@poe-platform/safe-fs 0.1.0

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.
Files changed (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +290 -0
  3. package/dist/safe-fs/bridge/confinement.d.ts +3 -0
  4. package/dist/safe-fs/bridge/confinement.js +171 -0
  5. package/dist/safe-fs/bridge/filesystem.d.ts +88 -0
  6. package/dist/safe-fs/bridge/filesystem.js +411 -0
  7. package/dist/safe-fs/bridge/index.d.ts +6 -0
  8. package/dist/safe-fs/bridge/index.js +18 -0
  9. package/dist/safe-fs/bridge/stats.d.ts +4 -0
  10. package/dist/safe-fs/bridge/stats.js +37 -0
  11. package/dist/safe-fs/bridge/types.d.ts +75 -0
  12. package/dist/safe-fs/bridge/types.js +1 -0
  13. package/dist/safe-fs/bridge/values.d.ts +6 -0
  14. package/dist/safe-fs/bridge/values.js +65 -0
  15. package/dist/safe-fs/config/memory.d.ts +3 -0
  16. package/dist/safe-fs/config/memory.js +9 -0
  17. package/dist/safe-fs/config/real.d.ts +5 -0
  18. package/dist/safe-fs/config/real.js +16 -0
  19. package/dist/safe-fs/config.d.ts +15 -0
  20. package/dist/safe-fs/config.js +46 -0
  21. package/dist/safe-fs/config.node.d.ts +2 -0
  22. package/dist/safe-fs/config.node.js +22 -0
  23. package/dist/safe-fs/contracts/abort.d.ts +5 -0
  24. package/dist/safe-fs/contracts/abort.js +34 -0
  25. package/dist/safe-fs/contracts/cleanup.d.ts +1 -0
  26. package/dist/safe-fs/contracts/cleanup.js +9 -0
  27. package/dist/safe-fs/contracts/errors.d.ts +50 -0
  28. package/dist/safe-fs/contracts/errors.js +77 -0
  29. package/dist/safe-fs/contracts/filesystem.d.ts +96 -0
  30. package/dist/safe-fs/contracts/filesystem.js +1 -0
  31. package/dist/safe-fs/contracts/index.d.ts +4 -0
  32. package/dist/safe-fs/contracts/index.js +4 -0
  33. package/dist/safe-fs/contracts/io.d.ts +8 -0
  34. package/dist/safe-fs/contracts/io.js +92 -0
  35. package/dist/safe-fs/contracts/path.d.ts +8 -0
  36. package/dist/safe-fs/contracts/path.js +8 -0
  37. package/dist/safe-fs/contracts/portable-path.d.ts +13 -0
  38. package/dist/safe-fs/contracts/portable-path.js +57 -0
  39. package/dist/safe-fs/contracts/virtual-path.d.ts +7 -0
  40. package/dist/safe-fs/contracts/virtual-path.js +66 -0
  41. package/dist/safe-fs/core.d.ts +12 -0
  42. package/dist/safe-fs/core.js +12 -0
  43. package/dist/safe-fs/fs/memory/index.d.ts +58 -0
  44. package/dist/safe-fs/fs/memory/index.js +532 -0
  45. package/dist/safe-fs/fs/mount/comparison.d.ts +19 -0
  46. package/dist/safe-fs/fs/mount/comparison.js +118 -0
  47. package/dist/safe-fs/fs/mount/identity.d.ts +2 -0
  48. package/dist/safe-fs/fs/mount/identity.js +12 -0
  49. package/dist/safe-fs/fs/mount/index.d.ts +44 -0
  50. package/dist/safe-fs/fs/mount/index.js +546 -0
  51. package/dist/safe-fs/fs/overlay/index.d.ts +73 -0
  52. package/dist/safe-fs/fs/overlay/index.js +927 -0
  53. package/dist/safe-fs/fs/readonly/index.d.ts +31 -0
  54. package/dist/safe-fs/fs/readonly/index.js +128 -0
  55. package/dist/safe-fs/fs/real/allocation.d.ts +1 -0
  56. package/dist/safe-fs/fs/real/allocation.js +8 -0
  57. package/dist/safe-fs/fs/real/index.d.ts +76 -0
  58. package/dist/safe-fs/fs/real/index.js +543 -0
  59. package/dist/safe-fs/fs/s3/authority.d.ts +7 -0
  60. package/dist/safe-fs/fs/s3/authority.js +31 -0
  61. package/dist/safe-fs/fs/s3/filesystem.d.ts +93 -0
  62. package/dist/safe-fs/fs/s3/filesystem.js +1024 -0
  63. package/dist/safe-fs/fs/s3/http/index.d.ts +2 -0
  64. package/dist/safe-fs/fs/s3/http/index.js +1 -0
  65. package/dist/safe-fs/fs/s3/http/request.d.ts +16 -0
  66. package/dist/safe-fs/fs/s3/http/request.js +196 -0
  67. package/dist/safe-fs/fs/s3/http/signature.d.ts +20 -0
  68. package/dist/safe-fs/fs/s3/http/signature.js +74 -0
  69. package/dist/safe-fs/fs/s3/http/transport.d.ts +3 -0
  70. package/dist/safe-fs/fs/s3/http/transport.js +455 -0
  71. package/dist/safe-fs/fs/s3/http/types.d.ts +30 -0
  72. package/dist/safe-fs/fs/s3/http/types.js +1 -0
  73. package/dist/safe-fs/fs/s3/http/xml.d.ts +11 -0
  74. package/dist/safe-fs/fs/s3/http/xml.js +188 -0
  75. package/dist/safe-fs/fs/s3/index.d.ts +6 -0
  76. package/dist/safe-fs/fs/s3/index.js +3 -0
  77. package/dist/safe-fs/fs/s3/mock.d.ts +48 -0
  78. package/dist/safe-fs/fs/s3/mock.js +233 -0
  79. package/dist/safe-fs/fs/s3/registry.d.ts +10 -0
  80. package/dist/safe-fs/fs/s3/registry.js +71 -0
  81. package/dist/safe-fs/fs/s3/transport.d.ts +103 -0
  82. package/dist/safe-fs/fs/s3/transport.js +28 -0
  83. package/dist/safe-fs/fs/webdav/index.d.ts +2 -0
  84. package/dist/safe-fs/fs/webdav/index.js +1 -0
  85. package/dist/safe-fs/fs/webdav/resource-id.d.ts +18 -0
  86. package/dist/safe-fs/fs/webdav/resource-id.js +109 -0
  87. package/dist/safe-fs/fs/webdav/webdav.d.ts +101 -0
  88. package/dist/safe-fs/fs/webdav/webdav.js +1226 -0
  89. package/dist/safe-fs/fs/webdav/xml.d.ts +15 -0
  90. package/dist/safe-fs/fs/webdav/xml.js +250 -0
  91. package/dist/safe-fs/index.d.ts +14 -0
  92. package/dist/safe-fs/index.js +12 -0
  93. package/dist/safe-fs/node/filesystem.d.ts +11 -0
  94. package/dist/safe-fs/node/filesystem.js +28 -0
  95. package/dist/safe-fs/node/index.d.ts +2 -0
  96. package/dist/safe-fs/node/index.js +1 -0
  97. package/dist/safe-fs/node/stats.d.ts +1 -0
  98. package/dist/safe-fs/node/stats.js +1 -0
  99. package/dist/safe-fs/node/values.d.ts +1 -0
  100. package/dist/safe-fs/node/values.js +1 -0
  101. package/dist/safe-fs/node-host.d.ts +1 -0
  102. package/dist/safe-fs/node-host.js +1 -0
  103. package/dist/safe-fs/node-unavailable.d.ts +1 -0
  104. package/dist/safe-fs/node-unavailable.js +1 -0
  105. package/dist/safe-fs/platform/browser.d.ts +12 -0
  106. package/dist/safe-fs/platform/browser.js +39 -0
  107. package/dist/safe-fs/platform/node.d.ts +13 -0
  108. package/dist/safe-fs/platform/node.js +26 -0
  109. package/package.json +108 -0
@@ -0,0 +1,118 @@
1
+ import { comparisonContext, platform } from "#safe-fs-platform";
2
+ import { FsError } from "../../contracts/errors.js";
3
+ import { compareIdentity } from "./identity.js";
4
+ const resolvers = new WeakMap();
5
+ const authorities = new WeakMap();
6
+ export function assertCallbackAuthorityAllowed() {
7
+ if (!platform.callbackAuthorities)
8
+ throw new FsError("ENOTSUP", { message: "custom comparison authorities require Node context" });
9
+ }
10
+ export function registerEntryView(filesystem, resolver) {
11
+ if (resolvers.has(filesystem))
12
+ throw new TypeError("entry view already registered");
13
+ resolvers.set(filesystem, resolver);
14
+ }
15
+ export function registerEntryAuthority(filesystem, authority) {
16
+ if (authorities.has(filesystem))
17
+ throw new TypeError("entry authority already registered");
18
+ authorities.set(filesystem, authority);
19
+ }
20
+ export async function resolveEntryView(filesystem, path, options = {}) {
21
+ let location = { filesystem, path };
22
+ let readOnly = false;
23
+ const visited = new Set();
24
+ for (;;) {
25
+ options.signal?.throwIfAborted();
26
+ if (visited.has(location.filesystem))
27
+ throw new FsError("EIO", { path, message: "cyclic entry view" });
28
+ visited.add(location.filesystem);
29
+ readOnly ||= location.readOnly === true || location.filesystem.capabilities.readOnly === true;
30
+ if (location.stat)
31
+ return { filesystem: location.filesystem, path: location.path, stat: location.stat, readOnly };
32
+ const resolve = resolvers.get(location.filesystem);
33
+ if (!resolve) {
34
+ let stat;
35
+ let followedPath;
36
+ try {
37
+ followedPath = await location.filesystem.realpath(location.path, options);
38
+ options.signal?.throwIfAborted();
39
+ stat = await location.filesystem.lstat(followedPath, options);
40
+ }
41
+ catch (error) {
42
+ options.signal?.throwIfAborted();
43
+ throw error;
44
+ }
45
+ options.signal?.throwIfAborted();
46
+ if (stat.type === "symlink")
47
+ throw new FsError("EIO", { path, message: "followed entry changed during observation" });
48
+ return { filesystem: location.filesystem, path: followedPath, stat, readOnly };
49
+ }
50
+ let next;
51
+ try {
52
+ next = await resolve(location.path, options);
53
+ }
54
+ catch (error) {
55
+ options.signal?.throwIfAborted();
56
+ throw error;
57
+ }
58
+ options.signal?.throwIfAborted();
59
+ if (next.filesystem === location.filesystem && next.stat) {
60
+ return { filesystem: next.filesystem, path: next.path, stat: next.stat, readOnly: readOnly || next.readOnly === true };
61
+ }
62
+ location = next;
63
+ }
64
+ }
65
+ export async function compareResolvedEntries(own, peer, options = {}) {
66
+ options.signal?.throwIfAborted();
67
+ if (comparisonContext.active(options))
68
+ return "unknown";
69
+ const identity = compareIdentity(own.stat, peer.stat);
70
+ if (identity !== "unknown")
71
+ return identity;
72
+ return comparisonContext.run(options, async (options) => {
73
+ const queried = new Set();
74
+ let result = "unknown";
75
+ for (const [left, right] of [[own, peer], [peer, own]]) {
76
+ options.signal?.throwIfAborted();
77
+ const authority = authorities.get(left.filesystem);
78
+ const key = authority ?? left.filesystem;
79
+ if (queried.has(key))
80
+ continue;
81
+ queried.add(key);
82
+ let answer;
83
+ try {
84
+ if (authority)
85
+ answer = await authority(left, right, options);
86
+ else if (left.filesystem.compareEntry) {
87
+ assertCallbackAuthorityAllowed();
88
+ answer = await left.filesystem.compareEntry(left.path, right.filesystem, right.path, options);
89
+ }
90
+ else
91
+ continue;
92
+ }
93
+ catch (error) {
94
+ options.signal?.throwIfAborted();
95
+ throw error;
96
+ }
97
+ options.signal?.throwIfAborted();
98
+ if (answer !== "same" && answer !== "distinct" && answer !== "unknown") {
99
+ throw new FsError("EIO", { path: own.path, dest: peer.path, message: "invalid entry comparison answer" });
100
+ }
101
+ if (answer === "unknown")
102
+ continue;
103
+ if (result !== "unknown" && result !== answer) {
104
+ throw new FsError("EIO", { path: own.path, dest: peer.path, message: "conflicting entry comparison answers" });
105
+ }
106
+ result = answer;
107
+ }
108
+ return result;
109
+ });
110
+ }
111
+ export async function compareEntries(filesystem, path, peer, peerPath, options = {}) {
112
+ options.signal?.throwIfAborted();
113
+ if (comparisonContext.active(options))
114
+ return "unknown";
115
+ const own = await resolveEntryView(filesystem, path, options);
116
+ const other = await resolveEntryView(peer, peerPath, options);
117
+ return compareResolvedEntries(own, other, options);
118
+ }
@@ -0,0 +1,2 @@
1
+ import type { FileStat } from "../../contracts/filesystem.js";
2
+ export declare function compareIdentity(left: FileStat | undefined, right: FileStat | undefined): "same" | "distinct" | "unknown";
@@ -0,0 +1,12 @@
1
+ function complete(stat) {
2
+ const { identityScope, dev, ino } = stat;
3
+ return ((typeof identityScope === "object" && identityScope !== null) || typeof identityScope === "symbol")
4
+ && typeof dev === "number" && Number.isSafeInteger(dev) && dev >= 0
5
+ && typeof ino === "number" && Number.isSafeInteger(ino) && ino >= 0;
6
+ }
7
+ export function compareIdentity(left, right) {
8
+ if (!left || !right || !complete(left) || !complete(right))
9
+ return "unknown";
10
+ return left.identityScope === right.identityScope && left.dev === right.dev && left.ino === right.ino
11
+ ? "same" : "distinct";
12
+ }
@@ -0,0 +1,44 @@
1
+ import type { AppendFileOptions, CopyFileOptions, DirectoryEntry, FileStat, FileSystem, FileSystemCapabilities, FsOptions, MkdirOptions, ReadFileOptions, ReadStreamOptions, RemoveOptions, WriteFileOptions } from "../../contracts/filesystem.js";
2
+ import type { ByteSource } from "../../contracts/io.js";
3
+ export interface MountFileSystemOptions {
4
+ readonly root: FileSystem;
5
+ readonly mounts?: Readonly<Record<string, FileSystem>>;
6
+ }
7
+ export declare class MountFileSystem implements FileSystem {
8
+ readonly capabilities: FileSystemCapabilities;
9
+ private readonly mounts;
10
+ constructor(options: MountFileSystemOptions);
11
+ private select;
12
+ private protected;
13
+ private error;
14
+ private operation;
15
+ private components;
16
+ private lookup;
17
+ private resolve;
18
+ private mutable;
19
+ private entryPath;
20
+ private optional;
21
+ readFile(path: string, options?: ReadFileOptions): Promise<Uint8Array>;
22
+ writeFile(path: string, data: Uint8Array, options?: WriteFileOptions): Promise<void>;
23
+ appendFile(path: string, data: Uint8Array, options?: AppendFileOptions): Promise<void>;
24
+ stat(path: string, options?: FsOptions): Promise<FileStat>;
25
+ lstat(path: string, options?: FsOptions): Promise<FileStat>;
26
+ readdir(path: string, options?: FsOptions): Promise<DirectoryEntry[]>;
27
+ mkdir(path: string, options?: MkdirOptions): Promise<void>;
28
+ rmdir(path: string, options?: FsOptions): Promise<void>;
29
+ rm(path: string, options?: RemoveOptions): Promise<void>;
30
+ rename(source: string, destination: string, options?: FsOptions): Promise<void>;
31
+ copyFile(source: string, destination: string, options?: CopyFileOptions): Promise<void>;
32
+ realpath(path: string, options?: FsOptions): Promise<string>;
33
+ compareEntry(path: string, peer: FileSystem, peerPath: string, options?: FsOptions): Promise<import("../../contracts/filesystem.js").EntryComparison>;
34
+ access(path: string, mode?: number, options?: FsOptions): Promise<void>;
35
+ readlink(path: string, options?: FsOptions): Promise<string>;
36
+ symlink(target: string, path: string, options?: FsOptions): Promise<void>;
37
+ link(existingPath: string, newPath: string, options?: FsOptions): Promise<void>;
38
+ chmod(path: string, mode: number, options?: FsOptions): Promise<void>;
39
+ utimes(path: string, atimeMs: number, mtimeMs: number, options?: FsOptions): Promise<void>;
40
+ truncate(path: string, length?: number, options?: FsOptions): Promise<void>;
41
+ readStream(path: string, options?: ReadStreamOptions): ByteSource;
42
+ writeStream(path: string, source: ByteSource, options?: WriteFileOptions): Promise<void>;
43
+ }
44
+ export declare function createMountFileSystem(options: MountFileSystemOptions): MountFileSystem;