sandboxedjs 0.1.46 → 0.1.48
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/dist/index.cjs +201 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +49 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.js +201 -9
- package/dist/index.js.map +1 -1
- package/dist/service-worker.js +41 -5
- package/dist/service-worker.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -993,6 +993,10 @@ declare class MirroringVolume implements RuntimeVolume {
|
|
|
993
993
|
readFileSync(path: string): Uint8Array;
|
|
994
994
|
readdirSync(path: string): string[];
|
|
995
995
|
lstatSync(path: string): VolumeStat;
|
|
996
|
+
/** The mirror's copy of a file, if it has one and we are allowed to look. */
|
|
997
|
+
private fromMirror;
|
|
998
|
+
/** The mirror's entries for a directory, for merging into a listing. */
|
|
999
|
+
private mirrorNames;
|
|
996
1000
|
readlinkSync(path: string): string;
|
|
997
1001
|
getStats(): VolumeStats;
|
|
998
1002
|
writeFileSync(path: string, data: string | Uint8Array): void;
|
|
@@ -1002,7 +1006,35 @@ declare class MirroringVolume implements RuntimeVolume {
|
|
|
1002
1006
|
}): void;
|
|
1003
1007
|
rmdirSync(path: string): void;
|
|
1004
1008
|
unlinkSync(path: string): void;
|
|
1009
|
+
/**
|
|
1010
|
+
* Rename, carrying anything the mirrored engine put there.
|
|
1011
|
+
*
|
|
1012
|
+
* This is the operation the dependency optimizer is built on, and the one
|
|
1013
|
+
* that used to destroy its output. Vite bundles into a temporary directory
|
|
1014
|
+
* and renames it into place when it is complete — but only half of that
|
|
1015
|
+
* directory is ever on this volume. Vite writes `_metadata.json` and
|
|
1016
|
+
* `package.json` through here; Rolldown writes the actual bundles through
|
|
1017
|
+
* WASI into the mirror. Renaming moved the half that was here and then
|
|
1018
|
+
* `sync(from)` deleted the half that was not, because from this side the
|
|
1019
|
+
* source directory had simply gone.
|
|
1020
|
+
*
|
|
1021
|
+
* What survived was a `deps` directory holding metadata that described five
|
|
1022
|
+
* optimized dependencies and contained none of them — which Vite reports, on
|
|
1023
|
+
* the failed read, as `504 Outdated Optimize Dep`. Nothing in that message is
|
|
1024
|
+
* true, and following it leads to hashes rather than to a missing file.
|
|
1025
|
+
*
|
|
1026
|
+
* So the mirror's side of the move is collected first, and lands here as
|
|
1027
|
+
* part of the rename.
|
|
1028
|
+
*/
|
|
1005
1029
|
renameSync(from: string, to: string): void;
|
|
1030
|
+
/**
|
|
1031
|
+
* Copy whatever the mirror holds under `from` into this volume under `to`.
|
|
1032
|
+
*
|
|
1033
|
+
* Deliberately not filtered the way {@link absorb} is: this walks one
|
|
1034
|
+
* directory that is being renamed, not the whole project, so the subtree is
|
|
1035
|
+
* small and `node_modules` is exactly where the interesting case lives.
|
|
1036
|
+
*/
|
|
1037
|
+
private collect;
|
|
1006
1038
|
symlinkSync(target: string, path: string): void;
|
|
1007
1039
|
linkSync(existing: string, path: string): void;
|
|
1008
1040
|
truncateSync(path: string, length?: number): void;
|
|
@@ -1214,11 +1246,28 @@ declare class CleanPackageInstaller implements RuntimePackageInstaller {
|
|
|
1214
1246
|
private readonly fetcher;
|
|
1215
1247
|
private readonly metadata;
|
|
1216
1248
|
private readonly tarballs;
|
|
1249
|
+
/** Single-version manifests, for the fields the packument omits. */
|
|
1250
|
+
private readonly details;
|
|
1217
1251
|
constructor(volume: RuntimeVolume, options?: CleanInstallerOptions);
|
|
1218
1252
|
forCwd(cwd: string): CleanPackageInstaller;
|
|
1219
1253
|
install(name: string, version?: string, options?: InstallOptions): Promise<RegistryManifest>;
|
|
1220
1254
|
installFromManifest(path: string, options?: InstallOptions): Promise<void>;
|
|
1221
1255
|
private installAt;
|
|
1256
|
+
/**
|
|
1257
|
+
* The `libc` and `main` fields, which the abbreviated packument leaves out.
|
|
1258
|
+
*
|
|
1259
|
+
* Fetched per version rather than as a full packument: the single-version
|
|
1260
|
+
* document is a few kilobytes, while the full one for a popular package runs
|
|
1261
|
+
* to megabytes. Only packages that already declare `os` or `cpu` ask for it,
|
|
1262
|
+
* so an ordinary install of pure-JavaScript dependencies makes no extra
|
|
1263
|
+
* requests at all — it is the prebuilt binaries, a handful per project, that
|
|
1264
|
+
* need the answer.
|
|
1265
|
+
*
|
|
1266
|
+
* A failure here is not fatal. Being unable to read `libc` puts the check
|
|
1267
|
+
* back where it was before this existed, which is worth strictly less than
|
|
1268
|
+
* being right and strictly more than refusing to install.
|
|
1269
|
+
*/
|
|
1270
|
+
private platformDetail;
|
|
1222
1271
|
private getMetadata;
|
|
1223
1272
|
private getTarball;
|
|
1224
1273
|
private createBinLinks;
|
package/dist/index.d.ts
CHANGED
|
@@ -993,6 +993,10 @@ declare class MirroringVolume implements RuntimeVolume {
|
|
|
993
993
|
readFileSync(path: string): Uint8Array;
|
|
994
994
|
readdirSync(path: string): string[];
|
|
995
995
|
lstatSync(path: string): VolumeStat;
|
|
996
|
+
/** The mirror's copy of a file, if it has one and we are allowed to look. */
|
|
997
|
+
private fromMirror;
|
|
998
|
+
/** The mirror's entries for a directory, for merging into a listing. */
|
|
999
|
+
private mirrorNames;
|
|
996
1000
|
readlinkSync(path: string): string;
|
|
997
1001
|
getStats(): VolumeStats;
|
|
998
1002
|
writeFileSync(path: string, data: string | Uint8Array): void;
|
|
@@ -1002,7 +1006,35 @@ declare class MirroringVolume implements RuntimeVolume {
|
|
|
1002
1006
|
}): void;
|
|
1003
1007
|
rmdirSync(path: string): void;
|
|
1004
1008
|
unlinkSync(path: string): void;
|
|
1009
|
+
/**
|
|
1010
|
+
* Rename, carrying anything the mirrored engine put there.
|
|
1011
|
+
*
|
|
1012
|
+
* This is the operation the dependency optimizer is built on, and the one
|
|
1013
|
+
* that used to destroy its output. Vite bundles into a temporary directory
|
|
1014
|
+
* and renames it into place when it is complete — but only half of that
|
|
1015
|
+
* directory is ever on this volume. Vite writes `_metadata.json` and
|
|
1016
|
+
* `package.json` through here; Rolldown writes the actual bundles through
|
|
1017
|
+
* WASI into the mirror. Renaming moved the half that was here and then
|
|
1018
|
+
* `sync(from)` deleted the half that was not, because from this side the
|
|
1019
|
+
* source directory had simply gone.
|
|
1020
|
+
*
|
|
1021
|
+
* What survived was a `deps` directory holding metadata that described five
|
|
1022
|
+
* optimized dependencies and contained none of them — which Vite reports, on
|
|
1023
|
+
* the failed read, as `504 Outdated Optimize Dep`. Nothing in that message is
|
|
1024
|
+
* true, and following it leads to hashes rather than to a missing file.
|
|
1025
|
+
*
|
|
1026
|
+
* So the mirror's side of the move is collected first, and lands here as
|
|
1027
|
+
* part of the rename.
|
|
1028
|
+
*/
|
|
1005
1029
|
renameSync(from: string, to: string): void;
|
|
1030
|
+
/**
|
|
1031
|
+
* Copy whatever the mirror holds under `from` into this volume under `to`.
|
|
1032
|
+
*
|
|
1033
|
+
* Deliberately not filtered the way {@link absorb} is: this walks one
|
|
1034
|
+
* directory that is being renamed, not the whole project, so the subtree is
|
|
1035
|
+
* small and `node_modules` is exactly where the interesting case lives.
|
|
1036
|
+
*/
|
|
1037
|
+
private collect;
|
|
1006
1038
|
symlinkSync(target: string, path: string): void;
|
|
1007
1039
|
linkSync(existing: string, path: string): void;
|
|
1008
1040
|
truncateSync(path: string, length?: number): void;
|
|
@@ -1214,11 +1246,28 @@ declare class CleanPackageInstaller implements RuntimePackageInstaller {
|
|
|
1214
1246
|
private readonly fetcher;
|
|
1215
1247
|
private readonly metadata;
|
|
1216
1248
|
private readonly tarballs;
|
|
1249
|
+
/** Single-version manifests, for the fields the packument omits. */
|
|
1250
|
+
private readonly details;
|
|
1217
1251
|
constructor(volume: RuntimeVolume, options?: CleanInstallerOptions);
|
|
1218
1252
|
forCwd(cwd: string): CleanPackageInstaller;
|
|
1219
1253
|
install(name: string, version?: string, options?: InstallOptions): Promise<RegistryManifest>;
|
|
1220
1254
|
installFromManifest(path: string, options?: InstallOptions): Promise<void>;
|
|
1221
1255
|
private installAt;
|
|
1256
|
+
/**
|
|
1257
|
+
* The `libc` and `main` fields, which the abbreviated packument leaves out.
|
|
1258
|
+
*
|
|
1259
|
+
* Fetched per version rather than as a full packument: the single-version
|
|
1260
|
+
* document is a few kilobytes, while the full one for a popular package runs
|
|
1261
|
+
* to megabytes. Only packages that already declare `os` or `cpu` ask for it,
|
|
1262
|
+
* so an ordinary install of pure-JavaScript dependencies makes no extra
|
|
1263
|
+
* requests at all — it is the prebuilt binaries, a handful per project, that
|
|
1264
|
+
* need the answer.
|
|
1265
|
+
*
|
|
1266
|
+
* A failure here is not fatal. Being unable to read `libc` puts the check
|
|
1267
|
+
* back where it was before this existed, which is worth strictly less than
|
|
1268
|
+
* being right and strictly more than refusing to install.
|
|
1269
|
+
*/
|
|
1270
|
+
private platformDetail;
|
|
1222
1271
|
private getMetadata;
|
|
1223
1272
|
private getTarball;
|
|
1224
1273
|
private createBinLinks;
|
package/dist/index.js
CHANGED
|
@@ -20301,6 +20301,8 @@ var CleanPackageInstaller = class _CleanPackageInstaller {
|
|
|
20301
20301
|
fetcher;
|
|
20302
20302
|
metadata = /* @__PURE__ */ new Map();
|
|
20303
20303
|
tarballs = /* @__PURE__ */ new Map();
|
|
20304
|
+
/** Single-version manifests, for the fields the packument omits. */
|
|
20305
|
+
details = /* @__PURE__ */ new Map();
|
|
20304
20306
|
forCwd(cwd) {
|
|
20305
20307
|
return new _CleanPackageInstaller(this.volume, { ...this.options, cwd });
|
|
20306
20308
|
}
|
|
@@ -20326,10 +20328,17 @@ var CleanPackageInstaller = class _CleanPackageInstaller {
|
|
|
20326
20328
|
const version = resolveVersion(metadata, range);
|
|
20327
20329
|
const manifest = metadata.versions[version];
|
|
20328
20330
|
if (!manifest) throw new Error(`No matching version found for ${name}@${range}`);
|
|
20329
|
-
if (!supportsPlatform(manifest)) {
|
|
20330
|
-
throw new Error(`${name}@${version} is not compatible with linux/x64/glibc`);
|
|
20331
|
-
}
|
|
20332
20331
|
const identity = `${name}@${version}`;
|
|
20332
|
+
if (!supportsPlatform(manifest)) throw new IncompatiblePlatform(identity, "");
|
|
20333
|
+
if (manifest.os?.length || manifest.cpu?.length) {
|
|
20334
|
+
const detail = await this.platformDetail(name, version);
|
|
20335
|
+
if (!platformListAllows(detail.libc, PLATFORM.libc)) {
|
|
20336
|
+
throw new IncompatiblePlatform(identity, ` (needs ${detail.libc?.join(", ")})`);
|
|
20337
|
+
}
|
|
20338
|
+
if (detail.main?.endsWith(".node")) {
|
|
20339
|
+
throw new IncompatiblePlatform(identity, " (native addon; this runtime cannot dlopen)");
|
|
20340
|
+
}
|
|
20341
|
+
}
|
|
20333
20342
|
const target = join(modulesRoot, name);
|
|
20334
20343
|
const installed2 = this.tryReadJson(join(target, "package.json"));
|
|
20335
20344
|
if (installed2?.version === version) return installed2;
|
|
@@ -20351,11 +20360,44 @@ var CleanPackageInstaller = class _CleanPackageInstaller {
|
|
|
20351
20360
|
try {
|
|
20352
20361
|
await this.installAt(dependency, dependencyRange, childRoot, options, nextAncestry);
|
|
20353
20362
|
} catch (error) {
|
|
20363
|
+
if (error instanceof IncompatiblePlatform) continue;
|
|
20354
20364
|
options.onProgress?.(`Skipped optional ${dependency}: ${error instanceof Error ? error.message : String(error)}`);
|
|
20355
20365
|
}
|
|
20356
20366
|
}
|
|
20357
20367
|
return manifest;
|
|
20358
20368
|
}
|
|
20369
|
+
/**
|
|
20370
|
+
* The `libc` and `main` fields, which the abbreviated packument leaves out.
|
|
20371
|
+
*
|
|
20372
|
+
* Fetched per version rather than as a full packument: the single-version
|
|
20373
|
+
* document is a few kilobytes, while the full one for a popular package runs
|
|
20374
|
+
* to megabytes. Only packages that already declare `os` or `cpu` ask for it,
|
|
20375
|
+
* so an ordinary install of pure-JavaScript dependencies makes no extra
|
|
20376
|
+
* requests at all — it is the prebuilt binaries, a handful per project, that
|
|
20377
|
+
* need the answer.
|
|
20378
|
+
*
|
|
20379
|
+
* A failure here is not fatal. Being unable to read `libc` puts the check
|
|
20380
|
+
* back where it was before this existed, which is worth strictly less than
|
|
20381
|
+
* being right and strictly more than refusing to install.
|
|
20382
|
+
*/
|
|
20383
|
+
async platformDetail(name, version) {
|
|
20384
|
+
const key = `${name}@${version}`;
|
|
20385
|
+
let request = this.details.get(key);
|
|
20386
|
+
if (!request) {
|
|
20387
|
+
request = (async () => {
|
|
20388
|
+
try {
|
|
20389
|
+
const encoded = name.startsWith("@") ? name.replace("/", "%2F") : encodeURIComponent(name);
|
|
20390
|
+
const response = await this.fetcher(`${this.registry}/${encoded}/${version}`);
|
|
20391
|
+
if (!response.ok) return {};
|
|
20392
|
+
return await response.json();
|
|
20393
|
+
} catch {
|
|
20394
|
+
return {};
|
|
20395
|
+
}
|
|
20396
|
+
})();
|
|
20397
|
+
this.details.set(key, request);
|
|
20398
|
+
}
|
|
20399
|
+
return request;
|
|
20400
|
+
}
|
|
20359
20401
|
async getMetadata(name) {
|
|
20360
20402
|
let request = this.metadata.get(name);
|
|
20361
20403
|
if (!request) {
|
|
@@ -20423,8 +20465,15 @@ var CleanPackageInstaller = class _CleanPackageInstaller {
|
|
|
20423
20465
|
}
|
|
20424
20466
|
}
|
|
20425
20467
|
};
|
|
20468
|
+
var PLATFORM = { os: "linux", cpu: "x64", libc: "glibc" };
|
|
20469
|
+
var IncompatiblePlatform = class extends Error {
|
|
20470
|
+
constructor(identity, detail) {
|
|
20471
|
+
super(`${identity} is not compatible with ${PLATFORM.os}/${PLATFORM.cpu}/${PLATFORM.libc}${detail}`);
|
|
20472
|
+
this.name = "IncompatiblePlatform";
|
|
20473
|
+
}
|
|
20474
|
+
};
|
|
20426
20475
|
function supportsPlatform(manifest) {
|
|
20427
|
-
return
|
|
20476
|
+
return platformListAllows(manifest.os, PLATFORM.os) && platformListAllows(manifest.cpu, PLATFORM.cpu) && platformListAllows(manifest.libc, PLATFORM.libc);
|
|
20428
20477
|
}
|
|
20429
20478
|
function platformListAllows(values, current) {
|
|
20430
20479
|
if (!values?.length) return true;
|
|
@@ -20516,7 +20565,9 @@ function safeTarget(destination, name) {
|
|
|
20516
20565
|
return join(destination, clean2);
|
|
20517
20566
|
}
|
|
20518
20567
|
function stripPackageRoot(name) {
|
|
20519
|
-
|
|
20568
|
+
const clean2 = name.replace(/^\.\//, "").replace(/\/$/, "");
|
|
20569
|
+
const slash = clean2.indexOf("/");
|
|
20570
|
+
return slash === -1 ? "" : clean2.slice(slash + 1);
|
|
20520
20571
|
}
|
|
20521
20572
|
function text(bytes2, start2, length) {
|
|
20522
20573
|
return new TextDecoder().decode(bytes2.subarray(start2, start2 + length)).replace(/\0.*$/, "").trim();
|
|
@@ -26562,15 +26613,91 @@ var MirroringVolume = class {
|
|
|
26562
26613
|
mirror.writeFileSync(path, this.inner.readFileSync(path));
|
|
26563
26614
|
});
|
|
26564
26615
|
}
|
|
26565
|
-
// ── reads: straight through
|
|
26616
|
+
// ── reads: straight through, then the mirror ──────────────────────────────
|
|
26617
|
+
/*
|
|
26618
|
+
* A file the bundler produced exists only in the mirror until something
|
|
26619
|
+
* asks for it here.
|
|
26620
|
+
*
|
|
26621
|
+
* {@link absorb} was the original answer and is not enough on its own. It
|
|
26622
|
+
* runs when a process ends — a dev server never ends — and it skips
|
|
26623
|
+
* `node_modules`, where Vite keeps the one output that a dev server depends
|
|
26624
|
+
* on: `node_modules/.vite/deps`. Between those two, the entire pre-bundled
|
|
26625
|
+
* dependency set stayed invisible to the container that had to serve it.
|
|
26626
|
+
*
|
|
26627
|
+
* The symptom was almost perfectly disguised. Vite writes `_metadata.json`
|
|
26628
|
+
* itself, through this volume, so the directory looked half-populated and
|
|
26629
|
+
* the metadata listed every dependency as optimized. Rolldown wrote the
|
|
26630
|
+
* actual bundles through WASI into the mirror, where nothing brought them
|
|
26631
|
+
* back. Vite then read a file that was not there — and reports a failed read
|
|
26632
|
+
* of an optimized dependency as `504 Outdated Optimize Dep`, which describes
|
|
26633
|
+
* a stale hash and sends everyone looking at hashes. The hash was never
|
|
26634
|
+
* wrong. The file was missing.
|
|
26635
|
+
*
|
|
26636
|
+
* Falling back on read fixes it wherever it happens, for any path, without
|
|
26637
|
+
* polling and without depending on how the engine chose to write.
|
|
26638
|
+
*/
|
|
26566
26639
|
readFileSync(path) {
|
|
26567
|
-
|
|
26640
|
+
try {
|
|
26641
|
+
return this.inner.readFileSync(path);
|
|
26642
|
+
} catch (error) {
|
|
26643
|
+
const produced = this.fromMirror(path);
|
|
26644
|
+
if (!produced) throw error;
|
|
26645
|
+
try {
|
|
26646
|
+
this.ensureDirectory(dirname(path));
|
|
26647
|
+
this.inner.writeFileSync(path, produced);
|
|
26648
|
+
} catch {
|
|
26649
|
+
}
|
|
26650
|
+
return produced;
|
|
26651
|
+
}
|
|
26568
26652
|
}
|
|
26569
26653
|
readdirSync(path) {
|
|
26570
|
-
|
|
26654
|
+
let here = [];
|
|
26655
|
+
let missing;
|
|
26656
|
+
try {
|
|
26657
|
+
here = this.inner.readdirSync(path);
|
|
26658
|
+
} catch (error) {
|
|
26659
|
+
missing = error;
|
|
26660
|
+
}
|
|
26661
|
+
const mirrored = this.mirrorNames(path);
|
|
26662
|
+
if (!mirrored) {
|
|
26663
|
+
if (missing) throw missing;
|
|
26664
|
+
return here;
|
|
26665
|
+
}
|
|
26666
|
+
return [.../* @__PURE__ */ new Set([...here, ...mirrored])].sort();
|
|
26571
26667
|
}
|
|
26572
26668
|
lstatSync(path) {
|
|
26573
|
-
|
|
26669
|
+
try {
|
|
26670
|
+
return this.inner.lstatSync(path);
|
|
26671
|
+
} catch (error) {
|
|
26672
|
+
if (this.fromMirror(path)) {
|
|
26673
|
+
try {
|
|
26674
|
+
this.readFileSync(path);
|
|
26675
|
+
return this.inner.lstatSync(path);
|
|
26676
|
+
} catch {
|
|
26677
|
+
}
|
|
26678
|
+
}
|
|
26679
|
+
throw error;
|
|
26680
|
+
}
|
|
26681
|
+
}
|
|
26682
|
+
/** The mirror's copy of a file, if it has one and we are allowed to look. */
|
|
26683
|
+
fromMirror(path) {
|
|
26684
|
+
const mirror = this.mirror;
|
|
26685
|
+
if (!mirror?.readFileSync || !mirror.lstatSync || !this.mirrored(path)) return void 0;
|
|
26686
|
+
try {
|
|
26687
|
+
if (!mirror.lstatSync(path).isDirectory()) return mirror.readFileSync(path);
|
|
26688
|
+
} catch {
|
|
26689
|
+
}
|
|
26690
|
+
return void 0;
|
|
26691
|
+
}
|
|
26692
|
+
/** The mirror's entries for a directory, for merging into a listing. */
|
|
26693
|
+
mirrorNames(path) {
|
|
26694
|
+
const mirror = this.mirror;
|
|
26695
|
+
if (!mirror?.readdirSync || !this.mirrored(path)) return void 0;
|
|
26696
|
+
try {
|
|
26697
|
+
return mirror.readdirSync(path);
|
|
26698
|
+
} catch {
|
|
26699
|
+
return void 0;
|
|
26700
|
+
}
|
|
26574
26701
|
}
|
|
26575
26702
|
readlinkSync(path) {
|
|
26576
26703
|
return this.inner.readlinkSync(path);
|
|
@@ -26599,11 +26726,76 @@ var MirroringVolume = class {
|
|
|
26599
26726
|
this.inner.unlinkSync(path);
|
|
26600
26727
|
this.sync(path);
|
|
26601
26728
|
}
|
|
26729
|
+
/**
|
|
26730
|
+
* Rename, carrying anything the mirrored engine put there.
|
|
26731
|
+
*
|
|
26732
|
+
* This is the operation the dependency optimizer is built on, and the one
|
|
26733
|
+
* that used to destroy its output. Vite bundles into a temporary directory
|
|
26734
|
+
* and renames it into place when it is complete — but only half of that
|
|
26735
|
+
* directory is ever on this volume. Vite writes `_metadata.json` and
|
|
26736
|
+
* `package.json` through here; Rolldown writes the actual bundles through
|
|
26737
|
+
* WASI into the mirror. Renaming moved the half that was here and then
|
|
26738
|
+
* `sync(from)` deleted the half that was not, because from this side the
|
|
26739
|
+
* source directory had simply gone.
|
|
26740
|
+
*
|
|
26741
|
+
* What survived was a `deps` directory holding metadata that described five
|
|
26742
|
+
* optimized dependencies and contained none of them — which Vite reports, on
|
|
26743
|
+
* the failed read, as `504 Outdated Optimize Dep`. Nothing in that message is
|
|
26744
|
+
* true, and following it leads to hashes rather than to a missing file.
|
|
26745
|
+
*
|
|
26746
|
+
* So the mirror's side of the move is collected first, and lands here as
|
|
26747
|
+
* part of the rename.
|
|
26748
|
+
*/
|
|
26602
26749
|
renameSync(from, to) {
|
|
26603
26750
|
this.inner.renameSync(from, to);
|
|
26751
|
+
this.collect(from, to);
|
|
26604
26752
|
this.sync(from);
|
|
26605
26753
|
this.sync(to);
|
|
26606
26754
|
}
|
|
26755
|
+
/**
|
|
26756
|
+
* Copy whatever the mirror holds under `from` into this volume under `to`.
|
|
26757
|
+
*
|
|
26758
|
+
* Deliberately not filtered the way {@link absorb} is: this walks one
|
|
26759
|
+
* directory that is being renamed, not the whole project, so the subtree is
|
|
26760
|
+
* small and `node_modules` is exactly where the interesting case lives.
|
|
26761
|
+
*/
|
|
26762
|
+
collect(from, to) {
|
|
26763
|
+
const mirror = this.mirror;
|
|
26764
|
+
if (!mirror?.readdirSync || !mirror.readFileSync || !mirror.lstatSync) return;
|
|
26765
|
+
if (!this.mirrored(from)) return;
|
|
26766
|
+
const walk = (source, destination) => {
|
|
26767
|
+
let stat2;
|
|
26768
|
+
try {
|
|
26769
|
+
stat2 = mirror.lstatSync(source);
|
|
26770
|
+
} catch {
|
|
26771
|
+
return;
|
|
26772
|
+
}
|
|
26773
|
+
if (stat2.isSymbolicLink()) return;
|
|
26774
|
+
if (stat2.isDirectory()) {
|
|
26775
|
+
let names;
|
|
26776
|
+
try {
|
|
26777
|
+
names = mirror.readdirSync(source);
|
|
26778
|
+
} catch {
|
|
26779
|
+
return;
|
|
26780
|
+
}
|
|
26781
|
+
this.ensureDirectory(destination);
|
|
26782
|
+
for (const name of names) walk(join(source, name), join(destination, name));
|
|
26783
|
+
return;
|
|
26784
|
+
}
|
|
26785
|
+
try {
|
|
26786
|
+
this.inner.lstatSync(destination);
|
|
26787
|
+
return;
|
|
26788
|
+
} catch {
|
|
26789
|
+
}
|
|
26790
|
+
try {
|
|
26791
|
+
const bytes2 = mirror.readFileSync(source);
|
|
26792
|
+
this.ensureDirectory(dirname(destination));
|
|
26793
|
+
this.inner.writeFileSync(destination, bytes2);
|
|
26794
|
+
} catch {
|
|
26795
|
+
}
|
|
26796
|
+
};
|
|
26797
|
+
this.safely(() => walk(from, to));
|
|
26798
|
+
}
|
|
26607
26799
|
symlinkSync(target, path) {
|
|
26608
26800
|
this.inner.symlinkSync(target, path);
|
|
26609
26801
|
this.sync(path);
|