@statewalker/webrun-files 0.5.0 → 0.9.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/LICENSE +1 -1
- package/README.md +131 -114
- package/dist/cjs/index.cjs +85 -529
- package/dist/esm/index.js +78 -519
- package/dist/file-utils.d.ts +47 -0
- package/dist/file-utils.d.ts.map +1 -0
- package/dist/index.d.ts +14 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/{utils/path-utils.d.ts → path-utils.d.ts} +10 -1
- package/dist/path-utils.d.ts.map +1 -0
- package/dist/types.d.ts +130 -51
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -10
- package/src/file-utils.ts +106 -0
- package/src/index.ts +38 -27
- package/src/{utils/path-utils.ts → path-utils.ts} +16 -2
- package/src/types.ts +136 -53
- package/dist/files-api.d.ts +0 -44
- package/dist/files-api.d.ts.map +0 -1
- package/dist/impl/index.d.ts +0 -6
- package/dist/impl/index.d.ts.map +0 -1
- package/dist/impl/mem-files-api.d.ts +0 -13
- package/dist/impl/mem-files-api.d.ts.map +0 -1
- package/dist/impl/node-files-api.d.ts +0 -24
- package/dist/impl/node-files-api.d.ts.map +0 -1
- package/dist/utils/collect-stream.d.ts +0 -16
- package/dist/utils/collect-stream.d.ts.map +0 -1
- package/dist/utils/file-info-utils.d.ts +0 -10
- package/dist/utils/file-info-utils.d.ts.map +0 -1
- package/dist/utils/index.d.ts +0 -8
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/normalize-path.d.ts +0 -21
- package/dist/utils/normalize-path.d.ts.map +0 -1
- package/dist/utils/path-utils.d.ts.map +0 -1
- package/src/files-api.ts +0 -168
- package/src/impl/index.ts +0 -6
- package/src/impl/mem-files-api.ts +0 -323
- package/src/impl/node-files-api.ts +0 -271
- package/src/utils/collect-stream.ts +0 -35
- package/src/utils/file-info-utils.ts +0 -15
- package/src/utils/index.ts +0 -8
- package/src/utils/normalize-path.ts +0 -34
package/src/types.ts
CHANGED
|
@@ -1,79 +1,162 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Core types for FilesApi abstraction
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
export type FileKind = "file" | "directory";
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Options for reading file content with range support.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* // Read 100 bytes starting at position 50
|
|
12
|
+
* api.read("/file.bin", { start: 50, length: 100 })
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* // Read from position 1000 to end of file
|
|
16
|
+
* api.read("/file.bin", { start: 1000 })
|
|
17
|
+
*/
|
|
18
|
+
export interface ReadOptions {
|
|
19
|
+
/** Starting byte position (0-indexed). Defaults to 0. */
|
|
20
|
+
start?: number;
|
|
21
|
+
/** Number of bytes to read. If omitted, reads to end of file. */
|
|
22
|
+
length?: number;
|
|
23
|
+
/** AbortSignal for cancellation support. */
|
|
24
|
+
signal?: AbortSignal;
|
|
14
25
|
}
|
|
15
26
|
|
|
16
|
-
|
|
17
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Options for listing directory contents.
|
|
29
|
+
*/
|
|
18
30
|
export interface ListOptions {
|
|
31
|
+
/** If true, lists all descendants recursively. Defaults to false. */
|
|
19
32
|
recursive?: boolean;
|
|
20
33
|
}
|
|
21
34
|
|
|
22
|
-
|
|
23
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Metadata of a regular file.
|
|
37
|
+
*
|
|
38
|
+
* `size` and `lastModified` are REQUIRED. Every storage that can hold a file
|
|
39
|
+
* can say how large it is and when it last changed; an implementation that
|
|
40
|
+
* cannot is claiming less than it must, and the omission must surface as a
|
|
41
|
+
* failure rather than as an `undefined` a consumer has to defend against.
|
|
42
|
+
*/
|
|
43
|
+
export interface FileEntryStats {
|
|
44
|
+
kind: "file";
|
|
45
|
+
/** Length in bytes. A zero-byte file is `0`, never `undefined`. */
|
|
46
|
+
size: number;
|
|
47
|
+
/** Modification time as milliseconds since the epoch. */
|
|
48
|
+
lastModified: number;
|
|
24
49
|
}
|
|
25
50
|
|
|
26
|
-
|
|
27
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Metadata of a directory.
|
|
53
|
+
*
|
|
54
|
+
* Deliberately carries nothing else. A directory has no size, and a
|
|
55
|
+
* modification time is available on some storages (memory, a local
|
|
56
|
+
* filesystem) and unavailable on others (an object store, where a directory
|
|
57
|
+
* is a common prefix that exists only as an artefact of key naming). Neither
|
|
58
|
+
* value may be relied upon, so neither is part of the contract: an
|
|
59
|
+
* implementation that happens to know one drops it here instead of leaking a
|
|
60
|
+
* value consumers would have to treat as optional anyway.
|
|
61
|
+
*/
|
|
62
|
+
export interface DirectoryEntryStats {
|
|
63
|
+
kind: "directory";
|
|
28
64
|
}
|
|
29
65
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
66
|
+
/**
|
|
67
|
+
* File or directory metadata returned by `stats()`.
|
|
68
|
+
*
|
|
69
|
+
* A DISCRIMINATED UNION on `kind`, not a single shape with optional fields.
|
|
70
|
+
* The optionality this replaces never expressed what a given implementation
|
|
71
|
+
* could report — it expressed a property of the entry kind, collapsed into
|
|
72
|
+
* one type because `kind` was an ordinary field. Narrow on `kind` and the
|
|
73
|
+
* fields that exist for that kind are then known to be present:
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* const stats = await api.stats("/some/path");
|
|
77
|
+
* if (stats?.kind === "file") {
|
|
78
|
+
* console.log(stats.size, stats.lastModified); // both `number`
|
|
79
|
+
* }
|
|
80
|
+
*/
|
|
81
|
+
export type FileStats = FileEntryStats | DirectoryEntryStats;
|
|
35
82
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
83
|
+
/** Name and path carried by every entry a `list()` yields. */
|
|
84
|
+
export interface FileEntryLocation {
|
|
85
|
+
name: string;
|
|
86
|
+
path: string;
|
|
39
87
|
}
|
|
40
88
|
|
|
41
|
-
|
|
89
|
+
/** A file yielded by `list()`. */
|
|
90
|
+
export interface FileEntryInfo extends FileEntryStats, FileEntryLocation {}
|
|
42
91
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
close(): Promise<void>;
|
|
92
|
+
/** A directory yielded by `list()`. */
|
|
93
|
+
export interface DirectoryEntryInfo extends DirectoryEntryStats, FileEntryLocation {}
|
|
46
94
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
95
|
+
/**
|
|
96
|
+
* File or directory information returned by `list()`.
|
|
97
|
+
*
|
|
98
|
+
* The same union as {@link FileStats}, plus `name` and `path`, so a listing
|
|
99
|
+
* consumer narrows per entry exactly as a `stats()` consumer does.
|
|
100
|
+
*/
|
|
101
|
+
export type FileInfo = FileEntryInfo | DirectoryEntryInfo;
|
|
50
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Cross-platform filesystem abstraction interface.
|
|
105
|
+
*
|
|
106
|
+
* All paths are virtual paths using forward slashes and starting with "/".
|
|
107
|
+
* Implementations handle mapping to underlying storage.
|
|
108
|
+
*/
|
|
109
|
+
export interface FilesApi {
|
|
51
110
|
/**
|
|
52
|
-
* Read
|
|
53
|
-
*
|
|
54
|
-
* @param buffer - The buffer to read bytes into
|
|
55
|
-
* @param offset - The offset in the buffer to start writing at
|
|
56
|
-
* @param length - The number of bytes to read
|
|
57
|
-
* @param position - The position in the file to start reading from
|
|
58
|
-
* @returns The number of bytes actually read (may be less than length at EOF)
|
|
111
|
+
* Read file content as an async iterable of chunks.
|
|
112
|
+
* Returns empty iterable for non-existent files.
|
|
59
113
|
*/
|
|
60
|
-
read(
|
|
114
|
+
read(path: string, options?: ReadOptions): AsyncIterable<Uint8Array>;
|
|
61
115
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
116
|
+
/**
|
|
117
|
+
* Write content to a file, creating parent directories as needed.
|
|
118
|
+
* Overwrites existing file content.
|
|
119
|
+
*/
|
|
120
|
+
write(path: string, content: Iterable<Uint8Array> | AsyncIterable<Uint8Array>): Promise<void>;
|
|
65
121
|
|
|
66
|
-
/**
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
122
|
+
/**
|
|
123
|
+
* Create a directory and all parent directories.
|
|
124
|
+
* No-op if directory already exists.
|
|
125
|
+
*/
|
|
126
|
+
mkdir(path: string): Promise<void>;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* List directory contents.
|
|
130
|
+
* Returns empty iterable for non-existent or non-directory paths.
|
|
131
|
+
*/
|
|
132
|
+
list(path: string, options?: ListOptions): AsyncIterable<FileInfo>;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Get file or directory metadata.
|
|
136
|
+
* Returns undefined for non-existent paths.
|
|
137
|
+
*/
|
|
138
|
+
stats(path: string): Promise<FileStats | undefined>;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Check if a path exists.
|
|
142
|
+
*/
|
|
143
|
+
exists(path: string): Promise<boolean>;
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Remove a file or directory (recursively).
|
|
147
|
+
* Returns true if something was removed, false if path didn't exist.
|
|
148
|
+
*/
|
|
149
|
+
remove(path: string): Promise<boolean>;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Move/rename a file or directory.
|
|
153
|
+
* Returns true on success, false if source doesn't exist.
|
|
154
|
+
*/
|
|
155
|
+
move(source: string, target: string): Promise<boolean>;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Copy a file or directory (recursively).
|
|
159
|
+
* Returns true on success, false if source doesn't exist.
|
|
160
|
+
*/
|
|
161
|
+
copy(source: string, target: string): Promise<boolean>;
|
|
79
162
|
}
|
package/dist/files-api.d.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FilesApi wrapper class providing convenience methods on top of IFilesApi
|
|
3
|
-
*/
|
|
4
|
-
import type { BinaryStream, CopyOptions, FileHandle, FileInfo, FileRef, IFilesApi, ListOptions, ReadStreamOptions } from "./types.js";
|
|
5
|
-
export declare class FilesApi implements IFilesApi {
|
|
6
|
-
private fs;
|
|
7
|
-
constructor(fs: IFilesApi);
|
|
8
|
-
list(file: FileRef, options?: ListOptions): AsyncGenerator<FileInfo>;
|
|
9
|
-
stats(file: FileRef): Promise<FileInfo | undefined>;
|
|
10
|
-
remove(file: FileRef): Promise<boolean>;
|
|
11
|
-
open(file: FileRef): Promise<FileHandle>;
|
|
12
|
-
/**
|
|
13
|
-
* Checks if a file or directory exists.
|
|
14
|
-
*/
|
|
15
|
-
exists(file: FileRef): Promise<boolean>;
|
|
16
|
-
/**
|
|
17
|
-
* Reads file content as a stream.
|
|
18
|
-
*/
|
|
19
|
-
read(file: FileRef, options?: ReadStreamOptions): AsyncGenerator<Uint8Array>;
|
|
20
|
-
/**
|
|
21
|
-
* Writes content to a file.
|
|
22
|
-
*/
|
|
23
|
-
write(file: FileRef, content: BinaryStream): Promise<void>;
|
|
24
|
-
/**
|
|
25
|
-
* Reads entire file into a single buffer.
|
|
26
|
-
*/
|
|
27
|
-
readFile(file: FileRef): Promise<Uint8Array>;
|
|
28
|
-
/**
|
|
29
|
-
* Copies file or directory.
|
|
30
|
-
* Uses native implementation if available, otherwise falls back to read/write.
|
|
31
|
-
*/
|
|
32
|
-
copy(source: FileRef, target: FileRef, options?: CopyOptions): Promise<boolean>;
|
|
33
|
-
/**
|
|
34
|
-
* Moves file or directory.
|
|
35
|
-
* Uses native implementation if available, otherwise falls back to copy+delete.
|
|
36
|
-
*/
|
|
37
|
-
move(source: FileRef, target: FileRef): Promise<boolean>;
|
|
38
|
-
/**
|
|
39
|
-
* Creates a directory.
|
|
40
|
-
* Uses native implementation if available, otherwise creates a placeholder file.
|
|
41
|
-
*/
|
|
42
|
-
mkdir(file: FileRef): Promise<void>;
|
|
43
|
-
}
|
|
44
|
-
//# sourceMappingURL=files-api.d.ts.map
|
package/dist/files-api.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"files-api.d.ts","sourceRoot":"","sources":["../src/files-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EACV,QAAQ,EACR,OAAO,EACP,SAAS,EACT,WAAW,EACX,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAOpB,qBAAa,QAAS,YAAW,SAAS;IAC5B,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,SAAS;IAMjC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,cAAc,CAAC,QAAQ,CAAC;IAIpE,KAAK,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAInD,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAIvC,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAQxC;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAK7C;;OAEG;IACI,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,iBAAsB,GAAG,cAAc,CAAC,UAAU,CAAC;IASvF;;OAEG;IACG,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAShE;;OAEG;IACG,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAqBlD;;;OAGG;IACG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IA4BzF;;;OAGG;IACG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAa9D;;;OAGG;IACG,KAAK,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAW1C"}
|
package/dist/impl/index.d.ts
DELETED
package/dist/impl/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/impl/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* In-memory implementation of IFilesApi for testing
|
|
3
|
-
*/
|
|
4
|
-
import type { FileHandle, FileInfo, FileRef, IFilesApi, ListOptions } from "../types.js";
|
|
5
|
-
export declare class MemFilesApi implements IFilesApi {
|
|
6
|
-
private store;
|
|
7
|
-
list(file: FileRef, options?: ListOptions): AsyncGenerator<FileInfo>;
|
|
8
|
-
stats(file: FileRef): Promise<FileInfo | undefined>;
|
|
9
|
-
remove(file: FileRef): Promise<boolean>;
|
|
10
|
-
open(file: FileRef): Promise<FileHandle>;
|
|
11
|
-
mkdir(file: FileRef): Promise<void>;
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=mem-files-api.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mem-files-api.d.ts","sourceRoot":"","sources":["../../src/impl/mem-files-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAGV,UAAU,EACV,QAAQ,EACR,OAAO,EACP,SAAS,EACT,WAAW,EAGZ,MAAM,aAAa,CAAC;AA8JrB,qBAAa,WAAY,YAAW,SAAS;IAC3C,OAAO,CAAC,KAAK,CAA4B;IAElC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,WAAgB,GAAG,cAAc,CAAC,QAAQ,CAAC;IAqEzE,KAAK,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IA0CnD,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBvC,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAKxC,KAAK,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAS1C"}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Node.js implementation of IFilesApi
|
|
3
|
-
*/
|
|
4
|
-
import type * as NodeFS from "node:fs/promises";
|
|
5
|
-
import type { CopyOptions, FileHandle, FileInfo, FileRef, IFilesApi, ListOptions } from "../types.js";
|
|
6
|
-
interface NodeFilesApiOptions {
|
|
7
|
-
fs: typeof NodeFS;
|
|
8
|
-
rootDir?: string;
|
|
9
|
-
}
|
|
10
|
-
export declare class NodeFilesApi implements IFilesApi {
|
|
11
|
-
private fs;
|
|
12
|
-
private rootDir;
|
|
13
|
-
constructor(options: NodeFilesApiOptions);
|
|
14
|
-
private resolvePath;
|
|
15
|
-
list(file: FileRef, options?: ListOptions): AsyncGenerator<FileInfo>;
|
|
16
|
-
stats(file: FileRef): Promise<FileInfo | undefined>;
|
|
17
|
-
remove(file: FileRef): Promise<boolean>;
|
|
18
|
-
open(file: FileRef): Promise<FileHandle>;
|
|
19
|
-
move(source: FileRef, target: FileRef): Promise<boolean>;
|
|
20
|
-
copy(source: FileRef, target: FileRef, options?: CopyOptions): Promise<boolean>;
|
|
21
|
-
mkdir(file: FileRef): Promise<void>;
|
|
22
|
-
}
|
|
23
|
-
export {};
|
|
24
|
-
//# sourceMappingURL=node-files-api.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"node-files-api.d.ts","sourceRoot":"","sources":["../../src/impl/node-files-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAEhD,OAAO,KAAK,EAGV,WAAW,EACX,UAAU,EACV,QAAQ,EACR,OAAO,EACP,SAAS,EACT,WAAW,EAGZ,MAAM,aAAa,CAAC;AAIrB,UAAU,mBAAmB;IAC3B,EAAE,EAAE,OAAO,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA4GD,qBAAa,YAAa,YAAW,SAAS;IAC5C,OAAO,CAAC,EAAE,CAAgB;IAC1B,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,mBAAmB;IAKxC,OAAO,CAAC,WAAW;IAKZ,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,WAAgB,GAAG,cAAc,CAAC,QAAQ,CAAC;IAsCzE,KAAK,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAkBnD,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBvC,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAexC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBxD,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBnF,KAAK,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAI1C"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Stream collection utilities
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Collects all values from an async generator into an array.
|
|
6
|
-
*/
|
|
7
|
-
export declare function collectGenerator<T>(generator: AsyncIterable<T>): Promise<T[]>;
|
|
8
|
-
/**
|
|
9
|
-
* Converts a synchronous iterable to an async iterable.
|
|
10
|
-
*/
|
|
11
|
-
export declare function toAsyncIterable<T>(iterable: Iterable<T>): AsyncIterable<T>;
|
|
12
|
-
/**
|
|
13
|
-
* Normalizes BinaryStream to AsyncIterable<Uint8Array>.
|
|
14
|
-
*/
|
|
15
|
-
export declare function toBinaryAsyncIterable(data: AsyncIterable<Uint8Array> | Iterable<Uint8Array>): AsyncIterable<Uint8Array>;
|
|
16
|
-
//# sourceMappingURL=collect-stream.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"collect-stream.d.ts","sourceRoot":"","sources":["../../src/utils/collect-stream.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAMnF;AAED;;GAEG;AACH,wBAAuB,eAAe,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAIjF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,GACrD,aAAa,CAAC,UAAU,CAAC,CAK3B"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { FileInfo } from "../types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Check if FileInfo represents a directory
|
|
4
|
-
*/
|
|
5
|
-
export declare function isDirectory(info: FileInfo | undefined): boolean;
|
|
6
|
-
/**
|
|
7
|
-
* Check if FileInfo represents a file
|
|
8
|
-
*/
|
|
9
|
-
export declare function isFile(info: FileInfo | undefined): boolean;
|
|
10
|
-
//# sourceMappingURL=file-info-utils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"file-info-utils.d.ts","sourceRoot":"","sources":["../../src/utils/file-info-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAE/D;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAE1D"}
|
package/dist/utils/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Path normalization utilities
|
|
3
|
-
*/
|
|
4
|
-
import type { FileRef } from "../types.js";
|
|
5
|
-
/**
|
|
6
|
-
* Normalizes a file path to a consistent format.
|
|
7
|
-
* - Adds leading slash if missing
|
|
8
|
-
* - Removes trailing slash
|
|
9
|
-
* - Removes `.` segments
|
|
10
|
-
* - Collapses multiple slashes
|
|
11
|
-
*/
|
|
12
|
-
export declare function normalizePath(filePath: string): string;
|
|
13
|
-
/**
|
|
14
|
-
* Extracts path string from FileRef.
|
|
15
|
-
*/
|
|
16
|
-
export declare function toPath(file: FileRef): string;
|
|
17
|
-
/**
|
|
18
|
-
* Normalizes FileRef to a path string.
|
|
19
|
-
*/
|
|
20
|
-
export declare function resolveFileRef(file: FileRef): string;
|
|
21
|
-
//# sourceMappingURL=normalize-path.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-path.d.ts","sourceRoot":"","sources":["../../src/utils/normalize-path.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAEpD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"path-utils.d.ts","sourceRoot":"","sources":["../../src/utils/path-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAGtD;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK5C;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ3D;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK5C"}
|
package/src/files-api.ts
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FilesApi wrapper class providing convenience methods on top of IFilesApi
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type {
|
|
6
|
-
BinaryStream,
|
|
7
|
-
CopyOptions,
|
|
8
|
-
FileHandle,
|
|
9
|
-
FileInfo,
|
|
10
|
-
FileRef,
|
|
11
|
-
IFilesApi,
|
|
12
|
-
ListOptions,
|
|
13
|
-
ReadStreamOptions,
|
|
14
|
-
} from "./types.js";
|
|
15
|
-
import { toBinaryAsyncIterable } from "./utils/collect-stream.js";
|
|
16
|
-
import { resolveFileRef } from "./utils/index.js";
|
|
17
|
-
import { joinPath } from "./utils/path-utils.js";
|
|
18
|
-
|
|
19
|
-
const IGNORE_FILE = ".ignore";
|
|
20
|
-
|
|
21
|
-
export class FilesApi implements IFilesApi {
|
|
22
|
-
constructor(private fs: IFilesApi) {}
|
|
23
|
-
|
|
24
|
-
// ========================================
|
|
25
|
-
// IFilesApi delegation
|
|
26
|
-
// ========================================
|
|
27
|
-
|
|
28
|
-
list(file: FileRef, options?: ListOptions): AsyncGenerator<FileInfo> {
|
|
29
|
-
return this.fs.list(file, options);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
stats(file: FileRef): Promise<FileInfo | undefined> {
|
|
33
|
-
return this.fs.stats(file);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
remove(file: FileRef): Promise<boolean> {
|
|
37
|
-
return this.fs.remove(file);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
open(file: FileRef): Promise<FileHandle> {
|
|
41
|
-
return this.fs.open(file);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// ========================================
|
|
45
|
-
// Convenience methods built on core API
|
|
46
|
-
// ========================================
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Checks if a file or directory exists.
|
|
50
|
-
*/
|
|
51
|
-
async exists(file: FileRef): Promise<boolean> {
|
|
52
|
-
const info = await this.stats(file);
|
|
53
|
-
return info !== undefined;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Reads file content as a stream.
|
|
58
|
-
*/
|
|
59
|
-
async *read(file: FileRef, options: ReadStreamOptions = {}): AsyncGenerator<Uint8Array> {
|
|
60
|
-
const handle = await this.open(file);
|
|
61
|
-
try {
|
|
62
|
-
yield* handle.createReadStream(options);
|
|
63
|
-
} finally {
|
|
64
|
-
await handle.close();
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Writes content to a file.
|
|
70
|
-
*/
|
|
71
|
-
async write(file: FileRef, content: BinaryStream): Promise<void> {
|
|
72
|
-
const handle = await this.open(file);
|
|
73
|
-
try {
|
|
74
|
-
await handle.createWriteStream(toBinaryAsyncIterable(content));
|
|
75
|
-
} finally {
|
|
76
|
-
await handle.close();
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Reads entire file into a single buffer.
|
|
82
|
-
*/
|
|
83
|
-
async readFile(file: FileRef): Promise<Uint8Array> {
|
|
84
|
-
const chunks: Uint8Array[] = [];
|
|
85
|
-
let totalLength = 0;
|
|
86
|
-
|
|
87
|
-
for await (const chunk of this.read(file)) {
|
|
88
|
-
chunks.push(chunk);
|
|
89
|
-
totalLength += chunk.length;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (chunks.length === 0) return new Uint8Array(0);
|
|
93
|
-
if (chunks.length === 1) return chunks[0];
|
|
94
|
-
|
|
95
|
-
const result = new Uint8Array(totalLength);
|
|
96
|
-
let offset = 0;
|
|
97
|
-
for (const chunk of chunks) {
|
|
98
|
-
result.set(chunk, offset);
|
|
99
|
-
offset += chunk.length;
|
|
100
|
-
}
|
|
101
|
-
return result;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Copies file or directory.
|
|
106
|
-
* Uses native implementation if available, otherwise falls back to read/write.
|
|
107
|
-
*/
|
|
108
|
-
async copy(source: FileRef, target: FileRef, options: CopyOptions = {}): Promise<boolean> {
|
|
109
|
-
// Try native implementation first
|
|
110
|
-
if (this.fs.copy) {
|
|
111
|
-
return this.fs.copy(source, target, options);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Fallback: read from source, write to target
|
|
115
|
-
const sourceInfo = await this.stats(source);
|
|
116
|
-
if (!sourceInfo) return false;
|
|
117
|
-
|
|
118
|
-
const sourcePath = resolveFileRef(source);
|
|
119
|
-
const targetPath = resolveFileRef(target);
|
|
120
|
-
const recursive = options.recursive ?? true;
|
|
121
|
-
|
|
122
|
-
if (sourceInfo.kind === "directory") {
|
|
123
|
-
for await (const entry of this.list(source, { recursive })) {
|
|
124
|
-
if (entry.kind === "directory") continue;
|
|
125
|
-
const suffix = entry.path.substring(sourcePath.length);
|
|
126
|
-
const newTargetPath = targetPath + suffix;
|
|
127
|
-
await this.write(newTargetPath, this.read(entry.path));
|
|
128
|
-
}
|
|
129
|
-
} else {
|
|
130
|
-
await this.write(targetPath, this.read(sourcePath));
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return true;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Moves file or directory.
|
|
138
|
-
* Uses native implementation if available, otherwise falls back to copy+delete.
|
|
139
|
-
*/
|
|
140
|
-
async move(source: FileRef, target: FileRef): Promise<boolean> {
|
|
141
|
-
// Try native implementation first
|
|
142
|
-
if (this.fs.move) {
|
|
143
|
-
return this.fs.move(source, target);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Fallback: copy then delete
|
|
147
|
-
const copied = await this.copy(source, target);
|
|
148
|
-
if (!copied) return false;
|
|
149
|
-
await this.remove(source);
|
|
150
|
-
return true;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Creates a directory.
|
|
155
|
-
* Uses native implementation if available, otherwise creates a placeholder file.
|
|
156
|
-
*/
|
|
157
|
-
async mkdir(file: FileRef): Promise<void> {
|
|
158
|
-
// Try native implementation first
|
|
159
|
-
if (this.fs.mkdir) {
|
|
160
|
-
return this.fs.mkdir(file);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Fallback: create a placeholder file to establish the directory
|
|
164
|
-
const dirPath = resolveFileRef(file);
|
|
165
|
-
const placeholderPath = joinPath(dirPath, IGNORE_FILE);
|
|
166
|
-
await this.write(placeholderPath, [new Uint8Array(0)]);
|
|
167
|
-
}
|
|
168
|
-
}
|