@oxog/vld 2.0.3 → 2.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +120 -1
- package/README.md +1296 -1171
- package/dist/chunks/errors-core-Cqi4-9ew.js +1 -0
- package/dist/chunks/index-CkbfQQ4n.js +1 -0
- package/dist/chunks/index-yjpbvFgw.js +1 -0
- package/dist/chunks/ip-validation-g5LWgy9t.js +1 -0
- package/dist/chunks/security-Dy24T8N7.js +1 -0
- package/dist/cjs/chunks/errors-core-DKPohm9I.cjs +1 -0
- package/dist/cjs/chunks/index-BEV9nG0N.cjs +1 -0
- package/dist/cjs/chunks/index-ZjHAxYdA.cjs +1 -0
- package/dist/cjs/chunks/ip-validation-BZqPamPC.cjs +1 -0
- package/dist/cjs/chunks/security-aXZVI7qW.cjs +1 -0
- package/dist/cjs/cli/bin.cjs +2 -0
- package/dist/cjs/cli/index.cjs +1 -0
- package/dist/cjs/codecs/index.cjs +1 -0
- package/dist/cjs/coercion/index.cjs +1 -0
- package/dist/cjs/compat/emitter.cjs +1 -0
- package/dist/cjs/compat/result.cjs +1 -0
- package/dist/cjs/errors.cjs +1 -387
- package/dist/cjs/index.cjs +1 -10759
- package/dist/cjs/kernel.cjs +1 -0
- package/dist/cjs/locales/af.cjs +1 -0
- package/dist/cjs/locales/ar.cjs +1 -0
- package/dist/cjs/locales/bn.cjs +1 -0
- package/dist/cjs/locales/da.cjs +1 -0
- package/dist/cjs/locales/de.cjs +1 -0
- package/dist/cjs/locales/en.cjs +1 -0
- package/dist/cjs/locales/es-MX.cjs +1 -0
- package/dist/cjs/locales/es.cjs +1 -0
- package/dist/cjs/locales/fi.cjs +1 -0
- package/dist/cjs/locales/fr.cjs +1 -0
- package/dist/cjs/locales/hi.cjs +1 -0
- package/dist/cjs/locales/id.cjs +1 -0
- package/dist/cjs/locales/index.cjs +1 -2877
- package/dist/cjs/locales/it.cjs +1 -0
- package/dist/cjs/locales/ja.cjs +1 -0
- package/dist/cjs/locales/ko.cjs +1 -0
- package/dist/cjs/locales/lazy.cjs +1 -3169
- package/dist/cjs/locales/nl.cjs +1 -0
- package/dist/cjs/locales/no.cjs +1 -0
- package/dist/cjs/locales/pl.cjs +1 -0
- package/dist/cjs/locales/pt-BR.cjs +1 -0
- package/dist/cjs/locales/pt.cjs +1 -0
- package/dist/cjs/locales/ru.cjs +1 -0
- package/dist/cjs/locales/runtime.cjs +1 -0
- package/dist/cjs/locales/sv.cjs +1 -0
- package/dist/cjs/locales/sw.cjs +1 -0
- package/dist/cjs/locales/th.cjs +1 -0
- package/dist/cjs/locales/tr.cjs +1 -0
- package/dist/cjs/locales/vi.cjs +1 -0
- package/dist/cjs/locales/zh.cjs +1 -0
- package/dist/cjs/mini.cjs +1 -7474
- package/dist/cjs/pigment.cjs +1 -0
- package/dist/cjs/plugins/index.cjs +1 -0
- package/dist/cjs/registry.cjs +1 -0
- package/dist/cjs/v3/index.cjs +1 -0
- package/dist/cjs/v4/core/index.cjs +1 -0
- package/dist/cjs/v4/index.cjs +1 -0
- package/dist/cjs/v4/locales/index.cjs +1 -0
- package/dist/cjs/v4/mini/index.cjs +1 -0
- package/dist/cjs/v4-mini/index.cjs +1 -0
- package/dist/cjs/validators/any.cjs +1 -0
- package/dist/cjs/validators/array.cjs +1 -0
- package/dist/cjs/validators/base.cjs +1 -0
- package/dist/cjs/validators/base64.cjs +1 -0
- package/dist/cjs/validators/bigint.cjs +1 -0
- package/dist/cjs/validators/boolean.cjs +1 -0
- package/dist/cjs/validators/codec.cjs +1 -0
- package/dist/cjs/validators/custom.cjs +1 -0
- package/dist/cjs/validators/date.cjs +1 -0
- package/dist/cjs/validators/discriminated-union.cjs +1 -0
- package/dist/cjs/validators/enum.cjs +1 -0
- package/dist/cjs/validators/file.cjs +1 -0
- package/dist/cjs/validators/function.cjs +1 -0
- package/dist/cjs/validators/hex.cjs +1 -0
- package/dist/cjs/validators/index.cjs +1 -0
- package/dist/cjs/validators/intersection.cjs +1 -0
- package/dist/cjs/validators/json.cjs +1 -0
- package/dist/cjs/validators/lazy.cjs +1 -0
- package/dist/cjs/validators/literal.cjs +1 -0
- package/dist/cjs/validators/map.cjs +1 -0
- package/dist/cjs/validators/nan.cjs +1 -0
- package/dist/cjs/validators/never.cjs +1 -0
- package/dist/cjs/validators/null.cjs +1 -0
- package/dist/cjs/validators/number.cjs +1 -0
- package/dist/cjs/validators/object.cjs +1 -0
- package/dist/cjs/validators/promise.cjs +1 -0
- package/dist/cjs/validators/record.cjs +1 -0
- package/dist/cjs/validators/set.cjs +1 -0
- package/dist/cjs/validators/string-bool.cjs +1 -0
- package/dist/cjs/validators/string-formats.cjs +1 -0
- package/dist/cjs/validators/string.cjs +1 -0
- package/dist/cjs/validators/symbol.cjs +1 -0
- package/dist/cjs/validators/template-literal.cjs +1 -0
- package/dist/cjs/validators/tuple.cjs +1 -0
- package/dist/cjs/validators/uint8array.cjs +1 -0
- package/dist/cjs/validators/undefined.cjs +1 -0
- package/dist/cjs/validators/union.cjs +1 -0
- package/dist/cjs/validators/unknown.cjs +1 -0
- package/dist/cjs/validators/void.cjs +1 -0
- package/dist/cjs/validators/xor.cjs +1 -0
- package/dist/cli/bin.d.ts +0 -1
- package/dist/cli/bin.js +2 -0
- package/dist/cli/commands/benchmark.d.ts +1 -2
- package/dist/cli/commands/validate.d.ts +1 -2
- package/dist/cli/index.d.ts +0 -1
- package/dist/cli/index.js +1 -0
- package/dist/codecs/index.d.ts +21 -4
- package/dist/codecs/index.js +1 -4
- package/dist/coercion/bigint.d.ts +2 -3
- package/dist/coercion/boolean.d.ts +3 -3
- package/dist/coercion/date.d.ts +3 -3
- package/dist/coercion/index.d.ts +5 -6
- package/dist/coercion/index.js +1 -111
- package/dist/coercion/number.d.ts +2 -3
- package/dist/coercion/string.d.ts +2 -3
- package/dist/compat/emitter.d.ts +0 -1
- package/dist/compat/emitter.js +1 -181
- package/dist/compat/index.d.ts +4 -5
- package/dist/compat/result.d.ts +1 -2
- package/dist/compat/result.js +1 -171
- package/dist/errors-core.d.ts +58 -0
- package/dist/errors.d.ts +4 -54
- package/dist/errors.js +1 -235
- package/dist/events.d.ts +3 -4
- package/dist/index.d.ts +1093 -851
- package/dist/index.js +1 -855
- package/dist/kernel.d.ts +2 -3
- package/dist/kernel.js +1 -405
- package/dist/locales/af.d.ts +1 -2
- package/dist/locales/af.js +1 -107
- package/dist/locales/ar.d.ts +1 -2
- package/dist/locales/ar.js +1 -107
- package/dist/locales/bn.d.ts +1 -2
- package/dist/locales/bn.js +1 -107
- package/dist/locales/da.d.ts +1 -2
- package/dist/locales/da.js +1 -107
- package/dist/locales/de.d.ts +1 -2
- package/dist/locales/de.js +1 -107
- package/dist/locales/en.d.ts +1 -2
- package/dist/locales/en.js +1 -107
- package/dist/locales/es-MX.d.ts +1 -2
- package/dist/locales/es-MX.js +1 -106
- package/dist/locales/es.d.ts +1 -2
- package/dist/locales/es.js +1 -95
- package/dist/locales/fi.d.ts +1 -2
- package/dist/locales/fi.js +1 -107
- package/dist/locales/fr.d.ts +1 -2
- package/dist/locales/fr.js +1 -95
- package/dist/locales/hi.d.ts +1 -2
- package/dist/locales/hi.js +1 -107
- package/dist/locales/id.d.ts +1 -2
- package/dist/locales/id.js +1 -107
- package/dist/locales/index.d.ts +10 -15
- package/dist/locales/index.js +1 -3
- package/dist/locales/it.d.ts +1 -2
- package/dist/locales/it.js +1 -107
- package/dist/locales/ja.d.ts +1 -2
- package/dist/locales/ja.js +1 -107
- package/dist/locales/ko.d.ts +1 -2
- package/dist/locales/ko.js +1 -107
- package/dist/locales/lazy.d.ts +4 -26
- package/dist/locales/lazy.js +1 -220
- package/dist/locales/nl.d.ts +1 -2
- package/dist/locales/nl.js +1 -107
- package/dist/locales/no.d.ts +1 -2
- package/dist/locales/no.js +1 -107
- package/dist/locales/pl.d.ts +1 -2
- package/dist/locales/pl.js +1 -107
- package/dist/locales/pt-BR.d.ts +1 -2
- package/dist/locales/pt-BR.js +1 -107
- package/dist/locales/pt.d.ts +1 -2
- package/dist/locales/pt.js +1 -107
- package/dist/locales/ru.d.ts +1 -2
- package/dist/locales/ru.js +1 -107
- package/dist/locales/runtime.d.ts +10 -0
- package/dist/locales/runtime.js +1 -0
- package/dist/locales/sv.d.ts +1 -2
- package/dist/locales/sv.js +1 -107
- package/dist/locales/sw.d.ts +1 -2
- package/dist/locales/sw.js +1 -107
- package/dist/locales/th.d.ts +1 -2
- package/dist/locales/th.js +1 -107
- package/dist/locales/tr.d.ts +1 -2
- package/dist/locales/tr.js +1 -107
- package/dist/locales/types.d.ts +0 -1
- package/dist/locales/vi.d.ts +1 -2
- package/dist/locales/vi.js +1 -107
- package/dist/locales/zh.d.ts +1 -2
- package/dist/locales/zh.js +1 -107
- package/dist/logger.d.ts +0 -1
- package/dist/mini.d.ts +67 -68
- package/dist/mini.js +1 -132
- package/dist/pigment.d.ts +0 -1
- package/dist/pigment.js +1 -178
- package/dist/plugins/index.d.ts +2 -3
- package/dist/plugins/index.js +1 -0
- package/dist/plugins/types.d.ts +4 -5
- package/dist/registry.d.ts +23 -0
- package/dist/registry.js +1 -0
- package/dist/utils/codec-utils.d.ts +0 -1
- package/dist/utils/deep-merge.d.ts +0 -1
- package/dist/utils/ip-validation.d.ts +0 -1
- package/dist/utils/json-schema.d.ts +26 -7
- package/dist/utils/security.d.ts +2 -6
- package/dist/v3/index.d.ts +2 -0
- package/dist/v3/index.js +1 -0
- package/dist/v4/core/index.d.ts +272 -0
- package/dist/v4/core/index.js +1 -0
- package/dist/v4/index.d.ts +4 -0
- package/dist/v4/index.js +1 -0
- package/dist/v4/locales/index.d.ts +57 -0
- package/dist/v4/locales/index.js +1 -0
- package/dist/v4/mini/index.d.ts +2 -0
- package/dist/v4/mini/index.js +1 -0
- package/dist/v4-mini/index.d.ts +22 -0
- package/dist/v4-mini/index.js +1 -0
- package/dist/validators/any.d.ts +7 -2
- package/dist/validators/any.js +1 -0
- package/dist/validators/array.d.ts +16 -2
- package/dist/validators/array.js +1 -0
- package/dist/validators/base.d.ts +213 -14
- package/dist/validators/base.js +1 -0
- package/dist/validators/base64.d.ts +1 -2
- package/dist/validators/base64.js +1 -0
- package/dist/validators/bigint.d.ts +21 -3
- package/dist/validators/bigint.js +1 -0
- package/dist/validators/boolean.d.ts +13 -4
- package/dist/validators/boolean.js +1 -0
- package/dist/validators/codec.d.ts +9 -2
- package/dist/validators/codec.js +1 -0
- package/dist/validators/custom.d.ts +15 -2
- package/dist/validators/custom.js +1 -0
- package/dist/validators/date.d.ts +19 -3
- package/dist/validators/date.js +1 -0
- package/dist/validators/discriminated-union.d.ts +6 -5
- package/dist/validators/discriminated-union.js +1 -0
- package/dist/validators/enum.d.ts +10 -7
- package/dist/validators/enum.js +1 -0
- package/dist/validators/file.d.ts +7 -2
- package/dist/validators/file.js +1 -0
- package/dist/validators/function.d.ts +11 -5
- package/dist/validators/function.js +1 -0
- package/dist/validators/hex.d.ts +1 -2
- package/dist/validators/hex.js +1 -0
- package/dist/validators/index.d.ts +38 -39
- package/dist/validators/index.js +1 -515
- package/dist/validators/intersection.d.ts +1 -2
- package/dist/validators/intersection.js +1 -0
- package/dist/validators/json.d.ts +1 -2
- package/dist/validators/json.js +1 -0
- package/dist/validators/lazy.d.ts +5 -9
- package/dist/validators/lazy.js +1 -0
- package/dist/validators/literal.d.ts +9 -5
- package/dist/validators/literal.js +1 -0
- package/dist/validators/map.d.ts +15 -2
- package/dist/validators/map.js +1 -0
- package/dist/validators/nan.d.ts +2 -3
- package/dist/validators/nan.js +1 -0
- package/dist/validators/never.d.ts +1 -2
- package/dist/validators/never.js +1 -0
- package/dist/validators/null.d.ts +3 -3
- package/dist/validators/null.js +1 -0
- package/dist/validators/number.d.ts +75 -27
- package/dist/validators/number.js +1 -0
- package/dist/validators/object.d.ts +42 -11
- package/dist/validators/object.js +1 -0
- package/dist/validators/promise.d.ts +15 -10
- package/dist/validators/promise.js +1 -0
- package/dist/validators/record.d.ts +21 -9
- package/dist/validators/record.js +1 -0
- package/dist/validators/set.d.ts +11 -2
- package/dist/validators/set.js +1 -0
- package/dist/validators/string-bool.d.ts +7 -10
- package/dist/validators/string-bool.js +1 -0
- package/dist/validators/string-formats.d.ts +64 -65
- package/dist/validators/string-formats.js +1 -0
- package/dist/validators/string.d.ts +84 -26
- package/dist/validators/string.js +1 -0
- package/dist/validators/symbol.d.ts +8 -3
- package/dist/validators/symbol.js +1 -0
- package/dist/validators/template-literal.d.ts +1 -2
- package/dist/validators/template-literal.js +1 -0
- package/dist/validators/tuple.d.ts +29 -12
- package/dist/validators/tuple.js +1 -0
- package/dist/validators/uint8array.d.ts +3 -4
- package/dist/validators/uint8array.js +1 -0
- package/dist/validators/undefined.d.ts +3 -3
- package/dist/validators/undefined.js +1 -0
- package/dist/validators/union.d.ts +7 -4
- package/dist/validators/union.js +1 -0
- package/dist/validators/unknown.d.ts +7 -2
- package/dist/validators/unknown.js +1 -0
- package/dist/validators/void.d.ts +3 -2
- package/dist/validators/void.js +1 -0
- package/dist/validators/xor.d.ts +4 -5
- package/dist/validators/xor.js +1 -0
- package/package.json +239 -154
- package/dist/chunks/bigint-CRS0QVsy.js +0 -1854
- package/dist/chunks/bigint-CRS0QVsy.js.map +0 -1
- package/dist/chunks/date-50JV_Mfj.js +0 -506
- package/dist/chunks/date-50JV_Mfj.js.map +0 -1
- package/dist/chunks/index-DO8CFMxD.js +0 -894
- package/dist/chunks/index-DO8CFMxD.js.map +0 -1
- package/dist/chunks/json-Cp4WO0M9.js +0 -2021
- package/dist/chunks/json-Cp4WO0M9.js.map +0 -1
- package/dist/chunks/unknown-Dhzri_T-.js +0 -28
- package/dist/chunks/unknown-Dhzri_T-.js.map +0 -1
- package/dist/cjs/errors.cjs.map +0 -1
- package/dist/cjs/index.cjs.map +0 -1
- package/dist/cjs/locales/index.cjs.map +0 -1
- package/dist/cjs/locales/lazy.cjs.map +0 -1
- package/dist/cjs/mini.cjs.map +0 -1
- package/dist/cli/bin.d.ts.map +0 -1
- package/dist/cli/commands/benchmark.d.ts.map +0 -1
- package/dist/cli/commands/validate.d.ts.map +0 -1
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/codecs/index.d.ts.map +0 -1
- package/dist/codecs/index.js.map +0 -1
- package/dist/coercion/bigint.d.ts.map +0 -1
- package/dist/coercion/boolean.d.ts.map +0 -1
- package/dist/coercion/date.d.ts.map +0 -1
- package/dist/coercion/index.d.ts.map +0 -1
- package/dist/coercion/index.js.map +0 -1
- package/dist/coercion/number.d.ts.map +0 -1
- package/dist/coercion/string.d.ts.map +0 -1
- package/dist/compat/emitter.d.ts.map +0 -1
- package/dist/compat/emitter.js.map +0 -1
- package/dist/compat/index.d.ts.map +0 -1
- package/dist/compat/result.d.ts.map +0 -1
- package/dist/compat/result.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/events.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/kernel.d.ts.map +0 -1
- package/dist/kernel.js.map +0 -1
- package/dist/locales/af.d.ts.map +0 -1
- package/dist/locales/af.js.map +0 -1
- package/dist/locales/ar.d.ts.map +0 -1
- package/dist/locales/ar.js.map +0 -1
- package/dist/locales/backup-en.d.ts +0 -3
- package/dist/locales/backup-en.d.ts.map +0 -1
- package/dist/locales/bn.d.ts.map +0 -1
- package/dist/locales/bn.js.map +0 -1
- package/dist/locales/da.d.ts.map +0 -1
- package/dist/locales/da.js.map +0 -1
- package/dist/locales/de.d.ts.map +0 -1
- package/dist/locales/de.js.map +0 -1
- package/dist/locales/en.d.ts.map +0 -1
- package/dist/locales/en.js.map +0 -1
- package/dist/locales/es-MX.d.ts.map +0 -1
- package/dist/locales/es-MX.js.map +0 -1
- package/dist/locales/es.d.ts.map +0 -1
- package/dist/locales/es.js.map +0 -1
- package/dist/locales/fi.d.ts.map +0 -1
- package/dist/locales/fi.js.map +0 -1
- package/dist/locales/fr.d.ts.map +0 -1
- package/dist/locales/fr.js.map +0 -1
- package/dist/locales/hi.d.ts.map +0 -1
- package/dist/locales/hi.js.map +0 -1
- package/dist/locales/id.d.ts.map +0 -1
- package/dist/locales/id.js.map +0 -1
- package/dist/locales/index.d.ts.map +0 -1
- package/dist/locales/index.js.map +0 -1
- package/dist/locales/it.d.ts.map +0 -1
- package/dist/locales/it.js.map +0 -1
- package/dist/locales/ja.d.ts.map +0 -1
- package/dist/locales/ja.js.map +0 -1
- package/dist/locales/ko.d.ts.map +0 -1
- package/dist/locales/ko.js.map +0 -1
- package/dist/locales/lazy.d.ts.map +0 -1
- package/dist/locales/lazy.js.map +0 -1
- package/dist/locales/nl.d.ts.map +0 -1
- package/dist/locales/nl.js.map +0 -1
- package/dist/locales/no.d.ts.map +0 -1
- package/dist/locales/no.js.map +0 -1
- package/dist/locales/pl.d.ts.map +0 -1
- package/dist/locales/pl.js.map +0 -1
- package/dist/locales/pt-BR.d.ts.map +0 -1
- package/dist/locales/pt-BR.js.map +0 -1
- package/dist/locales/pt.d.ts.map +0 -1
- package/dist/locales/pt.js.map +0 -1
- package/dist/locales/ru.d.ts.map +0 -1
- package/dist/locales/ru.js.map +0 -1
- package/dist/locales/sv.d.ts.map +0 -1
- package/dist/locales/sv.js.map +0 -1
- package/dist/locales/sw.d.ts.map +0 -1
- package/dist/locales/sw.js.map +0 -1
- package/dist/locales/th.d.ts.map +0 -1
- package/dist/locales/th.js.map +0 -1
- package/dist/locales/tr.d.ts.map +0 -1
- package/dist/locales/tr.js.map +0 -1
- package/dist/locales/types.d.ts.map +0 -1
- package/dist/locales/vi.d.ts.map +0 -1
- package/dist/locales/vi.js.map +0 -1
- package/dist/locales/zh.d.ts.map +0 -1
- package/dist/locales/zh.js.map +0 -1
- package/dist/logger.d.ts.map +0 -1
- package/dist/mini.d.ts.map +0 -1
- package/dist/mini.js.map +0 -1
- package/dist/pigment.d.ts.map +0 -1
- package/dist/pigment.js.map +0 -1
- package/dist/plugins/index.d.ts.map +0 -1
- package/dist/plugins/types.d.ts.map +0 -1
- package/dist/utils/codec-utils.d.ts.map +0 -1
- package/dist/utils/deep-merge.d.ts.map +0 -1
- package/dist/utils/ip-validation.d.ts.map +0 -1
- package/dist/utils/json-schema.d.ts.map +0 -1
- package/dist/utils/security.d.ts.map +0 -1
- package/dist/validators/any.d.ts.map +0 -1
- package/dist/validators/array.d.ts.map +0 -1
- package/dist/validators/base.d.ts.map +0 -1
- package/dist/validators/base64.d.ts.map +0 -1
- package/dist/validators/bigint.d.ts.map +0 -1
- package/dist/validators/boolean.d.ts.map +0 -1
- package/dist/validators/codec.d.ts.map +0 -1
- package/dist/validators/custom.d.ts.map +0 -1
- package/dist/validators/date.d.ts.map +0 -1
- package/dist/validators/discriminated-union.d.ts.map +0 -1
- package/dist/validators/enum.d.ts.map +0 -1
- package/dist/validators/file.d.ts.map +0 -1
- package/dist/validators/function.d.ts.map +0 -1
- package/dist/validators/hex.d.ts.map +0 -1
- package/dist/validators/index.d.ts.map +0 -1
- package/dist/validators/index.js.map +0 -1
- package/dist/validators/intersection.d.ts.map +0 -1
- package/dist/validators/json.d.ts.map +0 -1
- package/dist/validators/lazy.d.ts.map +0 -1
- package/dist/validators/literal.d.ts.map +0 -1
- package/dist/validators/map.d.ts.map +0 -1
- package/dist/validators/nan.d.ts.map +0 -1
- package/dist/validators/never.d.ts.map +0 -1
- package/dist/validators/null.d.ts.map +0 -1
- package/dist/validators/number.d.ts.map +0 -1
- package/dist/validators/object.d.ts.map +0 -1
- package/dist/validators/promise.d.ts.map +0 -1
- package/dist/validators/record.d.ts.map +0 -1
- package/dist/validators/set.d.ts.map +0 -1
- package/dist/validators/string-bool.d.ts.map +0 -1
- package/dist/validators/string-formats.d.ts.map +0 -1
- package/dist/validators/string.d.ts.map +0 -1
- package/dist/validators/symbol.d.ts.map +0 -1
- package/dist/validators/template-literal.d.ts.map +0 -1
- package/dist/validators/tuple.d.ts.map +0 -1
- package/dist/validators/uint8array.d.ts.map +0 -1
- package/dist/validators/undefined.d.ts.map +0 -1
- package/dist/validators/union.d.ts.map +0 -1
- package/dist/validators/unknown.d.ts.map +0 -1
- package/dist/validators/void.d.ts.map +0 -1
- package/dist/validators/xor.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,1171 +1,1296 @@
|
|
|
1
|
-
# VLD - Fast & Lightweight TypeScript Validation Library
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/@oxog/vld) [](https://opensource.org/licenses/MIT) [](https://www.typescriptlang.org/) [](package.json) [](
|
|
15
|
-
- [Error Handling & Formatting](
|
|
16
|
-
- [Advanced Examples](
|
|
17
|
-
- [
|
|
18
|
-
- [
|
|
19
|
-
- [
|
|
20
|
-
- [
|
|
21
|
-
- [
|
|
22
|
-
- [
|
|
23
|
-
- [Benchmarks](
|
|
24
|
-
- [Contributing](
|
|
25
|
-
- [Links](
|
|
26
|
-
|
|
27
|
-
## Features
|
|
28
|
-
|
|
29
|
-
### Core Features
|
|
30
|
-
- **Blazing Fast**: Optimized for V8 engine with superior performance
|
|
31
|
-
- **Type-Safe**: Full TypeScript support with excellent type inference
|
|
32
|
-
- **Zero Dependencies**: Lightweight with no external dependencies
|
|
33
|
-
- **Tree-Shakeable**: Only import what you need
|
|
34
|
-
- **Composable**: Chain validations for complex schemas
|
|
35
|
-
- **Advanced Error Formatting**: Tree, pretty, and flatten error utilities
|
|
36
|
-
- **Multi-language**: Built-in support for 27+ languages
|
|
37
|
-
- **
|
|
38
|
-
- **
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
- **
|
|
44
|
-
- **
|
|
45
|
-
- **
|
|
46
|
-
- **
|
|
47
|
-
- **
|
|
48
|
-
- **
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
-
|
|
96
|
-
-
|
|
97
|
-
-
|
|
98
|
-
|
|
99
|
-
####
|
|
100
|
-
|
|
101
|
-
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
-
|
|
119
|
-
-
|
|
120
|
-
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
-
|
|
124
|
-
-
|
|
125
|
-
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
- **`
|
|
132
|
-
-
|
|
133
|
-
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
- **`
|
|
137
|
-
- **`
|
|
138
|
-
- **`
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
-
|
|
144
|
-
-
|
|
145
|
-
- **
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
-
|
|
154
|
-
-
|
|
155
|
-
-
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
-
|
|
163
|
-
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
-
|
|
167
|
-
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
-
|
|
171
|
-
-
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
npm
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
v
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
//
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
v.
|
|
291
|
-
v.
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
v.
|
|
328
|
-
v.
|
|
329
|
-
v.
|
|
330
|
-
v.
|
|
331
|
-
v.
|
|
332
|
-
v.
|
|
333
|
-
v.
|
|
334
|
-
v.
|
|
335
|
-
v.
|
|
336
|
-
v.
|
|
337
|
-
v.
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
v.
|
|
345
|
-
v.
|
|
346
|
-
v.
|
|
347
|
-
v.
|
|
348
|
-
v.
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
v.
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
//
|
|
374
|
-
|
|
375
|
-
.
|
|
376
|
-
.
|
|
377
|
-
.
|
|
378
|
-
.
|
|
379
|
-
|
|
380
|
-
//
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
.
|
|
386
|
-
.
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
//
|
|
394
|
-
v.
|
|
395
|
-
|
|
396
|
-
//
|
|
397
|
-
v.
|
|
398
|
-
|
|
399
|
-
//
|
|
400
|
-
v.
|
|
401
|
-
|
|
402
|
-
//
|
|
403
|
-
v.
|
|
404
|
-
|
|
405
|
-
//
|
|
406
|
-
v.
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
)
|
|
410
|
-
|
|
411
|
-
//
|
|
412
|
-
v.
|
|
413
|
-
|
|
414
|
-
//
|
|
415
|
-
v.
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
v.
|
|
424
|
-
|
|
425
|
-
//
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
//
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
//
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
})
|
|
451
|
-
|
|
452
|
-
//
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
//
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
//
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
//
|
|
472
|
-
|
|
473
|
-
.
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
//
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
v.
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
v.
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
//
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
);
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
const
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
```
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
const
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
```
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
//
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
const
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
const
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
//
|
|
963
|
-
const
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
//
|
|
985
|
-
|
|
986
|
-
```
|
|
987
|
-
|
|
988
|
-
###
|
|
989
|
-
|
|
990
|
-
```typescript
|
|
991
|
-
import {
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
//
|
|
998
|
-
const
|
|
999
|
-
|
|
1000
|
-
```
|
|
1001
|
-
|
|
1002
|
-
##
|
|
1003
|
-
|
|
1004
|
-
VLD includes
|
|
1005
|
-
|
|
1006
|
-
###
|
|
1007
|
-
|
|
1008
|
-
```
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
.
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
###
|
|
1056
|
-
|
|
1057
|
-
```typescript
|
|
1058
|
-
import {
|
|
1059
|
-
|
|
1060
|
-
//
|
|
1061
|
-
const
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
-
|
|
1166
|
-
|
|
1167
|
-
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1
|
+
# VLD - Fast & Lightweight TypeScript Validation Library
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@oxog/vld) [](https://opensource.org/licenses/MIT) [](https://www.typescriptlang.org/) [](package.json) [](package.json)
|
|
4
|
+
|
|
5
|
+
VLD is a blazing-fast, type-safe validation library for TypeScript and JavaScript with **Zod-compatible root and subpath APIs**. Built with performance in mind, it provides a simple and intuitive API while maintaining excellent type inference and 27+ language internationalization support.
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Features](#features)
|
|
10
|
+
- [Performance](#performance)
|
|
11
|
+
- [Installation](#installation)
|
|
12
|
+
- [Quick Start](#quick-start)
|
|
13
|
+
- [API Reference](#api-reference)
|
|
14
|
+
- [Internationalization (i18n)](#internationalization-i18n)
|
|
15
|
+
- [Error Handling & Formatting](#error-handling--formatting)
|
|
16
|
+
- [Advanced Examples](#advanced-examples)
|
|
17
|
+
- [Codecs - Bidirectional Transformations](#codecs---bidirectional-transformations)
|
|
18
|
+
- [Plugin System](#plugin-system)
|
|
19
|
+
- [Result Pattern](#result-pattern)
|
|
20
|
+
- [CLI Tools](#cli-tools)
|
|
21
|
+
- [Logger & Colored Output](#logger--colored-output)
|
|
22
|
+
- [VLD vs. Zod](#vld-vs-zod)
|
|
23
|
+
- [Benchmarks](#benchmarks)
|
|
24
|
+
- [Contributing](#contributing)
|
|
25
|
+
- [Links](#links)
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
### Core Features
|
|
30
|
+
- **Blazing Fast**: Optimized for V8 engine with superior performance
|
|
31
|
+
- **Type-Safe**: Full TypeScript support with excellent type inference
|
|
32
|
+
- **Zero Dependencies**: Lightweight with no external dependencies
|
|
33
|
+
- **Tree-Shakeable**: Only import what you need
|
|
34
|
+
- **Composable**: Chain validations for complex schemas
|
|
35
|
+
- **Advanced Error Formatting**: Tree, pretty, and flatten error utilities
|
|
36
|
+
- **Multi-language**: Built-in support for 27+ languages
|
|
37
|
+
- **100% Statement / Branch / Function / Line Coverage**: Rigorously tested with 2502 passing tests
|
|
38
|
+
- **Release-Gated Performance**: CI guards require VLD to stay faster than the latest stable Zod across runtime, startup, and memory benchmarks
|
|
39
|
+
- **Drop-in App Verification**: A real TypeScript fixture is compiled and run once with `zod` and once with built VLD, then normalized runtime output is compared
|
|
40
|
+
- **Audited Compatibility Contract**: Modern Zod 4.4.3 factory signatures, schema direction methods, release-fix behaviors, and JSON Schema defaults are differential-tested; see [the compatibility policy](docs/ZOD_COMPATIBILITY.md)
|
|
41
|
+
|
|
42
|
+
### Advanced Zod-Compatible Features
|
|
43
|
+
- **Type Coercion**: `v.coerce.string()`, `v.coerce.number()`, `v.coerce.boolean()`, etc.
|
|
44
|
+
- **Advanced Types**: BigInt, Symbol, Tuple, Record, Set, Map validation
|
|
45
|
+
- **Intersection Types**: Combine multiple schemas with intelligent merging
|
|
46
|
+
- **Custom Validation**: `refine()` for custom predicates and validation logic
|
|
47
|
+
- **Data Transformation**: `transform()` for post-validation data transformation
|
|
48
|
+
- **Default Values**: `default()` for handling undefined inputs elegantly
|
|
49
|
+
- **Fallback Handling**: `catch()` for graceful error recovery
|
|
50
|
+
- **Object Utilities**: `pick()`, `omit()`, `extend()` for flexible object schemas
|
|
51
|
+
|
|
52
|
+
### New in v2.2.x - Error Parity, Canary Parity, and Minified Builds
|
|
53
|
+
|
|
54
|
+
#### Zod 4-Compatible Error Issues
|
|
55
|
+
Validation failures now carry Zod 4's structured issue shape, so error-handling code ports across unchanged:
|
|
56
|
+
- `invalid_type` issues expose `expected` and `received` and use the `"Invalid input: expected X, received Y"` message format
|
|
57
|
+
- `too_small` / `too_big` issues expose `minimum`, `maximum`, `origin`, and `inclusive`
|
|
58
|
+
- `invalid_format` issues expose `format`, `origin`, and `pattern`; `invalid_value` issues expose a `values` array
|
|
59
|
+
- `parse()` throws `VldError` (which extends `Error`) for every validator, matching Zod's throw behavior
|
|
60
|
+
|
|
61
|
+
#### New Parity Helpers
|
|
62
|
+
```typescript
|
|
63
|
+
import { v, deepPartial, input, output } from '@oxog/vld';
|
|
64
|
+
|
|
65
|
+
v.creditCard().parse('4242424242424242'); // regex plus Luhn checksum
|
|
66
|
+
|
|
67
|
+
const schema = v.object({
|
|
68
|
+
profile: v.object({ name: v.string(), age: v.number() })
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const draft = deepPartial(schema); // every nested field optional
|
|
72
|
+
const inputSide = input(schema); // input-side view of a pipe
|
|
73
|
+
const outputSide = output(schema); // output-side view of a pipe
|
|
74
|
+
```
|
|
75
|
+
- `deepPartial()` walks children first, mirroring Zod's `visit.js` ordering, and stays cycle-safe through lazy deferral
|
|
76
|
+
- `input()` / `output()` resolve pipe direction the way Zod's root helpers do
|
|
77
|
+
- `@oxog/vld/v4/core` gained the matching `_creditCard`, `isValidCreditCard`, `standardProps`, `handleUnrepresentable`, `$ZodCyclicError`, `attachMemoizer`, and `isBackEdge` shims
|
|
78
|
+
|
|
79
|
+
#### Minified Release Builds
|
|
80
|
+
- Release artifacts ship minified by default (opt out with `VLD_MINIFY=0`)
|
|
81
|
+
- Mangling preserves `/^Vld/` class names, because JSON Schema conversion dispatches on `schema.constructor.name`
|
|
82
|
+
- A built-CJS guard in `verify:drop-in` asserts name-dispatched composites against the minified bundle, so this can never silently regress again
|
|
83
|
+
|
|
84
|
+
### NEW in v2.0.0 - Modular Architecture
|
|
85
|
+
|
|
86
|
+
#### Tree-Shakable Mini API
|
|
87
|
+
```typescript
|
|
88
|
+
import { string, number, object, optional } from '@oxog/vld/mini';
|
|
89
|
+
|
|
90
|
+
const schema = object({
|
|
91
|
+
name: string().min(1),
|
|
92
|
+
age: optional(number().positive()),
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
- **82% smaller bundles** when using only needed validators
|
|
96
|
+
- Individual factory functions for optimal tree-shaking
|
|
97
|
+
- Full TypeScript support with identical type inference
|
|
98
|
+
|
|
99
|
+
#### Lazy Locale Loading
|
|
100
|
+
|
|
101
|
+
> **Bundle-size contract:** the lazy entrypoint is published as
|
|
102
|
+
> `@oxog/vld/locales/lazy` (`src/locales/lazy.ts`). It uses dynamic `import()`
|
|
103
|
+
> for each locale on first use, so tree-shaken bundles ship **only English by
|
|
104
|
+
> default**. Importing the plain `@oxog/vld/locales` subpath (or the root
|
|
105
|
+
> `@oxog/vld` package) eagerly pulls every locale into the graph; pick the
|
|
106
|
+
> `lazy` subpath if you only need one or two languages in production.
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import { setLocaleAsync, preloadLocales } from '@oxog/vld/locales/lazy';
|
|
110
|
+
|
|
111
|
+
// First call loads the locale on demand; subsequent calls hit the cache.
|
|
112
|
+
await setLocaleAsync('tr');
|
|
113
|
+
|
|
114
|
+
// SSR / batch warm-up: preload what you need before serving traffic.
|
|
115
|
+
await preloadLocales(['en', 'de', 'ja']);
|
|
116
|
+
```
|
|
117
|
+
- **92% bundle reduction** when you only ship English plus the locales you pre-load
|
|
118
|
+
- `setLocaleAsync()` is true async dynamic-import, not a sync wrapper
|
|
119
|
+
- `preloadLocales()` for SSR/batch loading
|
|
120
|
+
- Backwards-compatible `setLocale()` is still available on the eager entrypoint
|
|
121
|
+
|
|
122
|
+
#### Dual ESM/CJS Build
|
|
123
|
+
- ESM builds for modern bundlers (Vite, esbuild)
|
|
124
|
+
- CJS builds for Node.js and legacy environments
|
|
125
|
+
- Proper `exports` field with conditional exports
|
|
126
|
+
|
|
127
|
+
### NEW in v1.5.0 - Major Platform Release
|
|
128
|
+
|
|
129
|
+
#### Plugin System
|
|
130
|
+
- **`definePlugin()`**: Create custom plugins with validators, transforms, and codecs
|
|
131
|
+
- **`usePlugin()`**: Register plugins globally
|
|
132
|
+
- **Plugin Hooks**: Lifecycle hooks for validation events
|
|
133
|
+
- **Custom Validators**: Extend VLD with your own validators
|
|
134
|
+
|
|
135
|
+
#### Result Pattern
|
|
136
|
+
- **`Ok()`/`Err()`**: Functional error handling
|
|
137
|
+
- **`match()`**: Pattern matching on results
|
|
138
|
+
- **`map()`/`flatMap()`**: Transform results
|
|
139
|
+
- **`tryCatch()`**: Safe function execution
|
|
140
|
+
- **`all()`**: Combine multiple results
|
|
141
|
+
|
|
142
|
+
#### Event System
|
|
143
|
+
- **`createEmitter()`**: Type-safe event emitter
|
|
144
|
+
- **`createEventBus()`**: Global event bus
|
|
145
|
+
- **Validation Events**: Parse start, success, error, field validation
|
|
146
|
+
|
|
147
|
+
#### CLI Tools
|
|
148
|
+
- **`vld validate`**: Validate data from command line
|
|
149
|
+
- **`vld benchmark`**: Run performance benchmarks
|
|
150
|
+
- **Colored Output**: Beautiful terminal output with pigment
|
|
151
|
+
|
|
152
|
+
#### New Validators
|
|
153
|
+
- **`v.discriminatedUnion()`**: Discriminated union types
|
|
154
|
+
- **`v.xor()`**: Exclusive OR validation
|
|
155
|
+
- **`v.file()`**: File upload validation
|
|
156
|
+
- **`v.function()`**: Function validation
|
|
157
|
+
- **`v.custom()`**: Type-safe custom validators
|
|
158
|
+
- **`v.json()`**: JSON string validation with schema
|
|
159
|
+
- **`v.lazy()`**: Recursive schema support
|
|
160
|
+
- **`v.nan()`**: NaN validation
|
|
161
|
+
- **`v.null()`**: Null validation
|
|
162
|
+
- **`v.undefined()`**: Undefined validation
|
|
163
|
+
- **`v.templateLiteral()`**: Template literal types
|
|
164
|
+
|
|
165
|
+
#### New String Format Validators
|
|
166
|
+
- **`v.hostname()`**: Hostname validation
|
|
167
|
+
- **`v.emoji()`**: Emoji validation
|
|
168
|
+
- **`v.base64()`/`v.base64url()`**: Base64 format validation
|
|
169
|
+
- **`v.hex()`**: Hex string validation
|
|
170
|
+
- **`v.jwt()`**: JWT format validation
|
|
171
|
+
- **`v.nanoid()`/`v.cuid()`/`v.cuid2()`/`v.ulid()`**: ID format validation
|
|
172
|
+
- **`v.mac()`**: MAC address validation
|
|
173
|
+
- **`v.cidrv4()`/`v.cidrv6()`**: CIDR block validation
|
|
174
|
+
- **`v.e164()`**: E.164 phone number validation
|
|
175
|
+
- **`v.hash()`**: Hash validation (md5, sha1, sha256, sha384, sha512)
|
|
176
|
+
- **`v.iso.date()`/`v.iso.time()`/`v.iso.dateTime()`/`v.iso.duration()`**: ISO format validation
|
|
177
|
+
|
|
178
|
+
#### Enhanced Object Utilities
|
|
179
|
+
- **`v.strictObject()`**: Strict mode object validation
|
|
180
|
+
- **`v.looseObject()`**: Passthrough object validation
|
|
181
|
+
- **`v.partialRecord()`**: Partial record validation
|
|
182
|
+
- **`v.looseRecord()`**: Loose record validation
|
|
183
|
+
- **`v.int()`**: Integer shortcut
|
|
184
|
+
- **`v.int32()`**: 32-bit integer shortcut
|
|
185
|
+
- **`v.nullish()`**: Null or undefined
|
|
186
|
+
- **`v.NEVER`**: NEVER constant for transforms (Zod 4 parity)
|
|
187
|
+
|
|
188
|
+
### Codec System - Beyond Zod
|
|
189
|
+
- **Bidirectional Transformations**: Full encode/decode support for data conversion
|
|
190
|
+
- **19 Built-in Codecs**: String conversions, date parsing, JSON, URL, binary data
|
|
191
|
+
- **Zod-Compatible**: All `stringToNumber`, `jsonCodec`, `base64ToBytes`, etc.
|
|
192
|
+
- **Async Support**: Both sync and async codec operations
|
|
193
|
+
- **Custom Codecs**: Create your own bidirectional transformations
|
|
194
|
+
- **Type-Safe**: Full TypeScript support with perfect type inference
|
|
195
|
+
|
|
196
|
+
## Performance
|
|
197
|
+
|
|
198
|
+
VLD is designed for speed and efficiency with recent optimizations delivering exceptional performance:
|
|
199
|
+
|
|
200
|
+
### Release-Gated Speed Benchmarks (v2.2.1 vs Zod 4.4.3)
|
|
201
|
+
- Runtime guard: VLD must stay at least 1.2x faster on every guarded hot path and keep at least a 3x average ratio
|
|
202
|
+
- Startup guard: cross-platform floors are 0.85x import, 0.9x total startup, and 1.25x warm parse versus Zod
|
|
203
|
+
- Memory guard: VLD must keep at least 2x lower total retained heap, 1.5x higher aggregate throughput, and no guarded case below 1.1x speed
|
|
204
|
+
|
|
205
|
+
### Latest Runtime Guard Snapshot
|
|
206
|
+
|
|
207
|
+
Measured with `npm run benchmark:guard` (5 samples per case) against Zod 4.4.3:
|
|
208
|
+
|
|
209
|
+
| Guarded case | VLD | Zod | Ratio |
|
|
210
|
+
|--------------|-----|-----|-------|
|
|
211
|
+
| Nullish parse | 214.1M ops/sec | 7.0M ops/sec | **30.70x** |
|
|
212
|
+
| Number positive int parse | 252.9M ops/sec | 27.8M ops/sec | **9.10x** |
|
|
213
|
+
| Discriminated union parse | 35.0M ops/sec | 8.6M ops/sec | **4.06x** |
|
|
214
|
+
| Optional parse | 212.9M ops/sec | 56.6M ops/sec | **3.76x** |
|
|
215
|
+
| Union string and number parse | 39.1M ops/sec | 11.9M ops/sec | **3.30x** |
|
|
216
|
+
| Simple string parse | 620.7M ops/sec | 208.8M ops/sec | **2.97x** |
|
|
217
|
+
| Array number parse | 49.2M ops/sec | 28.3M ops/sec | **1.74x** |
|
|
218
|
+
| Simple object parse | 45.2M ops/sec | 27.7M ops/sec | **1.63x** |
|
|
219
|
+
|
|
220
|
+
8/8 guarded cases pass with a **7.16x average ratio**. Absolute ops/sec numbers are hardware-dependent; the ratios are what the release gate enforces.
|
|
221
|
+
|
|
222
|
+
### Optimizations
|
|
223
|
+
- **110x improvement** in union type validation
|
|
224
|
+
- **Simplified email regex** for maximum performance
|
|
225
|
+
- **Inline type checks** in object validation
|
|
226
|
+
- **Optimized loops** with direct array assignment
|
|
227
|
+
- **SafeParse optimization** to avoid try-catch overhead
|
|
228
|
+
- **Pre-computed keys** with Set for O(1) lookups
|
|
229
|
+
|
|
230
|
+
### Memory Efficiency
|
|
231
|
+
|
|
232
|
+
Measured with `npm run benchmark:memory` against Zod 4.4.3. Heap deltas move a few percent between runs, so treat these as approximate:
|
|
233
|
+
|
|
234
|
+
- **~12.7x less memory** for schema creation
|
|
235
|
+
- **~7.3x less memory** for union validation
|
|
236
|
+
- **~2.9x less memory** for simple string validation
|
|
237
|
+
- **~2.7x less memory** for complex object validation
|
|
238
|
+
- **~5x less memory** overall
|
|
239
|
+
|
|
240
|
+
### A Note on Real-World Benchmarking
|
|
241
|
+
|
|
242
|
+
Many validation library benchmarks can be misleading because they often test with **reused schema instances**:
|
|
243
|
+
|
|
244
|
+
```javascript
|
|
245
|
+
// What benchmarks typically test (unrealistic):
|
|
246
|
+
const schema = z.string();
|
|
247
|
+
for (let i = 0; i < 1000000; i++) {
|
|
248
|
+
schema.parse(data); // Same instance reused
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// What happens in real applications:
|
|
252
|
+
app.post('/api/user', (req, res) => {
|
|
253
|
+
// New schema created for each request
|
|
254
|
+
const schema = z.object({
|
|
255
|
+
email: z.string().email(),
|
|
256
|
+
age: z.number().min(18)
|
|
257
|
+
});
|
|
258
|
+
schema.parse(req.body);
|
|
259
|
+
});
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
When testing real-world patterns:
|
|
263
|
+
- **Creating new instances**: VLD is **2000x faster** than Zod
|
|
264
|
+
- **Reused instances**: Zod benefits from V8's singleton optimization
|
|
265
|
+
- **Real applications**: Schemas are often created dynamically, where VLD excels
|
|
266
|
+
|
|
267
|
+
Run `npm run benchmark:truth` to see the real performance difference.
|
|
268
|
+
|
|
269
|
+
## Installation
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
npm install @oxog/vld
|
|
273
|
+
# or
|
|
274
|
+
yarn add @oxog/vld
|
|
275
|
+
# or
|
|
276
|
+
pnpm add @oxog/vld
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Quick Start
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
import { v } from '@oxog/vld';
|
|
283
|
+
|
|
284
|
+
// It is recommended to import as `v` for consistency with Zod's `z`
|
|
285
|
+
// and for a more concise syntax.
|
|
286
|
+
|
|
287
|
+
// Define a schema
|
|
288
|
+
const userSchema = v.object({
|
|
289
|
+
name: v.string().min(2),
|
|
290
|
+
email: v.string().email(),
|
|
291
|
+
age: v.number().min(18).max(100),
|
|
292
|
+
isActive: v.boolean()
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
// Validate data
|
|
296
|
+
const result = userSchema.safeParse({
|
|
297
|
+
name: 'John Doe',
|
|
298
|
+
email: 'john@example.com',
|
|
299
|
+
age: 25,
|
|
300
|
+
isActive: true
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
if (result.success) {
|
|
304
|
+
console.log('Valid user:', result.data);
|
|
305
|
+
} else {
|
|
306
|
+
console.log('Validation error:', result.error);
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
For advanced error formatting:
|
|
311
|
+
```typescript
|
|
312
|
+
import { v, VldError, treeifyError, prettifyError, flattenError } from '@oxog/vld';
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## API Reference
|
|
316
|
+
|
|
317
|
+
### Basic Types
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
v.string() // String validation
|
|
321
|
+
v.number() // Number validation
|
|
322
|
+
v.int() // Integer validation (shortcut)
|
|
323
|
+
v.int32() // 32-bit integer validation
|
|
324
|
+
v.boolean() // Boolean validation
|
|
325
|
+
v.bigint() // BigInt validation
|
|
326
|
+
v.symbol() // Symbol validation
|
|
327
|
+
v.date() // Date validation
|
|
328
|
+
v.uint8array()// Uint8Array validation
|
|
329
|
+
v.literal() // Literal values
|
|
330
|
+
v.enum() // Enum values (supports TypeScript enums)
|
|
331
|
+
v.any() // Any type
|
|
332
|
+
v.unknown() // Unknown type
|
|
333
|
+
v.void() // Void type
|
|
334
|
+
v.never() // Never type
|
|
335
|
+
v.null() // Null type
|
|
336
|
+
v.undefined() // Undefined type
|
|
337
|
+
v.nan() // NaN type
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Advanced Types
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
// Collections
|
|
344
|
+
v.array(v.string()) // Array validation
|
|
345
|
+
v.tuple(v.string(), v.number()) // Fixed-length tuple
|
|
346
|
+
v.record(v.number()) // Record/dictionary validation
|
|
347
|
+
v.set(v.string()) // Set validation
|
|
348
|
+
v.map(v.string(), v.number()) // Map validation
|
|
349
|
+
|
|
350
|
+
// Objects
|
|
351
|
+
v.object({ // Object schema
|
|
352
|
+
name: v.string(),
|
|
353
|
+
age: v.number()
|
|
354
|
+
})
|
|
355
|
+
v.strictObject({...}) // No extra fields allowed
|
|
356
|
+
v.looseObject({...}) // Extra fields passed through
|
|
357
|
+
|
|
358
|
+
// Composition
|
|
359
|
+
v.union(v.string(), v.number()) // Union types
|
|
360
|
+
v.intersection(schemaA, schemaB) // Intersection types
|
|
361
|
+
v.discriminatedUnion('type', ...) // Discriminated union
|
|
362
|
+
v.xor(schemaA, schemaB) // Exclusive OR
|
|
363
|
+
v.optional(v.string()) // Optional fields
|
|
364
|
+
v.nullable(v.string()) // Nullable fields
|
|
365
|
+
v.nullish(v.string()) // Null or undefined
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### String Validators
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
v.string()
|
|
372
|
+
.min(5) // Minimum length
|
|
373
|
+
.max(10) // Maximum length
|
|
374
|
+
.length(8) // Exact length
|
|
375
|
+
.email() // Email format
|
|
376
|
+
.url() // URL format
|
|
377
|
+
.uuid() // UUID format
|
|
378
|
+
.regex(/pattern/) // Custom regex
|
|
379
|
+
.startsWith('prefix') // String prefix
|
|
380
|
+
.endsWith('suffix') // String suffix
|
|
381
|
+
.includes('substring') // Contains substring
|
|
382
|
+
.ip() // IP address (v4 or v6)
|
|
383
|
+
.trim() // Trim whitespace
|
|
384
|
+
.toLowerCase() // Convert to lowercase
|
|
385
|
+
.toUpperCase() // Convert to uppercase
|
|
386
|
+
.nonempty() // Non-empty string
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### String Format Validators (Top-Level)
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
v.email() // Email validation
|
|
393
|
+
v.uuid() // UUID validation
|
|
394
|
+
v.uuid({ version: 'v4' }) // UUID v4 validation
|
|
395
|
+
v.uuidv4() // UUID v4 shortcut
|
|
396
|
+
v.hostname() // Hostname validation
|
|
397
|
+
v.emoji() // Emoji validation
|
|
398
|
+
v.base64() // Base64 format
|
|
399
|
+
v.base64url() // Base64 URL-safe format
|
|
400
|
+
v.hex() // Hex string
|
|
401
|
+
v.jwt() // JWT format
|
|
402
|
+
v.nanoid() // NanoID format
|
|
403
|
+
v.cuid() // CUID format
|
|
404
|
+
v.cuid2() // CUID2 format
|
|
405
|
+
v.ulid() // ULID format
|
|
406
|
+
v.ipv4() // IPv4 address
|
|
407
|
+
v.ipv6() // IPv6 address
|
|
408
|
+
v.mac() // MAC address
|
|
409
|
+
v.cidrv4() // IPv4 CIDR block
|
|
410
|
+
v.cidrv6() // IPv6 CIDR block
|
|
411
|
+
v.e164() // E.164 phone number
|
|
412
|
+
v.creditCard() // Credit card number (regex plus Luhn checksum)
|
|
413
|
+
v.hash('sha256') // Hash validation
|
|
414
|
+
v.iso.date() // ISO date format
|
|
415
|
+
v.iso.time() // ISO time format
|
|
416
|
+
v.iso.dateTime() // ISO datetime format
|
|
417
|
+
v.iso.duration() // ISO duration format
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Number Validators
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
v.number()
|
|
424
|
+
.min(0) // Minimum value
|
|
425
|
+
.max(100) // Maximum value
|
|
426
|
+
.int() // Integer only
|
|
427
|
+
.positive() // Positive numbers
|
|
428
|
+
.negative() // Negative numbers
|
|
429
|
+
.nonnegative() // >= 0
|
|
430
|
+
.nonpositive() // <= 0
|
|
431
|
+
.finite() // Finite numbers
|
|
432
|
+
.safe() // Safe integers
|
|
433
|
+
.multipleOf(5) // Multiple of value
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### Arrays and Objects
|
|
437
|
+
|
|
438
|
+
```typescript
|
|
439
|
+
// Arrays
|
|
440
|
+
v.array(v.string()) // Array of strings
|
|
441
|
+
.min(1) // Minimum length
|
|
442
|
+
.max(10) // Maximum length
|
|
443
|
+
.length(5) // Exact length
|
|
444
|
+
.nonempty() // Non-empty array
|
|
445
|
+
|
|
446
|
+
// Objects
|
|
447
|
+
v.object({
|
|
448
|
+
name: v.string(),
|
|
449
|
+
age: v.number()
|
|
450
|
+
})
|
|
451
|
+
.partial() // All fields optional
|
|
452
|
+
.strict() // No extra fields
|
|
453
|
+
.passthrough() // Allow extra fields
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### Composite Types
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
// Optional
|
|
460
|
+
v.optional(v.string()) // string | undefined
|
|
461
|
+
|
|
462
|
+
// Nullable
|
|
463
|
+
v.nullable(v.string()) // string | null
|
|
464
|
+
|
|
465
|
+
// Nullish
|
|
466
|
+
v.nullish(v.string()) // string | null | undefined
|
|
467
|
+
|
|
468
|
+
// Union
|
|
469
|
+
v.union(v.string(), v.number()) // string | number
|
|
470
|
+
|
|
471
|
+
// Discriminated Union
|
|
472
|
+
v.discriminatedUnion('type',
|
|
473
|
+
v.object({ type: v.literal('a'), a: v.string() }),
|
|
474
|
+
v.object({ type: v.literal('b'), b: v.number() })
|
|
475
|
+
)
|
|
476
|
+
|
|
477
|
+
// Literal
|
|
478
|
+
v.literal('active') // 'active'
|
|
479
|
+
|
|
480
|
+
// Enum
|
|
481
|
+
v.enum('red', 'green', 'blue') // 'red' | 'green' | 'blue'
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
### Type Coercion
|
|
485
|
+
|
|
486
|
+
```typescript
|
|
487
|
+
// Coerce strings from various types
|
|
488
|
+
v.coerce.string().parse(123) // "123"
|
|
489
|
+
v.coerce.string().parse(true) // "true"
|
|
490
|
+
|
|
491
|
+
// Coerce numbers from strings/booleans
|
|
492
|
+
v.coerce.number().parse("123") // 123
|
|
493
|
+
v.coerce.number().parse(true) // 1
|
|
494
|
+
|
|
495
|
+
// Coerce booleans from strings/numbers
|
|
496
|
+
v.coerce.boolean().parse("true") // true
|
|
497
|
+
v.coerce.boolean().parse(1) // true
|
|
498
|
+
|
|
499
|
+
// Coerce BigInt from strings/numbers
|
|
500
|
+
v.coerce.bigint().parse("123") // 123n
|
|
501
|
+
v.coerce.bigint().parse(456) // 456n
|
|
502
|
+
|
|
503
|
+
// Coerce Date from strings/timestamps
|
|
504
|
+
v.coerce.date().parse("2023-01-01") // Date object
|
|
505
|
+
v.coerce.date().parse(1672531200000) // Date object
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### Object Schema Methods
|
|
509
|
+
|
|
510
|
+
```typescript
|
|
511
|
+
const userSchema = v.object({
|
|
512
|
+
name: v.string(),
|
|
513
|
+
age: v.number(),
|
|
514
|
+
email: v.string(),
|
|
515
|
+
role: v.string()
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
// Pick specific fields
|
|
519
|
+
const publicSchema = userSchema.pick('name', 'age');
|
|
520
|
+
// Type: { name: string; age: number }
|
|
521
|
+
|
|
522
|
+
// Omit sensitive fields
|
|
523
|
+
const safeSchema = userSchema.omit('email', 'role');
|
|
524
|
+
// Type: { name: string; age: number }
|
|
525
|
+
|
|
526
|
+
// Extend with new fields
|
|
527
|
+
const extendedSchema = userSchema.extend({
|
|
528
|
+
isActive: v.boolean(),
|
|
529
|
+
lastLogin: v.date()
|
|
530
|
+
});
|
|
531
|
+
// Type: { name: string; age: number; email: string; role: string; isActive: boolean; lastLogin: Date }
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### Advanced Validation Methods
|
|
535
|
+
|
|
536
|
+
```typescript
|
|
537
|
+
// Custom validation with refine()
|
|
538
|
+
const positiveNumber = v.number()
|
|
539
|
+
.refine(n => n > 0, "Number must be positive");
|
|
540
|
+
|
|
541
|
+
// Data transformation with transform()
|
|
542
|
+
const uppercaseString = v.string()
|
|
543
|
+
.transform(s => s.toUpperCase());
|
|
544
|
+
|
|
545
|
+
// Default values for undefined
|
|
546
|
+
const withDefault = v.string().default("fallback");
|
|
547
|
+
withDefault.parse(undefined); // "fallback"
|
|
548
|
+
|
|
549
|
+
// Catch errors and provide fallback
|
|
550
|
+
const withCatch = v.number().catch(-1);
|
|
551
|
+
withCatch.parse("invalid"); // -1
|
|
552
|
+
|
|
553
|
+
// Method chaining
|
|
554
|
+
const complexSchema = v.string()
|
|
555
|
+
.min(3)
|
|
556
|
+
.transform(s => s.trim())
|
|
557
|
+
.refine(s => s.includes('@'), 'Must contain @')
|
|
558
|
+
.default('user@example.com');
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
### Special Validators
|
|
562
|
+
|
|
563
|
+
```typescript
|
|
564
|
+
// JSON validator with optional schema
|
|
565
|
+
v.json() // Any valid JSON
|
|
566
|
+
v.json(v.object({ name: v.string() })) // Typed JSON
|
|
567
|
+
|
|
568
|
+
// Lazy for recursive schemas
|
|
569
|
+
const categorySchema = v.lazy(() =>
|
|
570
|
+
v.object({
|
|
571
|
+
name: v.string(),
|
|
572
|
+
children: v.array(categorySchema).optional()
|
|
573
|
+
})
|
|
574
|
+
);
|
|
575
|
+
|
|
576
|
+
// Custom validator
|
|
577
|
+
v.custom({
|
|
578
|
+
check: (val) => typeof val === 'string' && val.length > 0,
|
|
579
|
+
message: 'Must be a non-empty string'
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
// File validator
|
|
583
|
+
v.file()
|
|
584
|
+
.maxSize(5 * 1024 * 1024) // 5MB
|
|
585
|
+
.type(['image/png', 'image/jpeg']);
|
|
586
|
+
|
|
587
|
+
// Function validator
|
|
588
|
+
v.function()
|
|
589
|
+
.args(v.string(), v.number())
|
|
590
|
+
.returns(v.boolean());
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
### Type Inference
|
|
594
|
+
|
|
595
|
+
```typescript
|
|
596
|
+
import { v } from '@oxog/vld';
|
|
597
|
+
import type { Infer } from '@oxog/vld';
|
|
598
|
+
|
|
599
|
+
const schema = v.object({
|
|
600
|
+
name: v.string(),
|
|
601
|
+
age: v.number()
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
// Automatically infer the type
|
|
605
|
+
type User = Infer<typeof schema>;
|
|
606
|
+
// { name: string; age: number }
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
### Error Formatting Types
|
|
610
|
+
|
|
611
|
+
```typescript
|
|
612
|
+
import { VldError } from '@oxog/vld';
|
|
613
|
+
import type {
|
|
614
|
+
VldIssue, // Individual validation issue
|
|
615
|
+
VldErrorTree, // Nested error structure
|
|
616
|
+
VldFlattenedError // Flattened error structure
|
|
617
|
+
} from '@oxog/vld';
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### Custom Error Messages
|
|
621
|
+
|
|
622
|
+
```typescript
|
|
623
|
+
const schema = v.string().min(8, 'Password must be at least 8 characters');
|
|
624
|
+
|
|
625
|
+
const result = schema.safeParse('short');
|
|
626
|
+
if (!result.success) {
|
|
627
|
+
console.log(result.error.message); // 'Password must be at least 8 characters'
|
|
628
|
+
}
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
## Internationalization (i18n)
|
|
632
|
+
|
|
633
|
+
VLD supports 27+ languages out of the box with comprehensive error messages:
|
|
634
|
+
|
|
635
|
+
```typescript
|
|
636
|
+
import { v, setLocale } from '@oxog/vld';
|
|
637
|
+
|
|
638
|
+
// Default is English
|
|
639
|
+
const schema = v.string().min(5);
|
|
640
|
+
schema.safeParse('Hi'); // Error: "String must be at least 5 characters"
|
|
641
|
+
|
|
642
|
+
// Switch to Turkish
|
|
643
|
+
setLocale('tr');
|
|
644
|
+
schema.safeParse('Hi'); // Error: "Metin en az 5 karakter olmali"
|
|
645
|
+
|
|
646
|
+
// Switch to Spanish
|
|
647
|
+
setLocale('es');
|
|
648
|
+
schema.safeParse('Hi'); // Error: "La cadena debe tener al menos 5 caracteres"
|
|
649
|
+
|
|
650
|
+
// Switch to Japanese
|
|
651
|
+
setLocale('ja');
|
|
652
|
+
schema.safeParse('Hi'); // Error: "..."
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
### Supported Languages
|
|
656
|
+
|
|
657
|
+
#### Base Languages (15):
|
|
658
|
+
- English (`en`) - Turkish (`tr`) - Spanish (`es`) - French (`fr`) - German (`de`)
|
|
659
|
+
- Italian (`it`) - Portuguese (`pt`) - Russian (`ru`) - Japanese (`ja`) - Korean (`ko`)
|
|
660
|
+
- Chinese (`zh`) - Arabic (`ar`) - Hindi (`hi`) - Dutch (`nl`) - Polish (`pl`)
|
|
661
|
+
|
|
662
|
+
#### European Languages (4):
|
|
663
|
+
- Danish (`da`) - Swedish (`sv`) - Norwegian (`no`) - Finnish (`fi`)
|
|
664
|
+
|
|
665
|
+
#### Asian Languages (4):
|
|
666
|
+
- Thai (`th`) - Vietnamese (`vi`) - Indonesian (`id`) - Bengali (`bn`)
|
|
667
|
+
|
|
668
|
+
#### African Languages (2):
|
|
669
|
+
- Swahili (`sw`) - Afrikaans (`af`)
|
|
670
|
+
|
|
671
|
+
#### American Languages (2):
|
|
672
|
+
- Portuguese Brazil (`pt-BR`) - Spanish Mexico (`es-MX`)
|
|
673
|
+
|
|
674
|
+
**Plus 75+ additional languages** supported through comprehensive type definitions with English fallback.
|
|
675
|
+
|
|
676
|
+
## Error Handling & Formatting
|
|
677
|
+
|
|
678
|
+
VLD provides advanced error formatting utilities similar to Zod's error handling system.
|
|
679
|
+
|
|
680
|
+
### Error Formatting Utilities
|
|
681
|
+
|
|
682
|
+
```typescript
|
|
683
|
+
import { v, VldError, treeifyError, prettifyError, flattenError } from '@oxog/vld';
|
|
684
|
+
|
|
685
|
+
const userSchema = v.object({
|
|
686
|
+
username: v.string().min(3),
|
|
687
|
+
favoriteNumbers: v.array(v.number()),
|
|
688
|
+
profile: v.object({
|
|
689
|
+
name: v.string(),
|
|
690
|
+
email: v.string().email()
|
|
691
|
+
})
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
const result = userSchema.safeParse({
|
|
695
|
+
username: 'ab',
|
|
696
|
+
favoriteNumbers: [1, 'two', 3],
|
|
697
|
+
profile: {
|
|
698
|
+
name: '',
|
|
699
|
+
email: 'invalid-email'
|
|
700
|
+
},
|
|
701
|
+
extraField: 'not allowed'
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
if (!result.success) {
|
|
705
|
+
const error = result.error as VldError;
|
|
706
|
+
|
|
707
|
+
// 1. Tree Format - Nested structure for complex UIs
|
|
708
|
+
const tree = treeifyError(error);
|
|
709
|
+
|
|
710
|
+
// 2. Pretty Format - Human-readable console output
|
|
711
|
+
const pretty = prettifyError(error);
|
|
712
|
+
|
|
713
|
+
// 3. Flatten Format - Simple form validation
|
|
714
|
+
const flattened = flattenError(error);
|
|
715
|
+
}
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
### Using Error Formats in Practice
|
|
719
|
+
|
|
720
|
+
#### React Form Validation
|
|
721
|
+
```typescript
|
|
722
|
+
function UserForm() {
|
|
723
|
+
const [errors, setErrors] = useState<VldFlattenedError | null>(null);
|
|
724
|
+
|
|
725
|
+
const handleSubmit = (data: unknown) => {
|
|
726
|
+
const result = userSchema.safeParse(data);
|
|
727
|
+
|
|
728
|
+
if (!result.success) {
|
|
729
|
+
setErrors(flattenError(result.error as VldError));
|
|
730
|
+
} else {
|
|
731
|
+
setErrors(null);
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
return (
|
|
736
|
+
<form onSubmit={handleSubmit}>
|
|
737
|
+
{errors?.formErrors.map(error => (
|
|
738
|
+
<div key={error} className="form-error">{error}</div>
|
|
739
|
+
))}
|
|
740
|
+
|
|
741
|
+
<input name="username" />
|
|
742
|
+
{errors?.fieldErrors.username?.map(error => (
|
|
743
|
+
<div key={error} className="field-error">{error}</div>
|
|
744
|
+
))}
|
|
745
|
+
</form>
|
|
746
|
+
);
|
|
747
|
+
}
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
#### API Error Responses
|
|
751
|
+
```typescript
|
|
752
|
+
app.post('/api/users', (req, res) => {
|
|
753
|
+
const result = userSchema.safeParse(req.body);
|
|
754
|
+
|
|
755
|
+
if (!result.success) {
|
|
756
|
+
const tree = treeifyError(result.error as VldError);
|
|
757
|
+
res.status(400).json({
|
|
758
|
+
error: 'Validation failed',
|
|
759
|
+
details: tree
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
});
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
## Advanced Examples
|
|
766
|
+
|
|
767
|
+
### Complex Validation with New Features
|
|
768
|
+
|
|
769
|
+
```typescript
|
|
770
|
+
const postSchema = v.object({
|
|
771
|
+
id: v.union(v.string().uuid(), v.number()),
|
|
772
|
+
title: v.string().min(5).max(100),
|
|
773
|
+
content: v.string().min(10),
|
|
774
|
+
author: v.object({
|
|
775
|
+
name: v.string(),
|
|
776
|
+
email: v.string().email(),
|
|
777
|
+
age: v.coerce.number(),
|
|
778
|
+
}),
|
|
779
|
+
tags: v.set(v.string()).default(new Set()),
|
|
780
|
+
metadata: v.record(v.any()),
|
|
781
|
+
coordinates: v.tuple(v.number(), v.number()),
|
|
782
|
+
publishedAt: v.date().default(() => new Date()),
|
|
783
|
+
status: v.enum('draft', 'published', 'archived')
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
// Extend with additional fields
|
|
787
|
+
const blogPostSchema = postSchema.extend({
|
|
788
|
+
viewCount: v.bigint().default(0n),
|
|
789
|
+
categories: v.array(v.string()).min(1),
|
|
790
|
+
featured: v.boolean().default(false)
|
|
791
|
+
});
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
### Discriminated Union
|
|
795
|
+
|
|
796
|
+
```typescript
|
|
797
|
+
const eventSchema = v.discriminatedUnion('type',
|
|
798
|
+
v.object({
|
|
799
|
+
type: v.literal('click'),
|
|
800
|
+
x: v.number(),
|
|
801
|
+
y: v.number()
|
|
802
|
+
}),
|
|
803
|
+
v.object({
|
|
804
|
+
type: v.literal('scroll'),
|
|
805
|
+
direction: v.enum('up', 'down'),
|
|
806
|
+
distance: v.number()
|
|
807
|
+
}),
|
|
808
|
+
v.object({
|
|
809
|
+
type: v.literal('keypress'),
|
|
810
|
+
key: v.string(),
|
|
811
|
+
modifiers: v.array(v.enum('ctrl', 'alt', 'shift'))
|
|
812
|
+
})
|
|
813
|
+
);
|
|
814
|
+
|
|
815
|
+
// Type-safe parsing
|
|
816
|
+
const event = eventSchema.parse({
|
|
817
|
+
type: 'click',
|
|
818
|
+
x: 100,
|
|
819
|
+
y: 200
|
|
820
|
+
});
|
|
821
|
+
```
|
|
822
|
+
|
|
823
|
+
### Recursive Schemas
|
|
824
|
+
|
|
825
|
+
```typescript
|
|
826
|
+
const categorySchema: ReturnType<typeof v.lazy> = v.lazy(() =>
|
|
827
|
+
v.object({
|
|
828
|
+
name: v.string(),
|
|
829
|
+
slug: v.string().regex(/^[a-z0-9-]+$/),
|
|
830
|
+
children: v.array(categorySchema).optional()
|
|
831
|
+
})
|
|
832
|
+
);
|
|
833
|
+
|
|
834
|
+
const category = categorySchema.parse({
|
|
835
|
+
name: 'Electronics',
|
|
836
|
+
slug: 'electronics',
|
|
837
|
+
children: [
|
|
838
|
+
{
|
|
839
|
+
name: 'Phones',
|
|
840
|
+
slug: 'phones',
|
|
841
|
+
children: [
|
|
842
|
+
{ name: 'Smartphones', slug: 'smartphones' }
|
|
843
|
+
]
|
|
844
|
+
}
|
|
845
|
+
]
|
|
846
|
+
});
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
### Type-Safe Forms
|
|
850
|
+
|
|
851
|
+
```typescript
|
|
852
|
+
const loginSchema = v.object({
|
|
853
|
+
username: v.string().min(3),
|
|
854
|
+
password: v.string().min(8),
|
|
855
|
+
rememberMe: v.optional(v.boolean())
|
|
856
|
+
});
|
|
857
|
+
|
|
858
|
+
type LoginForm = Infer<typeof loginSchema>;
|
|
859
|
+
|
|
860
|
+
function handleLogin(data: unknown) {
|
|
861
|
+
const result = loginSchema.safeParse(data);
|
|
862
|
+
|
|
863
|
+
if (result.success) {
|
|
864
|
+
const { username, password, rememberMe } = result.data;
|
|
865
|
+
// ... handle login
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
```
|
|
869
|
+
|
|
870
|
+
## Codecs - Bidirectional Transformations
|
|
871
|
+
|
|
872
|
+
VLD introduces **codecs** - powerful bidirectional transformations that can convert data between different representations.
|
|
873
|
+
|
|
874
|
+
### What are Codecs?
|
|
875
|
+
|
|
876
|
+
Codecs enable safe, type-checked conversions between different data formats:
|
|
877
|
+
|
|
878
|
+
```typescript
|
|
879
|
+
import { stringToNumber, jsonCodec, base64ToBytes } from '@oxog/vld';
|
|
880
|
+
|
|
881
|
+
// String to number conversion
|
|
882
|
+
const age = stringToNumber.parse('25'); // 25
|
|
883
|
+
const price = stringToNumber.encode(99.99); // "99.99"
|
|
884
|
+
|
|
885
|
+
// JSON codec
|
|
886
|
+
const userJson = jsonCodec();
|
|
887
|
+
const user = userJson.parse('{"name":"John","age":30}');
|
|
888
|
+
const jsonString = userJson.encode(user);
|
|
889
|
+
|
|
890
|
+
// Binary data
|
|
891
|
+
const bytes = base64ToBytes.parse('SGVsbG8gV29ybGQ=');
|
|
892
|
+
```
|
|
893
|
+
|
|
894
|
+
### Built-in Codecs
|
|
895
|
+
|
|
896
|
+
#### String Conversion Codecs
|
|
897
|
+
```typescript
|
|
898
|
+
import { stringToNumber, stringToInt, stringToBigInt, stringToBoolean } from '@oxog/vld';
|
|
899
|
+
|
|
900
|
+
stringToNumber.parse('42.5'); // 42.5
|
|
901
|
+
stringToInt.parse('42'); // 42
|
|
902
|
+
stringToBigInt.parse('123n'); // 123n
|
|
903
|
+
stringToBoolean.parse('true'); // true
|
|
904
|
+
```
|
|
905
|
+
|
|
906
|
+
#### Date Conversion Codecs
|
|
907
|
+
```typescript
|
|
908
|
+
import { isoDatetimeToDate, epochSecondsToDate, epochMillisToDate } from '@oxog/vld';
|
|
909
|
+
|
|
910
|
+
isoDatetimeToDate.parse('2023-12-25T10:30:00.000Z'); // Date
|
|
911
|
+
epochSecondsToDate.parse(1703505000); // Date
|
|
912
|
+
epochMillisToDate.parse(1703505000000); // Date
|
|
913
|
+
```
|
|
914
|
+
|
|
915
|
+
#### URL Codecs
|
|
916
|
+
```typescript
|
|
917
|
+
import { stringToURL, stringToHttpURL, uriComponent } from '@oxog/vld';
|
|
918
|
+
|
|
919
|
+
stringToURL.parse('https://example.com/path?q=1');
|
|
920
|
+
stringToHttpURL.parse('https://api.example.com');
|
|
921
|
+
uriComponent.parse('Hello World!'); // "Hello%20World!"
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
#### Binary Data Codecs
|
|
925
|
+
```typescript
|
|
926
|
+
import { base64ToBytes, hexToBytes, utf8ToBytes, bytesToUtf8 } from '@oxog/vld';
|
|
927
|
+
|
|
928
|
+
base64ToBytes.parse('SGVsbG8='); // Uint8Array
|
|
929
|
+
hexToBytes.parse('48656c6c6f'); // Uint8Array
|
|
930
|
+
utf8ToBytes.parse('Hello'); // Uint8Array
|
|
931
|
+
bytesToUtf8.parse(new Uint8Array([72, 101, 108, 108, 111])); // "Hello"
|
|
932
|
+
```
|
|
933
|
+
|
|
934
|
+
### Custom Codecs
|
|
935
|
+
|
|
936
|
+
```typescript
|
|
937
|
+
const csvToArray = v.codec(
|
|
938
|
+
v.string(),
|
|
939
|
+
v.array(v.string()),
|
|
940
|
+
{
|
|
941
|
+
decode: (csv: string) => csv.split(',').map(s => s.trim()),
|
|
942
|
+
encode: (arr: string[]) => arr.join(', ')
|
|
943
|
+
}
|
|
944
|
+
);
|
|
945
|
+
|
|
946
|
+
const tags = csvToArray.parse('react, typescript, vld');
|
|
947
|
+
// ["react", "typescript", "vld"]
|
|
948
|
+
|
|
949
|
+
const csvString = csvToArray.encode(['node', 'express', 'api']);
|
|
950
|
+
// "node, express, api"
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
## Plugin System
|
|
954
|
+
|
|
955
|
+
VLD v1.5.0 introduces a powerful plugin system for extending functionality.
|
|
956
|
+
|
|
957
|
+
### Creating a Plugin
|
|
958
|
+
|
|
959
|
+
```typescript
|
|
960
|
+
import { definePlugin, usePlugin, v } from '@oxog/vld';
|
|
961
|
+
|
|
962
|
+
// Define a custom plugin
|
|
963
|
+
const myPlugin = definePlugin({
|
|
964
|
+
name: 'my-plugin',
|
|
965
|
+
version: '1.0.0',
|
|
966
|
+
|
|
967
|
+
// Custom validators
|
|
968
|
+
validators: {
|
|
969
|
+
phoneNumber: () => v.string().regex(/^\+?[1-9]\d{1,14}$/),
|
|
970
|
+
postalCode: () => v.string().regex(/^\d{5}(-\d{4})?$/)
|
|
971
|
+
},
|
|
972
|
+
|
|
973
|
+
// Custom transforms
|
|
974
|
+
transforms: {
|
|
975
|
+
normalizePhone: (phone: string) => phone.replace(/[^\d+]/g, '')
|
|
976
|
+
},
|
|
977
|
+
|
|
978
|
+
// Lifecycle hooks
|
|
979
|
+
install(kernel) {
|
|
980
|
+
console.log('Plugin installed!');
|
|
981
|
+
}
|
|
982
|
+
});
|
|
983
|
+
|
|
984
|
+
// Register the plugin
|
|
985
|
+
usePlugin(myPlugin);
|
|
986
|
+
```
|
|
987
|
+
|
|
988
|
+
### Using Plugin Validators
|
|
989
|
+
|
|
990
|
+
```typescript
|
|
991
|
+
import { createVldKernel, usePlugin } from '@oxog/vld';
|
|
992
|
+
|
|
993
|
+
const kernel = createVldKernel({ debug: true });
|
|
994
|
+
|
|
995
|
+
kernel.use(myPlugin);
|
|
996
|
+
|
|
997
|
+
// Access custom validators
|
|
998
|
+
const phoneSchema = kernel.validator('phoneNumber');
|
|
999
|
+
phoneSchema.parse('+1234567890');
|
|
1000
|
+
```
|
|
1001
|
+
|
|
1002
|
+
## Result Pattern
|
|
1003
|
+
|
|
1004
|
+
VLD v1.5.0 includes a functional Result pattern for error handling.
|
|
1005
|
+
|
|
1006
|
+
### Basic Usage
|
|
1007
|
+
|
|
1008
|
+
```typescript
|
|
1009
|
+
import { Ok, Err, match, map, flatMap, tryCatch } from '@oxog/vld';
|
|
1010
|
+
|
|
1011
|
+
// Create results
|
|
1012
|
+
const success = Ok(42);
|
|
1013
|
+
const failure = Err(new Error('Something went wrong'));
|
|
1014
|
+
|
|
1015
|
+
// Pattern matching
|
|
1016
|
+
const message = match(success, {
|
|
1017
|
+
ok: (value) => `Got: ${value}`,
|
|
1018
|
+
err: (error) => `Error: ${error.message}`
|
|
1019
|
+
});
|
|
1020
|
+
|
|
1021
|
+
// Transform results
|
|
1022
|
+
const doubled = map(success, (n) => n * 2); // Ok(84)
|
|
1023
|
+
|
|
1024
|
+
// Chain operations
|
|
1025
|
+
const result = flatMap(success, (n) =>
|
|
1026
|
+
n > 0 ? Ok(n * 2) : Err(new Error('Must be positive'))
|
|
1027
|
+
);
|
|
1028
|
+
|
|
1029
|
+
// Safe function execution
|
|
1030
|
+
const parsed = tryCatch(() => JSON.parse('{"a":1}'));
|
|
1031
|
+
```
|
|
1032
|
+
|
|
1033
|
+
### With Validation
|
|
1034
|
+
|
|
1035
|
+
```typescript
|
|
1036
|
+
import { v, isOk, isErr, unwrapOr } from '@oxog/vld';
|
|
1037
|
+
|
|
1038
|
+
const schema = v.object({
|
|
1039
|
+
name: v.string(),
|
|
1040
|
+
age: v.number().min(0)
|
|
1041
|
+
});
|
|
1042
|
+
|
|
1043
|
+
const result = schema.safeParse(data);
|
|
1044
|
+
|
|
1045
|
+
if (isOk(result)) {
|
|
1046
|
+
console.log('Valid:', result.data);
|
|
1047
|
+
} else {
|
|
1048
|
+
console.log('Invalid:', result.error);
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
// With default value
|
|
1052
|
+
const user = unwrapOr(result, { name: 'Guest', age: 0 });
|
|
1053
|
+
```
|
|
1054
|
+
|
|
1055
|
+
### Combining Results
|
|
1056
|
+
|
|
1057
|
+
```typescript
|
|
1058
|
+
import { all, fromNullable } from '@oxog/vld';
|
|
1059
|
+
|
|
1060
|
+
// Combine multiple results
|
|
1061
|
+
const results = [Ok(1), Ok(2), Ok(3)];
|
|
1062
|
+
const combined = all(results); // Ok([1, 2, 3])
|
|
1063
|
+
|
|
1064
|
+
// Convert nullable to Result
|
|
1065
|
+
const maybeValue: string | null = getValue();
|
|
1066
|
+
const result = fromNullable(maybeValue, new Error('Value is null'));
|
|
1067
|
+
```
|
|
1068
|
+
|
|
1069
|
+
## CLI Tools
|
|
1070
|
+
|
|
1071
|
+
VLD includes command-line tools for validation and benchmarking.
|
|
1072
|
+
|
|
1073
|
+
### Installation
|
|
1074
|
+
|
|
1075
|
+
```bash
|
|
1076
|
+
npm install -g @oxog/vld
|
|
1077
|
+
# or use npx
|
|
1078
|
+
npx vld --help
|
|
1079
|
+
```
|
|
1080
|
+
|
|
1081
|
+
### Commands
|
|
1082
|
+
|
|
1083
|
+
```bash
|
|
1084
|
+
# Show help
|
|
1085
|
+
vld --help
|
|
1086
|
+
|
|
1087
|
+
# Validate data
|
|
1088
|
+
vld validate schema.json data.json
|
|
1089
|
+
|
|
1090
|
+
# Run benchmarks
|
|
1091
|
+
vld benchmark
|
|
1092
|
+
|
|
1093
|
+
# Show version
|
|
1094
|
+
vld --version
|
|
1095
|
+
```
|
|
1096
|
+
|
|
1097
|
+
### Programmatic CLI
|
|
1098
|
+
|
|
1099
|
+
```typescript
|
|
1100
|
+
import { createCli, vldCli } from '@oxog/vld/cli';
|
|
1101
|
+
|
|
1102
|
+
// Use the built-in CLI
|
|
1103
|
+
vldCli.run(process.argv.slice(2));
|
|
1104
|
+
|
|
1105
|
+
// Or create a custom CLI
|
|
1106
|
+
const cli = createCli('my-app', '1.0.0', 'My validation app')
|
|
1107
|
+
.command({
|
|
1108
|
+
name: 'validate',
|
|
1109
|
+
description: 'Validate data',
|
|
1110
|
+
action: async (args, options) => {
|
|
1111
|
+
// Custom validation logic
|
|
1112
|
+
}
|
|
1113
|
+
});
|
|
1114
|
+
|
|
1115
|
+
cli.run(process.argv.slice(2));
|
|
1116
|
+
```
|
|
1117
|
+
|
|
1118
|
+
## Logger & Colored Output
|
|
1119
|
+
|
|
1120
|
+
VLD includes a logging system and colored terminal output.
|
|
1121
|
+
|
|
1122
|
+
### Logger
|
|
1123
|
+
|
|
1124
|
+
```typescript
|
|
1125
|
+
import { createLogger, setLogLevel, enableDebug } from '@oxog/vld';
|
|
1126
|
+
|
|
1127
|
+
// Create a logger
|
|
1128
|
+
const logger = createLogger({ prefix: 'VLD' });
|
|
1129
|
+
|
|
1130
|
+
logger.info('Processing...');
|
|
1131
|
+
logger.warn('Deprecated feature');
|
|
1132
|
+
logger.error('Validation failed');
|
|
1133
|
+
logger.debug('Debug info');
|
|
1134
|
+
|
|
1135
|
+
// Set log level globally
|
|
1136
|
+
setLogLevel('debug');
|
|
1137
|
+
|
|
1138
|
+
// Enable debug mode
|
|
1139
|
+
enableDebug();
|
|
1140
|
+
```
|
|
1141
|
+
|
|
1142
|
+
### Colored Output (Pigment)
|
|
1143
|
+
|
|
1144
|
+
```typescript
|
|
1145
|
+
import { pigment, red, green, blue, bold, dim } from '@oxog/vld';
|
|
1146
|
+
|
|
1147
|
+
console.log(red('Error!'));
|
|
1148
|
+
console.log(green('Success!'));
|
|
1149
|
+
console.log(bold(blue('Important')));
|
|
1150
|
+
console.log(dim('Less important'));
|
|
1151
|
+
|
|
1152
|
+
// Or use the pigment object
|
|
1153
|
+
console.log(pigment.red('Error!'));
|
|
1154
|
+
console.log(pigment.bold(pigment.green('Success!')));
|
|
1155
|
+
```
|
|
1156
|
+
|
|
1157
|
+
## VLD vs. Zod
|
|
1158
|
+
|
|
1159
|
+
VLD is designed as a compelling alternative to Zod, maintaining an audited compatibility baseline while delivering additional platform features.
|
|
1160
|
+
|
|
1161
|
+
### Feature Comparison
|
|
1162
|
+
|
|
1163
|
+
| Feature | VLD | Zod |
|
|
1164
|
+
| ----------------------- | ---------------------------------- | ------------------------------------ |
|
|
1165
|
+
| **Performance** | **Release-gated faster runtime, startup, and memory paths** | Baseline |
|
|
1166
|
+
| **Memory Usage** | **~5x less** overall | Baseline |
|
|
1167
|
+
| **Internationalization**| **Built-in 27+ locales with lazy loading** | Built-in locales |
|
|
1168
|
+
| **Dependencies** | **Zero runtime dependencies** | Zero runtime dependencies |
|
|
1169
|
+
| **Bundle Size** | Smaller | Larger |
|
|
1170
|
+
| **API** | Zod 4.4.3 compatibility gate + extensions | Standard Zod API |
|
|
1171
|
+
| **Plugin System** | **Built-in** | Not available |
|
|
1172
|
+
| **Result Pattern** | **Built-in** | Not available |
|
|
1173
|
+
| **CLI Tools** | **Built-in** | Not available |
|
|
1174
|
+
| **Codecs** | Built-in system plus reusable presets | Built-in primitives; recipes documented |
|
|
1175
|
+
| **Type Inference** | Excellent | Excellent |
|
|
1176
|
+
|
|
1177
|
+
### Seamless Migration from Zod
|
|
1178
|
+
|
|
1179
|
+
```javascript
|
|
1180
|
+
// Before (Zod)
|
|
1181
|
+
import { z } from 'zod';
|
|
1182
|
+
const schema = z.string().email();
|
|
1183
|
+
|
|
1184
|
+
// After (VLD) - Exact same syntax!
|
|
1185
|
+
import { v } from '@oxog/vld';
|
|
1186
|
+
const schema = v.string().email();
|
|
1187
|
+
```
|
|
1188
|
+
|
|
1189
|
+
### Drop-in Package Subpaths
|
|
1190
|
+
|
|
1191
|
+
VLD also exposes Zod-compatible package subpaths so applications that import Zod 4 entry points can migrate by changing the package name:
|
|
1192
|
+
|
|
1193
|
+
```typescript
|
|
1194
|
+
// Before
|
|
1195
|
+
import { z } from 'zod';
|
|
1196
|
+
import * as core from 'zod/v4/core';
|
|
1197
|
+
import * as mini from 'zod/v4-mini';
|
|
1198
|
+
import * as locales from 'zod/v4/locales';
|
|
1199
|
+
|
|
1200
|
+
// After
|
|
1201
|
+
import { z } from '@oxog/vld';
|
|
1202
|
+
import * as core from '@oxog/vld/v4/core';
|
|
1203
|
+
import * as mini from '@oxog/vld/v4-mini';
|
|
1204
|
+
import * as locales from '@oxog/vld/v4/locales';
|
|
1205
|
+
```
|
|
1206
|
+
|
|
1207
|
+
Release checks enforce zero missing exports and zero `typeof` mismatches for `zod/v4`, `zod/v4-mini`, `zod/v4/mini`, `zod/v4/core`, and `zod/v4/locales` against the installed latest Zod.
|
|
1208
|
+
|
|
1209
|
+
### Real App Drop-in Verification
|
|
1210
|
+
|
|
1211
|
+
`npm run verify:drop-in` creates two temporary TypeScript applications from the same fixture:
|
|
1212
|
+
|
|
1213
|
+
- One imports and runs against real `zod`.
|
|
1214
|
+
- One imports and runs against the locally built `@oxog/vld` package.
|
|
1215
|
+
- The fixture exercises root APIs, `v4`, `v4-mini`, `v4/core`, `v4/locales`, parsing, error formatting, JSON Schema output, mini helpers, and core factories.
|
|
1216
|
+
- The normalized runtime outputs must match exactly.
|
|
1217
|
+
|
|
1218
|
+
## Benchmarks
|
|
1219
|
+
|
|
1220
|
+
### Performance Results
|
|
1221
|
+
|
|
1222
|
+
Median of 11 samples per case against Zod 4.4.3, the latest stable release at the time of measurement. The release gate also runs focused runtime, startup, memory, package, install, security, Zod parity, and real drop-in app checks before publishing.
|
|
1223
|
+
|
|
1224
|
+
| Test Case | VLD Median Performance | Improvement |
|
|
1225
|
+
|-----------|----------------|-------------|
|
|
1226
|
+
| Simple String | 719.2M ops/sec | **3.40x faster** |
|
|
1227
|
+
| Email Validation | 22.1M ops/sec | **2.87x faster** |
|
|
1228
|
+
| Top-level Email Format | 22.8M ops/sec | **3.66x faster** |
|
|
1229
|
+
| StringBool Validation | 32.7M ops/sec | **3.44x faster** |
|
|
1230
|
+
| Number Validation | 226.2M ops/sec | **27.62x faster** |
|
|
1231
|
+
| Simple Object | 37.7M ops/sec | **1.40x faster** |
|
|
1232
|
+
| Complex Object | 2.3M ops/sec | **1.02x faster** |
|
|
1233
|
+
| Array Validation | 39.8M ops/sec | **6.74x faster** |
|
|
1234
|
+
| Union Types | 38.1M ops/sec | **4.10x faster** |
|
|
1235
|
+
| Optional Values | 236.9M ops/sec | **7.57x faster** |
|
|
1236
|
+
| Nullable Values | 224.7M ops/sec | **10.71x faster** |
|
|
1237
|
+
| Nullish Values | 228.4M ops/sec | **52.92x faster** |
|
|
1238
|
+
| Default Values | 207.8M ops/sec | **9.71x faster** |
|
|
1239
|
+
| Catch Values | 232.1M ops/sec | **46.58x faster** |
|
|
1240
|
+
| SafeParse | 162.0M ops/sec | **1.80x faster** |
|
|
1241
|
+
| Type Coercion | 204.5M ops/sec | **8.72x faster** |
|
|
1242
|
+
| Enum Validation | 180.3M ops/sec | **1.32x faster** |
|
|
1243
|
+
| Discriminated Union | 19.2M ops/sec | **1.79x faster** |
|
|
1244
|
+
| Tuple Validation | 50.0M ops/sec | **7.99x faster** |
|
|
1245
|
+
| Record Validation | 10.7M ops/sec | **5.63x faster** |
|
|
1246
|
+
| Set Validation | 18.9M ops/sec | **1.84x faster** |
|
|
1247
|
+
| Map Validation | 14.8M ops/sec | **2.37x faster** |
|
|
1248
|
+
| BigInt Validation | 164.8M ops/sec | **14.88x faster** |
|
|
1249
|
+
| Date Validation | 227.2M ops/sec | **2.57x faster** |
|
|
1250
|
+
| Symbol Validation | 230.0M ops/sec | **1.01x faster** |
|
|
1251
|
+
| Any Validation | 232.5M ops/sec | **1.01x faster** |
|
|
1252
|
+
| Unknown Validation | 234.9M ops/sec | **1.04x faster** |
|
|
1253
|
+
| Function Validation | 233.6M ops/sec | **3.52x faster** |
|
|
1254
|
+
| Template Literal Validation | 39.3M ops/sec | **1.15x faster** |
|
|
1255
|
+
| Promise Async Validation | 6.3M ops/sec | **1.38x faster** |
|
|
1256
|
+
|
|
1257
|
+
**VLD won 30/30 snapshot tests. Release checks additionally enforce runtime, startup, memory, Zod subpath parity, and real drop-in app guard thresholds against Zod.**
|
|
1258
|
+
|
|
1259
|
+
### Run Benchmarks
|
|
1260
|
+
|
|
1261
|
+
```bash
|
|
1262
|
+
# Quick performance comparison
|
|
1263
|
+
npm run benchmark
|
|
1264
|
+
|
|
1265
|
+
# Median-based stable comparison
|
|
1266
|
+
npm run benchmark:stable
|
|
1267
|
+
|
|
1268
|
+
# Fast CI-friendly performance regression guard
|
|
1269
|
+
npm run benchmark:guard
|
|
1270
|
+
|
|
1271
|
+
# Full release gate: lint, source and published types, tests, exports, package and install checks, security audit, Zod parity, real drop-in app verification, and performance guards
|
|
1272
|
+
npm run release:check
|
|
1273
|
+
|
|
1274
|
+
# Memory usage comparison
|
|
1275
|
+
npm run benchmark:memory
|
|
1276
|
+
|
|
1277
|
+
# Startup time comparison
|
|
1278
|
+
npm run benchmark:startup
|
|
1279
|
+
|
|
1280
|
+
# Run all benchmarks
|
|
1281
|
+
npm run benchmark:all
|
|
1282
|
+
```
|
|
1283
|
+
|
|
1284
|
+
## Contributing
|
|
1285
|
+
|
|
1286
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
1287
|
+
|
|
1288
|
+
## Links
|
|
1289
|
+
|
|
1290
|
+
- [Documentation](https://vld.oxog.dev)
|
|
1291
|
+
- [NPM Package](https://www.npmjs.com/package/@oxog/vld)
|
|
1292
|
+
- [GitHub Repository](https://github.com/ersinkoc/vld)
|
|
1293
|
+
|
|
1294
|
+
---
|
|
1295
|
+
|
|
1296
|
+
Made with Love by [Ersin KOC](https://github.com/ersinkoc)
|