@voidbase/foundation
v1.1.1
Published
A comprehensive utility library for Vue and Nuxt projects. Includes validation utilities, form/input components, localization support, and more. Make starting new projects easier with production-ready tools.
Downloads
372
Maintainers
Readme
Void Foundation
A comprehensive utility library for Vue and Nuxt projects. Make starting new projects easier with production-ready validation utilities, form/input components, and essential tools.
What's Included
Current Features
✅ Validation Utilities - Composable validation with 30+ rules
✅ HTTP Client - Universal HTTP client with interceptors, retry, and auth
✅ Type Safety - 100% TypeScript with zero any types
✅ Localization - Built-in support for 5 languages (en, es, fr, ar, ckb)
✅ Extensible - Custom validators, transforms, and locales
✅ Zero Dependencies - Lightweight and fast
✅ Well Tested - 70+ passing tests
Coming Soon
🚧 Form Components - Ready-to-use form and input components for Vue/Nuxt
🚧 Additional Utilities - More helpers to accelerate project development
Installation
# Using bun
bun add @voidbase/foundation
# Using npm
npm install @voidbase/foundationQuick Start
import { validate, string, number } from '@voidbase/foundation';
const schema = {
username: string('Username').required().min(3).max(20),
email: string('Email').required().email().lowercase(),
age: number('Age').required().min(18).integer(),
};
const result = validate({
username: 'john_doe',
email: '[email protected]',
age: 25,
}, schema);
if (result.valid) {
console.log('✓ Valid:', result.data);
// { username: 'john_doe', email: '[email protected]', age: 25 }
} else {
result.errors.forEach(err => {
console.log(`✗ ${err.field}: ${err.message}`);
});
}Why Void Foundation?
Composable & Intuitive
// ✅ Void Foundation - Fluent and readable
const email = string('Email')
.required()
.email()
.lowercase()
.trim();
// ❌ Traditional approach - Verbose object syntax
const email = {
type: 'string',
label: 'Email',
required: true,
isEmail: true,
lowercase: true,
trim: true,
};Built-in Localization
import { setLocale } from '@voidbase/foundation';
// Switch to Spanish
setLocale('es');
// Error: "Email es requerido"
// Switch to French
setLocale('fr');
// Error: "Email est requis"
// Or use inline
validate(data, schema, { locale: 'es' });Type-Safe by Design
interface UserData {
name: string;
email: string;
age: number;
}
const result: ValidationResult<UserData> = validate(data, schema);
if (result.valid) {
// result.data is fully typed as UserData
const user: UserData = result.data;
}Schema Builders
String Validation
import { string } from '@voidbase/foundation';
string('Email').required().email().lowercase();
string('Username').required().min(3).max(20).pattern(/^[a-zA-Z0-9_]+$/);
string('Password').required().min(8).strongPassword();
string('Website').url().trim();Number Validation
import { number } from '@voidbase/foundation';
number('Age').required().min(18).max(120).integer();
number('Price').required().positive();
number('Rating').required().min(1).max(5);Array Validation
import { array, string } from '@voidbase/foundation';
array(string().email(), 'Recipients').required().min(1).max(10);
array(string().min(2).max(20), 'Tags').min(1).max(5);File Validation
import { file } from '@voidbase/foundation';
file('Avatar')
.required()
.maxSize(5, 'MB')
.extensions(['jpg', 'jpeg', 'png'])
.mimeTypes(['image/jpeg', 'image/png']);Date Validation
import { date } from '@voidbase/foundation';
date('Birth Date').required().past();
date('Event Date').required().future();
date('Start Date').min(new Date('2024-01-01'));Enum Validation
import { enumField } from '@voidbase/foundation';
enumField(['admin', 'user', 'moderator'], 'Role').required();
enumField(['active', 'inactive', 'pending'], 'Status');Nested Objects
import { object, string } from '@voidbase/foundation';
const schema = {
name: string('Name').required(),
address: object({
street: string('Street').required(),
city: string('City').required(),
zipCode: string('Zip').required().pattern(/^\d{5}$/),
}, 'Address'),
};HTTP Client
A universal HTTP client that works in both browser and server environments.
Basic Usage
import { http } from '@voidbase/foundation';
// GET request
const { data } = await http.get('/api/users');
// POST request
await http.post('/api/users', {
name: 'John',
email: '[email protected]'
});
// With options
await http.get('/api/users', {
params: { page: 1, limit: 10 },
timeout: 5000
});Create Custom Instance
import { createHttpClient } from '@voidbase/foundation';
const api = createHttpClient({
baseURL: 'https://api.example.com',
timeout: 10000,
headers: {
'X-API-Key': 'your-api-key'
}
});
await api.get('/users'); // https://api.example.com/usersAuthentication
// Bearer token
await http.get('/api/protected', {
auth: { type: 'bearer', token: 'your-jwt-token' }
});
// Basic auth
await http.get('/api/protected', {
auth: { type: 'basic', username: 'user', password: 'pass' }
});Interceptors
const api = createHttpClient({ baseURL: 'https://api.example.com' });
// Add auth token to all requests
api.interceptors.request.use({
onRequest: (config) => ({
...config,
headers: {
...config.headers,
'Authorization': `Bearer ${getToken()}`
}
})
});
// Handle errors globally
api.interceptors.response.use({
onResponseError: (error) => {
if (error.status === 401) {
redirectToLogin();
}
throw error;
}
});Retry Logic
// Simple retry (3 attempts, exponential backoff)
await http.get('/api/flaky', { retry: true });
// Advanced retry
await http.get('/api/flaky', {
retry: {
times: 5,
delay: 1000,
backoff: 'exponential',
retryOn: [500, 502, 503, 504]
}
});Error Handling
import { http, isHttpError } from '@voidbase/foundation';
try {
await http.get('/api/users');
} catch (error) {
if (isHttpError(error)) {
console.log('Status:', error.status); // 404
console.log('Code:', error.code); // 'RESPONSE_ERROR'
console.log('Data:', error.data); // Response body
}
}Request Cancellation
import { createCancelToken } from '@voidbase/foundation';
const token = createCancelToken();
http.get('/api/data', { signal: token.signal });
// Cancel the request
token.cancel('User navigated away');Real-World Examples
User Registration
const registrationSchema = {
username: string('Username')
.required()
.min(3)
.max(20)
.pattern(/^[a-zA-Z0-9_]+$/),
email: string('Email')
.required()
.email()
.lowercase()
.trim(),
password: string('Password')
.required()
.min(8)
.strongPassword(),
confirmPassword: string('Confirm Password')
.required()
.custom((value, data) => {
return value === data.password || 'Passwords must match';
}),
age: number('Age')
.required()
.min(18)
.integer(),
};Product Schema
const productSchema = {
name: string('Product Name').required().min(3).max(100),
description: string('Description').required().min(10).max(5000),
price: number('Price').required().positive().min(0.01),
quantity: number('Quantity').required().integer().min(0),
category: enumField(['electronics', 'clothing', 'food'], 'Category').required(),
tags: array(string().min(2).max(30), 'Tags').required().min(1).max(10),
};Advanced Features
Custom Validators
const username = string('Username')
.required()
.custom((value) => {
if (value.includes('admin')) {
return 'Username cannot contain "admin"';
}
return true;
});Cross-Field Validation
const schema = {
password: string('Password').required(),
confirmPassword: string('Confirm Password')
.required()
.custom((value, data) => {
return value === data.password || 'Passwords must match';
}),
};Conditional Validation
const schema = {
accountType: enumField(['personal', 'business'], 'Account Type').required(),
companyName: string('Company Name').when('accountType', {
is: 'business',
then: { required: true, minLength: 2 },
otherwise: { required: false },
}),
};Transform Functions
const email = string('Email')
.trim()
.lowercase()
.transform((value) => value.replace(/\+.*@/, '@'));Validation Options
// Stop on first error
validate(data, schema, { abortEarly: true });
// Remove unknown fields
validate(data, schema, { stripUnknown: true });
// Allow unknown fields
validate(data, schema, { allowUnknown: true });
// Use specific locale
validate(data, schema, { locale: 'es' });
// Pass context to custom validators
validate(data, schema, { context: { userId: '123' } });Localization
Built-in Languages
- English (
en) - Default - Spanish (
es) - Complete - French (
fr) - Complete - Arabic (
ar) - Complete - Central Kurdish/Sorani (
ckb) - Complete
Set Global Locale
import { setLocale } from '@voidbase/foundation';
setLocale('es'); // Spanish
setLocale('fr'); // FrenchRegister Custom Locale
import { LocaleRegistry, setLocale } from '@voidbase/foundation';
LocaleRegistry.register('de', {
required: ({ label }) => `${label} ist erforderlich`,
invalidEmail: ({ label }) => `${label} muss eine gültige E-Mail sein`,
minLength: ({ label, min }) => `${label} muss mindestens ${min} Zeichen lang sein`,
});
setLocale('de');Helper Functions
Use validation helpers independently:
import {
isEmail,
isUrl,
isStrongPassword,
isInRange,
isEmpty,
} from '@voidbase/foundation';
if (isEmail('[email protected]')) {
console.log('Valid email');
}
if (isUrl('https://example.com')) {
console.log('Valid URL');
}
if (isStrongPassword('SecurePass123!')) {
console.log('Strong password');
}Documentation
- API Reference - Complete API documentation
- Usage Guide - Comprehensive usage examples
- Examples - Code examples
TypeScript Support
Fully typed with TypeScript:
import type {
ValidationResult,
ValidationSchema,
FieldSchema,
ValidatorOptions,
} from '@voidbase/foundation';Development
# Install dependencies
bun install
# Run tests
bun test
# Watch mode
bun test --watch
# Coverage
bun test --coverage
# Type check
bun run type-check
# Build
bun run build:allBrowser Support
- Modern browsers (ES2020+)
- Node.js 18+
- Bun 1.0+
Performance
- Zero dependencies
- Lightweight bundle size
- Fast validation (optimized for performance)
- Tree-shakeable exports
Contributing
Contributions are welcome! Please feel free to submit issues or pull requests.
License
MIT © Void Foundation Team
Support
For issues, questions, or contributions:
Changelog
v1.1.0
- ✨ HTTP Client - Universal HTTP client (browser + server)
- ✨ Request/Response interceptors
- ✨ Automatic retry with exponential backoff
- ✨ Bearer, Basic, and custom authentication
- ✨ Request cancellation with AbortController
- ✨ Polling and concurrent request helpers
- ✨ 70+ passing tests
v1.0.0
- ✨ Initial release
- ✨ Composable schema builders
- ✨ Built-in localization (en, es, fr, ar, ckb)
- ✨ Full TypeScript support
- ✨ 30+ validation rules
- ✨ 36+ passing tests
