A lightweight, zero-dependency validation engine for dynamic strings and reserved identifiers in TypeScript. Perfect for validating routes, usernames, and custom identifiers with built-in security checks.
- π Zero Dependencies - No external libraries, just pure TypeScript
- π¦ Tree Shakeable - Only bundle what you use
- π Security First - Blocks reserved system words and impersonation terms
- π― Type Safe - Full TypeScript support with strict typing
- β‘ Fast - Optimized for performance with minimal overhead
- π οΈ Customizable - Extend with your own reserved lists and validation rules
- π± ESM & CommonJS - Supports both module systems
npm install @fantasy42/valloor
yarn add @fantasy42/valloor
pnpm add @fantasy42/valloimport { vallo } from '@fantasy42/vallo';
// Validate a route
if (vallo.route('my-profile')) {
console.log('Route is available!');
} else {
console.log('Route is reserved or invalid');
}
// Validate a username
if (vallo.username('john.doe')) {
console.log('Username is valid!');
}Validates route segments against reserved system routes and brand terms.
vallo.route('admin'); // false - reserved
vallo.route('my-route'); // true - validValidates usernames with alphanumeric characters, dots, and underscores.
vallo.username('root'); // false - reserved
vallo.username('user-name'); // false - dashes not allowed
vallo.username('username123'); // trueCreate your own validators with custom rules by extending the core validators:
import { createUsernameValidator } from '@fantasy42/vallo';
// Custom username validator for a social platform
const socialUsernameValidator = createUsernameValidator({
extensions: ['blocked-name-1', 'blocked-name-2'],
caseSensitive: false, // Default: case-insensitive
maxLength: 25,
minLength: 3,
pattern: /^[a-zA-Z0-9._-]+$/ // Alphanumeric, dots, underscores, dashes
});
// Usage examples
console.log(socialUsernameValidator('john.doe')); // true
console.log(socialUsernameValidator('blocked-name-1')); // false (in extensions)
console.log(socialUsernameValidator('user_name')); // true
console.log(socialUsernameValidator('user@name')); // false (special chars not allowed)For advanced use cases, import from the extended module:
import { createExtendedRouteValidator } from '@fantasy42/vallo/extended';Important: Always validate and sanitize user inputs before processing. Use libraries like Zod for robust input validation to prevent injection attacks and ensure data integrity.
import express from 'express';
import { z } from 'zod';
import { vallo } from '@fantasy42/vallo';
const app = express();
app.use(express.json());
// Input validation schema
const routeSchema = z
.string()
.min(1)
.max(50)
.trim()
app.get('/:route', (req, res) => {
// Validate input first
const validation = routeSchema.safeParse(req.params.route);
if (!validation.success) {
return res.status(400).json({ error: 'Invalid route format' });
}
const route = validation.data;
// Then check against reserved words
if (!vallo.route(route)) {
return res.status(400).json({ error: 'Route is reserved or invalid' });
}
res.json({ message: `Route ${route} is valid and available` });
});import React, { useState } from 'react';
import { z } from 'zod';
import { vallo } from '@fantasy42/vallo';
// Input validation schema
const usernameSchema = z
.string()
.min(3)
.max(30)
.trim()
function UsernameForm() {
const [username, setUsername] = useState('');
const [error, setError] = useState('');
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// Validate input format first
const validation = usernameSchema.safeParse(username);
if (!validation.success) {
setError(validation.error.errors[0].message);
return;
}
const cleanUsername = validation.data;
// Then check against reserved words and patterns
if (!vallo.username(cleanUsername)) {
setError('Username is reserved or invalid.');
return;
}
// Submit form
console.log('Username is valid:', cleanUsername);
setError('');
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
placeholder="Enter username"
/>
{error && <p style={{ color: 'red' }}>{error}</p>}
<button type="submit">Submit</button>
</form>
);
}All validators support the following options:
| Option | Type | Default | Description |
|---|---|---|---|
extensions |
ReservedList |
undefined |
Additional reserved words to block |
caseSensitive |
boolean |
false |
Whether validation is case-sensitive |
maxLength |
number |
50 |
Maximum allowed length |
minLength |
number |
3 |
Minimum allowed length |
pattern |
RegExp | null |
null |
Custom regex pattern to match against |
Vallo is written in TypeScript and provides full type safety:
import type { Validator, ValidatorOptions } from '@fantasy42/vallo';
// Types are exported for advanced usage
const options: ValidatorOptions = {
extensions: ['forbidden'],
caseSensitive: true
};
const validator: Validator = createRouteValidator(options);We welcome contributions!
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with β€οΈ using TypeScript
- Inspired by the need for secure, type-safe validation in modern web apps
Made with β€οΈ by Fantasy