pi-bridge 0.3.3 → 0.3.4
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 +1 -1
- package/src/local/fs-patch.js +34 -18
package/package.json
CHANGED
package/src/local/fs-patch.js
CHANGED
|
@@ -4,6 +4,7 @@ const fs = require('fs');
|
|
|
4
4
|
const fsp = require('fs/promises');
|
|
5
5
|
const http = require('http');
|
|
6
6
|
const path = require('path');
|
|
7
|
+
const { fileURLToPath } = require('url');
|
|
7
8
|
const { isFakePath, toRemotePath } = require('./path-mapper');
|
|
8
9
|
const { httpGet, httpPost } = require('./http-client');
|
|
9
10
|
|
|
@@ -127,9 +128,28 @@ function patchFs(fakeRoot, port, token) {
|
|
|
127
128
|
cp: fs.promises.cp ? fs.promises.cp.bind(fs.promises) : undefined,
|
|
128
129
|
};
|
|
129
130
|
|
|
130
|
-
// Resolve any path (relative or absolute) to absolute before checking fake root
|
|
131
|
+
// Resolve any path (relative or absolute) to absolute before checking fake root.
|
|
132
|
+
// file: URLs are accepted too: jiti's bundled ESM resolver probes package
|
|
133
|
+
// mains with fs.statSync(new URL(...)), which must reach the remote.
|
|
134
|
+
// Buffer paths deliberately pass through: Node 20's JS rmSync walks children
|
|
135
|
+
// as Buffers via the public fs.*, and routing those would make removeFakeDir
|
|
136
|
+
// list and delete files on the remote.
|
|
131
137
|
function abs(p) {
|
|
132
|
-
|
|
138
|
+
if (typeof p === 'string') return path.resolve(p);
|
|
139
|
+
if (p instanceof URL) return p.protocol === 'file:' ? path.resolve(fileURLToPath(p)) : null;
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Shared by statSync/lstatSync. Honours { throwIfNoEntry: false }, which the
|
|
144
|
+
// ESM resolver relies on to probe candidate files without try/catch.
|
|
145
|
+
function statRemoteSync(s, opts) {
|
|
146
|
+
try {
|
|
147
|
+
return makeStats(JSON.parse(httpGet(port, token, '/stat?path=' + encodeURIComponent(rpath(s)))));
|
|
148
|
+
} catch (e) {
|
|
149
|
+
const missing = e && e.message && (e.message.includes('ENOENT') || e.message.includes('403'));
|
|
150
|
+
if (missing && opts && opts.throwIfNoEntry === false) return undefined;
|
|
151
|
+
rethrowRemote(e, s);
|
|
152
|
+
}
|
|
133
153
|
}
|
|
134
154
|
|
|
135
155
|
function rpath(fakePath) {
|
|
@@ -229,17 +249,13 @@ function patchFs(fakeRoot, port, token) {
|
|
|
229
249
|
fs.statSync = function patchedStatSync(p, opts) {
|
|
230
250
|
const s = abs(p);
|
|
231
251
|
if (!s || !isFakePath(s, fakeRoot)) return orig.statSync(p, opts);
|
|
232
|
-
|
|
233
|
-
return makeStats(JSON.parse(httpGet(port, token, '/stat?path=' + encodeURIComponent(rpath(s)))));
|
|
234
|
-
} catch (e) { rethrowRemote(e, s); }
|
|
252
|
+
return statRemoteSync(s, opts);
|
|
235
253
|
};
|
|
236
254
|
|
|
237
255
|
fs.lstatSync = function patchedLstatSync(p, opts) {
|
|
238
256
|
const s = abs(p);
|
|
239
257
|
if (!s || !isFakePath(s, fakeRoot)) return orig.lstatSync(p, opts);
|
|
240
|
-
|
|
241
|
-
return makeStats(JSON.parse(httpGet(port, token, '/stat?path=' + encodeURIComponent(rpath(s)))));
|
|
242
|
-
} catch (e) { rethrowRemote(e, s); }
|
|
258
|
+
return statRemoteSync(s, opts);
|
|
243
259
|
};
|
|
244
260
|
|
|
245
261
|
fs.writeFileSync = function patchedWriteFileSync(p, data, opts) {
|
|
@@ -359,7 +375,7 @@ function patchFs(fakeRoot, port, token) {
|
|
|
359
375
|
|
|
360
376
|
// createReadStream: read entire file from remote, pipe as stream
|
|
361
377
|
fs.createReadStream = function patchedCreateReadStream(p, opts) {
|
|
362
|
-
const s =
|
|
378
|
+
const s = abs(p);
|
|
363
379
|
if (!s || !isFakePath(s, fakeRoot)) return orig.createReadStream(p, opts);
|
|
364
380
|
const { Readable } = require('stream');
|
|
365
381
|
const stream = new Readable({ read() {} });
|
|
@@ -372,7 +388,7 @@ function patchFs(fakeRoot, port, token) {
|
|
|
372
388
|
|
|
373
389
|
// createWriteStream: buffer writes, POST on finish
|
|
374
390
|
fs.createWriteStream = function patchedCreateWriteStream(p, opts) {
|
|
375
|
-
const s =
|
|
391
|
+
const s = abs(p);
|
|
376
392
|
if (!s || !isFakePath(s, fakeRoot)) return orig.createWriteStream(p, opts);
|
|
377
393
|
const { Writable } = require('stream');
|
|
378
394
|
const chunks = [];
|
|
@@ -402,7 +418,7 @@ function patchFs(fakeRoot, port, token) {
|
|
|
402
418
|
};
|
|
403
419
|
|
|
404
420
|
fs.promises.readFile = async function patchedReadFile(p, opts) {
|
|
405
|
-
const s =
|
|
421
|
+
const s = abs(p);
|
|
406
422
|
if (!s || !isFakePath(s, fakeRoot)) return origP.readFile(p, opts);
|
|
407
423
|
try {
|
|
408
424
|
const body = await httpGetAsync(port, token, '/read?path=' + encodeURIComponent(rpath(s)));
|
|
@@ -416,7 +432,7 @@ function patchFs(fakeRoot, port, token) {
|
|
|
416
432
|
};
|
|
417
433
|
|
|
418
434
|
fs.promises.readdir = async function patchedReaddir(p, opts) {
|
|
419
|
-
const s =
|
|
435
|
+
const s = abs(p) || p.toString();
|
|
420
436
|
if (!isFakePath(s, fakeRoot)) return origP.readdir(p, opts);
|
|
421
437
|
try {
|
|
422
438
|
const withFileTypes = opts && opts.withFileTypes;
|
|
@@ -465,7 +481,7 @@ function patchFs(fakeRoot, port, token) {
|
|
|
465
481
|
};
|
|
466
482
|
|
|
467
483
|
fs.promises.writeFile = async function patchedWriteFile(p, data, opts) {
|
|
468
|
-
const s =
|
|
484
|
+
const s = abs(p);
|
|
469
485
|
if (!s || !isFakePath(s, fakeRoot)) return origP.writeFile(p, data, opts);
|
|
470
486
|
const content = Buffer.isBuffer(data) ? data.toString('utf8') : String(data);
|
|
471
487
|
await new Promise(function(resolve, reject) {
|
|
@@ -517,7 +533,7 @@ function patchFs(fakeRoot, port, token) {
|
|
|
517
533
|
};
|
|
518
534
|
|
|
519
535
|
fs.promises.appendFile = async function patchedAppendFile(p, data, opts) {
|
|
520
|
-
const s =
|
|
536
|
+
const s = abs(p);
|
|
521
537
|
if (!s || !isFakePath(s, fakeRoot)) return origP.appendFile(p, data, opts);
|
|
522
538
|
const content = Buffer.isBuffer(data) ? data.toString('utf8') : String(data);
|
|
523
539
|
const buf = Buffer.from(content, 'utf8');
|
|
@@ -614,7 +630,7 @@ function patchFs(fakeRoot, port, token) {
|
|
|
614
630
|
|
|
615
631
|
// fs.promises.open: return a minimal FileHandle for reading
|
|
616
632
|
fs.promises.open = async function patchedOpen(p, flags, mode) {
|
|
617
|
-
const s =
|
|
633
|
+
const s = abs(p);
|
|
618
634
|
if (!s || !isFakePath(s, fakeRoot)) return origP.open(p, flags, mode);
|
|
619
635
|
// Fetch the file content eagerly; return a minimal FileHandle-like object
|
|
620
636
|
const content = await httpGetAsync(port, token, '/read?path=' + encodeURIComponent(rpath(s)));
|
|
@@ -646,7 +662,7 @@ function patchFs(fakeRoot, port, token) {
|
|
|
646
662
|
const watchFilePollers = new Map();
|
|
647
663
|
|
|
648
664
|
fs.watch = function patchedWatch(filename, opts, listener) {
|
|
649
|
-
const s = abs(
|
|
665
|
+
const s = abs(filename);
|
|
650
666
|
if (!s || !isFakePath(s, fakeRoot)) return origWatch(filename, opts, listener);
|
|
651
667
|
|
|
652
668
|
if (typeof opts === 'function') { listener = opts; opts = {}; }
|
|
@@ -711,7 +727,7 @@ function patchFs(fakeRoot, port, token) {
|
|
|
711
727
|
};
|
|
712
728
|
|
|
713
729
|
fs.watchFile = function patchedWatchFile(filename, opts, listener) {
|
|
714
|
-
const s = abs(
|
|
730
|
+
const s = abs(filename);
|
|
715
731
|
if (!s || !isFakePath(s, fakeRoot)) {
|
|
716
732
|
return origWatchFile ? origWatchFile(filename, opts, listener) : undefined;
|
|
717
733
|
}
|
|
@@ -741,7 +757,7 @@ function patchFs(fakeRoot, port, token) {
|
|
|
741
757
|
};
|
|
742
758
|
|
|
743
759
|
fs.unwatchFile = function patchedUnwatchFile(filename, listener) {
|
|
744
|
-
const s = abs(
|
|
760
|
+
const s = abs(filename);
|
|
745
761
|
if (!s || !isFakePath(s, fakeRoot)) {
|
|
746
762
|
return origUnwatchFile ? origUnwatchFile(filename, listener) : undefined;
|
|
747
763
|
}
|