@zenfs/dom 0.0.4 → 0.0.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/dist/backends/FileSystemAccess.d.ts +1 -1
- package/dist/backends/FileSystemAccess.js +154 -208
- package/dist/backends/HTTPRequest.d.ts +4 -5
- package/dist/backends/HTTPRequest.js +81 -97
- package/dist/backends/Storage.js +2 -2
- package/dist/backends/Worker.d.ts +4 -5
- package/dist/backends/Worker.js +23 -29
- package/dist/browser.min.js +3 -3
- package/dist/browser.min.js.map +3 -3
- package/dist/fetch.js +20 -33
- package/package.json +2 -2
|
@@ -29,7 +29,7 @@ export declare class FileSystemAccessFileSystem extends BaseFileSystem {
|
|
|
29
29
|
get metadata(): FileSystemMetadata;
|
|
30
30
|
_sync(p: string, data: Uint8Array, stats: Stats, cred: Cred): Promise<void>;
|
|
31
31
|
rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
|
|
32
|
-
writeFile(fname: string, data:
|
|
32
|
+
writeFile(fname: string, data: Uint8Array, flag: FileFlag, mode: number, cred: Cred, createFile?: boolean): Promise<void>;
|
|
33
33
|
createFile(p: string, flag: FileFlag, mode: number, cred: Cred): Promise<FileSystemAccessFile>;
|
|
34
34
|
stat(path: string, cred: Cred): Promise<Stats>;
|
|
35
35
|
exists(p: string, cred: Cred): Promise<boolean>;
|
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
11
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
12
|
-
var m = o[Symbol.asyncIterator], i;
|
|
13
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
14
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
15
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
16
|
-
};
|
|
17
1
|
var _a;
|
|
18
2
|
import { basename, dirname, join } from '@zenfs/core/emulation/path.js';
|
|
19
3
|
import { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';
|
|
@@ -32,18 +16,14 @@ export class FileSystemAccessFile extends PreloadFile {
|
|
|
32
16
|
constructor(_fs, _path, _flag, _stat, contents) {
|
|
33
17
|
super(_fs, _path, _flag, _stat, contents);
|
|
34
18
|
}
|
|
35
|
-
sync() {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
});
|
|
19
|
+
async sync() {
|
|
20
|
+
if (this.isDirty()) {
|
|
21
|
+
await this._fs._sync(this.getPath(), this.getBuffer(), this.getStats(), Cred.Root);
|
|
22
|
+
this.resetDirty();
|
|
23
|
+
}
|
|
42
24
|
}
|
|
43
|
-
close() {
|
|
44
|
-
|
|
45
|
-
yield this.sync();
|
|
46
|
-
});
|
|
25
|
+
async close() {
|
|
26
|
+
await this.sync();
|
|
47
27
|
}
|
|
48
28
|
}
|
|
49
29
|
export class FileSystemAccessFileSystem extends BaseFileSystem {
|
|
@@ -56,204 +36,170 @@ export class FileSystemAccessFileSystem extends BaseFileSystem {
|
|
|
56
36
|
this._handles.set('/', handle);
|
|
57
37
|
}
|
|
58
38
|
get metadata() {
|
|
59
|
-
return
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
for (const file of files) {
|
|
81
|
-
yield this.rename(join(oldPath, file), join(newPath, file), cred);
|
|
82
|
-
yield this.unlink(oldPath, cred);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
39
|
+
return {
|
|
40
|
+
...super.metadata,
|
|
41
|
+
name: _a.Name,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
async _sync(p, data, stats, cred) {
|
|
45
|
+
const currentStats = await this.stat(p, cred);
|
|
46
|
+
if (stats.mtime !== currentStats.mtime) {
|
|
47
|
+
await this.writeFile(p, data, FileFlag.getFileFlag('w'), currentStats.mode, cred);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async rename(oldPath, newPath, cred) {
|
|
51
|
+
try {
|
|
52
|
+
const handle = await this.getHandle(oldPath);
|
|
53
|
+
if (handle instanceof FileSystemDirectoryHandle) {
|
|
54
|
+
const files = await this.readdir(oldPath, cred);
|
|
55
|
+
await this.mkdir(newPath, 'wx', cred);
|
|
56
|
+
if (files.length === 0) {
|
|
57
|
+
await this.unlink(oldPath, cred);
|
|
85
58
|
}
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const writable = yield newFile.createWritable();
|
|
91
|
-
const buffer = yield oldFile.arrayBuffer();
|
|
92
|
-
yield writable.write(buffer);
|
|
93
|
-
writable.close();
|
|
94
|
-
yield this.unlink(oldPath, cred);
|
|
59
|
+
else {
|
|
60
|
+
for (const file of files) {
|
|
61
|
+
await this.rename(join(oldPath, file), join(newPath, file), cred);
|
|
62
|
+
await this.unlink(oldPath, cred);
|
|
95
63
|
}
|
|
96
64
|
}
|
|
97
65
|
}
|
|
98
|
-
catch (err) {
|
|
99
|
-
handleError(oldPath, err);
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
writeFile(fname, data, encoding, flag, mode, cred, createFile) {
|
|
104
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
105
|
-
const handle = yield this.getHandle(dirname(fname));
|
|
106
|
-
if (handle instanceof FileSystemDirectoryHandle) {
|
|
107
|
-
const file = yield handle.getFileHandle(basename(fname), { create: true });
|
|
108
|
-
const writable = yield file.createWritable();
|
|
109
|
-
yield writable.write(data);
|
|
110
|
-
yield writable.close();
|
|
111
|
-
//return createFile ? this.newFile(fname, flag, data) : undefined;
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
createFile(p, flag, mode, cred) {
|
|
116
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
117
|
-
yield this.writeFile(p, new Uint8Array(), null, flag, mode, cred, true);
|
|
118
|
-
return this.openFile(p, flag, cred);
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
stat(path, cred) {
|
|
122
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
123
|
-
const handle = yield this.getHandle(path);
|
|
124
|
-
if (!handle) {
|
|
125
|
-
throw ApiError.FileError(ErrorCode.EINVAL, path);
|
|
126
|
-
}
|
|
127
|
-
if (handle instanceof FileSystemDirectoryHandle) {
|
|
128
|
-
return new Stats(FileType.DIRECTORY, 4096);
|
|
129
|
-
}
|
|
130
|
-
if (handle instanceof FileSystemFileHandle) {
|
|
131
|
-
const { lastModified, size } = yield handle.getFile();
|
|
132
|
-
return new Stats(FileType.FILE, size, undefined, undefined, lastModified);
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
exists(p, cred) {
|
|
137
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
138
|
-
try {
|
|
139
|
-
yield this.getHandle(p);
|
|
140
|
-
return true;
|
|
141
|
-
}
|
|
142
|
-
catch (e) {
|
|
143
|
-
return false;
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
openFile(path, flags, cred) {
|
|
148
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
149
|
-
const handle = yield this.getHandle(path);
|
|
150
66
|
if (handle instanceof FileSystemFileHandle) {
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
const handle = yield this.getHandle(dirname(path));
|
|
160
|
-
if (handle instanceof FileSystemDirectoryHandle) {
|
|
161
|
-
try {
|
|
162
|
-
yield handle.removeEntry(basename(path), { recursive: true });
|
|
163
|
-
}
|
|
164
|
-
catch (e) {
|
|
165
|
-
handleError(path, e);
|
|
67
|
+
const oldFile = await handle.getFile(), destFolder = await this.getHandle(dirname(newPath));
|
|
68
|
+
if (destFolder instanceof FileSystemDirectoryHandle) {
|
|
69
|
+
const newFile = await destFolder.getFileHandle(basename(newPath), { create: true });
|
|
70
|
+
const writable = await newFile.createWritable();
|
|
71
|
+
const buffer = await oldFile.arrayBuffer();
|
|
72
|
+
await writable.write(buffer);
|
|
73
|
+
writable.close();
|
|
74
|
+
await this.unlink(oldPath, cred);
|
|
166
75
|
}
|
|
167
76
|
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
handleError(oldPath, err);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async writeFile(fname, data, flag, mode, cred, createFile) {
|
|
83
|
+
const handle = await this.getHandle(dirname(fname));
|
|
84
|
+
if (handle instanceof FileSystemDirectoryHandle) {
|
|
85
|
+
const file = await handle.getFileHandle(basename(fname), { create: true });
|
|
86
|
+
const writable = await file.createWritable();
|
|
87
|
+
await writable.write(data);
|
|
88
|
+
await writable.close();
|
|
89
|
+
//return createFile ? this.newFile(fname, flag, data) : undefined;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async createFile(p, flag, mode, cred) {
|
|
93
|
+
await this.writeFile(p, new Uint8Array(), flag, mode, cred, true);
|
|
94
|
+
return this.openFile(p, flag, cred);
|
|
95
|
+
}
|
|
96
|
+
async stat(path, cred) {
|
|
97
|
+
const handle = await this.getHandle(path);
|
|
98
|
+
if (!handle) {
|
|
99
|
+
throw ApiError.FileError(ErrorCode.EINVAL, path);
|
|
100
|
+
}
|
|
101
|
+
if (handle instanceof FileSystemDirectoryHandle) {
|
|
102
|
+
return new Stats(FileType.DIRECTORY, 4096);
|
|
103
|
+
}
|
|
104
|
+
if (handle instanceof FileSystemFileHandle) {
|
|
105
|
+
const { lastModified, size } = await handle.getFile();
|
|
106
|
+
return new Stats(FileType.FILE, size, undefined, undefined, lastModified);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async exists(p, cred) {
|
|
110
|
+
try {
|
|
111
|
+
await this.getHandle(p);
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
catch (e) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async openFile(path, flags, cred) {
|
|
119
|
+
const handle = await this.getHandle(path);
|
|
120
|
+
if (handle instanceof FileSystemFileHandle) {
|
|
121
|
+
const file = await handle.getFile();
|
|
122
|
+
const buffer = await file.arrayBuffer();
|
|
123
|
+
return this.newFile(path, flags, buffer, file.size, file.lastModified);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async unlink(path, cred) {
|
|
127
|
+
const handle = await this.getHandle(dirname(path));
|
|
128
|
+
if (handle instanceof FileSystemDirectoryHandle) {
|
|
196
129
|
try {
|
|
197
|
-
|
|
198
|
-
_d = _g.value;
|
|
199
|
-
_e = false;
|
|
200
|
-
const key = _d;
|
|
201
|
-
_keys.push(join(path, key));
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
205
|
-
finally {
|
|
206
|
-
try {
|
|
207
|
-
if (!_e && !_b && (_c = _f.return)) yield _c.call(_f);
|
|
208
|
-
}
|
|
209
|
-
finally { if (e_1) throw e_1.error; }
|
|
130
|
+
await handle.removeEntry(basename(path), { recursive: true });
|
|
210
131
|
}
|
|
211
|
-
|
|
212
|
-
|
|
132
|
+
catch (e) {
|
|
133
|
+
handleError(path, e);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async rmdir(path, cred) {
|
|
138
|
+
return this.unlink(path, cred);
|
|
139
|
+
}
|
|
140
|
+
async mkdir(p, mode, cred) {
|
|
141
|
+
const overwrite = mode && mode.flag && mode.flag.includes('w') && !mode.flag.includes('x');
|
|
142
|
+
const existingHandle = await this.getHandle(p);
|
|
143
|
+
if (existingHandle && !overwrite) {
|
|
144
|
+
throw ApiError.EEXIST(p);
|
|
145
|
+
}
|
|
146
|
+
const handle = await this.getHandle(dirname(p));
|
|
147
|
+
if (handle instanceof FileSystemDirectoryHandle) {
|
|
148
|
+
await handle.getDirectoryHandle(basename(p), { create: true });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
async readdir(path, cred) {
|
|
152
|
+
const handle = await this.getHandle(path);
|
|
153
|
+
if (!(handle instanceof FileSystemDirectoryHandle)) {
|
|
154
|
+
throw ApiError.ENOTDIR(path);
|
|
155
|
+
}
|
|
156
|
+
const _keys = [];
|
|
157
|
+
for await (const key of handle.keys()) {
|
|
158
|
+
_keys.push(join(path, key));
|
|
159
|
+
}
|
|
160
|
+
return _keys;
|
|
213
161
|
}
|
|
214
162
|
newFile(path, flag, data, size, lastModified) {
|
|
215
163
|
return new FileSystemAccessFile(this, path, flag, new Stats(FileType.FILE, size || 0, undefined, undefined, lastModified || new Date().getTime()), new Uint8Array(data));
|
|
216
164
|
}
|
|
217
|
-
getHandle(path) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
return this._handles.get(path);
|
|
231
|
-
}
|
|
232
|
-
getHandleParts(remainingPathParts);
|
|
233
|
-
};
|
|
234
|
-
const handle = this._handles.get(walkedPath);
|
|
235
|
-
try {
|
|
236
|
-
return yield continueWalk(yield handle.getDirectoryHandle(pathPart));
|
|
165
|
+
async getHandle(path) {
|
|
166
|
+
if (this._handles.has(path)) {
|
|
167
|
+
return this._handles.get(path);
|
|
168
|
+
}
|
|
169
|
+
let walkedPath = '/';
|
|
170
|
+
const [, ...pathParts] = path.split('/');
|
|
171
|
+
const getHandleParts = async ([pathPart, ...remainingPathParts]) => {
|
|
172
|
+
const walkingPath = join(walkedPath, pathPart);
|
|
173
|
+
const continueWalk = (handle) => {
|
|
174
|
+
walkedPath = walkingPath;
|
|
175
|
+
this._handles.set(walkedPath, handle);
|
|
176
|
+
if (remainingPathParts.length === 0) {
|
|
177
|
+
return this._handles.get(path);
|
|
237
178
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
throw new ApiError(ErrorCode.ENOENT, error.message, walkingPath);
|
|
179
|
+
getHandleParts(remainingPathParts);
|
|
180
|
+
};
|
|
181
|
+
const handle = this._handles.get(walkedPath);
|
|
182
|
+
try {
|
|
183
|
+
return await continueWalk(await handle.getDirectoryHandle(pathPart));
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
if (error.name === 'TypeMismatchError') {
|
|
187
|
+
try {
|
|
188
|
+
return await continueWalk(await handle.getFileHandle(pathPart));
|
|
249
189
|
}
|
|
250
|
-
|
|
251
|
-
handleError(walkingPath,
|
|
190
|
+
catch (err) {
|
|
191
|
+
handleError(walkingPath, err);
|
|
252
192
|
}
|
|
253
193
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
194
|
+
else if (error.message === 'Name is not allowed.') {
|
|
195
|
+
throw new ApiError(ErrorCode.ENOENT, error.message, walkingPath);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
handleError(walkingPath, error);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
await getHandleParts(pathParts);
|
|
257
203
|
}
|
|
258
204
|
}
|
|
259
205
|
_a = FileSystemAccessFileSystem;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { BaseFileSystem, FileContents, FileSystemMetadata } from '@zenfs/core/filesystem.js';
|
|
1
|
+
import { BaseFileSystem, FileSystemMetadata } from '@zenfs/core/filesystem.js';
|
|
3
2
|
import { FileFlag, NoSyncFile } from '@zenfs/core/file.js';
|
|
4
3
|
import { Stats } from '@zenfs/core/stats.js';
|
|
5
4
|
import { Cred } from '@zenfs/core/cred.js';
|
|
@@ -63,8 +62,8 @@ export declare class HTTPRequest extends BaseFileSystem {
|
|
|
63
62
|
empty(): void;
|
|
64
63
|
/**
|
|
65
64
|
* Special HTTPFS function: Preload the given file into the index.
|
|
66
|
-
* @param
|
|
67
|
-
* @param
|
|
65
|
+
* @param path
|
|
66
|
+
* @param buffer
|
|
68
67
|
*/
|
|
69
68
|
preloadFile(path: string, buffer: Uint8Array): void;
|
|
70
69
|
stat(path: string, cred: Cred): Promise<Stats>;
|
|
@@ -73,7 +72,7 @@ export declare class HTTPRequest extends BaseFileSystem {
|
|
|
73
72
|
/**
|
|
74
73
|
* We have the entire file as a buffer; optimize readFile.
|
|
75
74
|
*/
|
|
76
|
-
readFile(fname: string,
|
|
75
|
+
readFile(fname: string, flag: FileFlag, cred: Cred): Promise<Uint8Array>;
|
|
77
76
|
private _getHTTPPath;
|
|
78
77
|
/**
|
|
79
78
|
* Asynchronously download the given file.
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
var _a;
|
|
11
2
|
import { BaseFileSystem } from '@zenfs/core/filesystem.js';
|
|
12
3
|
import { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';
|
|
@@ -16,7 +7,6 @@ import { fetchIsAvailable, fetchFile, fetchFileSize } from '../fetch.js';
|
|
|
16
7
|
import { FileIndex, isIndexFileInode, isIndexDirInode } from '@zenfs/core/FileIndex.js';
|
|
17
8
|
import { CreateBackend } from '@zenfs/core/backends/backend.js';
|
|
18
9
|
import { R_OK } from '@zenfs/core/emulation/constants.js';
|
|
19
|
-
import { decode } from '@zenfs/core/utils.js';
|
|
20
10
|
/**
|
|
21
11
|
* A simple filesystem backed by HTTP downloads. You must create a directory listing using the
|
|
22
12
|
* `make_http_index` tool provided by ZenFS.
|
|
@@ -66,7 +56,11 @@ export class HTTPRequest extends BaseFileSystem {
|
|
|
66
56
|
this.prefixUrl = baseUrl;
|
|
67
57
|
}
|
|
68
58
|
get metadata() {
|
|
69
|
-
return
|
|
59
|
+
return {
|
|
60
|
+
...super.metadata,
|
|
61
|
+
name: _a.Name,
|
|
62
|
+
readonly: true,
|
|
63
|
+
};
|
|
70
64
|
}
|
|
71
65
|
empty() {
|
|
72
66
|
this._index.fileIterator(function (file) {
|
|
@@ -75,8 +69,8 @@ export class HTTPRequest extends BaseFileSystem {
|
|
|
75
69
|
}
|
|
76
70
|
/**
|
|
77
71
|
* Special HTTPFS function: Preload the given file into the index.
|
|
78
|
-
* @param
|
|
79
|
-
* @param
|
|
72
|
+
* @param path
|
|
73
|
+
* @param buffer
|
|
80
74
|
*/
|
|
81
75
|
preloadFile(path, buffer) {
|
|
82
76
|
const inode = this._index.getInode(path);
|
|
@@ -92,98 +86,88 @@ export class HTTPRequest extends BaseFileSystem {
|
|
|
92
86
|
throw ApiError.EISDIR(path);
|
|
93
87
|
}
|
|
94
88
|
}
|
|
95
|
-
stat(path, cred) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
stats.size = yield this._requestFileSize(path);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
else if (isIndexDirInode(inode)) {
|
|
113
|
-
stats = inode.getStats();
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
throw ApiError.FileError(ErrorCode.EINVAL, path);
|
|
89
|
+
async stat(path, cred) {
|
|
90
|
+
const inode = this._index.getInode(path);
|
|
91
|
+
if (inode === null) {
|
|
92
|
+
throw ApiError.ENOENT(path);
|
|
93
|
+
}
|
|
94
|
+
if (!inode.toStats().hasAccess(R_OK, cred)) {
|
|
95
|
+
throw ApiError.EACCES(path);
|
|
96
|
+
}
|
|
97
|
+
let stats;
|
|
98
|
+
if (isIndexFileInode(inode)) {
|
|
99
|
+
stats = inode.getData();
|
|
100
|
+
// At this point, a non-opened file will still have default stats from the listing.
|
|
101
|
+
if (stats.size < 0) {
|
|
102
|
+
stats.size = await this._requestFileSize(path);
|
|
117
103
|
}
|
|
118
|
-
|
|
119
|
-
|
|
104
|
+
}
|
|
105
|
+
else if (isIndexDirInode(inode)) {
|
|
106
|
+
stats = inode.getStats();
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
throw ApiError.FileError(ErrorCode.EINVAL, path);
|
|
110
|
+
}
|
|
111
|
+
return stats;
|
|
120
112
|
}
|
|
121
|
-
open(path, flags, mode, cred) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
throw new ApiError(ErrorCode.EINVAL, 'Invalid FileMode object.');
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
throw ApiError.EPERM(path);
|
|
113
|
+
async open(path, flags, mode, cred) {
|
|
114
|
+
// INVARIANT: You can't write to files on this file system.
|
|
115
|
+
if (flags.isWriteable()) {
|
|
116
|
+
throw new ApiError(ErrorCode.EPERM, path);
|
|
117
|
+
}
|
|
118
|
+
// Check if the path exists, and is a file.
|
|
119
|
+
const inode = this._index.getInode(path);
|
|
120
|
+
if (inode === null) {
|
|
121
|
+
throw ApiError.ENOENT(path);
|
|
122
|
+
}
|
|
123
|
+
if (!inode.toStats().hasAccess(flags.getMode(), cred)) {
|
|
124
|
+
throw ApiError.EACCES(path);
|
|
125
|
+
}
|
|
126
|
+
if (isIndexFileInode(inode) || isIndexDirInode(inode)) {
|
|
127
|
+
switch (flags.pathExistsAction()) {
|
|
128
|
+
case ActionType.THROW_EXCEPTION:
|
|
129
|
+
case ActionType.TRUNCATE_FILE:
|
|
130
|
+
throw ApiError.EEXIST(path);
|
|
131
|
+
case ActionType.NOP:
|
|
132
|
+
if (isIndexDirInode(inode)) {
|
|
133
|
+
const stats = inode.getStats();
|
|
134
|
+
return new NoSyncFile(this, path, flags, stats, stats.fileData || undefined);
|
|
135
|
+
}
|
|
136
|
+
const stats = inode.getData();
|
|
137
|
+
// Use existing file contents.
|
|
138
|
+
// XXX: Uh, this maintains the previously-used flag.
|
|
139
|
+
if (stats.fileData) {
|
|
140
|
+
return new NoSyncFile(this, path, flags, Stats.clone(stats), stats.fileData);
|
|
141
|
+
}
|
|
142
|
+
// @todo be lazier about actually requesting the file
|
|
143
|
+
const buffer = await this._requestFile(path, 'buffer');
|
|
144
|
+
// we don't initially have file sizes
|
|
145
|
+
stats.size = buffer.length;
|
|
146
|
+
stats.fileData = buffer;
|
|
147
|
+
return new NoSyncFile(this, path, flags, Stats.clone(stats), buffer);
|
|
148
|
+
default:
|
|
149
|
+
throw new ApiError(ErrorCode.EINVAL, 'Invalid FileMode object.');
|
|
163
150
|
}
|
|
164
|
-
}
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
throw ApiError.EPERM(path);
|
|
154
|
+
}
|
|
165
155
|
}
|
|
166
|
-
readdir(path, cred) {
|
|
167
|
-
return
|
|
168
|
-
return this.readdirSync(path, cred);
|
|
169
|
-
});
|
|
156
|
+
async readdir(path, cred) {
|
|
157
|
+
return this.readdirSync(path, cred);
|
|
170
158
|
}
|
|
171
159
|
/**
|
|
172
160
|
* We have the entire file as a buffer; optimize readFile.
|
|
173
161
|
*/
|
|
174
|
-
readFile(fname,
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
finally {
|
|
184
|
-
yield fd.close();
|
|
185
|
-
}
|
|
186
|
-
});
|
|
162
|
+
async readFile(fname, flag, cred) {
|
|
163
|
+
// Get file.
|
|
164
|
+
const fd = await this.open(fname, flag, 0o644, cred);
|
|
165
|
+
try {
|
|
166
|
+
return fd.getBuffer();
|
|
167
|
+
}
|
|
168
|
+
finally {
|
|
169
|
+
await fd.close();
|
|
170
|
+
}
|
|
187
171
|
}
|
|
188
172
|
_getHTTPPath(filePath) {
|
|
189
173
|
if (filePath.charAt(0) === '/') {
|