ts-to-laravel-validate
v0.1.1
Published
Convert TypeScript interfaces/types into Laravel validation rule arrays.
Maintainers
Readme
ts2laravel-validate
Convert TypeScript interfaces and types into Laravel validation rule arrays.
Features
- 🔄 Automatically converts TypeScript types to Laravel validation rules
- 📝 Support for JSDoc
@laravelannotations for custom rules - 🎯 Handles enums, unions, arrays, nested objects, and optional fields
- 🔧 CLI and programmatic API
- 📦 Output as PHP array or JSON format
Installation
npm install ts-to-laravel-validateQuick Start
CLI Usage
# Generate validation rules from a TypeScript interface
npx ts2laravel-validate --file src/types/User.ts --type CreateUser
# Save to a file
npx ts2laravel-validate --file src/types/User.ts --type CreateUser --out validation/user.php
# Output as JSON
npx ts2laravel-validate --file src/types/User.ts --type CreateUser --format jsonProgrammatic Usage
import { generateLaravelRules } from 'ts-to-laravel-validate'
const rules = generateLaravelRules({
entryFile: 'src/types/User.ts',
rootTypeName: 'CreateUser',
outFormat: 'php', // or 'json'
strictArrays: false
})
console.log(rules)Type Mapping
TypeScript types are automatically mapped to Laravel validation rules:
| TypeScript Type | Laravel Rule |
|----------------|--------------|
| string | string |
| number | numeric |
| bigint | integer |
| boolean | boolean |
| Date | date |
| string[] | array with string elements |
| 'a' \| 'b' \| 'c' | in:a,b,c |
| field? | sometimes |
| field: T \| null | nullable |
Examples
Basic Example
// src/types/User.ts
export interface CreateUser {
name: string
email: string
age?: number
role: 'admin' | 'user' | 'guest'
}Output:
return [
'name' => 'required|string',
'email' => 'required|string',
'age' => 'sometimes|numeric',
'role' => 'required|in:admin,user,guest',
];Using JSDoc Annotations
You can add custom Laravel validation rules using @laravel JSDoc comments:
export interface CreateUser {
/** @laravel required|string|min:3|max:50 */
name: string
/** @laravel required|email|unique:users,email */
email: string
/** @laravel required|string|min:8|confirmed */
password: string
age?: number
}Output:
return [
'name' => 'required|string|min:3|max:50',
'email' => 'required|email|unique:users,email',
'password' => 'required|string|min:8|confirmed',
'age' => 'sometimes|numeric',
];Enums and Unions
export enum Role {
Admin = "admin",
User = "user"
}
export interface CreateUser {
role: Role | 'guest'
status: 'active' | 'inactive' | 'pending'
}Output:
return [
'role' => 'required|in:admin,user,guest',
'status' => 'required|in:active,inactive,pending',
];Arrays and Nested Objects
export interface CreateUser {
name: string
tags?: string[]
meta?: {
newsletter: boolean
score: number | null
}
profiles?: Profile[]
}
export interface Profile {
/** @laravel string|max:140 */
bio?: string | null
birthDate?: Date | null
}Output:
return [
'name' => 'required|string',
'tags' => 'sometimes|array',
'tags.*' => 'string',
'meta' => 'sometimes|array',
'meta.newsletter' => 'required|boolean',
'meta.score' => 'required|numeric',
'profiles' => 'sometimes|array',
'profiles.*' => 'array',
'profiles.*.bio' => 'sometimes|string|max:140',
'profiles.*.birthDate' => 'sometimes|date',
];CLI Options
ts2laravel-validate [options]
Options:
-f, --file <path> TypeScript entry file (required)
-t, --type <name> Root exported interface/type (required)
-p, --project <tsconfig> Path to tsconfig.json
-o, --out <path> Write output to file
--format <php|json> Output format (default: "php")
--strict-arrays Add 'present' to array parents (default: false)
-h, --help Display helpAPI Options
interface GenerateOptions {
entryFile: string // Path to TypeScript file
rootTypeName: string // Name of the exported type/interface
tsconfigPath?: string // Optional path to tsconfig.json
outFormat?: 'php' | 'json' // Output format (default: 'php')
strictArrays?: boolean // Add 'present' rule to arrays (default: false)
}Integration with Vue/TypeScript Projects
Add to package.json scripts
{
"scripts": {
"generate:validation": "ts2laravel-validate --file src/types/User.ts --type CreateUserDTO --out ../backend/validation/user.php"
}
}Use in Build Process
// scripts/generate-validation.ts
import { generateLaravelRules } from 'ts-to-laravel-validate'
import { writeFileSync } from 'fs'
import { glob } from 'glob'
// Generate validation for all DTO files
const dtoFiles = glob.sync('src/types/*DTO.ts')
dtoFiles.forEach(file => {
const typeName = file.match(/\/(\w+)\.ts$/)?.[1]
if (!typeName) return
const rules = generateLaravelRules({
entryFile: file,
rootTypeName: typeName,
outFormat: 'php'
})
writeFileSync(`../backend/validation/${typeName}.php`, rules)
})How It Works
- Parses TypeScript using ts-morph
- Analyzes types to determine appropriate Laravel validation rules
- Expands enums to their literal values for
in:rules - Handles unions by combining string/number literals into validation lists
- Processes nested structures using Laravel's dot notation
- Merges custom rules from
@laravelJSDoc comments
Limitations
- Only processes exported types/interfaces
- Limited to types that map to Laravel validation rules
- Complex conditional types may not be supported
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
