label-printer 0.2.3 → 0.2.5
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.d.mts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +152 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +142 -12
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -179,7 +179,6 @@ declare class TSPLBitmapCommand extends TSPLVisualCommand {
|
|
|
179
179
|
private readonly bitmap;
|
|
180
180
|
private readonly mode;
|
|
181
181
|
/**
|
|
182
|
-
*
|
|
183
182
|
* @param bitmap Bitmap to present.
|
|
184
183
|
* @param x X coordinates in dots
|
|
185
184
|
* @param y Y Coordinates in dots
|
|
@@ -191,6 +190,17 @@ declare class TSPLBitmapCommand extends TSPLVisualCommand {
|
|
|
191
190
|
private get commandWithoutBytes();
|
|
192
191
|
private get modeValue();
|
|
193
192
|
write(device: UsbDevice): Promise<void>;
|
|
193
|
+
/**
|
|
194
|
+
* Create a new bitmap command for the given image url
|
|
195
|
+
* @param image Image to create command for
|
|
196
|
+
* @param x X coordinate of the image
|
|
197
|
+
* @param y Y coordinate of the image
|
|
198
|
+
* @param imageWidth Desired width of the image
|
|
199
|
+
* @param imageHeight Desired height of the image
|
|
200
|
+
* @param mode Graphics mode
|
|
201
|
+
* @returns
|
|
202
|
+
*/
|
|
203
|
+
static forImageUrl(image: string, x: number, y: number, imageWidth?: number, imageHeight?: number, mode?: GraphicMode): Promise<TSPLBitmapCommand>;
|
|
194
204
|
}
|
|
195
205
|
|
|
196
206
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -179,7 +179,6 @@ declare class TSPLBitmapCommand extends TSPLVisualCommand {
|
|
|
179
179
|
private readonly bitmap;
|
|
180
180
|
private readonly mode;
|
|
181
181
|
/**
|
|
182
|
-
*
|
|
183
182
|
* @param bitmap Bitmap to present.
|
|
184
183
|
* @param x X coordinates in dots
|
|
185
184
|
* @param y Y Coordinates in dots
|
|
@@ -191,6 +190,17 @@ declare class TSPLBitmapCommand extends TSPLVisualCommand {
|
|
|
191
190
|
private get commandWithoutBytes();
|
|
192
191
|
private get modeValue();
|
|
193
192
|
write(device: UsbDevice): Promise<void>;
|
|
193
|
+
/**
|
|
194
|
+
* Create a new bitmap command for the given image url
|
|
195
|
+
* @param image Image to create command for
|
|
196
|
+
* @param x X coordinate of the image
|
|
197
|
+
* @param y Y coordinate of the image
|
|
198
|
+
* @param imageWidth Desired width of the image
|
|
199
|
+
* @param imageHeight Desired height of the image
|
|
200
|
+
* @param mode Graphics mode
|
|
201
|
+
* @returns
|
|
202
|
+
*/
|
|
203
|
+
static forImageUrl(image: string, x: number, y: number, imageWidth?: number, imageHeight?: number, mode?: GraphicMode): Promise<TSPLBitmapCommand>;
|
|
194
204
|
}
|
|
195
205
|
|
|
196
206
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
var __async = (__this, __arguments, generator) => {
|
|
20
30
|
return new Promise((resolve, reject) => {
|
|
@@ -172,10 +182,120 @@ var TSPLVisualCommand = class extends TSPLCommand {
|
|
|
172
182
|
}
|
|
173
183
|
};
|
|
174
184
|
|
|
175
|
-
// src/
|
|
176
|
-
var
|
|
185
|
+
// src/helpers/ImageUtils.ts
|
|
186
|
+
var import_image_pixels = __toESM(require("image-pixels"));
|
|
187
|
+
var BLACK_PIXEL = 0;
|
|
188
|
+
var WHITE_PIXEL = 1;
|
|
189
|
+
var ImageUtils = class {
|
|
190
|
+
/**
|
|
191
|
+
* Get pixel information about an image
|
|
192
|
+
* @param image Image to process
|
|
193
|
+
* @returns
|
|
194
|
+
*/
|
|
195
|
+
static getPixels(image) {
|
|
196
|
+
return __async(this, null, function* () {
|
|
197
|
+
const { width, height, data } = yield (0, import_image_pixels.default)(image);
|
|
198
|
+
const bitsPerPixel = data.length / height / width;
|
|
199
|
+
return {
|
|
200
|
+
data,
|
|
201
|
+
width,
|
|
202
|
+
height,
|
|
203
|
+
bitsPerPixel
|
|
204
|
+
};
|
|
205
|
+
});
|
|
206
|
+
}
|
|
177
207
|
/**
|
|
208
|
+
* Return a bitmap in which all pixels are represented with one bit of either 1 or 0 representing white and black
|
|
209
|
+
* pixels respectively. `destinationWidth` and `destinationHeight` have to be smaller or equal to the
|
|
210
|
+
* input size as only downscaling is performed
|
|
178
211
|
*
|
|
212
|
+
* @param image Image to process
|
|
213
|
+
* @param destinationWidth Width of the ouput bitmap
|
|
214
|
+
* @param destinationHeight Height of the output bitmap
|
|
215
|
+
* @returns
|
|
216
|
+
*/
|
|
217
|
+
static getBWBitmap(image, destinationWidth, destinationHeight) {
|
|
218
|
+
return __async(this, null, function* () {
|
|
219
|
+
const {
|
|
220
|
+
data,
|
|
221
|
+
width,
|
|
222
|
+
height,
|
|
223
|
+
bitsPerPixel
|
|
224
|
+
} = yield this.getPixels(image);
|
|
225
|
+
const dWidth = destinationWidth != null ? destinationWidth : width;
|
|
226
|
+
const dHeight = destinationHeight != null ? destinationHeight : height;
|
|
227
|
+
const differenceToDividable = dWidth % 8 == 0 ? 0 : 8 - dWidth % 8;
|
|
228
|
+
const dividableDWidth = dWidth + differenceToDividable;
|
|
229
|
+
const bitmapData = new Uint8Array(dividableDWidth * dHeight);
|
|
230
|
+
let destinationIndex = 0;
|
|
231
|
+
for (let h = 0; h < dHeight; h++) {
|
|
232
|
+
const originalHeight = Math.round(h * (height - 1) / (dHeight - 1));
|
|
233
|
+
for (let w = 0; w < dWidth; w++) {
|
|
234
|
+
const originalWidth = Math.round(w * (width - 1) / (dWidth - 1));
|
|
235
|
+
const baseIndex = originalHeight * width * bitsPerPixel + originalWidth * bitsPerPixel;
|
|
236
|
+
const r = data[baseIndex];
|
|
237
|
+
const g = data[baseIndex + 1];
|
|
238
|
+
const b = data[baseIndex + 2];
|
|
239
|
+
const a = data[baseIndex + 3];
|
|
240
|
+
if (a > 128) {
|
|
241
|
+
const avg = (r + g + b) / 3;
|
|
242
|
+
if (avg > 128) {
|
|
243
|
+
bitmapData[destinationIndex] = WHITE_PIXEL;
|
|
244
|
+
} else {
|
|
245
|
+
bitmapData[destinationIndex] = BLACK_PIXEL;
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
bitmapData[destinationIndex] = WHITE_PIXEL;
|
|
249
|
+
}
|
|
250
|
+
destinationIndex += 1;
|
|
251
|
+
}
|
|
252
|
+
for (let i = 0; i < differenceToDividable; i++) {
|
|
253
|
+
bitmapData[destinationIndex] = WHITE_PIXEL;
|
|
254
|
+
destinationIndex += 1;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
const byteArrays = this.chunk(bitmapData, 8);
|
|
258
|
+
const widthInBytes = dividableDWidth / 8;
|
|
259
|
+
const bytes = byteArrays.map(this.bitsToByte);
|
|
260
|
+
const finalBytes = new Uint8Array(bytes);
|
|
261
|
+
return {
|
|
262
|
+
width: widthInBytes,
|
|
263
|
+
height: dHeight,
|
|
264
|
+
bytes: finalBytes
|
|
265
|
+
};
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Splits an array into chunks.
|
|
270
|
+
* @param originalArray
|
|
271
|
+
* @param chunkSize
|
|
272
|
+
* @returns
|
|
273
|
+
*/
|
|
274
|
+
static chunk(originalArray, chunkSize) {
|
|
275
|
+
const resultArray = [];
|
|
276
|
+
for (let i = 0; i < originalArray.length; i += chunkSize) {
|
|
277
|
+
const chunk = originalArray.slice(i, i + chunkSize);
|
|
278
|
+
resultArray.push(chunk);
|
|
279
|
+
}
|
|
280
|
+
return resultArray;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Converts an array of bits to a byte
|
|
284
|
+
* @param bits
|
|
285
|
+
* @returns
|
|
286
|
+
*/
|
|
287
|
+
static bitsToByte(bits) {
|
|
288
|
+
let byteValue = 0;
|
|
289
|
+
for (let i = 0; i < bits.length; i++) {
|
|
290
|
+
byteValue = byteValue << 1 | bits[i];
|
|
291
|
+
}
|
|
292
|
+
return byteValue;
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
// src/commands/tspl/commands/basic/TSPLBitmapCommand.ts
|
|
297
|
+
var TSPLBitmapCommand = class _TSPLBitmapCommand extends TSPLVisualCommand {
|
|
298
|
+
/**
|
|
179
299
|
* @param bitmap Bitmap to present.
|
|
180
300
|
* @param x X coordinates in dots
|
|
181
301
|
* @param y Y Coordinates in dots
|
|
@@ -213,6 +333,22 @@ var TSPLBitmapCommand = class extends TSPLVisualCommand {
|
|
|
213
333
|
yield this.terminateCommand(device);
|
|
214
334
|
});
|
|
215
335
|
}
|
|
336
|
+
/**
|
|
337
|
+
* Create a new bitmap command for the given image url
|
|
338
|
+
* @param image Image to create command for
|
|
339
|
+
* @param x X coordinate of the image
|
|
340
|
+
* @param y Y coordinate of the image
|
|
341
|
+
* @param imageWidth Desired width of the image
|
|
342
|
+
* @param imageHeight Desired height of the image
|
|
343
|
+
* @param mode Graphics mode
|
|
344
|
+
* @returns
|
|
345
|
+
*/
|
|
346
|
+
static forImageUrl(image, x, y, imageWidth, imageHeight, mode) {
|
|
347
|
+
return __async(this, null, function* () {
|
|
348
|
+
const bitmap = yield ImageUtils.getBWBitmap(image, imageWidth, imageHeight);
|
|
349
|
+
return new _TSPLBitmapCommand(bitmap, x, y, mode);
|
|
350
|
+
});
|
|
351
|
+
}
|
|
216
352
|
};
|
|
217
353
|
|
|
218
354
|
// src/commands/tspl/types.ts
|
|
@@ -417,9 +553,6 @@ var Printer = class {
|
|
|
417
553
|
}
|
|
418
554
|
};
|
|
419
555
|
|
|
420
|
-
// src/helpers/USBUtils.ts
|
|
421
|
-
var import_usb = require("usb");
|
|
422
|
-
|
|
423
556
|
// src/helpers/StringUtils.ts
|
|
424
557
|
var StringUtils = class {
|
|
425
558
|
/**
|
|
@@ -444,23 +577,30 @@ var StringUtils = class {
|
|
|
444
577
|
// src/helpers/USBUtils.ts
|
|
445
578
|
var unsupportedUsbError = "usb-unsupported";
|
|
446
579
|
var stringHelper = new StringUtils();
|
|
447
|
-
var
|
|
580
|
+
var usbAgent;
|
|
581
|
+
var getUSB = () => __async(void 0, null, function* () {
|
|
582
|
+
if (usbAgent)
|
|
583
|
+
return usbAgent;
|
|
448
584
|
if (typeof navigator !== "undefined") {
|
|
449
585
|
if (navigator.usb) {
|
|
450
|
-
|
|
586
|
+
usbAgent = navigator.usb;
|
|
451
587
|
} else {
|
|
452
588
|
throw unsupportedUsbError;
|
|
453
589
|
}
|
|
590
|
+
} else {
|
|
591
|
+
const { WebUSB } = yield import("usb");
|
|
592
|
+
usbAgent = new WebUSB({ allowAllDevices: true });
|
|
454
593
|
}
|
|
455
|
-
return
|
|
456
|
-
};
|
|
457
|
-
var usbAgent = getUSB();
|
|
594
|
+
return usbAgent;
|
|
595
|
+
});
|
|
458
596
|
var getDevices = () => __async(void 0, null, function* () {
|
|
459
|
-
const
|
|
597
|
+
const agent = yield getUSB();
|
|
598
|
+
const devices = yield agent.getDevices();
|
|
460
599
|
return devices.map((device) => new UsbDevice(device));
|
|
461
600
|
});
|
|
462
601
|
var requestDevice = () => __async(void 0, null, function* () {
|
|
463
|
-
const
|
|
602
|
+
const agent = yield getUSB();
|
|
603
|
+
const device = yield agent.requestDevice();
|
|
464
604
|
if (device) {
|
|
465
605
|
return new UsbDevice(device);
|
|
466
606
|
} else {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../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 * as commands from \"./commands\"\nexport * as printers from \"./printers\"","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 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 { 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 the list of available devices\n * In node this returns all the connected devices but in the browser it will only return devices \n * that the user already gave permission to\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 * In node, it returns the first available device, in the browser (supported browsers only) it shows \n * a UI for the user to choose a device\n * @returns The first available device\n */\nexport const requestDevice = async (): Promise<UsbDevice|undefined> => {\n const device = await usbAgent.requestDevice()\n if(device) {\n return new UsbDevice(device)\n } else {\n return undefined\n }\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, requestDevice } 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\n /**\n * This is intended to be used in the browser although it also works in node\n * In the browser, it provides a UI for the user to choose a USB device and if it is a\n * printer, it returns a new printer instance. In Node however, this will try to create\n * a printer for the first available device and returns it. This means that even if there is a \n * printer, it may return undefined. In node, use `getPrinters` instead\n */\n static async requestPrinter(): Promise<Printer|undefined> {\n const device = await requestDevice()\n if(device) {\n return PrinterService.printerForDevice(device)\n }\n }\n}"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../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/helpers/ImageUtils.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/StringUtils.ts","../src/helpers/USBUtils.ts","../src/printers/TSPLPrinter.ts","../src/printers/PrinterService.ts"],"sourcesContent":["export * as commands from \"./commands\"\nexport * as printers from \"./printers\"","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}","// @ts-ignore\nimport pixels from \"image-pixels\"\n\n/**\n * Helper type to transmit image bitmap data\n */\nexport type Pixels = {\n data: Uint8Array, \n width: number,\n height: number, \n bitsPerPixel: number\n}\n\n/**\n * Helper type to transmit black and white bitmap data\n */\nexport type BWBitmap = {\n width: number,\n height: number,\n bytes: Uint8Array\n}\n\nconst BLACK_PIXEL = 0\nconst WHITE_PIXEL = 1\n\n/**\n * Set of image utility\n */\nexport default class ImageUtils {\n /**\n * Get pixel information about an image\n * @param image Image to process\n * @returns \n */\n static async getPixels(image: string|Blob): Promise<Pixels> {\n const {width, height, data} = await pixels(image) as Omit<Pixels, \"bitsPerPixel\">\n const bitsPerPixel = data.length / height / width\n\n return {\n data, width, height, bitsPerPixel\n }\n }\n\n /**\n * Return a bitmap in which all pixels are represented with one bit of either 1 or 0 representing white and black\n * pixels respectively. `destinationWidth` and `destinationHeight` have to be smaller or equal to the\n * input size as only downscaling is performed\n * \n * @param image Image to process \n * @param destinationWidth Width of the ouput bitmap\n * @param destinationHeight Height of the output bitmap\n * @returns \n */\n static async getBWBitmap(image: string, destinationWidth?: number, destinationHeight?: number): Promise<BWBitmap> {\n const {\n data,\n width,\n height,\n bitsPerPixel\n } = await this.getPixels(image)\n \n // Number of pixels width and height => number of bits for each row and number of rows\n const dWidth = destinationWidth ?? width\n const dHeight = destinationHeight ?? height\n \n const differenceToDividable = dWidth % 8 == 0 ? 0 : (8 - (dWidth % 8))\n const dividableDWidth = dWidth + differenceToDividable\n \n // Size of the array has to be with * height but width has to be extended to be dividable by 8\n const bitmapData = new Uint8Array(dividableDWidth * dHeight)\n \n let destinationIndex = 0\n for (let h=0; h < dHeight; h++) {\n const originalHeight = Math.round((h * (height - 1)) / (dHeight - 1))\n \n for(let w=0; w < dWidth; w++) {\n const originalWidth = Math.round((w * (width - 1)) / (dWidth - 1))\n \n const baseIndex = (originalHeight * width * bitsPerPixel) + (originalWidth * bitsPerPixel)\n \n const r = data[baseIndex]\n const g = data[baseIndex + 1]\n const b = data[baseIndex + 2]\n const a = data[baseIndex + 3]\n \n if(a > 128) {\n const avg = (r + g + b) / 3\n \n if(avg > 128) {\n bitmapData[destinationIndex] = WHITE_PIXEL\n } else {\n bitmapData[destinationIndex] = BLACK_PIXEL\n }\n } else {\n bitmapData[destinationIndex] = WHITE_PIXEL\n }\n destinationIndex += 1\n }\n \n for(let i=0; i < differenceToDividable; i++) {\n bitmapData[destinationIndex] = WHITE_PIXEL\n destinationIndex += 1\n }\n }\n \n const byteArrays = this.chunk(bitmapData,8)\n const widthInBytes = dividableDWidth / 8\n \n const bytes = byteArrays.map(this.bitsToByte)\n const finalBytes = new Uint8Array(bytes)\n \n return {\n width: widthInBytes,\n height: dHeight,\n bytes: finalBytes\n }\n }\n\n /**\n * Splits an array into chunks.\n * @param originalArray\n * @param chunkSize\n * @returns\n */\n private static chunk(originalArray: Uint8Array, chunkSize: number): Uint8Array[] {\n const resultArray = [];\n\n for (let i = 0; i < originalArray.length; i += chunkSize) {\n const chunk = originalArray.slice(i, i + chunkSize);\n resultArray.push(chunk);\n }\n\n return resultArray;\n }\n\n /**\n * Converts an array of bits to a byte\n * @param bits\n * @returns\n */\n private static bitsToByte(bits: Uint8Array) {\n let byteValue = 0;\n for (let i = 0; i < bits.length; i++) {\n byteValue = (byteValue << 1) | bits[i];\n }\n return byteValue;\n }\n}","import ImageUtils, { 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 * @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\n /**\n * Create a new bitmap command for the given image url\n * @param image Image to create command for \n * @param x X coordinate of the image\n * @param y Y coordinate of the image\n * @param imageWidth Desired width of the image\n * @param imageHeight Desired height of the image\n * @param mode Graphics mode\n * @returns \n */\n static async forImageUrl(image: string, x: number, y: number, imageWidth?: number, imageHeight?: number, mode?: GraphicMode) {\n const bitmap = await ImageUtils.getBWBitmap(image, imageWidth, imageHeight)\n return new TSPLBitmapCommand(bitmap, x, y, mode)\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 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}","/**\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 { WebUSB } from \"usb\";\nimport StringUtils from \"./StringUtils\";\n\nconst unsupportedUsbError = \"usb-unsupported\"\nconst stringHelper = new StringUtils()\n\nlet usbAgent: USB\n\n/**\n * @returns The appropiate USB agent based on the environment\n */\nconst getUSB = async (): Promise<USB> => {\n if(usbAgent) return usbAgent\n\n if(typeof navigator !== \"undefined\") {\n if(navigator.usb) {\n usbAgent = navigator.usb\n } else {\n throw unsupportedUsbError\n }\n } else {\n const { WebUSB } = await import(\"usb\")\n usbAgent = new WebUSB({allowAllDevices: true})\n }\n\n return usbAgent\n}\n\n/**\n * Returns the list of available devices\n * In node this returns all the connected devices but in the browser it will only return devices \n * that the user already gave permission to\n * @returns A list of available devices\n */\nexport const getDevices = async (): Promise<UsbDevice[]> => {\n const agent = await getUSB()\n const devices = await agent.getDevices()\n return devices.map(device => new UsbDevice(device) )\n}\n\n/**\n * In node, it returns the first available device, in the browser (supported browsers only) it shows \n * a UI for the user to choose a device\n * @returns The first available device\n */\nexport const requestDevice = async (): Promise<UsbDevice|undefined> => {\n const agent = await getUSB()\n const device = await agent.requestDevice()\n if(device) {\n return new UsbDevice(device)\n } else {\n return undefined\n }\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","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, requestDevice } 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\n /**\n * This is intended to be used in the browser although it also works in node\n * In the browser, it provides a UI for the user to choose a USB device and if it is a\n * printer, it returns a new printer instance. In Node however, this will try to create\n * a printer for the first available device and returns it. This means that even if there is a \n * printer, it may return undefined. In node, use `getPrinters` instead\n */\n static async requestPrinter(): Promise<Printer|undefined> {\n const device = await requestDevice()\n if(device) {\n return PrinterService.printerForDevice(device)\n }\n }\n}"],"mappings":"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","names":["pixels"]}
|
package/dist/index.mjs
CHANGED
|
@@ -151,10 +151,120 @@ var TSPLVisualCommand = class extends TSPLCommand {
|
|
|
151
151
|
}
|
|
152
152
|
};
|
|
153
153
|
|
|
154
|
-
// src/
|
|
155
|
-
|
|
154
|
+
// src/helpers/ImageUtils.ts
|
|
155
|
+
import pixels from "image-pixels";
|
|
156
|
+
var BLACK_PIXEL = 0;
|
|
157
|
+
var WHITE_PIXEL = 1;
|
|
158
|
+
var ImageUtils = class {
|
|
159
|
+
/**
|
|
160
|
+
* Get pixel information about an image
|
|
161
|
+
* @param image Image to process
|
|
162
|
+
* @returns
|
|
163
|
+
*/
|
|
164
|
+
static getPixels(image) {
|
|
165
|
+
return __async(this, null, function* () {
|
|
166
|
+
const { width, height, data } = yield pixels(image);
|
|
167
|
+
const bitsPerPixel = data.length / height / width;
|
|
168
|
+
return {
|
|
169
|
+
data,
|
|
170
|
+
width,
|
|
171
|
+
height,
|
|
172
|
+
bitsPerPixel
|
|
173
|
+
};
|
|
174
|
+
});
|
|
175
|
+
}
|
|
156
176
|
/**
|
|
177
|
+
* Return a bitmap in which all pixels are represented with one bit of either 1 or 0 representing white and black
|
|
178
|
+
* pixels respectively. `destinationWidth` and `destinationHeight` have to be smaller or equal to the
|
|
179
|
+
* input size as only downscaling is performed
|
|
157
180
|
*
|
|
181
|
+
* @param image Image to process
|
|
182
|
+
* @param destinationWidth Width of the ouput bitmap
|
|
183
|
+
* @param destinationHeight Height of the output bitmap
|
|
184
|
+
* @returns
|
|
185
|
+
*/
|
|
186
|
+
static getBWBitmap(image, destinationWidth, destinationHeight) {
|
|
187
|
+
return __async(this, null, function* () {
|
|
188
|
+
const {
|
|
189
|
+
data,
|
|
190
|
+
width,
|
|
191
|
+
height,
|
|
192
|
+
bitsPerPixel
|
|
193
|
+
} = yield this.getPixels(image);
|
|
194
|
+
const dWidth = destinationWidth != null ? destinationWidth : width;
|
|
195
|
+
const dHeight = destinationHeight != null ? destinationHeight : height;
|
|
196
|
+
const differenceToDividable = dWidth % 8 == 0 ? 0 : 8 - dWidth % 8;
|
|
197
|
+
const dividableDWidth = dWidth + differenceToDividable;
|
|
198
|
+
const bitmapData = new Uint8Array(dividableDWidth * dHeight);
|
|
199
|
+
let destinationIndex = 0;
|
|
200
|
+
for (let h = 0; h < dHeight; h++) {
|
|
201
|
+
const originalHeight = Math.round(h * (height - 1) / (dHeight - 1));
|
|
202
|
+
for (let w = 0; w < dWidth; w++) {
|
|
203
|
+
const originalWidth = Math.round(w * (width - 1) / (dWidth - 1));
|
|
204
|
+
const baseIndex = originalHeight * width * bitsPerPixel + originalWidth * bitsPerPixel;
|
|
205
|
+
const r = data[baseIndex];
|
|
206
|
+
const g = data[baseIndex + 1];
|
|
207
|
+
const b = data[baseIndex + 2];
|
|
208
|
+
const a = data[baseIndex + 3];
|
|
209
|
+
if (a > 128) {
|
|
210
|
+
const avg = (r + g + b) / 3;
|
|
211
|
+
if (avg > 128) {
|
|
212
|
+
bitmapData[destinationIndex] = WHITE_PIXEL;
|
|
213
|
+
} else {
|
|
214
|
+
bitmapData[destinationIndex] = BLACK_PIXEL;
|
|
215
|
+
}
|
|
216
|
+
} else {
|
|
217
|
+
bitmapData[destinationIndex] = WHITE_PIXEL;
|
|
218
|
+
}
|
|
219
|
+
destinationIndex += 1;
|
|
220
|
+
}
|
|
221
|
+
for (let i = 0; i < differenceToDividable; i++) {
|
|
222
|
+
bitmapData[destinationIndex] = WHITE_PIXEL;
|
|
223
|
+
destinationIndex += 1;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
const byteArrays = this.chunk(bitmapData, 8);
|
|
227
|
+
const widthInBytes = dividableDWidth / 8;
|
|
228
|
+
const bytes = byteArrays.map(this.bitsToByte);
|
|
229
|
+
const finalBytes = new Uint8Array(bytes);
|
|
230
|
+
return {
|
|
231
|
+
width: widthInBytes,
|
|
232
|
+
height: dHeight,
|
|
233
|
+
bytes: finalBytes
|
|
234
|
+
};
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Splits an array into chunks.
|
|
239
|
+
* @param originalArray
|
|
240
|
+
* @param chunkSize
|
|
241
|
+
* @returns
|
|
242
|
+
*/
|
|
243
|
+
static chunk(originalArray, chunkSize) {
|
|
244
|
+
const resultArray = [];
|
|
245
|
+
for (let i = 0; i < originalArray.length; i += chunkSize) {
|
|
246
|
+
const chunk = originalArray.slice(i, i + chunkSize);
|
|
247
|
+
resultArray.push(chunk);
|
|
248
|
+
}
|
|
249
|
+
return resultArray;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Converts an array of bits to a byte
|
|
253
|
+
* @param bits
|
|
254
|
+
* @returns
|
|
255
|
+
*/
|
|
256
|
+
static bitsToByte(bits) {
|
|
257
|
+
let byteValue = 0;
|
|
258
|
+
for (let i = 0; i < bits.length; i++) {
|
|
259
|
+
byteValue = byteValue << 1 | bits[i];
|
|
260
|
+
}
|
|
261
|
+
return byteValue;
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
// src/commands/tspl/commands/basic/TSPLBitmapCommand.ts
|
|
266
|
+
var TSPLBitmapCommand = class _TSPLBitmapCommand extends TSPLVisualCommand {
|
|
267
|
+
/**
|
|
158
268
|
* @param bitmap Bitmap to present.
|
|
159
269
|
* @param x X coordinates in dots
|
|
160
270
|
* @param y Y Coordinates in dots
|
|
@@ -192,6 +302,22 @@ var TSPLBitmapCommand = class extends TSPLVisualCommand {
|
|
|
192
302
|
yield this.terminateCommand(device);
|
|
193
303
|
});
|
|
194
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* Create a new bitmap command for the given image url
|
|
307
|
+
* @param image Image to create command for
|
|
308
|
+
* @param x X coordinate of the image
|
|
309
|
+
* @param y Y coordinate of the image
|
|
310
|
+
* @param imageWidth Desired width of the image
|
|
311
|
+
* @param imageHeight Desired height of the image
|
|
312
|
+
* @param mode Graphics mode
|
|
313
|
+
* @returns
|
|
314
|
+
*/
|
|
315
|
+
static forImageUrl(image, x, y, imageWidth, imageHeight, mode) {
|
|
316
|
+
return __async(this, null, function* () {
|
|
317
|
+
const bitmap = yield ImageUtils.getBWBitmap(image, imageWidth, imageHeight);
|
|
318
|
+
return new _TSPLBitmapCommand(bitmap, x, y, mode);
|
|
319
|
+
});
|
|
320
|
+
}
|
|
195
321
|
};
|
|
196
322
|
|
|
197
323
|
// src/commands/tspl/types.ts
|
|
@@ -396,9 +522,6 @@ var Printer = class {
|
|
|
396
522
|
}
|
|
397
523
|
};
|
|
398
524
|
|
|
399
|
-
// src/helpers/USBUtils.ts
|
|
400
|
-
import { WebUSB } from "usb";
|
|
401
|
-
|
|
402
525
|
// src/helpers/StringUtils.ts
|
|
403
526
|
var StringUtils = class {
|
|
404
527
|
/**
|
|
@@ -423,23 +546,30 @@ var StringUtils = class {
|
|
|
423
546
|
// src/helpers/USBUtils.ts
|
|
424
547
|
var unsupportedUsbError = "usb-unsupported";
|
|
425
548
|
var stringHelper = new StringUtils();
|
|
426
|
-
var
|
|
549
|
+
var usbAgent;
|
|
550
|
+
var getUSB = () => __async(void 0, null, function* () {
|
|
551
|
+
if (usbAgent)
|
|
552
|
+
return usbAgent;
|
|
427
553
|
if (typeof navigator !== "undefined") {
|
|
428
554
|
if (navigator.usb) {
|
|
429
|
-
|
|
555
|
+
usbAgent = navigator.usb;
|
|
430
556
|
} else {
|
|
431
557
|
throw unsupportedUsbError;
|
|
432
558
|
}
|
|
559
|
+
} else {
|
|
560
|
+
const { WebUSB } = yield import("usb");
|
|
561
|
+
usbAgent = new WebUSB({ allowAllDevices: true });
|
|
433
562
|
}
|
|
434
|
-
return
|
|
435
|
-
};
|
|
436
|
-
var usbAgent = getUSB();
|
|
563
|
+
return usbAgent;
|
|
564
|
+
});
|
|
437
565
|
var getDevices = () => __async(void 0, null, function* () {
|
|
438
|
-
const
|
|
566
|
+
const agent = yield getUSB();
|
|
567
|
+
const devices = yield agent.getDevices();
|
|
439
568
|
return devices.map((device) => new UsbDevice(device));
|
|
440
569
|
});
|
|
441
570
|
var requestDevice = () => __async(void 0, null, function* () {
|
|
442
|
-
const
|
|
571
|
+
const agent = yield getUSB();
|
|
572
|
+
const device = yield agent.requestDevice();
|
|
443
573
|
if (device) {
|
|
444
574
|
return new UsbDevice(device);
|
|
445
575
|
} else {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +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 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 { 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 the list of available devices\n * In node this returns all the connected devices but in the browser it will only return devices \n * that the user already gave permission to\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 * In node, it returns the first available device, in the browser (supported browsers only) it shows \n * a UI for the user to choose a device\n * @returns The first available device\n */\nexport const requestDevice = async (): Promise<UsbDevice|undefined> => {\n const device = await usbAgent.requestDevice()\n if(device) {\n return new UsbDevice(device)\n } else {\n return undefined\n }\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, requestDevice } 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\n /**\n * This is intended to be used in the browser although it also works in node\n * In the browser, it provides a UI for the user to choose a USB device and if it is a\n * printer, it returns a new printer instance. In Node however, this will try to create\n * a printer for the first available device and returns it. This means that even if there is a \n * printer, it may return undefined. In node, use `getPrinters` instead\n */\n static async requestPrinter(): Promise<Printer|undefined> {\n const device = await requestDevice()\n if(device) {\n return PrinterService.printerForDevice(device)\n }\n }\n}"],"mappings":"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","names":[]}
|
|
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/helpers/ImageUtils.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/StringUtils.ts","../src/helpers/USBUtils.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}","// @ts-ignore\nimport pixels from \"image-pixels\"\n\n/**\n * Helper type to transmit image bitmap data\n */\nexport type Pixels = {\n data: Uint8Array, \n width: number,\n height: number, \n bitsPerPixel: number\n}\n\n/**\n * Helper type to transmit black and white bitmap data\n */\nexport type BWBitmap = {\n width: number,\n height: number,\n bytes: Uint8Array\n}\n\nconst BLACK_PIXEL = 0\nconst WHITE_PIXEL = 1\n\n/**\n * Set of image utility\n */\nexport default class ImageUtils {\n /**\n * Get pixel information about an image\n * @param image Image to process\n * @returns \n */\n static async getPixels(image: string|Blob): Promise<Pixels> {\n const {width, height, data} = await pixels(image) as Omit<Pixels, \"bitsPerPixel\">\n const bitsPerPixel = data.length / height / width\n\n return {\n data, width, height, bitsPerPixel\n }\n }\n\n /**\n * Return a bitmap in which all pixels are represented with one bit of either 1 or 0 representing white and black\n * pixels respectively. `destinationWidth` and `destinationHeight` have to be smaller or equal to the\n * input size as only downscaling is performed\n * \n * @param image Image to process \n * @param destinationWidth Width of the ouput bitmap\n * @param destinationHeight Height of the output bitmap\n * @returns \n */\n static async getBWBitmap(image: string, destinationWidth?: number, destinationHeight?: number): Promise<BWBitmap> {\n const {\n data,\n width,\n height,\n bitsPerPixel\n } = await this.getPixels(image)\n \n // Number of pixels width and height => number of bits for each row and number of rows\n const dWidth = destinationWidth ?? width\n const dHeight = destinationHeight ?? height\n \n const differenceToDividable = dWidth % 8 == 0 ? 0 : (8 - (dWidth % 8))\n const dividableDWidth = dWidth + differenceToDividable\n \n // Size of the array has to be with * height but width has to be extended to be dividable by 8\n const bitmapData = new Uint8Array(dividableDWidth * dHeight)\n \n let destinationIndex = 0\n for (let h=0; h < dHeight; h++) {\n const originalHeight = Math.round((h * (height - 1)) / (dHeight - 1))\n \n for(let w=0; w < dWidth; w++) {\n const originalWidth = Math.round((w * (width - 1)) / (dWidth - 1))\n \n const baseIndex = (originalHeight * width * bitsPerPixel) + (originalWidth * bitsPerPixel)\n \n const r = data[baseIndex]\n const g = data[baseIndex + 1]\n const b = data[baseIndex + 2]\n const a = data[baseIndex + 3]\n \n if(a > 128) {\n const avg = (r + g + b) / 3\n \n if(avg > 128) {\n bitmapData[destinationIndex] = WHITE_PIXEL\n } else {\n bitmapData[destinationIndex] = BLACK_PIXEL\n }\n } else {\n bitmapData[destinationIndex] = WHITE_PIXEL\n }\n destinationIndex += 1\n }\n \n for(let i=0; i < differenceToDividable; i++) {\n bitmapData[destinationIndex] = WHITE_PIXEL\n destinationIndex += 1\n }\n }\n \n const byteArrays = this.chunk(bitmapData,8)\n const widthInBytes = dividableDWidth / 8\n \n const bytes = byteArrays.map(this.bitsToByte)\n const finalBytes = new Uint8Array(bytes)\n \n return {\n width: widthInBytes,\n height: dHeight,\n bytes: finalBytes\n }\n }\n\n /**\n * Splits an array into chunks.\n * @param originalArray\n * @param chunkSize\n * @returns\n */\n private static chunk(originalArray: Uint8Array, chunkSize: number): Uint8Array[] {\n const resultArray = [];\n\n for (let i = 0; i < originalArray.length; i += chunkSize) {\n const chunk = originalArray.slice(i, i + chunkSize);\n resultArray.push(chunk);\n }\n\n return resultArray;\n }\n\n /**\n * Converts an array of bits to a byte\n * @param bits\n * @returns\n */\n private static bitsToByte(bits: Uint8Array) {\n let byteValue = 0;\n for (let i = 0; i < bits.length; i++) {\n byteValue = (byteValue << 1) | bits[i];\n }\n return byteValue;\n }\n}","import ImageUtils, { 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 * @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\n /**\n * Create a new bitmap command for the given image url\n * @param image Image to create command for \n * @param x X coordinate of the image\n * @param y Y coordinate of the image\n * @param imageWidth Desired width of the image\n * @param imageHeight Desired height of the image\n * @param mode Graphics mode\n * @returns \n */\n static async forImageUrl(image: string, x: number, y: number, imageWidth?: number, imageHeight?: number, mode?: GraphicMode) {\n const bitmap = await ImageUtils.getBWBitmap(image, imageWidth, imageHeight)\n return new TSPLBitmapCommand(bitmap, x, y, mode)\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 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}","/**\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 { WebUSB } from \"usb\";\nimport StringUtils from \"./StringUtils\";\n\nconst unsupportedUsbError = \"usb-unsupported\"\nconst stringHelper = new StringUtils()\n\nlet usbAgent: USB\n\n/**\n * @returns The appropiate USB agent based on the environment\n */\nconst getUSB = async (): Promise<USB> => {\n if(usbAgent) return usbAgent\n\n if(typeof navigator !== \"undefined\") {\n if(navigator.usb) {\n usbAgent = navigator.usb\n } else {\n throw unsupportedUsbError\n }\n } else {\n const { WebUSB } = await import(\"usb\")\n usbAgent = new WebUSB({allowAllDevices: true})\n }\n\n return usbAgent\n}\n\n/**\n * Returns the list of available devices\n * In node this returns all the connected devices but in the browser it will only return devices \n * that the user already gave permission to\n * @returns A list of available devices\n */\nexport const getDevices = async (): Promise<UsbDevice[]> => {\n const agent = await getUSB()\n const devices = await agent.getDevices()\n return devices.map(device => new UsbDevice(device) )\n}\n\n/**\n * In node, it returns the first available device, in the browser (supported browsers only) it shows \n * a UI for the user to choose a device\n * @returns The first available device\n */\nexport const requestDevice = async (): Promise<UsbDevice|undefined> => {\n const agent = await getUSB()\n const device = await agent.requestDevice()\n if(device) {\n return new UsbDevice(device)\n } else {\n return undefined\n }\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","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, requestDevice } 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\n /**\n * This is intended to be used in the browser although it also works in node\n * In the browser, it provides a UI for the user to choose a USB device and if it is a\n * printer, it returns a new printer instance. In Node however, this will try to create\n * a printer for the first available device and returns it. This means that even if there is a \n * printer, it may return undefined. In node, use `getPrinters` instead\n */\n static async requestPrinter(): Promise<Printer|undefined> {\n const device = await requestDevice()\n if(device) {\n return PrinterService.printerForDevice(device)\n }\n }\n}"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "label-printer",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "js package providing an abstraction over different thermal printer languages",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
"ts-node": "^10.9.2",
|
|
24
24
|
"tsconfig-paths": "^4.2.0",
|
|
25
25
|
"tsup": "^8.0.1",
|
|
26
|
-
"typescript": "^5.3.3"
|
|
26
|
+
"typescript": "^5.3.3",
|
|
27
|
+
"@changesets/cli": "^2.27.1"
|
|
27
28
|
},
|
|
28
29
|
"dependencies": {
|
|
29
|
-
"@changesets/cli": "^2.27.1",
|
|
30
30
|
"@types/w3c-web-usb": "^1.0.10",
|
|
31
31
|
"image-pixels": "^2.2.2",
|
|
32
32
|
"usb": "^2.11.0"
|