pi-bridge 0.2.4 → 0.2.7
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-bridge",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"description": "Transparent filesystem bridge that makes pi run natively on a remote machine over SSH",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"bin": {
|
|
@@ -27,6 +27,14 @@
|
|
|
27
27
|
"filesystem"
|
|
28
28
|
],
|
|
29
29
|
"license": "MIT",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/zeflq/pi-bridge.git"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/zeflq/pi-bridge#readme",
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/zeflq/pi-bridge/issues"
|
|
37
|
+
},
|
|
30
38
|
"devDependencies": {
|
|
31
39
|
"vitest": "^2.0.0"
|
|
32
40
|
}
|
|
@@ -29,11 +29,33 @@ function patchChildProcess(fakeRoot, remote) {
|
|
|
29
29
|
return typeof c === 'string' ? path.resolve(c) : c.toString();
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* On Windows, pi may call spawn with a full exe path like
|
|
34
|
+
* C:\Program Files\Git\bin\bash.exe. Strip it to the bare command name
|
|
35
|
+
* ('bash') so the remote Linux shell can find it.
|
|
36
|
+
*/
|
|
37
|
+
function normalizeCmd(file) {
|
|
38
|
+
if (process.platform !== 'win32') return file;
|
|
39
|
+
return path.basename(String(file)).replace(/\.exe$/i, '');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Returns true for commands that must always run locally, never over SSH.
|
|
44
|
+
* - node / node.exe: pi's internal tooling (session export, compaction, …)
|
|
45
|
+
* spawns Node with large payloads as args; redirecting those over SSH would
|
|
46
|
+
* produce an ENAMETOOLONG error on Windows and is never correct anyway.
|
|
47
|
+
*/
|
|
48
|
+
function isLocalOnly(file) {
|
|
49
|
+
const name = normalizeCmd(file).toLowerCase();
|
|
50
|
+
return name === 'node';
|
|
51
|
+
}
|
|
52
|
+
|
|
32
53
|
/**
|
|
33
54
|
* Build the SSH-redirected command: cd to remote cwd, then run the
|
|
34
55
|
* original command with its arguments, all shell-quoted.
|
|
35
56
|
*/
|
|
36
57
|
function buildSshArgs(file, args, opts) {
|
|
58
|
+
file = normalizeCmd(file);
|
|
37
59
|
const fakeCwd = effectiveCwd(opts);
|
|
38
60
|
const remoteCwd = toRemotePath(fakeCwd, fakeRoot);
|
|
39
61
|
|
|
@@ -54,7 +76,7 @@ function patchChildProcess(fakeRoot, remote) {
|
|
|
54
76
|
opts = opts || {};
|
|
55
77
|
|
|
56
78
|
const cwd = effectiveCwd(opts);
|
|
57
|
-
if (!isFakePath(cwd, fakeRoot)) return origSpawn(file, args, opts);
|
|
79
|
+
if (!isFakePath(cwd, fakeRoot) || isLocalOnly(file)) return origSpawn(file, args, opts);
|
|
58
80
|
|
|
59
81
|
return origSpawn('ssh', buildSshArgs(file, args, opts), Object.assign({}, opts, { cwd: undefined }));
|
|
60
82
|
};
|
|
@@ -66,7 +88,7 @@ function patchChildProcess(fakeRoot, remote) {
|
|
|
66
88
|
opts = opts || {};
|
|
67
89
|
|
|
68
90
|
const cwd = effectiveCwd(opts);
|
|
69
|
-
if (!isFakePath(cwd, fakeRoot)) return origSpawnSync(file, args, opts);
|
|
91
|
+
if (!isFakePath(cwd, fakeRoot) || isLocalOnly(file)) return origSpawnSync(file, args, opts);
|
|
70
92
|
|
|
71
93
|
return origSpawnSync('ssh', buildSshArgs(file, args, opts), Object.assign({}, opts, { cwd: undefined }));
|
|
72
94
|
};
|
package/src/local/fs-patch.js
CHANGED
|
@@ -38,6 +38,15 @@ function makeEisdir(p) {
|
|
|
38
38
|
);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Returns true if the path looks like a bash executable.
|
|
43
|
+
* Used on Windows to fake bash presence so pi's shell-detection passes.
|
|
44
|
+
*/
|
|
45
|
+
function isBashPath(p) {
|
|
46
|
+
const n = String(p).replace(/\\/g, '/').toLowerCase();
|
|
47
|
+
return n.endsWith('/bash.exe') || n.endsWith('/bash') || n === '/bin/bash';
|
|
48
|
+
}
|
|
49
|
+
|
|
41
50
|
function rethrowRemote(e, p) {
|
|
42
51
|
if (!e || !e.message) throw e;
|
|
43
52
|
if (e.message.includes('403')) throw makeEnoent(p);
|
|
@@ -176,6 +185,11 @@ function patchFs(fakeRoot, port, token) {
|
|
|
176
185
|
|
|
177
186
|
fs.existsSync = function patchedExistsSync(p) {
|
|
178
187
|
const s = abs(p);
|
|
188
|
+
// On Windows, pi checks for bash locally before using the shell tool.
|
|
189
|
+
// The check never reaches our SSH bridge (it's just an existsSync call).
|
|
190
|
+
// Fake it so pi believes bash is available; the actual spawn is intercepted
|
|
191
|
+
// and the Windows exe path is normalised to 'bash' before going over SSH.
|
|
192
|
+
if (process.platform === 'win32' && isBashPath(s)) return true;
|
|
179
193
|
if (!s || !isFakePath(s, fakeRoot)) return orig.existsSync(p);
|
|
180
194
|
try {
|
|
181
195
|
return httpGet(port, token, '/exists?path=' + encodeURIComponent(rpath(s))).trim() === '1';
|