poe-code 14.0.94 → 14.0.96
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/metafile.json +1 -1
- package/package.json +1 -1
- package/packages/safe-bash/dist/commands/apply-patch/apply.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/apply-patch/apply.js +5 -2
- package/packages/safe-bash/dist/commands/apply-patch/apply.js.map +1 -1
- package/packages/safe-bash/dist/commands/archive/extract.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/archive/extract.js +5 -2
- package/packages/safe-bash/dist/commands/archive/extract.js.map +1 -1
- package/packages/safe-bash/dist/commands/archive/internal.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/archive/internal.js +6 -2
- package/packages/safe-bash/dist/commands/archive/internal.js.map +1 -1
- package/packages/safe-bash/dist/commands/bytes/compression/files.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/bytes/compression/files.js +10 -6
- package/packages/safe-bash/dist/commands/bytes/compression/files.js.map +1 -1
- package/packages/safe-bash/dist/commands/diff-patch/diff.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/diff-patch/diff.js +4 -3
- package/packages/safe-bash/dist/commands/diff-patch/diff.js.map +1 -1
- package/packages/safe-bash/dist/commands/diff-patch/shared.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/diff-patch/shared.js +5 -3
- package/packages/safe-bash/dist/commands/diff-patch/shared.js.map +1 -1
- package/packages/safe-bash/dist/commands/du/du.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/du/du.js +6 -6
- package/packages/safe-bash/dist/commands/du/du.js.map +1 -1
- package/packages/safe-bash/dist/commands/file/index.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/file/index.js +9 -3
- package/packages/safe-bash/dist/commands/file/index.js.map +1 -1
- package/packages/safe-bash/dist/commands/filesystem-requirements.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/filesystem-requirements.js +1 -0
- package/packages/safe-bash/dist/commands/filesystem-requirements.js.map +1 -1
- package/packages/safe-bash/dist/commands/filesystem.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/filesystem.js +54 -10
- package/packages/safe-bash/dist/commands/filesystem.js.map +1 -1
- package/packages/safe-bash/dist/commands/find.js +1 -1
- package/packages/safe-bash/dist/commands/find.js.map +1 -1
- package/packages/safe-bash/dist/commands/html-to-markdown/input.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/html-to-markdown/input.js +12 -18
- package/packages/safe-bash/dist/commands/html-to-markdown/input.js.map +1 -1
- package/packages/safe-bash/dist/commands/internal.d.ts +1 -1
- package/packages/safe-bash/dist/commands/internal.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/internal.js +3 -2
- package/packages/safe-bash/dist/commands/internal.js.map +1 -1
- package/packages/safe-bash/dist/commands/metadata/internal.d.ts +2 -2
- package/packages/safe-bash/dist/commands/metadata/internal.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/metadata/internal.js +1 -1
- package/packages/safe-bash/dist/commands/metadata/internal.js.map +1 -1
- package/packages/safe-bash/dist/commands/metadata/mktemp.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/metadata/mktemp.js +5 -2
- package/packages/safe-bash/dist/commands/metadata/mktemp.js.map +1 -1
- package/packages/safe-bash/dist/commands/metadata/stat.js +1 -1
- package/packages/safe-bash/dist/commands/metadata/stat.js.map +1 -1
- package/packages/safe-bash/dist/commands/move.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/move.js +3 -2
- package/packages/safe-bash/dist/commands/move.js.map +1 -1
- package/packages/safe-bash/dist/commands/network/body.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/network/body.js +3 -1
- package/packages/safe-bash/dist/commands/network/body.js.map +1 -1
- package/packages/safe-bash/dist/commands/predicates.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/predicates.js +8 -2
- package/packages/safe-bash/dist/commands/predicates.js.map +1 -1
- package/packages/safe-bash/dist/commands/safejs/index.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/safejs/index.js +2 -1
- package/packages/safe-bash/dist/commands/safejs/index.js.map +1 -1
- package/packages/safe-bash/dist/commands/split/io.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/split/io.js +2 -1
- package/packages/safe-bash/dist/commands/split/io.js.map +1 -1
- package/packages/safe-bash/dist/commands/split/split.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/split/split.js +2 -1
- package/packages/safe-bash/dist/commands/split/split.js.map +1 -1
- package/packages/safe-bash/dist/commands/stream-format/shared.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/stream-format/shared.js +7 -4
- package/packages/safe-bash/dist/commands/stream-format/shared.js.map +1 -1
- package/packages/safe-bash/dist/commands/stream-inspection/shared.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/stream-inspection/shared.js +7 -4
- package/packages/safe-bash/dist/commands/stream-inspection/shared.js.map +1 -1
- package/packages/safe-bash/dist/commands/streams.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/streams.js +4 -2
- package/packages/safe-bash/dist/commands/streams.js.map +1 -1
- package/packages/safe-bash/dist/commands/structured/jq.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/structured/jq.js +15 -5
- package/packages/safe-bash/dist/commands/structured/jq.js.map +1 -1
- package/packages/safe-bash/dist/commands/table-text/internal.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/table-text/internal.js +5 -4
- package/packages/safe-bash/dist/commands/table-text/internal.js.map +1 -1
- package/packages/safe-bash/dist/commands/text-programs/awk-runtime.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/text-programs/awk-runtime.js +10 -4
- package/packages/safe-bash/dist/commands/text-programs/awk-runtime.js.map +1 -1
- package/packages/safe-bash/dist/commands/text.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/text.js +3 -2
- package/packages/safe-bash/dist/commands/text.js.map +1 -1
- package/packages/safe-bash/dist/commands/time-env/date.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/time-env/date.js +3 -2
- package/packages/safe-bash/dist/commands/time-env/date.js.map +1 -1
- package/packages/safe-bash/dist/commands/tree/tree.d.ts.map +1 -1
- package/packages/safe-bash/dist/commands/tree/tree.js +2 -1
- package/packages/safe-bash/dist/commands/tree/tree.js.map +1 -1
- package/packages/safe-bash/dist/contracts/filesystem.d.ts +1 -1
- package/packages/safe-bash/dist/contracts/filesystem.d.ts.map +1 -1
- package/packages/safe-bash/dist/core.browser.js +259 -119
- package/packages/safe-bash/dist/core.browser.js.map +4 -4
- package/packages/safe-bash/dist/shell/conditional.d.ts.map +1 -1
- package/packages/safe-bash/dist/shell/conditional.js +10 -6
- package/packages/safe-bash/dist/shell/conditional.js.map +1 -1
- package/packages/safe-bash/dist/shell/input.d.ts +1 -1
- package/packages/safe-bash/dist/shell/input.d.ts.map +1 -1
- package/packages/safe-bash/dist/shell/input.js +7 -3
- package/packages/safe-bash/dist/shell/input.js.map +1 -1
- package/packages/safe-bash/dist/shell/runtime.d.ts +2 -1
- package/packages/safe-bash/dist/shell/runtime.d.ts.map +1 -1
- package/packages/safe-bash/dist/shell/runtime.js +37 -28
- package/packages/safe-bash/dist/shell/runtime.js.map +1 -1
- package/packages/safe-bash/dist/shell/shell.d.ts.map +1 -1
- package/packages/safe-bash/dist/shell/shell.js +3 -1
- package/packages/safe-bash/dist/shell/shell.js.map +1 -1
- package/packages/safe-fs/dist/contracts/filesystem.d.ts +6 -2
- package/packages/safe-fs/dist/core.d.ts +1 -0
- package/packages/safe-fs/dist/fs/devices/index.d.ts +33 -0
- package/packages/safe-fs/dist/fs/devices/path.d.ts +5 -0
- package/packages/safe-fs/dist/fs/devices/stream.d.ts +5 -0
- package/packages/safe-fs/dist/fs/memory/index.d.ts +3 -2
- package/packages/safe-fs/dist/fs/mount/index.d.ts +2 -2
- package/packages/safe-fs/dist/fs/overlay/index.d.ts +2 -2
- package/packages/safe-fs/dist/fs/readonly/index.d.ts +2 -2
- package/packages/safe-fs/dist/fs/real/index.d.ts +2 -2
- package/packages/safe-fs/dist/fs/s3/filesystem.d.ts +3 -2
- package/packages/safe-fs/dist/fs/webdav/webdav.d.ts +3 -2
- package/packages/safe-fs/dist/index.d.ts +1 -0
- package/packages/safe-js/dist/browser/chunks/{chunk-I3HSJDAA.js → chunk-QK4IEGRO.js} +610 -4
- package/packages/safe-js/dist/browser/chunks/chunk-QK4IEGRO.js.map +7 -0
- package/packages/safe-js/dist/browser/safe-fs-core.js +5 -1
- package/packages/safe-js/dist/browser/safe-fs.js +5 -1
- package/packages/safe-js/dist/chunks/{chunk-CQZRYT3K.js → chunk-6V4U2JZS.js} +610 -4
- package/packages/safe-js/dist/chunks/chunk-6V4U2JZS.js.map +7 -0
- package/packages/safe-js/dist/chunks/{chunk-PZSJ52ZO.js → chunk-EZRL4ES2.js} +3 -3
- package/packages/safe-js/dist/chunks/{chunk-66PPRTEP.js → chunk-XOQ5CVQM.js} +9 -2
- package/packages/safe-js/dist/chunks/chunk-XOQ5CVQM.js.map +7 -0
- package/packages/safe-js/dist/cli.js +3 -3
- package/packages/safe-js/dist/index.js +3 -3
- package/packages/safe-js/dist/safe-fs-core.js +5 -1
- package/packages/safe-js/dist/safe-fs-core.js.map +1 -1
- package/packages/safe-js/dist/safe-fs-node.js +6 -2
- package/packages/safe-js/dist/safe-fs.js +6 -2
- package/packages/safe-js/dist/browser/chunks/chunk-I3HSJDAA.js.map +0 -7
- package/packages/safe-js/dist/chunks/chunk-66PPRTEP.js.map +0 -7
- package/packages/safe-js/dist/chunks/chunk-CQZRYT3K.js.map +0 -7
- /package/packages/safe-js/dist/chunks/{chunk-PZSJ52ZO.js.map → chunk-EZRL4ES2.js.map} +0 -0
|
@@ -775,6 +775,7 @@ var MemoryFileSystem = class _MemoryFileSystem {
|
|
|
775
775
|
removeDirectory: true,
|
|
776
776
|
recursiveRemove: true,
|
|
777
777
|
rename: true,
|
|
778
|
+
atomicRenameNoReplace: true,
|
|
778
779
|
copy: true,
|
|
779
780
|
exclusiveCopy: true,
|
|
780
781
|
readlink: true,
|
|
@@ -1199,6 +1200,7 @@ var MemoryFileSystem = class _MemoryFileSystem {
|
|
|
1199
1200
|
if (this.terminalDot(source) || this.terminalDot(destination)) this.fail("EINVAL", "rename", source, destination);
|
|
1200
1201
|
if (node === this.root || target.node === this.root) this.fail("EBUSY", "rename", source, destination);
|
|
1201
1202
|
if (destination.endsWith("/") && node.type !== "directory") this.fail("ENOTDIR", "rename", source, destination);
|
|
1203
|
+
if (options.noReplace && target.node) this.fail("EEXIST", "rename", source, destination);
|
|
1202
1204
|
if (target.node === node) return;
|
|
1203
1205
|
if (node.type === "directory" && target.path.startsWith(`${origin.path}/`)) this.fail("EINVAL", "rename", source, destination);
|
|
1204
1206
|
this.permission(origin.parent, 3, "rename", source);
|
|
@@ -1489,6 +1491,574 @@ function createMemoryFileSystem(options = {}) {
|
|
|
1489
1491
|
return new MemoryFileSystem(normalizeMemoryFileSystemLimits(options));
|
|
1490
1492
|
}
|
|
1491
1493
|
|
|
1494
|
+
// packages/safe-fs/src/fs/devices/path.ts
|
|
1495
|
+
var nullPath = "/dev/null";
|
|
1496
|
+
var deviceDirectory = "/dev";
|
|
1497
|
+
function lexicalDevicePath(path) {
|
|
1498
|
+
validatePath(path);
|
|
1499
|
+
const parts = [];
|
|
1500
|
+
for (const component of path.split("/")) {
|
|
1501
|
+
if (`/${parts.join("/")}` === nullPath) throw new FsError("ENOTDIR", { path });
|
|
1502
|
+
if (component === "..") parts.pop();
|
|
1503
|
+
else if (component && component !== ".") parts.push(component);
|
|
1504
|
+
}
|
|
1505
|
+
return `/${parts.join("/")}`;
|
|
1506
|
+
}
|
|
1507
|
+
async function resolveDevicePath(filesystem, path, options, followFinal = true) {
|
|
1508
|
+
options.signal?.throwIfAborted();
|
|
1509
|
+
const lexical = lexicalDevicePath(path);
|
|
1510
|
+
const aliases = typeof filesystem.lstat === "function";
|
|
1511
|
+
if (!aliases && lexical !== nullPath && lexical !== deviceDirectory && lexical !== "/") return lexical;
|
|
1512
|
+
const pending = path.split("/");
|
|
1513
|
+
const parts = [];
|
|
1514
|
+
let links = 0;
|
|
1515
|
+
let expanded = path.length;
|
|
1516
|
+
let absolute = path.startsWith("/");
|
|
1517
|
+
let traversalFailure;
|
|
1518
|
+
while (pending.length) {
|
|
1519
|
+
options.signal?.throwIfAborted();
|
|
1520
|
+
if (`/${parts.join("/")}` === nullPath) throw new FsError("ENOTDIR", { path });
|
|
1521
|
+
const component = pending.shift();
|
|
1522
|
+
if (!component || component === ".") continue;
|
|
1523
|
+
if (component === "..") {
|
|
1524
|
+
parts.pop();
|
|
1525
|
+
continue;
|
|
1526
|
+
}
|
|
1527
|
+
const candidate = `/${[...parts, component].join("/")}`;
|
|
1528
|
+
if (candidate !== deviceDirectory && candidate !== nullPath && (followFinal && aliases || pending.length)) {
|
|
1529
|
+
const lookup = absolute ? candidate : candidate.slice(1);
|
|
1530
|
+
let stat;
|
|
1531
|
+
try {
|
|
1532
|
+
if (typeof filesystem.lstat !== "function") throw new FsError("ENOTSUP", { path });
|
|
1533
|
+
stat = await filesystem.lstat(lookup, options);
|
|
1534
|
+
} catch (error) {
|
|
1535
|
+
options.signal?.throwIfAborted();
|
|
1536
|
+
if (isFsError(error, "ENOTSUP") && links === 0 && lexical !== nullPath && lexical !== deviceDirectory && lexical !== "/") return lexical;
|
|
1537
|
+
if (!isFsError(error, "ENOENT")) throw error;
|
|
1538
|
+
if (pending.length) traversalFailure ??= error;
|
|
1539
|
+
}
|
|
1540
|
+
options.signal?.throwIfAborted();
|
|
1541
|
+
if (stat?.type === "symlink") {
|
|
1542
|
+
if (typeof filesystem.readlink !== "function") throw new FsError("ENOTSUP", { path });
|
|
1543
|
+
if (++links > 40) throw new FsError("ELOOP", { path });
|
|
1544
|
+
const target = await filesystem.readlink(lookup, options);
|
|
1545
|
+
options.signal?.throwIfAborted();
|
|
1546
|
+
validatePath(target);
|
|
1547
|
+
expanded += target.length;
|
|
1548
|
+
if (expanded > 65536) throw new FsError("ENAMETOOLONG", { path });
|
|
1549
|
+
if (target.startsWith("/")) {
|
|
1550
|
+
parts.length = 0;
|
|
1551
|
+
absolute = true;
|
|
1552
|
+
}
|
|
1553
|
+
pending.unshift(...target.split("/"));
|
|
1554
|
+
continue;
|
|
1555
|
+
}
|
|
1556
|
+
if (stat && pending.length && stat.type !== "directory") traversalFailure ??= new FsError("ENOTDIR", { path });
|
|
1557
|
+
}
|
|
1558
|
+
parts.push(component);
|
|
1559
|
+
}
|
|
1560
|
+
const resolved = `/${parts.join("/")}`;
|
|
1561
|
+
if (traversalFailure && (resolved === nullPath || resolved === deviceDirectory || resolved === "/")) throw traversalFailure;
|
|
1562
|
+
return resolved;
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
// packages/safe-fs/src/fs/devices/stream.ts
|
|
1566
|
+
function deviceReadStream(open) {
|
|
1567
|
+
return { [Symbol.asyncIterator]() {
|
|
1568
|
+
let opened;
|
|
1569
|
+
let closing;
|
|
1570
|
+
const iterator = () => opened ??= open().then((source) => source[Symbol.asyncIterator]());
|
|
1571
|
+
const close = () => closing ??= iterator().then(async (source) => source.return ? source.return() : { done: true, value: void 0 });
|
|
1572
|
+
return {
|
|
1573
|
+
async next() {
|
|
1574
|
+
if (closing) {
|
|
1575
|
+
await closing;
|
|
1576
|
+
return { done: true, value: void 0 };
|
|
1577
|
+
}
|
|
1578
|
+
try {
|
|
1579
|
+
return await (await iterator()).next();
|
|
1580
|
+
} catch (error) {
|
|
1581
|
+
await finishCleanup(close, true);
|
|
1582
|
+
throw error;
|
|
1583
|
+
}
|
|
1584
|
+
},
|
|
1585
|
+
return: close
|
|
1586
|
+
};
|
|
1587
|
+
} };
|
|
1588
|
+
}
|
|
1589
|
+
async function drainDeviceFile(handle, signal) {
|
|
1590
|
+
let failed = false;
|
|
1591
|
+
let position = 0;
|
|
1592
|
+
try {
|
|
1593
|
+
await drainDeviceInput({ [Symbol.asyncIterator]: () => ({ async next() {
|
|
1594
|
+
const value = await handle.read(position, 65536, signal ? { signal } : {});
|
|
1595
|
+
if (!(value instanceof Uint8Array) || value.byteLength > 65536) throw new TypeError("Retained reads must return bounded Uint8Array chunks");
|
|
1596
|
+
position += value.byteLength;
|
|
1597
|
+
if (!Number.isSafeInteger(position)) throw new RangeError("Retained read position exceeds safe integer range");
|
|
1598
|
+
return { done: value.byteLength === 0, value };
|
|
1599
|
+
} }) }, signal);
|
|
1600
|
+
} catch (error) {
|
|
1601
|
+
failed = true;
|
|
1602
|
+
throw error;
|
|
1603
|
+
} finally {
|
|
1604
|
+
await finishCleanup(async () => {
|
|
1605
|
+
try {
|
|
1606
|
+
await handle.close();
|
|
1607
|
+
} catch (error) {
|
|
1608
|
+
signal?.throwIfAborted();
|
|
1609
|
+
throw error;
|
|
1610
|
+
}
|
|
1611
|
+
}, failed);
|
|
1612
|
+
}
|
|
1613
|
+
signal?.throwIfAborted();
|
|
1614
|
+
}
|
|
1615
|
+
function nextChunk(iterator, signal) {
|
|
1616
|
+
signal?.throwIfAborted();
|
|
1617
|
+
return new Promise((resolve, reject) => {
|
|
1618
|
+
const aborted = () => {
|
|
1619
|
+
signal?.removeEventListener("abort", aborted);
|
|
1620
|
+
reject(signal?.reason);
|
|
1621
|
+
};
|
|
1622
|
+
signal?.addEventListener("abort", aborted, { once: true });
|
|
1623
|
+
try {
|
|
1624
|
+
Promise.resolve(iterator.next()).then((result) => {
|
|
1625
|
+
signal?.removeEventListener("abort", aborted);
|
|
1626
|
+
if (signal?.aborted) reject(signal.reason);
|
|
1627
|
+
else resolve(result);
|
|
1628
|
+
}, (error) => {
|
|
1629
|
+
signal?.removeEventListener("abort", aborted);
|
|
1630
|
+
reject(signal?.aborted ? signal.reason : error);
|
|
1631
|
+
});
|
|
1632
|
+
} catch (error) {
|
|
1633
|
+
signal?.removeEventListener("abort", aborted);
|
|
1634
|
+
reject(signal?.aborted ? signal.reason : error);
|
|
1635
|
+
}
|
|
1636
|
+
});
|
|
1637
|
+
}
|
|
1638
|
+
async function drainDeviceInput(source, signal) {
|
|
1639
|
+
signal?.throwIfAborted();
|
|
1640
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
1641
|
+
let failed = false;
|
|
1642
|
+
let bytes = 0;
|
|
1643
|
+
let pulls = 0;
|
|
1644
|
+
try {
|
|
1645
|
+
for (; ; ) {
|
|
1646
|
+
const result = await nextChunk(iterator, signal);
|
|
1647
|
+
signal?.throwIfAborted();
|
|
1648
|
+
if (result.done) break;
|
|
1649
|
+
if (!(result.value instanceof Uint8Array)) throw new TypeError("Byte sources must yield Uint8Array chunks");
|
|
1650
|
+
bytes += result.value.byteLength;
|
|
1651
|
+
if (++pulls >= 64 || bytes >= 65536) {
|
|
1652
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1653
|
+
signal?.throwIfAborted();
|
|
1654
|
+
bytes = 0;
|
|
1655
|
+
pulls = 0;
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
} catch (error) {
|
|
1659
|
+
failed = true;
|
|
1660
|
+
throw error;
|
|
1661
|
+
} finally {
|
|
1662
|
+
await finishCleanup(async () => {
|
|
1663
|
+
try {
|
|
1664
|
+
await iterator.return?.();
|
|
1665
|
+
} catch (error) {
|
|
1666
|
+
signal?.throwIfAborted();
|
|
1667
|
+
throw error;
|
|
1668
|
+
}
|
|
1669
|
+
}, failed);
|
|
1670
|
+
}
|
|
1671
|
+
signal?.throwIfAborted();
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
// packages/safe-fs/src/fs/devices/index.ts
|
|
1675
|
+
var views = /* @__PURE__ */ new WeakMap();
|
|
1676
|
+
var deviceCapabilities = Object.freeze({
|
|
1677
|
+
readOnly: false,
|
|
1678
|
+
read: true,
|
|
1679
|
+
stat: true,
|
|
1680
|
+
realpath: true,
|
|
1681
|
+
access: true,
|
|
1682
|
+
readdir: false,
|
|
1683
|
+
write: true,
|
|
1684
|
+
append: true,
|
|
1685
|
+
exclusiveCreate: true,
|
|
1686
|
+
streamingRead: true,
|
|
1687
|
+
retainedRead: true,
|
|
1688
|
+
streamingWrite: true,
|
|
1689
|
+
streamingAppend: true,
|
|
1690
|
+
copy: true,
|
|
1691
|
+
exclusiveCopy: true,
|
|
1692
|
+
remove: false,
|
|
1693
|
+
removeDirectory: false,
|
|
1694
|
+
recursiveRemove: false,
|
|
1695
|
+
rename: false,
|
|
1696
|
+
mkdir: false,
|
|
1697
|
+
recursiveMkdir: false,
|
|
1698
|
+
symlinks: false,
|
|
1699
|
+
hardlinks: false,
|
|
1700
|
+
readlink: false,
|
|
1701
|
+
permissions: false,
|
|
1702
|
+
timestamps: false,
|
|
1703
|
+
truncate: false,
|
|
1704
|
+
randomAccessWrite: false,
|
|
1705
|
+
atomicRename: false,
|
|
1706
|
+
atomicRenameNoReplace: false,
|
|
1707
|
+
descriptorWriteStream: true
|
|
1708
|
+
});
|
|
1709
|
+
function globalCapabilities(filesystem) {
|
|
1710
|
+
const capabilities = { readOnly: false };
|
|
1711
|
+
const optional = {
|
|
1712
|
+
streamingRead: ["readStream"],
|
|
1713
|
+
streamingWrite: ["writeStream"],
|
|
1714
|
+
retainedRead: ["openReadFile"],
|
|
1715
|
+
streamingAppend: ["writeStream"],
|
|
1716
|
+
descriptorWriteStream: ["writeStream"],
|
|
1717
|
+
symlinks: ["symlink", "readlink"],
|
|
1718
|
+
hardlinks: ["link"],
|
|
1719
|
+
permissions: ["chmod"],
|
|
1720
|
+
timestamps: ["utimes"],
|
|
1721
|
+
readlink: ["readlink"],
|
|
1722
|
+
truncate: ["truncate"],
|
|
1723
|
+
removeDirectory: ["rmdir"]
|
|
1724
|
+
};
|
|
1725
|
+
for (const key of /* @__PURE__ */ new Set([...Object.keys(filesystem.capabilities), ...Object.keys(deviceCapabilities)])) {
|
|
1726
|
+
if (key === "readOnly") continue;
|
|
1727
|
+
Object.defineProperty(capabilities, key, { enumerable: true, get() {
|
|
1728
|
+
if (key === "copy" || key === "exclusiveCopy") return void 0;
|
|
1729
|
+
let declared = filesystem.capabilities[key];
|
|
1730
|
+
if (declared === true && optional[key]?.some((method) => typeof filesystem[method] !== "function")) declared = false;
|
|
1731
|
+
if (key === "descriptorWriteStream" && filesystem.capabilities.streamingWrite === false) declared = false;
|
|
1732
|
+
return declared === deviceCapabilities[key] ? declared : void 0;
|
|
1733
|
+
} });
|
|
1734
|
+
}
|
|
1735
|
+
return Object.freeze(capabilities);
|
|
1736
|
+
}
|
|
1737
|
+
function reserved(path) {
|
|
1738
|
+
return path === "/" || path === deviceDirectory || path === nullPath;
|
|
1739
|
+
}
|
|
1740
|
+
function nonnegative(value, path) {
|
|
1741
|
+
if (value !== void 0 && (!Number.isSafeInteger(value) || value < 0)) throw new FsError("EINVAL", { path });
|
|
1742
|
+
}
|
|
1743
|
+
var DeviceFileSystem = class {
|
|
1744
|
+
#filesystem;
|
|
1745
|
+
capabilities;
|
|
1746
|
+
#nullStat;
|
|
1747
|
+
#directoryStat;
|
|
1748
|
+
constructor(filesystem) {
|
|
1749
|
+
this.#filesystem = filesystem;
|
|
1750
|
+
this.capabilities = globalCapabilities(filesystem);
|
|
1751
|
+
const identityScope = Object.freeze({});
|
|
1752
|
+
this.#nullStat = Object.freeze({
|
|
1753
|
+
type: "character",
|
|
1754
|
+
mode: 8630,
|
|
1755
|
+
size: 0,
|
|
1756
|
+
allocatedBytes: 0,
|
|
1757
|
+
mtimeMs: 0,
|
|
1758
|
+
atimeMs: 0,
|
|
1759
|
+
ctimeMs: 0,
|
|
1760
|
+
birthtimeMs: 0,
|
|
1761
|
+
identityScope,
|
|
1762
|
+
ino: 1,
|
|
1763
|
+
dev: 0,
|
|
1764
|
+
nlink: 1
|
|
1765
|
+
});
|
|
1766
|
+
this.#directoryStat = Object.freeze({ ...this.#nullStat, type: "directory", mode: 16877, ino: 2 });
|
|
1767
|
+
const methods = /* @__PURE__ */ new Map();
|
|
1768
|
+
const view = new Proxy(this, {
|
|
1769
|
+
set: (_target, property, value) => Reflect.set(filesystem, property, value, filesystem),
|
|
1770
|
+
get(target, property) {
|
|
1771
|
+
const value = Reflect.get(target, property, target);
|
|
1772
|
+
if (typeof value !== "function" || property === "constructor") return value;
|
|
1773
|
+
const backing = Reflect.get(filesystem, property, filesystem);
|
|
1774
|
+
const cached = methods.get(property);
|
|
1775
|
+
if (cached && cached.backing === backing) return cached.bound;
|
|
1776
|
+
const bound = value.bind(target);
|
|
1777
|
+
methods.set(property, { backing, bound });
|
|
1778
|
+
return bound;
|
|
1779
|
+
}
|
|
1780
|
+
});
|
|
1781
|
+
for (const identity of [this, view]) registerEntryView(identity, async (path, options) => {
|
|
1782
|
+
const resolved = await this.#resolve(path, options);
|
|
1783
|
+
if (resolved === nullPath || resolved === deviceDirectory) return {
|
|
1784
|
+
filesystem: this,
|
|
1785
|
+
path: resolved,
|
|
1786
|
+
stat: resolved === nullPath ? this.#nullStat : this.#directoryStat,
|
|
1787
|
+
readOnly: false
|
|
1788
|
+
};
|
|
1789
|
+
return { filesystem, path };
|
|
1790
|
+
});
|
|
1791
|
+
return view;
|
|
1792
|
+
}
|
|
1793
|
+
#resolve(path, options, followFinal = true) {
|
|
1794
|
+
return resolveDevicePath(this.#filesystem, path, options, followFinal);
|
|
1795
|
+
}
|
|
1796
|
+
async #mutable(path, options, followFinal = true) {
|
|
1797
|
+
if (reserved(await this.#resolve(path, options, followFinal))) throw new FsError("EBUSY", { path });
|
|
1798
|
+
}
|
|
1799
|
+
async #writeTarget(path, options) {
|
|
1800
|
+
const resolved = await this.#resolve(path, options);
|
|
1801
|
+
if (resolved === nullPath) {
|
|
1802
|
+
if (options.flag === "wx" || options.flag === "ax") throw new FsError("EEXIST", { path });
|
|
1803
|
+
if (options.flag !== void 0 && options.flag !== "w" && options.flag !== "a") throw new FsError("EINVAL", { path });
|
|
1804
|
+
return true;
|
|
1805
|
+
}
|
|
1806
|
+
if (resolved === "/" || resolved === deviceDirectory) throw new FsError("EISDIR", { path });
|
|
1807
|
+
return false;
|
|
1808
|
+
}
|
|
1809
|
+
canonicalizeMissingTarget(path, options = {}) {
|
|
1810
|
+
options.signal?.throwIfAborted();
|
|
1811
|
+
const resolved = lexicalDevicePath(path);
|
|
1812
|
+
return reserved(resolved) ? resolved : this.#filesystem.canonicalizeMissingTarget?.(path, options);
|
|
1813
|
+
}
|
|
1814
|
+
async capabilitiesFor(path, options = {}) {
|
|
1815
|
+
const resolved = await this.#resolve(path, options);
|
|
1816
|
+
if (resolved === nullPath) return deviceCapabilities;
|
|
1817
|
+
if (resolved === deviceDirectory) return {
|
|
1818
|
+
...deviceCapabilities,
|
|
1819
|
+
readdir: true,
|
|
1820
|
+
write: false,
|
|
1821
|
+
append: false,
|
|
1822
|
+
exclusiveCreate: false,
|
|
1823
|
+
streamingWrite: false,
|
|
1824
|
+
streamingAppend: false,
|
|
1825
|
+
descriptorWriteStream: false,
|
|
1826
|
+
retainedRead: false,
|
|
1827
|
+
streamingRead: false,
|
|
1828
|
+
copy: false,
|
|
1829
|
+
exclusiveCopy: false
|
|
1830
|
+
};
|
|
1831
|
+
const capabilities = await this.#filesystem.capabilitiesFor?.(path, options) ?? this.#filesystem.capabilities;
|
|
1832
|
+
const unavailable = {};
|
|
1833
|
+
if (typeof this.#filesystem.readStream !== "function") unavailable.streamingRead = false;
|
|
1834
|
+
if (typeof this.#filesystem.writeStream !== "function") {
|
|
1835
|
+
unavailable.streamingWrite = false;
|
|
1836
|
+
unavailable.streamingAppend = false;
|
|
1837
|
+
unavailable.descriptorWriteStream = false;
|
|
1838
|
+
}
|
|
1839
|
+
if (typeof this.#filesystem.openReadFile !== "function") unavailable.retainedRead = false;
|
|
1840
|
+
return Object.keys(unavailable).some((key) => capabilities[key] !== false) ? { ...capabilities, ...unavailable } : capabilities;
|
|
1841
|
+
}
|
|
1842
|
+
async stat(path, options = {}) {
|
|
1843
|
+
const resolved = await this.#resolve(path, options);
|
|
1844
|
+
if (resolved === nullPath) return { ...this.#nullStat };
|
|
1845
|
+
if (resolved === deviceDirectory) return { ...this.#directoryStat };
|
|
1846
|
+
return this.#filesystem.stat(path, options);
|
|
1847
|
+
}
|
|
1848
|
+
async lstat(path, options = {}) {
|
|
1849
|
+
const resolved = await this.#resolve(path, options, false);
|
|
1850
|
+
if (resolved === nullPath) return { ...this.#nullStat };
|
|
1851
|
+
if (resolved === deviceDirectory) return { ...this.#directoryStat };
|
|
1852
|
+
return this.#filesystem.lstat(path, options);
|
|
1853
|
+
}
|
|
1854
|
+
compareEntry(path, peer, peerPath, options = {}) {
|
|
1855
|
+
return compareEntries(this, path, peer, peerPath, options);
|
|
1856
|
+
}
|
|
1857
|
+
async realpath(path, options = {}) {
|
|
1858
|
+
const resolved = await this.#resolve(path, options);
|
|
1859
|
+
return reserved(resolved) ? resolved : this.#filesystem.realpath(path, options);
|
|
1860
|
+
}
|
|
1861
|
+
async readFile(path, options = {}) {
|
|
1862
|
+
const resolved = await this.#resolve(path, options);
|
|
1863
|
+
if (resolved === nullPath) {
|
|
1864
|
+
nonnegative(options.maxBytes, path);
|
|
1865
|
+
return new Uint8Array();
|
|
1866
|
+
}
|
|
1867
|
+
if (resolved === deviceDirectory) throw new FsError("EISDIR", { path });
|
|
1868
|
+
return this.#filesystem.readFile(path, options);
|
|
1869
|
+
}
|
|
1870
|
+
readStream(path, options = {}) {
|
|
1871
|
+
return deviceReadStream(async () => {
|
|
1872
|
+
const resolved = await this.#resolve(path, options);
|
|
1873
|
+
if (resolved === nullPath) {
|
|
1874
|
+
nonnegative(options.start, path);
|
|
1875
|
+
nonnegative(options.endExclusive, path);
|
|
1876
|
+
nonnegative(options.chunkSize, path);
|
|
1877
|
+
if (options.chunkSize === 0 || options.endExclusive !== void 0 && options.endExclusive < (options.start ?? 0)) throw new FsError("EINVAL", { path });
|
|
1878
|
+
return { [Symbol.asyncIterator]: () => ({ next: async () => ({ done: true, value: void 0 }) }) };
|
|
1879
|
+
}
|
|
1880
|
+
if (resolved === deviceDirectory) throw new FsError("EISDIR", { path });
|
|
1881
|
+
if (!this.#filesystem.readStream) throw new FsError("ENOTSUP", { path });
|
|
1882
|
+
return this.#filesystem.readStream(path, options);
|
|
1883
|
+
});
|
|
1884
|
+
}
|
|
1885
|
+
async openReadFile(path, options = {}) {
|
|
1886
|
+
const resolved = await this.#resolve(path, options);
|
|
1887
|
+
if (resolved !== nullPath) {
|
|
1888
|
+
if (resolved === deviceDirectory) throw new FsError("EISDIR", { path });
|
|
1889
|
+
if (!this.#filesystem.openReadFile) throw new FsError("ENOTSUP", { path });
|
|
1890
|
+
return this.#filesystem.openReadFile(path, options);
|
|
1891
|
+
}
|
|
1892
|
+
const stat = this.#nullStat;
|
|
1893
|
+
let closed = false;
|
|
1894
|
+
const check = (settings) => {
|
|
1895
|
+
settings.signal?.throwIfAborted();
|
|
1896
|
+
if (closed) throw new FsError("EBADF", { path });
|
|
1897
|
+
};
|
|
1898
|
+
return {
|
|
1899
|
+
async stat(settings = {}) {
|
|
1900
|
+
check(settings);
|
|
1901
|
+
return { ...stat };
|
|
1902
|
+
},
|
|
1903
|
+
async read(position, maxBytes, settings = {}) {
|
|
1904
|
+
check(settings);
|
|
1905
|
+
nonnegative(position, path);
|
|
1906
|
+
nonnegative(maxBytes, path);
|
|
1907
|
+
return new Uint8Array();
|
|
1908
|
+
},
|
|
1909
|
+
async close() {
|
|
1910
|
+
closed = true;
|
|
1911
|
+
}
|
|
1912
|
+
};
|
|
1913
|
+
}
|
|
1914
|
+
async writeFile(path, data, options = {}) {
|
|
1915
|
+
if (await this.#writeTarget(path, options)) {
|
|
1916
|
+
if (!(data instanceof Uint8Array)) throw new TypeError("File data must be Uint8Array");
|
|
1917
|
+
return;
|
|
1918
|
+
}
|
|
1919
|
+
await this.#filesystem.writeFile(path, data, options);
|
|
1920
|
+
}
|
|
1921
|
+
async appendFile(path, data, options = {}) {
|
|
1922
|
+
if (await this.#writeTarget(path, options)) {
|
|
1923
|
+
if (!(data instanceof Uint8Array)) throw new TypeError("File data must be Uint8Array");
|
|
1924
|
+
return;
|
|
1925
|
+
}
|
|
1926
|
+
await this.#filesystem.appendFile(path, data, options);
|
|
1927
|
+
}
|
|
1928
|
+
async writeStream(path, source, options = {}) {
|
|
1929
|
+
if (await this.#writeTarget(path, options)) return drainDeviceInput(source, options.signal);
|
|
1930
|
+
if (!this.#filesystem.writeStream) throw new FsError("ENOTSUP", { path });
|
|
1931
|
+
await this.#filesystem.writeStream(path, source, options);
|
|
1932
|
+
}
|
|
1933
|
+
async readdir(path, options = {}) {
|
|
1934
|
+
const resolved = await this.#resolve(path, options);
|
|
1935
|
+
if (resolved === nullPath) throw new FsError("ENOTDIR", { path });
|
|
1936
|
+
if (resolved !== "/" && resolved !== deviceDirectory) return this.#filesystem.readdir(path, options);
|
|
1937
|
+
const limit = directoryEntryLimit(options, path);
|
|
1938
|
+
let entries2;
|
|
1939
|
+
try {
|
|
1940
|
+
entries2 = await this.#filesystem.readdir(resolved, options);
|
|
1941
|
+
} catch (error) {
|
|
1942
|
+
options.signal?.throwIfAborted();
|
|
1943
|
+
if (!isFsError(error, "ENOENT") && !isFsError(error, "ENOTDIR")) throw error;
|
|
1944
|
+
entries2 = [];
|
|
1945
|
+
}
|
|
1946
|
+
options.signal?.throwIfAborted();
|
|
1947
|
+
const merged = /* @__PURE__ */ new Map();
|
|
1948
|
+
for (const entry of entries2) {
|
|
1949
|
+
if (entry.name === "." || entry.name === "..") continue;
|
|
1950
|
+
if (!entry.name || entry.name.includes("/") || entry.name.includes("\0")) throw new FsError("EIO", { path, message: "invalid directory entry" });
|
|
1951
|
+
merged.set(entry.name, { name: entry.name, type: entry.type });
|
|
1952
|
+
admitDirectoryEntries(merged.size, limit, path);
|
|
1953
|
+
}
|
|
1954
|
+
const name = resolved === "/" ? "dev" : "null";
|
|
1955
|
+
merged.set(name, { name, type: resolved === "/" ? "directory" : "character" });
|
|
1956
|
+
admitDirectoryEntries(merged.size, limit, path);
|
|
1957
|
+
return [...merged.values()];
|
|
1958
|
+
}
|
|
1959
|
+
async mkdir(path, options = {}) {
|
|
1960
|
+
const resolved = await this.#resolve(path, options);
|
|
1961
|
+
if (reserved(resolved)) {
|
|
1962
|
+
if (resolved !== nullPath && options.recursive) return;
|
|
1963
|
+
throw new FsError("EEXIST", { path });
|
|
1964
|
+
}
|
|
1965
|
+
await this.#filesystem.mkdir(path, options);
|
|
1966
|
+
}
|
|
1967
|
+
async rm(path, options = {}) {
|
|
1968
|
+
await this.#mutable(path, options, false);
|
|
1969
|
+
await this.#filesystem.rm(path, options);
|
|
1970
|
+
}
|
|
1971
|
+
async rmdir(path, options = {}) {
|
|
1972
|
+
const resolved = await this.#resolve(path, options, false);
|
|
1973
|
+
if (resolved === nullPath) throw new FsError("ENOTDIR", { path });
|
|
1974
|
+
if (reserved(resolved)) throw new FsError("EBUSY", { path });
|
|
1975
|
+
if (!this.#filesystem.rmdir) throw new FsError("ENOTSUP", { path });
|
|
1976
|
+
await this.#filesystem.rmdir(path, options);
|
|
1977
|
+
}
|
|
1978
|
+
async rename(source, destination, options = {}) {
|
|
1979
|
+
await this.#mutable(source, options, false);
|
|
1980
|
+
await this.#mutable(destination, options, false);
|
|
1981
|
+
if (options.noReplace) {
|
|
1982
|
+
const capabilities = await this.#filesystem.capabilitiesFor?.(destination, options) ?? this.#filesystem.capabilities;
|
|
1983
|
+
options.signal?.throwIfAborted();
|
|
1984
|
+
if (capabilities.atomicRenameNoReplace !== true) throw new FsError("ENOTSUP", { syscall: "rename", path: source, dest: destination });
|
|
1985
|
+
}
|
|
1986
|
+
await this.#filesystem.rename(source, destination, options);
|
|
1987
|
+
}
|
|
1988
|
+
async copyFile(source, destination, options = {}) {
|
|
1989
|
+
const target = await this.#resolve(destination, options);
|
|
1990
|
+
if (target === nullPath && options.exclusive) throw new FsError("EEXIST", { path: destination });
|
|
1991
|
+
const origin = await this.#resolve(source, options);
|
|
1992
|
+
if (target !== nullPath && origin !== nullPath) {
|
|
1993
|
+
if (target === "/" || target === deviceDirectory) throw new FsError("EISDIR", { path: destination });
|
|
1994
|
+
await this.#filesystem.copyFile(source, destination, options);
|
|
1995
|
+
return;
|
|
1996
|
+
}
|
|
1997
|
+
if (target === nullPath) {
|
|
1998
|
+
if (origin === nullPath) return;
|
|
1999
|
+
if (origin === "/" || origin === deviceDirectory) throw new FsError("EISDIR", { path: source });
|
|
2000
|
+
const capabilities = await this.capabilitiesFor(source, options);
|
|
2001
|
+
if (this.#filesystem.readStream && capabilities.streamingRead !== false) {
|
|
2002
|
+
await drainDeviceInput(this.#filesystem.readStream(source, options), options.signal);
|
|
2003
|
+
} else if (this.#filesystem.openReadFile && capabilities.retainedRead !== false) {
|
|
2004
|
+
await drainDeviceFile(await this.#filesystem.openReadFile(source, options), options.signal);
|
|
2005
|
+
} else throw new FsError("ENOTSUP", { path: source });
|
|
2006
|
+
return;
|
|
2007
|
+
}
|
|
2008
|
+
if (reserved(target)) throw new FsError("EISDIR", { path: destination });
|
|
2009
|
+
await this.#filesystem.writeFile(destination, new Uint8Array(), { ...options, flag: options.exclusive ? "wx" : "w" });
|
|
2010
|
+
}
|
|
2011
|
+
async access(path, mode2 = 0, options = {}) {
|
|
2012
|
+
const resolved = await this.#resolve(path, options);
|
|
2013
|
+
if (resolved === nullPath || resolved === deviceDirectory) {
|
|
2014
|
+
if (!Number.isInteger(mode2) || mode2 < 0 || mode2 > 7) throw new FsError("EINVAL", { path });
|
|
2015
|
+
if (resolved === nullPath && mode2 & 1 || resolved === deviceDirectory && mode2 & 2) throw new FsError("EACCES", { path });
|
|
2016
|
+
return;
|
|
2017
|
+
}
|
|
2018
|
+
await this.#filesystem.access(path, mode2, options);
|
|
2019
|
+
}
|
|
2020
|
+
async readlink(path, options = {}) {
|
|
2021
|
+
if (reserved(await this.#resolve(path, options, false))) throw new FsError("EINVAL", { path });
|
|
2022
|
+
if (!this.#filesystem.readlink) throw new FsError("ENOTSUP", { path });
|
|
2023
|
+
return this.#filesystem.readlink(path, options);
|
|
2024
|
+
}
|
|
2025
|
+
async symlink(target, path, options = {}) {
|
|
2026
|
+
await this.#mutable(path, options, false);
|
|
2027
|
+
if (!this.#filesystem.symlink) throw new FsError("ENOTSUP", { path });
|
|
2028
|
+
await this.#filesystem.symlink(target, path, options);
|
|
2029
|
+
}
|
|
2030
|
+
async link(existingPath, newPath, options = {}) {
|
|
2031
|
+
await this.#mutable(existingPath, options, false);
|
|
2032
|
+
await this.#mutable(newPath, options, false);
|
|
2033
|
+
if (!this.#filesystem.link) throw new FsError("ENOTSUP", { path: newPath });
|
|
2034
|
+
await this.#filesystem.link(existingPath, newPath, options);
|
|
2035
|
+
}
|
|
2036
|
+
async chmod(path, mode2, options = {}) {
|
|
2037
|
+
await this.#mutable(path, options);
|
|
2038
|
+
if (!this.#filesystem.chmod) throw new FsError("ENOTSUP", { path });
|
|
2039
|
+
await this.#filesystem.chmod(path, mode2, options);
|
|
2040
|
+
}
|
|
2041
|
+
async utimes(path, atimeMs, mtimeMs, options = {}) {
|
|
2042
|
+
await this.#mutable(path, options);
|
|
2043
|
+
if (!this.#filesystem.utimes) throw new FsError("ENOTSUP", { path });
|
|
2044
|
+
await this.#filesystem.utimes(path, atimeMs, mtimeMs, options);
|
|
2045
|
+
}
|
|
2046
|
+
async truncate(path, length, options = {}) {
|
|
2047
|
+
await this.#mutable(path, options);
|
|
2048
|
+
if (!this.#filesystem.truncate) throw new FsError("ENOTSUP", { path });
|
|
2049
|
+
await this.#filesystem.truncate(path, length, options);
|
|
2050
|
+
}
|
|
2051
|
+
};
|
|
2052
|
+
function createDeviceFileSystem(filesystem) {
|
|
2053
|
+
if (filesystem instanceof DeviceFileSystem) return filesystem;
|
|
2054
|
+
let view = views.get(filesystem);
|
|
2055
|
+
if (!view) {
|
|
2056
|
+
view = new DeviceFileSystem(filesystem);
|
|
2057
|
+
views.set(filesystem, view);
|
|
2058
|
+
}
|
|
2059
|
+
return view;
|
|
2060
|
+
}
|
|
2061
|
+
|
|
1492
2062
|
// packages/safe-fs/src/fs/capabilities.ts
|
|
1493
2063
|
function retainedReadCapabilities(filesystem, capabilities = filesystem.capabilities) {
|
|
1494
2064
|
return typeof filesystem.openReadFile === "function" ? capabilities : { ...capabilities, retainedRead: false };
|
|
@@ -1549,6 +2119,7 @@ function readOnlyCapabilities(capabilities) {
|
|
|
1549
2119
|
timestamps: false,
|
|
1550
2120
|
descriptorWriteStream: false,
|
|
1551
2121
|
atomicRename: false,
|
|
2122
|
+
atomicRenameNoReplace: false,
|
|
1552
2123
|
streamingWrite: false
|
|
1553
2124
|
});
|
|
1554
2125
|
}
|
|
@@ -1804,7 +2375,7 @@ var MountFileSystem = class _MountFileSystem {
|
|
|
1804
2375
|
if (capability === "descriptorWriteStream" && backend.capabilities.streamingWrite === false) return false;
|
|
1805
2376
|
return declared === true && optional[capability]?.some((method) => typeof backend[method] !== "function") ? false : declared;
|
|
1806
2377
|
});
|
|
1807
|
-
if (["rename", "copy", "exclusiveCopy"].includes(capability) && mounts.length > 1) return void 0;
|
|
2378
|
+
if (["rename", "atomicRenameNoReplace", "copy", "exclusiveCopy"].includes(capability) && mounts.length > 1) return void 0;
|
|
1808
2379
|
return values.every((value) => value === true) ? true : values.every((value) => value === false) ? false : void 0;
|
|
1809
2380
|
};
|
|
1810
2381
|
const semantics = Object.fromEntries([
|
|
@@ -1824,6 +2395,7 @@ var MountFileSystem = class _MountFileSystem {
|
|
|
1824
2395
|
"removeDirectory",
|
|
1825
2396
|
"recursiveRemove",
|
|
1826
2397
|
"rename",
|
|
2398
|
+
"atomicRenameNoReplace",
|
|
1827
2399
|
"copy",
|
|
1828
2400
|
"exclusiveCopy",
|
|
1829
2401
|
"readlink",
|
|
@@ -2137,6 +2709,11 @@ var MountFileSystem = class _MountFileSystem {
|
|
|
2137
2709
|
this.mutable(target);
|
|
2138
2710
|
this.entryPath(source);
|
|
2139
2711
|
this.entryPath(destination);
|
|
2712
|
+
if (options.noReplace) {
|
|
2713
|
+
const capabilities = await target.mount.backend.capabilitiesFor?.(target.local, options) ?? target.mount.backend.capabilities;
|
|
2714
|
+
options.signal?.throwIfAborted();
|
|
2715
|
+
if (capabilities.atomicRenameNoReplace !== true) fail("ENOTSUP");
|
|
2716
|
+
}
|
|
2140
2717
|
await origin.mount.backend.rename(origin.local, target.local, options);
|
|
2141
2718
|
}, destination);
|
|
2142
2719
|
}
|
|
@@ -2400,6 +2977,7 @@ var OverlayFileSystem = class {
|
|
|
2400
2977
|
...upper.readOnly === void 0 ? {} : { readOnly: upper.readOnly },
|
|
2401
2978
|
...effectiveAppend === void 0 ? {} : { append: effectiveAppend },
|
|
2402
2979
|
atomicRename: false,
|
|
2980
|
+
atomicRenameNoReplace: false,
|
|
2403
2981
|
descriptorWriteStream: false,
|
|
2404
2982
|
hardlinks: false,
|
|
2405
2983
|
symlinks: writable && this.#upper.capabilities.symlinks === true && typeof this.#upper.symlink === "function" && typeof this.#upper.readlink === "function" && (this.#lower.capabilities.symlinks !== true || typeof this.#lower.readlink === "function"),
|
|
@@ -2906,6 +3484,7 @@ var OverlayFileSystem = class {
|
|
|
2906
3484
|
}
|
|
2907
3485
|
async rename(source, destination, options = {}) {
|
|
2908
3486
|
return this.run(options, async () => {
|
|
3487
|
+
if (options.noReplace) fail2("ENOTSUP", source, "atomic no-replace rename is unsupported");
|
|
2909
3488
|
this.writable(source);
|
|
2910
3489
|
const original = await this.required(source, options, false);
|
|
2911
3490
|
const target = await this.resolve(destination, options, false, true);
|
|
@@ -3233,6 +3812,15 @@ function withFileSystemQuota(fs, options) {
|
|
|
3233
3812
|
await fs.appendFile(path, data, appendOptions);
|
|
3234
3813
|
});
|
|
3235
3814
|
},
|
|
3815
|
+
async rename(source, destination, renameOptions) {
|
|
3816
|
+
if (renameOptions?.noReplace) {
|
|
3817
|
+
renameOptions.signal?.throwIfAborted();
|
|
3818
|
+
const capabilities = await fs.capabilitiesFor?.(destination, renameOptions) ?? fs.capabilities;
|
|
3819
|
+
renameOptions?.signal?.throwIfAborted();
|
|
3820
|
+
if (capabilities.atomicRenameNoReplace !== true) throw new FsError("ENOTSUP", { syscall: "rename", path: source, dest: destination });
|
|
3821
|
+
}
|
|
3822
|
+
await fs.rename(source, destination, renameOptions);
|
|
3823
|
+
},
|
|
3236
3824
|
copyFile(source, destination, copyOptions) {
|
|
3237
3825
|
return mutate(async () => {
|
|
3238
3826
|
await assertDelta(destination, (await fs.stat(source, copyOptions)).size, copyOptions);
|
|
@@ -3388,6 +3976,17 @@ function scopeFileSystem(filesystem, charge, signal) {
|
|
|
3388
3976
|
const peer = args[1];
|
|
3389
3977
|
args[1] = originals.get(peer) ?? peer;
|
|
3390
3978
|
}
|
|
3979
|
+
if (property === "rename" && args[2]?.noReplace) return (async () => {
|
|
3980
|
+
const options = args[2];
|
|
3981
|
+
const capabilities = await original.capabilitiesFor?.(args[1], options) ?? original.capabilities;
|
|
3982
|
+
assertOpen(options);
|
|
3983
|
+
if (capabilities.atomicRenameNoReplace !== true) throw new FsError("ENOTSUP", {
|
|
3984
|
+
syscall: "rename",
|
|
3985
|
+
path: args[0],
|
|
3986
|
+
dest: args[1]
|
|
3987
|
+
});
|
|
3988
|
+
return Reflect.apply(method, original, args);
|
|
3989
|
+
})();
|
|
3391
3990
|
return Reflect.apply(method, original, args);
|
|
3392
3991
|
};
|
|
3393
3992
|
const scoped = property === "openReadFile" ? async (...args) => wrapHandle(await dispatch(...args)) : property === "readStream" ? (...args) => wrapStream(dispatch(...args), args[1]) : operations.has(property) && property !== "canonicalizeMissingTarget" ? async (...args) => dispatch(...args) : dispatch;
|
|
@@ -3772,6 +4371,7 @@ var WebDavFileSystem = class {
|
|
|
3772
4371
|
remove: true,
|
|
3773
4372
|
recursiveRemove: true,
|
|
3774
4373
|
rename: true,
|
|
4374
|
+
atomicRenameNoReplace: false,
|
|
3775
4375
|
copy: true,
|
|
3776
4376
|
exclusiveCopy: true,
|
|
3777
4377
|
readlink: false,
|
|
@@ -4710,6 +5310,10 @@ var WebDavFileSystem = class {
|
|
|
4710
5310
|
}
|
|
4711
5311
|
}
|
|
4712
5312
|
async rename(source, destination, options = {}) {
|
|
5313
|
+
if (options.noReplace) {
|
|
5314
|
+
options.signal?.throwIfAborted();
|
|
5315
|
+
fail3("ENOTSUP", "rename", source, "atomic no-replace rename is unsupported");
|
|
5316
|
+
}
|
|
4713
5317
|
await this.transfer("MOVE", source, destination, options);
|
|
4714
5318
|
}
|
|
4715
5319
|
async copyFile(source, destination, options = {}) {
|
|
@@ -4793,7 +5397,7 @@ function predicates(type) {
|
|
|
4793
5397
|
isDirectory: () => type === "directory",
|
|
4794
5398
|
isSymbolicLink: () => type === "symlink",
|
|
4795
5399
|
isBlockDevice: () => false,
|
|
4796
|
-
isCharacterDevice: () =>
|
|
5400
|
+
isCharacterDevice: () => type === "character",
|
|
4797
5401
|
isFIFO: () => false,
|
|
4798
5402
|
isSocket: () => false
|
|
4799
5403
|
};
|
|
@@ -4802,7 +5406,7 @@ function bridgeStats(stat) {
|
|
|
4802
5406
|
return {
|
|
4803
5407
|
dev: stat.dev ?? 0,
|
|
4804
5408
|
ino: stat.ino ?? 0,
|
|
4805
|
-
mode: stat.mode & 4095 | (stat.type === "directory" ? 16384 : stat.type === "symlink" ? 40960 : 32768),
|
|
5409
|
+
mode: stat.mode & 4095 | (stat.type === "directory" ? 16384 : stat.type === "symlink" ? 40960 : stat.type === "character" ? 8192 : 32768),
|
|
4806
5410
|
nlink: stat.nlink ?? 1,
|
|
4807
5411
|
uid: stat.uid ?? 0,
|
|
4808
5412
|
gid: stat.gid ?? 0,
|
|
@@ -5422,6 +6026,8 @@ export {
|
|
|
5422
6026
|
defaultMemoryFileSystemLimits,
|
|
5423
6027
|
MemoryFileSystem,
|
|
5424
6028
|
createMemoryFileSystem,
|
|
6029
|
+
DeviceFileSystem,
|
|
6030
|
+
createDeviceFileSystem,
|
|
5425
6031
|
ReadOnlyFileSystem,
|
|
5426
6032
|
createReadOnlyFileSystem,
|
|
5427
6033
|
MountFileSystem,
|
|
@@ -5434,4 +6040,4 @@ export {
|
|
|
5434
6040
|
WebDavFileSystem,
|
|
5435
6041
|
createFsBridge
|
|
5436
6042
|
};
|
|
5437
|
-
//# sourceMappingURL=chunk-
|
|
6043
|
+
//# sourceMappingURL=chunk-QK4IEGRO.js.map
|