@anabranch/fs 0.2.4 → 0.3.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.
package/esm/index.d.ts CHANGED
@@ -32,7 +32,9 @@ export { glob, readDir, walk } from './dir.js';
32
32
  export type { DirError } from './dir.js';
33
33
  export { watch } from './watch.js';
34
34
  export type { WatchError } from './watch.js';
35
- export type { DirEntry, FsEvent, GlobOptions, WalkEntry, WalkOptions, WatchOptions, } from './types.js';
36
- export { FSError } from './errors.js';
35
+ export { copyFile, ensureDir, exists, remove, stat } from './util.js';
36
+ export type { CopyFileError, EnsureDirError, ExistsError, RemoveError, StatError, } from './util.js';
37
+ export type { DirEntry, FsEvent, GlobOptions, StatInfo, WalkEntry, WalkOptions, WatchOptions, } from './types.js';
38
+ export { FSError, nodeErrorToFSError } from './errors.js';
37
39
  export { AlreadyExists, InvalidData, IsDirectory, NotDirectory, NotFound, PermissionDenied, ReadError, Unknown, WriteError, } from './errors.js';
38
40
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,qBAAqB,CAAC;AAE7B,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACvE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAC7D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAChE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AAC9C,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC5C,YAAY,EACV,QAAQ,EACR,OAAO,EACP,WAAW,EACX,SAAS,EACT,WAAW,EACX,YAAY,GACb,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACrC,OAAO,EACL,aAAa,EACb,WAAW,EACX,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,OAAO,EACP,UAAU,GACX,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,qBAAqB,CAAC;AAE7B,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACvE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAC7D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAChE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AAC9C,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACrE,YAAY,EACV,aAAa,EACb,cAAc,EACd,WAAW,EACX,WAAW,EACX,SAAS,GACV,MAAM,WAAW,CAAA;AAClB,YAAY,EACV,QAAQ,EACR,OAAO,EACP,WAAW,EACX,QAAQ,EACR,SAAS,EACT,WAAW,EACX,YAAY,GACb,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EACL,aAAa,EACb,WAAW,EACX,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,OAAO,EACP,UAAU,GACX,MAAM,aAAa,CAAA"}
package/esm/index.js CHANGED
@@ -28,5 +28,6 @@ export { readFile, readJson, readLines, readTextFile } from './read.js';
28
28
  export { writeFile, writeJson, writeTextFile } from './write.js';
29
29
  export { glob, readDir, walk } from './dir.js';
30
30
  export { watch } from './watch.js';
31
- export { FSError } from './errors.js';
31
+ export { copyFile, ensureDir, exists, remove, stat } from './util.js';
32
+ export { FSError, nodeErrorToFSError } from './errors.js';
32
33
  export { AlreadyExists, InvalidData, IsDirectory, NotDirectory, NotFound, PermissionDenied, ReadError, Unknown, WriteError, } from './errors.js';
package/esm/types.d.ts CHANGED
@@ -49,6 +49,23 @@ export interface WalkOptions {
49
49
  /** Options for {@link glob}. Same as {@link WalkOptions} without `match`. */
50
50
  export interface GlobOptions extends Omit<WalkOptions, 'match'> {
51
51
  }
52
+ /** File metadata returned by {@link stat}. */
53
+ export interface StatInfo {
54
+ /** Size in bytes. */
55
+ size: number;
56
+ /** Whether the path is a regular file. */
57
+ isFile: boolean;
58
+ /** Whether the path is a directory. */
59
+ isDirectory: boolean;
60
+ /** Whether the path is a symbolic link. */
61
+ isSymlink: boolean;
62
+ /** Last modification time. */
63
+ mtime: Date;
64
+ /** Last access time. */
65
+ atime: Date;
66
+ /** Creation time. */
67
+ birthtime: Date;
68
+ }
52
69
  /** A file-system change event, as yielded by {@link watch}. */
53
70
  export interface FsEvent {
54
71
  /** The type of change. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,MAAM,WAAW,QAAQ;IACvB,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAA;IACZ,2CAA2C;IAC3C,MAAM,EAAE,OAAO,CAAA;IACf,wCAAwC;IACxC,WAAW,EAAE,OAAO,CAAA;IACpB,4CAA4C;IAC5C,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,yFAAyF;AACzF,MAAM,WAAW,SAAU,SAAQ,QAAQ;IACzC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAA;CACb;AAED,gCAAgC;AAChC,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,6EAA6E;AAC7E,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC;CAAG;AAElE,+DAA+D;AAC/D,MAAM,WAAW,OAAO;IACtB,0BAA0B;IAC1B,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAA;IACpC,4CAA4C;IAC5C,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,iCAAiC;AACjC,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,MAAM,WAAW,QAAQ;IACvB,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAA;IACZ,2CAA2C;IAC3C,MAAM,EAAE,OAAO,CAAA;IACf,wCAAwC;IACxC,WAAW,EAAE,OAAO,CAAA;IACpB,4CAA4C;IAC5C,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,yFAAyF;AACzF,MAAM,WAAW,SAAU,SAAQ,QAAQ;IACzC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAA;CACb;AAED,gCAAgC;AAChC,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,6EAA6E;AAC7E,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC;CAAG;AAElE,8CAA8C;AAC9C,MAAM,WAAW,QAAQ;IACvB,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,0CAA0C;IAC1C,MAAM,EAAE,OAAO,CAAA;IACf,uCAAuC;IACvC,WAAW,EAAE,OAAO,CAAA;IACpB,2CAA2C;IAC3C,SAAS,EAAE,OAAO,CAAA;IAClB,8BAA8B;IAC9B,KAAK,EAAE,IAAI,CAAA;IACX,wBAAwB;IACxB,KAAK,EAAE,IAAI,CAAA;IACX,qBAAqB;IACrB,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,+DAA+D;AAC/D,MAAM,WAAW,OAAO;IACtB,0BAA0B;IAC1B,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAA;IACpC,4CAA4C;IAC5C,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,iCAAiC;AACjC,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB"}
package/esm/util.d.ts ADDED
@@ -0,0 +1,62 @@
1
+ import { Task } from 'anabranch';
2
+ import { type NotFound, type PermissionDenied, type Unknown } from './errors.js';
3
+ import type { StatInfo } from './types.js';
4
+ /**
5
+ * Checks whether a path exists.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * if (await exists("./config.json").run()) {
10
+ * // file exists
11
+ * }
12
+ * ```
13
+ */
14
+ export declare function exists(path: string | URL): Task<boolean, ExistsError>;
15
+ /** Errors that can occur when checking existence. */
16
+ export type ExistsError = PermissionDenied | Unknown;
17
+ /**
18
+ * Creates a directory and any missing parents, like `mkdir -p`.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * await ensureDir("./data/cache/images").run();
23
+ * ```
24
+ */
25
+ export declare function ensureDir(path: string | URL): Task<void, EnsureDirError>;
26
+ /** Errors that can occur when ensuring a directory. */
27
+ export type EnsureDirError = PermissionDenied | Unknown;
28
+ /**
29
+ * Removes a file or directory recursively. No error if the path doesn't exist.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * await remove("./tmp").run();
34
+ * ```
35
+ */
36
+ export declare function remove(path: string | URL): Task<void, RemoveError>;
37
+ /** Errors that can occur when removing a path. */
38
+ export type RemoveError = PermissionDenied | Unknown;
39
+ /**
40
+ * Copies a single file from `src` to `dst`.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * await copyFile("./template.txt", "./output.txt").run();
45
+ * ```
46
+ */
47
+ export declare function copyFile(src: string | URL, dst: string | URL): Task<void, CopyFileError>;
48
+ /** Errors that can occur when copying a file. */
49
+ export type CopyFileError = NotFound | PermissionDenied | Unknown;
50
+ /**
51
+ * Returns metadata for a path without reading its contents.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * const info = await stat("./data.csv").run();
56
+ * console.log(info.size, info.mtime);
57
+ * ```
58
+ */
59
+ export declare function stat(path: string | URL): Task<StatInfo, StatError>;
60
+ /** Errors that can occur when stat-ing a path. */
61
+ export type StatError = NotFound | PermissionDenied | Unknown;
62
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,OAAO,EACb,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE1C;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAWrE;AAED,qDAAqD;AACrD,MAAM,MAAM,WAAW,GAAG,gBAAgB,GAAG,OAAO,CAAA;AAEpD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAIxE;AAED,uDAAuD;AACvD,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG,OAAO,CAAA;AAEvD;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAIlE;AAED,kDAAkD;AAClD,MAAM,MAAM,WAAW,GAAG,gBAAgB,GAAG,OAAO,CAAA;AAEpD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,GAAG,EAAE,MAAM,GAAG,GAAG,GAChB,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,CAI3B;AAED,iDAAiD;AACjD,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,gBAAgB,GAAG,OAAO,CAAA;AAEjE;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAalE;AAED,kDAAkD;AAClD,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,gBAAgB,GAAG,OAAO,CAAA"}
package/esm/util.js ADDED
@@ -0,0 +1,89 @@
1
+ import { access, copyFile as fsCopyFile, lstat, mkdir, rm, } from 'node:fs/promises';
2
+ import { Task } from 'anabranch';
3
+ import { nodeErrorToFSError, } from './errors.js';
4
+ /**
5
+ * Checks whether a path exists.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * if (await exists("./config.json").run()) {
10
+ * // file exists
11
+ * }
12
+ * ```
13
+ */
14
+ export function exists(path) {
15
+ return Task.of(async () => {
16
+ try {
17
+ await access(path);
18
+ return true;
19
+ }
20
+ catch (error) {
21
+ const fsError = nodeErrorToFSError(error, path);
22
+ if (fsError.kind === 'NotFound')
23
+ return false;
24
+ throw fsError;
25
+ }
26
+ });
27
+ }
28
+ /**
29
+ * Creates a directory and any missing parents, like `mkdir -p`.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * await ensureDir("./data/cache/images").run();
34
+ * ```
35
+ */
36
+ export function ensureDir(path) {
37
+ return Task.of(async () => {
38
+ await mkdir(path, { recursive: true });
39
+ }).mapErr((error) => nodeErrorToFSError(error, path));
40
+ }
41
+ /**
42
+ * Removes a file or directory recursively. No error if the path doesn't exist.
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * await remove("./tmp").run();
47
+ * ```
48
+ */
49
+ export function remove(path) {
50
+ return Task.of(async () => {
51
+ await rm(path, { recursive: true, force: true });
52
+ }).mapErr((error) => nodeErrorToFSError(error, path));
53
+ }
54
+ /**
55
+ * Copies a single file from `src` to `dst`.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * await copyFile("./template.txt", "./output.txt").run();
60
+ * ```
61
+ */
62
+ export function copyFile(src, dst) {
63
+ return Task.of(async () => {
64
+ await fsCopyFile(src, dst);
65
+ }).mapErr((error) => nodeErrorToFSError(error, src));
66
+ }
67
+ /**
68
+ * Returns metadata for a path without reading its contents.
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * const info = await stat("./data.csv").run();
73
+ * console.log(info.size, info.mtime);
74
+ * ```
75
+ */
76
+ export function stat(path) {
77
+ return Task.of(async () => {
78
+ const s = await lstat(path);
79
+ return {
80
+ size: s.size,
81
+ isFile: s.isFile(),
82
+ isDirectory: s.isDirectory(),
83
+ isSymlink: s.isSymbolicLink(),
84
+ mtime: s.mtimeMs ? new Date(s.mtimeMs) : s.mtime,
85
+ atime: s.atimeMs ? new Date(s.atimeMs) : s.atime,
86
+ birthtime: s.birthtimeMs ? new Date(s.birthtimeMs) : s.birthtime,
87
+ };
88
+ }).mapErr((error) => nodeErrorToFSError(error, path));
89
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACvD,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACtB,MAAM,aAAa,CAAA;AAEpB,2DAA2D;AAC3D,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,gBAAgB,CAAA;AAEpD;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CACnB,IAAI,EAAE,MAAM,GAAG,GAAG,EAClB,OAAO,CAAC,EAAE,YAAY,GACrB,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,CAiC7B"}
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACvD,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACtB,MAAM,aAAa,CAAA;AAEpB,2DAA2D;AAC3D,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,gBAAgB,CAAA;AAEpD;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CACnB,IAAI,EAAE,MAAM,GAAG,GAAG,EAClB,OAAO,CAAC,EAAE,YAAY,GACrB,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,CAgC7B"}
package/esm/watch.js CHANGED
@@ -29,9 +29,8 @@ export function watch(path, options) {
29
29
  }
30
30
  channel.send({ kind, paths: [fullPath] });
31
31
  });
32
- const channel = new Channel({
33
- onClose: () => watcher?.close(),
34
- });
32
+ const channel = Channel.create()
33
+ .withOnClose(() => watcher?.close());
35
34
  watcher.once('error', (err) => channel.fail(nodeErrorToFSError(err, path)));
36
35
  watcher.once('close', () => channel.close());
37
36
  yield* channel;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anabranch/fs",
3
- "version": "0.2.4",
3
+ "version": "0.3.0",
4
4
  "description": "Streaming file-system utilities for reading, walking, globbing, and watching files with composable error handling.",
5
5
  "repository": {
6
6
  "type": "git",