typescript-runtime-schemas
Version:
A TypeScript schema generation tool that extracts Zod schemas from TypeScript source files with runtime validation support. Generate validation schemas directly from your existing TypeScript types with support for computed types and constraint-based valid
609 lines (463 loc) • 15.3 kB
Markdown
# TypeScript Runtime Schemas
A TypeScript schema generation tool that extracts Zod schemas from TypeScript source files with runtime validation support. Generate validation schemas directly from your existing TypeScript types with support for computed types and constraint-based validation.
## Installation
```bash
npm install typescript-runtime-schemas
```
## Features
- 🎯 **Schema File Generation**: Extract Zod schemas directly from TypeScript source files
- 🔧 **CLI Tool**: Command-line interface for batch processing and file generation
- 🚀 **Computed Types Support**: Full support for utility types like `Pick`, `Omit`, `Partial`, `Required`, etc.
- 📝 **Constraint Types**: Use TypeScript intersection types for validation constraints
- 🔍 **Runtime Validation**: Generate Zod schemas with runtime validation support
- 📦 **Programmatic API**: Full API for integration into your build process
- 📝 **Type Safety**: Full TypeScript support with proper type definitions
## Quick Start
### 1. Define Types with Runtime Validation Support
For schema generation to work, your types must extend `SupportsRuntimeValidation`:
```typescript
import {
Min,
Max,
Email,
UUID,
MinLength,
SupportsRuntimeValidation,
} from "typescript-runtime-schemas";
// ✅ This type will be processed for schema generation
type User = {
id: string & UUID;
email: string & Email;
age: number & Min<18> & Max<120>;
name: string & MinLength<2>;
} & SupportsRuntimeValidation;
// ✅ Interface extending SupportsRuntimeValidation
interface Product extends SupportsRuntimeValidation {
id: string & UUID;
name: string & MinLength<1>;
price: number & Min<0>;
}
// ❌ This type will be ignored (no SupportsRuntimeValidation)
type IgnoredType = {
id: string;
name: string;
};
```
### 2. Generate Schema Files from Source Code
```bash
# Generate schemas from a single file
npx typescript-runtime-schemas generate ./src/types.ts --output ./schemas
# Generate schemas from entire directory
npx typescript-runtime-schemas generate ./src --output ./schemas --structured
# List types that support runtime validation
npx typescript-runtime-schemas list ./src/types.ts
```
### 3. Working with Computed Types
Schema Gen fully supports TypeScript utility types:
```typescript
import {
UUID,
Email,
Min,
SupportsRuntimeValidation,
} from "typescript-runtime-schemas";
// Base type
type BaseUser = {
id: string & UUID;
email: string & Email;
name: string;
age: number & Min<18>;
role: string;
createdAt: Date;
} & SupportsRuntimeValidation;
// ✅ Pick utility type - generates schema for selected fields only
type UserProfile = Pick<BaseUser, "id" | "name" | "email"> &
SupportsRuntimeValidation;
// ✅ Omit utility type - generates schema excluding specified fields
type CreateUserRequest = Omit<BaseUser, "id" | "createdAt"> &
SupportsRuntimeValidation;
// ✅ Partial utility type - makes all fields optional
type UpdateUserRequest = Partial<BaseUser> & SupportsRuntimeValidation;
// ✅ Complex combinations
type UserSummary = Pick<BaseUser, "id" | "name"> & {
lastLogin: Date;
} & SupportsRuntimeValidation;
```
Generated schemas will be:
```typescript
// UserProfile schema
z.object({
id: z.string().uuid(),
name: z.string(),
email: z.string().email(),
});
// CreateUserRequest schema
z.object({
email: z.string().email(),
name: z.string(),
age: z.number().min(18),
role: z.string(),
});
// UpdateUserRequest schema (all fields optional)
z.object({
id: z.string().uuid().optional(),
email: z.string().email().optional(),
name: z.string().optional(),
age: z.number().min(18).optional(),
role: z.string().optional(),
createdAt: z.date().optional(),
});
```
## CLI Usage (Primary Use Case)
### Generate Command
```bash
# Basic file generation
npx typescript-runtime-schemas generate <input> --output <output>
# Generate structured output (one schema file per source file)
npx typescript-runtime-schemas generate ./src --output ./schemas --structured
# Use configuration file for complex setups
npx typescript-runtime-schemas generate --config ./my-config.js
# Options
--output, -o Output directory or file
--structured Create structured output (one file per source file)
--format Output format (zod, json) [default: zod]
--include Include glob patterns
--exclude Exclude glob patterns
--config <file> Configuration file path
```
#### Configuration File (Optional)
You can optionally create a `typescript-runtime-schemas.config.js` file in your project root to set default options and avoid repeating command-line arguments:
```javascript
module.exports = {
input: "./src/**/*.ts",
output: "./schemas",
structured: true,
format: "zod",
exclude: ["**/*.test.ts", "**/*.spec.ts"],
};
```
The CLI will automatically look for config files in this order:
- `typescript-runtime-schemas.config.js`
- `typescript-runtime-schemas.config.json`
- `typescript-runtime-schemas.config.mjs`
Command-line options always take precedence over config file settings.
### List Command
```bash
# List all types that support runtime validation
npx typescript-runtime-schemas list ./src/types.ts
# List types in directory recursively
npx typescript-runtime-schemas list ./src --recursive
```
### Extract Command
```bash
# Extract type information as JSON
npx typescript-runtime-schemas extract ./src/types.ts --format json
# Parallel processing options for large codebases
npx typescript-runtime-schemas extract ./src --concurrency 8 --progress
npx typescript-runtime-schemas extract ./src --chunk-size 50 --no-parallel
```
### Stats Command
```bash
# Get statistics about types and validation support
npx typescript-runtime-schemas stats ./src
```
## SupportsRuntimeValidation
**Important**: Only types that extend `SupportsRuntimeValidation` will be processed for schema generation!
This is a design decision to ensure explicit opt-in for runtime validation.
### Type Aliases
```typescript
import {
SupportsRuntimeValidation,
Email,
Min,
} from "typescript-runtime-schemas";
// ✅ Correct - intersection with SupportsRuntimeValidation
type User = {
email: string & Email;
age: number & Min<18>;
} & SupportsRuntimeValidation;
// ❌ Incorrect - will be ignored
type IgnoredUser = {
email: string & Email;
age: number & Min<18>;
};
```
### Interfaces
```typescript
import {
SupportsRuntimeValidation,
Email,
Min,
} from "typescript-runtime-schemas";
// ✅ Correct - extends SupportsRuntimeValidation
interface User extends SupportsRuntimeValidation {
email: string & Email;
age: number & Min<18>;
}
// ❌ Incorrect - will be ignored
interface IgnoredUser {
email: string & Email;
age: number & Min<18>;
}
```
### Computed Types
```typescript
// ✅ Computed types must also extend SupportsRuntimeValidation
type UserProfile = Pick<User, "email"> & SupportsRuntimeValidation;
type CreateUser = Omit<User, "id"> & SupportsRuntimeValidation;
```
## Supported Computed Types
Schema Gen provides full support for TypeScript utility types:
### Object Manipulation
- `Pick<T, K>` - Select specific properties
- `Omit<T, K>` - Exclude specific properties
- `Partial<T>` - Make all properties optional
- `Required<T>` - Make all properties required
- `Readonly<T>` - Make all properties readonly
### Type Filtering
- `Exclude<T, U>` - Exclude types from union
- `Extract<T, U>` - Extract types from union
- `NonNullable<T>` - Remove null and undefined
### Function Types
- `ReturnType<T>` - Extract function return type
- `Parameters<T>` - Extract function parameter types
- `ConstructorParameters<T>` - Extract constructor parameter types
- `InstanceType<T>` - Extract instance type from constructor
### Advanced Types
- `Record<K, V>` - Create object type with specific keys and values
- Complex intersections and unions
## Available Constraint Types
### Numeric Constraints
```typescript
import {
Min,
Max,
Integer,
Positive,
Negative,
Range,
} from "typescript-runtime-schemas";
type Product = {
price: number & Positive & Min<0.01>;
quantity: number & Integer & Min<0>;
rating: number & Range<1, 5>;
} & SupportsRuntimeValidation;
```
### String Constraints
```typescript
import {
MinLength,
MaxLength,
Email,
UUID,
URL,
Regex,
} from "typescript-runtime-schemas";
type User = {
email: string & Email;
id: string & UUID;
website: string & URL;
username: string & MinLength<3> & MaxLength<20>;
phone: string & Regex<"^\\+?[1-9]\\d{1,14}$">;
} & SupportsRuntimeValidation;
```
### Array Constraints
```typescript
import { MinLength, MaxLength } from "typescript-runtime-schemas";
type Team = {
members: string[] & MinLength<1> & MaxLength<10>;
} & SupportsRuntimeValidation;
```
### Custom Constraints
```typescript
import {
Phone,
CreditCard,
IPAddress,
Base64,
} from "typescript-runtime-schemas";
type Contact = {
phone: string & Phone;
ip: string & IPAddress;
avatar: string & Base64;
} & SupportsRuntimeValidation;
```
## Programmatic API (Secondary Use Case)
For advanced use cases, you can use the programmatic API:
### SchemaExtractor
Extract schemas from various sources:
```typescript
import { SchemaExtractor } from "typescript-runtime-schemas";
// From source code string
const schemas = await SchemaExtractor.extractZodSchemas(sourceCode);
// From file
const schemas = await SchemaExtractor.extractZodSchemasFromFile("./types.ts");
// From directory
const schemas = await SchemaExtractor.extractZodSchemasFromDirectory("./src");
// Extract and write to files
await SchemaExtractor.extractAndWriteZodSchemas(sourceCode, "./output");
```
### TypeResolver
Resolve complex TypeScript types including computed types:
```typescript
import { TypeResolver } from "typescript-runtime-schemas";
const resolver = new TypeResolver(sourceCode);
const resolvedTypes = resolver.resolveTypes(["User", "Product"]);
```
### ZodSchemaGenerator
Generate Zod schemas from parsed types:
```typescript
import { ZodSchemaGenerator } from "typescript-runtime-schemas";
const schemas = ZodSchemaGenerator.generateSchemas(parsedTypes);
```
## Import Options
The package provides multiple import paths for different use cases:
```typescript
// Import everything (constraint types + API)
import {
Min,
Max,
SchemaExtractor,
SupportsRuntimeValidation,
} from "typescript-runtime-schemas";
// Import only constraint types
import {
Min,
Max,
Email,
UUID,
SupportsRuntimeValidation,
} from "typescript-runtime-schemas/types";
// Import only the programmatic API
import { SchemaExtractor, TypeResolver } from "typescript-runtime-schemas/api";
```
## Examples
### Basic Type with Constraints
```typescript
import {
Min,
Max,
Email,
SupportsRuntimeValidation,
} from "typescript-runtime-schemas";
type User = {
id: number & Min<1>;
email: string & Email;
age: number & Min<0> & Max<150>;
} & SupportsRuntimeValidation;
// Generated Zod schema:
// z.object({
// id: z.number().min(1),
// email: z.string().email(),
// age: z.number().min(0).max(150)
// })
```
### Complex Computed Types
```typescript
import {
MinLength,
UUID,
Positive,
SupportsRuntimeValidation,
} from "typescript-runtime-schemas";
type Order = {
id: string & UUID;
items: OrderItem[] & MinLength<1>;
total: number & Positive;
} & SupportsRuntimeValidation;
type OrderItem = {
productId: string & UUID;
quantity: number & Min<1>;
price: number & Positive;
} & SupportsRuntimeValidation;
// Create computed types for different use cases
type CreateOrderRequest = Omit<Order, "id"> & SupportsRuntimeValidation;
type OrderSummary = Pick<Order, "id" | "total"> & SupportsRuntimeValidation;
type UpdateOrderRequest = Partial<Pick<Order, "items" | "total">> &
SupportsRuntimeValidation;
```
### Integration with Build Process
```typescript
// build-schemas.ts
import { SchemaExtractor } from "typescript-runtime-schemas";
import { glob } from "fast-glob";
async function buildSchemas() {
const files = await glob("./src/**/*.ts");
for (const file of files) {
await SchemaExtractor.extractAndWriteZodSchemasFromFile(
file,
"./generated/schemas"
);
}
}
buildSchemas().catch(console.error);
```
## Performance & Parallel Processing
Schema Gen automatically optimizes performance for large codebases using parallel processing:
### Automatic Optimization
- **Small codebases** (≤10 types): Sequential processing for minimal overhead
- **Large codebases** (>10 types): Automatic parallel processing with optimal concurrency
- **Progress tracking**: Real-time progress updates for long-running operations
- **Memory management**: Adaptive concurrency based on memory usage
### Manual Configuration
```bash
# Control concurrency (default: number of CPU cores)
npx typescript-runtime-schemas extract ./src --concurrency 4
# Process in chunks for memory efficiency
npx typescript-runtime-schemas extract ./src --chunk-size 100
# Disable parallel processing
npx typescript-runtime-schemas extract ./src --no-parallel
# Enable progress tracking
npx typescript-runtime-schemas extract ./src --progress
# Memory-aware processing
npx typescript-runtime-schemas extract ./src --max-memory 512
```
### Programmatic API
```typescript
import { SchemaExtractor } from "typescript-runtime-schemas";
const result = await SchemaExtractor.extract(input, {
parallel: {
concurrency: 8, // Number of concurrent workers
useParallelProcessing: true, // Enable/disable parallel processing
chunkSize: 50, // Process types in chunks
enableProgressTracking: true, // Enable progress callbacks
maxMemoryMB: 512, // Memory limit for adaptive concurrency
onProgress: (progress) => {
// Progress callback with timing information
console.log(`${progress.percentage}% complete`);
console.log(`ETA: ${progress.eta}ms`);
console.log(`Rate: ${progress.rate} types/sec`);
},
},
});
```
### Performance Benefits
- **2-4x faster** processing on multi-core systems for large codebases
- **Memory efficient** chunked processing with adaptive concurrency
- **Graceful error handling** - failed types don't stop the entire process
- **Progress tracking** with ETA and processing rate information
- **Automatic optimization** - switches between sequential and parallel based on workload size
- **Semaphore-based concurrency control** - prevents resource exhaustion
## TypeScript Configuration
Ensure your `tsconfig.json` includes:
```json
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"strict": true
}
}
```
## Contributing
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## License
MIT License - see the [LICENSE](LICENSE) file for details.
## Support
- 📖 [Documentation](./docs)
- 🐛 [Issue Tracker](https://github.com/your-username/schema-gen/issues)
- 💬 [Discussions](https://github.com/your-username/schema-gen/discussions)