@bobfrankston/brother-label 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,629 @@
1
+ #!/usr/bin/env node
2
+ import { Jimp, loadFont, measureText, measureTextHeight } from "jimp";
3
+ import { program } from "commander";
4
+ import { exec, spawn } from "child_process";
5
+ import * as fs from "fs";
6
+ import * as path from "path";
7
+ import * as os from "os";
8
+ import { renderHtmlFile, closeBrowser } from "./render.js";
9
+ import QRCode from "qrcode";
10
+ const __dirname = import.meta.dirname;
11
+ const CONFIG_PATH = path.join(os.homedir(), ".brother-label.json");
12
+ function loadConfig() {
13
+ try {
14
+ if (fs.existsSync(CONFIG_PATH)) {
15
+ return JSON.parse(fs.readFileSync(CONFIG_PATH, "utf-8"));
16
+ }
17
+ }
18
+ catch (err) {
19
+ // Ignore config errors
20
+ }
21
+ return {};
22
+ }
23
+ function saveConfig(config) {
24
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
25
+ }
26
+ // Available font sizes in jimp
27
+ const FONT_SIZES = [128, 64, 32, 16, 14, 12, 10, 8];
28
+ async function loadFontBySize(size) {
29
+ const fontDir = path.join(__dirname, "node_modules/@jimp/plugin-print/fonts/open-sans");
30
+ const fontFolder = `open-sans-${size}-black`;
31
+ const fontPath = path.join(fontDir, fontFolder, `${fontFolder}.fnt`);
32
+ return loadFont(fontPath);
33
+ }
34
+ async function createLabelImage(text, options) {
35
+ const lines = text.split("\\n").join("\n");
36
+ const targetHeight = options.height;
37
+ // Use largest font for best quality, then scale down
38
+ let font = await loadFontBySize(128);
39
+ // Render text at large size first
40
+ const textWidth = measureText(font, lines);
41
+ const textHeight = measureTextHeight(font, lines, textWidth + 100);
42
+ // Create image for text with small padding
43
+ const padding = 10;
44
+ const imgWidth = textWidth + padding * 2;
45
+ const imgHeight = textHeight + padding * 2;
46
+ const tempImage = new Jimp({ width: imgWidth, height: imgHeight, color: 0xffffffff });
47
+ tempImage.print({
48
+ font: font,
49
+ x: padding,
50
+ y: padding,
51
+ text: lines,
52
+ });
53
+ // Scale to fit tape height (tape sizes already account for printable area)
54
+ const scale = targetHeight / imgHeight;
55
+ const finalWidth = Math.round(imgWidth * scale);
56
+ const finalHeight = Math.round(imgHeight * scale);
57
+ tempImage.resize({ w: finalWidth, h: finalHeight });
58
+ // Create final image sized to content with small horizontal padding
59
+ const hPadding = Math.round(targetHeight * 0.2); // ~20% of height as side margins
60
+ const outputWidth = finalWidth + hPadding * 2;
61
+ const image = new Jimp({ width: outputWidth, height: targetHeight, color: 0xffffffff });
62
+ // Center both horizontally and vertically
63
+ const xOffset = hPadding;
64
+ const yOffset = Math.round((targetHeight - finalHeight) / 2);
65
+ image.composite(tempImage, xOffset, yOffset);
66
+ return image.getBuffer("image/png");
67
+ }
68
+ async function createQrLabelImage(data, options, labelText) {
69
+ const targetHeight = options.height;
70
+ const qrSize = Math.floor(targetHeight * 0.95); // QR code is 95% of tape height
71
+ // Margins in mm converted to pixels at PRINT_DPI
72
+ // Left margin ~2mm, right margin ~4mm to account for printer feed
73
+ const pxPerMm = PRINT_DPI / 25.4;
74
+ const leftMargin = Math.round(2 * pxPerMm);
75
+ const rightMargin = Math.round(4 * pxPerMm);
76
+ // Generate QR code as PNG buffer at high resolution
77
+ const qrBuffer = await QRCode.toBuffer(data, {
78
+ type: "png",
79
+ width: qrSize,
80
+ margin: 0,
81
+ errorCorrectionLevel: "M",
82
+ color: { dark: "#000000", light: "#ffffff" },
83
+ });
84
+ const qrImage = await Jimp.read(qrBuffer);
85
+ if (!labelText) {
86
+ // QR only - create minimal label with margins
87
+ const outputWidth = leftMargin + qrSize + rightMargin;
88
+ const image = new Jimp({ width: outputWidth, height: targetHeight, color: 0xffffffff });
89
+ const yOffset = Math.floor((targetHeight - qrSize) / 2);
90
+ image.composite(qrImage, leftMargin, yOffset);
91
+ return image.getBuffer("image/png");
92
+ }
93
+ // QR + text label
94
+ const font = await loadFontBySize(64);
95
+ const textWidth = measureText(font, labelText);
96
+ const textHeight = measureTextHeight(font, labelText, textWidth + 50);
97
+ // Scale text to fit beside QR
98
+ const maxTextHeight = targetHeight * 0.8;
99
+ const textScale = Math.min(1, maxTextHeight / textHeight);
100
+ const scaledTextWidth = Math.round(textWidth * textScale);
101
+ const scaledTextHeight = Math.round(textHeight * textScale);
102
+ // Create text image
103
+ const textImg = new Jimp({ width: textWidth + 20, height: textHeight + 20, color: 0xffffffff });
104
+ textImg.print({ font, x: 10, y: 10, text: labelText });
105
+ if (textScale < 1) {
106
+ textImg.resize({ w: scaledTextWidth, h: scaledTextHeight });
107
+ }
108
+ // Compose final image: QR on left, text on right
109
+ const gap = Math.floor(targetHeight * 0.15);
110
+ const outputWidth = leftMargin + qrSize + gap + scaledTextWidth + rightMargin;
111
+ const image = new Jimp({ width: outputWidth, height: targetHeight, color: 0xffffffff });
112
+ const qrY = Math.floor((targetHeight - qrSize) / 2);
113
+ image.composite(qrImage, leftMargin, qrY);
114
+ const textY = Math.floor((targetHeight - scaledTextHeight) / 2);
115
+ image.composite(textImg, leftMargin + qrSize + gap, textY);
116
+ return image.getBuffer("image/png");
117
+ }
118
+ async function printImage(imagePath, printerName, tapeMm) {
119
+ // Map tape mm to Brother CustomMediaSize for PrintTicket
120
+ const mediaOptions = {
121
+ 6: { name: "CustomMediaSize257", width: 5900 },
122
+ 9: { name: "CustomMediaSize258", width: 9000 },
123
+ 12: { name: "CustomMediaSize259", width: 11900 },
124
+ 18: { name: "CustomMediaSize260", width: 18100 },
125
+ 24: { name: "CustomMediaSize261", width: 24000 },
126
+ };
127
+ const media = mediaOptions[tapeMm] || mediaOptions[12];
128
+ return new Promise((resolve, reject) => {
129
+ const psScript = `
130
+ Add-Type -AssemblyName System.Drawing
131
+ Add-Type -AssemblyName System.Printing
132
+ Add-Type -AssemblyName ReachFramework
133
+ Add-Type -AssemblyName PresentationCore
134
+
135
+ $img = [System.Drawing.Image]::FromFile('${imagePath.replace(/\\/g, "\\\\")}')
136
+
137
+ # Calculate label dimensions in microns (using ${PRINT_DPI} DPI source images)
138
+ $labelLengthMicrons = [int]($img.Width / ${PRINT_DPI}.0 * 25400) + 3000
139
+ $tapeWidthMicrons = ${media.width}
140
+
141
+ # Image dimensions in WPF units (1/96 inch) - convert from ${PRINT_DPI} DPI source
142
+ $imgWidthWpf = $img.Width / ${PRINT_DPI}.0 * 96
143
+ $imgHeightWpf = $img.Height / ${PRINT_DPI}.0 * 96
144
+
145
+ Write-Host "Using ${tapeMm}mm tape, label length: $([int]($labelLengthMicrons/1000))mm"
146
+
147
+ # Build PrintTicket XML
148
+ $ticketXml = @"
149
+ <?xml version="1.0" encoding="UTF-8"?>
150
+ <psf:PrintTicket xmlns:psf="http://schemas.microsoft.com/windows/2003/08/printing/printschemaframework"
151
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1"
152
+ xmlns:psk="http://schemas.microsoft.com/windows/2003/08/printing/printschemakeywords"
153
+ xmlns:ns0001="http://schemas.brother.info/mfc/printing/2006/11/printschemakeywords">
154
+ <psf:Feature name="psk:PageMediaSize">
155
+ <psf:Option name="ns0001:${media.name}">
156
+ <psf:ScoredProperty name="psk:MediaSizeWidth">
157
+ <psf:Value xsi:type="xsd:integer">${media.width}</psf:Value>
158
+ </psf:ScoredProperty>
159
+ <psf:ScoredProperty name="psk:MediaSizeHeight">
160
+ <psf:ParameterRef name="psk:PageMediaSizeMediaSizeHeight" />
161
+ </psf:ScoredProperty>
162
+ </psf:Option>
163
+ </psf:Feature>
164
+ <psf:ParameterInit name="psk:PageMediaSizeMediaSizeHeight">
165
+ <psf:Value xsi:type="xsd:integer">$labelLengthMicrons</psf:Value>
166
+ </psf:ParameterInit>
167
+ <psf:Feature name="psk:PageOrientation">
168
+ <psf:Option name="psk:Landscape" />
169
+ </psf:Feature>
170
+ <psf:Feature name="ns0001:PageRollFeedToEndOfSheet">
171
+ <psf:Option name="ns0001:FeedToImageEdge" />
172
+ </psf:Feature>
173
+ <psf:Feature name="psk:PageMediaType">
174
+ <psf:Option name="psk:Label" />
175
+ </psf:Feature>
176
+ <psf:Feature name="ns0001:JobRollCutSheet">
177
+ <psf:Option name="ns0001:CutSheet" />
178
+ </psf:Feature>
179
+ </psf:PrintTicket>
180
+ "@
181
+
182
+ $xmlBytes = [System.Text.Encoding]::UTF8.GetBytes($ticketXml)
183
+ $memStream = New-Object System.IO.MemoryStream(,$xmlBytes)
184
+ $ticket = New-Object System.Printing.PrintTicket($memStream)
185
+
186
+ # Get print queue and create XPS document writer with our ticket
187
+ $server = New-Object System.Printing.LocalPrintServer
188
+ $queue = $server.GetPrintQueue('${printerName}')
189
+
190
+ # Create temp XPS file
191
+ $xpsPath = [System.IO.Path]::GetTempFileName() + ".xps"
192
+
193
+ # Page size in WPF units (96 dpi) - convert from microns
194
+ $pageWidth = $labelLengthMicrons / 25400.0 * 96 # length is horizontal
195
+ $pageHeight = $tapeWidthMicrons / 25400.0 * 96 # tape width is vertical
196
+
197
+ # Create XPS document
198
+ $package = [System.IO.Packaging.Package]::Open($xpsPath, [System.IO.FileMode]::Create)
199
+ $xpsDoc = New-Object System.Windows.Xps.Packaging.XpsDocument($package)
200
+ $writer = [System.Windows.Xps.Packaging.XpsDocument]::CreateXpsDocumentWriter($xpsDoc)
201
+
202
+ # Create visual with image
203
+ $visual = New-Object System.Windows.Media.DrawingVisual
204
+ $dc = $visual.RenderOpen()
205
+
206
+ # Load image as WPF bitmap
207
+ $bitmapImg = New-Object System.Windows.Media.Imaging.BitmapImage
208
+ $bitmapImg.BeginInit()
209
+ $bitmapImg.UriSource = New-Object System.Uri('${imagePath.replace(/\\/g, "\\\\")}')
210
+ $bitmapImg.EndInit()
211
+
212
+ # Draw image centered vertically on page
213
+ $yOffset = ($pageHeight - $imgHeightWpf) / 2
214
+ $rect = New-Object System.Windows.Rect(0, $yOffset, $imgWidthWpf, $imgHeightWpf)
215
+ $dc.DrawImage($bitmapImg, $rect)
216
+ $dc.Close()
217
+
218
+ # Write to XPS with page size
219
+ $pageSize = New-Object System.Printing.PageMediaSize($pageWidth, $pageHeight)
220
+ $writer.Write($visual, $ticket)
221
+
222
+ $xpsDoc.Close()
223
+ $package.Close()
224
+ $img.Dispose()
225
+
226
+ # Print the XPS file with our ticket
227
+ $xpsDocForPrint = New-Object System.Windows.Xps.Packaging.XpsDocument($xpsPath, [System.IO.FileAccess]::Read)
228
+ $seq = $xpsDocForPrint.GetFixedDocumentSequence()
229
+
230
+ $xpsWriter = [System.Printing.PrintQueue]::CreateXpsDocumentWriter($queue)
231
+ $xpsWriter.Write($seq, $ticket)
232
+
233
+ $xpsDocForPrint.Close()
234
+ Remove-Item $xpsPath -ErrorAction SilentlyContinue
235
+
236
+ Write-Host "Print complete"
237
+ `;
238
+ const ps = spawn("powershell", ["-Command", psScript], { stdio: "pipe" });
239
+ let stdout = "";
240
+ let stderr = "";
241
+ ps.stdout.on("data", (data) => {
242
+ stdout += data.toString();
243
+ });
244
+ ps.stderr.on("data", (data) => {
245
+ stderr += data.toString();
246
+ });
247
+ ps.on("close", (code) => {
248
+ if (stdout)
249
+ console.log(stdout.trim());
250
+ if (code === 0) {
251
+ resolve();
252
+ }
253
+ else {
254
+ reject(new Error(`Print failed: ${stderr}`));
255
+ }
256
+ });
257
+ ps.on("error", (err) => {
258
+ reject(new Error(`Failed to print: ${err.message}`));
259
+ });
260
+ });
261
+ }
262
+ async function printLabel(text, options) {
263
+ // Create temp file for the image
264
+ const tempDir = os.tmpdir();
265
+ const tempFile = path.join(tempDir, `label-${Date.now()}.png`);
266
+ try {
267
+ const imageBuffer = await createLabelImage(text, options);
268
+ fs.writeFileSync(tempFile, imageBuffer);
269
+ await printImage(tempFile, options.printer, options.tapeMm);
270
+ }
271
+ finally {
272
+ // Clean up temp file
273
+ if (fs.existsSync(tempFile)) {
274
+ fs.unlinkSync(tempFile);
275
+ }
276
+ }
277
+ }
278
+ async function printHtmlLabel(htmlPath, options) {
279
+ const tempDir = os.tmpdir();
280
+ const tempFile = path.join(tempDir, `label-html-${Date.now()}.png`);
281
+ try {
282
+ // CSS mm units use 96 DPI. Convert tape mm to CSS pixels, then scale up.
283
+ // For 12mm tape: 12mm * 3.78 px/mm = ~45px CSS height
284
+ // deviceScaleFactor of 300/96 ≈ 3.125 gives us 300 DPI output
285
+ const cssPixelsPerMm = 96 / 25.4; // ~3.78
286
+ const viewportHeight = Math.round(options.tapeMm * cssPixelsPerMm);
287
+ const viewportWidth = Math.round(viewportHeight * 5); // ~5:1 aspect for labels
288
+ const scaleFactor = PRINT_DPI / 96; // Scale CSS pixels to print DPI
289
+ const renderedBuffer = await renderHtmlFile(htmlPath, {
290
+ width: viewportWidth,
291
+ height: viewportHeight,
292
+ deviceScaleFactor: scaleFactor,
293
+ keepScale: true, // Keep full resolution for printing
294
+ });
295
+ // Add margins for printer feed (3mm left, 4mm right)
296
+ const pxPerMm = PRINT_DPI / 25.4;
297
+ const leftMargin = Math.round(3 * pxPerMm);
298
+ const rightMargin = Math.round(4 * pxPerMm);
299
+ const rendered = await Jimp.read(renderedBuffer);
300
+ const paddedWidth = rendered.width + leftMargin + rightMargin;
301
+ const padded = new Jimp({ width: paddedWidth, height: rendered.height, color: 0xffffffff });
302
+ padded.composite(rendered, leftMargin, 0);
303
+ const imageBuffer = await padded.getBuffer("image/png");
304
+ fs.writeFileSync(tempFile, imageBuffer);
305
+ await printImage(tempFile, options.printer, options.tapeMm);
306
+ }
307
+ finally {
308
+ if (fs.existsSync(tempFile)) {
309
+ fs.unlinkSync(tempFile);
310
+ }
311
+ await closeBrowser();
312
+ }
313
+ }
314
+ async function listPrinters() {
315
+ return new Promise((resolve, reject) => {
316
+ exec('powershell -Command "Get-Printer | Where-Object { $_.Name -like \'*Brother*\' -or $_.Name -like \'*PT*\' } | Select-Object -ExpandProperty Name"', (error, stdout, stderr) => {
317
+ if (error) {
318
+ reject(new Error(`Failed to list printers: ${stderr}`));
319
+ return;
320
+ }
321
+ const printers = stdout.trim().split("\n").filter(p => p.trim());
322
+ if (printers.length === 0) {
323
+ console.log("No Brother printers found");
324
+ }
325
+ else {
326
+ console.log("Brother printers:");
327
+ printers.forEach(p => console.log(` ${p.trim()}`));
328
+ }
329
+ resolve();
330
+ });
331
+ });
332
+ }
333
+ async function detectTapeSize(printerName) {
334
+ // First check config file for user-specified tape size
335
+ const config = loadConfig();
336
+ if (config.defaultTape) {
337
+ const mm = parseInt(config.defaultTape.replace("mm", ""), 10);
338
+ if (!isNaN(mm) && TAPE_SIZES[`${mm}mm`]) {
339
+ return mm;
340
+ }
341
+ }
342
+ // Fall back to WMI query (may be stale after tape change)
343
+ return new Promise((resolve) => {
344
+ exec(`powershell -Command "(Get-WmiObject Win32_PrinterConfiguration -Filter \\"Name='${printerName}'\\").PaperWidth"`, (error, stdout) => {
345
+ if (error || !stdout.trim()) {
346
+ resolve(null);
347
+ return;
348
+ }
349
+ // PaperWidth is in tenths of mm
350
+ const tenthsMm = parseInt(stdout.trim(), 10);
351
+ if (isNaN(tenthsMm)) {
352
+ resolve(null);
353
+ return;
354
+ }
355
+ const mm = Math.round(tenthsMm / 10);
356
+ resolve(mm);
357
+ });
358
+ });
359
+ }
360
+ // Default printer name
361
+ const DEFAULT_PRINTER = "Brother PT-P710BT";
362
+ // Label sizes for P-touch tapes at 300 DPI (high quality)
363
+ // PT-P710BT has 180 DPI print head; 300 DPI source ensures max quality
364
+ // Printable area from printer: 0.71" height for 24mm tape, proportional for others
365
+ const PRINT_DPI = 300;
366
+ const TAPE_SIZES = {
367
+ "6mm": { width: 1137, height: 56, mm: 6 }, // 3.79" x 0.19" @ 300 DPI
368
+ "9mm": { width: 1137, height: 84, mm: 9 }, // 3.79" x 0.28" @ 300 DPI
369
+ "12mm": { width: 1137, height: 113, mm: 12 }, // 3.79" x 0.38" @ 300 DPI
370
+ "18mm": { width: 1137, height: 169, mm: 18 }, // 3.79" x 0.56" @ 300 DPI
371
+ "24mm": { width: 1137, height: 213, mm: 24 }, // 3.79" x 0.71" @ 300 DPI
372
+ };
373
+ program
374
+ .name("brother-print")
375
+ .description("Print labels to Brother P-touch and QL label printers")
376
+ .version("1.0.0");
377
+ program
378
+ .command("print <text>")
379
+ .description("Print a text label (use \\\\n for newlines)")
380
+ .option("-p, --printer <name>", "Printer name", DEFAULT_PRINTER)
381
+ .option("-t, --tape <size>", "Tape size: 6mm, 9mm, 12mm, 18mm, 24mm, or 'auto'", "auto")
382
+ .option("-w, --width <px>", "Custom width in pixels")
383
+ .option("-H, --img-height <px>", "Custom height in pixels")
384
+ .action(async (text, opts) => {
385
+ try {
386
+ let tapeMm;
387
+ let tapeSize;
388
+ if (opts.tape === "auto") {
389
+ const detected = await detectTapeSize(opts.printer);
390
+ if (detected) {
391
+ tapeMm = detected;
392
+ tapeSize = TAPE_SIZES[`${detected}mm`] || TAPE_SIZES["24mm"];
393
+ console.log(`Detected ${detected}mm tape`);
394
+ }
395
+ else {
396
+ console.log("Could not detect tape, using 24mm");
397
+ tapeMm = 24;
398
+ tapeSize = TAPE_SIZES["24mm"];
399
+ }
400
+ }
401
+ else {
402
+ tapeSize = TAPE_SIZES[opts.tape] || TAPE_SIZES["24mm"];
403
+ tapeMm = tapeSize.mm;
404
+ }
405
+ const options = {
406
+ printer: opts.printer,
407
+ fontSize: 32,
408
+ width: opts.width ? parseInt(opts.width, 10) : tapeSize.width, // label length
409
+ height: opts.imgHeight ? parseInt(opts.imgHeight, 10) : tapeSize.height, // tape height (printable)
410
+ tapeMm: tapeMm,
411
+ };
412
+ await printLabel(text, options);
413
+ console.log("Label printed successfully");
414
+ }
415
+ catch (err) {
416
+ console.error(`Error: ${err.message}`);
417
+ process.exit(1);
418
+ }
419
+ });
420
+ program
421
+ .command("list")
422
+ .description("List connected Brother printers")
423
+ .action(async () => {
424
+ try {
425
+ await listPrinters();
426
+ }
427
+ catch (err) {
428
+ console.error(`Error: ${err.message}`);
429
+ process.exit(1);
430
+ }
431
+ });
432
+ program
433
+ .command("image <file>")
434
+ .description("Print an image file (PNG, JPG, BMP)")
435
+ .option("-p, --printer <name>", "Printer name", DEFAULT_PRINTER)
436
+ .option("-t, --tape <size>", "Tape size: 6mm, 9mm, 12mm, 18mm, 24mm, or 'auto'", "auto")
437
+ .action(async (file, opts) => {
438
+ try {
439
+ let tapeMm;
440
+ let tapeSize;
441
+ if (opts.tape === "auto") {
442
+ const detected = await detectTapeSize(opts.printer);
443
+ if (detected) {
444
+ tapeMm = detected;
445
+ tapeSize = TAPE_SIZES[`${detected}mm`] || TAPE_SIZES["24mm"];
446
+ console.log(`Detected ${detected}mm tape`);
447
+ }
448
+ else {
449
+ console.log("Could not detect tape, using 24mm");
450
+ tapeMm = 24;
451
+ tapeSize = TAPE_SIZES["24mm"];
452
+ }
453
+ }
454
+ else {
455
+ tapeSize = TAPE_SIZES[opts.tape] || TAPE_SIZES["24mm"];
456
+ tapeMm = tapeSize.mm;
457
+ }
458
+ const absolutePath = path.resolve(file);
459
+ await printImage(absolutePath, opts.printer, tapeMm);
460
+ console.log("Image printed successfully");
461
+ }
462
+ catch (err) {
463
+ console.error(`Error: ${err.message}`);
464
+ process.exit(1);
465
+ }
466
+ });
467
+ program
468
+ .command("html <file>")
469
+ .description("Print an HTML file as a label")
470
+ .option("-p, --printer <name>", "Printer name", DEFAULT_PRINTER)
471
+ .option("-t, --tape <size>", "Tape size: 6mm, 9mm, 12mm, 18mm, 24mm, or 'auto'", "auto")
472
+ .action(async (file, opts) => {
473
+ try {
474
+ let tapeMm;
475
+ let tapeSize;
476
+ if (opts.tape === "auto") {
477
+ const detected = await detectTapeSize(opts.printer);
478
+ if (detected) {
479
+ tapeMm = detected;
480
+ tapeSize = TAPE_SIZES[`${detected}mm`] || TAPE_SIZES["24mm"];
481
+ console.log(`Detected ${detected}mm tape`);
482
+ }
483
+ else {
484
+ console.log("Could not detect tape, using 24mm");
485
+ tapeMm = 24;
486
+ tapeSize = TAPE_SIZES["24mm"];
487
+ }
488
+ }
489
+ else {
490
+ tapeSize = TAPE_SIZES[opts.tape] || TAPE_SIZES["24mm"];
491
+ tapeMm = tapeSize.mm;
492
+ }
493
+ const options = {
494
+ printer: opts.printer,
495
+ fontSize: 32,
496
+ width: tapeSize.width, // label length
497
+ height: tapeSize.height, // tape height (printable)
498
+ tapeMm: tapeMm,
499
+ };
500
+ await printHtmlLabel(file, options);
501
+ console.log("HTML label printed successfully");
502
+ }
503
+ catch (err) {
504
+ console.error(`Error: ${err.message}`);
505
+ process.exit(1);
506
+ }
507
+ });
508
+ program
509
+ .command("preview <text>")
510
+ .description("Save label as PNG without printing")
511
+ .option("-f, --font-size <size>", "Font size (16 or 32)", "32")
512
+ .option("-t, --tape <size>", "Tape size: 6mm, 9mm, 12mm, 18mm, 24mm", "12mm")
513
+ .option("-w, --width <px>", "Custom width in pixels")
514
+ .option("-H, --img-height <px>", "Custom height in pixels")
515
+ .option("-o, --output <file>", "Output file path", "label-preview.png")
516
+ .action(async (text, opts) => {
517
+ try {
518
+ const tapeSize = TAPE_SIZES[opts.tape] || TAPE_SIZES["12mm"];
519
+ const options = {
520
+ printer: "",
521
+ fontSize: parseInt(opts.fontSize, 10),
522
+ width: opts.width ? parseInt(opts.width, 10) : tapeSize.width, // label length
523
+ height: opts.imgHeight ? parseInt(opts.imgHeight, 10) : tapeSize.height, // tape height
524
+ tapeMm: tapeSize.mm,
525
+ };
526
+ const imageBuffer = await createLabelImage(text, options);
527
+ fs.writeFileSync(opts.output, imageBuffer);
528
+ console.log(`Preview saved to ${opts.output}`);
529
+ }
530
+ catch (err) {
531
+ console.error(`Error: ${err.message}`);
532
+ process.exit(1);
533
+ }
534
+ });
535
+ program
536
+ .command("qr <data>")
537
+ .description("Print a QR code label")
538
+ .option("-p, --printer <name>", "Printer name", DEFAULT_PRINTER)
539
+ .option("-t, --tape <size>", "Tape size: 6mm, 9mm, 12mm, 18mm, 24mm, or 'auto'", "auto")
540
+ .option("-l, --label <text>", "Optional text label beside QR code")
541
+ .option("-o, --output <file>", "Save to file instead of printing")
542
+ .action(async (data, opts) => {
543
+ try {
544
+ let tapeMm;
545
+ let tapeSize;
546
+ if (opts.tape === "auto") {
547
+ const detected = await detectTapeSize(opts.printer);
548
+ if (detected) {
549
+ tapeMm = detected;
550
+ tapeSize = TAPE_SIZES[`${detected}mm`] || TAPE_SIZES["24mm"];
551
+ console.log(`Detected ${detected}mm tape`);
552
+ }
553
+ else {
554
+ console.log("Could not detect tape, using 24mm");
555
+ tapeMm = 24;
556
+ tapeSize = TAPE_SIZES["24mm"];
557
+ }
558
+ }
559
+ else {
560
+ tapeSize = TAPE_SIZES[opts.tape] || TAPE_SIZES["24mm"];
561
+ tapeMm = tapeSize.mm;
562
+ }
563
+ const options = {
564
+ printer: opts.printer,
565
+ fontSize: 32,
566
+ width: tapeSize.width,
567
+ height: tapeSize.height,
568
+ tapeMm: tapeMm,
569
+ };
570
+ const imageBuffer = await createQrLabelImage(data, options, opts.label);
571
+ if (opts.output) {
572
+ fs.writeFileSync(opts.output, imageBuffer);
573
+ console.log(`QR label saved to ${opts.output}`);
574
+ }
575
+ else {
576
+ const tempDir = os.tmpdir();
577
+ const tempFile = path.join(tempDir, `qr-label-${Date.now()}.png`);
578
+ try {
579
+ fs.writeFileSync(tempFile, imageBuffer);
580
+ await printImage(tempFile, options.printer, options.tapeMm);
581
+ console.log("QR label printed successfully");
582
+ }
583
+ finally {
584
+ if (fs.existsSync(tempFile)) {
585
+ fs.unlinkSync(tempFile);
586
+ }
587
+ }
588
+ }
589
+ }
590
+ catch (err) {
591
+ console.error(`Error: ${err.message}`);
592
+ process.exit(1);
593
+ }
594
+ });
595
+ program
596
+ .command("config")
597
+ .description("Set default tape size and printer (stored in ~/.brother-label.json)")
598
+ .option("-t, --tape <size>", "Set default tape size: 6mm, 9mm, 12mm, 18mm, 24mm")
599
+ .option("-p, --printer <name>", "Set default printer name")
600
+ .option("-s, --show", "Show current configuration")
601
+ .action((opts) => {
602
+ const config = loadConfig();
603
+ if (opts.show || (!opts.tape && !opts.printer)) {
604
+ console.log("Current configuration:");
605
+ console.log(` Config file: ${CONFIG_PATH}`);
606
+ console.log(` Default tape: ${config.defaultTape || "(not set - will use WMI detection)"}`);
607
+ console.log(` Default printer: ${config.defaultPrinter || DEFAULT_PRINTER}`);
608
+ console.log("\nAvailable tape sizes: 6mm, 9mm, 12mm, 18mm, 24mm");
609
+ return;
610
+ }
611
+ if (opts.tape) {
612
+ const tape = opts.tape.endsWith("mm") ? opts.tape : `${opts.tape}mm`;
613
+ if (!TAPE_SIZES[tape]) {
614
+ console.error(`Invalid tape size: ${opts.tape}`);
615
+ console.error("Valid sizes: 6mm, 9mm, 12mm, 18mm, 24mm");
616
+ process.exit(1);
617
+ }
618
+ config.defaultTape = tape;
619
+ console.log(`Default tape set to: ${tape}`);
620
+ }
621
+ if (opts.printer) {
622
+ config.defaultPrinter = opts.printer;
623
+ console.log(`Default printer set to: ${opts.printer}`);
624
+ }
625
+ saveConfig(config);
626
+ console.log(`Configuration saved to ${CONFIG_PATH}`);
627
+ });
628
+ program.parse();
629
+ //# sourceMappingURL=brother-print.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brother-print.js","sourceRoot":"","sources":["brother-print.ts"],"names":[],"mappings":"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"}