Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .kiro/steering/code-generation-flow.md
1 change: 1 addition & 0 deletions .kiro/steering/dependency-management.md
1 change: 1 addition & 0 deletions .kiro/steering/generic-types.md
1 change: 1 addition & 0 deletions .kiro/steering/handler-system.md
1 change: 1 addition & 0 deletions .kiro/steering/import-resolution.md
1 change: 1 addition & 0 deletions .kiro/steering/interface-inheritance.md
1 change: 1 addition & 0 deletions .kiro/steering/parser-system.md
1 change: 1 addition & 0 deletions .kiro/steering/project-overview.md
1 change: 1 addition & 0 deletions .kiro/steering/system-architecture.md
1 change: 1 addition & 0 deletions .kiro/steering/testing-strategy.md
1 change: 1 addition & 0 deletions .kiro/steering/utilities.md
1 change: 1 addition & 0 deletions .trae/rules/architecture.md
1 change: 1 addition & 0 deletions .trae/rules/code-generation-flow.md
1 change: 1 addition & 0 deletions .trae/rules/dependency-management.md
1 change: 1 addition & 0 deletions .trae/rules/generic-types.md
1 change: 1 addition & 0 deletions .trae/rules/handler-system.md
1 change: 1 addition & 0 deletions .trae/rules/import-resolution.md
1 change: 1 addition & 0 deletions .trae/rules/interface-inheritance.md
1 change: 1 addition & 0 deletions .trae/rules/overview.md
1 change: 1 addition & 0 deletions .trae/rules/parser-system.md
1 change: 0 additions & 1 deletion .trae/rules/project_architecture.md

This file was deleted.

1 change: 1 addition & 0 deletions .trae/rules/testing.md
1 change: 1 addition & 0 deletions .trae/rules/utilities.md
404 changes: 0 additions & 404 deletions ARCHITECTURE.md

This file was deleted.

72 changes: 57 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,68 @@
# TypeBox Codegen Fork
`@daxserver/validation-schema-codegen` transforms TypeScript type definitions into TypeBox validation schemas. It handles complex type relationships and manages dependencies through graph-based analysis.

This project is a code generation tool designed to automate the creation of TypeBox schemas from existing TypeScript source files. It leverages the `ts-morph` library to parse TypeScript code and extract structural information from various constructs, including:
## Usage

- **Type Aliases**: Converts TypeScript type aliases into corresponding TypeBox definitions.
- **Enums**: Transforms TypeScript enums into TypeBox enum schemas.
- **Interfaces**: Processes TypeScript interfaces to generate TypeBox object schemas.
- **Function Declarations**: Analyzes function signatures to create TypeBox schemas for their parameters and return types.
```typescript
import { generateCode } from '@daxserver/validation-schema-codegen'

The primary goal is to streamline the process of defining data validation and serialization schemas by generating them directly from your TypeScript types, ensuring type safety and consistency across your application.
// Using source code string
const result = generateCode({
sourceCode: `
interface User {
id: string;
name: string;
email?: string;
}
`,
callerFile: './src/types.ts',
})

## Installation
// Using file path
const result = generateCode({
filePath: './types.ts',
})
```

### Generated Output

```typescript
import { Type, Static } from '@sinclair/typebox'

export const User = Type.Object({
id: Type.String(),
name: Type.String(),
email: Type.Optional(Type.String()),
})

export type User = Static<typeof User>
```

To get started with this project, first ensure you have Bun installed. Then, install the project dependencies by running:
## Development Workflow

### Testing

```bash
bun install
# Run all tests
bun test

# Run specific test file
bun test tests/handlers/typebox/function-types.test.ts

# Type checking
bun typecheck

# Linting
bun lint

# Formatting
bun format
```

## Scripts
## Contributing

This project includes several utility scripts to help with development and maintenance:
When contributing to the project:

- `bun run format`: This script uses Prettier to automatically format all code files, ensuring consistent code style across the project.
- `bun run typecheck`: Runs the TypeScript compiler (`tsc`) with the `--noEmit` flag to perform a type check on the entire codebase. This helps catch type-related errors early in the development process.
- `bun run lint`: Executes ESLint to analyze the code for potential errors, stylistic issues, and adherence to best practices. This helps maintain code quality and consistency.
1. Read the relevant documentation sections for the area you're working on
2. Follow the TDD workflow outlined in [Testing Strategy](./docs/testing.md)
3. Ensure your changes align with the architectural patterns described in the documentation
4. Update documentation as needed for new features or changes
30 changes: 30 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Architecture

```
Input → Parser → Dependency Analysis → Handler System → Printer → Output
```

## Components

1. **Input Handler** - Processes file paths or source code strings
2. **Parser System** - Parses TypeScript AST using ts-morph
3. **Dependency Analysis** - Builds dependency graph and sorts types
4. **Handler System** - Converts TypeScript types to TypeBox expressions
5. **Printer** - Generates output code

## Process

1. Parse TypeScript source to AST
2. Extract type declarations
3. Build dependency graph
4. Sort types by dependencies
5. Convert each type to TypeBox expression
6. Generate output code

## Key Files

- `src/index.ts` - Main entry point
- `src/parsers/` - TypeScript AST parsers
- `src/handlers/` - Type conversion handlers
- `src/traverse/` - Dependency analysis
- `src/printer/` - Code generation
75 changes: 75 additions & 0 deletions docs/code-generation-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Code Generation Flow

Process for transforming TypeScript types to TypeBox schemas.

## Main Pipeline

```typescript
export function generateCode(options: InputOptions): string
```

### Steps

1. **Input Processing** - Create SourceFile from input
2. **Generic Detection** - Check for generic types to determine imports
3. **Output Setup** - Create output file with TypeBox imports
4. **Dependency Analysis** - Use DependencyTraversal to sort types
5. **Code Generation** - Process nodes through TypeBoxPrinter
6. **Output** - Return formatted code

## Input Types

```typescript
interface InputOptions {
filePath?: string // File path
sourceCode?: string // Source code string
callerFile?: string // Context for relative imports
project?: Project // Existing ts-morph Project
}
```

## Processing Stages

### 1. Input Handling

- File path: Load and parse TypeScript file
- Source code: Process in-memory code with validation
- Project reuse: Share ts-morph Project instances

### 2. Dependency Analysis

Three-tier approach:

- **DependencyTraversal** - Orchestrates analysis
- **FileGraph** - File-level dependencies
- **NodeGraph** - Type-level dependencies and sorting

### 3. Type Conversion

Each type processed through specialized parsers:

- Type aliases → TypeAliasParser
- Interfaces → InterfaceParser
- Enums → EnumParser
- Functions → FunctionDeclarationParser

### 4. Code Generation

For each type:

1. Generate TypeBox schema variable
2. Generate static type alias
3. Handle generic types with arrow functions

## Output Format

```typescript
import { Type, Static } from '@sinclair/typebox'

export const User = Type.Object({
id: Type.String(),
name: Type.String(),
})

export type User = Static<typeof User>
```
56 changes: 56 additions & 0 deletions docs/dependency-management.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Dependency Management

Graph-based dependency analysis for proper type processing order.

## Components

### DependencyTraversal

Main orchestrator in `src/traverse/dependency-traversal.ts`:

- Coordinates dependency collection
- Returns topologically sorted nodes

### FileGraph

Manages file-level dependencies in `src/traverse/file-graph.ts`:

- Tracks import relationships
- Detects circular imports

### NodeGraph

Handles type-level dependencies in `src/traverse/node-graph.ts`:

- Maps type relationships
- Performs topological sorting
- Detects circular type dependencies

## Process

1. Collect local types from main file
2. Process import chains recursively
3. Extract type dependencies
4. Build dependency graph
5. Topological sort for processing order

## Circular Dependencies

### Detection

- File-level: A imports B, B imports A
- Type-level: Type A references Type B, Type B references Type A

### Resolution

- Forward declarations using `Type.Ref()`
- Error reporting with dependency chains

## Visualization

`GraphVisualizer` generates interactive HTML visualizations:

- Sigma.js integration
- Custom node shapes for different types
- Color coding by import depth
- WebGL rendering for performance
59 changes: 59 additions & 0 deletions docs/generic-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Generic Types

Supports generic interfaces and type aliases.

## Processing

Both interfaces and type aliases use `GenericTypeUtils.createGenericArrowFunction` for consistency.

### Type Aliases

```typescript
// TypeScript
type ApiResponse<T> = { data: T; success: boolean }

// Generated TypeBox
export const ApiResponse = <T extends TSchema>(T: T) =>
Type.Object({
data: T,
success: Type.Boolean(),
})

export type ApiResponse<T> = Static<ReturnType<typeof ApiResponse<T>>>
```

### Interfaces

```typescript
// TypeScript
interface Repository<T> {
findById(id: string): Promise<T>
}

// Generated TypeBox
export const Repository = <T extends TSchema>(T: T) =>
Type.Object({
findById: Type.Function([Type.String()], Type.Promise(T)),
})
```

## Type Parameters

All type parameters use `TSchema` constraints for TypeBox compatibility:

```typescript
// TypeScript: T extends object
// TypeBox: T extends TSchema
```

## Multiple Parameters

```typescript
type Result<T, E> = { success: true; data: T } | { success: false; error: E }

export const Result = <T extends TSchema, E extends TSchema>(T: T, E: E) =>
Type.Union([
Type.Object({ success: Type.Literal(true), data: T }),
Type.Object({ success: Type.Literal(false), error: E }),
])
```
Loading