# TransAI Print Connector

A flexible print connector for generating and sending labels to Zebra printers (ZPL) or generating PDF documents. Supports text, images (including SVG), QR codes, barcodes, and lines.

## Features

- ✅ **Dual Output**: Generate ZPL for Zebra printers or PDF documents
- ✅ **Template-Based**: JSON template system with variable interpolation
- ✅ **Image Support**: SVG, PNG, JPEG converted to ZPL GRF format or embedded in PDF
- ✅ **QR Codes & Barcodes**: Built-in support for QR codes and CODE128 barcodes
- ✅ **Font Styling**: Bold and regular text with optimized spacing
- ✅ **Actions Support**: Integrates with TransAI action system

## Installation

This connector is part of the TransAI monorepo and uses the connector SDK.

### Dependencies

```json
{
  "dependencies": {
    "@transai/connector-runtime-sdk": "*",
    "sharp": "^0.33.0",
    "zpl-image": "^0.3.0",
    "bwip-js": "^4.0.0",
    "pdfkit": "^0.13.0",
    "qrcode": "^1.5.0",
    "svg-to-pdfkit": "^0.18.0",
    "axios": "^1.6.0"
  }
}
```

## Configuration

### ZPL Printer Configuration

```json
{
  "printerType": "zpl",
  "printerUrl": "http://192.168.1.100:9100",
  "printerTimeout": 30000
}
```

### PDF Configuration

```json
{
  "printerType": "pdf",
  "targetDir": "/path/to/output",
  "targetShare": "smb://server/share"
}
```

## Template Format

Templates are JSON objects defining the label layout:

```json
{
  "width": 100,
  "height": 150,
  "elements": [
    {
      "type": "text",
      "x": 10,
      "y": 10,
      "content": "{{productName}}",
      "fontSize": 14,
      "fontWeight": "bold"
    },
    {
      "type": "qr",
      "x": 10,
      "y": 30,
      "content": "{{serialNumber}}",
      "size": 20,
      "errorCorrection": "M"
    },
    {
      "type": "barcode",
      "x": 10,
      "y": 60,
      "content": "{{barcode}}",
      "width": 60,
      "height": 15,
      "barcodeType": "CODE128"
    },
    {
      "type": "image",
      "x": 5,
      "y": 5,
      "src": "/path/to/logo.svg",
      "width": 40,
      "height": 12
    },
    {
      "type": "line",
      "x": 10,
      "y": 25,
      "x2": 90,
      "y2": 25,
      "thickness": 0.5
    }
  ]
}
```

### Element Types

#### Text
- `type`: "text"
- `x`, `y`: Position in mm
- `content`: Text content (supports `{{variables}}`)
- `fontSize`: Font size in points (default: 12)
- `fontWeight`: "regular" or "bold" (default: "regular")
- `alignment`: "left", "center", or "right" (default: "left")
- `width`: Width for alignment (optional)

#### QR Code
- `type`: "qr"
- `x`, `y`: Position in mm
- `content`: QR code data (supports `{{variables}}`)
- `size`: Size in mm
- `errorCorrection`: "L", "M", "Q", or "H" (default: "M")

#### Barcode
- `type`: "barcode"
- `x`, `y`: Position in mm
- `content`: Barcode data (supports `{{variables}}`)
- `width`: Width in mm
- `height`: Height in mm
- `barcodeType`: "CODE128", "CODE39", "EAN13", etc.

#### Image
- `type`: "image"
- `x`, `y`: Position in mm
- `src`: File path or base64 data URL
- `width`: Width in mm
- `height`: Height in mm

#### Line
- `type`: "line"
- `x`, `y`: Start position in mm
- `x2`, `y2`: End position in mm
- `thickness`: Line thickness in mm

## Usage

### Programmatic Usage

```typescript
import { ZPLGenerator } from './lib/zpl-generator';
import { PDFGenerator } from './lib/pdf-generator';

// Generate ZPL
const zplGenerator = new ZPLGenerator(203); // 203 DPI
const zpl = await zplGenerator.generate(template, data);

// Generate PDF
const pdfGenerator = new PDFGenerator();
const pdfBuffer = await pdfGenerator.generate(template, data);
```

### Action Handler

The connector automatically handles actions from the TransAI system:

```typescript
{
  "type": "JOB",
  "actionIdentifier": "print-label",
  "actionVersion": "1.0.0",
  "config": {
    "template": { /* template object */ }
  },
  "payload": {
    "params": {
      "productName": "Widget A",
      "serialNumber": "SN-12345"
    }
  }
}
```

Supports batch printing by passing an array:

```typescript
{
  "payload": {
    "params": [
      { "productName": "Widget A", "serialNumber": "SN-001" },
      { "productName": "Widget B", "serialNumber": "SN-002" }
    ]
  }
}
```

## Font Specifications

### ZPL Fonts
- **Bold Text**: Font 0, 15% larger than base size, 0.85 width ratio
- **Regular Text**: Font F (Univers), 0.6 width ratio

### PDF Fonts
- **Bold Text**: Roboto Bold (fallback: Helvetica-Bold)
- **Regular Text**: Roboto Regular (fallback: Helvetica)

Fonts are loaded from system paths:
- `/usr/share/fonts/truetype/roboto/unhinted/RobotoTTF/`

## Image Conversion

Images are automatically converted based on output format:

### For ZPL
1. Load image using `sharp`
2. Resize to specified dimensions
3. Convert to PNG
4. Extract RGBA pixel data
5. Convert to Z64-encoded GRF format using `zpl-image`
6. Embed in ZPL with `^GFA` command

### For PDF
1. SVG: Rendered directly as vector graphics
2. PNG/JPEG: Embedded as raster images

## Size Optimizations

### QR Codes
- Magnification: 4 (43% smaller than default)
- Remains scannable at standard distances

### Barcodes
- Height: 60% of specified height
- Maintains readability while reducing size

## Testing

Run the test suite:

```bash
npx nx test connector-runner-print
```

### Generating Demo Files

To generate ZPL and PDF from the complete-demo.json template:

```bash
# From workspace root:
npx nx generate-demo connector-runner-print

# Or using npm (from libs/connector-runner-print directory):
cd libs/connector-runner-print
npm run generate-demo
```

This creates:
- `libs/connector-runner-print/complete-demo.zpl` - ZPL code for Zebra printers
- `libs/connector-runner-print/complete-demo.pdf` - PDF version for preview

**What's included:**
- TransAI Logo (SVG → ZPL GRF format)
- Text elements (regular, bold, centered)
- Lines (horizontal and vertical)
- QR codes with error correction
- CODE128 barcodes  
- Placeholder images

**Technical Details:**
- Images are processed using `sharp` to resize and extract RGBA data
- RGBA data is converted to Z64-encoded GRF format using `zpl-image`
- The conversion uses a 50% threshold for black/white
- Images are embedded directly in the ZPL with the `^GFA` command

## Examples

Example templates are located in `examples/`:
- `complete-demo.json` - Demonstrates all element types
- `shipping.json` - Shipping label template
- `product.json` - Product label template

## Architecture

### Core Components

- **ZPLGenerator**: Converts templates to ZPL format
- **PDFGenerator**: Converts templates to PDF format
- **ActionsHandler**: Handles action execution and printer communication

### Processing Flow

```
Template + Data → Generator → Output
                     ↓
              ZPL or PDF
                     ↓
           Zebra Printer or File
```

## Error Handling

- Missing images are skipped with a warning
- Invalid template elements are ignored
- Printer communication errors are logged and returned as failed status
- All errors include detailed logging for debugging

## Performance

- Template generation: ~50ms per label
- Image conversion: ~100-200ms per image (depending on size)
- Batch printing: Sequential to avoid overwhelming printer

## Limitations

- Maximum label size: Limited by printer
- Image formats: SVG, PNG, JPEG, GIF supported
- Barcode types: Limited to types supported by bwip-js
- Font embedding: Roboto fonts must be installed on system for PDF

## License

LGPL-3.0-or-later

## Author

TransAI
- Email: samen@transai.com
- Website: https://transai.com

