node-thermal-printer-js 1.2.0 → 1.2.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/app.js +31 -16
- package/package.json +1 -6
- package/scripts/install-deps.js +0 -135
package/app.js
CHANGED
|
@@ -22,25 +22,30 @@ let bleServerPort = null;
|
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Find an available Python 3.9+ executable on the system.
|
|
25
|
-
* Tries
|
|
26
|
-
* @returns {string|null} Command
|
|
25
|
+
* Tries local venv first, then versioned launcher probes on Windows, then system Python.
|
|
26
|
+
* @returns {{ cmd: string, args: string[] }|null} Command descriptor if found, null otherwise
|
|
27
27
|
*/
|
|
28
28
|
const findPythonCmd = () => {
|
|
29
29
|
const candidates = getPythonLaunchCandidates();
|
|
30
30
|
|
|
31
|
-
for (const
|
|
31
|
+
for (const candidate of candidates) {
|
|
32
32
|
try {
|
|
33
|
-
const result = spawnSync(cmd, ["--version"], {
|
|
33
|
+
const result = spawnSync(candidate.cmd, [...candidate.args, "--version"], {
|
|
34
34
|
encoding: "utf8",
|
|
35
35
|
timeout: 2000,
|
|
36
36
|
shell: false,
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
const output = `${result.stdout || ""}${result.stderr || ""}`.trim();
|
|
40
|
-
const match = output.match(/Python (\d
|
|
41
|
-
if (match
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
const match = output.match(/Python (\d+)\.(\d+)/);
|
|
41
|
+
if (match) {
|
|
42
|
+
const major = parseInt(match[1], 10);
|
|
43
|
+
const minor = parseInt(match[2], 10);
|
|
44
|
+
// Check if Python 3.9+
|
|
45
|
+
if (major > 3 || (major === 3 && minor >= 9)) {
|
|
46
|
+
console.log(`[BLE] ✓ Detected Python: ${candidate.cmd} ${candidate.args.join(" ")} (${output})`);
|
|
47
|
+
return candidate;
|
|
48
|
+
}
|
|
44
49
|
}
|
|
45
50
|
} catch {
|
|
46
51
|
// Continue to next candidate
|
|
@@ -52,20 +57,30 @@ const findPythonCmd = () => {
|
|
|
52
57
|
const getPythonLaunchCandidates = () => {
|
|
53
58
|
const localVenvCandidates = process.platform === "win32"
|
|
54
59
|
? [
|
|
55
|
-
path.join(scriptDir, ".venv", "Scripts", "python.exe"),
|
|
56
|
-
path.join(scriptDir, ".venv", "Scripts", "python"),
|
|
60
|
+
{ cmd: path.join(scriptDir, ".venv", "Scripts", "python.exe"), args: [] },
|
|
61
|
+
{ cmd: path.join(scriptDir, ".venv", "Scripts", "python"), args: [] },
|
|
57
62
|
]
|
|
58
63
|
: [
|
|
59
|
-
path.join(scriptDir, ".venv", "bin", "python"),
|
|
60
|
-
path.join(scriptDir, ".venv", "bin", "python3"),
|
|
64
|
+
{ cmd: path.join(scriptDir, ".venv", "bin", "python"), args: [] },
|
|
65
|
+
{ cmd: path.join(scriptDir, ".venv", "bin", "python3"), args: [] },
|
|
61
66
|
];
|
|
62
67
|
|
|
63
68
|
const systemCandidates = process.platform === "win32"
|
|
64
|
-
? [
|
|
65
|
-
|
|
69
|
+
? [
|
|
70
|
+
{ cmd: "py", args: ["-3.11"] },
|
|
71
|
+
{ cmd: "py", args: ["-3"] },
|
|
72
|
+
{ cmd: "py", args: [] },
|
|
73
|
+
{ cmd: "python3", args: [] },
|
|
74
|
+
{ cmd: "python", args: [] },
|
|
75
|
+
]
|
|
76
|
+
: [
|
|
77
|
+
{ cmd: "python3", args: [] },
|
|
78
|
+
{ cmd: "python", args: [] },
|
|
79
|
+
{ cmd: "py", args: [] },
|
|
80
|
+
];
|
|
66
81
|
|
|
67
82
|
return [
|
|
68
|
-
...localVenvCandidates.filter((candidate) => existsSync(candidate)),
|
|
83
|
+
...localVenvCandidates.filter((candidate) => existsSync(candidate.cmd)),
|
|
69
84
|
...systemCandidates,
|
|
70
85
|
];
|
|
71
86
|
};
|
|
@@ -327,7 +342,7 @@ const startBleServer = async (options = {}) => {
|
|
|
327
342
|
const candidates = envCmd
|
|
328
343
|
? [{ cmd: envCmd, cmdArgs: ["-u"] }] // -u for unbuffered output
|
|
329
344
|
: [
|
|
330
|
-
...(detectedPythonCmd ? [{ cmd: detectedPythonCmd, cmdArgs: ["-u"] }] : []),
|
|
345
|
+
...(detectedPythonCmd ? [{ cmd: detectedPythonCmd.cmd, cmdArgs: [...detectedPythonCmd.args, "-u"] }] : []),
|
|
331
346
|
...getPythonLaunchCandidates().map((cmd) => ({ cmd, cmdArgs: ["-u"] })),
|
|
332
347
|
];
|
|
333
348
|
|
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.2",
|
|
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,135 +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
|
-
path.join(scriptDir, ".venv", "Scripts", "python.exe"),
|
|
19
|
-
path.join(scriptDir, ".venv", "Scripts", "python"),
|
|
20
|
-
]
|
|
21
|
-
: [
|
|
22
|
-
path.join(scriptDir, ".venv", "bin", "python"),
|
|
23
|
-
path.join(scriptDir, ".venv", "bin", "python3"),
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
const candidates = [
|
|
27
|
-
...localVenvCandidates.filter((candidate) => existsSync(candidate)),
|
|
28
|
-
...(process.platform === "win32"
|
|
29
|
-
? ["py", "python3", "python"]
|
|
30
|
-
: ["python3", "python", "py"]),
|
|
31
|
-
];
|
|
32
|
-
|
|
33
|
-
for (const cmd of candidates) {
|
|
34
|
-
try {
|
|
35
|
-
const result = spawnSync(cmd, ["--version"], {
|
|
36
|
-
encoding: "utf8",
|
|
37
|
-
stdio: "pipe",
|
|
38
|
-
timeout: 2000,
|
|
39
|
-
shell: false,
|
|
40
|
-
});
|
|
41
|
-
const version = `${result.stdout || ""}${result.stderr || ""}`.trim();
|
|
42
|
-
// Check if Python 3.9+
|
|
43
|
-
const match = version.match(/Python (\d+\.\d+)/);
|
|
44
|
-
if (match && parseFloat(match[1]) >= 3.9) {
|
|
45
|
-
console.log(`✓ Found ${cmd} (${version})`);
|
|
46
|
-
return cmd;
|
|
47
|
-
}
|
|
48
|
-
} catch {
|
|
49
|
-
// Continue to next candidate
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return null;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const installBleak = (pythonCmd) => {
|
|
57
|
-
console.log(`\n📦 Installing bleak Python package...`);
|
|
58
|
-
try {
|
|
59
|
-
const result = spawnSync(pythonCmd, ["-m", "pip", "install", "bleak"], {
|
|
60
|
-
encoding: "utf8",
|
|
61
|
-
stdio: "inherit",
|
|
62
|
-
timeout: 120000,
|
|
63
|
-
shell: false,
|
|
64
|
-
});
|
|
65
|
-
if (result.status !== 0) {
|
|
66
|
-
throw new Error(`pip exited with code ${result.status ?? "unknown"}`);
|
|
67
|
-
}
|
|
68
|
-
console.log("✓ bleak installed successfully");
|
|
69
|
-
return true;
|
|
70
|
-
} catch (err) {
|
|
71
|
-
console.warn("⚠ Could not auto-install bleak");
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
const main = async () => {
|
|
77
|
-
console.log("\n🔧 node-thermal-printer postinstall setup\n");
|
|
78
|
-
|
|
79
|
-
// Step 1: Find Python
|
|
80
|
-
console.log("1️⃣ Checking Python installation...");
|
|
81
|
-
const pythonCmd = findPythonCmd();
|
|
82
|
-
|
|
83
|
-
if (!pythonCmd) {
|
|
84
|
-
console.error("\n❌ ERROR: Python 3.9+ not found!");
|
|
85
|
-
console.error(
|
|
86
|
-
"\nPlease install Python from https://www.python.org/downloads/",
|
|
87
|
-
);
|
|
88
|
-
console.error("After installing Python, run: npm install again\n");
|
|
89
|
-
process.exit(1);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
console.log(` Using: ${pythonCmd}\n`);
|
|
93
|
-
|
|
94
|
-
// Step 2: Install bleak
|
|
95
|
-
console.log("2️⃣ Checking bleak dependency...");
|
|
96
|
-
try {
|
|
97
|
-
const importCheck = spawnSync(pythonCmd, ["-c", "import bleak"], {
|
|
98
|
-
stdio: "pipe",
|
|
99
|
-
timeout: 2000,
|
|
100
|
-
shell: false,
|
|
101
|
-
});
|
|
102
|
-
if (importCheck.status !== 0) {
|
|
103
|
-
throw new Error("bleak import check failed");
|
|
104
|
-
}
|
|
105
|
-
console.log("✓ bleak already installed\n");
|
|
106
|
-
} catch {
|
|
107
|
-
const installed = installBleak(pythonCmd);
|
|
108
|
-
if (!installed) {
|
|
109
|
-
console.error("\n⚠ Manual installation required:");
|
|
110
|
-
console.error(` ${pythonCmd} -m pip install bleak\n`);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Step 3: Platform-specific notes
|
|
115
|
-
console.log("3️⃣ Platform-specific requirements:");
|
|
116
|
-
const platform = process.platform;
|
|
117
|
-
if (platform === "linux") {
|
|
118
|
-
console.log(" 📋 Linux detected - BLE requires group permissions:");
|
|
119
|
-
console.log(" sudo usermod -a -G dialout,plugdev $USER");
|
|
120
|
-
console.log(" (Log out and back in for changes to take effect)\n");
|
|
121
|
-
} else if (platform === "darwin") {
|
|
122
|
-
console.log(" 📋 macOS detected - Ensure Bluetooth is enabled\n");
|
|
123
|
-
} else if (platform === "win32") {
|
|
124
|
-
console.log(
|
|
125
|
-
" 📋 Windows detected - Ensure Bluetooth drivers are installed\n",
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
console.log("✅ Setup complete! You can now use node-thermal-printer-js\n");
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
main().catch((err) => {
|
|
133
|
-
console.error("Error during setup:", err.message);
|
|
134
|
-
process.exit(1);
|
|
135
|
-
});
|