label-printer 0.2.0

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.
package/dist/index.mjs ADDED
@@ -0,0 +1,595 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+ var __async = (__this, __arguments, generator) => {
7
+ return new Promise((resolve, reject) => {
8
+ var fulfilled = (value) => {
9
+ try {
10
+ step(generator.next(value));
11
+ } catch (e) {
12
+ reject(e);
13
+ }
14
+ };
15
+ var rejected = (value) => {
16
+ try {
17
+ step(generator.throw(value));
18
+ } catch (e) {
19
+ reject(e);
20
+ }
21
+ };
22
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
23
+ step((generator = generator.apply(__this, __arguments)).next());
24
+ });
25
+ };
26
+
27
+ // src/commands/index.ts
28
+ var commands_exports = {};
29
+ __export(commands_exports, {
30
+ Command: () => Command,
31
+ CommandGroup: () => CommandGroup,
32
+ tspl: () => tspl_exports
33
+ });
34
+
35
+ // src/commands/Command.ts
36
+ var Command = class {
37
+ /**
38
+ * Write the command data to a USB device
39
+ * @param device Device to write to
40
+ */
41
+ write(device) {
42
+ return __async(this, null, function* () {
43
+ yield this.writeString(this.commandString, device);
44
+ yield this.terminateCommand(device);
45
+ });
46
+ }
47
+ /**
48
+ * Byte representation of a newline
49
+ */
50
+ get commandTerminatorBytes() {
51
+ return new Uint8Array([10]);
52
+ }
53
+ /**
54
+ * Writes a string to a device
55
+ * @param data String representation of data
56
+ * @param device Device to write to
57
+ */
58
+ writeString(data, device) {
59
+ return __async(this, null, function* () {
60
+ yield device.writeString(data);
61
+ });
62
+ }
63
+ /**
64
+ * Writes bytes to a device. It will automatically end a command with @see{commandTerminatorBytes}
65
+ * @param data Byte array to send
66
+ * @param device Device to write to
67
+ */
68
+ writeBytes(data, device) {
69
+ return __async(this, null, function* () {
70
+ yield device.writeData(data);
71
+ });
72
+ }
73
+ /**
74
+ * Write the command terminator to the device
75
+ * @param device
76
+ */
77
+ terminateCommand(device) {
78
+ return __async(this, null, function* () {
79
+ yield this.writeBytes(this.commandTerminatorBytes, device);
80
+ });
81
+ }
82
+ };
83
+
84
+ // src/commands/CommandGroup.ts
85
+ var CommandGroup = class extends Command {
86
+ constructor(commands) {
87
+ super();
88
+ this.commands = commands;
89
+ }
90
+ write(device) {
91
+ return __async(this, null, function* () {
92
+ for (let commandIndex in this.commands) {
93
+ yield this.commands[commandIndex].write(device);
94
+ }
95
+ });
96
+ }
97
+ get commandString() {
98
+ return "";
99
+ }
100
+ };
101
+
102
+ // src/commands/tspl/index.ts
103
+ var tspl_exports = {};
104
+ __export(tspl_exports, {
105
+ TSPLBarCommand: () => TSPLBarCommand,
106
+ TSPLBitmapCommand: () => TSPLBitmapCommand,
107
+ TSPLBlockCommand: () => TSPLBlockCommand,
108
+ TSPLCLSCommand: () => TSPLCLSCommand,
109
+ TSPLCommand: () => TSPLCommand,
110
+ TSPLCommandGroup: () => TSPLCommandGroup,
111
+ TSPLDirectionCommand: () => TSPLDirectionCommand,
112
+ TSPLGapCommand: () => TSPLGapCommand,
113
+ TSPLPrintCommand: () => TSPLPrintCommand,
114
+ TSPLQRCommand: () => TSPLQRCommand,
115
+ TSPLRawCommand: () => TSPLRawCommand,
116
+ TSPLSizeCommand: () => TSPLSizeCommand,
117
+ TSPLTextCommand: () => TSPLTextCommand,
118
+ TSPLVisualCommand: () => TSPLVisualCommand,
119
+ alignmentToNumber: () => alignmentToNumber
120
+ });
121
+
122
+ // src/commands/tspl/TSPLCommand.ts
123
+ var TSPLCommand = class extends Command {
124
+ };
125
+
126
+ // src/commands/tspl/commands/TSPLRawCommand.ts
127
+ var TSPLRawCommand = class extends TSPLCommand {
128
+ /**
129
+ * Initialize a command with a raw body
130
+ * @param body
131
+ */
132
+ constructor(body) {
133
+ super();
134
+ this.commandBody = body;
135
+ }
136
+ get commandString() {
137
+ return this.commandBody;
138
+ }
139
+ };
140
+
141
+ // src/commands/tspl/commands/TSPLCommandGroup.ts
142
+ var TSPLCommandGroup = class extends CommandGroup {
143
+ };
144
+
145
+ // src/commands/tspl/commands/TSPLVisualCommand.ts
146
+ var TSPLVisualCommand = class extends TSPLCommand {
147
+ constructor(x, y) {
148
+ super();
149
+ this.x = x;
150
+ this.y = y;
151
+ }
152
+ };
153
+
154
+ // src/commands/tspl/commands/basic/TSPLBitmapCommand.ts
155
+ var TSPLBitmapCommand = class extends TSPLVisualCommand {
156
+ /**
157
+ *
158
+ * @param bitmap Bitmap to present.
159
+ * @param x X coordinates in dots
160
+ * @param y Y Coordinates in dots
161
+ * @param mode Represents the strategy to use when two bitmaps overlap. The final value will be determined by
162
+ * either overwriting the first bitmap's value with the second one or performing an 'or' or 'xor' operation on the values
163
+ */
164
+ constructor(bitmap, x, y, mode) {
165
+ super(x, y);
166
+ this.bitmap = bitmap;
167
+ this.mode = mode != null ? mode : "overwrite";
168
+ }
169
+ get commandString() {
170
+ const textDecoder = new TextDecoder("utf-8");
171
+ const bytesString = textDecoder.decode(this.bitmap.bytes);
172
+ return `${this.commandWithoutBytes}${bytesString.slice(0, 5)}...
173
+ `;
174
+ }
175
+ get commandWithoutBytes() {
176
+ return `BITMAP ${this.x}, ${this.y},${this.bitmap.width},${this.bitmap.height},${this.modeValue},`;
177
+ }
178
+ get modeValue() {
179
+ switch (this.mode) {
180
+ case "overwrite":
181
+ return 0;
182
+ case "or":
183
+ return 1;
184
+ case "xor":
185
+ return 2;
186
+ }
187
+ }
188
+ write(device) {
189
+ return __async(this, null, function* () {
190
+ yield this.writeString(this.commandWithoutBytes, device);
191
+ yield this.writeBytes(this.bitmap.bytes, device);
192
+ yield this.terminateCommand(device);
193
+ });
194
+ }
195
+ };
196
+
197
+ // src/commands/tspl/types.ts
198
+ var alignmentToNumber = (alignment) => {
199
+ switch (alignment) {
200
+ case void 0:
201
+ return 0;
202
+ case "left":
203
+ return 1;
204
+ case "center":
205
+ return 2;
206
+ case "right":
207
+ return 3;
208
+ }
209
+ };
210
+
211
+ // src/commands/tspl/commands/basic/TSPLTextCommand.ts
212
+ var TSPLTextCommand = class extends TSPLVisualCommand {
213
+ constructor(content, x, y, font, rotation, xMultiplication, yMultiplication, alignment) {
214
+ super(x, y);
215
+ this.font = font;
216
+ this.rotatation = rotation != null ? rotation : 0;
217
+ this.xMultiplication = xMultiplication != null ? xMultiplication : 1;
218
+ this.yMultiplication = yMultiplication != null ? yMultiplication : 1;
219
+ this.alignment = alignmentToNumber(alignment);
220
+ this.content = content;
221
+ }
222
+ get commandString() {
223
+ return `TEXT ${this.x},${this.y},"${this.font}",${this.rotatation},${this.xMultiplication},${this.yMultiplication},${this.alignment},"${this.content}"`;
224
+ }
225
+ };
226
+
227
+ // src/commands/tspl/commands/basic/TSPLGapCommand.ts
228
+ var TSPLGapCommand = class extends TSPLCommand {
229
+ constructor(gap, offset, unitSystem) {
230
+ super();
231
+ this.gap = gap;
232
+ this.offset = offset;
233
+ this.unitSystem = unitSystem;
234
+ }
235
+ get commandString() {
236
+ return `GAP ${this.valueWithUnit(this.gap)}, ${this.valueWithUnit(this.offset)}`;
237
+ }
238
+ valueWithUnit(value) {
239
+ switch (this.unitSystem) {
240
+ case "dot":
241
+ return `${value} dot`;
242
+ case "imperial":
243
+ return value;
244
+ case "metric":
245
+ return `${value} mm`;
246
+ }
247
+ }
248
+ };
249
+
250
+ // src/commands/tspl/commands/basic/TSPLSizeCommand.ts
251
+ var TSPLSizeCommand = class extends TSPLCommand {
252
+ constructor(width, height, unitSystem) {
253
+ super();
254
+ this.width = width;
255
+ this.height = height;
256
+ this.unitSystem = unitSystem;
257
+ }
258
+ get commandString() {
259
+ return `SIZE ${this.valueWithUnit(this.width)}, ${this.valueWithUnit(this.height)}`;
260
+ }
261
+ valueWithUnit(value) {
262
+ switch (this.unitSystem) {
263
+ case "dot":
264
+ return `${value} dot`;
265
+ case "imperial":
266
+ return value;
267
+ case "metric":
268
+ return `${value} mm`;
269
+ }
270
+ }
271
+ };
272
+
273
+ // src/commands/tspl/commands/basic/TSPLCLSCommand.ts
274
+ var TSPLCLSCommand = class extends TSPLCommand {
275
+ get commandString() {
276
+ return "CLS";
277
+ }
278
+ };
279
+
280
+ // src/commands/tspl/commands/basic/TSPLDirectionCommand.ts
281
+ var TSPLDirectionCommand = class extends TSPLCommand {
282
+ /**
283
+ * @param direction Controls the orientation of the resulting label compared to the printer
284
+ * @param mirror Controls mirroring relative to the center line of the label perpendicular to the printhead. See the documentsion for examples
285
+ */
286
+ constructor(direction, mirror) {
287
+ super();
288
+ this.direction = direction == "normal" ? 1 : 0;
289
+ this.mirror = mirror ? 1 : 0;
290
+ }
291
+ get commandString() {
292
+ return `DIRECTION ${this.direction}, ${this.mirror}`;
293
+ }
294
+ };
295
+
296
+ // src/commands/tspl/commands/basic/TSPLPrintCommand.ts
297
+ var TSPLPrintCommand = class extends TSPLCommand {
298
+ constructor(sets, copies = 1) {
299
+ super();
300
+ this.sets = sets;
301
+ this.copies = copies;
302
+ }
303
+ get commandString() {
304
+ return `PRINT ${this.sets}, ${this.copies}`;
305
+ }
306
+ };
307
+
308
+ // src/commands/tspl/commands/basic/TSPLBarCommand.ts
309
+ var TSPLBarCommand = class extends TSPLVisualCommand {
310
+ /**
311
+ * @param x X coordinates in dots
312
+ * @param y Y coordinates in dots
313
+ * @param width Width of tha bar in dots
314
+ * @param height Height of the bar in dots
315
+ */
316
+ constructor(x, y, width, height) {
317
+ super(x, y);
318
+ this.width = width;
319
+ this.height = height;
320
+ }
321
+ get commandString() {
322
+ return `BAR ${this.x}, ${this.y}, ${this.width}, ${this.height}`;
323
+ }
324
+ };
325
+
326
+ // src/commands/tspl/commands/basic/TSPLQRCommand.ts
327
+ var TSPLQRCommand = class extends TSPLVisualCommand {
328
+ constructor(content, x, y, cellWidth, ecc = "H", mode = "A", rotation = 0, model = "M2", mask = 7) {
329
+ super(x, y);
330
+ this.content = content;
331
+ this.cellWidth = cellWidth;
332
+ this.ecc = ecc;
333
+ this.mode = mode;
334
+ this.rotation = rotation;
335
+ this.model = model;
336
+ this.mask = mask;
337
+ if (mask < 0 || mask > 8) {
338
+ throw new Error(`Invalid mask provided: ${mask}`);
339
+ }
340
+ }
341
+ get commandString() {
342
+ return `QRCODE ${this.x}, ${this.y}, ${this.ecc}, ${this.cellWidth}, ${this.mode}, ${this.rotation}, ${this.model}, ${this.mask}, "${this.content}"`;
343
+ }
344
+ };
345
+
346
+ // src/commands/tspl/commands/basic/TSPLBlockCommand.ts
347
+ var TSPLBlockCommand = class extends TSPLTextCommand {
348
+ constructor(content, x, y, width, height, font, rotation, xMultiplication, yMultiplication, lineSpacing = 0, alignment) {
349
+ super(content, x, y, font, rotation, xMultiplication, yMultiplication, alignment);
350
+ this.width = width;
351
+ this.height = height;
352
+ this.lineSpacing = lineSpacing;
353
+ }
354
+ get commandString() {
355
+ return `BLOCK ${this.x},${this.y},${this.width}, ${this.height},"${this.font}",${this.rotatation},${this.xMultiplication},${this.yMultiplication},${this.lineSpacing},${this.alignment},"${this.content}"`;
356
+ }
357
+ };
358
+
359
+ // src/printers/index.ts
360
+ var printers_exports = {};
361
+ __export(printers_exports, {
362
+ Printer: () => Printer,
363
+ PrinterService: () => PrinterService
364
+ });
365
+
366
+ // src/printers/Printer.ts
367
+ var Printer = class {
368
+ constructor(device) {
369
+ this.usbDevice = device;
370
+ }
371
+ /**
372
+ * Close the printer USB
373
+ */
374
+ close() {
375
+ return __async(this, null, function* () {
376
+ yield this.usbDevice.close();
377
+ });
378
+ }
379
+ /**
380
+ * Writes a command to the printers usb
381
+ * @param command Command to send to the usb
382
+ */
383
+ writeCommand(command) {
384
+ return __async(this, null, function* () {
385
+ if (!this.usbDevice.opened)
386
+ yield this.usbDevice.openAndConfigure();
387
+ yield command.write(this.usbDevice);
388
+ });
389
+ }
390
+ /**
391
+ * Check if the device is indeed a printer
392
+ * @param device
393
+ */
394
+ static try(_device) {
395
+ throw new Error("try(device:) should be implemented");
396
+ }
397
+ };
398
+
399
+ // src/helpers/USBUtils.ts
400
+ import { WebUSB } from "usb";
401
+
402
+ // src/helpers/StringUtils.ts
403
+ var StringUtils = class {
404
+ /**
405
+ * Convert string to utf8 array
406
+ * @param str Convert string to byte array
407
+ */
408
+ toUTF8Array(str) {
409
+ let utf8Encode = new TextEncoder();
410
+ return utf8Encode.encode(str);
411
+ }
412
+ /**
413
+ * Convert bytes to utf8 encoded string
414
+ * @param bytes Bytes to decode
415
+ * @returns A string
416
+ */
417
+ toString(bytes) {
418
+ let decoder = new TextDecoder();
419
+ return decoder.decode(bytes);
420
+ }
421
+ };
422
+
423
+ // src/helpers/USBUtils.ts
424
+ var unsupportedUsbError = "usb-unsupported";
425
+ var stringHelper = new StringUtils();
426
+ var getUSB = () => {
427
+ if (typeof navigator !== "undefined") {
428
+ if (navigator.usb) {
429
+ return navigator.usb;
430
+ } else {
431
+ throw unsupportedUsbError;
432
+ }
433
+ }
434
+ return new WebUSB({ allowAllDevices: true });
435
+ };
436
+ var usbAgent = getUSB();
437
+ var getDevices = () => __async(void 0, null, function* () {
438
+ const devices = yield usbAgent.getDevices();
439
+ return devices.map((device) => new UsbDevice(device));
440
+ });
441
+ var UsbDevice = class {
442
+ get opened() {
443
+ return this.device.opened;
444
+ }
445
+ /**
446
+ * All available endpoints
447
+ */
448
+ get endpoints() {
449
+ var _a, _b;
450
+ return (_b = (_a = this.device.configuration) == null ? void 0 : _a.interfaces[0].alternate.endpoints) != null ? _b : [];
451
+ }
452
+ /**
453
+ * Endpoint for writing
454
+ */
455
+ get outEndpoint() {
456
+ var _a;
457
+ return (_a = this.endpoints.find((e) => e.direction == "out")) == null ? void 0 : _a.endpointNumber;
458
+ }
459
+ /**
460
+ * Endpoint for reading
461
+ */
462
+ get inEndpoint() {
463
+ var _a;
464
+ return (_a = this.endpoints.find((e) => e.direction == "in")) == null ? void 0 : _a.endpointNumber;
465
+ }
466
+ constructor(device) {
467
+ this.device = device;
468
+ }
469
+ /**
470
+ * Open the device and claim its interface
471
+ */
472
+ openAndConfigure() {
473
+ return __async(this, null, function* () {
474
+ yield this.device.open();
475
+ yield this.device.selectConfiguration(1);
476
+ yield this.device.claimInterface(0);
477
+ });
478
+ }
479
+ /**
480
+ * Closes the device
481
+ */
482
+ close() {
483
+ return __async(this, null, function* () {
484
+ yield this.device.releaseInterface(0);
485
+ yield this.device.close();
486
+ });
487
+ }
488
+ /**
489
+ * Write data to an USB device
490
+ * @param data Data to write
491
+ */
492
+ writeData(data) {
493
+ return __async(this, null, function* () {
494
+ const endpointNumber = this.outEndpoint;
495
+ yield this.device.transferOut(endpointNumber, data);
496
+ });
497
+ }
498
+ /**
499
+ * Writes a text to a device
500
+ * @param text Text to write
501
+ */
502
+ writeString(text) {
503
+ return __async(this, null, function* () {
504
+ const bytes = stringHelper.toUTF8Array(text);
505
+ yield this.writeData(bytes);
506
+ });
507
+ }
508
+ /**
509
+ * Reads bytes from the usb device
510
+ * @param length The max length of the incoming data.
511
+ * @returns Bytes received as a DataView or undefined. If data is longer then `length`, undefined will be returned
512
+ */
513
+ readData(length) {
514
+ return __async(this, null, function* () {
515
+ const endpointNumber = this.inEndpoint;
516
+ const result = yield this.device.transferIn(endpointNumber, length);
517
+ if (result.status == "ok" && result.data) {
518
+ return result.data;
519
+ } else {
520
+ return void 0;
521
+ }
522
+ });
523
+ }
524
+ /**
525
+ * Reads data from the usb device and converts it to string
526
+ * {@see readData}
527
+ */
528
+ readString(length) {
529
+ return __async(this, null, function* () {
530
+ const bytes = yield this.readData(length);
531
+ if (bytes)
532
+ return stringHelper.toString(bytes);
533
+ return void 0;
534
+ });
535
+ }
536
+ };
537
+
538
+ // src/printers/TSPLPrinter.ts
539
+ var TSPLPrinter = class extends Printer {
540
+ get language() {
541
+ return "tspl";
542
+ }
543
+ feedLabel() {
544
+ return __async(this, null, function* () {
545
+ const feedCommand = new TSPLRawCommand("FORMFEED");
546
+ yield this.writeCommand(feedCommand);
547
+ });
548
+ }
549
+ static try(device) {
550
+ return __async(this, null, function* () {
551
+ if (!device.opened)
552
+ yield device.openAndConfigure();
553
+ const testCommand = new TSPLRawCommand("~!I");
554
+ yield testCommand.write(device);
555
+ const response = yield device.readString(64);
556
+ yield device.close();
557
+ return !!response;
558
+ });
559
+ }
560
+ };
561
+
562
+ // src/printers/PrinterService.ts
563
+ var PrinterService = class _PrinterService {
564
+ /**
565
+ * Try each type of printer and return the one that mathces the usb device
566
+ * @param device
567
+ * @returns
568
+ */
569
+ static printerForDevice(device) {
570
+ return __async(this, null, function* () {
571
+ const classes = [TSPLPrinter];
572
+ for (const key in classes) {
573
+ if (yield classes[key].try(device)) {
574
+ return new classes[key](device);
575
+ }
576
+ }
577
+ return void 0;
578
+ });
579
+ }
580
+ /**
581
+ * @returns List of available printers
582
+ */
583
+ static getPrinters() {
584
+ return __async(this, null, function* () {
585
+ const devices = yield getDevices();
586
+ const optionalPrinters = yield Promise.all(devices.map(_PrinterService.printerForDevice));
587
+ return optionalPrinters.filter((printer) => !!printer);
588
+ });
589
+ }
590
+ };
591
+ export {
592
+ commands_exports as commands,
593
+ printers_exports as printers
594
+ };
595
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/index.ts","../src/commands/Command.ts","../src/commands/CommandGroup.ts","../src/commands/tspl/index.ts","../src/commands/tspl/TSPLCommand.ts","../src/commands/tspl/commands/TSPLRawCommand.ts","../src/commands/tspl/commands/TSPLCommandGroup.ts","../src/commands/tspl/commands/TSPLVisualCommand.ts","../src/commands/tspl/commands/basic/TSPLBitmapCommand.ts","../src/commands/tspl/types.ts","../src/commands/tspl/commands/basic/TSPLTextCommand.ts","../src/commands/tspl/commands/basic/TSPLGapCommand.ts","../src/commands/tspl/commands/basic/TSPLSizeCommand.ts","../src/commands/tspl/commands/basic/TSPLCLSCommand.ts","../src/commands/tspl/commands/basic/TSPLDirectionCommand.ts","../src/commands/tspl/commands/basic/TSPLPrintCommand.ts","../src/commands/tspl/commands/basic/TSPLBarCommand.ts","../src/commands/tspl/commands/basic/TSPLQRCommand.ts","../src/commands/tspl/commands/basic/TSPLBlockCommand.ts","../src/printers/index.ts","../src/printers/Printer.ts","../src/helpers/USBUtils.ts","../src/helpers/StringUtils.ts","../src/printers/TSPLPrinter.ts","../src/printers/PrinterService.ts"],"sourcesContent":["export { default as Command } from \"./Command\"\nexport { default as CommandGroup } from \"./CommandGroup\"\n\nexport type PrinterLanguage = \"tspl\"\n\nexport * as tspl from \"./tspl\"","import { UsbDevice } from \"@/helpers/USBUtils\"\n\n/**\n * Base implementation for all types of command\n * Represents a command to be send to the printer to execute, such as print\n */\nexport default abstract class Command {\n /**\n * Returns a string representation of the command\n */\n abstract get commandString(): string\n\n /**\n * Write the command data to a USB device\n * @param device Device to write to\n */\n async write(device: UsbDevice): Promise<void> {\n await this.writeString(this.commandString, device)\n await this.terminateCommand(device)\n }\n\n /**\n * Byte representation of a newline\n */\n protected get commandTerminatorBytes(): Uint8Array {\n return new Uint8Array([10])\n }\n\n /**\n * Writes a string to a device\n * @param data String representation of data\n * @param device Device to write to\n */\n protected async writeString(data: string, device: UsbDevice): Promise<void> {\n await device.writeString(data)\n }\n\n /**\n * Writes bytes to a device. It will automatically end a command with @see{commandTerminatorBytes}\n * @param data Byte array to send\n * @param device Device to write to\n */\n protected async writeBytes(data: Uint8Array, device: UsbDevice): Promise<void> {\n await device.writeData(data)\n }\n\n /**\n * Write the command terminator to the device\n * @param device \n */\n protected async terminateCommand(device: UsbDevice): Promise<void> {\n await this.writeBytes(this.commandTerminatorBytes, device)\n }\n}","import { UsbDevice } from \"@/helpers/USBUtils\";\nimport Command from \"./Command\";\n\n/**\n * A utility class that helps groupping commands together\n * Should be implemnted with a specific command type to ensure only commands for the same lagnuage are\n * groupped together\n */\nexport default abstract class CommandGroup<T extends Command> extends Command {\n private commands: T[]\n\n constructor(commands: T[]) {\n super()\n this.commands = commands\n }\n\n async write(device: UsbDevice): Promise<void> {\n for (let commandIndex in this.commands) {\n await this.commands[commandIndex].write(device)\n }\n }\n\n get commandString(): string {\n return \"\"\n }\n}","export { default as TSPLCommand } from \"./TSPLCommand\"\n\nexport * from \"./commands\"\nexport * from \"./types\"","import Command from \"@/commands/Command\";\n\n/**\n * Base for TSPL specific commands\n */\nexport default abstract class TSPLCommand extends Command {\n}","import TSPLCommand from \"../TSPLCommand\"\n\n/**\n * A raw TSPL command. Can be used to use a command that is not yet supported\n */\nexport default class TSPLRawCommand extends TSPLCommand {\n /**\n * Raw command string\n */\n private readonly commandBody: string\n\n /**\n * Initialize a command with a raw body\n * @param body\n */\n constructor(body: string) {\n super()\n this.commandBody = body\n }\n\n get commandString(): string {\n return this.commandBody;\n }\n}\n","import CommandGroup from \"@/commands/CommandGroup\";\nimport TSPLCommand from \"../TSPLCommand\";\n\n/**\n * Command group for tspl commands\n */\nexport default class TSPLCommandGroup extends CommandGroup<TSPLCommand> {}","import TSPLCommand from \"../TSPLCommand\";\n\n/**\n * Base for all TSPL commands that have a visual effect on the final label\n */\nexport default abstract class TSPLVisualCommand extends TSPLCommand {\n protected readonly x: number\n protected readonly y: number\n\n constructor(x: number, y: number) {\n super()\n this.x = x\n this.y = y\n }\n}","import { BWBitmap } from \"@/helpers/ImageUtils\";\nimport { GraphicMode } from \"../../types\";\nimport TSPLVisualCommand from \"../TSPLVisualCommand\";\nimport { UsbDevice } from \"@/helpers/USBUtils\";\n\n/**\n * Represents a bitmap command. Can be used to draw an image to the label\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLBitmapCommand extends TSPLVisualCommand {\n /**\n * Bitmap to present. \n * TSPL only supports black and write printing so this bitmap contains a matrix of 1 (White pixel)\n * and 0 (Black pixel) values\n */\n private readonly bitmap: BWBitmap\n private readonly mode: GraphicMode\n \n /**\n * \n * @param bitmap Bitmap to present. \n * @param x X coordinates in dots\n * @param y Y Coordinates in dots\n * @param mode Represents the strategy to use when two bitmaps overlap. The final value will be determined by\n * either overwriting the first bitmap's value with the second one or performing an 'or' or 'xor' operation on the values\n */\n constructor(bitmap: BWBitmap, x: number, y: number, mode?: GraphicMode) {\n super(x, y);\n this.bitmap = bitmap;\n this.mode = mode ?? \"overwrite\"\n }\n\n get commandString(): string {\n const textDecoder = new TextDecoder('utf-8')\n const bytesString = textDecoder.decode(this.bitmap.bytes)\n\n return `${this.commandWithoutBytes}${bytesString.slice(0,5)}...\\n`;\n }\n\n private get commandWithoutBytes(): string {\n return `BITMAP ${this.x}, ${this.y},${this.bitmap.width},${this.bitmap.height},${this.modeValue},`\n }\n\n private get modeValue(): 0|1|2 {\n switch (this.mode) {\n case \"overwrite\": return 0\n case \"or\": return 1\n case \"xor\": return 2\n }\n }\n\n async write(device: UsbDevice): Promise<void> {\n await this.writeString(this.commandWithoutBytes, device)\n await this.writeBytes(this.bitmap.bytes, device)\n await this.terminateCommand(device)\n }\n}","export type Rotation = 0|90|180|270\nexport type Alignment = undefined|\"left\"|\"center\"|\"right\"\n\n/**\n * Convert an alignemnt string to its number value\n * @param alignment \n * @returns \n */\nexport const alignmentToNumber = (alignment: Alignment): 0|1|2|3 => {\n switch(alignment) {\n case undefined: return 0\n case \"left\": return 1\n case \"center\": return 2\n case \"right\": return 3\n }\n}\n\n/**\n * Represents the strategy to use when two bitmaps overlap. The final value will be determined by\n * either overwriting the first bitmap's value with the second one or performing an 'or' or 'xor' operation\n * on the values\n */\nexport type GraphicMode = \"overwrite\"|\"or\"|\"xor\"\nexport type UnitSystem = \"imperial\"|\"metric\"|\"dot\"\nexport type ECCLevel = \"L\"|\"M\"|\"Q\"|\"H\"\nexport type AutoManual = \"A\"|\"M\"\nexport type QRModel = \"M1\"|\"M2\"\nexport type BarcodeType = \"CODE128\"|\"EAN13\"|\"EAN8\"|\"EAN5\"|\"EAN2\"|\"UPC\"|\"CODE39\"|\"ITF14\"|\"MSI10\"|\"MSI11\"|\"MSI1010\"|\"MSI1110\"|\"pharmacode\"|\"codabar\"\nexport type BarcodeHumanReable = \"none\"|\"left\"|\"right\"|\"center\"","import { Alignment, Rotation, alignmentToNumber } from \"../../types\";\nimport TSPLVisualCommand from \"../TSPLVisualCommand\";\n\n/**\n * Prints a single line text on the label\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLTextCommand extends TSPLVisualCommand {\n /**\n * Name of the font to use. Consult documentation for more info\n */\n protected readonly font: string\n /**\n * Angle of rotation of the text. 0, 90, 180 or 270\n */\n protected readonly rotatation: Rotation\n /**\n * Multiplication of the font size in x axis\n */\n protected readonly xMultiplication: number\n /**\n * Multiplication of the font size in y axis\n */\n protected readonly yMultiplication: number\n /**\n * Text alignment. Left, Center or Right. The default alignmnet is left\n */\n protected readonly alignment: number\n /**\n * Text to print\n */\n protected readonly content: string\n\n constructor(content: string, x: number, y: number, font: string, rotation?: Rotation, xMultiplication?: number, yMultiplication?: number, alignment?: Alignment) {\n super(x, y)\n this.font = font\n this.rotatation = rotation ?? 0\n this.xMultiplication = xMultiplication ?? 1\n this.yMultiplication = yMultiplication ?? 1\n this.alignment = alignmentToNumber(alignment)\n this.content = content\n }\n\n get commandString(): string {\n return `TEXT ${this.x},${this.y},\\\"${this.font}\\\",${this.rotatation},${this.xMultiplication},${this.yMultiplication},${this.alignment},\\\"${this.content}\\\"`\n }\n}","import TSPLCommand from \"../../TSPLCommand\";\nimport { UnitSystem } from \"../../types\";\n\n/**\n * Defines the gap between two labels\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLGapCommand extends TSPLCommand {\n private readonly gap: number\n private readonly offset: number\n\n /**\n * This controls what unit the {@link width} and {@link height} will be\n * - For imperial, the unit is inches\n * - For metric, the unit is milimeters\n * - For dots, the unit is dots\n */\n private readonly unitSystem: UnitSystem\n\n constructor(gap: number, offset: number, unitSystem: UnitSystem) {\n super()\n this.gap = gap\n this.offset = offset\n this.unitSystem = unitSystem\n } \n\n get commandString(): string {\n return `GAP ${this.valueWithUnit(this.gap)}, ${this.valueWithUnit(this.offset)}`\n }\n\n private valueWithUnit(value: number) {\n switch(this.unitSystem) {\n case \"dot\": return `${value} dot`\n case \"imperial\": return value\n case \"metric\": return `${value} mm`\n }\n }\n}","import TSPLCommand from \"../../TSPLCommand\";\nimport { UnitSystem } from \"../../types\";\n\n/**\n * Defines the size of the label to rpint\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLSizeCommand extends TSPLCommand {\n private readonly width: number\n private readonly height: number\n /**\n * This controls what unit the {@link width} and {@link height} will be\n * - For imperial, the unit is inches\n * - For metric, the unit is milimeters\n * - For dots, the unit is dots\n */\n private readonly unitSystem: UnitSystem\n\n constructor(width: number, height: number, unitSystem: UnitSystem) {\n super()\n this.width = width\n this.height = height\n this.unitSystem = unitSystem\n } \n\n get commandString(): string {\n return `SIZE ${this.valueWithUnit(this.width)}, ${this.valueWithUnit(this.height)}`\n }\n\n private valueWithUnit(value: number) {\n switch(this.unitSystem) {\n case \"dot\": return `${value} dot`\n case \"imperial\": return value\n case \"metric\": return `${value} mm`\n }\n }\n}","import TSPLCommand from \"../../TSPLCommand\";\n\n/**\n * Clear the image buffer\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLCLSCommand extends TSPLCommand {\n get commandString(): string {\n return \"CLS\"\n }\n}","import TSPLCommand from \"../../TSPLCommand\";\n\n/**\n * This command defines in which direction will the label be printed and wether or not to mirror the image\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLDirectionCommand extends TSPLCommand {\n private readonly direction: 0|1\n private readonly mirror: 0|1\n\n /**\n * @param direction Controls the orientation of the resulting label compared to the printer\n * @param mirror Controls mirroring relative to the center line of the label perpendicular to the printhead. See the documentsion for examples\n */\n constructor(direction: \"normal\"|\"inverse\", mirror?: boolean) {\n super()\n this.direction = direction == \"normal\" ? 1 : 0\n this.mirror = mirror ? 1 : 0\n }\n\n get commandString(): string {\n return `DIRECTION ${this.direction}, ${this.mirror}`\n }\n}\n","import TSPLCommand from \"../../TSPLCommand\";\n\n/**\n * Prints the current image buffer\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLPrintCommand extends TSPLCommand {\n /**\n * The number of set to print.\n */\n private readonly sets: number\n /**\n * The number of copies to print of each set.\n * The difference between a set and a copy is that if you have a counter for example,\n * the counter will be incremented for each set but not for each copy\n */\n private readonly copies: number\n\n constructor(sets: number, copies: number = 1) {\n super()\n this.sets = sets\n this.copies = copies\n }\n\n get commandString(): string {\n return `PRINT ${this.sets}, ${this.copies}`\n }\n}","import TSPLVisualCommand from \"../TSPLVisualCommand\";\n\n/**\n * Draws a black bar\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLBarCommand extends TSPLVisualCommand {\n private readonly width: number\n private readonly height: number\n\n /**\n * @param x X coordinates in dots\n * @param y Y coordinates in dots\n * @param width Width of tha bar in dots\n * @param height Height of the bar in dots\n */\n constructor(x: number, y: number, width: number, height: number) {\n super(x,y)\n this.width = width\n this.height = height\n }\n\n get commandString(): string {\n return `BAR ${this.x}, ${this.y}, ${this.width}, ${this.height}`\n }\n}","import { ECCLevel, AutoManual, Rotation, QRModel } from \"../../types\";\nimport TSPLVisualCommand from \"../TSPLVisualCommand\";\n\n/**\n * Prints a QR code\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLQRCommand extends TSPLVisualCommand {\n private readonly ecc: ECCLevel\n private readonly cellWidth: number\n private readonly mode: AutoManual\n private readonly rotation: Rotation\n private readonly model: QRModel\n /**\n * Should be between 0 and 7\n */\n private readonly mask: number\n private readonly content: string\n\n constructor(content: string, \n x: number, \n y: number, \n cellWidth: number, \n ecc: ECCLevel = \"H\", \n mode: AutoManual = \"A\", \n rotation: Rotation = 0, \n model: QRModel = \"M2\", \n mask: number = 7) {\n super(x,y)\n this.content = content\n this.cellWidth = cellWidth\n this.ecc = ecc\n this.mode = mode\n this.rotation = rotation\n this.model = model\n this.mask = mask\n\n if (mask < 0 || mask > 8) {\n throw new Error(`Invalid mask provided: ${mask}`)\n }\n }\n\n get commandString(): string {\n return `QRCODE ${this.x}, ${this.y}, ${this.ecc}, ${this.cellWidth}, ${this.mode}, ${this.rotation}, ${this.model}, ${this.mask}, \\\"${this.content}\\\"`\n }\n}","import { Alignment, Rotation } from \"../../types\";\nimport TSPLTextCommand from \"./TSPLTextCommand\";\n\nexport default class TSPLBlockCommand extends TSPLTextCommand {\n private readonly width: number\n private readonly height: number\n private readonly lineSpacing: number\n\n constructor(content: string, \n x: number, \n y: number, \n width: number,\n height: number,\n font: string, \n rotation?: Rotation, \n xMultiplication?: number, \n yMultiplication?: number, \n lineSpacing: number = 0,\n alignment?: Alignment) {\n super(content, x, y, font, rotation, xMultiplication, yMultiplication, alignment)\n this.width = width\n this.height = height\n this.lineSpacing = lineSpacing\n }\n\n get commandString(): string {\n return `BLOCK ${this.x},${this.y},${this.width}, ${this.height},\\\"${this.font}\\\",${this.rotatation},${this.xMultiplication},${this.yMultiplication},${this.lineSpacing},${this.alignment},\\\"${this.content}\\\"`\n }\n}","export { default as Printer } from \"./Printer\"\nexport { PrinterService } from \"./PrinterService\"","import { Command, PrinterLanguage } from \"@/commands\";\nimport { UsbDevice } from \"@/helpers/USBUtils\";\n\n/**\n * Base class that encapsulates functionality of all printers\n */\nexport default abstract class Printer {\n private readonly usbDevice: UsbDevice\n\n /**\n * Printer language used by the type of printer the subclass represents\n */\n abstract get language(): PrinterLanguage\n\n /**\n * When called, it will feed the labels to the beginig of the next label\n */\n abstract feedLabel(): Promise<void>\n\n constructor(device: UsbDevice) {\n this.usbDevice = device\n }\n\n /**\n * Close the printer USB\n */\n async close() {\n await this.usbDevice.close()\n }\n\n /**\n * Writes a command to the printers usb\n * @param command Command to send to the usb\n */\n protected async writeCommand(command: Command): Promise<void> {\n if(!this.usbDevice.opened) await this.usbDevice.openAndConfigure()\n await command.write(this.usbDevice)\n }\n\n /**\n * Check if the device is indeed a printer\n * @param device \n */\n static try(_device: UsbDevice): Promise<boolean> {\n throw new Error(\"try(device:) should be implemented\")\n }\n}","import { InEndpoint, WebUSB } from \"usb\";\nimport StringUtils from \"./StringUtils\";\n\nconst unsupportedUsbError = \"usb-unsupported\"\nconst stringHelper = new StringUtils()\n\n/**\n * @returns The appropiate USB agent based on the environment\n */\nconst getUSB = (): USB => {\n if(typeof navigator !== \"undefined\") {\n if(navigator.usb) {\n return navigator.usb\n } else {\n throw unsupportedUsbError\n }\n }\n\n return new WebUSB({allowAllDevices: true})\n}\n\nexport const usbAgent = getUSB()\n\n/**\n * @returns A list of available devices\n */\nexport const getDevices = async (): Promise<UsbDevice[]> => {\n const devices = await usbAgent.getDevices()\n return devices.map(device => new UsbDevice(device) )\n}\n\n/**\n * Convenience wrapper for a web usb device\n * Its main purpose is to hide the details of the usb library from client code so in case\n * it needs to be switched, compatibility can be retained\n */\nexport class UsbDevice {\n private readonly device: USBDevice\n\n get opened() {\n return this.device.opened\n }\n\n /**\n * All available endpoints\n */\n private get endpoints() {\n return this.device.configuration?.interfaces[0].alternate.endpoints ?? []\n }\n\n /**\n * Endpoint for writing\n */\n private get outEndpoint() {\n return this.endpoints.find(e => e.direction == \"out\")?.endpointNumber\n }\n\n /**\n * Endpoint for reading\n */\n private get inEndpoint() {\n return this.endpoints.find(e => e.direction == \"in\")?.endpointNumber\n }\n\n constructor(device: USBDevice) {\n this.device = device\n }\n\n /**\n * Open the device and claim its interface\n */\n async openAndConfigure() {\n await this.device.open();\n await this.device.selectConfiguration(1);\n await this.device.claimInterface(0);\n }\n\n /**\n * Closes the device\n */\n async close() {\n await this.device.releaseInterface(0)\n await this.device.close()\n }\n\n /**\n * Write data to an USB device\n * @param data Data to write\n */\n async writeData(data: Uint8Array): Promise<void> {\n const endpointNumber = this.outEndpoint\n await this.device.transferOut(endpointNumber!, data)\n }\n\n /**\n * Writes a text to a device\n * @param text Text to write\n */\n async writeString(text: string): Promise<void> {\n const bytes = stringHelper.toUTF8Array(text)\n await this.writeData(bytes)\n }\n\n /**\n * Reads bytes from the usb device\n * @param length The max length of the incoming data. \n * @returns Bytes received as a DataView or undefined. If data is longer then `length`, undefined will be returned\n */\n async readData(length: number): Promise<DataView|undefined> {\n const endpointNumber = this.inEndpoint\n const result = await this.device.transferIn(endpointNumber!, length)\n\n if(result.status == \"ok\" && result.data) {\n return result.data\n } else {\n return undefined\n }\n }\n\n /**\n * Reads data from the usb device and converts it to string\n * {@see readData}\n */\n async readString(length: number): Promise<string|undefined> {\n const bytes = await this.readData(length)\n if(bytes) return stringHelper.toString(bytes)\n return undefined\n }\n}\n","/**\n * Collection of helpers to work with strings\n */\nexport default class StringUtils {\n /**\n * Convert string to utf8 array\n * @param str Convert string to byte array\n */\n toUTF8Array(str: string) {\n let utf8Encode = new TextEncoder();\n return utf8Encode.encode(str)\n }\n\n /**\n * Convert bytes to utf8 encoded string\n * @param bytes Bytes to decode\n * @returns A string\n */\n toString(bytes: Uint8Array|DataView) {\n let decoder = new TextDecoder()\n return decoder.decode(bytes)\n }\n}","import { TSPLRawCommand } from \"@/commands/tspl\";\nimport { PrinterLanguage } from \"@/commands\"\nimport Printer from \"./Printer\";\nimport { UsbDevice } from \"@/helpers/USBUtils\";\n\nexport default class TSPLPrinter extends Printer {\n get language(): PrinterLanguage {\n return \"tspl\"\n }\n\n async feedLabel(): Promise<void> {\n const feedCommand = new TSPLRawCommand(\"FORMFEED\")\n await this.writeCommand(feedCommand)\n }\n\n static async try(device: UsbDevice): Promise<boolean> {\n if(!device.opened) await device.openAndConfigure()\n const testCommand = new TSPLRawCommand(\"~!I\")\n await testCommand.write(device)\n\n const response = await device.readString(64)\n await device.close()\n // If there is a response, we have a TSPL printer\n return !!response\n }\n}","import { UsbDevice, getDevices } from \"@/helpers/USBUtils\"\nimport TSPLPrinter from \"./TSPLPrinter\"\nimport Printer from \"./Printer\"\n\nexport class PrinterService {\n /**\n * Try each type of printer and return the one that mathces the usb device\n * @param device \n * @returns \n */\n static async printerForDevice(device: UsbDevice): Promise<Printer|undefined> {\n const classes = [TSPLPrinter]\n\n for (const key in classes) {\n if(await classes[key].try(device)) {\n return new classes[key](device)\n }\n }\n\n return undefined\n }\n\n /**\n * @returns List of available printers\n */\n static async getPrinters(): Promise<Printer[]> {\n const devices = await getDevices()\n const optionalPrinters = await Promise.all(devices.map(PrinterService.printerForDevice))\n return optionalPrinters.filter(printer => !!printer) as Printer[]\n }\n}"],"mappings":"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","names":[]}