@connectedxm/zpl-generator
v0.0.15
Published
A TypeScript library for generating ZPL (Zebra Programming Language) code from structured badge configurations. This library provides type-safe APIs for creating thermal printer labels with text fields, barcodes, and QR codes.
Readme
ZPL Generator
A TypeScript library for generating ZPL (Zebra Programming Language) code from structured badge configurations. This library provides type-safe APIs for creating thermal printer labels with text fields, barcodes, and QR codes.
Features
- Type-Safe Configuration: Full TypeScript support with Zod validation schemas
- Thermal Badge Support: Generate ZPL for thermal transfer and direct thermal printers
- Multiple Block Types:
- Text fields with advanced formatting (word wrapping, alignment, vertical positioning)
- Barcodes (Code 128)
- QR codes with configurable error correction
- Comprehensive Printer Settings: Control print speed, darkness, orientation, media type, and more
- Validation: Built-in validation with detailed error messages
- Word Wrapping: Accurate line counting with optional word-width measurements for precise text layout
Installation
npm install cxm-zpl-generatorQuick Start
import { generate } from 'cxm-zpl-generator';
import {
ThermalBadge,
MediaType,
ThermalMediaType,
PrintOrientation,
FontOrientation,
TextAlignment,
VerticalAlignment,
PostPrintMode,
PrepeelMode,
AllMediaMode,
BackfeedAction,
ReverseMode,
PrintDensityAdjustment,
} from 'cxm-zpl-generator';
const badge: ThermalBadge = {
type: 'thermal',
tearOffAdjustment: 0,
backfeedActions: BackfeedAction.Normal,
media: MediaType.NonContinuousMarkSensing,
mediaOffset: 0,
thermalMediaType: ThermalMediaType.ThermalTransfer,
printOrientation: PrintOrientation.Normal,
mirror: MirrorMode.Normal,
labelHomeX: 20,
labelHomeY: 0,
printDensityAdjustment: PrintDensityAdjustment.Normal,
printSpeed: 1,
slewSpeed: 1,
backfeedSpeed: 1,
darkness: 30,
reverse: ReverseMode.Disable,
postPrintMode: PostPrintMode.TearOff,
prepeel: PrepeelMode.NoPrepeel,
printWidth: 900,
labelLength: 600,
allMedia: AllMediaMode.ContinuousOnly,
blocks: [
{
type: 'field',
name: 'title',
x: 0,
y: 100,
data: 'Hello World',
font: 'A',
fontHeight: 100,
maxWidth: 900,
maxLines: 1,
lineSpacing: 100,
alignment: TextAlignment.Center,
fontOrientation: FontOrientation.NoRotation,
hangingIndent: 0,
verticalAlignment: VerticalAlignment.Start,
},
],
};
const zpl = generate(badge);
console.log(zpl);
// Output: ^XA
// ~TA000
// ~JSN
// ...API Reference
generate(badge: Badge): string
Generates ZPL code from a badge configuration.
Parameters:
badge: A validatedBadgeobject (must be of type'thermal')
Returns: A string containing valid ZPL code
Example:
const zpl = generate(badge);
// Send zpl to your Zebra printervalidateBadge(data: unknown)
Validates a badge configuration object. Returns a Zod SafeParseReturnType with success/error information.
Example:
import { validateBadge } from 'cxm-zpl-generator';
const result = validateBadge(jsonData);
if (result.success) {
const badge = result.data; // Type-safe Badge object
const zpl = generate(badge);
} else {
console.error(result.error.errors);
}validateBadgeOrThrow(data: unknown)
Validates a badge configuration and throws a ZodError if validation fails.
Example:
import { validateBadgeOrThrow } from 'cxm-zpl-generator';
try {
const badge = validateBadgeOrThrow(jsonData);
const zpl = generate(badge);
} catch (error) {
// Handle validation error
}Badge Configuration
Base Badge Properties
All thermal badges require the following configuration:
| Property | Type | Description |
|----------|------|-------------|
| type | 'thermal' | Badge type (currently only thermal is supported) |
| tearOffAdjustment | number | Tear-off adjustment (0-120) |
| backfeedActions | BackfeedAction | Backfeed sequence configuration |
| media | MediaType | Media type (continuous, variable length, etc.) |
| mediaOffset | number | Media offset (-75 to 283) |
| thermalMediaType | ThermalMediaType | Direct thermal or thermal transfer |
| printOrientation | PrintOrientation | Normal or inverted |
| mirror | MirrorMode | Mirror mode setting |
| labelHomeX | number | Label home X coordinate (0-32000) |
| labelHomeY | number | Label home Y coordinate (0-32000) |
| printDensityAdjustment | PrintDensityAdjustment? | Optional print density adjustment |
| printSpeed | number | Print speed (1-14) |
| slewSpeed | number | Slew speed (1-14) |
| backfeedSpeed | number | Backfeed speed (1-14) |
| darkness | number | Print darkness (0-30) |
| reverse | ReverseMode | Reverse mode setting |
| postPrintMode | PostPrintMode | Post-print action (tear off, peel off, etc.) |
| prepeel | PrepeelMode | Prepeel mode setting |
| printWidth | number | Print width in dots (minimum 2) |
| labelLength | number | Label length in dots (1-32000) |
| allMedia | AllMediaMode | All media mode setting |
| blocks | Block[] | Array of content blocks |
Block Types
Field Block (Text)
Displays text with configurable font, size, alignment, and wrapping.
{
type: 'field',
name: 'field_name', // Identifier for the block
x: 0, // X position in dots
y: 100, // Y position in dots
data: 'Text content', // Text to display
font: 'A', // Font identifier (A-Z, 0-9)
fontHeight: 100, // Font height in dots (1-32000)
fontOrientation: FontOrientation, // Text rotation
maxWidth: 900, // Maximum width for wrapping (0-9999)
maxLines: 3, // Maximum number of lines (1-9999)
lineSpacing: 0, // Line spacing (-9999 to 9999)
alignment: TextAlignment, // Text alignment (Left, Right, Center, Justified)
hangingIndent: 0, // Hanging indent (0-9999)
verticalAlignment: VerticalAlignment, // Vertical alignment (Start, End)
wordWidths?: WordWidth[], // Optional word width measurements for accurate wrapping
}Vertical Alignment:
VerticalAlignment.Start: Text starts at the top of the fieldVerticalAlignment.End: Text is aligned to the bottom (uses only the lines needed, no line-break padding)
Word Widths:
For accurate text wrapping with proportional fonts, provide wordWidths:
wordWidths: [
{ word: 'Hello', width: 50, spaceWidth: 10 },
{ word: 'World', width: 60, spaceWidth: 10 },
]Barcode Block
Generates a Code 128 barcode.
{
type: 'barcode',
name: 'barcode_name',
x: 0,
y: 200,
data: '1234567890', // Barcode data
barWidth: 5, // Bar width multiplier (4-9999)
orientation: FontOrientation, // Barcode orientation
height: 60, // Barcode height in dots (1-32000)
line: YesNo, // Show human-readable line below
lineAbove: YesNo, // Show human-readable line above
checkDigit: YesNo, // Include check digit
}QR Code Block
Generates a QR code.
{
type: 'qrcode',
name: 'qrcode_name',
x: 0,
y: 300,
data: 'https://example.com', // QR code data
orientation: 'N', // Must be 'N' (no rotation)
model: '2', // Must be '2' (Model 2)
magnification: 5, // Magnification factor (1-100)
errorCorrection: QRCodeErrorCorrection, // Error correction level
mask: 0, // Mask pattern (0-7)
}Enums and Constants
Media Types
MediaType.Continuous- Continuous mediaMediaType.VariableLengthContinuous- Variable length continuousMediaType.NonContinuousWebSensing- Non-continuous web sensingMediaType.NonContinuousWebSensingAlt- Non-continuous web sensing (alternate)MediaType.NonContinuousMarkSensing- Non-continuous mark sensingMediaType.AutoDetect- Auto-detect media type
Thermal Media Types
ThermalMediaType.DirectThermal- Direct thermal printingThermalMediaType.ThermalTransfer- Thermal transfer printing
Text Alignment
TextAlignment.Left- Left-aligned textTextAlignment.Right- Right-aligned textTextAlignment.Center- Center-aligned textTextAlignment.Justified- Justified text
Font Orientation
FontOrientation.NoRotation- No rotation (0°)FontOrientation.Rotate90- Rotate 90° clockwiseFontOrientation.Rotate180- Rotate 180°FontOrientation.Rotate270- Rotate 270° clockwise
Post Print Modes
PostPrintMode.TearOff- Tear off after printingPostPrintMode.PeelOff- Peel off after printingPostPrintMode.Rewind- Rewind after printingPostPrintMode.Applicator- Applicator modePostPrintMode.Cut- Cut after printingPostPrintMode.DelayedCut- Delayed cutPostPrintMode.EncodeRFID- Encode RFIDPostPrintMode.Kiosk- Kiosk mode
QR Code Error Correction
QRCodeErrorCorrection.Highest- Highest error correction (~30%)QRCodeErrorCorrection.High- High error correction (~25%)QRCodeErrorCorrection.Medium- Medium error correction (~15%)QRCodeErrorCorrection.Lower- Lower error correction (~7%)
Advanced Usage
Dynamic Content with Templates
You can use template strings in your badge data and replace them before generating ZPL:
const badge: ThermalBadge = {
// ... configuration
blocks: [
{
type: 'field',
name: 'name',
x: 0,
y: 100,
data: '{{firstName}} {{lastName}}', // Template string
// ... other properties
},
],
};
// Replace template variables
const badgeWithData = {
...badge,
blocks: badge.blocks.map(block => ({
...block,
data: block.data
.replace('{{firstName}}', 'John')
.replace('{{lastName}}', 'Doe'),
})),
};
const zpl = generate(badgeWithData);Accurate Text Wrapping
For precise text layout with proportional fonts, measure word widths and provide them:
import { countLines } from 'cxm-zpl-generator';
// Measure word widths (e.g., using canvas or font metrics)
const wordWidths: WordWidth[] = [
{ word: 'Hello', width: 50, spaceWidth: 10 },
{ word: 'World', width: 60, spaceWidth: 10 },
];
const fieldBlock: FieldBlock = {
type: 'field',
name: 'text',
x: 0,
y: 0,
data: 'Hello World',
font: 'A',
fontHeight: 20,
maxWidth: 100,
maxLines: 5,
lineSpacing: 0,
alignment: TextAlignment.Left,
fontOrientation: FontOrientation.NoRotation,
hangingIndent: 0,
verticalAlignment: VerticalAlignment.End,
wordWidths, // Provide measured widths
};
// countLines can be used to preview line count
const lines = countLines(fieldBlock);
console.log(`Text will occupy ${lines} lines`);Validating JSON Configuration
When loading badge configurations from JSON files or APIs:
import { validateBadgeOrThrow, generate } from 'cxm-zpl-generator';
// Load from JSON file or API
const jsonData = await fetch('/api/badge-config').then(r => r.json());
try {
const badge = validateBadgeOrThrow(jsonData);
const zpl = generate(badge);
// Send to printer
} catch (error) {
if (error instanceof ZodError) {
console.error('Validation errors:', error.errors);
}
}Examples
See the examples/ directory for complete working examples:
simple-label.ts- Basic label with text fields and barcode
Testing
Run tests with:
npm testWatch mode:
npm run test:watchBuilding
Build the library:
npm run buildLicense
ISC
Contributing
Contributions are welcome! Please ensure all tests pass and follow the existing code style.
