@zenfs/core 1.1.0 → 1.1.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.
@@ -265,6 +265,11 @@ export declare function readdir(path: fs.PathLike, options: fs.ObjectEncodingOpt
265
265
  withFileTypes: true;
266
266
  recursive?: boolean;
267
267
  }): Promise<Dirent[]>;
268
+ export declare function readdir(path: fs.PathLike, options?: {
269
+ withFileTypes?: boolean;
270
+ recursive?: boolean;
271
+ encoding?: BufferEncoding | 'buffer' | null;
272
+ } | BufferEncoding | 'buffer' | null): Promise<string[] | Dirent[] | Buffer[]>;
268
273
  export declare function link(targetPath: fs.PathLike, linkPath: fs.PathLike): Promise<void>;
269
274
  /**
270
275
  * `symlink`.
@@ -51,7 +51,7 @@ import { Errno, ErrnoError } from '../error.js';
51
51
  import { flagToMode, isAppendable, isExclusive, isReadable, isTruncating, isWriteable, parseFlag } from '../file.js';
52
52
  import '../polyfills.js';
53
53
  import { BigIntStats } from '../stats.js';
54
- import { normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
54
+ import { decodeUTF8, normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
55
55
  import * as constants from './constants.js';
56
56
  import { Dir, Dirent } from './dir.js';
57
57
  import { dirname, join, parse } from './path.js';
@@ -627,19 +627,16 @@ export async function mkdir(path, options) {
627
627
  }
628
628
  mkdir;
629
629
  export async function readdir(path, options) {
630
+ options = typeof options === 'object' ? options : { encoding: options };
630
631
  path = normalizePath(path);
631
632
  if (!(await stat(path)).hasAccess(constants.R_OK)) {
632
633
  throw ErrnoError.With('EACCES', path, 'readdir');
633
634
  }
634
635
  path = (await exists(path)) ? await realpath(path) : path;
635
636
  const { fs, path: resolved } = resolveMount(path);
636
- let entries;
637
- try {
638
- entries = await fs.readdir(resolved);
639
- }
640
- catch (e) {
637
+ const entries = await fs.readdir(resolved).catch((e) => {
641
638
  throw fixError(e, { [resolved]: path });
642
- }
639
+ });
643
640
  for (const point of mounts.keys()) {
644
641
  if (point.startsWith(path)) {
645
642
  const entry = point.slice(path.length);
@@ -652,12 +649,37 @@ export async function readdir(path, options) {
652
649
  }
653
650
  const values = [];
654
651
  for (const entry of entries) {
655
- values.push(typeof options == 'object' && options?.withFileTypes ? new Dirent(entry, await stat(join(path, entry))) : entry);
652
+ const fullPath = join(path, entry);
653
+ const stats = options?.recursive || options?.withFileTypes ? await stat(fullPath) : null;
654
+ if (options?.withFileTypes) {
655
+ values.push(new Dirent(entry, stats));
656
+ }
657
+ else if (options?.encoding === 'buffer') {
658
+ values.push(Buffer.from(entry));
659
+ }
660
+ else {
661
+ values.push(entry);
662
+ }
663
+ if (!options?.recursive || !stats?.isDirectory()) {
664
+ continue;
665
+ }
666
+ for (const subEntry of await readdir(fullPath, options)) {
667
+ if (subEntry instanceof Dirent) {
668
+ subEntry.path = join(entry, subEntry.path);
669
+ values.push(subEntry);
670
+ }
671
+ else if (Buffer.isBuffer(subEntry)) {
672
+ // Convert Buffer to string, prefix with the full path
673
+ values.push(Buffer.from(join(entry, decodeUTF8(subEntry))));
674
+ }
675
+ else {
676
+ values.push(join(entry, subEntry));
677
+ }
678
+ }
656
679
  }
657
680
  return values;
658
681
  }
659
682
  readdir;
660
- // SYMLINK METHODS
661
683
  export async function link(targetPath, linkPath) {
662
684
  targetPath = normalizePath(targetPath);
663
685
  if (!(await stat(dirname(targetPath))).hasAccess(constants.R_OK)) {
@@ -128,6 +128,11 @@ export declare function readdirSync(path: fs.PathLike, options?: (fs.ObjectEncod
128
128
  withFileTypes?: false;
129
129
  recursive?: boolean;
130
130
  }) | BufferEncoding | null): string[] | Buffer[];
131
+ export declare function readdirSync(path: fs.PathLike, options?: {
132
+ withFileTypes?: boolean;
133
+ recursive?: boolean;
134
+ encoding?: BufferEncoding | 'buffer' | null;
135
+ } | BufferEncoding | 'buffer' | null): string[] | Dirent[] | Buffer[];
131
136
  export declare function linkSync(targetPath: fs.PathLike, linkPath: fs.PathLike): void;
132
137
  /**
133
138
  * Synchronous `symlink`.
@@ -49,7 +49,7 @@ import { Buffer } from 'buffer';
49
49
  import { Errno, ErrnoError } from '../error.js';
50
50
  import { flagToMode, isAppendable, isExclusive, isReadable, isTruncating, isWriteable, parseFlag } from '../file.js';
51
51
  import { BigIntStats } from '../stats.js';
52
- import { normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
52
+ import { decodeUTF8, normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
53
53
  import * as constants from './constants.js';
54
54
  import { Dir, Dirent } from './dir.js';
55
55
  import { dirname, join, parse } from './path.js';
@@ -431,6 +431,7 @@ export function mkdirSync(path, options) {
431
431
  }
432
432
  mkdirSync;
433
433
  export function readdirSync(path, options) {
434
+ options = typeof options === 'object' ? options : { encoding: options };
434
435
  path = normalizePath(path);
435
436
  const { fs, path: resolved } = resolveMount(existsSync(path) ? realpathSync(path) : path);
436
437
  let entries;
@@ -454,15 +455,36 @@ export function readdirSync(path, options) {
454
455
  }
455
456
  entries.push(entry);
456
457
  }
457
- return entries.map((entry) => {
458
- if (typeof options == 'object' && options?.withFileTypes) {
459
- return new Dirent(entry, statSync(join(path.toString(), entry)));
458
+ // Iterate over entries and handle recursive case if needed
459
+ const values = [];
460
+ for (const entry of entries) {
461
+ const fullPath = join(path, entry);
462
+ const entryStat = statSync(fullPath);
463
+ if (options?.withFileTypes) {
464
+ values.push(new Dirent(entry, entryStat));
460
465
  }
461
- if (options == 'buffer' || (typeof options == 'object' && options?.encoding == 'buffer')) {
462
- return Buffer.from(entry);
466
+ else if (options?.encoding === 'buffer') {
467
+ values.push(Buffer.from(entry));
463
468
  }
464
- return entry;
465
- });
469
+ else {
470
+ values.push(entry);
471
+ }
472
+ if (!entryStat.isDirectory() || !options?.recursive)
473
+ continue;
474
+ for (const subEntry of readdirSync(fullPath, options)) {
475
+ if (subEntry instanceof Dirent) {
476
+ subEntry.path = join(entry, subEntry.path);
477
+ values.push(subEntry);
478
+ }
479
+ else if (Buffer.isBuffer(subEntry)) {
480
+ values.push(Buffer.from(join(entry, decodeUTF8(subEntry))));
481
+ }
482
+ else {
483
+ values.push(join(entry, subEntry));
484
+ }
485
+ }
486
+ }
487
+ return values;
466
488
  }
467
489
  readdirSync;
468
490
  // SYMLINK METHODS
package/package.json CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "name": "@zenfs/core",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "A filesystem, anywhere",
5
+ "funding": {
6
+ "type": "individual",
7
+ "url": "https://github.com/sponsors/james-pre"
8
+ },
5
9
  "main": "dist/index.js",
6
10
  "types": "dist/index.d.ts",
7
11
  "keywords": [
@@ -13,7 +13,7 @@ import { flagToMode, isAppendable, isExclusive, isReadable, isTruncating, isWrit
13
13
  import type { FileContents } from '../filesystem.js';
14
14
  import '../polyfills.js';
15
15
  import { BigIntStats, type Stats } from '../stats.js';
16
- import { normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
16
+ import { decodeUTF8, normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
17
17
  import * as constants from './constants.js';
18
18
  import { Dir, Dirent } from './dir.js';
19
19
  import { dirname, join, parse } from './path.js';
@@ -692,22 +692,28 @@ export async function readdir(
692
692
  options?: (fs.ObjectEncodingOptions & { withFileTypes?: false; recursive?: boolean }) | BufferEncoding | null
693
693
  ): Promise<string[] | Buffer[]>;
694
694
  export async function readdir(path: fs.PathLike, options: fs.ObjectEncodingOptions & { withFileTypes: true; recursive?: boolean }): Promise<Dirent[]>;
695
+ export async function readdir(
696
+ path: fs.PathLike,
697
+ options?: { withFileTypes?: boolean; recursive?: boolean; encoding?: BufferEncoding | 'buffer' | null } | BufferEncoding | 'buffer' | null
698
+ ): Promise<string[] | Dirent[] | Buffer[]>;
695
699
  export async function readdir(
696
700
  path: fs.PathLike,
697
701
  options?: { withFileTypes?: boolean; recursive?: boolean; encoding?: BufferEncoding | 'buffer' | null } | BufferEncoding | 'buffer' | null
698
702
  ): Promise<string[] | Dirent[] | Buffer[]> {
703
+ options = typeof options === 'object' ? options : { encoding: options };
699
704
  path = normalizePath(path);
705
+
700
706
  if (!(await stat(path)).hasAccess(constants.R_OK)) {
701
707
  throw ErrnoError.With('EACCES', path, 'readdir');
702
708
  }
709
+
703
710
  path = (await exists(path)) ? await realpath(path) : path;
704
711
  const { fs, path: resolved } = resolveMount(path);
705
- let entries: string[];
706
- try {
707
- entries = await fs.readdir(resolved);
708
- } catch (e) {
712
+
713
+ const entries = await fs.readdir(resolved).catch((e: Error) => {
709
714
  throw fixError(e as Error, { [resolved]: path });
710
- }
715
+ });
716
+
711
717
  for (const point of mounts.keys()) {
712
718
  if (point.startsWith(path)) {
713
719
  const entry = point.slice(path.length);
@@ -718,16 +724,41 @@ export async function readdir(
718
724
  entries.push(entry);
719
725
  }
720
726
  }
721
- const values: (string | Dirent)[] = [];
727
+
728
+ const values: (string | Dirent | Buffer)[] = [];
722
729
  for (const entry of entries) {
723
- values.push(typeof options == 'object' && options?.withFileTypes ? new Dirent(entry, await stat(join(path, entry))) : entry);
730
+ const fullPath = join(path, entry);
731
+
732
+ const stats = options?.recursive || options?.withFileTypes ? await stat(fullPath) : null;
733
+ if (options?.withFileTypes) {
734
+ values.push(new Dirent(entry, stats!));
735
+ } else if (options?.encoding === 'buffer') {
736
+ values.push(Buffer.from(entry));
737
+ } else {
738
+ values.push(entry);
739
+ }
740
+
741
+ if (!options?.recursive || !stats?.isDirectory()) {
742
+ continue;
743
+ }
744
+
745
+ for (const subEntry of await readdir(fullPath, options)) {
746
+ if (subEntry instanceof Dirent) {
747
+ subEntry.path = join(entry, subEntry.path);
748
+ values.push(subEntry);
749
+ } else if (Buffer.isBuffer(subEntry)) {
750
+ // Convert Buffer to string, prefix with the full path
751
+ values.push(Buffer.from(join(entry, decodeUTF8(subEntry))));
752
+ } else {
753
+ values.push(join(entry, subEntry));
754
+ }
755
+ }
724
756
  }
757
+
725
758
  return values as string[] | Dirent[];
726
759
  }
727
760
  readdir satisfies typeof promises.readdir;
728
761
 
729
- // SYMLINK METHODS
730
-
731
762
  export async function link(targetPath: fs.PathLike, linkPath: fs.PathLike): Promise<void> {
732
763
  targetPath = normalizePath(targetPath);
733
764
  if (!(await stat(dirname(targetPath))).hasAccess(constants.R_OK)) {
@@ -5,7 +5,7 @@ import type { File } from '../file.js';
5
5
  import { flagToMode, isAppendable, isExclusive, isReadable, isTruncating, isWriteable, parseFlag } from '../file.js';
6
6
  import type { FileContents } from '../filesystem.js';
7
7
  import { BigIntStats, type Stats } from '../stats.js';
8
- import { normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
8
+ import { decodeUTF8, normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
9
9
  import * as constants from './constants.js';
10
10
  import { Dir, Dirent } from './dir.js';
11
11
  import { dirname, join, parse } from './path.js';
@@ -437,10 +437,15 @@ export function readdirSync(path: fs.PathLike, options?: { recursive?: boolean;
437
437
  export function readdirSync(path: fs.PathLike, options: { recursive?: boolean; encoding: 'buffer'; withFileTypes?: false } | 'buffer'): Buffer[];
438
438
  export function readdirSync(path: fs.PathLike, options: { recursive?: boolean; withFileTypes: true }): Dirent[];
439
439
  export function readdirSync(path: fs.PathLike, options?: (fs.ObjectEncodingOptions & { withFileTypes?: false; recursive?: boolean }) | BufferEncoding | null): string[] | Buffer[];
440
+ export function readdirSync(
441
+ path: fs.PathLike,
442
+ options?: { withFileTypes?: boolean; recursive?: boolean; encoding?: BufferEncoding | 'buffer' | null } | BufferEncoding | 'buffer' | null
443
+ ): string[] | Dirent[] | Buffer[];
440
444
  export function readdirSync(
441
445
  path: fs.PathLike,
442
446
  options?: { recursive?: boolean; encoding?: BufferEncoding | 'buffer' | null; withFileTypes?: boolean } | BufferEncoding | 'buffer' | null
443
447
  ): string[] | Dirent[] | Buffer[] {
448
+ options = typeof options === 'object' ? options : { encoding: options };
444
449
  path = normalizePath(path);
445
450
  const { fs, path: resolved } = resolveMount(existsSync(path) ? realpathSync(path) : path);
446
451
  let entries: string[];
@@ -452,6 +457,7 @@ export function readdirSync(
452
457
  } catch (e) {
453
458
  throw fixError(e as Error, { [resolved]: path });
454
459
  }
460
+
455
461
  for (const mount of mounts.keys()) {
456
462
  if (!mount.startsWith(path)) {
457
463
  continue;
@@ -463,17 +469,35 @@ export function readdirSync(
463
469
  }
464
470
  entries.push(entry);
465
471
  }
466
- return entries.map((entry: string) => {
467
- if (typeof options == 'object' && options?.withFileTypes) {
468
- return new Dirent(entry, statSync(join(path.toString(), entry)));
469
- }
470
472
 
471
- if (options == 'buffer' || (typeof options == 'object' && options?.encoding == 'buffer')) {
472
- return Buffer.from(entry);
473
+ // Iterate over entries and handle recursive case if needed
474
+ const values: (string | Dirent | Buffer)[] = [];
475
+ for (const entry of entries) {
476
+ const fullPath = join(path, entry);
477
+ const entryStat = statSync(fullPath);
478
+
479
+ if (options?.withFileTypes) {
480
+ values.push(new Dirent(entry, entryStat));
481
+ } else if (options?.encoding === 'buffer') {
482
+ values.push(Buffer.from(entry));
483
+ } else {
484
+ values.push(entry);
485
+ }
486
+ if (!entryStat.isDirectory() || !options?.recursive) continue;
487
+
488
+ for (const subEntry of readdirSync(fullPath, options)) {
489
+ if (subEntry instanceof Dirent) {
490
+ subEntry.path = join(entry, subEntry.path);
491
+ values.push(subEntry);
492
+ } else if (Buffer.isBuffer(subEntry)) {
493
+ values.push(Buffer.from(join(entry, decodeUTF8(subEntry))));
494
+ } else {
495
+ values.push(join(entry, subEntry));
496
+ }
473
497
  }
498
+ }
474
499
 
475
- return entry;
476
- }) as string[] | Dirent[] | Buffer[];
500
+ return values as string[] | Dirent[] | Buffer[];
477
501
  }
478
502
  readdirSync satisfies typeof fs.readdirSync;
479
503