npm install @ferrow/input-validatorA rule-string validation engine for TypeScript/Node — Laravel-style rule
strings ("required|number|min:18|max:120"), nested object schemas, array
item validation, custom rule registration, and full error collection (not
just the first failure) with dot/bracket field paths. Zero runtime
dependencies.
Copy src/index.ts into your project, or build this repo (npm run build)
and depend on the compiled dist/.
import{validate}from'input-validator';constschema={name: 'required|string|length:2,50',email: 'required|email',age: 'number|min:18|max:120',};const{ valid, errors }=validate(schema,{name: 'A',email: 'bad',age: 15});// valid: false// errors: [// { path: 'name', message: 'name must have length >= 2' },// { path: 'email', message: 'email must be a valid email' },// { path: 'age', message: 'age must be >= 18' },// ]Or use the class form to reuse one schema:
import{InputValidator}from'input-validator';constvalidator=newInputValidator(schema);validator.validate(payload);required · string · number · boolean · email ·
min:N (numeric >= N, or string length >= N) ·
max:N (numeric <= N, or string length <= N) ·
length:min,max (string length range) ·
in:a,b,c (must equal one of the comma-separated values) ·
regex:pattern (tested with new RegExp(pattern))
A field without required is skipped entirely (no errors) when its value
is undefined, null, or ''.
constschema={address: {schema: {city: 'required|string',zip: 'regex:^[0-9]{5}$'}},tags: {array: 'string'},// array of primitivesfriends: {arraySchema: {name: 'required|string'}},// array of objects};Error paths reflect nesting: address.city, friends[0].name.
import{registerRule}from'input-validator';registerRule('even',(value)=>(typeofvalue==='number'&&value%2===0 ? null : 'must be even'));validate({n: 'number|even'},{n: 3});// { valid: false, errors: [{ path: 'n', message: 'n must be even' }] }registerRule is global — it adds the rule name for every schema in the
process, matching how the built-in rules are registered.
- Rule arguments are always plain strings (
min:18,in:a,b,c) — no cross-field rules (e.g. "must equal another field") are built in; write a custom rule with access to the full record via the thirddataargument passed toRuleFnif you need that. regex:rule arguments cannot contain a literal|(the rule-string delimiter) or:beyond the first — for complex patterns, register a custom rule instead of using theregex:shorthand.- Not a coercion/transform library — it validates the value as given, it doesn't parse strings into numbers/booleans for you first.
Sponsored by Ferrow
Part of the ferrow-toolkit collection · Sponsored by Ferrow