node-thermal-printer-js 1.2.1 → 1.2.3
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 +174 -168
- package/package.json +1 -6
- package/scripts/install-deps.js +0 -177
package/README.md
CHANGED
|
@@ -2,78 +2,68 @@
|
|
|
2
2
|
|
|
3
3
|
Public npm package for sending ESC/POS print jobs to a PSF588 printer over BLE or classic Bluetooth COM port.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
|
|
10
|
-
- **pip**: Python package manager (usually included with Python)
|
|
7
|
+
```bash
|
|
8
|
+
npm install node-thermal-printer-js
|
|
9
|
+
```
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
- **bleak**: BLE client library for Python
|
|
14
|
-
- Auto-installed during `npm install` (see postinstall)
|
|
15
|
-
- Or manually: `pip install bleak`
|
|
11
|
+
That's it! No validation, no postinstall hooks. Just a clean package.
|
|
16
12
|
|
|
17
|
-
|
|
13
|
+
---
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
- Python 3.9+ with pip
|
|
21
|
-
- Bluetooth drivers (usually included with Windows 10+)
|
|
22
|
-
- No special permissions needed
|
|
15
|
+
## Runtime Requirements
|
|
23
16
|
|
|
24
|
-
|
|
25
|
-
- Python 3.9+ with pip
|
|
26
|
-
- Ensure Bluetooth is enabled in System Preferences
|
|
27
|
-
- May require granting Terminal/Node.js permission to use Bluetooth
|
|
17
|
+
To use this package, your environment needs:
|
|
28
18
|
|
|
29
|
-
|
|
30
|
-
- Python 3.9
|
|
31
|
-
- **
|
|
32
|
-
```bash
|
|
33
|
-
sudo usermod -a -G dialout,plugdev $USER
|
|
34
|
-
```
|
|
35
|
-
Then log out and back in for changes to take effect.
|
|
36
|
-
Without this, BLE operations will fail with permission errors.
|
|
19
|
+
- **Node.js**: 16.0.0 or higher
|
|
20
|
+
- **Python**: 3.9 or higher
|
|
21
|
+
- **Python package**: `bleak` (BLE client library)
|
|
37
22
|
|
|
38
|
-
|
|
23
|
+
### For End Users (.exe Applications)
|
|
24
|
+
|
|
25
|
+
If you're distributing this as an `.exe`, include the `setup-runtime.bat` script:
|
|
39
26
|
|
|
40
|
-
### 1. Install Package
|
|
41
27
|
```bash
|
|
42
|
-
|
|
28
|
+
setup-runtime.bat
|
|
43
29
|
```
|
|
44
30
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
31
|
+
This script automatically:
|
|
32
|
+
1. ✅ Checks and installs Node.js (if missing)
|
|
33
|
+
2. ✅ Checks and installs Python 3.11 (if missing)
|
|
34
|
+
3. ✅ Installs the `bleak` library
|
|
35
|
+
4. ✅ Shows timing for each step
|
|
49
36
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
37
|
+
**Usage:**
|
|
38
|
+
- Unzip your application
|
|
39
|
+
- Double-click `setup-runtime.bat`
|
|
40
|
+
- Wait for completion
|
|
41
|
+
- Run your `.exe`
|
|
54
42
|
|
|
55
|
-
|
|
56
|
-
PRINTER_BLE_NAME=PSF588
|
|
57
|
-
PRINTER_BLE_ADDRESS=C8:47:8C:1F:72:34
|
|
58
|
-
PRINTER_BLE_CHAR_UUID=49535343-8841-43f4-a8d4-ecbe34729bb3
|
|
43
|
+
---
|
|
59
44
|
|
|
60
|
-
|
|
61
|
-
PRINTER_BLE_SERVER_HOST=127.0.0.1
|
|
62
|
-
PRINTER_BLE_SERVER_PORT=5555
|
|
63
|
-
PRINTER_BLE_REQUEST_TIMEOUT_MS=40000
|
|
45
|
+
## Quick Start (Development)
|
|
64
46
|
|
|
65
|
-
|
|
66
|
-
PRINTER_COM_PORT=COM3
|
|
47
|
+
### 1. Install Package
|
|
67
48
|
|
|
68
|
-
|
|
69
|
-
|
|
49
|
+
```bash
|
|
50
|
+
npm install node-thermal-printer-js
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 2. Ensure Python & Bleak are Available
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
python -m pip install bleak
|
|
57
|
+
# or
|
|
58
|
+
python3 -m pip install bleak
|
|
70
59
|
```
|
|
71
60
|
|
|
72
|
-
### 3. Use in Code
|
|
61
|
+
### 3. Use in Your Code
|
|
62
|
+
|
|
73
63
|
```js
|
|
74
64
|
import { printData, startPrinterServer, stopPrinterServer } from "node-thermal-printer-js";
|
|
75
65
|
|
|
76
|
-
// Option 1: Fast persistent server (recommended)
|
|
66
|
+
// Option 1: Fast persistent server (recommended for multiple prints)
|
|
77
67
|
await startPrinterServer({ bleName: "PSF588" });
|
|
78
68
|
await printData("Hello World");
|
|
79
69
|
await printData("Second print (faster)");
|
|
@@ -87,31 +77,61 @@ await printData("Hello World", {
|
|
|
87
77
|
connectTimeout: 15
|
|
88
78
|
});
|
|
89
79
|
|
|
90
|
-
// Option 3: COM port
|
|
80
|
+
// Option 3: Windows COM port
|
|
91
81
|
await printData("Hello World", {
|
|
92
82
|
transport: "com",
|
|
93
83
|
portPath: "COM3"
|
|
94
84
|
});
|
|
95
85
|
```
|
|
96
86
|
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Configuration (.env)
|
|
90
|
+
|
|
91
|
+
Create a `.env` file to customize behavior:
|
|
92
|
+
|
|
93
|
+
```env
|
|
94
|
+
# Transport: "ble-server" (recommended), "ble", or "com"
|
|
95
|
+
PRINTER_TRANSPORT=ble-server
|
|
96
|
+
|
|
97
|
+
# BLE Configuration
|
|
98
|
+
PRINTER_BLE_NAME=PSF588
|
|
99
|
+
PRINTER_BLE_ADDRESS=C8:47:8C:1F:72:34
|
|
100
|
+
PRINTER_BLE_CHAR_UUID=49535343-8841-43f4-a8d4-ecbe34729bb3
|
|
101
|
+
|
|
102
|
+
# Server Configuration
|
|
103
|
+
PRINTER_BLE_SERVER_HOST=127.0.0.1
|
|
104
|
+
PRINTER_BLE_SERVER_PORT=5555
|
|
105
|
+
PRINTER_BLE_REQUEST_TIMEOUT_MS=40000
|
|
106
|
+
|
|
107
|
+
# COM Port (for Windows COM transport)
|
|
108
|
+
PRINTER_COM_PORT=COM3
|
|
109
|
+
|
|
110
|
+
# Python Command (if auto-detection fails)
|
|
111
|
+
PRINTER_PYTHON_CMD=python3
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
97
116
|
## API Reference
|
|
98
117
|
|
|
99
118
|
### `printData(data, options?)`
|
|
119
|
+
|
|
100
120
|
Print ESC/POS data to thermal printer.
|
|
101
121
|
|
|
102
122
|
**Parameters:**
|
|
103
123
|
- `data` (string): ESC/POS data to print
|
|
104
124
|
- `options` (object, optional):
|
|
105
|
-
- `transport` (string): "ble-server"
|
|
106
|
-
- `bleName` (string): Printer
|
|
107
|
-
- `bleAddress` (string): MAC address (e.g., "C8:47:8C:1F:72:34")
|
|
108
|
-
- `charUUID` (string): BLE characteristic UUID
|
|
109
|
-
- `portPath` (string): COM port path (e.g., "COM3")
|
|
125
|
+
- `transport` (string): `"ble-server"`, `"ble"`, or `"com"` — default: `"ble-server"`
|
|
126
|
+
- `bleName` (string): Printer BLE device name
|
|
127
|
+
- `bleAddress` (string): BLE MAC address (e.g., `"C8:47:8C:1F:72:34"`)
|
|
128
|
+
- `charUUID` (string): BLE characteristic UUID
|
|
129
|
+
- `portPath` (string): COM port path for Windows (e.g., `"COM3"`)
|
|
110
130
|
- `scanTimeout` (number): BLE scan timeout in seconds (default: 10)
|
|
111
131
|
- `connectTimeout` (number): BLE connection timeout in seconds (default: 15)
|
|
112
|
-
- `requestTimeoutMs` (number): Server request timeout in
|
|
132
|
+
- `requestTimeoutMs` (number): Server request timeout in milliseconds (default: 40000)
|
|
113
133
|
|
|
114
|
-
**Returns:** Promise<{ok: boolean, bytes_sent: number}
|
|
134
|
+
**Returns:** `Promise<{ok: boolean, bytes_sent: number}>`
|
|
115
135
|
|
|
116
136
|
**Example:**
|
|
117
137
|
```js
|
|
@@ -126,12 +146,15 @@ try {
|
|
|
126
146
|
}
|
|
127
147
|
```
|
|
128
148
|
|
|
149
|
+
---
|
|
150
|
+
|
|
129
151
|
### `startPrinterServer(options?)`
|
|
130
|
-
|
|
152
|
+
|
|
153
|
+
Start persistent BLE server for faster multi-print performance.
|
|
131
154
|
|
|
132
155
|
**Parameters:** Same as `printData` options
|
|
133
156
|
|
|
134
|
-
**Returns:** Promise<void
|
|
157
|
+
**Returns:** `Promise<void>`
|
|
135
158
|
|
|
136
159
|
**Example:**
|
|
137
160
|
```js
|
|
@@ -142,13 +165,19 @@ await startPrinterServer({
|
|
|
142
165
|
console.log("Server ready for fast printing");
|
|
143
166
|
```
|
|
144
167
|
|
|
168
|
+
---
|
|
169
|
+
|
|
145
170
|
### `stopPrinterServer()`
|
|
171
|
+
|
|
146
172
|
Stop the running BLE server and clean up resources.
|
|
147
173
|
|
|
148
|
-
**Returns:** Promise<void
|
|
174
|
+
**Returns:** `Promise<void>`
|
|
175
|
+
|
|
176
|
+
---
|
|
149
177
|
|
|
150
178
|
### `getPrinterServerStatus()`
|
|
151
|
-
|
|
179
|
+
|
|
180
|
+
Get status of the running BLE server.
|
|
152
181
|
|
|
153
182
|
**Returns:**
|
|
154
183
|
```js
|
|
@@ -160,164 +189,141 @@ Get status of running BLE server.
|
|
|
160
189
|
}
|
|
161
190
|
```
|
|
162
191
|
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Transport Modes
|
|
195
|
+
|
|
196
|
+
| Mode | Speed | Best For |
|
|
197
|
+
|------|-------|----------|
|
|
198
|
+
| `ble-server` | 100-200ms | Multiple prints, APIs, production |
|
|
199
|
+
| `ble` | 1-2s | Single prints, testing, fallback |
|
|
200
|
+
| `com` | Variable | Windows paired COM port, fallback |
|
|
201
|
+
|
|
202
|
+
**Recommendation:** Use `ble-server` (default) for best performance.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
163
206
|
## Troubleshooting
|
|
164
207
|
|
|
165
|
-
###
|
|
166
|
-
**Solution:**
|
|
167
|
-
1. Install Python from https://www.python.org/downloads/
|
|
168
|
-
2. Ensure Python is in system PATH:
|
|
169
|
-
- Windows: Check "Add Python to PATH" during installation
|
|
170
|
-
- Mac/Linux: Verify `python3` works in terminal
|
|
171
|
-
3. Set environment variable:
|
|
172
|
-
```bash
|
|
173
|
-
export PRINTER_PYTHON_CMD=python3 # or python, py.exe, etc.
|
|
174
|
-
```
|
|
175
|
-
4. Run: `npm install` again
|
|
208
|
+
### Python or Bleak Not Found
|
|
176
209
|
|
|
177
|
-
|
|
178
|
-
**Solution:**
|
|
210
|
+
**For Developers:**
|
|
179
211
|
```bash
|
|
212
|
+
# Install Python from: https://www.python.org/downloads/ (3.9+)
|
|
213
|
+
# Then install bleak:
|
|
180
214
|
pip install bleak
|
|
181
|
-
# or with Python 3 explicitly:
|
|
182
|
-
python3 -m pip install bleak
|
|
183
215
|
```
|
|
184
216
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
This happens if a previous BLE server crashed. The package auto-detects and cleans up stale processes, but manual cleanup:
|
|
188
|
-
```bash
|
|
189
|
-
# Windows
|
|
190
|
-
netstat -ano | findstr :5555
|
|
191
|
-
taskkill /PID <PID> /F
|
|
217
|
+
**For End Users (.exe):**
|
|
218
|
+
- Run `setup-runtime.bat` to auto-install everything
|
|
192
219
|
|
|
193
|
-
|
|
194
|
-
lsof -ti:5555 | xargs kill -9
|
|
195
|
-
```
|
|
220
|
+
### "Device not found" or Connection Timeouts
|
|
196
221
|
|
|
197
|
-
### "Device not found" or connection timeouts
|
|
198
|
-
**Solutions:**
|
|
199
222
|
1. Ensure printer is powered on and in BLE discoverable mode
|
|
200
223
|
2. Increase timeouts:
|
|
201
224
|
```js
|
|
202
225
|
await printData(data, { scanTimeout: 20, connectTimeout: 25 });
|
|
203
226
|
```
|
|
204
|
-
3. Try specifying MAC address (faster than
|
|
227
|
+
3. Try specifying MAC address (faster than discovery):
|
|
205
228
|
```js
|
|
206
229
|
await printData(data, { bleAddress: "C8:47:8C:1F:72:34" });
|
|
207
230
|
```
|
|
208
|
-
4. On Linux, verify group permissions: `id $USER` should show `dialout` and `plugdev` groups
|
|
209
231
|
|
|
210
|
-
### "
|
|
211
|
-
|
|
232
|
+
### "Address already in use" (Port 5555)
|
|
233
|
+
|
|
234
|
+
This happens if a previous BLE server crashed. Restart your terminal or kill the process:
|
|
235
|
+
|
|
236
|
+
**Windows:**
|
|
212
237
|
```bash
|
|
213
|
-
|
|
214
|
-
|
|
238
|
+
netstat -ano | findstr :5555
|
|
239
|
+
taskkill /PID <PID> /F
|
|
240
|
+
```
|
|
215
241
|
|
|
216
|
-
|
|
217
|
-
|
|
242
|
+
**Mac/Linux:**
|
|
243
|
+
```bash
|
|
244
|
+
lsof -ti:5555 | xargs kill -9
|
|
218
245
|
```
|
|
219
246
|
|
|
220
|
-
### Print
|
|
221
|
-
|
|
247
|
+
### Print Job Times Out
|
|
248
|
+
|
|
222
249
|
1. Increase timeout:
|
|
223
250
|
```js
|
|
224
251
|
await printData(data, { requestTimeoutMs: 60000 });
|
|
225
252
|
```
|
|
226
|
-
2. Check printer is still connected
|
|
227
|
-
3. Try
|
|
253
|
+
2. Check printer is still connected
|
|
254
|
+
3. Try fallback transport:
|
|
228
255
|
```js
|
|
229
|
-
await printData(data, { transport: "ble" });
|
|
256
|
+
await printData(data, { transport: "ble" });
|
|
230
257
|
```
|
|
231
258
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
### Transport Modes Comparison
|
|
235
|
-
|
|
236
|
-
| Mode | Speed | Resource Use | Recommended For |
|
|
237
|
-
|------|-------|--------------|-----------------|
|
|
238
|
-
| `ble-server` | **100-200ms** ✓ | Low (persistent) | Multiple prints, APIs |
|
|
239
|
-
| `ble` | 1-2s | Medium (spawn/connect each time) | Single prints, testing |
|
|
240
|
-
| `com` | Variable | Low | Windows paired COM port |
|
|
241
|
-
|
|
242
|
-
### Why `ble-server` is Fast
|
|
243
|
-
- Reuses single BLE connection for multiple prints
|
|
244
|
-
- Eliminates per-print connection overhead (1s)
|
|
245
|
-
- Persistent Python daemon handles I/O
|
|
246
|
-
|
|
247
|
-
## Development
|
|
248
|
-
|
|
249
|
-
### Local Development
|
|
250
|
-
```bash
|
|
251
|
-
# Clone and setup
|
|
252
|
-
git clone <repo>
|
|
253
|
-
cd Printer
|
|
254
|
-
npm install
|
|
255
|
-
|
|
256
|
-
# Run tests
|
|
257
|
-
npm test
|
|
258
|
-
|
|
259
|
-
# Watch mode
|
|
260
|
-
npm run dev
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
### Requirements for development
|
|
264
|
-
```bash
|
|
265
|
-
# Install Python dev dependencies
|
|
266
|
-
pip install -r requirements.txt
|
|
267
|
-
```
|
|
259
|
+
---
|
|
268
260
|
|
|
269
261
|
## Architecture
|
|
270
262
|
|
|
271
263
|
### Components
|
|
272
|
-
1. **app.js** (Node.js): Express-compatible export module, socket IPC client
|
|
273
|
-
2. **ble_server.py** (Python): Long-running BLE daemon, accepts print requests over TCP
|
|
274
|
-
3. **ble_print.py** (Python): Fallback legacy BLE bridge (process per print)
|
|
275
|
-
4. **scripts/install-deps.js** (Node.js): Postinstall hook for dependency verification
|
|
276
264
|
|
|
277
|
-
|
|
265
|
+
1. **app.js** — Main Node.js module with BLE client logic
|
|
266
|
+
2. **ble_server.py** — Persistent Python BLE daemon (optional, for ble-server mode)
|
|
267
|
+
3. **ble_print.py** — Legacy BLE bridge (one process per print)
|
|
268
|
+
4. **ble_scan.py** — Device discovery utility
|
|
269
|
+
|
|
270
|
+
### Data Flow (ble-server mode - Recommended)
|
|
271
|
+
|
|
278
272
|
```
|
|
279
|
-
printData(data)
|
|
273
|
+
printData(data, options)
|
|
274
|
+
↓
|
|
275
|
+
startBleServer() [if not running]
|
|
280
276
|
↓
|
|
281
|
-
|
|
277
|
+
Node.js spawns ble_server.py (persistent)
|
|
282
278
|
↓
|
|
283
|
-
|
|
279
|
+
Send TCP request to server with ESC/POS data
|
|
284
280
|
↓
|
|
285
|
-
ble_server.py connects to PSF588
|
|
281
|
+
ble_server.py connects to PSF588 via BLE
|
|
286
282
|
↓
|
|
287
|
-
Writes
|
|
283
|
+
Writes data via BLE characteristic
|
|
288
284
|
↓
|
|
289
|
-
Response
|
|
285
|
+
Response returned to Node.js
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Data Flow (ble mode - Fallback)
|
|
290
289
|
|
|
291
|
-
|
|
290
|
+
```
|
|
291
|
+
printData(data, options)
|
|
292
|
+
↓
|
|
293
|
+
Spawn ble_print.py process
|
|
292
294
|
↓
|
|
293
|
-
|
|
295
|
+
Connect to printer, send data, exit
|
|
294
296
|
↓
|
|
295
|
-
|
|
297
|
+
Response returned to Node.js
|
|
296
298
|
```
|
|
297
299
|
|
|
298
|
-
|
|
300
|
+
---
|
|
299
301
|
|
|
300
|
-
|
|
302
|
+
## Development
|
|
303
|
+
|
|
304
|
+
### Local Setup
|
|
301
305
|
|
|
306
|
+
```bash
|
|
307
|
+
git clone <repo>
|
|
308
|
+
cd Printer
|
|
309
|
+
npm install
|
|
302
310
|
|
|
303
|
-
|
|
311
|
+
# Install Python dependencies
|
|
312
|
+
pip install bleak
|
|
304
313
|
|
|
305
|
-
|
|
314
|
+
# Run tests
|
|
315
|
+
npm test
|
|
306
316
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
.\.venv\Scripts\activate
|
|
310
|
-
pip install -r requirements.txt
|
|
311
|
-
# or: pip install bleak
|
|
317
|
+
# Watch mode
|
|
318
|
+
npm run dev
|
|
312
319
|
```
|
|
313
320
|
|
|
314
|
-
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## License
|
|
324
|
+
|
|
325
|
+
ISC
|
|
315
326
|
|
|
316
|
-
```bash
|
|
317
|
-
python3 -m venv .venv
|
|
318
|
-
source .venv/bin/activate
|
|
319
|
-
pip install -r requirements.txt
|
|
320
|
-
# or: pip install bleak
|
|
321
327
|
```
|
|
322
328
|
|
|
323
329
|
Verify the Python BLE dependency is available:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-thermal-printer-js",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"description": "ESC/POS printer helper for PSF588 Bluetooth and COM printing.",
|
|
5
5
|
"main": "app.js",
|
|
6
6
|
"exports": {
|
|
@@ -11,18 +11,13 @@
|
|
|
11
11
|
"ble_print.py",
|
|
12
12
|
"ble_scan.py",
|
|
13
13
|
"ble_server.py",
|
|
14
|
-
"scripts/install-deps.js",
|
|
15
14
|
"README.md"
|
|
16
15
|
],
|
|
17
16
|
"scripts": {
|
|
18
|
-
"postinstall": "node scripts/install-deps.js",
|
|
19
17
|
"test": "node test-api.js",
|
|
20
18
|
"dev": "node --watch app.js",
|
|
21
19
|
"pack:dry": "npm pack --dry-run"
|
|
22
20
|
},
|
|
23
|
-
"engines": {
|
|
24
|
-
"node": ">=16.0.0"
|
|
25
|
-
},
|
|
26
21
|
"keywords": [
|
|
27
22
|
"printer",
|
|
28
23
|
"escpos",
|
package/scripts/install-deps.js
DELETED
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Postinstall script to verify and auto-install Python dependencies
|
|
4
|
-
* Runs: npm install --> postinstall hook
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { spawnSync } from "node:child_process";
|
|
8
|
-
import { existsSync } from "node:fs";
|
|
9
|
-
import { fileURLToPath } from "node:url";
|
|
10
|
-
import path from "node:path";
|
|
11
|
-
|
|
12
|
-
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
13
|
-
|
|
14
|
-
const findPythonCmd = () => {
|
|
15
|
-
const localVenvCandidates =
|
|
16
|
-
process.platform === "win32"
|
|
17
|
-
? [
|
|
18
|
-
{
|
|
19
|
-
cmd: path.join(scriptDir, ".venv", "Scripts", "python.exe"),
|
|
20
|
-
args: [],
|
|
21
|
-
},
|
|
22
|
-
{ cmd: path.join(scriptDir, ".venv", "Scripts", "python"), args: [] },
|
|
23
|
-
]
|
|
24
|
-
: [
|
|
25
|
-
{ cmd: path.join(scriptDir, ".venv", "bin", "python"), args: [] },
|
|
26
|
-
{ cmd: path.join(scriptDir, ".venv", "bin", "python3"), args: [] },
|
|
27
|
-
];
|
|
28
|
-
|
|
29
|
-
const systemCandidates =
|
|
30
|
-
process.platform === "win32"
|
|
31
|
-
? [
|
|
32
|
-
{ cmd: "py", args: ["-3.11"] },
|
|
33
|
-
{ cmd: "py", args: ["-3"] },
|
|
34
|
-
{ cmd: "py", args: [] },
|
|
35
|
-
{ cmd: "python3", args: [] },
|
|
36
|
-
{ cmd: "python", args: [] },
|
|
37
|
-
]
|
|
38
|
-
: [
|
|
39
|
-
{ cmd: "python3", args: [] },
|
|
40
|
-
{ cmd: "python", args: [] },
|
|
41
|
-
{ cmd: "py", args: [] },
|
|
42
|
-
];
|
|
43
|
-
|
|
44
|
-
const candidates = [
|
|
45
|
-
...localVenvCandidates.filter((candidate) => existsSync(candidate.cmd)),
|
|
46
|
-
...systemCandidates,
|
|
47
|
-
];
|
|
48
|
-
|
|
49
|
-
for (const candidate of candidates) {
|
|
50
|
-
try {
|
|
51
|
-
const result = spawnSync(
|
|
52
|
-
candidate.cmd,
|
|
53
|
-
[...candidate.args, "--version"],
|
|
54
|
-
{
|
|
55
|
-
encoding: "utf8",
|
|
56
|
-
stdio: "pipe",
|
|
57
|
-
timeout: 2000,
|
|
58
|
-
shell: false,
|
|
59
|
-
},
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
// Skip if command failed or timed out
|
|
63
|
-
if (result.status !== 0 || result.error) {
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const version = `${result.stdout || ""}${result.stderr || ""}`.trim();
|
|
68
|
-
// Check if Python 3.9+
|
|
69
|
-
const match = version.match(/Python (\d+)\.(\d+)/);
|
|
70
|
-
if (match) {
|
|
71
|
-
const major = parseInt(match[1], 10);
|
|
72
|
-
const minor = parseInt(match[2], 10);
|
|
73
|
-
if (major > 3 || (major === 3 && minor >= 9)) {
|
|
74
|
-
console.log(
|
|
75
|
-
`✓ Found ${candidate.cmd} ${candidate.args.join(" ")} (${version})`,
|
|
76
|
-
);
|
|
77
|
-
return candidate;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
} catch {
|
|
81
|
-
// Continue to next candidate
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return null;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
const installBleak = (pythonCmd) => {
|
|
89
|
-
console.log(`\n📦 Installing bleak Python package...`);
|
|
90
|
-
try {
|
|
91
|
-
const result = spawnSync(
|
|
92
|
-
pythonCmd.cmd,
|
|
93
|
-
[...pythonCmd.args, "-m", "pip", "install", "bleak"],
|
|
94
|
-
{
|
|
95
|
-
encoding: "utf8",
|
|
96
|
-
stdio: "inherit",
|
|
97
|
-
timeout: 120000,
|
|
98
|
-
shell: false,
|
|
99
|
-
},
|
|
100
|
-
);
|
|
101
|
-
if (result.status !== 0) {
|
|
102
|
-
throw new Error(`pip exited with code ${result.status ?? "unknown"}`);
|
|
103
|
-
}
|
|
104
|
-
console.log("✓ bleak installed successfully");
|
|
105
|
-
return true;
|
|
106
|
-
} catch (err) {
|
|
107
|
-
console.warn("⚠ Could not auto-install bleak");
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
const main = async () => {
|
|
113
|
-
console.log("\n🔧 node-thermal-printer postinstall setup\n");
|
|
114
|
-
|
|
115
|
-
// Step 1: Find Python
|
|
116
|
-
console.log("1️⃣ Checking Python installation...");
|
|
117
|
-
const pythonCmd = findPythonCmd();
|
|
118
|
-
|
|
119
|
-
if (!pythonCmd) {
|
|
120
|
-
console.error("\n❌ ERROR: Python 3.9+ not found!");
|
|
121
|
-
console.error(
|
|
122
|
-
"\nPlease install Python from https://www.python.org/downloads/",
|
|
123
|
-
);
|
|
124
|
-
console.error("After installing Python, run: npm install again\n");
|
|
125
|
-
process.exit(1);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
console.log(` Using: ${pythonCmd}\n`);
|
|
129
|
-
|
|
130
|
-
// Step 2: Install bleak
|
|
131
|
-
console.log("2️⃣ Checking bleak dependency...");
|
|
132
|
-
try {
|
|
133
|
-
const importCheck = spawnSync(
|
|
134
|
-
pythonCmd.cmd,
|
|
135
|
-
[...pythonCmd.args, "-c", "import bleak"],
|
|
136
|
-
{
|
|
137
|
-
stdio: "pipe",
|
|
138
|
-
timeout: 2000,
|
|
139
|
-
shell: false,
|
|
140
|
-
},
|
|
141
|
-
);
|
|
142
|
-
if (importCheck.status !== 0) {
|
|
143
|
-
throw new Error("bleak import check failed");
|
|
144
|
-
}
|
|
145
|
-
console.log("✓ bleak already installed\n");
|
|
146
|
-
} catch {
|
|
147
|
-
const installed = installBleak(pythonCmd);
|
|
148
|
-
if (!installed) {
|
|
149
|
-
console.error("\n⚠ Manual installation required:");
|
|
150
|
-
console.error(
|
|
151
|
-
` ${pythonCmd.cmd} ${pythonCmd.args.join(" ")} -m pip install bleak\n`,
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Step 3: Platform-specific notes
|
|
157
|
-
console.log("3️⃣ Platform-specific requirements:");
|
|
158
|
-
const platform = process.platform;
|
|
159
|
-
if (platform === "linux") {
|
|
160
|
-
console.log(" 📋 Linux detected - BLE requires group permissions:");
|
|
161
|
-
console.log(" sudo usermod -a -G dialout,plugdev $USER");
|
|
162
|
-
console.log(" (Log out and back in for changes to take effect)\n");
|
|
163
|
-
} else if (platform === "darwin") {
|
|
164
|
-
console.log(" 📋 macOS detected - Ensure Bluetooth is enabled\n");
|
|
165
|
-
} else if (platform === "win32") {
|
|
166
|
-
console.log(
|
|
167
|
-
" 📋 Windows detected - Ensure Bluetooth drivers are installed\n",
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
console.log("✅ Setup complete! You can now use node-thermal-printer-js\n");
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
main().catch((err) => {
|
|
175
|
-
console.error("Error during setup:", err.message);
|
|
176
|
-
process.exit(1);
|
|
177
|
-
});
|