Package Exports
- input-field-spec-ts
Readme
Dynamic Input Field Specification - TypeScript Implementation v1.0
A zero-dependency TypeScript implementation of the Dynamic Input Field Specification Protocol v1.0 with ordered constraint execution and enhanced API ergonomics.
๐ Quick Start
Installation
npm install
npm run build
๐ Learning Path
- ๐ Basic Concepts - Start with docs/USAGE_GUIDE.md
- ๐๏ธ Architecture - Understand the design with docs/ARCHITECTURE.md
- ๐ป Live Examples - Try the interactive examples:
npm run examples:basic # Basic validation npm run examples:dynamic # Dynamic values npm run examples:complete # Complete forms npm run examples:demo # Full demonstration
30-Second Example
import { FieldValidator, InputFieldSpec } from './src';
// Define field specification with new v2.0 structure
const emailField: InputFieldSpec = {
displayName: 'Email',
dataType: 'STRING',
expectMultipleValues: false,
required: true, // โจ Now at top-level for better API design
constraints: [ // โจ Now an array for ordered execution
{
name: 'email',
pattern: '^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$',
errorMessage: 'Please enter a valid email address'
}
]
};
// Validate input
const validator = new FieldValidator();
const result = await validator.validate(emailField, 'user@example.com', 'email');
console.log(result.isValid); // true
โจ What's New in v2.0
๐ฏ Enhanced API Design
- Required field at top-level:
required: boolean
moved from constraints toInputFieldSpec
- Ordered constraint execution: Constraints now execute in array order for predictable behavior
- Named constraints: Each constraint has a
name
property for better identification
๏ฟฝ Framework Integration
- Angular HttpClient: Seamless integration with interceptors and dependency injection
- Axios Support: Custom Axios instances with existing configurations preserved
- Custom HTTP Clients: Configurable fetch-based client with interceptors and error handling
- Zero Breaking Changes: Existing HTTP infrastructure remains intact
๏ฟฝ๐ Migration from v1.x
// Before (v1.x)
const oldSpec = {
constraints: {
myConstraint: { required: true, pattern: "..." }
}
};
// After (v2.0)
const newSpec = {
required: true, // Moved to top-level
constraints: [ // Now an array
{ name: 'myConstraint', pattern: "..." }
]
};
// Framework Integration (NEW!)
const httpClient = HttpClientFactory.createAngularAdapter(angularHttpClient);
const valuesResolver = new ValuesResolver(httpClient, cache);
๐ฆ Features
- Zero Runtime Dependencies: Pure TypeScript implementation
- Framework Integration: Angular, React, Vue, Vanilla JS support
- HTTP Client Injection: Preserves existing interceptors and configurations
- Type Safety: Complete TypeScript type definitions
- Validation Engine: Comprehensive field validation
- HTTP Client: Pluggable HTTP client with caching
- Dependency Injection: Clean architecture with IoC
- Extensive Testing: 58 tests with 96%+ coverage
๐๏ธ Architecture
Separation of Concerns
src/
โโโ types/ # Pure TypeScript interfaces (zero dependencies)
โโโ validation/ # Business logic validation engine
โโโ client/ # Infrastructure (HTTP, caching, resolution)
โโโ __tests__/ # Comprehensive test suite
Design Patterns
- Dependency Injection: Constructor injection with interfaces
- Strategy Pattern: Pluggable HTTP clients and cache providers
- Factory Pattern: Simplified object creation
- Template Method: Validation algorithms
๐ง Usage Examples
Basic Validation
import { FieldValidator, InputFieldSpec } from './src';
const fieldSpec: InputFieldSpec = {
displayName: 'Email',
dataType: 'STRING',
expectMultipleValues: false,
required: true, // โจ Top-level required field
constraints: [ // โจ Array with ordered execution
{
name: 'email',
pattern: '^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$',
errorMessage: 'Please enter a valid email address'
}
]
};
const validator = new FieldValidator();
const result = await validator.validate(fieldSpec, 'test@example.com', 'email');
console.log(result.isValid); // true
Multiple Constraints with Ordered Execution
const passwordSpec: InputFieldSpec = {
displayName: 'Password',
dataType: 'STRING',
expectMultipleValues: false,
required: true,
constraints: [ // Executed in order: length โ strength โ special
{
name: 'length',
min: 8,
max: 50,
errorMessage: 'Password must be 8-50 characters'
},
{
name: 'strength',
pattern: '^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)',
errorMessage: 'Must contain lowercase, uppercase, and digit'
},
{
name: 'special',
pattern: '.*[!@#$%^&*]',
errorMessage: 'Must contain special character'
}
]
};
// Validate specific constraint
const lengthResult = await validator.validate(passwordSpec, 'weak', 'length');
// Validate all constraints in order
const allResult = await validator.validate(passwordSpec, 'StrongPass123!');
Dynamic Values Resolution
import {
ValuesResolver,
FetchHttpClient,
MemoryCacheProvider,
createDefaultValuesEndpoint
} from './src';
// Setup with dependency injection
const resolver = new ValuesResolver(
new FetchHttpClient(),
new MemoryCacheProvider()
);
// Configure endpoint
const endpoint = createDefaultValuesEndpoint('https://api.example.com/countries');
// Resolve values with caching and pagination
const result = await resolver.resolveValues(endpoint, {
search: 'france',
page: 1,
limit: 10
});
Zero-Dependency Architecture
// No external dependencies at runtime!
import { MemoryCacheProvider, FetchHttpClient } from './src';
const cache = new MemoryCacheProvider(); // Uses native Map
const client = new FetchHttpClient(); // Uses native fetch
๐งช Testing
Run Tests
# All tests
npm test
# Watch mode
npm run test:watch
# Coverage report
npm run test:coverage
Test Results
- 58 tests pass with 100% success rate
- Types Module: 100% coverage
- Validation Module: 96% coverage
- Client Module: 86% coverage
- Integration Tests: End-to-end scenarios with new v2.0 structure
๐จ Build & Development
Available Scripts
npm run build # Build distribution files (CJS, ESM, types)
npm run dev # Build in watch mode
npm run test # Run test suite
npm run lint # ESLint checking
npm run format # Prettier formatting
npm run type-check # TypeScript type checking
Build Output
dist/
โโโ index.js # CommonJS build
โโโ index.mjs # ES Module build
โโโ index.d.ts # TypeScript declarations (CJS)
โโโ index.d.mts # TypeScript declarations (ESM)
๐ API Reference
Core Types
InputFieldSpec
- Complete field specificationConstraintDescriptor
- Validation rulesValidationResult
- Validation outcomeValuesEndpoint
- Dynamic values configuration
Classes
FieldValidator
- Main validation engineValuesResolver
- Value resolution orchestratorFetchHttpClient
- HTTP client implementationMemoryCacheProvider
- In-memory caching
Interfaces
HttpClient
- HTTP client abstractionCacheProvider
- Cache provider abstraction
๐ฏ Design Principles
Zero Dependencies
- Runtime: No external dependencies
- Build: Only development dependencies (TypeScript, Jest, etc.)
- Browser: Uses native fetch, Map, etc.
Type Safety
- Compile-time: Full TypeScript strict mode
- Runtime: Type guards for external data
- API: Strongly typed interfaces
Testability
- Dependency Injection: Easy mocking and testing
- Interface Segregation: Focused, testable interfaces
- Pure Functions: Predictable, testable logic
๐ Documentation
- Usage Guide - Getting started and common patterns
- API Reference - Complete API documentation with examples
- Framework Integration - Angular, React, Vue integration examples
- Performance Guide - Optimization strategies and benchmarks
- Architecture Guide - Design decisions and patterns
- Migration Guide - Migrating from v1.x to v2.0
- Release Notes - What's new in v2.0
๐ค Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Add tests for your changes
- Ensure all tests pass (
npm test
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
๐ License
MIT License - see LICENSE file for details.