@zenfs/core 1.9.2 → 1.9.4

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 (60) hide show
  1. package/dist/backends/backend.d.ts +16 -2
  2. package/dist/backends/backend.js +9 -2
  3. package/dist/backends/fetch.d.ts +9 -0
  4. package/dist/backends/fetch.js +13 -3
  5. package/dist/backends/memory.d.ts +2 -0
  6. package/dist/backends/memory.js +2 -0
  7. package/dist/backends/overlay.d.ts +2 -0
  8. package/dist/backends/overlay.js +1 -0
  9. package/dist/backends/passthrough.d.ts +4 -0
  10. package/dist/backends/port/fs.d.ts +8 -2
  11. package/dist/backends/port/fs.js +6 -0
  12. package/dist/backends/store/fs.d.ts +2 -4
  13. package/dist/backends/store/fs.js +2 -4
  14. package/dist/backends/store/map.d.ts +6 -0
  15. package/dist/backends/store/map.js +4 -0
  16. package/dist/backends/store/simple.d.ts +3 -0
  17. package/dist/backends/store/simple.js +1 -0
  18. package/dist/backends/store/store.d.ts +12 -1
  19. package/dist/backends/store/store.js +5 -1
  20. package/dist/config.d.ts +9 -15
  21. package/dist/config.js +8 -5
  22. package/dist/context.d.ts +3 -4
  23. package/dist/context.js +1 -1
  24. package/dist/internal/credentials.d.ts +9 -0
  25. package/dist/internal/credentials.js +7 -0
  26. package/dist/internal/devices.d.ts +14 -0
  27. package/dist/internal/devices.js +10 -0
  28. package/dist/internal/error.d.ts +6 -0
  29. package/dist/internal/error.js +3 -0
  30. package/dist/internal/file.d.ts +23 -0
  31. package/dist/internal/file.js +23 -1
  32. package/dist/internal/file_index.d.ts +2 -1
  33. package/dist/internal/file_index.js +2 -1
  34. package/dist/internal/filesystem.d.ts +9 -0
  35. package/dist/internal/filesystem.js +1 -0
  36. package/dist/internal/index_fs.d.ts +3 -1
  37. package/dist/internal/index_fs.js +7 -3
  38. package/dist/internal/inode.d.ts +8 -0
  39. package/dist/internal/inode.js +1 -0
  40. package/dist/mixins/async.d.ts +6 -2
  41. package/dist/mixins/async.js +1 -1
  42. package/dist/mixins/mutexed.d.ts +6 -0
  43. package/dist/mixins/mutexed.js +6 -0
  44. package/dist/mixins/readonly.d.ts +1 -0
  45. package/dist/mixins/readonly.js +1 -0
  46. package/dist/mixins/shared.d.ts +3 -0
  47. package/dist/mixins/sync.d.ts +1 -0
  48. package/dist/mixins/sync.js +1 -0
  49. package/dist/vfs/promises.d.ts +2 -2
  50. package/dist/vfs/promises.js +71 -78
  51. package/dist/vfs/shared.d.ts +14 -1
  52. package/dist/vfs/shared.js +4 -6
  53. package/dist/vfs/sync.d.ts +2 -2
  54. package/dist/vfs/sync.js +48 -48
  55. package/dist/vfs/types.d.ts +1 -13
  56. package/package.json +1 -1
  57. package/readme.md +4 -0
  58. package/tests/backend/fetch.test.ts +3 -2
  59. package/dist/vfs/cache.d.ts +0 -46
  60. package/dist/vfs/cache.js +0 -75
@@ -1,6 +1,7 @@
1
1
  import { Errno, ErrnoError } from '../internal/error.js';
2
2
  /**
3
3
  * Implements the non-readonly methods to throw `EROFS`
4
+ * @category Internals
4
5
  */
5
6
  /* eslint-disable @typescript-eslint/require-await */
6
7
  export function Readonly(FS) {
@@ -2,6 +2,7 @@ import type { ExtractProperties } from 'utilium';
2
2
  import type { FileSystem } from '../internal/filesystem.js';
3
3
  /**
4
4
  * `TBase` with `TMixin` mixed-in.
5
+ * @category Internals
5
6
  * @internal
6
7
  */
7
8
  export type Mixin<TBase extends typeof FileSystem, TMixin> = (abstract new (...args: any[]) => TMixin) & TBase;
@@ -19,11 +20,13 @@ export type _AsyncFSKeys = {
19
20
  }[_SyncFSKeys];
20
21
  /**
21
22
  * Asynchronous `FileSystem` methods. This is a convenience type for all of the async operations.
23
+ * @category Internals
22
24
  * @internal
23
25
  */
24
26
  export type AsyncFSMethods = Pick<FileSystem, _AsyncFSKeys>;
25
27
  /**
26
28
  * Concrete `FileSystem`. This is a convenience type.
29
+ * @category Internals
27
30
  * @internal
28
31
  */
29
32
  export type ConcreteFS = ExtractProperties<FileSystem, any>;
@@ -2,5 +2,6 @@ import type { FileSystem } from '../internal/filesystem.js';
2
2
  import type { AsyncFSMethods, Mixin } from './shared.js';
3
3
  /**
4
4
  * Implements the asynchronous API in terms of the synchronous API.
5
+ * @category Internals
5
6
  */
6
7
  export declare function Sync<T extends abstract new (...args: any[]) => FileSystem>(FS: T): Mixin<T, AsyncFSMethods>;
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * Implements the asynchronous API in terms of the synchronous API.
3
+ * @category Internals
3
4
  */
4
5
  /* eslint-disable @typescript-eslint/require-await */
5
6
  export function Sync(FS) {
@@ -6,7 +6,7 @@ import type { Interface as ReadlineInterface } from 'readline';
6
6
  import type { V_Context } from '../context.js';
7
7
  import type { File } from '../internal/file.js';
8
8
  import type { Stats } from '../stats.js';
9
- import type { FileContents, InternalOptions, NullEnc, ReaddirOptions, ReaddirOptsI, ReaddirOptsU } from './types.js';
9
+ import type { FileContents, NullEnc, ReaddirOptions, ReaddirOptsI, ReaddirOptsU } from './types.js';
10
10
  import { Buffer } from 'buffer';
11
11
  import '../polyfills.js';
12
12
  import { BigIntStats } from '../stats.js';
@@ -304,7 +304,7 @@ export declare function access(this: V_Context, path: fs.PathLike, mode?: number
304
304
  * Asynchronous `rm`. Removes files or directories (recursively).
305
305
  * @param path The path to the file or directory to remove.
306
306
  */
307
- export declare function rm(this: V_Context, path: fs.PathLike, options?: fs.RmOptions & InternalOptions): Promise<void>;
307
+ export declare function rm(this: V_Context, path: fs.PathLike, options?: fs.RmOptions): Promise<void>;
308
308
  /**
309
309
  * Asynchronous `mkdtemp`. Creates a unique temporary directory.
310
310
  * @param prefix The directory prefix.
@@ -57,7 +57,6 @@ import { flagToMode, isAppendable, isExclusive, isReadable, isTruncating, isWrit
57
57
  import '../polyfills.js';
58
58
  import { BigIntStats } from '../stats.js';
59
59
  import { decodeUTF8, normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
60
- import * as cache from './cache.js';
61
60
  import { config } from './config.js';
62
61
  import * as constants from './constants.js';
63
62
  import { Dir, Dirent } from './dir.js';
@@ -459,7 +458,7 @@ export async function unlink(path) {
459
458
  path = normalizePath(path);
460
459
  const { fs, path: resolved } = resolveMount(path, this);
461
460
  try {
462
- if (config.checkAccess && !(await (cache.stats.getAsync(path) || fs.stat(resolved))).hasAccess(constants.W_OK, this)) {
461
+ if (config.checkAccess && !(await fs.stat(resolved)).hasAccess(constants.W_OK, this)) {
463
462
  throw ErrnoError.With('EACCES', resolved, 'unlink');
464
463
  }
465
464
  await fs.unlink(resolved);
@@ -484,37 +483,35 @@ async function applySetId(file, uid, gid) {
484
483
  * Opens a file. This helper handles the complexity of file flags.
485
484
  * @internal
486
485
  */
487
- async function _open(path, opt) {
486
+ async function _open($, path, opt) {
488
487
  var _a;
489
488
  path = normalizePath(path);
490
489
  const mode = normalizeMode(opt.mode, 0o644), flag = parseFlag(opt.flag);
491
- path = opt.preserveSymlinks ? path : await realpath.call(this, path);
492
- const { fs, path: resolved } = resolveMount(path, this);
493
- const stats = await fs.stat(resolved).catch(() => null);
490
+ const { fullPath: realpath, fs, path: resolved, stats } = await _resolve($, path.toString(), opt.preserveSymlinks);
494
491
  if (!stats) {
495
492
  if ((!isWriteable(flag) && !isAppendable(flag)) || flag == 'r+') {
496
- throw ErrnoError.With('ENOENT', path, '_open');
493
+ throw ErrnoError.With('ENOENT', realpath, '_open');
497
494
  }
498
495
  // Create the file
499
496
  const parentStats = await fs.stat(dirname(resolved));
500
- if (config.checkAccess && !parentStats.hasAccess(constants.W_OK, this)) {
501
- throw ErrnoError.With('EACCES', dirname(path), '_open');
497
+ if (config.checkAccess && !parentStats.hasAccess(constants.W_OK, $)) {
498
+ throw ErrnoError.With('EACCES', dirname(realpath), '_open');
502
499
  }
503
500
  if (!parentStats.isDirectory()) {
504
- throw ErrnoError.With('ENOTDIR', dirname(path), '_open');
501
+ throw ErrnoError.With('ENOTDIR', dirname(realpath), '_open');
505
502
  }
506
- const { euid: uid, egid: gid } = (_a = this === null || this === void 0 ? void 0 : this.credentials) !== null && _a !== void 0 ? _a : credentials;
503
+ const { euid: uid, egid: gid } = (_a = $ === null || $ === void 0 ? void 0 : $.credentials) !== null && _a !== void 0 ? _a : credentials;
507
504
  const file = await fs.createFile(resolved, flag, mode, { uid, gid });
508
505
  await applySetId(file, uid, gid);
509
- return new FileHandle(file, this);
506
+ return new FileHandle(file, $);
510
507
  }
511
- if (config.checkAccess && !stats.hasAccess(flagToMode(flag), this)) {
512
- throw ErrnoError.With('EACCES', path, '_open');
508
+ if (config.checkAccess && !stats.hasAccess(flagToMode(flag), $)) {
509
+ throw ErrnoError.With('EACCES', realpath, '_open');
513
510
  }
514
511
  if (isExclusive(flag)) {
515
- throw ErrnoError.With('EEXIST', path, '_open');
512
+ throw ErrnoError.With('EEXIST', realpath, '_open');
516
513
  }
517
- const handle = new FileHandle(await fs.openFile(resolved, flag), this);
514
+ const handle = new FileHandle(await fs.openFile(resolved, flag), $);
518
515
  /*
519
516
  In a previous implementation, we deleted the file and
520
517
  re-created it. However, this created a race condition if another
@@ -533,7 +530,7 @@ async function _open(path, opt) {
533
530
  * @param mode Mode to use to open the file. Can be ignored if the filesystem doesn't support permissions.
534
531
  */
535
532
  export async function open(path, flag = 'r', mode = 0o644) {
536
- return await _open.call(this, path, { flag, mode });
533
+ return await _open(this, path, { flag, mode });
537
534
  }
538
535
  open;
539
536
  export async function readFile(path, _options) {
@@ -625,7 +622,7 @@ export async function rmdir(path) {
625
622
  path = await realpath.call(this, path);
626
623
  const { fs, path: resolved } = resolveMount(path, this);
627
624
  try {
628
- const stats = await (cache.stats.getAsync(path) || fs.stat(resolved));
625
+ const stats = await fs.stat(resolved);
629
626
  if (!stats) {
630
627
  throw ErrnoError.With('ENOENT', path, 'rmdir');
631
628
  }
@@ -688,9 +685,7 @@ export async function readdir(path, options) {
688
685
  throw fixError(e, { [resolved]: path });
689
686
  };
690
687
  const { fs, path: resolved } = resolveMount(path, this);
691
- const _stats = cache.stats.getAsync(path) || fs.stat(resolved).catch(handleError);
692
- cache.stats.setAsync(path, _stats);
693
- const stats = await _stats;
688
+ const stats = await fs.stat(resolved).catch(handleError);
694
689
  if (!stats) {
695
690
  throw ErrnoError.With('ENOENT', path, 'readdir');
696
691
  }
@@ -705,9 +700,7 @@ export async function readdir(path, options) {
705
700
  const addEntry = async (entry) => {
706
701
  let entryStats;
707
702
  if ((options === null || options === void 0 ? void 0 : options.recursive) || (options === null || options === void 0 ? void 0 : options.withFileTypes)) {
708
- const _entryStats = cache.stats.getAsync(join(path, entry)) || fs.stat(join(resolved, entry)).catch(handleError);
709
- cache.stats.setAsync(join(path, entry), _entryStats);
710
- entryStats = await _entryStats;
703
+ entryStats = await fs.stat(join(resolved, entry)).catch(handleError);
711
704
  }
712
705
  if (options === null || options === void 0 ? void 0 : options.withFileTypes) {
713
706
  values.push(new Dirent(entry, entryStats));
@@ -720,7 +713,7 @@ export async function readdir(path, options) {
720
713
  }
721
714
  if (!(options === null || options === void 0 ? void 0 : options.recursive) || !(entryStats === null || entryStats === void 0 ? void 0 : entryStats.isDirectory()))
722
715
  return;
723
- for (const subEntry of await readdir.call(this, join(path, entry), { ...options, _isIndirect: true })) {
716
+ for (const subEntry of await readdir.call(this, join(path, entry), options)) {
724
717
  if (subEntry instanceof Dirent) {
725
718
  subEntry.path = join(entry, subEntry.path);
726
719
  values.push(subEntry);
@@ -735,9 +728,6 @@ export async function readdir(path, options) {
735
728
  }
736
729
  };
737
730
  await Promise.all(entries.map(addEntry));
738
- if (!(options === null || options === void 0 ? void 0 : options._isIndirect)) {
739
- cache.stats.clear();
740
- }
741
731
  return values;
742
732
  }
743
733
  readdir;
@@ -781,7 +771,7 @@ export async function symlink(target, path, type = 'file') {
781
771
  if (await exists.call(this, path)) {
782
772
  throw ErrnoError.With('EEXIST', path.toString(), 'symlink');
783
773
  }
784
- const handle = __addDisposableResource(env_5, await _open.call(this, path, { flag: 'w+', mode: 0o644, preserveSymlinks: true }), true);
774
+ const handle = __addDisposableResource(env_5, await _open(this, path, { flag: 'w+', mode: 0o644, preserveSymlinks: true }), true);
785
775
  await handle.writeFile(target.toString());
786
776
  await handle.file.chmod(constants.S_IFLNK);
787
777
  }
@@ -799,7 +789,7 @@ symlink;
799
789
  export async function readlink(path, options) {
800
790
  const env_6 = { stack: [], error: void 0, hasError: false };
801
791
  try {
802
- const handle = __addDisposableResource(env_6, await _open.call(this, normalizePath(path), { flag: 'r', mode: 0o644, preserveSymlinks: true }), true);
792
+ const handle = __addDisposableResource(env_6, await _open(this, normalizePath(path), { flag: 'r', mode: 0o644, preserveSymlinks: true }), true);
803
793
  const value = await handle.readFile();
804
794
  const encoding = typeof options == 'object' ? options === null || options === void 0 ? void 0 : options.encoding : options;
805
795
  // always defaults to utf-8 to avoid wrangler (cloudflare) worker "unknown encoding" exception
@@ -836,7 +826,7 @@ chown;
836
826
  export async function lchown(path, uid, gid) {
837
827
  const env_8 = { stack: [], error: void 0, hasError: false };
838
828
  try {
839
- const handle = __addDisposableResource(env_8, await _open.call(this, path, {
829
+ const handle = __addDisposableResource(env_8, await _open(this, path, {
840
830
  flag: 'r+',
841
831
  mode: 0o644,
842
832
  preserveSymlinks: true,
@@ -875,7 +865,7 @@ chmod;
875
865
  export async function lchmod(path, mode) {
876
866
  const env_10 = { stack: [], error: void 0, hasError: false };
877
867
  try {
878
- const handle = __addDisposableResource(env_10, await _open.call(this, path, {
868
+ const handle = __addDisposableResource(env_10, await _open(this, path, {
879
869
  flag: 'r+',
880
870
  mode: 0o644,
881
871
  preserveSymlinks: true,
@@ -920,7 +910,7 @@ utimes;
920
910
  export async function lutimes(path, atime, mtime) {
921
911
  const env_12 = { stack: [], error: void 0, hasError: false };
922
912
  try {
923
- const handle = __addDisposableResource(env_12, await _open.call(this, path, {
913
+ const handle = __addDisposableResource(env_12, await _open(this, path, {
924
914
  flag: 'r+',
925
915
  mode: 0o644,
926
916
  preserveSymlinks: true,
@@ -939,52 +929,64 @@ export async function lutimes(path, atime, mtime) {
939
929
  }
940
930
  }
941
931
  lutimes;
942
- export async function realpath(path, options) {
943
- path = normalizePath(path);
944
- const ctx_path = ((this === null || this === void 0 ? void 0 : this.root) || '') + path;
945
- if (cache.paths.hasAsync(ctx_path))
946
- return cache.paths.getAsync(ctx_path);
932
+ /**
933
+ * Resolves the mount and real path for a path.
934
+ * Additionally, any stats fetched will be returned for de-duplication
935
+ * @internal @hidden
936
+ */
937
+ async function _resolve($, path, preserveSymlinks) {
938
+ if (preserveSymlinks) {
939
+ const resolved = resolveMount(path, $);
940
+ const stats = await resolved.fs.stat(resolved.path).catch(() => undefined);
941
+ return { ...resolved, fullPath: path, stats };
942
+ }
947
943
  /* Try to resolve it directly. If this works,
948
944
  that means we don't need to perform any resolution for parent directories. */
949
945
  try {
950
- const { fs, path: resolvedPath } = resolveMount(path, this);
946
+ const resolved = resolveMount(path, $);
951
947
  // Stat it to make sure it exists
952
- const stats = await fs.stat(resolvedPath);
953
- let real = path.toString();
954
- if (stats.isSymbolicLink()) {
955
- const target = resolve(dirname(resolvedPath), (await readlink.call(this, resolvedPath, options)).toString());
956
- real = cache.paths.get(((this === null || this === void 0 ? void 0 : this.root) || '') + target) || (await realpath.call(this, target));
957
- cache.paths.set(ctx_path, real);
948
+ const stats = await resolved.fs.stat(resolved.path);
949
+ if (!stats.isSymbolicLink()) {
950
+ return { ...resolved, fullPath: path, stats };
958
951
  }
959
- cache.paths.set(path.toString(), real);
960
- return real;
952
+ const target = resolve(dirname(path), (await readlink.call($, path)).toString());
953
+ return await _resolve($, target);
961
954
  }
962
955
  catch {
963
956
  // Go the long way
964
957
  }
965
958
  const { base, dir } = parse(path);
966
- const realDir = dir == '/' ? '/' : await (cache.paths.getAsync(((this === null || this === void 0 ? void 0 : this.root) || '') + dir) || realpath.call(this, dir));
967
- const lpath = join(realDir, base);
968
- const { fs, path: resolvedPath } = resolveMount(lpath, this);
959
+ const realDir = dir == '/' ? '/' : await realpath.call($, dir);
960
+ const maybePath = join(realDir, base);
961
+ const resolved = resolveMount(maybePath, $);
969
962
  try {
970
- const _stats = cache.stats.getAsync(lpath) || fs.stat(resolvedPath);
971
- cache.stats.setAsync(lpath, _stats);
972
- if (!(await _stats).isSymbolicLink()) {
973
- cache.paths.set(path, lpath);
974
- return lpath;
963
+ const stats = await resolved.fs.stat(resolved.path);
964
+ if (!stats.isSymbolicLink()) {
965
+ return { ...resolved, fullPath: maybePath, stats };
975
966
  }
976
- const target = resolve(realDir, (await readlink.call(this, lpath)).toString());
977
- const real = cache.paths.getAsync(((this === null || this === void 0 ? void 0 : this.root) || '') + target) || realpath.call(this, target);
978
- cache.paths.setAsync(ctx_path, real);
979
- return await real;
967
+ const target = resolve(realDir, (await readlink.call($, maybePath)).toString());
968
+ const real = await realpath.call($, target);
969
+ return { ...resolved, fullPath: real, stats };
980
970
  }
981
971
  catch (e) {
982
972
  if (e.code == 'ENOENT') {
983
- return path;
973
+ return { ...resolved, fullPath: path };
984
974
  }
985
- throw fixError(e, { [resolvedPath]: lpath });
975
+ throw fixError(e, { [resolved.path]: maybePath });
986
976
  }
987
977
  }
978
+ export async function realpath(path, options) {
979
+ var _a;
980
+ const encoding = typeof options == 'string' ? options : ((_a = options === null || options === void 0 ? void 0 : options.encoding) !== null && _a !== void 0 ? _a : 'utf8');
981
+ path = normalizePath(path);
982
+ const { fullPath } = await _resolve(this, path);
983
+ if (encoding == 'utf8' || encoding == 'utf-8')
984
+ return fullPath;
985
+ const buf = Buffer.from(fullPath, 'utf-8');
986
+ if (encoding == 'buffer')
987
+ return buf;
988
+ return buf.toString(encoding);
989
+ }
988
990
  realpath;
989
991
  export function watch(filename, options = {}) {
990
992
  const watcher = new FSWatcher(this, filename.toString(), typeof options !== 'string' ? options : { encoding: options });
@@ -1038,23 +1040,18 @@ access;
1038
1040
  */
1039
1041
  export async function rm(path, options) {
1040
1042
  path = normalizePath(path);
1041
- const stats = await (cache.stats.getAsync(path) ||
1042
- lstat.call(this, path).catch((error) => {
1043
- if (error.code == 'ENOENT' && (options === null || options === void 0 ? void 0 : options.force))
1044
- return undefined;
1045
- throw error;
1046
- }));
1047
- if (!stats) {
1043
+ const stats = await lstat.call(this, path).catch((error) => {
1044
+ if (error.code == 'ENOENT' && (options === null || options === void 0 ? void 0 : options.force))
1045
+ return undefined;
1046
+ throw error;
1047
+ });
1048
+ if (!stats)
1048
1049
  return;
1049
- }
1050
- cache.stats.set(path, stats);
1051
1050
  switch (stats.mode & constants.S_IFMT) {
1052
1051
  case constants.S_IFDIR:
1053
1052
  if (options === null || options === void 0 ? void 0 : options.recursive) {
1054
- for (const entry of await readdir.call(this, path, {
1055
- _isIndirect: true,
1056
- })) {
1057
- await rm.call(this, join(path, entry), { ...options, _isIndirect: true });
1053
+ for (const entry of (await readdir.call(this, path))) {
1054
+ await rm.call(this, join(path, entry), options);
1058
1055
  }
1059
1056
  }
1060
1057
  await rmdir.call(this, path);
@@ -1068,12 +1065,8 @@ export async function rm(path, options) {
1068
1065
  case constants.S_IFIFO:
1069
1066
  case constants.S_IFSOCK:
1070
1067
  default:
1071
- cache.stats.clear();
1072
1068
  throw new ErrnoError(Errno.EPERM, 'File type not supported', path, 'rm');
1073
1069
  }
1074
- if (!(options === null || options === void 0 ? void 0 : options._isIndirect)) {
1075
- cache.stats.clear();
1076
- }
1077
1070
  }
1078
1071
  rm;
1079
1072
  export async function mkdtemp(prefix, options) {
@@ -1,6 +1,7 @@
1
1
  import type * as fs from 'node:fs';
2
2
  import type { File } from '../internal/file.js';
3
3
  import type { FileSystem } from '../internal/filesystem.js';
4
+ import type { Stats } from '../stats.js';
4
5
  import { type BoundContext, type V_Context } from '../context.js';
5
6
  import { ErrnoError } from '../internal/error.js';
6
7
  import { type AbsolutePath } from './path.js';
@@ -22,16 +23,19 @@ export declare function fd2file(fd: number): File;
22
23
  export type MountObject = Record<AbsolutePath, FileSystem>;
23
24
  /**
24
25
  * The map of mount points
26
+ * @category Backends and Configuration
25
27
  * @internal
26
28
  */
27
29
  export declare const mounts: Map<string, FileSystem>;
28
30
  /**
29
31
  * Mounts the file system at `mountPoint`.
32
+ * @category Backends and Configuration
30
33
  * @internal
31
34
  */
32
35
  export declare function mount(mountPoint: string, fs: FileSystem): void;
33
36
  /**
34
37
  * Unmounts the file system at `mountPoint`.
38
+ * @category Backends and Configuration
35
39
  */
36
40
  export declare function umount(mountPoint: string): void;
37
41
  /**
@@ -43,6 +47,15 @@ export interface ResolvedMount {
43
47
  mountPoint: string;
44
48
  root: string;
45
49
  }
50
+ /**
51
+ * @internal @hidden
52
+ */
53
+ export interface ResolvedPath extends ResolvedMount {
54
+ /** The real, absolute path */
55
+ fullPath: string;
56
+ /** Stats */
57
+ stats?: Stats;
58
+ }
46
59
  /**
47
60
  * Gets the internal `FileSystem` for the path, then returns it along with the path relative to the FS' root
48
61
  * @internal @hidden
@@ -69,7 +82,7 @@ export declare function _statfs<const T extends boolean>(fs: FileSystem, bigint?
69
82
  /**
70
83
  * Change the root path
71
84
  * @param inPlace if true, this changes the root for the current context instead of creating a new one (if associated with a context).
72
- * @experimental
85
+ * @category Backends and Configuration
73
86
  */
74
87
  export declare function chroot(this: V_Context, path: string, inPlace?: false): BoundContext;
75
88
  export declare function chroot<T extends V_Context>(this: T, path: string, inPlace: true): T;
@@ -4,10 +4,8 @@ import { bindContext } from '../context.js';
4
4
  import { Errno, ErrnoError } from '../internal/error.js';
5
5
  import { alert, debug, err, info, log_deprecated, notice, warn } from '../internal/log.js';
6
6
  import { normalizePath } from '../utils.js';
7
- import { paths as pathCache } from './cache.js';
8
7
  import { size_max } from './constants.js';
9
8
  import { join, resolve } from './path.js';
10
- import { ZenFsType } from '../stats.js';
11
9
  // descriptors
12
10
  /**
13
11
  * @internal @hidden
@@ -33,6 +31,7 @@ export function fd2file(fd) {
33
31
  }
34
32
  /**
35
33
  * The map of mount points
34
+ * @category Backends and Configuration
36
35
  * @internal
37
36
  */
38
37
  export const mounts = new Map();
@@ -40,6 +39,7 @@ export const mounts = new Map();
40
39
  mount('/', InMemory.create({ name: 'root' }));
41
40
  /**
42
41
  * Mounts the file system at `mountPoint`.
42
+ * @category Backends and Configuration
43
43
  * @internal
44
44
  */
45
45
  export function mount(mountPoint, fs) {
@@ -53,10 +53,10 @@ export function mount(mountPoint, fs) {
53
53
  mounts.set(mountPoint, fs);
54
54
  info(`Mounted ${fs.name} on ${mountPoint}`);
55
55
  debug(`${fs.name} attributes: ${[...fs.attributes].map(([k, v]) => (v !== undefined && v !== null ? k + '=' + v : v)).join(', ')}`);
56
- pathCache.clear();
57
56
  }
58
57
  /**
59
58
  * Unmounts the file system at `mountPoint`.
59
+ * @category Backends and Configuration
60
60
  */
61
61
  export function umount(mountPoint) {
62
62
  if (mountPoint[0] != '/')
@@ -67,7 +67,6 @@ export function umount(mountPoint) {
67
67
  return;
68
68
  }
69
69
  mounts.delete(mountPoint);
70
- pathCache.clear();
71
70
  notice('Unmounted ' + mountPoint);
72
71
  }
73
72
  /**
@@ -82,9 +81,8 @@ export function resolveMount(path, ctx) {
82
81
  // We know path is normalized, so it would be a substring of the mount point.
83
82
  if (_isParentOf(mountPoint, path)) {
84
83
  path = path.slice(mountPoint.length > 1 ? mountPoint.length : 0); // Resolve the path relative to the mount point
85
- if (path === '') {
84
+ if (path === '')
86
85
  path = root;
87
- }
88
86
  return { fs, path, mountPoint, root };
89
87
  }
90
88
  }
@@ -1,7 +1,7 @@
1
1
  import type * as fs from 'node:fs';
2
2
  import type { V_Context } from '../context.js';
3
3
  import type { Stats } from '../stats.js';
4
- import type { FileContents, InternalOptions, NullEnc, ReaddirOptions, ReaddirOptsI, ReaddirOptsU } from './types.js';
4
+ import type { FileContents, NullEnc, ReaddirOptions, ReaddirOptsI, ReaddirOptsU } from './types.js';
5
5
  import { Buffer } from 'buffer';
6
6
  import { BigIntStats } from '../stats.js';
7
7
  import { Dir, Dirent } from './dir.js';
@@ -155,7 +155,7 @@ export declare function accessSync(this: V_Context, path: fs.PathLike, mode?: nu
155
155
  * Synchronous `rm`. Removes files or directories (recursively).
156
156
  * @param path The path to the file or directory to remove.
157
157
  */
158
- export declare function rmSync(this: V_Context, path: fs.PathLike, options?: fs.RmOptions & InternalOptions): void;
158
+ export declare function rmSync(this: V_Context, path: fs.PathLike, options?: fs.RmOptions): void;
159
159
  /**
160
160
  * Synchronous `mkdtemp`. Creates a unique temporary directory.
161
161
  * @param prefix The directory prefix.