Package Exports
- @ooneex/validation
- @ooneex/validation/constraints
- @ooneex/validation/package.json
Readme
@ooneex/validation
Type-safe validation framework powered by ArkType -- define schemas with built-in constraints, custom rules, and JSON Schema generation.
Features
✅ ArkType Powered - Full re-export of ArkType (type, scope, union, intersection) for schema definition
✅ 16 Built-in Constraints - Pre-built validators for email, URL, port, hostname, locale, currency, country code, hex color, YouTube URL, names, and more
✅ Abstract Validation Class - Extend Validation to create custom validators with getConstraint and getErrorMessage
✅ JSON Schema Conversion - jsonSchemaToTypeString utility to convert JSON Schema to readable type strings
✅ Inline Assertions - Assert utility for quick inline validation checks
✅ Custom Error Messages - Define user-friendly error messages for validation failures
✅ Type-Safe - Full TypeScript support with AssertType, IAssert, and ValidationResultType types
Installation
bun add @ooneex/validationUsage
Basic Validation with ArkType
import { type } from '@ooneex/validation';
// Define a schema
const UserSchema = type({
name: 'string',
email: 'string.email',
age: 'number >= 0'
});
// Validate data
const result = UserSchema({ name: 'John', email: 'john@example.com', age: 25 });
if (result instanceof type.errors) {
console.error('Validation failed:', result.summary);
} else {
console.log('Valid user:', result);
}Using the Validation Class
import { Validation, type } from '@ooneex/validation';
import type { AssertType, ValidationResultType } from '@ooneex/validation';
class EmailValidator extends Validation {
public getConstraint(): AssertType {
return type('string.email');
}
public getErrorMessage(): string | null {
return 'Please provide a valid email address';
}
}
const validator = new EmailValidator();
const result = validator.validate('not-an-email');
if (!result.isValid) {
console.error(result.message); // "Please provide a valid email address"
}Using Built-in Constraints
import {
AssertEmail,
AssertPort,
AssertHostname,
AssertAppEnv
} from '@ooneex/validation/constraints';
// Validate email
const emailValidator = new AssertEmail();
const emailResult = emailValidator.validate('user@example.com');
console.log(emailResult.isValid); // true
// Validate port number
const portValidator = new AssertPort();
const portResult = portValidator.validate(3000);
console.log(portResult.isValid); // true
// Validate hostname
const hostnameValidator = new AssertHostname();
const hostnameResult = hostnameValidator.validate('0.0.0.0');
console.log(hostnameResult.isValid); // trueRoute Validation
import { Route } from '@ooneex/routing';
import { type } from '@ooneex/validation';
import type { IController, ContextType } from '@ooneex/controller';
const CreateUserPayload = type({
name: 'string > 0',
email: 'string.email',
password: 'string >= 8'
});
const UserIdParam = type({
id: 'string.uuid'
});
@Route.http({
name: 'api.users.create',
path: '/api/users',
method: 'POST',
payload: CreateUserPayload,
description: 'Create a new user'
})
class UserCreateController implements IController {
public async index(context: ContextType): Promise<IResponse> {
// Payload is already validated at this point
const { name, email, password } = context.payload;
return context.response.json({
user: { name, email }
});
}
}API Reference
Re-exports from ArkType
This package re-exports all types and utilities from ArkType:
import { type, scope, union, intersection } from '@ooneex/validation';See the ArkType documentation for full API reference.
Classes
Validation
Abstract base class for creating custom validators.
Methods:
abstract getConstraint(): AssertType
Returns the ArkType schema to validate against.
abstract getErrorMessage(): string | null
Returns a custom error message or null to use the default ArkType error.
validate(data: unknown, constraint?: AssertType): ValidationResultType
Validates data against the constraint.
Parameters:
data- The data to validateconstraint- Optional constraint override
Returns: Validation result object
Example:
class PositiveNumberValidator extends Validation {
public getConstraint(): AssertType {
return type('number > 0');
}
public getErrorMessage(): string | null {
return 'Value must be a positive number';
}
}
const validator = new PositiveNumberValidator();
const result = validator.validate(42);
console.log(result); // { isValid: true }Functions
Assert
Utility for quick inline assertions.
import { Assert } from '@ooneex/validation';
const isValid = Assert(value, type('string.email'));jsonSchemaToTypeString(schema: object): string
Converts a JSON Schema to a human-readable type string.
Parameters:
schema- JSON Schema object
Returns: String representation of the type
Example:
import { type, jsonSchemaToTypeString } from '@ooneex/validation';
const UserSchema = type({
name: 'string',
age: 'number'
});
const jsonSchema = UserSchema.toJsonSchema();
const typeString = jsonSchemaToTypeString(jsonSchema);
console.log(typeString); // "{ name: string, age: number }"Types
AssertType
Type alias for ArkType's Type definition.
import type { AssertType } from '@ooneex/validation';
const schema: AssertType = type('string');IAssert
Interface for validator classes.
interface IAssert {
getConstraint: () => AssertType;
getErrorMessage: () => string | null;
validate: (data: unknown, constraint?: AssertType) => ValidationResultType;
}ValidationResultType
Result object returned from validation.
type ValidationResultType = {
isValid: boolean;
message?: string;
};ValidationClassType
Type for validator class constructors.
type ValidationClassType = new (...args: any[]) => IAssert;Built-in Constraints
Import from @ooneex/validation/constraints:
| Constraint | Description |
|---|---|
AssertEmail |
Validates email addresses |
AssertPort |
Validates port numbers (1-65535) |
AssertHostname |
Validates hostnames and IP addresses |
AssertAppEnv |
Validates application environment strings |
Advanced Usage
Creating Complex Schemas
import { type, scope } from '@ooneex/validation';
// Define a scope for related types
const $ = scope({
user: {
id: 'string.uuid',
email: 'string.email',
profile: 'profile'
},
profile: {
firstName: 'string > 0',
lastName: 'string > 0',
age: 'number.integer >= 0',
bio: 'string | null'
}
}).export();
// Use the scoped types
const user = $.user({
id: '123e4567-e89b-12d3-a456-426614174000',
email: 'john@example.com',
profile: {
firstName: 'John',
lastName: 'Doe',
age: 30,
bio: null
}
});Union Types
import { type } from '@ooneex/validation';
const StatusSchema = type("'pending' | 'active' | 'inactive'");
const result = StatusSchema('active');
console.log(result); // "active"Array Validation
import { type } from '@ooneex/validation';
const TagsSchema = type('string[]');
const NumbersSchema = type('number[] >= 1'); // Array with at least 1 element
const tags = TagsSchema(['typescript', 'validation']);
const numbers = NumbersSchema([1, 2, 3]);Optional Fields
import { type } from '@ooneex/validation';
const UserSchema = type({
name: 'string',
email: 'string.email',
'phone?': 'string', // Optional field
'age?': 'number >= 0'
});
const user = UserSchema({
name: 'John',
email: 'john@example.com'
// phone and age are optional
});Custom Validator with Translation
import { Validation, type } from '@ooneex/validation';
import type { LocaleType } from '@ooneex/translation';
class LocalizedEmailValidator extends Validation {
constructor(private readonly locale: LocaleType = 'en') {
super();
}
public getConstraint(): AssertType {
return type('string.email');
}
public getErrorMessage(): string | null {
const messages: Record<string, string> = {
en: 'Please enter a valid email address',
fr: 'Veuillez entrer une adresse email valide',
es: 'Por favor ingrese una dirección de correo válida'
};
return messages[this.locale] || messages.en;
}
}Converting to JSON Schema
import { type } from '@ooneex/validation';
const ProductSchema = type({
name: 'string',
price: 'number > 0',
category: "'electronics' | 'clothing' | 'food'"
});
// Convert to JSON Schema for OpenAPI documentation
const jsonSchema = ProductSchema.toJsonSchema();
console.log(JSON.stringify(jsonSchema, null, 2));Integration with AI Output Validation
import { OpenAi } from '@ooneex/ai';
import { type } from '@ooneex/validation';
const ai = new OpenAi();
const ProductSchema = type({
name: 'string',
description: 'string',
price: 'number > 0'
});
const product = await ai.run('Generate a product', {
output: ProductSchema
});
// Product is guaranteed to match the schema
console.log(product.name, product.price);License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Development Setup
- Clone the repository
- Install dependencies:
bun install - Run tests:
bun run test - Build the project:
bun run build
Guidelines
- Write tests for new features
- Follow the existing code style
- Update documentation for API changes
- Ensure all tests pass before submitting PR
Made with ❤️ by the Ooneex team