@zenfs/core 0.0.12 → 0.2.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.
Files changed (54) hide show
  1. package/dist/ApiError.d.ts +52 -15
  2. package/dist/ApiError.js +77 -50
  3. package/dist/FileIndex.d.ts +32 -35
  4. package/dist/FileIndex.js +93 -109
  5. package/dist/backends/AsyncMirror.d.ts +42 -43
  6. package/dist/backends/AsyncMirror.js +154 -147
  7. package/dist/backends/AsyncStore.d.ts +29 -28
  8. package/dist/backends/AsyncStore.js +375 -482
  9. package/dist/backends/FolderAdapter.js +8 -19
  10. package/dist/backends/InMemory.d.ts +16 -13
  11. package/dist/backends/InMemory.js +29 -14
  12. package/dist/backends/Locked.d.ts +8 -28
  13. package/dist/backends/Locked.js +74 -224
  14. package/dist/backends/OverlayFS.d.ts +26 -34
  15. package/dist/backends/OverlayFS.js +303 -511
  16. package/dist/backends/SyncStore.d.ts +54 -72
  17. package/dist/backends/SyncStore.js +159 -161
  18. package/dist/backends/backend.d.ts +45 -29
  19. package/dist/backends/backend.js +83 -13
  20. package/dist/backends/index.d.ts +6 -7
  21. package/dist/backends/index.js +5 -6
  22. package/dist/browser.min.js +21 -6
  23. package/dist/browser.min.js.map +4 -4
  24. package/dist/emulation/callbacks.d.ts +119 -113
  25. package/dist/emulation/callbacks.js +129 -92
  26. package/dist/emulation/constants.js +1 -1
  27. package/dist/emulation/dir.d.ts +55 -0
  28. package/dist/emulation/dir.js +104 -0
  29. package/dist/emulation/fs.d.ts +1 -2
  30. package/dist/emulation/fs.js +0 -1
  31. package/dist/emulation/index.d.ts +3 -0
  32. package/dist/emulation/index.js +3 -0
  33. package/dist/emulation/promises.d.ts +265 -145
  34. package/dist/emulation/promises.js +526 -383
  35. package/dist/emulation/shared.d.ts +20 -6
  36. package/dist/emulation/shared.js +22 -23
  37. package/dist/emulation/streams.d.ts +102 -0
  38. package/dist/emulation/streams.js +55 -0
  39. package/dist/emulation/sync.d.ts +98 -69
  40. package/dist/emulation/sync.js +280 -133
  41. package/dist/file.d.ts +175 -173
  42. package/dist/file.js +257 -273
  43. package/dist/filesystem.d.ts +71 -244
  44. package/dist/filesystem.js +67 -472
  45. package/dist/index.d.ts +7 -44
  46. package/dist/index.js +22 -75
  47. package/dist/inode.d.ts +37 -28
  48. package/dist/inode.js +123 -65
  49. package/dist/stats.d.ts +91 -36
  50. package/dist/stats.js +138 -110
  51. package/dist/utils.d.ts +26 -13
  52. package/dist/utils.js +79 -107
  53. package/package.json +7 -4
  54. package/readme.md +2 -40
@@ -1,7 +1,10 @@
1
1
  import { ApiError, ErrorCode } from '../ApiError.js';
2
- import { FileFlag } from '../file.js';
3
- import { normalizePath, cred, getFdForFile, normalizeMode, normalizeOptions, fdMap, fd2file, normalizeTime, resolveFS, fixError, mounts } from './shared.js';
2
+ import { ActionType, FileFlag } from '../file.js';
3
+ import { BigIntStats, FileType } from '../stats.js';
4
+ import { normalizePath, cred, getFdForFile, normalizeMode, normalizeOptions, fdMap, fd2file, normalizeTime, resolveFS, fixError, mounts, } from './shared.js';
4
5
  import { decode, encode } from '../utils.js';
6
+ import { Dirent } from './dir.js';
7
+ import { dirname, join } from './path.js';
5
8
  function doOp(...[name, resolveSymlinks, path, ...args]) {
6
9
  path = normalizePath(path);
7
10
  const { fs, path: resolvedPath } = resolveFS(resolveSymlinks && existsSync(path) ? realpathSync(path) : path);
@@ -36,6 +39,7 @@ export function renameSync(oldPath, newPath) {
36
39
  throw fixError(e, paths);
37
40
  }
38
41
  }
42
+ renameSync;
39
43
  /**
40
44
  * Test whether or not the given path exists by checking with the file system.
41
45
  * @param path
@@ -53,35 +57,32 @@ export function existsSync(path) {
53
57
  throw e;
54
58
  }
55
59
  }
56
- /**
57
- * Synchronous `stat`.
58
- * @param path
59
- * @returns Stats
60
- */
61
- export function statSync(path) {
62
- return doOp('statSync', true, path, cred);
60
+ existsSync;
61
+ export function statSync(path, options) {
62
+ const stats = doOp('statSync', true, path, cred);
63
+ return options?.bigint ? BigIntStats.clone(stats) : stats;
63
64
  }
64
- /**
65
- * Synchronous `lstat`.
66
- * `lstat()` is identical to `stat()`, except that if path is a symbolic link,
67
- * then the link itself is stat-ed, not the file that it refers to.
68
- * @param path
69
- * @return [ZenFS.node.fs.Stats]
70
- */
71
- export function lstatSync(path) {
72
- return doOp('statSync', false, path, cred);
65
+ statSync;
66
+ export function lstatSync(path, options) {
67
+ const stats = doOp('statSync', false, path, cred);
68
+ return options?.bigint ? BigIntStats.clone(stats) : stats;
73
69
  }
70
+ lstatSync;
74
71
  /**
75
72
  * Synchronous `truncate`.
76
73
  * @param path
77
74
  * @param len
78
75
  */
79
76
  export function truncateSync(path, len = 0) {
80
- if (len < 0) {
81
- throw new ApiError(ErrorCode.EINVAL);
77
+ const fd = openSync(path, 'r+');
78
+ try {
79
+ ftruncateSync(fd, len);
80
+ }
81
+ finally {
82
+ closeSync(fd);
82
83
  }
83
- return doOp('truncateSync', true, path, len, cred);
84
84
  }
85
+ truncateSync;
85
86
  /**
86
87
  * Synchronous `unlink`.
87
88
  * @param path
@@ -89,48 +90,147 @@ export function truncateSync(path, len = 0) {
89
90
  export function unlinkSync(path) {
90
91
  return doOp('unlinkSync', false, path, cred);
91
92
  }
93
+ unlinkSync;
94
+ function _openSync(_path, _flag, _mode, resolveSymlinks) {
95
+ const path = normalizePath(_path), mode = normalizeMode(_mode, 0o644), flag = FileFlag.FromString(_flag);
96
+ // Check if the path exists, and is a file.
97
+ let stats;
98
+ try {
99
+ stats = doOp('statSync', resolveSymlinks, path, cred);
100
+ }
101
+ catch (e) {
102
+ // File does not exist.
103
+ switch (flag.pathNotExistsAction()) {
104
+ case ActionType.CREATE:
105
+ // Ensure parent exists.
106
+ const parentStats = doOp('statSync', resolveSymlinks, dirname(path), cred);
107
+ if (!parentStats.isDirectory()) {
108
+ throw ApiError.ENOTDIR(dirname(path));
109
+ }
110
+ return doOp('createFileSync', resolveSymlinks, path, flag, mode, cred);
111
+ case ActionType.THROW:
112
+ throw ApiError.ENOENT(path);
113
+ default:
114
+ throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');
115
+ }
116
+ }
117
+ if (!stats.hasAccess(mode, cred)) {
118
+ throw ApiError.EACCES(path);
119
+ }
120
+ // File exists.
121
+ switch (flag.pathExistsAction()) {
122
+ case ActionType.THROW:
123
+ throw ApiError.EEXIST(path);
124
+ case ActionType.TRUNCATE:
125
+ // Delete file.
126
+ doOp('unlinkSync', resolveSymlinks, path, cred);
127
+ /*
128
+ Create file. Use the same mode as the old file.
129
+ Node itself modifies the ctime when this occurs, so this action
130
+ will preserve that behavior if the underlying file system
131
+ supports those properties.
132
+ */
133
+ return doOp('createFileSync', resolveSymlinks, path, flag, stats.mode, cred);
134
+ case ActionType.NOP:
135
+ return doOp('openFileSync', resolveSymlinks, path, flag, cred);
136
+ default:
137
+ throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');
138
+ }
139
+ }
92
140
  /**
93
141
  * Synchronous file open.
94
142
  * @see http://www.manpagez.com/man/2/open/
95
- * @param path
96
- * @param flags
97
- * @param mode defaults to `0644`
98
- * @return [ZenFS.File]
143
+ * @param flags Handles the complexity of the various file
144
+ * modes. See its API for more details.
145
+ * @param mode Mode to use to open the file. Can be ignored if the
146
+ * filesystem doesn't support permissions.
147
+ */
148
+ export function openSync(path, flag, mode) {
149
+ return getFdForFile(_openSync(path, flag, mode, true));
150
+ }
151
+ openSync;
152
+ /**
153
+ * Opens a file or symlink
154
+ * @internal
99
155
  */
100
- export function openSync(path, flag, mode = 0o644) {
101
- const file = doOp('openSync', true, path, FileFlag.getFileFlag(flag), normalizeMode(mode, 0o644), cred);
102
- return getFdForFile(file);
156
+ export function lopenSync(path, flag, mode) {
157
+ return getFdForFile(_openSync(path, flag, mode, false));
158
+ }
159
+ /**
160
+ * Synchronously reads the entire contents of a file.
161
+ */
162
+ function _readFileSync(fname, flag, resolveSymlinks) {
163
+ // Get file.
164
+ const file = _openSync(fname, flag, 0o644, resolveSymlinks);
165
+ try {
166
+ const stat = file.statSync();
167
+ // Allocate buffer.
168
+ const data = new Uint8Array(stat.size);
169
+ file.readSync(data, 0, stat.size, 0);
170
+ file.closeSync();
171
+ return data;
172
+ }
173
+ finally {
174
+ file.closeSync();
175
+ }
103
176
  }
104
177
  export function readFileSync(filename, arg2 = {}) {
105
- const options = normalizeOptions(arg2, null, 'r', null);
106
- const flag = FileFlag.getFileFlag(options.flag);
178
+ const options = normalizeOptions(arg2, null, 'r', 0o644);
179
+ const flag = FileFlag.FromString(options.flag);
107
180
  if (!flag.isReadable()) {
108
181
  throw new ApiError(ErrorCode.EINVAL, 'Flag passed to readFile must allow for reading.');
109
182
  }
110
- const data = doOp('readFileSync', true, filename, flag, cred);
111
- switch (options.encoding) {
112
- case 'utf8':
113
- case 'utf-8':
114
- return decode(data);
115
- default:
116
- return data;
183
+ const data = _readFileSync(filename, options.flag, true);
184
+ return options.encoding ? decode(data, options.encoding) : data;
185
+ }
186
+ readFileSync;
187
+ /**
188
+ * Synchronously writes data to a file, replacing the file
189
+ * if it already exists.
190
+ *
191
+ * The encoding option is ignored if data is a buffer.
192
+ */
193
+ function _writeFileSync(fname, data, flag, mode, resolveSymlinks) {
194
+ const file = _openSync(fname, flag, mode, resolveSymlinks);
195
+ try {
196
+ file.writeSync(data, 0, data.length, 0);
197
+ }
198
+ finally {
199
+ file.closeSync();
117
200
  }
118
201
  }
119
- export function writeFileSync(filename, data, arg3) {
120
- const options = normalizeOptions(arg3, 'utf8', 'w', 0o644);
121
- const flag = FileFlag.getFileFlag(options.flag);
202
+ export function writeFileSync(filename, data, _options) {
203
+ const options = normalizeOptions(_options, 'utf8', 'w', 0o644);
204
+ const flag = FileFlag.FromString(options.flag);
122
205
  if (!flag.isWriteable()) {
123
206
  throw new ApiError(ErrorCode.EINVAL, 'Flag passed to writeFile must allow for writing.');
124
207
  }
125
208
  if (typeof data != 'string' && !options.encoding) {
126
209
  throw new ApiError(ErrorCode.EINVAL, 'Encoding not specified');
127
210
  }
128
- const encodedData = typeof data == 'string' ? encode(data) : data;
129
- return doOp('writeFileSync', true, filename, encodedData, flag, options.mode, cred);
211
+ const encodedData = typeof data == 'string' ? encode(data, options.encoding) : data;
212
+ if (encodedData === undefined) {
213
+ throw new ApiError(ErrorCode.EINVAL, 'Data not specified');
214
+ }
215
+ _writeFileSync(filename, encodedData, options.flag, options.mode, true);
216
+ }
217
+ writeFileSync;
218
+ /**
219
+ * Synchronously append data to a file, creating the file if
220
+ * it not yet exists.
221
+ */
222
+ function _appendFileSync(fname, data, flag, mode, resolveSymlinks) {
223
+ const file = _openSync(fname, flag, mode, resolveSymlinks);
224
+ try {
225
+ file.writeSync(data, 0, data.length, null);
226
+ }
227
+ finally {
228
+ file.closeSync();
229
+ }
130
230
  }
131
231
  export function appendFileSync(filename, data, arg3) {
132
232
  const options = normalizeOptions(arg3, 'utf8', 'a', 0o644);
133
- const flag = FileFlag.getFileFlag(options.flag);
233
+ const flag = FileFlag.FromString(options.flag);
134
234
  if (!flag.isAppendable()) {
135
235
  throw new ApiError(ErrorCode.EINVAL, 'Flag passed to appendFile must allow for appending.');
136
236
  }
@@ -138,18 +238,14 @@ export function appendFileSync(filename, data, arg3) {
138
238
  throw new ApiError(ErrorCode.EINVAL, 'Encoding not specified');
139
239
  }
140
240
  const encodedData = typeof data == 'string' ? encode(data) : data;
141
- return doOp('appendFileSync', true, filename, encodedData, flag, options.mode, cred);
241
+ _appendFileSync(filename, encodedData, options.flag, options.mode, true);
142
242
  }
143
- /**
144
- * Synchronous `fstat`.
145
- * `fstat()` is identical to `stat()`, except that the file to be stat-ed is
146
- * specified by the file descriptor `fd`.
147
- * @param fd
148
- * @return [ZenFS.node.fs.Stats]
149
- */
150
- export function fstatSync(fd) {
151
- return fd2file(fd).statSync();
243
+ appendFileSync;
244
+ export function fstatSync(fd, options) {
245
+ const stats = fd2file(fd).statSync();
246
+ return options?.bigint ? BigIntStats.clone(stats) : stats;
152
247
  }
248
+ fstatSync;
153
249
  /**
154
250
  * Synchronous close.
155
251
  * @param fd
@@ -158,18 +254,19 @@ export function closeSync(fd) {
158
254
  fd2file(fd).closeSync();
159
255
  fdMap.delete(fd);
160
256
  }
257
+ closeSync;
161
258
  /**
162
259
  * Synchronous ftruncate.
163
260
  * @param fd
164
261
  * @param len
165
262
  */
166
263
  export function ftruncateSync(fd, len = 0) {
167
- const file = fd2file(fd);
168
264
  if (len < 0) {
169
265
  throw new ApiError(ErrorCode.EINVAL);
170
266
  }
171
- file.truncateSync(len);
267
+ fd2file(fd).truncateSync(len);
172
268
  }
269
+ ftruncateSync;
173
270
  /**
174
271
  * Synchronous fsync.
175
272
  * @param fd
@@ -177,6 +274,7 @@ export function ftruncateSync(fd, len = 0) {
177
274
  export function fsyncSync(fd) {
178
275
  fd2file(fd).syncSync();
179
276
  }
277
+ fsyncSync;
180
278
  /**
181
279
  * Synchronous fdatasync.
182
280
  * @param fd
@@ -184,29 +282,31 @@ export function fsyncSync(fd) {
184
282
  export function fdatasyncSync(fd) {
185
283
  fd2file(fd).datasyncSync();
186
284
  }
187
- export function writeSync(fd, arg2, arg3, arg4, arg5) {
285
+ fdatasyncSync;
286
+ export function writeSync(fd, data, posOrOff, lenOrEnc, pos) {
188
287
  let buffer, offset = 0, length, position;
189
- if (typeof arg2 === 'string') {
288
+ if (typeof data === 'string') {
190
289
  // Signature 1: (fd, string, [position?, [encoding?]])
191
- position = typeof arg3 === 'number' ? arg3 : null;
192
- const encoding = (typeof arg4 === 'string' ? arg4 : 'utf8');
290
+ position = typeof posOrOff === 'number' ? posOrOff : null;
291
+ const encoding = (typeof lenOrEnc === 'string' ? lenOrEnc : 'utf8');
193
292
  offset = 0;
194
- buffer = encode(arg2);
293
+ buffer = encode(data, encoding);
195
294
  length = buffer.length;
196
295
  }
197
296
  else {
198
297
  // Signature 2: (fd, buffer, offset, length, position?)
199
- buffer = arg2;
200
- offset = arg3;
201
- length = arg4;
202
- position = typeof arg5 === 'number' ? arg5 : null;
298
+ buffer = data;
299
+ offset = posOrOff;
300
+ length = lenOrEnc;
301
+ position = typeof pos === 'number' ? pos : null;
203
302
  }
204
303
  const file = fd2file(fd);
205
304
  if (position === undefined || position === null) {
206
- position = file.getPos();
305
+ position = file.position;
207
306
  }
208
307
  return file.writeSync(buffer, offset, length, position);
209
308
  }
309
+ writeSync;
210
310
  export function readSync(fd, buffer, opts, length, position) {
211
311
  const file = fd2file(fd);
212
312
  let offset = opts;
@@ -214,10 +314,11 @@ export function readSync(fd, buffer, opts, length, position) {
214
314
  ({ offset, length, position } = opts);
215
315
  }
216
316
  if (isNaN(+position)) {
217
- position = file.getPos();
317
+ position = file.position;
218
318
  }
219
319
  return file.readSync(buffer, offset, length, position);
220
320
  }
321
+ readSync;
221
322
  /**
222
323
  * Synchronous `fchown`.
223
324
  * @param fd
@@ -227,15 +328,20 @@ export function readSync(fd, buffer, opts, length, position) {
227
328
  export function fchownSync(fd, uid, gid) {
228
329
  fd2file(fd).chownSync(uid, gid);
229
330
  }
331
+ fchownSync;
230
332
  /**
231
333
  * Synchronous `fchmod`.
232
334
  * @param fd
233
335
  * @param mode
234
336
  */
235
337
  export function fchmodSync(fd, mode) {
236
- const numMode = typeof mode === 'string' ? parseInt(mode, 8) : mode;
338
+ const numMode = normalizeMode(mode, -1);
339
+ if (numMode < 0) {
340
+ throw new ApiError(ErrorCode.EINVAL, `Invalid mode.`);
341
+ }
237
342
  fd2file(fd).chmodSync(numMode);
238
343
  }
344
+ fchmodSync;
239
345
  /**
240
346
  * Change the file timestamps of a file referenced by the supplied file
241
347
  * descriptor.
@@ -246,7 +352,7 @@ export function fchmodSync(fd, mode) {
246
352
  export function futimesSync(fd, atime, mtime) {
247
353
  fd2file(fd).utimesSync(normalizeTime(atime), normalizeTime(mtime));
248
354
  }
249
- // DIRECTORY-ONLY METHODS
355
+ futimesSync;
250
356
  /**
251
357
  * Synchronous `rmdir`.
252
358
  * @param path
@@ -254,66 +360,76 @@ export function futimesSync(fd, atime, mtime) {
254
360
  export function rmdirSync(path) {
255
361
  return doOp('rmdirSync', true, path, cred);
256
362
  }
257
- /**
258
- * Synchronous `mkdir`.
259
- * @param path
260
- * @param mode defaults to `0777`
261
- */
262
- export function mkdirSync(path, mode) {
363
+ rmdirSync;
364
+ export function mkdirSync(path, options) {
365
+ const mode = typeof options == 'number' || typeof options == 'string' ? options : options?.mode;
366
+ const recursive = typeof options == 'object' && options?.recursive;
263
367
  doOp('mkdirSync', true, path, normalizeMode(mode, 0o777), cred);
264
368
  }
265
- /**
266
- * Synchronous `readdir`. Reads the contents of a directory.
267
- * @param path
268
- * @return [String[]]
269
- */
270
- export function readdirSync(path) {
369
+ mkdirSync;
370
+ export function readdirSync(path, options) {
271
371
  path = normalizePath(path);
272
372
  const entries = doOp('readdirSync', true, path, cred);
273
- const points = [...mounts.keys()];
274
- for (const point of points) {
275
- if (point.startsWith(path)) {
276
- const entry = point.slice(path.length);
277
- if (entry.includes('/') || entry.length == 0) {
278
- // ignore FSs mounted in subdirectories and any FS mounted to `path`.
279
- continue;
280
- }
281
- entries.push(entry);
373
+ for (const mount of mounts.keys()) {
374
+ if (!mount.startsWith(path)) {
375
+ continue;
376
+ }
377
+ const entry = mount.slice(path.length);
378
+ if (entry.includes('/') || entry.length == 0) {
379
+ // ignore FSs mounted in subdirectories and any FS mounted to `path`.
380
+ continue;
282
381
  }
382
+ entries.push(entry);
283
383
  }
284
- return entries;
384
+ return entries.map((entry) => {
385
+ if (typeof options == 'object' && options?.withFileTypes) {
386
+ return new Dirent(entry, statSync(join(path, entry)));
387
+ }
388
+ if (options == 'buffer' || (typeof options == 'object' && options.encoding == 'buffer')) {
389
+ return encode(entry);
390
+ }
391
+ return entry;
392
+ });
285
393
  }
394
+ readdirSync;
286
395
  // SYMLINK METHODS
287
396
  /**
288
397
  * Synchronous `link`.
289
- * @param srcpath
290
- * @param dstpath
398
+ * @param existing
399
+ * @param newpath
291
400
  */
292
- export function linkSync(srcpath, dstpath) {
293
- dstpath = normalizePath(dstpath);
294
- return doOp('linkSync', false, srcpath, dstpath, cred);
401
+ export function linkSync(existing, newpath) {
402
+ newpath = normalizePath(newpath);
403
+ return doOp('linkSync', false, existing, newpath, cred);
295
404
  }
405
+ linkSync;
296
406
  /**
297
407
  * Synchronous `symlink`.
298
- * @param srcpath
299
- * @param dstpath
408
+ * @param target target path
409
+ * @param path link path
300
410
  * @param type can be either `'dir'` or `'file'` (default is `'file'`)
301
411
  */
302
- export function symlinkSync(srcpath, dstpath, type) {
412
+ export function symlinkSync(target, path, type = 'file') {
303
413
  if (!['file', 'dir', 'junction'].includes(type)) {
304
414
  throw new ApiError(ErrorCode.EINVAL, 'Invalid type: ' + type);
305
415
  }
306
- dstpath = normalizePath(dstpath);
307
- return doOp('symlinkSync', false, srcpath, dstpath, type, cred);
308
- }
309
- /**
310
- * Synchronous readlink.
311
- * @param path
312
- * @return [String]
313
- */
314
- export function readlinkSync(path) {
315
- return doOp('readlinkSync', false, path, cred);
416
+ if (existsSync(path)) {
417
+ throw ApiError.EEXIST(path);
418
+ }
419
+ writeFileSync(path, target);
420
+ const file = _openSync(path, 'r+', 0o644, false);
421
+ file._setTypeSync(FileType.SYMLINK);
422
+ }
423
+ symlinkSync;
424
+ export function readlinkSync(path, options) {
425
+ const value = _readFileSync(path, 'r', false);
426
+ const encoding = typeof options == 'object' ? options.encoding : options;
427
+ if (encoding == 'buffer') {
428
+ return value;
429
+ }
430
+ return decode(value, encoding);
316
431
  }
432
+ readlinkSync;
317
433
  // PROPERTY OPERATIONS
318
434
  /**
319
435
  * Synchronous `chown`.
@@ -322,8 +438,11 @@ export function readlinkSync(path) {
322
438
  * @param gid
323
439
  */
324
440
  export function chownSync(path, uid, gid) {
325
- doOp('chownSync', true, path, uid, gid, cred);
441
+ const fd = openSync(path, 'r+');
442
+ fchownSync(fd, uid, gid);
443
+ closeSync(fd);
326
444
  }
445
+ chownSync;
327
446
  /**
328
447
  * Synchronous `lchown`.
329
448
  * @param path
@@ -331,32 +450,33 @@ export function chownSync(path, uid, gid) {
331
450
  * @param gid
332
451
  */
333
452
  export function lchownSync(path, uid, gid) {
334
- doOp('chownSync', false, path, uid, gid, cred);
453
+ const fd = lopenSync(path, 'r+');
454
+ fchownSync(fd, uid, gid);
455
+ closeSync(fd);
335
456
  }
457
+ lchownSync;
336
458
  /**
337
459
  * Synchronous `chmod`.
338
460
  * @param path
339
461
  * @param mode
340
462
  */
341
463
  export function chmodSync(path, mode) {
342
- const numMode = normalizeMode(mode, -1);
343
- if (numMode < 0) {
344
- throw new ApiError(ErrorCode.EINVAL, `Invalid mode.`);
345
- }
346
- doOp('chmodSync', true, path, numMode, cred);
464
+ const fd = openSync(path, 'r+');
465
+ fchmodSync(fd, mode);
466
+ closeSync(fd);
347
467
  }
468
+ chmodSync;
348
469
  /**
349
470
  * Synchronous `lchmod`.
350
471
  * @param path
351
472
  * @param mode
352
473
  */
353
474
  export function lchmodSync(path, mode) {
354
- const numMode = normalizeMode(mode, -1);
355
- if (numMode < 1) {
356
- throw new ApiError(ErrorCode.EINVAL, `Invalid mode.`);
357
- }
358
- doOp('chmodSync', false, path, numMode, cred);
475
+ const fd = lopenSync(path, 'r+');
476
+ fchmodSync(fd, mode);
477
+ closeSync(fd);
359
478
  }
479
+ lchmodSync;
360
480
  /**
361
481
  * Change file timestamps of the file referenced by the supplied path.
362
482
  * @param path
@@ -364,8 +484,11 @@ export function lchmodSync(path, mode) {
364
484
  * @param mtime
365
485
  */
366
486
  export function utimesSync(path, atime, mtime) {
367
- doOp('utimesSync', true, path, normalizeTime(atime), normalizeTime(mtime), cred);
487
+ const fd = openSync(path, 'r+');
488
+ futimesSync(fd, atime, mtime);
489
+ closeSync(fd);
368
490
  }
491
+ utimesSync;
369
492
  /**
370
493
  * Change file timestamps of the file referenced by the supplied path.
371
494
  * @param path
@@ -373,17 +496,12 @@ export function utimesSync(path, atime, mtime) {
373
496
  * @param mtime
374
497
  */
375
498
  export function lutimesSync(path, atime, mtime) {
376
- doOp('utimesSync', false, path, normalizeTime(atime), normalizeTime(mtime), cred);
499
+ const fd = lopenSync(path, 'r+');
500
+ futimesSync(fd, atime, mtime);
501
+ closeSync(fd);
377
502
  }
378
- /**
379
- * Synchronous `realpath`.
380
- * @param path
381
- * @param cache An object literal of mapped paths that can be used to
382
- * force a specific path resolution or avoid additional `fs.stat` calls for
383
- * known real paths.
384
- * @return [String]
385
- */
386
- export function realpathSync(path, cache = {}) {
503
+ lutimesSync;
504
+ export function realpathSync(path, options) {
387
505
  path = normalizePath(path);
388
506
  const { fs, path: resolvedPath, mountPoint } = resolveFS(path);
389
507
  try {
@@ -391,18 +509,47 @@ export function realpathSync(path, cache = {}) {
391
509
  if (!stats.isSymbolicLink()) {
392
510
  return path;
393
511
  }
394
- const dst = normalizePath(mountPoint + fs.readlinkSync(resolvedPath, cred));
512
+ const dst = normalizePath(mountPoint + decode(_readFileSync(resolvedPath, 'r+', false)));
395
513
  return realpathSync(dst);
396
514
  }
397
515
  catch (e) {
398
516
  throw fixError(e, { [resolvedPath]: path });
399
517
  }
400
518
  }
519
+ realpathSync;
401
520
  /**
402
521
  * Synchronous `access`.
403
522
  * @param path
404
523
  * @param mode
405
524
  */
406
525
  export function accessSync(path, mode = 0o600) {
407
- return doOp('accessSync', true, path, mode, cred);
526
+ const stats = statSync(path);
527
+ if (!stats.hasAccess(mode, cred)) {
528
+ throw new ApiError(ErrorCode.EACCES);
529
+ }
530
+ }
531
+ accessSync;
532
+ export function rmSync(path) {
533
+ throw new ApiError(ErrorCode.ENOTSUP);
534
+ }
535
+ rmSync;
536
+ export function mkdtempSync(prefix, options) {
537
+ throw new ApiError(ErrorCode.ENOTSUP);
538
+ }
539
+ mkdtempSync;
540
+ export function copyFileSync(src, dest, flags) {
541
+ throw new ApiError(ErrorCode.ENOTSUP);
542
+ }
543
+ copyFileSync;
544
+ export function readvSync(fd, buffers, position) {
545
+ throw new ApiError(ErrorCode.ENOTSUP);
546
+ }
547
+ readvSync;
548
+ export function writevSync(fd, buffers, position) {
549
+ throw new ApiError(ErrorCode.ENOTSUP);
550
+ }
551
+ writevSync;
552
+ export function opendirSync(path, options) {
553
+ throw new ApiError(ErrorCode.ENOTSUP);
408
554
  }
555
+ opendirSync;