@zenfs/dom 0.0.4 → 0.0.5

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.
@@ -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: any, encoding: string | null, flag: FileFlag, mode: number, cred: Cred, createFile?: boolean): Promise<void>;
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
- return __awaiter(this, void 0, void 0, function* () {
37
- if (this.isDirty()) {
38
- yield this._fs._sync(this.getPath(), this.getBuffer(), this.getStats(), Cred.Root);
39
- this.resetDirty();
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
- return __awaiter(this, void 0, void 0, function* () {
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 Object.assign(Object.assign({}, super.metadata), { name: _a.Name });
60
- }
61
- _sync(p, data, stats, cred) {
62
- return __awaiter(this, void 0, void 0, function* () {
63
- const currentStats = yield this.stat(p, cred);
64
- if (stats.mtime !== currentStats.mtime) {
65
- yield this.writeFile(p, data, null, FileFlag.getFileFlag('w'), currentStats.mode, cred);
66
- }
67
- });
68
- }
69
- rename(oldPath, newPath, cred) {
70
- return __awaiter(this, void 0, void 0, function* () {
71
- try {
72
- const handle = yield this.getHandle(oldPath);
73
- if (handle instanceof FileSystemDirectoryHandle) {
74
- const files = yield this.readdir(oldPath, cred);
75
- yield this.mkdir(newPath, 'wx', cred);
76
- if (files.length === 0) {
77
- yield this.unlink(oldPath, cred);
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
- if (handle instanceof FileSystemFileHandle) {
87
- const oldFile = yield handle.getFile(), destFolder = yield this.getHandle(dirname(newPath));
88
- if (destFolder instanceof FileSystemDirectoryHandle) {
89
- const newFile = yield destFolder.getFileHandle(basename(newPath), { create: true });
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 file = yield handle.getFile();
152
- const buffer = yield file.arrayBuffer();
153
- return this.newFile(path, flags, buffer, file.size, file.lastModified);
154
- }
155
- });
156
- }
157
- unlink(path, cred) {
158
- return __awaiter(this, void 0, void 0, function* () {
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
- rmdir(path, cred) {
171
- return __awaiter(this, void 0, void 0, function* () {
172
- return this.unlink(path, cred);
173
- });
174
- }
175
- mkdir(p, mode, cred) {
176
- return __awaiter(this, void 0, void 0, function* () {
177
- const overwrite = mode && mode.flag && mode.flag.includes('w') && !mode.flag.includes('x');
178
- const existingHandle = yield this.getHandle(p);
179
- if (existingHandle && !overwrite) {
180
- throw ApiError.EEXIST(p);
181
- }
182
- const handle = yield this.getHandle(dirname(p));
183
- if (handle instanceof FileSystemDirectoryHandle) {
184
- yield handle.getDirectoryHandle(basename(p), { create: true });
185
- }
186
- });
187
- }
188
- readdir(path, cred) {
189
- var _b, e_1, _c, _d;
190
- return __awaiter(this, void 0, void 0, function* () {
191
- const handle = yield this.getHandle(path);
192
- if (!(handle instanceof FileSystemDirectoryHandle)) {
193
- throw ApiError.ENOTDIR(path);
194
- }
195
- const _keys = [];
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
- for (var _e = true, _f = __asyncValues(handle.keys()), _g; _g = yield _f.next(), _b = _g.done, !_b; _e = true) {
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
- return _keys;
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
- return __awaiter(this, void 0, void 0, function* () {
219
- if (this._handles.has(path)) {
220
- return this._handles.get(path);
221
- }
222
- let walkedPath = '/';
223
- const [, ...pathParts] = path.split('/');
224
- const getHandleParts = ([pathPart, ...remainingPathParts]) => __awaiter(this, void 0, void 0, function* () {
225
- const walkingPath = join(walkedPath, pathPart);
226
- const continueWalk = (handle) => {
227
- walkedPath = walkingPath;
228
- this._handles.set(walkedPath, handle);
229
- if (remainingPathParts.length === 0) {
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
- catch (error) {
239
- if (error.name === 'TypeMismatchError') {
240
- try {
241
- return yield continueWalk(yield handle.getFileHandle(pathPart));
242
- }
243
- catch (err) {
244
- handleError(walkingPath, err);
245
- }
246
- }
247
- else if (error.message === 'Name is not allowed.') {
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
- else {
251
- handleError(walkingPath, error);
190
+ catch (err) {
191
+ handleError(walkingPath, err);
252
192
  }
253
193
  }
254
- });
255
- yield getHandleParts(pathParts);
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
- /// <reference types="node" resolution-mode="require"/>
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 [String] path
67
- * @param [ZenFS.Uint8Array] buffer
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, encoding: BufferEncoding, flag: FileFlag, cred: Cred): Promise<FileContents>;
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 Object.assign(Object.assign({}, super.metadata), { name: _a.Name, readonly: true });
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 [String] path
79
- * @param [ZenFS.Uint8Array] buffer
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
- return __awaiter(this, void 0, void 0, function* () {
97
- const inode = this._index.getInode(path);
98
- if (inode === null) {
99
- throw ApiError.ENOENT(path);
100
- }
101
- if (!inode.toStats().hasAccess(R_OK, cred)) {
102
- throw ApiError.EACCES(path);
103
- }
104
- let stats;
105
- if (isIndexFileInode(inode)) {
106
- stats = inode.getData();
107
- // At this point, a non-opened file will still have default stats from the listing.
108
- if (stats.size < 0) {
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
- return stats;
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
- return __awaiter(this, void 0, void 0, function* () {
123
- // INVARIANT: You can't write to files on this file system.
124
- if (flags.isWriteable()) {
125
- throw new ApiError(ErrorCode.EPERM, path);
126
- }
127
- // Check if the path exists, and is a file.
128
- const inode = this._index.getInode(path);
129
- if (inode === null) {
130
- throw ApiError.ENOENT(path);
131
- }
132
- if (!inode.toStats().hasAccess(flags.getMode(), cred)) {
133
- throw ApiError.EACCES(path);
134
- }
135
- if (isIndexFileInode(inode) || isIndexDirInode(inode)) {
136
- switch (flags.pathExistsAction()) {
137
- case ActionType.THROW_EXCEPTION:
138
- case ActionType.TRUNCATE_FILE:
139
- throw ApiError.EEXIST(path);
140
- case ActionType.NOP:
141
- if (isIndexDirInode(inode)) {
142
- const stats = inode.getStats();
143
- return new NoSyncFile(this, path, flags, stats, stats.fileData || undefined);
144
- }
145
- const stats = inode.getData();
146
- // Use existing file contents.
147
- // XXX: Uh, this maintains the previously-used flag.
148
- if (stats.fileData) {
149
- return new NoSyncFile(this, path, flags, Stats.clone(stats), stats.fileData);
150
- }
151
- // @todo be lazier about actually requesting the file
152
- const buffer = yield this._requestFile(path, 'buffer');
153
- // we don't initially have file sizes
154
- stats.size = buffer.length;
155
- stats.fileData = buffer;
156
- return new NoSyncFile(this, path, flags, Stats.clone(stats), buffer);
157
- default:
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 __awaiter(this, void 0, void 0, function* () {
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, encoding, flag, cred) {
175
- return __awaiter(this, void 0, void 0, function* () {
176
- // Get file.
177
- const fd = yield this.open(fname, flag, 0o644, cred);
178
- try {
179
- const fdCast = fd;
180
- const fdBuff = fdCast.getBuffer();
181
- return encoding ? decode(fdBuff) : fdBuff;
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) === '/') {