@b9g/filesystem 0.1.4 → 0.1.6
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/README.md +35 -22
- package/package.json +2 -27
- package/src/bun-s3.d.ts +51 -47
- package/src/bun-s3.js +215 -185
- package/src/index.d.ts +215 -6
- package/src/index.js +321 -17
- package/src/memory.d.ts +73 -12
- package/src/memory.js +192 -171
- package/src/node.d.ts +28 -58
- package/src/node.js +104 -218
- package/src/directory-storage.d.ts +0 -50
- package/src/directory-storage.js +0 -74
- package/src/registry.d.ts +0 -52
- package/src/registry.js +0 -79
- package/src/types.d.ts +0 -31
- package/src/types.js +0 -1
package/src/node.js
CHANGED
|
@@ -1,266 +1,152 @@
|
|
|
1
1
|
/// <reference types="./node.d.ts" />
|
|
2
2
|
// src/node.ts
|
|
3
|
-
import
|
|
4
|
-
import * as
|
|
5
|
-
import
|
|
6
|
-
var
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
writeStream.write(chunk, (error) => {
|
|
13
|
-
if (error)
|
|
14
|
-
reject(error);
|
|
15
|
-
else
|
|
16
|
-
resolve();
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
},
|
|
20
|
-
close() {
|
|
21
|
-
return new Promise((resolve, reject) => {
|
|
22
|
-
writeStream.end((error) => {
|
|
23
|
-
if (error)
|
|
24
|
-
reject(error);
|
|
25
|
-
else
|
|
26
|
-
resolve();
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
},
|
|
30
|
-
abort() {
|
|
31
|
-
writeStream.destroy();
|
|
32
|
-
return Promise.resolve();
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
this.filePath = filePath;
|
|
36
|
-
}
|
|
37
|
-
// File System Access API compatibility methods
|
|
38
|
-
async write(data) {
|
|
39
|
-
const writer = this.getWriter();
|
|
3
|
+
import { ShovelDirectoryHandle } from "./index.js";
|
|
4
|
+
import * as FS from "fs/promises";
|
|
5
|
+
import * as Path from "path";
|
|
6
|
+
var NodeFileSystemBackend = class {
|
|
7
|
+
#rootPath;
|
|
8
|
+
constructor(rootPath) {
|
|
9
|
+
this.#rootPath = rootPath;
|
|
10
|
+
}
|
|
11
|
+
async stat(filePath) {
|
|
40
12
|
try {
|
|
41
|
-
|
|
42
|
-
|
|
13
|
+
const fullPath = this.#resolvePath(filePath);
|
|
14
|
+
const stats = await FS.stat(fullPath);
|
|
15
|
+
if (stats.isFile()) {
|
|
16
|
+
return { kind: "file" };
|
|
17
|
+
} else if (stats.isDirectory()) {
|
|
18
|
+
return { kind: "directory" };
|
|
43
19
|
} else {
|
|
44
|
-
|
|
20
|
+
return null;
|
|
45
21
|
}
|
|
46
|
-
} finally {
|
|
47
|
-
writer.releaseLock();
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
async close() {
|
|
51
|
-
const writer = this.getWriter();
|
|
52
|
-
try {
|
|
53
|
-
await writer.close();
|
|
54
|
-
} finally {
|
|
55
|
-
writer.releaseLock();
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
var NodeFileSystemFileHandle = class _NodeFileSystemFileHandle {
|
|
60
|
-
constructor(filePath) {
|
|
61
|
-
this.filePath = filePath;
|
|
62
|
-
this.name = path.basename(filePath);
|
|
63
|
-
}
|
|
64
|
-
kind = "file";
|
|
65
|
-
name;
|
|
66
|
-
async getFile() {
|
|
67
|
-
try {
|
|
68
|
-
const stats = await fs.stat(this.filePath);
|
|
69
|
-
const buffer = await fs.readFile(this.filePath);
|
|
70
|
-
return new File([buffer], this.name, {
|
|
71
|
-
lastModified: stats.mtime.getTime(),
|
|
72
|
-
// Attempt to determine MIME type from extension
|
|
73
|
-
type: this.getMimeType(this.filePath)
|
|
74
|
-
});
|
|
75
22
|
} catch (error) {
|
|
76
23
|
if (error.code === "ENOENT") {
|
|
77
|
-
|
|
24
|
+
return null;
|
|
78
25
|
}
|
|
79
26
|
throw error;
|
|
80
27
|
}
|
|
81
28
|
}
|
|
82
|
-
async
|
|
83
|
-
await fs.mkdir(path.dirname(this.filePath), { recursive: true });
|
|
84
|
-
return new NodeFileSystemWritableFileStream(this.filePath);
|
|
85
|
-
}
|
|
86
|
-
async createSyncAccessHandle() {
|
|
87
|
-
throw new DOMException(
|
|
88
|
-
"Synchronous access handles are only available in workers",
|
|
89
|
-
"InvalidStateError"
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
async isSameEntry(other) {
|
|
93
|
-
if (other.kind !== "file")
|
|
94
|
-
return false;
|
|
95
|
-
if (!(other instanceof _NodeFileSystemFileHandle))
|
|
96
|
-
return false;
|
|
97
|
-
return this.filePath === other.filePath;
|
|
98
|
-
}
|
|
99
|
-
async queryPermission() {
|
|
100
|
-
return "granted";
|
|
101
|
-
}
|
|
102
|
-
async requestPermission() {
|
|
103
|
-
return "granted";
|
|
104
|
-
}
|
|
105
|
-
getMimeType(filePath) {
|
|
106
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
107
|
-
const mimeTypes = {
|
|
108
|
-
".txt": "text/plain",
|
|
109
|
-
".html": "text/html",
|
|
110
|
-
".css": "text/css",
|
|
111
|
-
".js": "text/javascript",
|
|
112
|
-
".json": "application/json",
|
|
113
|
-
".png": "image/png",
|
|
114
|
-
".jpg": "image/jpeg",
|
|
115
|
-
".jpeg": "image/jpeg",
|
|
116
|
-
".gif": "image/gif",
|
|
117
|
-
".svg": "image/svg+xml",
|
|
118
|
-
".pdf": "application/pdf",
|
|
119
|
-
".zip": "application/zip"
|
|
120
|
-
};
|
|
121
|
-
return mimeTypes[ext] || "application/octet-stream";
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
var NodeFileSystemDirectoryHandle = class _NodeFileSystemDirectoryHandle {
|
|
125
|
-
constructor(dirPath) {
|
|
126
|
-
this.dirPath = dirPath;
|
|
127
|
-
this.name = path.basename(dirPath);
|
|
128
|
-
}
|
|
129
|
-
kind = "directory";
|
|
130
|
-
name;
|
|
131
|
-
async getFileHandle(name, options) {
|
|
132
|
-
const filePath = path.join(this.dirPath, name);
|
|
29
|
+
async readFile(filePath) {
|
|
133
30
|
try {
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
31
|
+
const fullPath = this.#resolvePath(filePath);
|
|
32
|
+
const [buffer, stats] = await Promise.all([
|
|
33
|
+
FS.readFile(fullPath),
|
|
34
|
+
FS.stat(fullPath)
|
|
35
|
+
]);
|
|
36
|
+
return {
|
|
37
|
+
content: new Uint8Array(buffer),
|
|
38
|
+
lastModified: stats.mtimeMs
|
|
39
|
+
};
|
|
141
40
|
} catch (error) {
|
|
142
41
|
if (error.code === "ENOENT") {
|
|
143
|
-
|
|
144
|
-
await fs.mkdir(this.dirPath, { recursive: true });
|
|
145
|
-
await fs.writeFile(filePath, "");
|
|
146
|
-
} else {
|
|
147
|
-
throw new DOMException("File not found", "NotFoundError");
|
|
148
|
-
}
|
|
149
|
-
} else {
|
|
150
|
-
throw error;
|
|
42
|
+
throw new DOMException("File not found", "NotFoundError");
|
|
151
43
|
}
|
|
44
|
+
throw error;
|
|
152
45
|
}
|
|
153
|
-
return new NodeFileSystemFileHandle(filePath);
|
|
154
46
|
}
|
|
155
|
-
async
|
|
156
|
-
const subDirPath = path.join(this.dirPath, name);
|
|
47
|
+
async writeFile(filePath, data) {
|
|
157
48
|
try {
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
"Path exists but is not a directory",
|
|
162
|
-
"TypeMismatchError"
|
|
163
|
-
);
|
|
164
|
-
}
|
|
49
|
+
const fullPath = this.#resolvePath(filePath);
|
|
50
|
+
await FS.mkdir(Path.dirname(fullPath), { recursive: true });
|
|
51
|
+
await FS.writeFile(fullPath, data);
|
|
165
52
|
} catch (error) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
throw new DOMException("Directory not found", "NotFoundError");
|
|
171
|
-
}
|
|
172
|
-
} else {
|
|
173
|
-
throw error;
|
|
174
|
-
}
|
|
53
|
+
throw new DOMException(
|
|
54
|
+
`Failed to write file: ${error}`,
|
|
55
|
+
"InvalidModificationError"
|
|
56
|
+
);
|
|
175
57
|
}
|
|
176
|
-
return new _NodeFileSystemDirectoryHandle(subDirPath);
|
|
177
58
|
}
|
|
178
|
-
async
|
|
179
|
-
const entryPath = path.join(this.dirPath, name);
|
|
59
|
+
async listDir(dirPath) {
|
|
180
60
|
try {
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
61
|
+
const fullPath = this.#resolvePath(dirPath);
|
|
62
|
+
const entries = await FS.readdir(fullPath, { withFileTypes: true });
|
|
63
|
+
const results = [];
|
|
64
|
+
for (const entry of entries) {
|
|
65
|
+
if (entry.isFile()) {
|
|
66
|
+
results.push({ name: entry.name, kind: "file" });
|
|
67
|
+
} else if (entry.isDirectory()) {
|
|
68
|
+
results.push({ name: entry.name, kind: "directory" });
|
|
69
|
+
}
|
|
186
70
|
}
|
|
71
|
+
return results;
|
|
187
72
|
} catch (error) {
|
|
188
73
|
if (error.code === "ENOENT") {
|
|
189
|
-
throw new DOMException("
|
|
74
|
+
throw new DOMException("Directory not found", "NotFoundError");
|
|
190
75
|
}
|
|
191
76
|
throw error;
|
|
192
77
|
}
|
|
193
78
|
}
|
|
194
|
-
async
|
|
195
|
-
|
|
79
|
+
async createDir(dirPath) {
|
|
80
|
+
try {
|
|
81
|
+
const fullPath = this.#resolvePath(dirPath);
|
|
82
|
+
await FS.mkdir(fullPath, { recursive: true });
|
|
83
|
+
} catch (error) {
|
|
84
|
+
throw new DOMException(
|
|
85
|
+
`Failed to create directory: ${error}`,
|
|
86
|
+
"InvalidModificationError"
|
|
87
|
+
);
|
|
88
|
+
}
|
|
196
89
|
}
|
|
197
|
-
async
|
|
90
|
+
async remove(entryPath, recursive) {
|
|
198
91
|
try {
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
92
|
+
const fullPath = this.#resolvePath(entryPath);
|
|
93
|
+
const stats = await FS.stat(fullPath);
|
|
94
|
+
if (stats.isFile()) {
|
|
95
|
+
await FS.unlink(fullPath);
|
|
96
|
+
} else if (stats.isDirectory()) {
|
|
97
|
+
if (recursive) {
|
|
98
|
+
await FS.rm(fullPath, { recursive: true, force: true });
|
|
99
|
+
} else {
|
|
100
|
+
const entries = await FS.readdir(fullPath);
|
|
101
|
+
if (entries.length > 0) {
|
|
102
|
+
throw new DOMException(
|
|
103
|
+
"Directory is not empty",
|
|
104
|
+
"InvalidModificationError"
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
await FS.rmdir(fullPath);
|
|
206
108
|
}
|
|
207
109
|
}
|
|
208
110
|
} catch (error) {
|
|
209
111
|
if (error.code === "ENOENT") {
|
|
210
|
-
throw new DOMException("
|
|
112
|
+
throw new DOMException("Entry not found", "NotFoundError");
|
|
211
113
|
}
|
|
212
114
|
throw error;
|
|
213
115
|
}
|
|
214
116
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
117
|
+
#resolvePath(relativePath) {
|
|
118
|
+
const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
|
|
119
|
+
if (!cleanPath) {
|
|
120
|
+
return this.#rootPath;
|
|
218
121
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
122
|
+
if (cleanPath.includes("..") || cleanPath.includes("\0")) {
|
|
123
|
+
throw new DOMException(
|
|
124
|
+
"Invalid path: contains path traversal or null bytes",
|
|
125
|
+
"NotAllowedError"
|
|
126
|
+
);
|
|
223
127
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
async queryPermission() {
|
|
233
|
-
return "granted";
|
|
234
|
-
}
|
|
235
|
-
async requestPermission() {
|
|
236
|
-
return "granted";
|
|
128
|
+
const resolvedPath = Path.resolve(this.#rootPath, cleanPath);
|
|
129
|
+
if (!resolvedPath.startsWith(Path.resolve(this.#rootPath))) {
|
|
130
|
+
throw new DOMException(
|
|
131
|
+
"Invalid path: outside of root directory",
|
|
132
|
+
"NotAllowedError"
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
return resolvedPath;
|
|
237
136
|
}
|
|
238
137
|
};
|
|
239
|
-
var
|
|
240
|
-
|
|
241
|
-
rootPath
|
|
242
|
-
|
|
243
|
-
this
|
|
244
|
-
name: "node",
|
|
245
|
-
...config
|
|
246
|
-
};
|
|
247
|
-
this.rootPath = config.rootPath || path.join(process.cwd(), "dist");
|
|
248
|
-
}
|
|
249
|
-
async getDirectoryHandle(name) {
|
|
250
|
-
const dirPath = name ? path.join(this.rootPath, name) : this.rootPath;
|
|
251
|
-
try {
|
|
252
|
-
await fs.mkdir(dirPath, { recursive: true });
|
|
253
|
-
} catch (error) {
|
|
254
|
-
}
|
|
255
|
-
return new NodeFileSystemDirectoryHandle(dirPath);
|
|
138
|
+
var NodeBucket = class extends ShovelDirectoryHandle {
|
|
139
|
+
#rootPath;
|
|
140
|
+
constructor(rootPath) {
|
|
141
|
+
super(new NodeFileSystemBackend(rootPath), "/");
|
|
142
|
+
this.#rootPath = rootPath;
|
|
256
143
|
}
|
|
257
|
-
|
|
258
|
-
|
|
144
|
+
// Override name to use the directory basename instead of "/"
|
|
145
|
+
get name() {
|
|
146
|
+
return Path.basename(this.#rootPath) || "root";
|
|
259
147
|
}
|
|
260
148
|
};
|
|
261
149
|
export {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
NodeFileSystemFileHandle,
|
|
265
|
-
NodeFileSystemWritableFileStream
|
|
150
|
+
NodeBucket,
|
|
151
|
+
NodeFileSystemBackend
|
|
266
152
|
};
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import type { Bucket } from "./types.js";
|
|
2
|
-
/**
|
|
3
|
-
* BucketStorage implements bucket storage with a configurable factory
|
|
4
|
-
* The factory function receives the bucket name and can return different filesystem types
|
|
5
|
-
* This mirrors the CustomCacheStorage pattern for consistency
|
|
6
|
-
*
|
|
7
|
-
* Example usage:
|
|
8
|
-
* ```typescript
|
|
9
|
-
* const buckets = new BucketStorage((name) => {
|
|
10
|
-
* if (name === 'uploads') return new S3Bucket('my-bucket');
|
|
11
|
-
* if (name === 'temp') return new LocalBucket('/tmp');
|
|
12
|
-
* return new LocalBucket('./dist'); // Default to dist
|
|
13
|
-
* });
|
|
14
|
-
* ```
|
|
15
|
-
*/
|
|
16
|
-
export declare class BucketStorage {
|
|
17
|
-
private factory;
|
|
18
|
-
private instances;
|
|
19
|
-
constructor(factory: (name: string) => Bucket | Promise<Bucket>);
|
|
20
|
-
/**
|
|
21
|
-
* Opens a bucket with the given name
|
|
22
|
-
* Returns existing instance if already opened, otherwise creates a new one
|
|
23
|
-
*/
|
|
24
|
-
open(name: string): Promise<FileSystemDirectoryHandle>;
|
|
25
|
-
/**
|
|
26
|
-
* Returns true if a bucket with the given name exists (has been opened)
|
|
27
|
-
*/
|
|
28
|
-
has(name: string): Promise<boolean>;
|
|
29
|
-
/**
|
|
30
|
-
* Deletes a bucket with the given name
|
|
31
|
-
* Disposes of the instance if it exists
|
|
32
|
-
*/
|
|
33
|
-
delete(name: string): Promise<boolean>;
|
|
34
|
-
/**
|
|
35
|
-
* Returns a list of all opened bucket names
|
|
36
|
-
*/
|
|
37
|
-
keys(): Promise<string[]>;
|
|
38
|
-
/**
|
|
39
|
-
* Get statistics about the bucket storage
|
|
40
|
-
*/
|
|
41
|
-
getStats(): {
|
|
42
|
-
openInstances: number;
|
|
43
|
-
bucketNames: string[];
|
|
44
|
-
};
|
|
45
|
-
/**
|
|
46
|
-
* Dispose of all open adapter instances
|
|
47
|
-
* Useful for cleanup during shutdown
|
|
48
|
-
*/
|
|
49
|
-
dispose(): Promise<void>;
|
|
50
|
-
}
|
package/src/directory-storage.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/// <reference types="./directory-storage.d.ts" />
|
|
2
|
-
// src/directory-storage.ts
|
|
3
|
-
var BucketStorage = class {
|
|
4
|
-
constructor(factory) {
|
|
5
|
-
this.factory = factory;
|
|
6
|
-
}
|
|
7
|
-
instances = /* @__PURE__ */ new Map();
|
|
8
|
-
/**
|
|
9
|
-
* Opens a bucket with the given name
|
|
10
|
-
* Returns existing instance if already opened, otherwise creates a new one
|
|
11
|
-
*/
|
|
12
|
-
async open(name) {
|
|
13
|
-
const existingInstance = this.instances.get(name);
|
|
14
|
-
if (existingInstance) {
|
|
15
|
-
return await existingInstance.getDirectoryHandle("");
|
|
16
|
-
}
|
|
17
|
-
const adapter = await this.factory(name);
|
|
18
|
-
this.instances.set(name, adapter);
|
|
19
|
-
return await adapter.getDirectoryHandle("");
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Returns true if a bucket with the given name exists (has been opened)
|
|
23
|
-
*/
|
|
24
|
-
async has(name) {
|
|
25
|
-
return this.instances.has(name);
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Deletes a bucket with the given name
|
|
29
|
-
* Disposes of the instance if it exists
|
|
30
|
-
*/
|
|
31
|
-
async delete(name) {
|
|
32
|
-
const instance = this.instances.get(name);
|
|
33
|
-
if (instance) {
|
|
34
|
-
if (instance.dispose) {
|
|
35
|
-
await instance.dispose();
|
|
36
|
-
}
|
|
37
|
-
this.instances.delete(name);
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Returns a list of all opened bucket names
|
|
44
|
-
*/
|
|
45
|
-
async keys() {
|
|
46
|
-
return Array.from(this.instances.keys());
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Get statistics about the bucket storage
|
|
50
|
-
*/
|
|
51
|
-
getStats() {
|
|
52
|
-
return {
|
|
53
|
-
openInstances: this.instances.size,
|
|
54
|
-
bucketNames: Array.from(this.instances.keys())
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Dispose of all open adapter instances
|
|
59
|
-
* Useful for cleanup during shutdown
|
|
60
|
-
*/
|
|
61
|
-
async dispose() {
|
|
62
|
-
const disposePromises = [];
|
|
63
|
-
for (const [_name, instance] of this.instances) {
|
|
64
|
-
if (instance.dispose) {
|
|
65
|
-
disposePromises.push(instance.dispose());
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
await Promise.all(disposePromises);
|
|
69
|
-
this.instances.clear();
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
export {
|
|
73
|
-
BucketStorage
|
|
74
|
-
};
|
package/src/registry.d.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Filesystem adapter registry
|
|
3
|
-
* Manages registration and retrieval of filesystem adapters
|
|
4
|
-
*/
|
|
5
|
-
import type { FileSystemAdapter } from "./types.js";
|
|
6
|
-
/**
|
|
7
|
-
* Global registry of filesystem adapters
|
|
8
|
-
*/
|
|
9
|
-
declare class Registry {
|
|
10
|
-
private adapters;
|
|
11
|
-
private defaultAdapter;
|
|
12
|
-
constructor();
|
|
13
|
-
/**
|
|
14
|
-
* Register a filesystem adapter with a name
|
|
15
|
-
*/
|
|
16
|
-
register(name: string, adapter: FileSystemAdapter): void;
|
|
17
|
-
/**
|
|
18
|
-
* Get a filesystem adapter by name
|
|
19
|
-
*/
|
|
20
|
-
get(name?: string): FileSystemAdapter | null;
|
|
21
|
-
/**
|
|
22
|
-
* Set the default filesystem adapter
|
|
23
|
-
*/
|
|
24
|
-
setDefault(adapter: FileSystemAdapter): void;
|
|
25
|
-
/**
|
|
26
|
-
* Get all registered adapter names
|
|
27
|
-
*/
|
|
28
|
-
getAdapterNames(): string[];
|
|
29
|
-
/**
|
|
30
|
-
* Clear all registered adapters
|
|
31
|
-
*/
|
|
32
|
-
clear(): void;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Global filesystem registry instance
|
|
36
|
-
*/
|
|
37
|
-
export declare const FileSystemRegistry: Registry;
|
|
38
|
-
/**
|
|
39
|
-
* Get a file system directory handle using the registered adapters
|
|
40
|
-
* @param name Directory name. Use "" for root directory
|
|
41
|
-
* @param adapterName Optional adapter name (uses default if not specified)
|
|
42
|
-
*/
|
|
43
|
-
export declare function getDirectoryHandle(name: string, adapterName?: string): Promise<FileSystemDirectoryHandle>;
|
|
44
|
-
/**
|
|
45
|
-
* @deprecated Use getDirectoryHandle() instead
|
|
46
|
-
*/
|
|
47
|
-
export declare function getBucket(name?: string, adapterName?: string): Promise<FileSystemDirectoryHandle>;
|
|
48
|
-
/**
|
|
49
|
-
* @deprecated Use getDirectoryHandle() instead
|
|
50
|
-
*/
|
|
51
|
-
export declare function getFileSystemRoot(name?: string): Promise<FileSystemDirectoryHandle>;
|
|
52
|
-
export {};
|
package/src/registry.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/// <reference types="./registry.d.ts" />
|
|
2
|
-
// src/registry.ts
|
|
3
|
-
import { MemoryBucket } from "./memory.js";
|
|
4
|
-
var Registry = class {
|
|
5
|
-
adapters = /* @__PURE__ */ new Map();
|
|
6
|
-
defaultAdapter;
|
|
7
|
-
constructor() {
|
|
8
|
-
this.defaultAdapter = new MemoryBucket();
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Register a filesystem adapter with a name
|
|
12
|
-
*/
|
|
13
|
-
register(name, adapter) {
|
|
14
|
-
this.adapters.set(name, adapter);
|
|
15
|
-
if (!this.defaultAdapter) {
|
|
16
|
-
this.defaultAdapter = adapter;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Get a filesystem adapter by name
|
|
21
|
-
*/
|
|
22
|
-
get(name) {
|
|
23
|
-
if (!name) {
|
|
24
|
-
return this.defaultAdapter;
|
|
25
|
-
}
|
|
26
|
-
return this.adapters.get(name) || this.defaultAdapter;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Set the default filesystem adapter
|
|
30
|
-
*/
|
|
31
|
-
setDefault(adapter) {
|
|
32
|
-
this.defaultAdapter = adapter;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Get all registered adapter names
|
|
36
|
-
*/
|
|
37
|
-
getAdapterNames() {
|
|
38
|
-
return Array.from(this.adapters.keys());
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Clear all registered adapters
|
|
42
|
-
*/
|
|
43
|
-
clear() {
|
|
44
|
-
this.adapters.clear();
|
|
45
|
-
this.defaultAdapter = null;
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
var FileSystemRegistry = new Registry();
|
|
49
|
-
async function getDirectoryHandle(name, adapterName) {
|
|
50
|
-
const adapter = FileSystemRegistry.get(adapterName);
|
|
51
|
-
if (!adapter) {
|
|
52
|
-
if (adapterName) {
|
|
53
|
-
throw new Error(`No filesystem adapter registered with name: ${adapterName}`);
|
|
54
|
-
} else {
|
|
55
|
-
throw new Error("No default filesystem adapter registered");
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return await adapter.getDirectoryHandle(name);
|
|
59
|
-
}
|
|
60
|
-
async function getBucket(name, adapterName) {
|
|
61
|
-
const adapter = FileSystemRegistry.get(adapterName);
|
|
62
|
-
if (!adapter) {
|
|
63
|
-
throw new Error("No default filesystem adapter registered");
|
|
64
|
-
}
|
|
65
|
-
return await adapter.getDirectoryHandle(name || "");
|
|
66
|
-
}
|
|
67
|
-
async function getFileSystemRoot(name) {
|
|
68
|
-
const adapter = FileSystemRegistry.get();
|
|
69
|
-
if (!adapter) {
|
|
70
|
-
throw new Error("No default filesystem adapter registered");
|
|
71
|
-
}
|
|
72
|
-
return await adapter.getDirectoryHandle(name || "");
|
|
73
|
-
}
|
|
74
|
-
export {
|
|
75
|
-
FileSystemRegistry,
|
|
76
|
-
getBucket,
|
|
77
|
-
getDirectoryHandle,
|
|
78
|
-
getFileSystemRoot
|
|
79
|
-
};
|
package/src/types.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core filesystem adapter interface and types
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Configuration for filesystem adapters
|
|
6
|
-
*/
|
|
7
|
-
export interface FileSystemConfig {
|
|
8
|
-
/** Human readable name for this filesystem */
|
|
9
|
-
name?: string;
|
|
10
|
-
/** Platform-specific configuration */
|
|
11
|
-
[key: string]: any;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Core interface that all buckets must implement
|
|
15
|
-
* Provides File System Access API compatibility across all platforms
|
|
16
|
-
*/
|
|
17
|
-
export interface Bucket {
|
|
18
|
-
/**
|
|
19
|
-
* Get a directory handle for the bucket
|
|
20
|
-
* @param name Directory name. Use "" for root directory
|
|
21
|
-
*/
|
|
22
|
-
getDirectoryHandle(name: string): Promise<FileSystemDirectoryHandle>;
|
|
23
|
-
/**
|
|
24
|
-
* Get configuration for this bucket
|
|
25
|
-
*/
|
|
26
|
-
getConfig(): FileSystemConfig;
|
|
27
|
-
/**
|
|
28
|
-
* Cleanup resources when bucket is no longer needed
|
|
29
|
-
*/
|
|
30
|
-
dispose?(): Promise<void>;
|
|
31
|
-
}
|
package/src/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/// <reference types="./types.d.ts" />
|