Fortify Schema

TypeScript Schema Validation with Interface-Like Syntax
A modern TypeScript validation library designed around familiar interface syntax and powerful conditional validation. Experience schema validation that feels natural to TypeScript developers while unlocking advanced runtime validation capabilities.
π What's New
- Required Fields (
!
): Enforce non-empty strings and non-zero numbers with "string!"
and "number!"
- Object Types: Validate generic object structures with
"object"
and "object?"
- Enhanced Security: All string operations now use secure regex patterns instead of potentially vulnerable methods
- Improved Performance: Optimized validation paths with better caching and precompilation
- Better Error Messages: More descriptive validation errors with clear property paths
Quick Start
npm install fortify-schema
import { Interface } from "fortify-schema";
const UserSchema = Interface({
id: "uuid",
email: "email!",
name: "string(2,50)!",
age: "number(18,120)?",
role: "admin|user|guest",
profile: "object",
tags: "string[]",
metadata: "record<string, any>",
permissions: "when config.hasPermissions.$exists() *? string[] : =[]",
adminTools: "when role=admin *? boolean : =false",
});
const result = UserSchema.safeParse(userData);
if (result.success) {
console.log("Valid user:", result.data);
} else {
console.log("Validation errors:", result.errors);
}
Note: For nested objects, we recommend limiting depth to 50-100 or no more than 300 levels for performance and safety. Default depth limit is 500.
Test by running:
Note: you may have tsx installed if using this command. "npm i -g tsx".
Table of Contents
Installation & Setup
Requirements
- TypeScript 4.5+
- Node.js 14+
- VS Code (recommended for enhanced development experience)
Installation
npm install fortify-schema
yarn add fortify-schema
pnpm add fortify-schema
bun add fortify-schema
VS Code Extension
Enhance your development workflow with our dedicated VS Code extension featuring comprehensive developer tools:
π¨ Enhanced Features
- Syntax Highlighting: Full syntax highlighting for all Fortify Schema types and utilities
- Hover Documentation: Detailed type information, examples, and use cases on hover
- Go-to-Definition: Ctrl+Click on types to open comprehensive documentation
- IntelliSense Support: Smart autocomplete for schema definitions
- Error Detection: Real-time validation of schema syntax
- Code Snippets: Pre-built templates for common schema patterns
π Interactive Documentation
When you hover over any type in Interface({...})
blocks, you'll see:
- Type Description: What the type validates
- Usage Examples:
"string"
, "string?"
, "string[]"
- Use Cases: When and where to use each type
- Code Examples: Complete working examples
π§ Installation
curl https://sdk.nehonix.space/pkgs/mods/vscode/latest/fortify-schema.vsix -o fortify-schema.vsix
code --install-extension fortify-schema.vsix
Core Features
Intuitive Schema Definition
import { Interface } from "fortify-schema";
const ProductSchema = Interface({
id: "uuid",
name: "string(1,100)",
price: "number(0.01,99999.99)",
category: "electronics|books|clothing|home",
inStock: "boolean",
tags: "string[]?",
description: "string(,500)?",
createdAt: "date",
});
const product = {
id: "123e4567-e89b-12d3-a456-426614174000",
name: "Wireless Headphones",
price: 99.99,
category: "electronics",
inStock: true,
tags: ["wireless", "audio", "bluetooth"],
createdAt: new Date(),
};
const result = ProductSchema.safeParse(product);
console.log(result.success);
console.log(result.data);
Comprehensive Type Support
const ComprehensiveSchema = Interface({
name: "string",
age: "number",
active: "boolean",
birthday: "date",
nickname: "string?",
bio: "string?",
requiredName: "string!",
requiredCount: "number!",
username: "string(3,20)",
password: "string(8,)",
score: "number(0,100)",
email: "email",
website: "url",
secureApi: "url.https",
devServer: "url.dev",
phone: "phone",
userId: "uuid",
tags: "string[]",
scores: "number[]?",
limitedTags: "string[](1,5)",
status: "active|inactive|pending",
role: "user|admin|moderator",
profile: "object",
config: "object?",
settings: "record<string, any>",
counters: "record<string, number>",
metadata: "record<string, string>",
version: "=2.0",
type: "=user",
});
Deep Object Validation
const UserProfileSchema = Interface({
user: {
id: "uuid",
email: "email",
profile: {
firstName: "string(1,50)",
lastName: "string(1,50)",
avatar: "url?",
preferences: {
theme: "light|dark|auto",
language: "string(/^[a-z]{2}$/)",
notifications: "boolean",
},
},
},
metadata: {
createdAt: "date",
lastLogin: "date?",
loginCount: "number(0,)",
},
});
Utility Functions
Fortify Schema provides powerful utility functions for advanced schema definition:
Make.const() - Constant Values
Create schemas that validate against exact constant values:
import { Interface, Make } from "fortify-schema";
const ConfigSchema = Interface({
apiVersion: Make.const("v2.1"),
environment: Make.const("production"),
maxRetries: Make.const(3),
timeout: Make.const(5000),
enableLogging: Make.const(true),
defaultSettings: Make.const({
theme: "dark",
language: "en",
}),
supportedFormats: Make.const(["json", "xml", "csv"]),
});
const config = {
apiVersion: "v2.1",
environment: "staging",
maxRetries: 3,
timeout: 3000,
};
Record Types - Dynamic Objects
Validate objects with dynamic keys but consistent value types:
const DynamicSchema = Interface({
metadata: "record<string, any>",
scores: "record<string, number>",
translations: "record<string, string>",
optionalSettings: "record<string, boolean>?",
});
const data = {
metadata: {
userId: "123",
timestamp: new Date(),
flags: ["active", "verified"],
},
scores: {
math: 95,
science: 87,
english: 92,
},
translations: {
hello: "Hola",
goodbye: "AdiΓ³s",
welcome: "Bienvenido",
},
};
Conditional Validation
Fortify Schema's standout feature: advanced conditional validation based on runtime properties and business logic.
const SmartUserSchema = Interface({
config: "any?",
user: "any?",
features: "any?",
id: "uuid",
email: "email",
role: "admin|user|guest",
hasPermissions: "when config.permissions.$exists() *? boolean : =false",
hasProfile: "when user.profile.$exists() *? boolean : =false",
isListEmpty: "when config.items.$empty() *? boolean : =true",
hasAdminRole: "when user.roles.$contains(admin) *? boolean : =false",
defaultTags: 'when config.tags.$exists() *? string[] : =["default","user"]',
defaultSettings:
'when config.theme.$exists() *? any : ={"mode":"light","lang":"en"}',
advancedFeature:
"when user.profile.settings.advanced.$exists() *? boolean : =false",
isValidUser:
"when user.email.$exists() && user.verified.$exists() *? boolean : =false",
});
Runtime Validation Methods
const RuntimeMethodsSchema = Interface({
data: "any?",
hasData: "when data.field.$exists() *? boolean : =false",
isEmpty: "when data.list.$empty() *? boolean : =true",
isNull: "when data.value.$null() *? boolean : =false",
containsText:
"when data.description.$contains(important) *? boolean : =false",
startsWithPrefix: "when data.code.$startsWith(PRE) *? boolean : =false",
endsWithSuffix: "when data.filename.$endsWith(.pdf) *? boolean : =false",
inRange: "when data.score.$between(0,100) *? boolean : =false",
isValidStatus:
"when data.status.$in(active,pending,inactive) *? boolean : =false",
});
Live Utility - Real-time Validation (still in progress so not recommended for production use yet)
The Live utility transforms Fortify Schema into a powerful real-time validation system with EventEmitter-like interface, data transformation pipelines, and stream control methods. Perfect for modern applications requiring reactive validation.
Key Features
- Real-time Field Validation - Validate form fields as users type
- EventEmitter Interface - Full
.on()
, .emit()
, .off()
, .once()
support
- Data Transformation Pipeline - Chain
.transform()
, .filter()
, .map()
operations
- Stream Control -
.pause()
, .resume()
, .destroy()
for flow control
- Stream Piping - Connect validators with
.pipe()
for complex workflows
- Performance Monitoring - Built-in statistics and performance tracking
- InterfaceSchema Sync - Perfect synchronization with Interface validation
Quick Example
import { Live, Interface } from "fortify-schema";
const UserSchema = Interface({
name: "string(2,50)",
email: "email",
age: "number(18,120)",
});
const validator = Live.stream(UserSchema)
.transform((data) => ({ ...data, timestamp: Date.now() }))
.filter((data) => data.age >= 21)
.map((data) => ({ ...data, name: data.name.toUpperCase() }));
validator.on("valid", (data) => console.log("β
Valid:", data));
validator.on("invalid", (data, errors) => console.log("β Invalid:", errors));
validator.on("filtered", (data) => console.log("π« Filtered:", data));
validator.validate({ name: "john", email: "john@example.com", age: 25 });
Stream Control Example
const streamValidator = Live.stream(UserSchema);
streamValidator.pause();
streamValidator.validate(userData1);
streamValidator.validate(userData2);
console.log("Queue length:", streamValidator.queueLength);
streamValidator.resume();
const sourceValidator = Live.stream(InputSchema);
const destinationValidator = Live.stream(OutputSchema);
sourceValidator.pipe(destinationValidator);
Form Integration Example
const formValidator = Live.form(UserSchema);
formValidator.bindField("email", emailInput);
formValidator.bindField("name", nameInput);
formValidator.enableAutoValidation();
formValidator.onSubmit((isValid, data, errors) => {
if (isValid) {
submitToAPI(data);
} else {
displayErrors(errors);
}
});
The Live utility provides 100% coverage of standard stream methods while maintaining perfect synchronization with InterfaceSchema validation logic.
Real-World Applications
E-Commerce Product Management
const ECommerceProductSchema = Interface({
id: "uuid",
sku: "string(/^[A-Z0-9-]{8,20}$/)",
name: "string(1,200)",
slug: "string(/^[a-z0-9-]+$/)",
price: "number(0.01,999999.99)",
compareAtPrice: "number(0.01,999999.99)?",
cost: "number(0,999999.99)?",
inventory: {
quantity: "number(0,)",
trackQuantity: "boolean",
allowBackorder: "boolean",
lowStockThreshold: "number(0,)?"
},
description: "string(,5000)?",
shortDescription: "string(,500)?",
category: "electronics|clothing|books|home|sports|beauty",
tags: "string[](0,20)",
images: {
primary: "url",
gallery: "url[](0,10)",
alt: "string(,100)?"
}?,
seo: {
title: "string(,60)?",
description: "string(,160)?",
keywords: "string[](0,10)"
}?,
config: "any?",
shipping: "when config.isDigital.$exists() *? any? : ={weight:0,dimensions:{}}",
subscription: "when config.isSubscription.$exists() *? any : =null",
variants: "when config.hasVariants.$exists() *? any[] : =[]",
status: "draft|active|archived",
publishedAt: "date?",
createdAt: "date",
updatedAt: "date"
});
Performance Excellence
Fortify Schema is engineered for high-performance validation with multiple optimization strategies:
Performance Architecture
const performanceFeatures = {
precompilation: "Schemas optimized at creation time",
caching: "Intelligent caching for union types and constraints",
memoryOptimized: "Minimal runtime overhead per validation",
zeroAllocation: "Hot paths avoid unnecessary object creation",
earlyTermination: "Fast-fail validation on first error",
typeSpecialization: "Optimized validation paths per data type",
};
Benchmark Highlights
Our continuous performance monitoring shows excellent results across all validation scenarios:
- High Throughput: Millions of operations per second for common validation patterns
- Consistent Performance: Low variation in execution times
- Memory Efficient: Minimal memory overhead per schema instance
- Scalable: Performance scales predictably with data complexity
Performance Testing
Validate performance on your specific use cases:
bun run scripts/benchmark.js
View detailed benchmark results for comprehensive performance analysis.
Advanced Capabilities
Schema Transformation
import { Mod } from "fortify-schema";
const BaseUserSchema = Interface({
id: "uuid",
email: "email",
name: "string",
password: "string",
role: "user|admin",
createdAt: "date",
});
const PublicUserSchema = Mod.omit(BaseUserSchema, ["password"]);
const PartialUserSchema = Mod.partial(BaseUserSchema);
const RequiredUserSchema = Mod.required(PartialUserSchema);
const ExtendedUserSchema = Mod.extend(BaseUserSchema, {
lastLogin: "date?",
preferences: {
theme: "light|dark",
notifications: "boolean",
},
});
Comprehensive Error Handling
const result = UserSchema.safeParse(invalidData);
if (!result.success) {
result.errors.forEach((error) => {
console.log(`Field: ${error.path.join(".")}`);
console.log(`Message: ${error.message}`);
console.log(`Code: ${error.code}`);
console.log(`Expected: ${error.expected}`);
console.log(`Received: ${error.received}`);
});
}
try {
const data = UserSchema.parse(userData);
} catch (error) {
if (error instanceof ValidationError) {
console.log("Validation failed:", error.errors);
}
}
Developer Experience
VS Code Extension Features
Our dedicated VS Code extension transforms your development experience:
- Intelligent Syntax Highlighting for schema definitions
- Advanced IntelliSense with type and method completion
- Real-time Validation with inline error detection
- Rich Hover Documentation for all types and methods
- Multiple Theme Support for different coding preferences
const UserSchema = Interface({
email: "email",
name: "string(2,50)",
hasProfile: "when user.profile.$exists() *? boolean : =false",
});
What Sets Fortify Schema Apart
Design Philosophy
- Developer-Centric: Built around familiar TypeScript patterns and conventions
- Interface Syntax: Schema definitions that feel like native TypeScript interfaces
- Conditional Intelligence: Advanced runtime validation based on dynamic properties
- Performance Focused: Optimized for high-throughput production applications
- Tooling Excellence: Professional-grade development tools and IDE integration
- Type Safety: Complete TypeScript inference and compile-time validation
Key Strengths
- Familiar Syntax: Write schemas using TypeScript-like interface definitions
- Advanced Conditionals: Unique runtime property validation and business logic
- Rich Tooling: Dedicated VS Code extension with comprehensive development support
- Type Integration: Seamless TypeScript integration with full type inference
- Production Ready: Battle-tested with comprehensive error handling and debugging
Community and Growth
We're building Fortify Schema with transparency and community feedback at its core. We welcome:
- Real-world usage feedback and performance insights
- Issue reports with detailed reproduction cases
- Feature requests based on practical development needs
- Performance benchmarking on diverse use cases
- Constructive feedback on API design and developer experience
API Reference
Core Validation Methods
Interface(schema, options?)
Creates a new schema instance with comprehensive validation rules.
const UserSchema = Interface(
{
id: "uuid",
name: "string",
},
{
strict: true,
loose: false,
allowUnknown: false,
}
);
schema.parse(data)
Synchronous validation that returns validated data or throws detailed errors.
try {
const user = UserSchema.parse(userData);
} catch (error) {
console.error(error.errors);
}
schema.safeParse(data)
Safe validation that returns a result object without throwing exceptions.
const result = UserSchema.safeParse(userData);
if (result.success) {
console.log(result.data);
} else {
console.error(result.errors);
}
schema.safeParseUnknown(data)
Safe validation for unknown data types, ideal for testing and debugging.
const result = UserSchema.safeParseUnknown(unknownData);
schema.parseAsync(data)
Asynchronous validation with promise-based error handling.
try {
const user = await UserSchema.parseAsync(userData);
console.log("Valid user:", user);
} catch (error) {
console.error("Validation failed:", error.message);
}
schema.safeParseAsync(data)
Asynchronous safe validation that never throws exceptions.
const result = await UserSchema.safeParseAsync(userData);
if (result.success) {
console.log("Valid user:", result.data);
} else {
console.error("Validation errors:", result.errors);
}
schema.safeParseUnknownAsync(data)
Asynchronous safe validation for unknown data types.
const result = await UserSchema.safeParseUnknownAsync(unknownData);
if (result.success) {
console.log("Valid data:", result.data);
} else {
console.error("Validation errors:", result.errors);
}
Schema Transformation Operations
Mod.partial(schema)
- Optional Fields
const PartialUserSchema = Mod.partial(UserSchema);
Mod.required(schema)
- Required Fields
const RequiredUserSchema = Mod.required(PartialUserSchema);
Mod.pick(schema, keys)
- Field Selection
const PublicUserSchema = Mod.pick(UserSchema, ["id", "name", "email"]);
Mod.omit(schema, keys)
- Field Exclusion
const SafeUserSchema = Mod.omit(UserSchema, ["password", "internalId"]);
Mod.extend(schema, extension)
- Schema Extension
const ExtendedUserSchema = Mod.extend(UserSchema, {
lastLogin: "date?",
preferences: {
theme: "light|dark",
},
});
Mod.merge(schema1, schema2)
- Schema Merging
const CombinedSchema = Mod.merge(UserSchema, ProfileSchema);
Available Extensions
Fortify Schema provides powerful extensions for enhanced functionality:
export {
Smart,
When,
Live,
Docs,
Extensions,
Quick,
TypeScriptGenerator,
} from "fortify-schema";
Smart Inference
import { Smart } from "fortify-schema";
const sampleUser = {
id: 1,
email: "user@example.com",
name: "John Doe",
tags: ["developer", "typescript"],
};
const UserSchema = Smart.fromSample(sampleUser);
Conditional Builder
import { When } from "fortify-schema";
const OrderSchema = Interface({
orderType: "pickup|delivery",
address: "string?",
deliveryFee: When.field("orderType")
.is("delivery")
.then("number(0,)")
.default("number?"),
});
Real-time Validation with Live Utility
The Live utility provides comprehensive real-time validation with full EventEmitter-like interface, data transformation pipelines, and stream control methods. Perfect for forms, streaming data, and reactive applications.
import { Live } from "fortify-schema";
const UserSchema = Interface({
id: "number",
name: "string(2,50)",
email: "email",
age: "number(18,120)",
});
Live Validator - Real-time Field Validation
const liveValidator = Live.validator(UserSchema);
liveValidator.onValidation((result) => {
console.log("Validation result:", result.isValid);
console.log("Current errors:", result.errors);
updateUI(result);
});
liveValidator.validateField("email", "user@example.com");
liveValidator.validateField("name", "John Doe");
console.log("Is valid:", liveValidator.isValid);
console.log("All errors:", liveValidator.errors);
const fullResult = liveValidator.validateAll(userData);
Stream Validator - Advanced Stream Processing
The StreamValidator provides a complete EventEmitter-like interface with all standard stream methods:
const streamValidator = Live.stream(UserSchema);
streamValidator.on("valid", (data) => {
console.log("Valid data received:", data);
});
streamValidator.once("invalid", (data, errors) => {
console.log("First invalid data:", errors);
});
streamValidator.on("error", (error) => {
console.error("Stream error:", error);
});
streamValidator.on("custom-event", (message) => {
console.log("Custom event:", message);
});
streamValidator.emit("custom-event", "Hello from stream!");
streamValidator.off("valid", specificListener);
streamValidator.off("invalid");
Data Transformation Pipeline
const transformValidator = Live.stream(UserSchema)
.transform((data) => {
return { ...data, timestamp: Date.now(), source: "api" };
})
.filter((data) => {
return data.age >= 21;
})
.map((data) => {
return {
...data,
name: data.name.toUpperCase(),
email: data.email.toLowerCase(),
};
});
transformValidator.on("valid", (data) => {
console.log("Processed data:", data);
});
transformValidator.on("filtered", (data) => {
console.log("Data filtered out:", data);
});
transformValidator.on("invalid", (data, errors) => {
console.log("Validation failed after transformation:", errors);
});
transformValidator.validate(rawUserData);
Stream Control Methods
const controlValidator = Live.stream(UserSchema);
controlValidator.pause();
console.log("Stream paused:", controlValidator.paused);
controlValidator.validate(userData1);
controlValidator.validate(userData2);
console.log("Queue length:", controlValidator.queueLength);
controlValidator.resume();
console.log("Stream resumed, queue processed");
controlValidator.on("destroy", () => {
console.log("Stream destroyed and cleaned up");
});
controlValidator.destroy();
console.log("Stream destroyed:", controlValidator.destroyed);
Stream Piping
const sourceValidator = Live.stream(InputSchema);
const destinationValidator = Live.stream(OutputSchema);
sourceValidator.pipe(destinationValidator);
sourceValidator.validate(inputData);
const pipeline = sourceValidator
.pipe(transformValidator)
.pipe(destinationValidator);
Form Validator - Advanced Form Integration
const formValidator = Live.form(UserSchema);
formValidator.bindField("email", emailInput);
formValidator.bindField("name", nameInput);
formValidator.bindField("age", ageInput);
formValidator.enableAutoValidation();
formValidator.onSubmit((isValid, data, errors) => {
if (isValid) {
console.log("Form is valid, submitting:", data);
submitToAPI(data);
} else {
console.log("Form has errors:", errors);
displayErrors(errors);
}
});
const formResult = formValidator.validateForm();
console.log("Form valid:", formResult.isValid);
Advanced Event Handling
const streamValidator = Live.stream(UserSchema);
streamValidator.on("data", (data) => {
console.log("Data received for validation:", data);
});
streamValidator.on("validated", (data, result) => {
console.log("Validation completed:", result.isValid);
});
streamValidator.on("queued", (data) => {
console.log("Data queued (stream paused):", data);
});
streamValidator.on("pause", () => {
console.log("Stream paused");
});
streamValidator.on("resume", () => {
console.log("Stream resumed");
});
streamValidator.on("error", (error) => {
console.error("Stream error:", error.message);
});
Performance and Statistics
streamValidator.onStats((stats) => {
console.log("Validation Statistics:");
console.log(`- Total validated: ${stats.totalValidated}`);
console.log(`- Valid count: ${stats.validCount}`);
console.log(`- Invalid count: ${stats.invalidCount}`);
console.log(`- Error rate: ${(stats.errorRate * 100).toFixed(2)}%`);
console.log(`- Running since: ${stats.startTime}`);
});
const currentStats = streamValidator.getStats();
console.log("Current performance:", currentStats);
Integration with InterfaceSchema
The Live utility is fully synchronized with InterfaceSchema modules, ensuring consistent validation behavior:
const schema = Interface({
email: "email",
age: "number(18,120)",
role: "admin|user|guest",
});
const interfaceResult = schema.safeParse(userData);
const liveResult = Live.stream(schema).validate(userData);
console.log("Results match:", interfaceResult.success === liveResult.isValid);
Documentation Generation
import { Docs } from "fortify-schema";
const openApiSpec = Docs.openapi(UserSchema, {
title: "User API",
version: "1.0.0",
servers: ["https://api.example.com"],
});
const typeDefinitions = Docs.typescript(UserSchema, {
exportName: "User",
namespace: "API",
});
Quick Utilities
import { Quick } from "fortify-schema";
const schema = Quick.fromSample(sampleData);
const conditionalField = Quick.when("status").is("active").then("string");
const docs = Quick.docs(schema);
const typescript = Quick.typescript(schema);
Validation Configuration
Method Chaining
const FlexibleSchema = UserSchema.loose()
.allowUnknown()
.min(1)
.max(100)
.unique()
.pattern(/^[A-Z]/)
.default("N/A");
Contributing
By contributing to Fortify Schema, you help fortify-schema to:
- Improve the quality of TypeScript validation
- Expand the reach of TypeScript in the JavaScript ecosystem
- Provide a robust and reliable validation solution for developers
- Foster a community of developers who care about code quality and security
Development Environment
git clone https://github.com/Nehonix-Team/fortify-schema.git
cd fortify-schema
npm install
npm run test
npm run benchmark
npm run build
Quality Standards
- TypeScript: Strict mode with comprehensive type checking
- Test Coverage: 95%+ coverage requirement
- Performance: All benchmarks must pass performance thresholds
- Documentation: Complete JSDoc comments for all public APIs
- Code Quality: ESLint and Prettier configuration compliance
Contribution Process
- Fork the repository on GitHub
- Create a feature branch:
git checkout -b feature/enhancement-name
- Implement changes with comprehensive test coverage
- Verify all tests pass:
npm test
- Validate performance:
npm run benchmark
- Commit changes:
git commit -m 'Add enhancement: description'
- Push to branch:
git push origin feature/enhancement-name
- Submit a Pull Request with detailed description
Issue Reporting
For effective issue resolution, please provide:
- Environment Details: Fortify Schema, TypeScript, and Node.js versions
- Reproduction Case: Minimal code example demonstrating the issue
- Expected Behavior: Clear description of intended functionality
- Actual Behavior: Detailed explanation of observed behavior
- Error Information: Complete error messages and stack traces
Release History
See CHANGELOG.md for comprehensive release notes and migration guides.
License
MIT License - see LICENSE file for complete terms.
Support Resources
Development Status: Fortify Schema is in active development with a focus on production readiness. We maintain transparency about capabilities and limitations while continuously improving based on community feedback and real-world usage patterns.