label-printer 0.7.0 → 0.7.2
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/README.md +70 -39
- package/dist/index.d.mts +114 -1
- package/dist/index.d.ts +114 -1
- package/dist/index.js +120 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +120 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,16 +20,16 @@ npm install label-printer
|
|
|
20
20
|
|
|
21
21
|
The library exposes three main areas:
|
|
22
22
|
|
|
23
|
-
- **Commands**: `import {
|
|
24
|
-
- **Labels**: `import {
|
|
25
|
-
- **Printers**: `import {
|
|
23
|
+
- **Commands**: `import { commands } from "label-printer"`
|
|
24
|
+
- **Labels**: `import { labels } from "label-printer"`
|
|
25
|
+
- **Printers**: `import { printers } from "label-printer"`
|
|
26
26
|
|
|
27
27
|
## Runtime support (Browser vs Node)
|
|
28
28
|
|
|
29
29
|
### Browser
|
|
30
30
|
|
|
31
31
|
- Uses **WebUSB** to communicate with USB label printers.
|
|
32
|
-
- Typical entry point: `PrinterService.requestPrinter()`.
|
|
32
|
+
- Typical entry point: `printers.PrinterService.requestPrinter()`.
|
|
33
33
|
|
|
34
34
|
### Node.js
|
|
35
35
|
|
|
@@ -45,31 +45,31 @@ The library exposes three main areas:
|
|
|
45
45
|
### Discover printers
|
|
46
46
|
|
|
47
47
|
```ts
|
|
48
|
-
import {
|
|
48
|
+
import { printers } from "label-printer"
|
|
49
49
|
|
|
50
|
-
const
|
|
51
|
-
if(
|
|
50
|
+
const printersList = await printers.PrinterService.getPrinters()
|
|
51
|
+
if(printersList.length === 0) {
|
|
52
52
|
throw new Error("No printers found")
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
const printer =
|
|
55
|
+
const printer = printersList[0]
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
### Request a printer (browser-focused)
|
|
59
59
|
|
|
60
60
|
```ts
|
|
61
|
-
import {
|
|
61
|
+
import { printers } from "label-printer"
|
|
62
62
|
|
|
63
|
-
const printer = await PrinterService.requestPrinter()
|
|
63
|
+
const printer = await printers.PrinterService.requestPrinter()
|
|
64
64
|
if(!printer) throw new Error("No printer selected")
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
### Print or display a label
|
|
68
68
|
|
|
69
69
|
```ts
|
|
70
|
-
import {
|
|
70
|
+
import { labels } from "label-printer"
|
|
71
71
|
|
|
72
|
-
const label = new Label(50, 25)
|
|
72
|
+
const label = new labels.Label(50, 25)
|
|
73
73
|
// 1 label, 3mm gap
|
|
74
74
|
await printer.print(label, 1, 3)
|
|
75
75
|
// or
|
|
@@ -78,15 +78,48 @@ await printer.display(label)
|
|
|
78
78
|
await printer.close()
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
###
|
|
81
|
+
### Connect directly (bypass discovery)
|
|
82
82
|
|
|
83
|
-
If you already know
|
|
83
|
+
If you already know how to reach your printer (network address or USB identifiers), you can create a printer instance directly.
|
|
84
|
+
|
|
85
|
+
Auto-detect language (recommended default):
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { printers } from "label-printer"
|
|
89
|
+
|
|
90
|
+
const printer = await printers.PrinterService.connect({ network: { host: "192.168.100.31" } })
|
|
91
|
+
if(!printer) throw new Error("Printer not found or not supported")
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Explicit TSPL (when you know it's a TSPL printer):
|
|
84
95
|
|
|
85
96
|
```ts
|
|
86
|
-
import
|
|
87
|
-
|
|
97
|
+
import { printers } from "label-printer"
|
|
98
|
+
|
|
99
|
+
const printer = await printers.PrinterService.connectTSPL({ network: { host: "192.168.100.31", port: 9100 } })
|
|
100
|
+
if(!printer) throw new Error("Not a TSPL printer")
|
|
101
|
+
```
|
|
88
102
|
|
|
89
|
-
|
|
103
|
+
USB (Node.js - filter without a prompt):
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { printers } from "label-printer"
|
|
107
|
+
|
|
108
|
+
const printer = await printers.PrinterService.connect({
|
|
109
|
+
usb: { vendorId: 0x1234, productId: 0x5678, serialNumber: "ABC" }
|
|
110
|
+
})
|
|
111
|
+
if(!printer) throw new Error("Printer not found or not supported")
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
USB (Browser - shows a picker; you can optionally filter by `vendorId` / `productId`):
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import { printers } from "label-printer"
|
|
118
|
+
|
|
119
|
+
const printer = await printers.PrinterService.connect({
|
|
120
|
+
usb: { vendorId: 0x1234, productId: 0x5678 }
|
|
121
|
+
})
|
|
122
|
+
if(!printer) throw new Error("No printer selected")
|
|
90
123
|
```
|
|
91
124
|
|
|
92
125
|
## Device abstraction
|
|
@@ -94,16 +127,16 @@ const printer = new TSPLPrinter(new NetworkDevice("192.168.100.31", 9100))
|
|
|
94
127
|
Commands write to a transport-agnostic `Device` interface. This enables the same printer and label APIs to work over different transports.
|
|
95
128
|
|
|
96
129
|
- **USB** device implementation is internal to `USBUtils`.
|
|
97
|
-
- **
|
|
130
|
+
- **Network** support uses a TCP implementation in Node.js.
|
|
98
131
|
|
|
99
132
|
## Label layer
|
|
100
133
|
|
|
101
134
|
The label layer provides a language-independent way to construct labels, which can then be rendered to commands for the chosen printer language.
|
|
102
135
|
|
|
103
136
|
```ts
|
|
104
|
-
import {
|
|
137
|
+
import { labels } from "label-printer"
|
|
105
138
|
|
|
106
|
-
const label = new Label(50, 25)
|
|
139
|
+
const label = new labels.Label(50, 25)
|
|
107
140
|
// label.add(...fields)
|
|
108
141
|
```
|
|
109
142
|
|
|
@@ -113,19 +146,18 @@ const label = new Label(50, 25)
|
|
|
113
146
|
|
|
114
147
|
## Fields
|
|
115
148
|
|
|
116
|
-
Fields
|
|
149
|
+
Fields are available from the package root export.
|
|
117
150
|
|
|
118
151
|
### Text
|
|
119
152
|
|
|
120
153
|
Create a text field at (`x`, `y`) in **dots**.
|
|
121
154
|
|
|
122
155
|
```ts
|
|
123
|
-
import {
|
|
124
|
-
import { Text } from "label-printer/dist/labels/fields"
|
|
156
|
+
import { labels } from "label-printer"
|
|
125
157
|
|
|
126
|
-
const label = new Label(50, 25)
|
|
158
|
+
const label = new labels.Label(50, 25)
|
|
127
159
|
|
|
128
|
-
const text = new Text("Hello", 20, 20, true)
|
|
160
|
+
const text = new labels.Text("Hello", 20, 20, true)
|
|
129
161
|
text.setSingleLine(200)
|
|
130
162
|
|
|
131
163
|
label.add(text)
|
|
@@ -148,9 +180,9 @@ Formatted text (when `formatted = true`) supports basic tags:
|
|
|
148
180
|
Draw a line between two points (values in **dots**).
|
|
149
181
|
|
|
150
182
|
```ts
|
|
151
|
-
import {
|
|
183
|
+
import { labels } from "label-printer"
|
|
152
184
|
|
|
153
|
-
label.add(new Line({ x: 10, y: 10 }, { x: 300, y: 10 }, 3))
|
|
185
|
+
label.add(new labels.Line({ x: 10, y: 10 }, { x: 300, y: 10 }, 3))
|
|
154
186
|
```
|
|
155
187
|
|
|
156
188
|
### Image
|
|
@@ -159,9 +191,9 @@ Draw a black/white bitmap image. You can either provide a bitmap-like object dir
|
|
|
159
191
|
or use the async helper to load/convert an image.
|
|
160
192
|
|
|
161
193
|
```ts
|
|
162
|
-
import {
|
|
194
|
+
import { labels } from "label-printer"
|
|
163
195
|
|
|
164
|
-
const img = await Image.create("./logo.png", 10, 60, 200)
|
|
196
|
+
const img = await labels.Image.create("./logo.png", 10, 60, 200)
|
|
165
197
|
label.add(img)
|
|
166
198
|
```
|
|
167
199
|
|
|
@@ -170,9 +202,9 @@ label.add(img)
|
|
|
170
202
|
Draw a barcode (TSPL-backed). Values are in **dots**.
|
|
171
203
|
|
|
172
204
|
```ts
|
|
173
|
-
import {
|
|
205
|
+
import { labels } from "label-printer"
|
|
174
206
|
|
|
175
|
-
const barcode = new BarCode("123456789", 20, 120, "CODE128", 80)
|
|
207
|
+
const barcode = new labels.BarCode("123456789", 20, 120, "CODE128", 80)
|
|
176
208
|
barcode.setHumanReadable("bottom")
|
|
177
209
|
barcode.setRotation(0)
|
|
178
210
|
|
|
@@ -184,9 +216,9 @@ label.add(barcode)
|
|
|
184
216
|
Draw a QR code.
|
|
185
217
|
|
|
186
218
|
```ts
|
|
187
|
-
import {
|
|
219
|
+
import { labels } from "label-printer"
|
|
188
220
|
|
|
189
|
-
label.add(new QRCode("https://example.com", 20, 220, 6))
|
|
221
|
+
label.add(new labels.QRCode("https://example.com", 20, 220, 6))
|
|
190
222
|
```
|
|
191
223
|
|
|
192
224
|
### Table
|
|
@@ -194,12 +226,11 @@ label.add(new QRCode("https://example.com", 20, 220, 6))
|
|
|
194
226
|
The `Table` field draws a grid and places text into each cell. It uses the existing `Text` field for cell contents and the existing `Line` field for the grid lines.
|
|
195
227
|
|
|
196
228
|
```ts
|
|
197
|
-
import {
|
|
198
|
-
import { Table } from "label-printer/dist/labels/fields"
|
|
229
|
+
import { labels } from "label-printer"
|
|
199
230
|
|
|
200
|
-
const label = new Label(50, 25)
|
|
231
|
+
const label = new labels.Label(50, 25)
|
|
201
232
|
|
|
202
|
-
const table = new Table(10, 10, [
|
|
233
|
+
const table = new labels.Table(10, 10, [
|
|
203
234
|
["A1", "A2"],
|
|
204
235
|
["B1", "B2"],
|
|
205
236
|
], {
|
|
@@ -281,9 +312,9 @@ Registering fonts enables better text measurement (for wrapping) and ensures the
|
|
|
281
312
|
as part of the generated print/display command sequence.
|
|
282
313
|
|
|
283
314
|
```ts
|
|
284
|
-
import {
|
|
315
|
+
import { labels } from "label-printer"
|
|
285
316
|
|
|
286
|
-
const label = new Label(50, 25)
|
|
317
|
+
const label = new labels.Label(50, 25)
|
|
287
318
|
|
|
288
319
|
await label.registerFont({
|
|
289
320
|
name: "MyFont",
|
package/dist/index.d.mts
CHANGED
|
@@ -803,11 +803,12 @@ declare namespace index$1 {
|
|
|
803
803
|
export { index$1_BarCode as BarCode, index$1_Image as Image, index$1_Label as Label, index$1_LabelField as LabelField, index$1_Line as Line, index$1_QRCode as QRCode, index$1_Table as Table, index$1_Text as Text };
|
|
804
804
|
}
|
|
805
805
|
|
|
806
|
+
type PrinterStatus = "normal" | "head_opened" | "paper_jam" | "paper_jam_head_opened" | "out_of_paper" | "out_of_paper_head_opened" | "out_of_ribbon" | "out_of_ribbon_head_opened" | "out_of_ribbon_paper_jam" | "out_of_ribbon_paper_jam_head_opened" | "out_of_ribbon_out_of_paper" | "out_of_ribbon_out_of_paper_head_opened" | "paused" | "printing" | "other_error";
|
|
806
807
|
/**
|
|
807
808
|
* Base class that encapsulates functionality of all printers
|
|
808
809
|
*/
|
|
809
810
|
declare abstract class Printer {
|
|
810
|
-
|
|
811
|
+
protected readonly device: Device;
|
|
811
812
|
/**
|
|
812
813
|
* Printer language used by the type of printer the subclass represents
|
|
813
814
|
*/
|
|
@@ -816,6 +817,8 @@ declare abstract class Printer {
|
|
|
816
817
|
* When called, it will feed the labels to the beginig of the next label
|
|
817
818
|
*/
|
|
818
819
|
abstract feedLabel(): Promise<void>;
|
|
820
|
+
abstract getModelname(): Promise<string>;
|
|
821
|
+
abstract getStatus(): Promise<PrinterStatus>;
|
|
819
822
|
constructor(device: Device);
|
|
820
823
|
/**
|
|
821
824
|
* Close the printer USB
|
|
@@ -843,6 +846,88 @@ declare abstract class Printer {
|
|
|
843
846
|
static try(_device: Device): Promise<boolean>;
|
|
844
847
|
}
|
|
845
848
|
|
|
849
|
+
declare class NetworkDevice implements Device {
|
|
850
|
+
private socket?;
|
|
851
|
+
private readonly host;
|
|
852
|
+
private readonly port;
|
|
853
|
+
private readonly connectTimeoutMs;
|
|
854
|
+
private readonly readTimeoutMs;
|
|
855
|
+
/**
|
|
856
|
+
* Create a TCP-based device.
|
|
857
|
+
*
|
|
858
|
+
* This is intended for raw printing ports (typically 9100). It is Node-only.
|
|
859
|
+
*
|
|
860
|
+
* @param host Hostname or IP
|
|
861
|
+
* @param port TCP port (defaults to 9100)
|
|
862
|
+
* @param connectTimeoutMs Connection timeout
|
|
863
|
+
* @param readTimeoutMs Read timeout used by `readData`/`readString`
|
|
864
|
+
*/
|
|
865
|
+
constructor(host: string, port?: number, connectTimeoutMs?: number, readTimeoutMs?: number);
|
|
866
|
+
get opened(): boolean;
|
|
867
|
+
openAndConfigure(): Promise<void>;
|
|
868
|
+
close(): Promise<void>;
|
|
869
|
+
writeData(data: Uint8Array | ArrayBuffer): Promise<void>;
|
|
870
|
+
writeString(text: string): Promise<void>;
|
|
871
|
+
readData(length: number): Promise<DataView | undefined>;
|
|
872
|
+
readString(length: number): Promise<string | undefined>;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
declare class TSPLPrinter extends Printer {
|
|
876
|
+
get language(): PrinterLanguage;
|
|
877
|
+
feedLabel(): Promise<void>;
|
|
878
|
+
getModelname(): Promise<string>;
|
|
879
|
+
getStatus(): Promise<PrinterStatus>;
|
|
880
|
+
private static statusFor;
|
|
881
|
+
static try(device: Device): Promise<boolean>;
|
|
882
|
+
/**
|
|
883
|
+
* Discover TSPL-capable printers on the local network.
|
|
884
|
+
*
|
|
885
|
+
* Strategy:
|
|
886
|
+
* - Use Bonjour/mDNS to discover "printer-ish" services to obtain a set of candidate hosts.
|
|
887
|
+
* - For each unique host, probe TCP/9100 by sending the TSPL identify command (~!I).
|
|
888
|
+
* - Only return devices that respond to the TSPL probe.
|
|
889
|
+
* - If Bonjour yields no candidates (e.g. mDNS is blocked), fall back to a conservative
|
|
890
|
+
* subnet scan on local private /24 networks (still verified by the same TSPL probe).
|
|
891
|
+
*/
|
|
892
|
+
static discoverDevices(): Promise<NetworkDevice[]>;
|
|
893
|
+
/**
|
|
894
|
+
* Fallback discovery mechanism used when Bonjour/mDNS returns no printer candidates.
|
|
895
|
+
*
|
|
896
|
+
* It derives local private IPv4 /24 prefixes from the current machine's network interfaces
|
|
897
|
+
* and probes TCP/9100 using the TSPL identify command.
|
|
898
|
+
*
|
|
899
|
+
* The scan is intentionally conservative:
|
|
900
|
+
* - Limited number of prefixes
|
|
901
|
+
* - Concurrency limits
|
|
902
|
+
* - Total time cap
|
|
903
|
+
* - Early-exit when at least one printer is found
|
|
904
|
+
*/
|
|
905
|
+
private static discoverHostsBySubnetScan;
|
|
906
|
+
/**
|
|
907
|
+
* Returns a Node-style `require` function.
|
|
908
|
+
*
|
|
909
|
+
* This is used to keep runtime dependencies Node-only while still allowing the library to
|
|
910
|
+
* be imported/bundled in browser contexts.
|
|
911
|
+
*
|
|
912
|
+
* Tests may inject a custom require implementation via `globalThis.__label_printer_require`.
|
|
913
|
+
*/
|
|
914
|
+
private static getNodeRequire;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
type PrinterServiceUsbConnectOptions = {
|
|
918
|
+
vendorId?: number;
|
|
919
|
+
productId?: number;
|
|
920
|
+
serialNumber?: string;
|
|
921
|
+
};
|
|
922
|
+
type PrinterServiceNetworkConnectOptions = {
|
|
923
|
+
host: string;
|
|
924
|
+
port?: number;
|
|
925
|
+
};
|
|
926
|
+
type PrinterServiceConnectOptions = {
|
|
927
|
+
usb: PrinterServiceUsbConnectOptions;
|
|
928
|
+
} | {
|
|
929
|
+
network: PrinterServiceNetworkConnectOptions;
|
|
930
|
+
};
|
|
846
931
|
declare class PrinterService {
|
|
847
932
|
/**
|
|
848
933
|
* Try each type of printer and return the one that mathces the usb device
|
|
@@ -872,6 +957,34 @@ declare class PrinterService {
|
|
|
872
957
|
* printer, it may return undefined. In node, use `getPrinters` instead
|
|
873
958
|
*/
|
|
874
959
|
static requestPrinter(): Promise<Printer | undefined>;
|
|
960
|
+
/**
|
|
961
|
+
* Create a printer instance using explicit connection information.
|
|
962
|
+
*
|
|
963
|
+
* This is useful when you already know your printer's network address or USB identifiers
|
|
964
|
+
* and want to bypass discovery.
|
|
965
|
+
*
|
|
966
|
+
* Behavior differs by environment:
|
|
967
|
+
* - **Node.js**
|
|
968
|
+
* - `network`: connects via TCP (defaults to port `9100`)
|
|
969
|
+
* - `usb`: selects the first connected USB device matching the provided filters
|
|
970
|
+
* - **Browser**
|
|
971
|
+
* - `usb`: shows the WebUSB picker (optionally filtered by `vendorId`/`productId`)
|
|
972
|
+
* - `network`: not supported (will throw if network transport is used in the browser)
|
|
973
|
+
*/
|
|
974
|
+
static connect(options: PrinterServiceConnectOptions): Promise<Printer | undefined>;
|
|
975
|
+
/**
|
|
976
|
+
* Create a TSPL printer instance using explicit connection information.
|
|
977
|
+
*
|
|
978
|
+
* This still verifies the target by probing it with the TSPL identify command (`~!I`).
|
|
979
|
+
* If the probe fails, `undefined` is returned.
|
|
980
|
+
*/
|
|
981
|
+
static connectTSPL(options: PrinterServiceConnectOptions): Promise<TSPLPrinter | undefined>;
|
|
982
|
+
/**
|
|
983
|
+
* Convert user-facing connect options into a concrete device.
|
|
984
|
+
*
|
|
985
|
+
* This keeps transport details (USB vs TCP socket) out of the public API.
|
|
986
|
+
*/
|
|
987
|
+
private static deviceForConnectOptions;
|
|
875
988
|
}
|
|
876
989
|
|
|
877
990
|
type index_Printer = Printer;
|
package/dist/index.d.ts
CHANGED
|
@@ -803,11 +803,12 @@ declare namespace index$1 {
|
|
|
803
803
|
export { index$1_BarCode as BarCode, index$1_Image as Image, index$1_Label as Label, index$1_LabelField as LabelField, index$1_Line as Line, index$1_QRCode as QRCode, index$1_Table as Table, index$1_Text as Text };
|
|
804
804
|
}
|
|
805
805
|
|
|
806
|
+
type PrinterStatus = "normal" | "head_opened" | "paper_jam" | "paper_jam_head_opened" | "out_of_paper" | "out_of_paper_head_opened" | "out_of_ribbon" | "out_of_ribbon_head_opened" | "out_of_ribbon_paper_jam" | "out_of_ribbon_paper_jam_head_opened" | "out_of_ribbon_out_of_paper" | "out_of_ribbon_out_of_paper_head_opened" | "paused" | "printing" | "other_error";
|
|
806
807
|
/**
|
|
807
808
|
* Base class that encapsulates functionality of all printers
|
|
808
809
|
*/
|
|
809
810
|
declare abstract class Printer {
|
|
810
|
-
|
|
811
|
+
protected readonly device: Device;
|
|
811
812
|
/**
|
|
812
813
|
* Printer language used by the type of printer the subclass represents
|
|
813
814
|
*/
|
|
@@ -816,6 +817,8 @@ declare abstract class Printer {
|
|
|
816
817
|
* When called, it will feed the labels to the beginig of the next label
|
|
817
818
|
*/
|
|
818
819
|
abstract feedLabel(): Promise<void>;
|
|
820
|
+
abstract getModelname(): Promise<string>;
|
|
821
|
+
abstract getStatus(): Promise<PrinterStatus>;
|
|
819
822
|
constructor(device: Device);
|
|
820
823
|
/**
|
|
821
824
|
* Close the printer USB
|
|
@@ -843,6 +846,88 @@ declare abstract class Printer {
|
|
|
843
846
|
static try(_device: Device): Promise<boolean>;
|
|
844
847
|
}
|
|
845
848
|
|
|
849
|
+
declare class NetworkDevice implements Device {
|
|
850
|
+
private socket?;
|
|
851
|
+
private readonly host;
|
|
852
|
+
private readonly port;
|
|
853
|
+
private readonly connectTimeoutMs;
|
|
854
|
+
private readonly readTimeoutMs;
|
|
855
|
+
/**
|
|
856
|
+
* Create a TCP-based device.
|
|
857
|
+
*
|
|
858
|
+
* This is intended for raw printing ports (typically 9100). It is Node-only.
|
|
859
|
+
*
|
|
860
|
+
* @param host Hostname or IP
|
|
861
|
+
* @param port TCP port (defaults to 9100)
|
|
862
|
+
* @param connectTimeoutMs Connection timeout
|
|
863
|
+
* @param readTimeoutMs Read timeout used by `readData`/`readString`
|
|
864
|
+
*/
|
|
865
|
+
constructor(host: string, port?: number, connectTimeoutMs?: number, readTimeoutMs?: number);
|
|
866
|
+
get opened(): boolean;
|
|
867
|
+
openAndConfigure(): Promise<void>;
|
|
868
|
+
close(): Promise<void>;
|
|
869
|
+
writeData(data: Uint8Array | ArrayBuffer): Promise<void>;
|
|
870
|
+
writeString(text: string): Promise<void>;
|
|
871
|
+
readData(length: number): Promise<DataView | undefined>;
|
|
872
|
+
readString(length: number): Promise<string | undefined>;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
declare class TSPLPrinter extends Printer {
|
|
876
|
+
get language(): PrinterLanguage;
|
|
877
|
+
feedLabel(): Promise<void>;
|
|
878
|
+
getModelname(): Promise<string>;
|
|
879
|
+
getStatus(): Promise<PrinterStatus>;
|
|
880
|
+
private static statusFor;
|
|
881
|
+
static try(device: Device): Promise<boolean>;
|
|
882
|
+
/**
|
|
883
|
+
* Discover TSPL-capable printers on the local network.
|
|
884
|
+
*
|
|
885
|
+
* Strategy:
|
|
886
|
+
* - Use Bonjour/mDNS to discover "printer-ish" services to obtain a set of candidate hosts.
|
|
887
|
+
* - For each unique host, probe TCP/9100 by sending the TSPL identify command (~!I).
|
|
888
|
+
* - Only return devices that respond to the TSPL probe.
|
|
889
|
+
* - If Bonjour yields no candidates (e.g. mDNS is blocked), fall back to a conservative
|
|
890
|
+
* subnet scan on local private /24 networks (still verified by the same TSPL probe).
|
|
891
|
+
*/
|
|
892
|
+
static discoverDevices(): Promise<NetworkDevice[]>;
|
|
893
|
+
/**
|
|
894
|
+
* Fallback discovery mechanism used when Bonjour/mDNS returns no printer candidates.
|
|
895
|
+
*
|
|
896
|
+
* It derives local private IPv4 /24 prefixes from the current machine's network interfaces
|
|
897
|
+
* and probes TCP/9100 using the TSPL identify command.
|
|
898
|
+
*
|
|
899
|
+
* The scan is intentionally conservative:
|
|
900
|
+
* - Limited number of prefixes
|
|
901
|
+
* - Concurrency limits
|
|
902
|
+
* - Total time cap
|
|
903
|
+
* - Early-exit when at least one printer is found
|
|
904
|
+
*/
|
|
905
|
+
private static discoverHostsBySubnetScan;
|
|
906
|
+
/**
|
|
907
|
+
* Returns a Node-style `require` function.
|
|
908
|
+
*
|
|
909
|
+
* This is used to keep runtime dependencies Node-only while still allowing the library to
|
|
910
|
+
* be imported/bundled in browser contexts.
|
|
911
|
+
*
|
|
912
|
+
* Tests may inject a custom require implementation via `globalThis.__label_printer_require`.
|
|
913
|
+
*/
|
|
914
|
+
private static getNodeRequire;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
type PrinterServiceUsbConnectOptions = {
|
|
918
|
+
vendorId?: number;
|
|
919
|
+
productId?: number;
|
|
920
|
+
serialNumber?: string;
|
|
921
|
+
};
|
|
922
|
+
type PrinterServiceNetworkConnectOptions = {
|
|
923
|
+
host: string;
|
|
924
|
+
port?: number;
|
|
925
|
+
};
|
|
926
|
+
type PrinterServiceConnectOptions = {
|
|
927
|
+
usb: PrinterServiceUsbConnectOptions;
|
|
928
|
+
} | {
|
|
929
|
+
network: PrinterServiceNetworkConnectOptions;
|
|
930
|
+
};
|
|
846
931
|
declare class PrinterService {
|
|
847
932
|
/**
|
|
848
933
|
* Try each type of printer and return the one that mathces the usb device
|
|
@@ -872,6 +957,34 @@ declare class PrinterService {
|
|
|
872
957
|
* printer, it may return undefined. In node, use `getPrinters` instead
|
|
873
958
|
*/
|
|
874
959
|
static requestPrinter(): Promise<Printer | undefined>;
|
|
960
|
+
/**
|
|
961
|
+
* Create a printer instance using explicit connection information.
|
|
962
|
+
*
|
|
963
|
+
* This is useful when you already know your printer's network address or USB identifiers
|
|
964
|
+
* and want to bypass discovery.
|
|
965
|
+
*
|
|
966
|
+
* Behavior differs by environment:
|
|
967
|
+
* - **Node.js**
|
|
968
|
+
* - `network`: connects via TCP (defaults to port `9100`)
|
|
969
|
+
* - `usb`: selects the first connected USB device matching the provided filters
|
|
970
|
+
* - **Browser**
|
|
971
|
+
* - `usb`: shows the WebUSB picker (optionally filtered by `vendorId`/`productId`)
|
|
972
|
+
* - `network`: not supported (will throw if network transport is used in the browser)
|
|
973
|
+
*/
|
|
974
|
+
static connect(options: PrinterServiceConnectOptions): Promise<Printer | undefined>;
|
|
975
|
+
/**
|
|
976
|
+
* Create a TSPL printer instance using explicit connection information.
|
|
977
|
+
*
|
|
978
|
+
* This still verifies the target by probing it with the TSPL identify command (`~!I`).
|
|
979
|
+
* If the probe fails, `undefined` is returned.
|
|
980
|
+
*/
|
|
981
|
+
static connectTSPL(options: PrinterServiceConnectOptions): Promise<TSPLPrinter | undefined>;
|
|
982
|
+
/**
|
|
983
|
+
* Convert user-facing connect options into a concrete device.
|
|
984
|
+
*
|
|
985
|
+
* This keeps transport details (USB vs TCP socket) out of the public API.
|
|
986
|
+
*/
|
|
987
|
+
private static deviceForConnectOptions;
|
|
875
988
|
}
|
|
876
989
|
|
|
877
990
|
type index_Printer = Printer;
|
package/dist/index.js
CHANGED
|
@@ -1436,10 +1436,28 @@ var requestDevice = () => __async(null, null, function* () {
|
|
|
1436
1436
|
return void 0;
|
|
1437
1437
|
}
|
|
1438
1438
|
});
|
|
1439
|
+
var requestDeviceWithFilters = (..._0) => __async(null, [..._0], function* (filters = []) {
|
|
1440
|
+
const agent = yield getUSB();
|
|
1441
|
+
const device = yield agent.requestDevice({ filters });
|
|
1442
|
+
if (device) {
|
|
1443
|
+
return new UsbDevice(device);
|
|
1444
|
+
} else {
|
|
1445
|
+
return void 0;
|
|
1446
|
+
}
|
|
1447
|
+
});
|
|
1439
1448
|
var UsbDevice = class {
|
|
1440
1449
|
get opened() {
|
|
1441
1450
|
return this.device.opened;
|
|
1442
1451
|
}
|
|
1452
|
+
get vendorId() {
|
|
1453
|
+
return this.device.vendorId;
|
|
1454
|
+
}
|
|
1455
|
+
get productId() {
|
|
1456
|
+
return this.device.productId;
|
|
1457
|
+
}
|
|
1458
|
+
get serialNumber() {
|
|
1459
|
+
return this.device.serialNumber;
|
|
1460
|
+
}
|
|
1443
1461
|
/**
|
|
1444
1462
|
* All available endpoints
|
|
1445
1463
|
*/
|
|
@@ -1755,6 +1773,45 @@ var TSPLPrinter = class _TSPLPrinter extends Printer {
|
|
|
1755
1773
|
yield this.writeCommand(feedCommand);
|
|
1756
1774
|
});
|
|
1757
1775
|
}
|
|
1776
|
+
getModelname() {
|
|
1777
|
+
return __async(this, null, function* () {
|
|
1778
|
+
if (!this.device.opened) yield this.device.openAndConfigure();
|
|
1779
|
+
const command = new TSPLRawCommand("~!T");
|
|
1780
|
+
yield command.writeTo(this.device);
|
|
1781
|
+
const response = yield this.device.readString(256);
|
|
1782
|
+
return (response != null ? response : "").trim();
|
|
1783
|
+
});
|
|
1784
|
+
}
|
|
1785
|
+
getStatus() {
|
|
1786
|
+
return __async(this, null, function* () {
|
|
1787
|
+
if (!this.device.opened) yield this.device.openAndConfigure();
|
|
1788
|
+
yield this.device.writeData(new Uint8Array([27, 33, 63, 10]));
|
|
1789
|
+
const data = yield this.device.readData(1);
|
|
1790
|
+
const raw = data ? data.getUint8(0) : 128;
|
|
1791
|
+
return _TSPLPrinter.statusFor(raw);
|
|
1792
|
+
});
|
|
1793
|
+
}
|
|
1794
|
+
static statusFor(code) {
|
|
1795
|
+
var _a;
|
|
1796
|
+
const map = {
|
|
1797
|
+
0: "normal",
|
|
1798
|
+
1: "head_opened",
|
|
1799
|
+
2: "paper_jam",
|
|
1800
|
+
3: "paper_jam_head_opened",
|
|
1801
|
+
4: "out_of_paper",
|
|
1802
|
+
5: "out_of_paper_head_opened",
|
|
1803
|
+
8: "out_of_ribbon",
|
|
1804
|
+
9: "out_of_ribbon_head_opened",
|
|
1805
|
+
10: "out_of_ribbon_paper_jam",
|
|
1806
|
+
11: "out_of_ribbon_paper_jam_head_opened",
|
|
1807
|
+
12: "out_of_ribbon_out_of_paper",
|
|
1808
|
+
13: "out_of_ribbon_out_of_paper_head_opened",
|
|
1809
|
+
16: "paused",
|
|
1810
|
+
32: "printing",
|
|
1811
|
+
128: "other_error"
|
|
1812
|
+
};
|
|
1813
|
+
return (_a = map[code]) != null ? _a : "other_error";
|
|
1814
|
+
}
|
|
1758
1815
|
static try(device) {
|
|
1759
1816
|
return __async(this, null, function* () {
|
|
1760
1817
|
if (!device.opened) yield device.openAndConfigure();
|
|
@@ -1982,6 +2039,69 @@ var PrinterService = class _PrinterService {
|
|
|
1982
2039
|
}
|
|
1983
2040
|
});
|
|
1984
2041
|
}
|
|
2042
|
+
/**
|
|
2043
|
+
* Create a printer instance using explicit connection information.
|
|
2044
|
+
*
|
|
2045
|
+
* This is useful when you already know your printer's network address or USB identifiers
|
|
2046
|
+
* and want to bypass discovery.
|
|
2047
|
+
*
|
|
2048
|
+
* Behavior differs by environment:
|
|
2049
|
+
* - **Node.js**
|
|
2050
|
+
* - `network`: connects via TCP (defaults to port `9100`)
|
|
2051
|
+
* - `usb`: selects the first connected USB device matching the provided filters
|
|
2052
|
+
* - **Browser**
|
|
2053
|
+
* - `usb`: shows the WebUSB picker (optionally filtered by `vendorId`/`productId`)
|
|
2054
|
+
* - `network`: not supported (will throw if network transport is used in the browser)
|
|
2055
|
+
*/
|
|
2056
|
+
static connect(options) {
|
|
2057
|
+
return __async(this, null, function* () {
|
|
2058
|
+
const device = yield _PrinterService.deviceForConnectOptions(options);
|
|
2059
|
+
if (!device) return void 0;
|
|
2060
|
+
return _PrinterService.printerForDevice(device);
|
|
2061
|
+
});
|
|
2062
|
+
}
|
|
2063
|
+
/**
|
|
2064
|
+
* Create a TSPL printer instance using explicit connection information.
|
|
2065
|
+
*
|
|
2066
|
+
* This still verifies the target by probing it with the TSPL identify command (`~!I`).
|
|
2067
|
+
* If the probe fails, `undefined` is returned.
|
|
2068
|
+
*/
|
|
2069
|
+
static connectTSPL(options) {
|
|
2070
|
+
return __async(this, null, function* () {
|
|
2071
|
+
const device = yield _PrinterService.deviceForConnectOptions(options);
|
|
2072
|
+
if (!device) return void 0;
|
|
2073
|
+
const ok = yield TSPLPrinter.try(device);
|
|
2074
|
+
if (!ok) return void 0;
|
|
2075
|
+
return new TSPLPrinter(device);
|
|
2076
|
+
});
|
|
2077
|
+
}
|
|
2078
|
+
/**
|
|
2079
|
+
* Convert user-facing connect options into a concrete device.
|
|
2080
|
+
*
|
|
2081
|
+
* This keeps transport details (USB vs TCP socket) out of the public API.
|
|
2082
|
+
*/
|
|
2083
|
+
static deviceForConnectOptions(options) {
|
|
2084
|
+
return __async(this, null, function* () {
|
|
2085
|
+
var _a;
|
|
2086
|
+
if ("network" in options) {
|
|
2087
|
+
const port = (_a = options.network.port) != null ? _a : 9100;
|
|
2088
|
+
return new NetworkDevice(options.network.host, port);
|
|
2089
|
+
}
|
|
2090
|
+
const filters = [{ vendorId: options.usb.vendorId, productId: options.usb.productId }].filter((f) => f.vendorId != null || f.productId != null);
|
|
2091
|
+
if (typeof window !== "undefined") {
|
|
2092
|
+
if (filters.length > 0) return requestDeviceWithFilters(filters);
|
|
2093
|
+
return requestDevice();
|
|
2094
|
+
}
|
|
2095
|
+
const devices = yield getDevices();
|
|
2096
|
+
const matching = devices.filter((d) => {
|
|
2097
|
+
if (options.usb.vendorId != null && d.vendorId !== options.usb.vendorId) return false;
|
|
2098
|
+
if (options.usb.productId != null && d.productId !== options.usb.productId) return false;
|
|
2099
|
+
if (options.usb.serialNumber != null && d.serialNumber !== options.usb.serialNumber) return false;
|
|
2100
|
+
return true;
|
|
2101
|
+
});
|
|
2102
|
+
return matching[0];
|
|
2103
|
+
});
|
|
2104
|
+
}
|
|
1985
2105
|
};
|
|
1986
2106
|
|
|
1987
2107
|
// src/labels/index.ts
|