@zenfs/core 0.0.1

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 (55) hide show
  1. package/README.md +293 -0
  2. package/dist/ApiError.d.ts +86 -0
  3. package/dist/ApiError.js +135 -0
  4. package/dist/backends/AsyncMirror.d.ts +102 -0
  5. package/dist/backends/AsyncMirror.js +252 -0
  6. package/dist/backends/AsyncStore.d.ts +166 -0
  7. package/dist/backends/AsyncStore.js +620 -0
  8. package/dist/backends/FolderAdapter.d.ts +52 -0
  9. package/dist/backends/FolderAdapter.js +184 -0
  10. package/dist/backends/InMemory.d.ts +25 -0
  11. package/dist/backends/InMemory.js +46 -0
  12. package/dist/backends/Locked.d.ts +64 -0
  13. package/dist/backends/Locked.js +302 -0
  14. package/dist/backends/OverlayFS.d.ts +120 -0
  15. package/dist/backends/OverlayFS.js +749 -0
  16. package/dist/backends/SyncStore.d.ts +223 -0
  17. package/dist/backends/SyncStore.js +479 -0
  18. package/dist/backends/backend.d.ts +73 -0
  19. package/dist/backends/backend.js +14 -0
  20. package/dist/backends/index.d.ts +11 -0
  21. package/dist/backends/index.js +15 -0
  22. package/dist/browser.min.js +12 -0
  23. package/dist/browser.min.js.map +7 -0
  24. package/dist/cred.d.ts +14 -0
  25. package/dist/cred.js +15 -0
  26. package/dist/emulation/callbacks.d.ts +382 -0
  27. package/dist/emulation/callbacks.js +422 -0
  28. package/dist/emulation/constants.d.ts +101 -0
  29. package/dist/emulation/constants.js +110 -0
  30. package/dist/emulation/fs.d.ts +7 -0
  31. package/dist/emulation/fs.js +5 -0
  32. package/dist/emulation/index.d.ts +5 -0
  33. package/dist/emulation/index.js +7 -0
  34. package/dist/emulation/promises.d.ts +309 -0
  35. package/dist/emulation/promises.js +521 -0
  36. package/dist/emulation/shared.d.ts +62 -0
  37. package/dist/emulation/shared.js +192 -0
  38. package/dist/emulation/sync.d.ts +278 -0
  39. package/dist/emulation/sync.js +392 -0
  40. package/dist/file.d.ts +449 -0
  41. package/dist/file.js +576 -0
  42. package/dist/filesystem.d.ts +367 -0
  43. package/dist/filesystem.js +542 -0
  44. package/dist/index.d.ts +78 -0
  45. package/dist/index.js +113 -0
  46. package/dist/inode.d.ts +51 -0
  47. package/dist/inode.js +112 -0
  48. package/dist/mutex.d.ts +12 -0
  49. package/dist/mutex.js +48 -0
  50. package/dist/stats.d.ts +98 -0
  51. package/dist/stats.js +226 -0
  52. package/dist/utils.d.ts +52 -0
  53. package/dist/utils.js +261 -0
  54. package/license.md +122 -0
  55. package/package.json +61 -0
@@ -0,0 +1,192 @@
1
+ // Utilities and shared data
2
+ import { posix as path } from 'path';
3
+ import { ApiError, ErrorCode } from '../ApiError';
4
+ //import { BackendConstructor } from '../backends';
5
+ import { InMemoryFileSystem } from '../backends/InMemory';
6
+ /**
7
+ * converts Date or number to a fractional UNIX timestamp
8
+ * Grabbed from NodeJS sources (lib/fs.js)
9
+ */
10
+ export function _toUnixTimestamp(time) {
11
+ if (typeof time === 'number') {
12
+ return time;
13
+ }
14
+ else if (time instanceof Date) {
15
+ return time.getTime() / 1000;
16
+ }
17
+ throw new Error('Cannot parse time: ' + time);
18
+ }
19
+ export function normalizeMode(mode, def) {
20
+ switch (typeof mode) {
21
+ case 'number':
22
+ // (path, flag, mode, cb?)
23
+ return mode;
24
+ case 'string':
25
+ // (path, flag, modeString, cb?)
26
+ const trueMode = parseInt(mode, 8);
27
+ if (!isNaN(trueMode)) {
28
+ return trueMode;
29
+ }
30
+ // Invalid string.
31
+ return def;
32
+ default:
33
+ return def;
34
+ }
35
+ }
36
+ export function normalizeTime(time) {
37
+ if (time instanceof Date) {
38
+ return time;
39
+ }
40
+ if (typeof time === 'number') {
41
+ return new Date(time * 1000);
42
+ }
43
+ throw new ApiError(ErrorCode.EINVAL, `Invalid time.`);
44
+ }
45
+ export function normalizePath(p) {
46
+ // Node doesn't allow null characters in paths.
47
+ if (p.indexOf('\u0000') >= 0) {
48
+ throw new ApiError(ErrorCode.EINVAL, 'Path must be a string without null bytes.');
49
+ }
50
+ if (p === '') {
51
+ throw new ApiError(ErrorCode.EINVAL, 'Path must not be empty.');
52
+ }
53
+ p = p.replaceAll(/\/+/g, '/');
54
+ return path.resolve(p);
55
+ }
56
+ export function normalizeOptions(options, defEnc, defFlag, defMode) {
57
+ // typeof null === 'object' so special-case handing is needed.
58
+ switch (options === null ? 'null' : typeof options) {
59
+ case 'object':
60
+ return {
61
+ encoding: typeof options['encoding'] !== 'undefined' ? options['encoding'] : defEnc,
62
+ flag: typeof options['flag'] !== 'undefined' ? options['flag'] : defFlag,
63
+ mode: normalizeMode(options['mode'], defMode),
64
+ };
65
+ case 'string':
66
+ return {
67
+ encoding: options,
68
+ flag: defFlag,
69
+ mode: defMode,
70
+ };
71
+ case 'null':
72
+ case 'undefined':
73
+ case 'function':
74
+ return {
75
+ encoding: defEnc,
76
+ flag: defFlag,
77
+ mode: defMode,
78
+ };
79
+ default:
80
+ throw new TypeError(`"options" must be a string or an object, got ${typeof options} instead.`);
81
+ }
82
+ }
83
+ export function nop() {
84
+ // do nothing
85
+ }
86
+ // credentials
87
+ export let cred;
88
+ export function setCred(val) {
89
+ cred = val;
90
+ }
91
+ // descriptors
92
+ export const fdMap = new Map();
93
+ let nextFd = 100;
94
+ export function getFdForFile(file) {
95
+ const fd = nextFd++;
96
+ fdMap.set(fd, file);
97
+ return fd;
98
+ }
99
+ export function fd2file(fd) {
100
+ if (!fdMap.has(fd)) {
101
+ throw new ApiError(ErrorCode.EBADF, 'Invalid file descriptor.');
102
+ }
103
+ return fdMap.get(fd);
104
+ }
105
+ export const mounts = new Map();
106
+ /*
107
+ Set a default root.
108
+ There is a very small but not 0 change that initialize() will try to unmount the default before it is mounted.
109
+ This can be fixed by using a top-level await, which is not done to maintain ES6 compatibility.
110
+ */
111
+ InMemoryFileSystem.Create().then(fs => mount('/', fs));
112
+ /**
113
+ * Gets the file system mounted at `mountPoint`
114
+ */
115
+ export function getMount(mountPoint) {
116
+ return mounts.get(mountPoint);
117
+ }
118
+ /**
119
+ * Gets an object of mount points (keys) and filesystems (values)
120
+ */
121
+ export function getMounts() {
122
+ return Object.fromEntries(mounts.entries());
123
+ }
124
+ /**
125
+ * Mounts the file system at the given mount point.
126
+ */
127
+ export function mount(mountPoint, fs) {
128
+ if (mountPoint[0] !== '/') {
129
+ mountPoint = '/' + mountPoint;
130
+ }
131
+ mountPoint = path.resolve(mountPoint);
132
+ if (mounts.has(mountPoint)) {
133
+ throw new ApiError(ErrorCode.EINVAL, 'Mount point ' + mountPoint + ' is already in use.');
134
+ }
135
+ mounts.set(mountPoint, fs);
136
+ }
137
+ /**
138
+ * Unmounts the file system at the given mount point.
139
+ */
140
+ export function umount(mountPoint) {
141
+ if (mountPoint[0] !== '/') {
142
+ mountPoint = `/${mountPoint}`;
143
+ }
144
+ mountPoint = path.resolve(mountPoint);
145
+ if (!mounts.has(mountPoint)) {
146
+ throw new ApiError(ErrorCode.EINVAL, 'Mount point ' + mountPoint + ' is already unmounted.');
147
+ }
148
+ mounts.delete(mountPoint);
149
+ }
150
+ /**
151
+ * Gets the internal FileSystem for the path, then returns it along with the path relative to the FS' root
152
+ */
153
+ export function resolveFS(path) {
154
+ const sortedMounts = [...mounts].sort((a, b) => (a[0].length > b[0].length ? -1 : 1)); // decending order of the string length
155
+ for (const [mountPoint, fs] of sortedMounts) {
156
+ // We know path is normalized, so it would be a substring of the mount point.
157
+ if (mountPoint.length <= path.length && path.startsWith(mountPoint)) {
158
+ path = path.slice(mountPoint.length > 1 ? mountPoint.length : 0); // Resolve the path relative to the mount point
159
+ if (path === '') {
160
+ path = '/';
161
+ }
162
+ return { fs, path, mountPoint };
163
+ }
164
+ }
165
+ throw new ApiError(ErrorCode.EIO, 'ZenFS not initialized with a file system');
166
+ }
167
+ /**
168
+ * Reverse maps the paths in text from the mounted FileSystem to the global path
169
+ */
170
+ export function fixPaths(text, paths) {
171
+ for (const [from, to] of Object.entries(paths)) {
172
+ text = text.replaceAll(from, to);
173
+ }
174
+ return text;
175
+ }
176
+ export function fixError(e, paths) {
177
+ e.stack = fixPaths(e.stack, paths);
178
+ e.message = fixPaths(e.message, paths);
179
+ return e;
180
+ }
181
+ export function initialize(mountMapping) {
182
+ if (mountMapping['/']) {
183
+ umount('/');
184
+ }
185
+ for (const [point, fs] of Object.entries(mountMapping)) {
186
+ const FS = fs.constructor;
187
+ if (!FS.isAvailable()) {
188
+ throw new ApiError(ErrorCode.EINVAL, `Can not mount "${point}" since the filesystem is unavailable.`);
189
+ }
190
+ mount(point, fs);
191
+ }
192
+ }
@@ -0,0 +1,278 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { FileContents } from '../filesystem';
4
+ import { Stats } from '../stats';
5
+ import type { symlink, ReadSyncOptions } from 'fs';
6
+ /**
7
+ * Synchronous rename.
8
+ * @param oldPath
9
+ * @param newPath
10
+ */
11
+ export declare function renameSync(oldPath: string, newPath: string): void;
12
+ /**
13
+ * Test whether or not the given path exists by checking with the file system.
14
+ * @param path
15
+ */
16
+ export declare function existsSync(path: string): boolean;
17
+ /**
18
+ * Synchronous `stat`.
19
+ * @param path
20
+ * @returns Stats
21
+ */
22
+ export declare function statSync(path: string): Stats;
23
+ /**
24
+ * Synchronous `lstat`.
25
+ * `lstat()` is identical to `stat()`, except that if path is a symbolic link,
26
+ * then the link itself is stat-ed, not the file that it refers to.
27
+ * @param path
28
+ * @return [ZenFS.node.fs.Stats]
29
+ */
30
+ export declare function lstatSync(path: string): Stats;
31
+ /**
32
+ * Synchronous `truncate`.
33
+ * @param path
34
+ * @param len
35
+ */
36
+ export declare function truncateSync(path: string, len?: number): void;
37
+ /**
38
+ * Synchronous `unlink`.
39
+ * @param path
40
+ */
41
+ export declare function unlinkSync(path: string): void;
42
+ /**
43
+ * Synchronous file open.
44
+ * @see http://www.manpagez.com/man/2/open/
45
+ * @param path
46
+ * @param flags
47
+ * @param mode defaults to `0644`
48
+ * @return [ZenFS.File]
49
+ */
50
+ export declare function openSync(path: string, flag: string, mode?: number | string): number;
51
+ /**
52
+ * Synchronously reads the entire contents of a file.
53
+ * @param filename
54
+ * @param options
55
+ * @option options [String] encoding The string encoding for the file contents. Defaults to `null`.
56
+ * @option options [String] flag Defaults to `'r'`.
57
+ * @return [String | ZenFS.node.Buffer]
58
+ */
59
+ export declare function readFileSync(filename: string, options?: {
60
+ flag?: string;
61
+ }): Buffer;
62
+ export declare function readFileSync(filename: string, options: {
63
+ encoding: string;
64
+ flag?: string;
65
+ }): string;
66
+ export declare function readFileSync(filename: string, encoding: string): string;
67
+ /**
68
+ * Synchronously writes data to a file, replacing the file if it already
69
+ * exists.
70
+ *
71
+ * The encoding option is ignored if data is a buffer.
72
+ * @param filename
73
+ * @param data
74
+ * @param options
75
+ * @option options [String] encoding Defaults to `'utf8'`.
76
+ * @option options [Number] mode Defaults to `0644`.
77
+ * @option options [String] flag Defaults to `'w'`.
78
+ */
79
+ export declare function writeFileSync(filename: string, data: FileContents, options?: {
80
+ encoding?: string;
81
+ mode?: number | string;
82
+ flag?: string;
83
+ }): void;
84
+ export declare function writeFileSync(filename: string, data: FileContents, encoding?: string): void;
85
+ /**
86
+ * Asynchronously append data to a file, creating the file if it not yet
87
+ * exists.
88
+ *
89
+ * @example Usage example
90
+ * fs.appendFile('message.txt', 'data to append', function (err) {
91
+ * if (err) throw err;
92
+ * console.log('The "data to append" was appended to file!');
93
+ * });
94
+ * @param filename
95
+ * @param data
96
+ * @param options
97
+ * @option options [String] encoding Defaults to `'utf8'`.
98
+ * @option options [Number] mode Defaults to `0644`.
99
+ * @option options [String] flag Defaults to `'a'`.
100
+ */
101
+ export declare function appendFileSync(filename: string, data: FileContents, options?: {
102
+ encoding?: string;
103
+ mode?: number | string;
104
+ flag?: string;
105
+ }): void;
106
+ export declare function appendFileSync(filename: string, data: FileContents, encoding?: string): void;
107
+ /**
108
+ * Synchronous `fstat`.
109
+ * `fstat()` is identical to `stat()`, except that the file to be stat-ed is
110
+ * specified by the file descriptor `fd`.
111
+ * @param fd
112
+ * @return [ZenFS.node.fs.Stats]
113
+ */
114
+ export declare function fstatSync(fd: number): Stats;
115
+ /**
116
+ * Synchronous close.
117
+ * @param fd
118
+ */
119
+ export declare function closeSync(fd: number): void;
120
+ /**
121
+ * Synchronous ftruncate.
122
+ * @param fd
123
+ * @param len
124
+ */
125
+ export declare function ftruncateSync(fd: number, len?: number): void;
126
+ /**
127
+ * Synchronous fsync.
128
+ * @param fd
129
+ */
130
+ export declare function fsyncSync(fd: number): void;
131
+ /**
132
+ * Synchronous fdatasync.
133
+ * @param fd
134
+ */
135
+ export declare function fdatasyncSync(fd: number): void;
136
+ /**
137
+ * Write buffer to the file specified by `fd`.
138
+ * Note that it is unsafe to use fs.write multiple times on the same file
139
+ * without waiting for it to return.
140
+ * @param fd
141
+ * @param buffer Buffer containing the data to write to
142
+ * the file.
143
+ * @param offset Offset in the buffer to start reading data from.
144
+ * @param length The amount of bytes to write to the file.
145
+ * @param position Offset from the beginning of the file where this
146
+ * data should be written. If position is null, the data will be written at
147
+ * the current position.
148
+ */
149
+ export declare function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position?: number | null): number;
150
+ export declare function writeSync(fd: number, data: string, position?: number | null, encoding?: BufferEncoding): number;
151
+ /**
152
+ * Read data from the file specified by `fd`.
153
+ * @param fd
154
+ * @param buffer The buffer that the data will be
155
+ * written to.
156
+ * @param offset The offset within the buffer where writing will
157
+ * start.
158
+ * @param length An integer specifying the number of bytes to read.
159
+ * @param position An integer specifying where to begin reading from
160
+ * in the file. If position is null, data will be read from the current file
161
+ * position.
162
+ */
163
+ export declare function readSync(fd: number, buffer: Buffer, opts?: ReadSyncOptions): number;
164
+ export declare function readSync(fd: number, buffer: Buffer, offset: number, length: number, position?: number): number;
165
+ /**
166
+ * Synchronous `fchown`.
167
+ * @param fd
168
+ * @param uid
169
+ * @param gid
170
+ */
171
+ export declare function fchownSync(fd: number, uid: number, gid: number): void;
172
+ /**
173
+ * Synchronous `fchmod`.
174
+ * @param fd
175
+ * @param mode
176
+ */
177
+ export declare function fchmodSync(fd: number, mode: number | string): void;
178
+ /**
179
+ * Change the file timestamps of a file referenced by the supplied file
180
+ * descriptor.
181
+ * @param fd
182
+ * @param atime
183
+ * @param mtime
184
+ */
185
+ export declare function futimesSync(fd: number, atime: number | Date, mtime: number | Date): void;
186
+ /**
187
+ * Synchronous `rmdir`.
188
+ * @param path
189
+ */
190
+ export declare function rmdirSync(path: string): void;
191
+ /**
192
+ * Synchronous `mkdir`.
193
+ * @param path
194
+ * @param mode defaults to `0777`
195
+ */
196
+ export declare function mkdirSync(path: string, mode?: number | string): void;
197
+ /**
198
+ * Synchronous `readdir`. Reads the contents of a directory.
199
+ * @param path
200
+ * @return [String[]]
201
+ */
202
+ export declare function readdirSync(path: string): string[];
203
+ /**
204
+ * Synchronous `link`.
205
+ * @param srcpath
206
+ * @param dstpath
207
+ */
208
+ export declare function linkSync(srcpath: string, dstpath: string): void;
209
+ /**
210
+ * Synchronous `symlink`.
211
+ * @param srcpath
212
+ * @param dstpath
213
+ * @param type can be either `'dir'` or `'file'` (default is `'file'`)
214
+ */
215
+ export declare function symlinkSync(srcpath: string, dstpath: string, type?: symlink.Type): void;
216
+ /**
217
+ * Synchronous readlink.
218
+ * @param path
219
+ * @return [String]
220
+ */
221
+ export declare function readlinkSync(path: string): string;
222
+ /**
223
+ * Synchronous `chown`.
224
+ * @param path
225
+ * @param uid
226
+ * @param gid
227
+ */
228
+ export declare function chownSync(path: string, uid: number, gid: number): void;
229
+ /**
230
+ * Synchronous `lchown`.
231
+ * @param path
232
+ * @param uid
233
+ * @param gid
234
+ */
235
+ export declare function lchownSync(path: string, uid: number, gid: number): void;
236
+ /**
237
+ * Synchronous `chmod`.
238
+ * @param path
239
+ * @param mode
240
+ */
241
+ export declare function chmodSync(path: string, mode: string | number): void;
242
+ /**
243
+ * Synchronous `lchmod`.
244
+ * @param path
245
+ * @param mode
246
+ */
247
+ export declare function lchmodSync(path: string, mode: number | string): void;
248
+ /**
249
+ * Change file timestamps of the file referenced by the supplied path.
250
+ * @param path
251
+ * @param atime
252
+ * @param mtime
253
+ */
254
+ export declare function utimesSync(path: string, atime: number | Date, mtime: number | Date): void;
255
+ /**
256
+ * Change file timestamps of the file referenced by the supplied path.
257
+ * @param path
258
+ * @param atime
259
+ * @param mtime
260
+ */
261
+ export declare function lutimesSync(path: string, atime: number | Date, mtime: number | Date): void;
262
+ /**
263
+ * Synchronous `realpath`.
264
+ * @param path
265
+ * @param cache An object literal of mapped paths that can be used to
266
+ * force a specific path resolution or avoid additional `fs.stat` calls for
267
+ * known real paths.
268
+ * @return [String]
269
+ */
270
+ export declare function realpathSync(path: string, cache?: {
271
+ [path: string]: string;
272
+ }): string;
273
+ /**
274
+ * Synchronous `access`.
275
+ * @param path
276
+ * @param mode
277
+ */
278
+ export declare function accessSync(path: string, mode?: number): void;