@fedejm/capacitor-esc-pos-printer 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +355 -5
- package/android/src/main/AndroidManifest.xml +6 -0
- package/android/src/main/java/com/getcapacitor/community/escposprinter/EscPosPrinterPlugin.java +382 -22
- package/android/src/main/java/com/getcapacitor/community/escposprinter/printers/UsbPrinter.java +355 -3
- package/android/src/main/java/com/getcapacitor/community/escposprinter/printers/constants/PrinterErrorCode.java +2 -0
- package/dist/docs.json +160 -1
- package/dist/esm/definitions.d.ts +54 -3
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/enums/printer-connection-type.d.ts +3 -1
- package/dist/esm/enums/printer-connection-type.js +2 -0
- package/dist/esm/enums/printer-connection-type.js.map +1 -1
- package/dist/esm/enums/printer-error-code.d.ts +3 -1
- package/dist/esm/enums/printer-error-code.js +2 -0
- package/dist/esm/enums/printer-error-code.js.map +1 -1
- package/dist/esm/printers/index.d.ts +1 -0
- package/dist/esm/printers/index.js +1 -0
- package/dist/esm/printers/index.js.map +1 -1
- package/dist/esm/printers/usb-printer.d.ts +35 -0
- package/dist/esm/printers/usb-printer.js +42 -0
- package/dist/esm/printers/usb-printer.js.map +1 -0
- package/dist/esm/web.d.ts +3 -1
- package/dist/esm/web.js +10 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +55 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +55 -0
- package/dist/plugin.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,19 +2,138 @@
|
|
|
2
2
|
|
|
3
3
|
CapacitorJS wrapper for ESC POS (native) printers.
|
|
4
4
|
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Bluetooth printing** - Connect to Bluetooth ESC/POS printers (Android, iOS)
|
|
8
|
+
- **USB printing** - Connect to USB ESC/POS printers via USB Host API (Android only)
|
|
9
|
+
- **Raw data sending** - Send raw ESC/POS commands for full control
|
|
10
|
+
- **Bi-directional communication** - Read responses from printer
|
|
11
|
+
- **Permission management** - Built-in USB permission request flow
|
|
12
|
+
|
|
5
13
|
## Install
|
|
6
14
|
|
|
7
15
|
```bash
|
|
8
|
-
npm install capacitor-esc-pos-printer
|
|
16
|
+
npm install @fedejm/capacitor-esc-pos-printer
|
|
9
17
|
npx cap sync
|
|
10
18
|
```
|
|
11
19
|
|
|
20
|
+
## Platform Support
|
|
21
|
+
|
|
22
|
+
| Feature | Android | iOS | Web |
|
|
23
|
+
|------------|---------|---------|---------|
|
|
24
|
+
| Bluetooth | Yes | Yes | Limited |
|
|
25
|
+
| USB | Yes | No | No |
|
|
26
|
+
| Network | Planned | Planned | Planned |
|
|
27
|
+
|
|
28
|
+
### Android Requirements
|
|
29
|
+
|
|
30
|
+
- **Bluetooth**: Requires `BLUETOOTH_CONNECT` and `BLUETOOTH_SCAN` permissions (Android 12+)
|
|
31
|
+
- **USB**: Requires `android.hardware.usb.host` feature (automatically declared as optional)
|
|
32
|
+
|
|
33
|
+
### iOS Requirements
|
|
34
|
+
|
|
35
|
+
- Bluetooth printing is supported via CoreBluetooth framework
|
|
36
|
+
- USB printing is not available on iOS
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
### Bluetooth Printer
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { EscPosPrinter, BluetoothPrinter } from '@fedejm/capacitor-esc-pos-printer';
|
|
44
|
+
|
|
45
|
+
// Request Bluetooth enable (Android)
|
|
46
|
+
await EscPosPrinter.requestBluetoothEnable();
|
|
47
|
+
|
|
48
|
+
// Get paired Bluetooth printers
|
|
49
|
+
const { devices } = await EscPosPrinter.getBluetoothPrinterDevices();
|
|
50
|
+
console.log('Found printers:', devices);
|
|
51
|
+
|
|
52
|
+
// Create and connect to a printer
|
|
53
|
+
const printer = new BluetoothPrinter(devices[0].address);
|
|
54
|
+
await printer.link();
|
|
55
|
+
await printer.connect();
|
|
56
|
+
|
|
57
|
+
// Send ESC/POS commands
|
|
58
|
+
await printer.send([0x1B, 0x40]); // Initialize printer
|
|
59
|
+
await printer.send([0x48, 0x65, 0x6C, 0x6C, 0x6F]); // "Hello"
|
|
60
|
+
await printer.send([0x0A]); // Line feed
|
|
61
|
+
|
|
62
|
+
// Disconnect
|
|
63
|
+
await printer.disconnect();
|
|
64
|
+
await printer.dispose();
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### USB Printer (Android only)
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { EscPosPrinter, UsbPrinter } from '@fedejm/capacitor-esc-pos-printer';
|
|
71
|
+
|
|
72
|
+
// Get connected USB printers
|
|
73
|
+
const { devices } = await EscPosPrinter.getUsbPrinterDevices();
|
|
74
|
+
console.log('Found USB printers:', devices);
|
|
75
|
+
|
|
76
|
+
// Find a device and check permission status
|
|
77
|
+
const device = devices[0];
|
|
78
|
+
if (!device.hasPermission) {
|
|
79
|
+
// Request USB permission
|
|
80
|
+
const { value: granted } = await EscPosPrinter.requestUsbPermission({
|
|
81
|
+
address: device.id
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
if (!granted) {
|
|
85
|
+
console.log('USB permission denied for:', device.name);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Create and connect to a USB printer
|
|
91
|
+
const printer = new UsbPrinter(device.id);
|
|
92
|
+
await printer.link();
|
|
93
|
+
await printer.connect();
|
|
94
|
+
|
|
95
|
+
// Send ESC/POS commands (same as Bluetooth)
|
|
96
|
+
await printer.send([0x1B, 0x40]); // Initialize printer
|
|
97
|
+
await printer.send([0x48, 0x65, 0x6C, 0x6C, 0x6F]); // "Hello"
|
|
98
|
+
await printer.send([0x0A]); // Line feed
|
|
99
|
+
|
|
100
|
+
// Disconnect
|
|
101
|
+
await printer.disconnect();
|
|
102
|
+
await printer.dispose();
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Connection Lifecycle
|
|
106
|
+
|
|
107
|
+
The printer connection follows this lifecycle:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
┌─────────┐ link() ┌────────┐ connect() ┌───────────┐
|
|
111
|
+
│ Created ├───────────────►│ Linked ├─────────────────►│ Connected │
|
|
112
|
+
└─────────┘ └────────┘ └───────────┘
|
|
113
|
+
│
|
|
114
|
+
disconnect()
|
|
115
|
+
│
|
|
116
|
+
▼
|
|
117
|
+
┌─────────┐ dispose() ┌────────────┐
|
|
118
|
+
│Disposed │◄──────────────┤Disconnected│
|
|
119
|
+
└─────────┘ └────────────┘
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
1. **Create** - Instantiate `BluetoothPrinter` or `UsbPrinter` with device address
|
|
123
|
+
2. **Link** - Register with native plugin (`link()`)
|
|
124
|
+
3. **Connect** - Open connection to physical device (`connect()`)
|
|
125
|
+
4. **Send/Read** - Perform I/O operations (`send()`, `read()`)
|
|
126
|
+
5. **Disconnect** - Close connection (`disconnect()`)
|
|
127
|
+
6. **Dispose** - Unregister from plugin (`dispose()`)
|
|
128
|
+
|
|
12
129
|
## API
|
|
13
130
|
|
|
14
131
|
<docgen-index>
|
|
15
132
|
|
|
16
133
|
* [`requestBluetoothEnable()`](#requestbluetoothenable)
|
|
17
134
|
* [`getBluetoothPrinterDevices()`](#getbluetoothprinterdevices)
|
|
135
|
+
* [`getUsbPrinterDevices()`](#getusbprinterdevices)
|
|
136
|
+
* [`requestUsbPermission(...)`](#requestusbpermission)
|
|
18
137
|
* [`createPrinter(...)`](#createprinter)
|
|
19
138
|
* [`disposePrinter(...)`](#disposeprinter)
|
|
20
139
|
* [`isPrinterConnected(...)`](#isprinterconnected)
|
|
@@ -52,6 +171,38 @@ getBluetoothPrinterDevices() => Promise<BluetoothDevicesResult>
|
|
|
52
171
|
--------------------
|
|
53
172
|
|
|
54
173
|
|
|
174
|
+
### getUsbPrinterDevices()
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
getUsbPrinterDevices() => Promise<UsbDevicesResult>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Discovers USB devices that could be ESC/POS printers.
|
|
181
|
+
Returns devices with bulk OUT endpoints that may be suitable for printing.
|
|
182
|
+
|
|
183
|
+
**Returns:** <code>Promise<<a href="#usbdevicesresult">UsbDevicesResult</a>></code>
|
|
184
|
+
|
|
185
|
+
--------------------
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
### requestUsbPermission(...)
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
requestUsbPermission(options: WithAddress) => Promise<ValueResult<boolean>>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Requests USB permission for a specific device.
|
|
195
|
+
Note: May require user interaction via system UI.
|
|
196
|
+
|
|
197
|
+
| Param | Type |
|
|
198
|
+
| ------------- | --------------------------------------------------- |
|
|
199
|
+
| **`options`** | <code><a href="#withaddress">WithAddress</a></code> |
|
|
200
|
+
|
|
201
|
+
**Returns:** <code>Promise<<a href="#valueresult">ValueResult</a><boolean>></code>
|
|
202
|
+
|
|
203
|
+
--------------------
|
|
204
|
+
|
|
205
|
+
|
|
55
206
|
### createPrinter(...)
|
|
56
207
|
|
|
57
208
|
```typescript
|
|
@@ -168,12 +319,46 @@ readFromPrinter(options: WithHashKey) => Promise<ValueResult<number[]>>
|
|
|
168
319
|
| **`devices`** | <code>{ address: string; alias?: string; name: string; bondState: number; type: number; uuids: string[]; }[]</code> |
|
|
169
320
|
|
|
170
321
|
|
|
322
|
+
#### UsbDevicesResult
|
|
323
|
+
|
|
324
|
+
Result from USB device discovery.
|
|
325
|
+
Contains list of USB devices that could be ESC/POS printers.
|
|
326
|
+
|
|
327
|
+
| Prop | Type |
|
|
328
|
+
| ------------- | ---------------------------- |
|
|
329
|
+
| **`devices`** | <code>UsbDeviceInfo[]</code> |
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
#### UsbDeviceInfo
|
|
333
|
+
|
|
334
|
+
Information about a discovered USB device.
|
|
335
|
+
|
|
336
|
+
| Prop | Type | Description |
|
|
337
|
+
| ---------------------- | -------------------- | -------------------------------------------------------------------------- |
|
|
338
|
+
| **`id`** | <code>string</code> | Stable identifier for the device (format: "vendorId:productId:deviceName") |
|
|
339
|
+
| **`name`** | <code>string</code> | Human-readable name (product name or fallback) |
|
|
340
|
+
| **`vendorId`** | <code>number</code> | USB Vendor ID |
|
|
341
|
+
| **`productId`** | <code>number</code> | USB Product ID |
|
|
342
|
+
| **`deviceClass`** | <code>number</code> | USB Device Class |
|
|
343
|
+
| **`deviceSubclass`** | <code>number</code> | USB Device Subclass |
|
|
344
|
+
| **`deviceName`** | <code>string</code> | System device name/path |
|
|
345
|
+
| **`manufacturerName`** | <code>string</code> | Manufacturer name if available |
|
|
346
|
+
| **`hasPermission`** | <code>boolean</code> | Whether the app has USB permission for this device |
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
#### WithAddress
|
|
350
|
+
|
|
351
|
+
| Prop | Type |
|
|
352
|
+
| ------------- | ------------------- |
|
|
353
|
+
| **`address`** | <code>string</code> |
|
|
354
|
+
|
|
355
|
+
|
|
171
356
|
#### CreatePrinterOptions
|
|
172
357
|
|
|
173
|
-
| Prop | Type |
|
|
174
|
-
| -------------------- | ----------------------------------------------------------------------- |
|
|
175
|
-
| **`connectionType`** | <code><a href="#printerconnectiontype">PrinterConnectionType</a></code> |
|
|
176
|
-
| **`address`** | <code>string</code> |
|
|
358
|
+
| Prop | Type | Description |
|
|
359
|
+
| -------------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
360
|
+
| **`connectionType`** | <code><a href="#printerconnectiontype">PrinterConnectionType</a></code> | |
|
|
361
|
+
| **`address`** | <code>string</code> | Address/identifier for the printer: - Bluetooth: MAC address (e.g., "00:11:22:33:44:55") - USB: Device identifier (e.g., "1234:5678:002") - Network: IP address and optional port (e.g., "192.168.1.100:9100") |
|
|
177
362
|
|
|
178
363
|
|
|
179
364
|
#### WithHashKey
|
|
@@ -199,5 +384,170 @@ readFromPrinter(options: WithHashKey) => Promise<ValueResult<number[]>>
|
|
|
199
384
|
| Members | Value |
|
|
200
385
|
| --------------- | ------------------------ |
|
|
201
386
|
| **`Bluetooth`** | <code>'bluetooth'</code> |
|
|
387
|
+
| **`Usb`** | <code>'usb'</code> |
|
|
388
|
+
| **`Network`** | <code>'network'</code> |
|
|
202
389
|
|
|
203
390
|
</docgen-api>
|
|
391
|
+
|
|
392
|
+
## Error Handling
|
|
393
|
+
|
|
394
|
+
All printer operations may throw a `PrinterError` with a specific error code:
|
|
395
|
+
|
|
396
|
+
```typescript
|
|
397
|
+
import { PrinterError, PrinterErrorCode } from '@fedejm/capacitor-esc-pos-printer';
|
|
398
|
+
|
|
399
|
+
try {
|
|
400
|
+
await printer.connect();
|
|
401
|
+
} catch (error) {
|
|
402
|
+
if (error instanceof PrinterError) {
|
|
403
|
+
switch (error.code) {
|
|
404
|
+
case PrinterErrorCode.Connect:
|
|
405
|
+
console.log('Connection failed');
|
|
406
|
+
break;
|
|
407
|
+
case PrinterErrorCode.NotConnected:
|
|
408
|
+
console.log('Printer not connected');
|
|
409
|
+
break;
|
|
410
|
+
case PrinterErrorCode.Send:
|
|
411
|
+
console.log('Failed to send data');
|
|
412
|
+
break;
|
|
413
|
+
case PrinterErrorCode.Read:
|
|
414
|
+
console.log('Failed to read data');
|
|
415
|
+
break;
|
|
416
|
+
case PrinterErrorCode.Permissions:
|
|
417
|
+
console.log('Permission denied');
|
|
418
|
+
break;
|
|
419
|
+
case PrinterErrorCode.DeviceNotFound:
|
|
420
|
+
console.log('Device not found');
|
|
421
|
+
break;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
### Error Code Reference
|
|
428
|
+
|
|
429
|
+
| Code | Name | Value | Description |
|
|
430
|
+
|------|----------------|-------|---------------------------------------------------------------|
|
|
431
|
+
| 1 | Connect | 1 | Failed to establish connection to the printer |
|
|
432
|
+
| 2 | NotConnected | 2 | Attempted operation on disconnected printer |
|
|
433
|
+
| 3 | Send | 3 | Failed to send data to the printer |
|
|
434
|
+
| 4 | Read | 4 | Failed to read data from the printer |
|
|
435
|
+
| 5 | Permissions | 5 | Required permission not granted (Bluetooth or USB) |
|
|
436
|
+
| 6 | DeviceNotFound | 6 | Device not found or no longer available |
|
|
437
|
+
|
|
438
|
+
## USB Permissions (Android)
|
|
439
|
+
|
|
440
|
+
USB devices require explicit permission from the user. The plugin provides a complete permission flow:
|
|
441
|
+
|
|
442
|
+
### Checking Permission
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
const { devices } = await EscPosPrinter.getUsbPrinterDevices();
|
|
446
|
+
const device = devices.find(d => d.vendorId === 0x0483); // Find by vendor ID
|
|
447
|
+
|
|
448
|
+
if (device && !device.hasPermission) {
|
|
449
|
+
console.log('Permission required for:', device.name);
|
|
450
|
+
}
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### Requesting Permission
|
|
454
|
+
|
|
455
|
+
```typescript
|
|
456
|
+
// Request permission - triggers system dialog
|
|
457
|
+
const { value: granted } = await EscPosPrinter.requestUsbPermission({
|
|
458
|
+
address: device.id
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
if (granted) {
|
|
462
|
+
console.log('Permission granted!');
|
|
463
|
+
// Refresh device list to update permission status
|
|
464
|
+
const { devices: updated } = await EscPosPrinter.getUsbPrinterDevices();
|
|
465
|
+
} else {
|
|
466
|
+
console.log('Permission denied by user');
|
|
467
|
+
}
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
### Permission Flow Diagram
|
|
471
|
+
|
|
472
|
+
```
|
|
473
|
+
┌─────────────────────┐
|
|
474
|
+
│ getUsbPrinterDevices│
|
|
475
|
+
└──────────┬──────────┘
|
|
476
|
+
│
|
|
477
|
+
▼
|
|
478
|
+
┌──────────────┐
|
|
479
|
+
│hasPermission?│
|
|
480
|
+
└──────┬───────┘
|
|
481
|
+
│
|
|
482
|
+
┌─────┴─────┐
|
|
483
|
+
│ │
|
|
484
|
+
Yes No
|
|
485
|
+
│ │
|
|
486
|
+
▼ ▼
|
|
487
|
+
┌─────────┐ ┌────────────────────┐
|
|
488
|
+
│ Connect │ │requestUsbPermission│
|
|
489
|
+
└─────────┘ └─────────┬──────────┘
|
|
490
|
+
│
|
|
491
|
+
▼
|
|
492
|
+
┌──────────────────┐
|
|
493
|
+
│System Permission │
|
|
494
|
+
│ Dialog │
|
|
495
|
+
└────────┬─────────┘
|
|
496
|
+
│
|
|
497
|
+
┌─────┴─────┐
|
|
498
|
+
│ │
|
|
499
|
+
Granted Denied
|
|
500
|
+
│ │
|
|
501
|
+
▼ ▼
|
|
502
|
+
┌─────────┐ ┌───────┐
|
|
503
|
+
│ Connect │ │ Error │
|
|
504
|
+
└─────────┘ └───────┘
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### Notes on USB Permission
|
|
508
|
+
|
|
509
|
+
- Permission is granted per-device and persists until the app is uninstalled
|
|
510
|
+
- If the device is unplugged and replugged, permission may need to be re-requested
|
|
511
|
+
- The permission dialog is a system UI and cannot be customized
|
|
512
|
+
- Permission requests are idempotent - multiple calls for already-permitted devices return immediately
|
|
513
|
+
|
|
514
|
+
## Reading from Printer
|
|
515
|
+
|
|
516
|
+
Some printers support bi-directional communication. The `read()` method is best-effort:
|
|
517
|
+
|
|
518
|
+
```typescript
|
|
519
|
+
// Send status request command
|
|
520
|
+
await printer.send([0x10, 0x04, 0x01]); // DLE EOT 1 (transmit status)
|
|
521
|
+
|
|
522
|
+
// Read response
|
|
523
|
+
const response = await printer.read();
|
|
524
|
+
if (response.length > 0) {
|
|
525
|
+
console.log('Printer status:', response);
|
|
526
|
+
} else {
|
|
527
|
+
console.log('No response (printer may not support reading)');
|
|
528
|
+
}
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
**Note**: Many USB ESC/POS printers do not implement a read endpoint. The `read()` method will return an empty array in such cases without throwing an error.
|
|
532
|
+
|
|
533
|
+
## Future: Network Printing
|
|
534
|
+
|
|
535
|
+
Network/TCP printing is planned for a future release. The API design is already prepared:
|
|
536
|
+
|
|
537
|
+
```typescript
|
|
538
|
+
// Future API (not yet implemented)
|
|
539
|
+
const printer = new NetworkPrinter('192.168.1.100:9100');
|
|
540
|
+
await printer.link();
|
|
541
|
+
await printer.connect();
|
|
542
|
+
// ... same send/read API
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
The `PrinterConnectionType.Network` enum value is already defined for forward compatibility.
|
|
546
|
+
|
|
547
|
+
## Contributing
|
|
548
|
+
|
|
549
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and contribution guidelines.
|
|
550
|
+
|
|
551
|
+
## License
|
|
552
|
+
|
|
553
|
+
MIT
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
2
|
xmlns:tools="http://schemas.android.com/tools">
|
|
3
|
+
<!-- Bluetooth permissions -->
|
|
3
4
|
<uses-permission android:name="android.permission.BLUETOOTH"
|
|
4
5
|
android:maxSdkVersion="30" />
|
|
5
6
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
|
|
@@ -14,8 +15,13 @@
|
|
|
14
15
|
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"
|
|
15
16
|
tools:targetApi="s" />
|
|
16
17
|
|
|
18
|
+
<!-- Bluetooth features (not required) -->
|
|
17
19
|
<uses-feature android:name="android.hardware.bluetooth"
|
|
18
20
|
android:required="false" />
|
|
19
21
|
<uses-feature android:name="android.hardware.bluetooth_le"
|
|
20
22
|
android:required="false" />
|
|
23
|
+
|
|
24
|
+
<!-- USB Host feature (not required - allows app to work on devices without USB host) -->
|
|
25
|
+
<uses-feature android:name="android.hardware.usb.host"
|
|
26
|
+
android:required="false" />
|
|
21
27
|
</manifest>
|