UNPKG

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
# 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)