@validup/express-validator
v0.3.3
Published
A validup integration for express-validator.
Readme
@validup/express-validator 🛡️
A validup integration for express-validator — turn any ValidationChain into a validup Validator.
Wrap any express-validator ValidationChain as a validup Validator, mount it on a Container path, and let validup orchestrate path expansion, group filtering, and structured error reporting while express-validator drives the rule chain.
🚧 Work in Progress
Validup is currently under active development and is not yet ready for production.
Table of Contents
Installation
npm install @validup/express-validator validup express-validator --save| Peer dependency | Supported versions |
|---------------------|--------------------|
| express-validator | ^7.3.1 |
Quick Start
import { Container, ValidupError } from 'validup';
import { createValidationChain, createValidator } from '@validup/express-validator';
const container = new Container<{ tags: string[] }>();
container.mount(
'tags',
createValidator(() => {
const chain = createValidationChain();
return chain.isArray({ min: 1, max: 10 });
}),
);
const valid = await container.run({ tags: ['typescript', 'validation'] });
// valid is { tags: ['typescript', 'validation'] }createValidationChain() returns an express-validator body() chain — pre-bound to read the value validup hands the validator. Build your rules on top of it like any other express-validator chain.
Real-World Pattern
The dominant pattern is to subclass Container<T> and register chains inside initialize():
import { Container } from 'validup';
import { createValidationChain, createValidator } from '@validup/express-validator';
type User = {
name: string;
age: number;
password: string;
};
class UserValidator extends Container<User> {
protected override initialize() {
super.initialize();
this.mount('name', createValidator(() => {
const chain = createValidationChain();
return chain
.exists()
.notEmpty()
.isLength({ min: 3, max: 128 });
}));
this.mount('age', createValidator(() => {
const chain = createValidationChain();
return chain
.isNumeric()
.optional({ values: 'null' });
}));
this.mount('password', createValidator(() => {
const chain = createValidationChain();
return chain.isLength({ min: 3, max: 128 });
}));
}
}
const valid = await new UserValidator().run(input);Per-Context Chains
Pass a function to createValidator to build the chain from the validator context — for example, to switch rules based on the active group:
import { createValidationChain, createValidator } from '@validup/express-validator';
const tagsValidator = createValidator((ctx) => {
const chain = createValidationChain().isArray({ min: 1, max: 10 });
if (ctx.group === 'optional') {
return chain.optional({ values: 'null' });
}
return chain;
});
container.mount('tags', { group: 'required' }, tagsValidator);
container.mount('tags', { group: 'optional' }, tagsValidator);
await container.run({ tags: null }, { group: 'optional' }); // ✅ tags === null
await container.run({ tags: null }, { group: 'required' }); // ❌ throws ValidupErrorError Mapping
When the chain reports validation errors, the adapter converts each express-validator ValidationError into a validup IssueItem with path, message, and received fields. The adapter then throws a ValidupError containing those issues. All three error types are mapped:
field— the failing field name becomes the issuepath.alternative— nested errors are flattened into the issue list.alternative_grouped— nested error groups are recursively flattened.
try {
await container.run({ tags: [] });
} catch (error) {
if (error instanceof ValidupError) {
error.issues.forEach((issue) => {
console.log(issue.path, issue.message, issue.received);
});
}
}When the chain succeeds without transforming the value, the adapter returns the sanitized field value from express-validator's context — so chains like .toInt() or .trim() carry through to the validup output.
API Reference
| Export | Description |
|------------------------------|------------------------------------------------------------------------------|
| createValidator(input) | Wrap a ContextRunner (or (ctx) => ContextRunner) as a validup Validator. |
| createValidationChain() | Build a fresh express-validator body() chain pre-bound for use with the adapter. |
| buildIssuesForErrors(es) | Convert an array of express-validator ValidationErrors into validup Issues. |
function createValidator<C = unknown>(
input: ContextRunner | ((ctx: ValidatorContext<C>) => ContextRunner),
): Validator<C>;
function createValidationChain(): ValidationChain;License
Made with 💚
Published under Apache 2.0 License.
