@zenfs/core 0.8.1 → 0.9.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.
@@ -297,36 +297,64 @@ export declare function realpathSync(path: PathLike, options?: EncodingOption):
297
297
  */
298
298
  export declare function accessSync(path: PathLike, mode?: number): void;
299
299
  /**
300
- * @todo Implement
300
+ * Synchronous `rm`. Removes files or directories (recursively).
301
+ * @param path The path to the file or directory to remove.
301
302
  */
302
- export declare function rmSync(path: PathLike): void;
303
+ export declare function rmSync(path: PathLike, options?: Node.RmOptions): void;
303
304
  /**
304
- * @todo Implement
305
+ * Synchronous `mkdtemp`. Creates a unique temporary directory.
306
+ * @param prefix The directory prefix.
307
+ * @param options The encoding (or an object including `encoding`).
308
+ * @returns The path to the created temporary directory, encoded as a string or buffer.
305
309
  */
306
310
  export declare function mkdtempSync(prefix: string, options: BufferEncodingOption): Buffer;
307
311
  export declare function mkdtempSync(prefix: string, options?: EncodingOption): string;
308
312
  /**
309
- * @todo Implement
313
+ * Synchronous `copyFile`. Copies a file.
314
+ * @param src The source file.
315
+ * @param dest The destination file.
316
+ * @param flags Optional flags for the copy operation. Currently supports these flags:
317
+ * * `fs.constants.COPYFILE_EXCL`: If the destination file already exists, the operation fails.
310
318
  */
311
- export declare function copyFileSync(src: string, dest: string, flags?: number): void;
319
+ export declare function copyFileSync(src: PathLike, dest: PathLike, flags?: number): void;
312
320
  /**
313
- * @todo Implement
321
+ * Synchronous `readv`. Reads from a file descriptor into multiple buffers.
322
+ * @param fd The file descriptor.
323
+ * @param buffers An array of Uint8Array buffers.
324
+ * @param position The position in the file where to begin reading.
325
+ * @returns The number of bytes read.
314
326
  */
315
327
  export declare function readvSync(fd: number, buffers: readonly Uint8Array[], position?: number): number;
316
328
  /**
317
- * @todo Implement
329
+ * Synchronous `writev`. Writes from multiple buffers into a file descriptor.
330
+ * @param fd The file descriptor.
331
+ * @param buffers An array of Uint8Array buffers.
332
+ * @param position The position in the file where to begin writing.
333
+ * @returns The number of bytes written.
318
334
  */
319
335
  export declare function writevSync(fd: number, buffers: readonly Uint8Array[], position?: number): number;
320
336
  /**
321
- * @todo Implement
337
+ * Synchronous `opendir`. Opens a directory.
338
+ * @param path The path to the directory.
339
+ * @param options Options for opening the directory.
340
+ * @returns A `Dir` object representing the opened directory.
322
341
  */
323
342
  export declare function opendirSync(path: PathLike, options?: Node.OpenDirOptions): Dir;
324
343
  /**
325
- * @todo Implement
344
+ * Synchronous `cp`. Recursively copies a file or directory.
345
+ * @param source The source file or directory.
346
+ * @param destination The destination file or directory.
347
+ * @param opts Options for the copy operation. Currently supports these options from Node.js 'fs.cpSync':
348
+ * * `dereference`: Dereference symbolic links.
349
+ * * `errorOnExist`: Throw an error if the destination file or directory already exists.
350
+ * * `filter`: A function that takes a source and destination path and returns a boolean, indicating whether to copy the given source element.
351
+ * * `force`: Overwrite the destination if it exists, and overwrite existing readonly destination files.
352
+ * * `preserveTimestamps`: Preserve file timestamps.
353
+ * * `recursive`: If `true`, copies directories recursively.
326
354
  */
327
355
  export declare function cpSync(source: PathLike, destination: PathLike, opts?: Node.CopySyncOptions): void;
328
356
  /**
329
- * Synchronous statfs(2). Returns information about the mounted file system which contains path. The callback gets two arguments (err, stats) where stats is an <fs.StatFs> object.
357
+ * Synchronous statfs(2). Returns information about the mounted file system which contains path.
330
358
  * In case of an error, the err.code will be one of Common System Errors.
331
359
  * @param path A path to an existing file or directory on the file system to be queried.
332
360
  * @param callback
@@ -2,9 +2,11 @@ import { Buffer } from 'buffer';
2
2
  import { ApiError, ErrorCode } from '../ApiError.js';
3
3
  import { ActionType, isAppendable, isReadable, isWriteable, parseFlag, pathExistsAction, pathNotExistsAction } from '../file.js';
4
4
  import { BigIntStats, FileType } from '../stats.js';
5
- import { Dirent } from './dir.js';
5
+ import { normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
6
+ import { COPYFILE_EXCL, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFREG, S_IFSOCK } from './constants.js';
7
+ import { Dir, Dirent } from './dir.js';
6
8
  import { dirname, join, parse } from './path.js';
7
- import { cred, fd2file, fdMap, fixError, getFdForFile, mounts, normalizeMode, normalizeOptions, normalizePath, normalizeTime, resolveMount } from './shared.js';
9
+ import { cred, fd2file, fdMap, fixError, getFdForFile, mounts, resolveMount } from './shared.js';
8
10
  function doOp(...[name, resolveSymlinks, path, ...args]) {
9
11
  path = normalizePath(path);
10
12
  const { fs, path: resolvedPath } = resolveMount(resolveSymlinks && existsSync(path) ? realpathSync(path) : path);
@@ -104,22 +106,22 @@ function _openSync(_path, _flag, _mode, resolveSymlinks) {
104
106
  // Ensure parent exists.
105
107
  const parentStats = doOp('statSync', resolveSymlinks, dirname(path), cred);
106
108
  if (!parentStats.isDirectory()) {
107
- throw ApiError.With('ENOTDIR', dirname(path), '_openSync');
109
+ throw ApiError.With('ENOTDIR', dirname(path), '_open');
108
110
  }
109
111
  return doOp('createFileSync', resolveSymlinks, path, flag, mode, cred);
110
112
  case ActionType.THROW:
111
- throw ApiError.With('ENOENT', path, '_openSync');
113
+ throw ApiError.With('ENOENT', path, '_open');
112
114
  default:
113
115
  throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');
114
116
  }
115
117
  }
116
118
  if (!stats.hasAccess(mode, cred)) {
117
- throw ApiError.With('EACCES', path, '_openSync');
119
+ throw ApiError.With('EACCES', path, '_open');
118
120
  }
119
121
  // File exists.
120
122
  switch (pathExistsAction(flag)) {
121
123
  case ActionType.THROW:
122
- throw ApiError.With('EEXIST', path, '_openSync');
124
+ throw ApiError.With('EEXIST', path, '_open');
123
125
  case ActionType.TRUNCATE:
124
126
  // Delete file.
125
127
  doOp('unlinkSync', resolveSymlinks, path, cred);
@@ -426,7 +428,7 @@ export function symlinkSync(target, path, type = 'file') {
426
428
  throw new ApiError(ErrorCode.EINVAL, 'Invalid type: ' + type);
427
429
  }
428
430
  if (existsSync(path)) {
429
- throw ApiError.With('EEXIST', path, 'symlinkSync');
431
+ throw ApiError.With('EEXIST', path, 'symlink');
430
432
  }
431
433
  writeFileSync(path, target);
432
434
  const file = _openSync(path, 'r+', 0o644, false);
@@ -542,54 +544,151 @@ export function accessSync(path, mode = 0o600) {
542
544
  }
543
545
  }
544
546
  accessSync;
545
- /* eslint-disable @typescript-eslint/no-unused-vars */
546
547
  /**
547
- * @todo Implement
548
+ * Synchronous `rm`. Removes files or directories (recursively).
549
+ * @param path The path to the file or directory to remove.
548
550
  */
549
- export function rmSync(path) {
550
- throw ApiError.With('ENOTSUP', path, 'rmSync');
551
+ export function rmSync(path, options) {
552
+ path = normalizePath(path);
553
+ const stats = statSync(path);
554
+ switch (stats.mode & S_IFMT) {
555
+ case S_IFDIR:
556
+ if (options?.recursive) {
557
+ for (const entry of readdirSync(path)) {
558
+ rmSync(join(path, entry));
559
+ }
560
+ }
561
+ rmdirSync(path);
562
+ return;
563
+ case S_IFREG:
564
+ case S_IFLNK:
565
+ unlinkSync(path);
566
+ return;
567
+ case S_IFBLK:
568
+ case S_IFCHR:
569
+ case S_IFIFO:
570
+ case S_IFSOCK:
571
+ default:
572
+ throw new ApiError(ErrorCode.EPERM, 'File type not supported', path, 'rm');
573
+ }
551
574
  }
552
575
  rmSync;
553
576
  export function mkdtempSync(prefix, options) {
554
- throw ApiError.With('ENOTSUP', prefix, 'mkdtempSync');
577
+ const encoding = typeof options === 'object' ? options.encoding : options || 'utf8';
578
+ const fsName = `${prefix}${Date.now()}-${Math.random().toString(36).slice(2)}`;
579
+ const resolvedPath = '/tmp/' + fsName;
580
+ mkdirSync(resolvedPath);
581
+ return encoding == 'buffer' ? Buffer.from(resolvedPath) : resolvedPath;
555
582
  }
556
583
  mkdtempSync;
557
584
  /**
558
- * @todo Implement
585
+ * Synchronous `copyFile`. Copies a file.
586
+ * @param src The source file.
587
+ * @param dest The destination file.
588
+ * @param flags Optional flags for the copy operation. Currently supports these flags:
589
+ * * `fs.constants.COPYFILE_EXCL`: If the destination file already exists, the operation fails.
559
590
  */
560
591
  export function copyFileSync(src, dest, flags) {
561
- throw ApiError.With('ENOTSUP', src, 'copyFileSync');
592
+ src = normalizePath(src);
593
+ dest = normalizePath(dest);
594
+ if (flags && flags & COPYFILE_EXCL && existsSync(dest)) {
595
+ throw new ApiError(ErrorCode.EEXIST, 'Destination file already exists.', dest, 'copyFile');
596
+ }
597
+ writeFileSync(dest, readFileSync(src));
562
598
  }
563
599
  copyFileSync;
564
600
  /**
565
- * @todo Implement
601
+ * Synchronous `readv`. Reads from a file descriptor into multiple buffers.
602
+ * @param fd The file descriptor.
603
+ * @param buffers An array of Uint8Array buffers.
604
+ * @param position The position in the file where to begin reading.
605
+ * @returns The number of bytes read.
566
606
  */
567
607
  export function readvSync(fd, buffers, position) {
568
- throw ApiError.With('ENOTSUP', fd2file(fd).path, 'readvSync');
608
+ const file = fd2file(fd);
609
+ let bytesRead = 0;
610
+ for (const buffer of buffers) {
611
+ bytesRead += file.readSync(buffer, 0, buffer.length, position + bytesRead);
612
+ }
613
+ return bytesRead;
569
614
  }
570
615
  readvSync;
571
616
  /**
572
- * @todo Implement
617
+ * Synchronous `writev`. Writes from multiple buffers into a file descriptor.
618
+ * @param fd The file descriptor.
619
+ * @param buffers An array of Uint8Array buffers.
620
+ * @param position The position in the file where to begin writing.
621
+ * @returns The number of bytes written.
573
622
  */
574
623
  export function writevSync(fd, buffers, position) {
575
- throw ApiError.With('ENOTSUP', fd2file(fd).path, 'writevSync');
624
+ const file = fd2file(fd);
625
+ let bytesWritten = 0;
626
+ for (const buffer of buffers) {
627
+ bytesWritten += file.writeSync(buffer, 0, buffer.length, position + bytesWritten);
628
+ }
629
+ return bytesWritten;
576
630
  }
577
631
  writevSync;
578
632
  /**
579
- * @todo Implement
633
+ * Synchronous `opendir`. Opens a directory.
634
+ * @param path The path to the directory.
635
+ * @param options Options for opening the directory.
636
+ * @returns A `Dir` object representing the opened directory.
580
637
  */
581
638
  export function opendirSync(path, options) {
582
- throw ApiError.With('ENOTSUP', path, 'opendirSync');
639
+ path = normalizePath(path);
640
+ return new Dir(path); // Re-use existing `Dir` class
583
641
  }
584
642
  opendirSync;
585
643
  /**
586
- * @todo Implement
644
+ * Synchronous `cp`. Recursively copies a file or directory.
645
+ * @param source The source file or directory.
646
+ * @param destination The destination file or directory.
647
+ * @param opts Options for the copy operation. Currently supports these options from Node.js 'fs.cpSync':
648
+ * * `dereference`: Dereference symbolic links.
649
+ * * `errorOnExist`: Throw an error if the destination file or directory already exists.
650
+ * * `filter`: A function that takes a source and destination path and returns a boolean, indicating whether to copy the given source element.
651
+ * * `force`: Overwrite the destination if it exists, and overwrite existing readonly destination files.
652
+ * * `preserveTimestamps`: Preserve file timestamps.
653
+ * * `recursive`: If `true`, copies directories recursively.
587
654
  */
588
655
  export function cpSync(source, destination, opts) {
589
- throw ApiError.With('ENOTSUP', source, 'cpSync');
656
+ source = normalizePath(source);
657
+ destination = normalizePath(destination);
658
+ const srcStats = lstatSync(source); // Use lstat to follow symlinks if not dereferencing
659
+ if (opts?.errorOnExist && existsSync(destination)) {
660
+ throw new ApiError(ErrorCode.EEXIST, 'Destination file or directory already exists.', destination, 'cp');
661
+ }
662
+ switch (srcStats.mode & S_IFMT) {
663
+ case S_IFDIR:
664
+ if (!opts?.recursive) {
665
+ throw new ApiError(ErrorCode.EISDIR, source + ' is a directory (not copied)', source, 'cp');
666
+ }
667
+ mkdirSync(destination, { recursive: true }); // Ensure the destination directory exists
668
+ for (const dirent of readdirSync(source, { withFileTypes: true })) {
669
+ if (opts.filter && !opts.filter(join(source, dirent.name), join(destination, dirent.name))) {
670
+ continue; // Skip if the filter returns false
671
+ }
672
+ cpSync(join(source, dirent.name), join(destination, dirent.name), opts);
673
+ }
674
+ break;
675
+ case S_IFREG:
676
+ case S_IFLNK:
677
+ copyFileSync(source, destination);
678
+ break;
679
+ case S_IFBLK:
680
+ case S_IFCHR:
681
+ case S_IFIFO:
682
+ case S_IFSOCK:
683
+ default:
684
+ throw new ApiError(ErrorCode.EPERM, 'File type not supported', source, 'rm');
685
+ }
686
+ // Optionally preserve timestamps
687
+ if (opts?.preserveTimestamps) {
688
+ utimesSync(destination, srcStats.atime, srcStats.mtime);
689
+ }
590
690
  }
591
691
  cpSync;
592
692
  export function statfsSync(path, options) {
593
- throw ApiError.With('ENOTSUP', path, 'statfsSync');
693
+ throw ApiError.With('ENOSYS', path, 'statfs');
594
694
  }
595
- /* eslint-enable @typescript-eslint/no-unused-vars */
@@ -24,7 +24,7 @@ export interface FileSystemMetadata {
24
24
  freeSpace: number;
25
25
  }
26
26
  /**
27
- * Structure for a filesystem. All ZenFS FileSystems must implement this.
27
+ * Structure for a filesystem. All ZenFS backends must extend this.
28
28
  *
29
29
  * This class includes some default implementations
30
30
  *
@@ -220,5 +220,8 @@ declare abstract class ReadonlyFileSystem extends FileSystem {
220
220
  sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
221
221
  syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
222
222
  }
223
+ /**
224
+ * Implements the non-readonly methods to throw `EROFS`
225
+ */
223
226
  export declare function Readonly<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => ReadonlyFileSystem) & T;
224
227
  export {};
@@ -3,7 +3,7 @@ import { rootCred } from './cred.js';
3
3
  import { join } from './emulation/path.js';
4
4
  import { PreloadFile, parseFlag } from './file.js';
5
5
  /**
6
- * Structure for a filesystem. All ZenFS FileSystems must implement this.
6
+ * Structure for a filesystem. All ZenFS backends must extend this.
7
7
  *
8
8
  * This class includes some default implementations
9
9
  *
@@ -24,7 +24,6 @@ export class FileSystem {
24
24
  freeSpace: 0,
25
25
  };
26
26
  }
27
- /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
28
27
  constructor(options) {
29
28
  // unused
30
29
  }
@@ -57,9 +56,6 @@ export class FileSystem {
57
56
  * Implements the asynchronous API in terms of the synchronous API.
58
57
  */
59
58
  export function Sync(FS) {
60
- /**
61
- * Implements the asynchronous API in terms of the synchronous API.
62
- */
63
59
  class _SyncFileSystem extends FS {
64
60
  async ready() {
65
61
  return this;
@@ -239,6 +235,9 @@ export function Async(FS) {
239
235
  }
240
236
  return _AsyncFileSystem;
241
237
  }
238
+ /**
239
+ * Implements the non-readonly methods to throw `EROFS`
240
+ */
242
241
  export function Readonly(FS) {
243
242
  class _ReadonlyFileSystem extends FS {
244
243
  metadata() {
package/dist/index.d.ts CHANGED
@@ -1,15 +1,15 @@
1
- export * from './backends/backend.js';
1
+ export * from './ApiError.js';
2
2
  export * from './backends/AsyncStore.js';
3
3
  export * from './backends/InMemory.js';
4
+ export * from './backends/Index.js';
4
5
  export * from './backends/Locked.js';
5
6
  export * from './backends/Overlay.js';
6
7
  export * from './backends/SyncStore.js';
7
- export * from './ApiError.js';
8
+ export * from './backends/backend.js';
8
9
  export * from './config.js';
9
10
  export * from './cred.js';
10
11
  export * from './file.js';
11
12
  export * from './filesystem.js';
12
- export * from './FileIndex.js';
13
13
  export * from './inode.js';
14
14
  export * from './mutex.js';
15
15
  export * from './stats.js';
package/dist/index.js CHANGED
@@ -1,15 +1,15 @@
1
- export * from './backends/backend.js';
1
+ export * from './ApiError.js';
2
2
  export * from './backends/AsyncStore.js';
3
3
  export * from './backends/InMemory.js';
4
+ export * from './backends/Index.js';
4
5
  export * from './backends/Locked.js';
5
6
  export * from './backends/Overlay.js';
6
7
  export * from './backends/SyncStore.js';
7
- export * from './ApiError.js';
8
+ export * from './backends/backend.js';
8
9
  export * from './config.js';
9
10
  export * from './cred.js';
10
11
  export * from './file.js';
11
12
  export * from './filesystem.js';
12
- export * from './FileIndex.js';
13
13
  export * from './inode.js';
14
14
  export * from './mutex.js';
15
15
  export * from './stats.js';
package/dist/utils.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ /// <reference types="node" resolution-mode="require"/>
1
3
  import type { OptionalTuple } from 'utilium';
2
4
  import { ApiError } from './ApiError.js';
3
5
  import { Cred } from './cred.js';
@@ -41,3 +43,46 @@ export declare function decodeDirListing(data: Uint8Array): Record<string, bigin
41
43
  */
42
44
  export declare function encodeDirListing(data: Record<string, bigint>): Uint8Array;
43
45
  export type Callback<Args extends unknown[] = []> = (e?: ApiError, ...args: OptionalTuple<Args>) => unknown;
46
+ import type { EncodingOption, OpenMode, WriteFileOptions } from 'node:fs';
47
+ /**
48
+ * converts Date or number to a integer UNIX timestamp
49
+ * Grabbed from NodeJS sources (lib/fs.js)
50
+ *
51
+ * @internal
52
+ */
53
+ export declare function _toUnixTimestamp(time: Date | number): number;
54
+ /**
55
+ * Normalizes a mode
56
+ * @internal
57
+ */
58
+ export declare function normalizeMode(mode: string | number | unknown, def?: number): number;
59
+ /**
60
+ * Normalizes a time
61
+ * @internal
62
+ */
63
+ export declare function normalizeTime(time: string | number | Date): Date;
64
+ /**
65
+ * Normalizes a path
66
+ * @internal
67
+ */
68
+ export declare function normalizePath(p: string): string;
69
+ /**
70
+ * Normalizes options
71
+ * @param options options to normalize
72
+ * @param encoding default encoding
73
+ * @param flag default flag
74
+ * @param mode default mode
75
+ * @internal
76
+ */
77
+ export declare function normalizeOptions(options?: WriteFileOptions | (EncodingOption & {
78
+ flag?: OpenMode;
79
+ }), encoding?: BufferEncoding, flag?: string, mode?: number): {
80
+ encoding: BufferEncoding;
81
+ flag: string;
82
+ mode: number;
83
+ };
84
+ /**
85
+ * Do nothing
86
+ * @internal
87
+ */
88
+ export declare function nop(): void;
package/dist/utils.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ApiError, ErrorCode } from './ApiError.js';
2
- import { dirname } from './emulation/path.js';
2
+ import { dirname, resolve } from './emulation/path.js';
3
3
  /**
4
4
  * Synchronous recursive makedir.
5
5
  * @hidden
@@ -133,3 +133,96 @@ export function encodeDirListing(data) {
133
133
  return v.toString();
134
134
  }));
135
135
  }
136
+ /**
137
+ * converts Date or number to a integer UNIX timestamp
138
+ * Grabbed from NodeJS sources (lib/fs.js)
139
+ *
140
+ * @internal
141
+ */
142
+ export function _toUnixTimestamp(time) {
143
+ if (typeof time === 'number') {
144
+ return Math.floor(time);
145
+ }
146
+ if (time instanceof Date) {
147
+ return Math.floor(time.getTime() / 1000);
148
+ }
149
+ throw new Error('Cannot parse time: ' + time);
150
+ }
151
+ /**
152
+ * Normalizes a mode
153
+ * @internal
154
+ */
155
+ export function normalizeMode(mode, def) {
156
+ if (typeof mode == 'number') {
157
+ return mode;
158
+ }
159
+ if (typeof mode == 'string') {
160
+ const parsed = parseInt(mode, 8);
161
+ if (!isNaN(parsed)) {
162
+ return parsed;
163
+ }
164
+ }
165
+ if (typeof def == 'number') {
166
+ return def;
167
+ }
168
+ throw new ApiError(ErrorCode.EINVAL, 'Invalid mode: ' + mode?.toString());
169
+ }
170
+ /**
171
+ * Normalizes a time
172
+ * @internal
173
+ */
174
+ export function normalizeTime(time) {
175
+ if (time instanceof Date) {
176
+ return time;
177
+ }
178
+ if (typeof time == 'number') {
179
+ return new Date(time * 1000);
180
+ }
181
+ if (typeof time == 'string') {
182
+ return new Date(time);
183
+ }
184
+ throw new ApiError(ErrorCode.EINVAL, 'Invalid time.');
185
+ }
186
+ /**
187
+ * Normalizes a path
188
+ * @internal
189
+ */
190
+ export function normalizePath(p) {
191
+ // Node doesn't allow null characters in paths.
192
+ if (p.includes('\x00')) {
193
+ throw new ApiError(ErrorCode.EINVAL, 'Path must be a string without null bytes.');
194
+ }
195
+ if (p.length == 0) {
196
+ throw new ApiError(ErrorCode.EINVAL, 'Path must not be empty.');
197
+ }
198
+ return resolve(p.replaceAll(/[/\\]+/g, '/'));
199
+ }
200
+ /**
201
+ * Normalizes options
202
+ * @param options options to normalize
203
+ * @param encoding default encoding
204
+ * @param flag default flag
205
+ * @param mode default mode
206
+ * @internal
207
+ */
208
+ export function normalizeOptions(options, encoding = 'utf8', flag, mode = 0) {
209
+ if (typeof options != 'object' || options === null) {
210
+ return {
211
+ encoding: typeof options == 'string' ? options : encoding,
212
+ flag,
213
+ mode,
214
+ };
215
+ }
216
+ return {
217
+ encoding: typeof options?.encoding == 'string' ? options.encoding : encoding,
218
+ flag: typeof options?.flag == 'string' ? options.flag : flag,
219
+ mode: normalizeMode('mode' in options ? options?.mode : null, mode),
220
+ };
221
+ }
222
+ /**
223
+ * Do nothing
224
+ * @internal
225
+ */
226
+ export function nop() {
227
+ // do nothing
228
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenfs/core",
3
- "version": "0.8.1",
3
+ "version": "0.9.1",
4
4
  "description": "A filesystem in your browser",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist",
@@ -46,7 +46,7 @@
46
46
  "format": "prettier --write .",
47
47
  "format:check": "prettier --check .",
48
48
  "lint": "eslint src tests && tsc -p tsconfig.json --noEmit",
49
- "test": "cross-env NODE_OPTIONS=--experimental-vm-modules npx jest",
49
+ "test": "tsc -p tests/tsconfig.json --noEmit && cross-env NODE_OPTIONS=--experimental-vm-modules npx jest",
50
50
  "build": "node scripts/build.js --globalName=ZenFS --entry src/index.ts",
51
51
  "build:docs": "typedoc --out docs --name ZenFS src/index.ts",
52
52
  "dev": "npm run build -- --watch",
@@ -58,7 +58,7 @@
58
58
  "buffer": "^6.0.3",
59
59
  "minimatch": "^9.0.3",
60
60
  "readable-stream": "^4.5.2",
61
- "utilium": "^0.2.0"
61
+ "utilium": "^0.2.1"
62
62
  },
63
63
  "devDependencies": {
64
64
  "@fal-works/esbuild-plugin-global-externals": "^2.1.2",