# Lite Transformer Processors This directory contains the processor architecture for the `lite-transformer` plugin. ## Architecture The lite-transformer uses a modular processor-based architecture where each processor handles a specific transformation: ``` lite-transformer ├── BaseProcessor (abstract) ├── ClassDecoratorProcessor ├── SignalTransformerProcessor ├── TemplateProcessor ├── StyleProcessor └── DIProcessor ``` ## Processors ### BaseProcessor Abstract base class that all processors must extend. **Interface:** ```typescript abstract class BaseProcessor { abstract get name(): string; abstract process(context: ProcessorContext): Promise; } ``` ### TemplateProcessor Transforms `templateUrl` properties to inline `template` properties and processes Angular attributes. **Transformation:** ```typescript // Before templateUrl = './component.html' // After template = `
Component content
` ``` **Features:** - Reads HTML file from disk - Transforms Angular control flow syntax (`@if/@else` → `*ngIf`) - Parses and processes Angular attributes using helper system - Escapes template string characters - Throws error if file not found **Template Processing Pipeline:** 1. Read template file from disk 2. Transform control flow syntax 3. Parse HTML to element tree 4. Process attributes with specialized helpers 5. Reconstruct HTML from element tree 6. Escape template string characters **Supported Attribute Types:** - Structural directives: `*ngIf`, `*ngFor`, `*ngSwitch` - Input bindings: `[property]` - Output bindings: `(event)` - Two-way bindings: `[(model)]` - Template references: `#ref` See [helpers/README.md](../helpers/README.md) for detailed information about the attribute helper system. ### StyleProcessor Transforms `styleUrl` and `styleUrls` properties to inline `style` properties. **Transformations:** ```typescript // Single style file styleUrl = './component.scss' // → style = `:host { ... }` // Multiple style files styleUrls = ['./base.scss', './theme.scss'] // → style = `/* base.scss */\n/* theme.scss */` ``` **Features:** - Handles both `styleUrl` (single) and `styleUrls` (array) - Combines multiple style files with newline separator - Escapes template string characters - Throws error if any file not found ### DIProcessor Adds dependency injection metadata to classes with constructor parameters. **Transformation:** ```typescript // Before export class MyService { constructor(private http: HttpClient) {} } // After export class MyService { static __di_params__ = [HttpClient]; constructor(private http: HttpClient) {} } ``` **Features:** - Extracts constructor parameter types - Adds static `__di_params__` property - Skips classes without constructor parameters ### SignalTransformerProcessor Transforms Angular-like signal function calls (`input`, `output`) to include property name and `this` as arguments, and ensures `_nativeElement: HTMLElement` is available in the constructor. **Transformation:** ```typescript // Before export class MyComponent { public userName = input(); private clicked = output(); readonly count = input(0); constructor(private service: SomeService) {} } // After export class MyComponent { public userName = input("userName", this); private clicked = output("clicked", this); readonly count = input("count", this, 0); constructor(public _nativeElement: HTMLElement, private service: SomeService) {} } ``` **Features:** - Extracts property name and adds it as first argument (string) - Adds `this` as second argument for component context - Handles generic type parameters (e.g., `input()`) - Preserves existing arguments after `this` - Adds `public _nativeElement: HTMLElement` to constructor if not present - Skips if `HTMLElement` or `_nativeElement` already exists in constructor - Throws `SignalTransformerError` if property name cannot be determined **Supported Functions:** - `input` - Input signal binding (property name used for attribute binding) - `output` - Output signal binding (property name used for event name) **Error Handling:** If the processor cannot determine the property name (e.g., signal used outside of property assignment), it throws a `SignalTransformerError` which stops the build with a clear error message. ## Usage ### Using the Default Transformer ```typescript import { liteTransformer } from './lite-transformer'; // Uses all processors in default order plugins: [liteTransformer()] ``` ### Custom Processor Configuration ```typescript import { liteTransformer } from './lite-transformer'; import { TemplateProcessor, StyleProcessor } from './processors'; // Use only specific processors plugins: [ liteTransformer([ new TemplateProcessor(), new StyleProcessor() ]) ] ``` ### Creating Custom Processors ```typescript import { BaseProcessor, ProcessorContext, ProcessorResult } from './processors'; export class CustomProcessor extends BaseProcessor { get name(): string { return 'custom-processor'; } async process(context: ProcessorContext): Promise { // Your transformation logic return { source: context.source, modified: false }; } } ``` ## Processor Execution Order Processors execute in the order they are registered: 1. **ClassDecoratorProcessor** - Processes class decorators 2. **SignalTransformerProcessor** - Transforms signal function calls 3. **TemplateProcessor** - Inlines HTML templates 4. **StyleProcessor** - Inlines CSS styles 5. **DIProcessor** - Adds DI metadata Each processor receives the output of the previous processor, allowing for chained transformations. ## Error Handling All processors throw errors for missing files: ```typescript throw new Error(`Template file not found: ${fullPath} (referenced in ${context.filePath})`); ``` This ensures build-time validation of all referenced assets.