memfs 3.5.3 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/Dirent.js +26 -27
- package/lib/Stats.js +27 -31
- package/lib/encoding.js +2 -2
- package/lib/fsa/types.d.ts +82 -0
- package/lib/fsa/types.js +2 -0
- package/lib/index.d.ts +16 -2
- package/lib/index.js +28 -26
- package/lib/internal/buffer.js +5 -18
- package/lib/internal/errors.js +61 -91
- package/lib/node/FileHandle.d.ts +30 -0
- package/lib/node/FileHandle.js +50 -0
- package/lib/node/promises.d.ts +2 -0
- package/lib/node/promises.js +88 -0
- package/lib/node/types/callback.d.ts +83 -0
- package/lib/node/types/callback.js +2 -0
- package/lib/node/types/index.d.ts +7 -0
- package/lib/node/types/index.js +2 -0
- package/lib/node/types/misc.d.ts +112 -0
- package/lib/node/types/misc.js +2 -0
- package/lib/node/types/options.d.ts +72 -0
- package/lib/node/types/options.js +2 -0
- package/lib/node/types/promises.d.ts +31 -0
- package/lib/node/types/promises.js +2 -0
- package/lib/node/types/sync.d.ts +100 -0
- package/lib/node/types/sync.js +2 -0
- package/lib/node/util.d.ts +2 -0
- package/lib/node/util.js +13 -0
- package/lib/node.d.ts +2 -2
- package/lib/node.js +209 -289
- package/lib/process.js +5 -5
- package/lib/setImmediate.js +1 -1
- package/lib/setTimeoutUnref.js +1 -1
- package/lib/volume-localstorage.js +48 -85
- package/lib/volume.d.ts +13 -10
- package/lib/volume.js +789 -897
- package/package.json +1 -1
- package/lib/promises.d.ts +0 -78
- package/lib/promises.js +0 -158
package/lib/volume.js
CHANGED
|
@@ -1,54 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
if (typeof b !== "function" && b !== null)
|
|
11
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
-
extendStatics(d, b);
|
|
13
|
-
function __() { this.constructor = d; }
|
|
14
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
-
};
|
|
16
|
-
})();
|
|
17
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
18
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
19
|
-
if (ar || !(i in from)) {
|
|
20
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
21
|
-
ar[i] = from[i];
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
25
|
-
};
|
|
26
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
3
|
exports.FSWatcher = exports.StatWatcher = exports.Volume = exports.toUnixTimestamp = exports.bufferToEncoding = exports.dataToBuffer = exports.dataToStr = exports.pathToSteps = exports.filenameToSteps = exports.pathToFilename = exports.flagsToNumber = exports.FLAGS = void 0;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
4
|
+
const pathModule = require("path");
|
|
5
|
+
const node_1 = require("./node");
|
|
6
|
+
const Stats_1 = require("./Stats");
|
|
7
|
+
const Dirent_1 = require("./Dirent");
|
|
8
|
+
const buffer_1 = require("./internal/buffer");
|
|
9
|
+
const setImmediate_1 = require("./setImmediate");
|
|
10
|
+
const process_1 = require("./process");
|
|
11
|
+
const setTimeoutUnref_1 = require("./setTimeoutUnref");
|
|
12
|
+
const stream_1 = require("stream");
|
|
13
|
+
const constants_1 = require("./constants");
|
|
14
|
+
const events_1 = require("events");
|
|
15
|
+
const encoding_1 = require("./encoding");
|
|
16
|
+
const errors = require("./internal/errors");
|
|
17
|
+
const util = require("util");
|
|
18
|
+
const promises_1 = require("./node/promises");
|
|
19
|
+
const resolveCrossPlatform = pathModule.resolve;
|
|
20
|
+
const { O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_EXCL, O_TRUNC, O_APPEND, O_SYNC, O_DIRECTORY, F_OK, COPYFILE_EXCL, COPYFILE_FICLONE_FORCE, } = constants_1.constants;
|
|
21
|
+
const { sep, relative, join, dirname } = pathModule.posix ? pathModule.posix : pathModule;
|
|
22
|
+
const isWin = process_1.default.platform === 'win32';
|
|
23
|
+
const kMinPoolSpace = 128;
|
|
48
24
|
// const kMaxLength = require('buffer').kMaxLength;
|
|
49
25
|
// ---------------------------------------- Error messages
|
|
50
26
|
// TODO: Use `internal/errors.js` in the future.
|
|
51
|
-
|
|
27
|
+
const ERRSTR = {
|
|
52
28
|
PATH_STR: 'path must be a string or Buffer',
|
|
53
29
|
// FD: 'file descriptor must be a unsigned 32-bit integer',
|
|
54
30
|
FD: 'fd must be a file descriptor',
|
|
@@ -65,67 +41,60 @@ var ERRSTR = {
|
|
|
65
41
|
LENGTH: 'length must be an integer',
|
|
66
42
|
POSITION: 'position must be an integer',
|
|
67
43
|
};
|
|
68
|
-
|
|
44
|
+
const ERRSTR_OPTS = tipeof => `Expected options to be either an object or a string, but got ${tipeof} instead`;
|
|
69
45
|
// const ERRSTR_FLAG = flag => `Unknown file open flag: ${flag}`;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
function formatError(errorCode, func, path, path2) {
|
|
84
|
-
|
|
85
|
-
if (path === void 0) { path = ''; }
|
|
86
|
-
if (path2 === void 0) { path2 = ''; }
|
|
87
|
-
var pathFormatted = '';
|
|
46
|
+
const ENOENT = 'ENOENT';
|
|
47
|
+
const EBADF = 'EBADF';
|
|
48
|
+
const EINVAL = 'EINVAL';
|
|
49
|
+
const EPERM = 'EPERM';
|
|
50
|
+
const EPROTO = 'EPROTO';
|
|
51
|
+
const EEXIST = 'EEXIST';
|
|
52
|
+
const ENOTDIR = 'ENOTDIR';
|
|
53
|
+
const EMFILE = 'EMFILE';
|
|
54
|
+
const EACCES = 'EACCES';
|
|
55
|
+
const EISDIR = 'EISDIR';
|
|
56
|
+
const ENOTEMPTY = 'ENOTEMPTY';
|
|
57
|
+
const ENOSYS = 'ENOSYS';
|
|
58
|
+
const ERR_FS_EISDIR = 'ERR_FS_EISDIR';
|
|
59
|
+
function formatError(errorCode, func = '', path = '', path2 = '') {
|
|
60
|
+
let pathFormatted = '';
|
|
88
61
|
if (path)
|
|
89
|
-
pathFormatted =
|
|
62
|
+
pathFormatted = ` '${path}'`;
|
|
90
63
|
if (path2)
|
|
91
|
-
pathFormatted +=
|
|
64
|
+
pathFormatted += ` -> '${path2}'`;
|
|
92
65
|
switch (errorCode) {
|
|
93
66
|
case ENOENT:
|
|
94
|
-
return
|
|
67
|
+
return `ENOENT: no such file or directory, ${func}${pathFormatted}`;
|
|
95
68
|
case EBADF:
|
|
96
|
-
return
|
|
69
|
+
return `EBADF: bad file descriptor, ${func}${pathFormatted}`;
|
|
97
70
|
case EINVAL:
|
|
98
|
-
return
|
|
71
|
+
return `EINVAL: invalid argument, ${func}${pathFormatted}`;
|
|
99
72
|
case EPERM:
|
|
100
|
-
return
|
|
73
|
+
return `EPERM: operation not permitted, ${func}${pathFormatted}`;
|
|
101
74
|
case EPROTO:
|
|
102
|
-
return
|
|
75
|
+
return `EPROTO: protocol error, ${func}${pathFormatted}`;
|
|
103
76
|
case EEXIST:
|
|
104
|
-
return
|
|
77
|
+
return `EEXIST: file already exists, ${func}${pathFormatted}`;
|
|
105
78
|
case ENOTDIR:
|
|
106
|
-
return
|
|
79
|
+
return `ENOTDIR: not a directory, ${func}${pathFormatted}`;
|
|
107
80
|
case EISDIR:
|
|
108
|
-
return
|
|
81
|
+
return `EISDIR: illegal operation on a directory, ${func}${pathFormatted}`;
|
|
109
82
|
case EACCES:
|
|
110
|
-
return
|
|
83
|
+
return `EACCES: permission denied, ${func}${pathFormatted}`;
|
|
111
84
|
case ENOTEMPTY:
|
|
112
|
-
return
|
|
85
|
+
return `ENOTEMPTY: directory not empty, ${func}${pathFormatted}`;
|
|
113
86
|
case EMFILE:
|
|
114
|
-
return
|
|
87
|
+
return `EMFILE: too many open files, ${func}${pathFormatted}`;
|
|
115
88
|
case ENOSYS:
|
|
116
|
-
return
|
|
89
|
+
return `ENOSYS: function not implemented, ${func}${pathFormatted}`;
|
|
117
90
|
case ERR_FS_EISDIR:
|
|
118
|
-
return
|
|
91
|
+
return `[ERR_FS_EISDIR]: Path is a directory: ${func} returned EISDIR (is a directory) ${path}`;
|
|
119
92
|
default:
|
|
120
|
-
return
|
|
93
|
+
return `${errorCode}: error occurred, ${func}${pathFormatted}`;
|
|
121
94
|
}
|
|
122
95
|
}
|
|
123
|
-
function createError(errorCode, func, path, path2, Constructor) {
|
|
124
|
-
|
|
125
|
-
if (path === void 0) { path = ''; }
|
|
126
|
-
if (path2 === void 0) { path2 = ''; }
|
|
127
|
-
if (Constructor === void 0) { Constructor = Error; }
|
|
128
|
-
var error = new Constructor(formatError(errorCode, func, path, path2));
|
|
96
|
+
function createError(errorCode, func = '', path = '', path2 = '', Constructor = Error) {
|
|
97
|
+
const error = new Constructor(formatError(errorCode, func, path, path2));
|
|
129
98
|
error.code = errorCode;
|
|
130
99
|
if (path) {
|
|
131
100
|
error.path = path;
|
|
@@ -171,7 +140,7 @@ function flagsToNumber(flags) {
|
|
|
171
140
|
if (typeof flags === 'number')
|
|
172
141
|
return flags;
|
|
173
142
|
if (typeof flags === 'string') {
|
|
174
|
-
|
|
143
|
+
const flagsNum = FLAGS[flags];
|
|
175
144
|
if (typeof flagsNum !== 'undefined')
|
|
176
145
|
return flagsNum;
|
|
177
146
|
}
|
|
@@ -181,11 +150,11 @@ function flagsToNumber(flags) {
|
|
|
181
150
|
exports.flagsToNumber = flagsToNumber;
|
|
182
151
|
// ---------------------------------------- Options
|
|
183
152
|
function getOptions(defaults, options) {
|
|
184
|
-
|
|
153
|
+
let opts;
|
|
185
154
|
if (!options)
|
|
186
155
|
return defaults;
|
|
187
156
|
else {
|
|
188
|
-
|
|
157
|
+
const tipeof = typeof options;
|
|
189
158
|
switch (tipeof) {
|
|
190
159
|
case 'string':
|
|
191
160
|
opts = Object.assign({}, defaults, { encoding: options });
|
|
@@ -202,7 +171,7 @@ function getOptions(defaults, options) {
|
|
|
202
171
|
return opts;
|
|
203
172
|
}
|
|
204
173
|
function optsGenerator(defaults) {
|
|
205
|
-
return
|
|
174
|
+
return options => getOptions(defaults, options);
|
|
206
175
|
}
|
|
207
176
|
function validateCallback(callback) {
|
|
208
177
|
if (typeof callback !== 'function')
|
|
@@ -210,77 +179,70 @@ function validateCallback(callback) {
|
|
|
210
179
|
return callback;
|
|
211
180
|
}
|
|
212
181
|
function optsAndCbGenerator(getOpts) {
|
|
213
|
-
return function (options, callback)
|
|
214
|
-
return typeof options === 'function' ? [getOpts(), options] : [getOpts(options), validateCallback(callback)];
|
|
215
|
-
};
|
|
182
|
+
return (options, callback) => typeof options === 'function' ? [getOpts(), options] : [getOpts(options), validateCallback(callback)];
|
|
216
183
|
}
|
|
217
|
-
|
|
184
|
+
const optsDefaults = {
|
|
218
185
|
encoding: 'utf8',
|
|
219
186
|
};
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
187
|
+
const getDefaultOpts = optsGenerator(optsDefaults);
|
|
188
|
+
const getDefaultOptsAndCb = optsAndCbGenerator(getDefaultOpts);
|
|
189
|
+
const readFileOptsDefaults = {
|
|
223
190
|
flag: 'r',
|
|
224
191
|
};
|
|
225
|
-
|
|
226
|
-
|
|
192
|
+
const getReadFileOptions = optsGenerator(readFileOptsDefaults);
|
|
193
|
+
const writeFileDefaults = {
|
|
227
194
|
encoding: 'utf8',
|
|
228
195
|
mode: 438 /* MODE.DEFAULT */,
|
|
229
196
|
flag: FLAGS[FLAGS.w],
|
|
230
197
|
};
|
|
231
|
-
|
|
232
|
-
|
|
198
|
+
const getWriteFileOptions = optsGenerator(writeFileDefaults);
|
|
199
|
+
const appendFileDefaults = {
|
|
233
200
|
encoding: 'utf8',
|
|
234
201
|
mode: 438 /* MODE.DEFAULT */,
|
|
235
202
|
flag: FLAGS[FLAGS.a],
|
|
236
203
|
};
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
204
|
+
const getAppendFileOpts = optsGenerator(appendFileDefaults);
|
|
205
|
+
const getAppendFileOptsAndCb = optsAndCbGenerator(getAppendFileOpts);
|
|
206
|
+
const realpathDefaults = optsDefaults;
|
|
207
|
+
const getRealpathOptions = optsGenerator(realpathDefaults);
|
|
208
|
+
const getRealpathOptsAndCb = optsAndCbGenerator(getRealpathOptions);
|
|
209
|
+
const mkdirDefaults = {
|
|
243
210
|
mode: 511 /* MODE.DIR */,
|
|
244
211
|
recursive: false,
|
|
245
212
|
};
|
|
246
|
-
|
|
213
|
+
const getMkdirOptions = (options) => {
|
|
247
214
|
if (typeof options === 'number')
|
|
248
215
|
return Object.assign({}, mkdirDefaults, { mode: options });
|
|
249
216
|
return Object.assign({}, mkdirDefaults, options);
|
|
250
217
|
};
|
|
251
|
-
|
|
218
|
+
const rmdirDefaults = {
|
|
252
219
|
recursive: false,
|
|
253
220
|
};
|
|
254
|
-
|
|
221
|
+
const getRmdirOptions = (options) => {
|
|
255
222
|
return Object.assign({}, rmdirDefaults, options);
|
|
256
223
|
};
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
224
|
+
const getRmOpts = optsGenerator(optsDefaults);
|
|
225
|
+
const getRmOptsAndCb = optsAndCbGenerator(getRmOpts);
|
|
226
|
+
const readdirDefaults = {
|
|
260
227
|
encoding: 'utf8',
|
|
261
228
|
withFileTypes: false,
|
|
262
229
|
};
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
230
|
+
const getReaddirOptions = optsGenerator(readdirDefaults);
|
|
231
|
+
const getReaddirOptsAndCb = optsAndCbGenerator(getReaddirOptions);
|
|
232
|
+
const statDefaults = {
|
|
266
233
|
bigint: false,
|
|
267
234
|
};
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
return Object.assign({}, statDefaults, options);
|
|
271
|
-
};
|
|
272
|
-
var getStatOptsAndCb = function (options, callback) {
|
|
273
|
-
return typeof options === 'function' ? [getStatOptions(), options] : [getStatOptions(options), validateCallback(callback)];
|
|
274
|
-
};
|
|
235
|
+
const getStatOptions = (options = {}) => Object.assign({}, statDefaults, options);
|
|
236
|
+
const getStatOptsAndCb = (options, callback) => typeof options === 'function' ? [getStatOptions(), options] : [getStatOptions(options), validateCallback(callback)];
|
|
275
237
|
// ---------------------------------------- Utility functions
|
|
276
238
|
function getPathFromURLPosix(url) {
|
|
277
239
|
if (url.hostname !== '') {
|
|
278
240
|
throw new errors.TypeError('ERR_INVALID_FILE_URL_HOST', process_1.default.platform);
|
|
279
241
|
}
|
|
280
|
-
|
|
281
|
-
for (
|
|
242
|
+
const pathname = url.pathname;
|
|
243
|
+
for (let n = 0; n < pathname.length; n++) {
|
|
282
244
|
if (pathname[n] === '%') {
|
|
283
|
-
|
|
245
|
+
const third = pathname.codePointAt(n + 2) | 0x20;
|
|
284
246
|
if (pathname[n + 1] === '2' && third === 102) {
|
|
285
247
|
throw new errors.TypeError('ERR_INVALID_FILE_URL_PATH', 'must not include encoded / characters');
|
|
286
248
|
}
|
|
@@ -299,24 +261,21 @@ function pathToFilename(path) {
|
|
|
299
261
|
}
|
|
300
262
|
path = getPathFromURLPosix(path);
|
|
301
263
|
}
|
|
302
|
-
|
|
264
|
+
const pathString = String(path);
|
|
303
265
|
nullCheck(pathString);
|
|
304
266
|
// return slash(pathString);
|
|
305
267
|
return pathString;
|
|
306
268
|
}
|
|
307
269
|
exports.pathToFilename = pathToFilename;
|
|
308
|
-
|
|
309
|
-
if (base === void 0) { base = process_1.default.cwd(); }
|
|
310
|
-
return resolveCrossPlatform(base, filename);
|
|
311
|
-
};
|
|
270
|
+
let resolve = (filename, base = process_1.default.cwd()) => resolveCrossPlatform(base, filename);
|
|
312
271
|
if (isWin) {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
resolve =
|
|
272
|
+
const _resolve = resolve;
|
|
273
|
+
const { unixify } = require('fs-monkey/lib/correctPath');
|
|
274
|
+
resolve = (filename, base) => unixify(_resolve(filename, base));
|
|
316
275
|
}
|
|
317
276
|
function filenameToSteps(filename, base) {
|
|
318
|
-
|
|
319
|
-
|
|
277
|
+
const fullPath = resolve(filename, base);
|
|
278
|
+
const fullPathSansSlash = fullPath.substring(1);
|
|
320
279
|
if (!fullPathSansSlash)
|
|
321
280
|
return [];
|
|
322
281
|
return fullPathSansSlash.split(sep);
|
|
@@ -326,8 +285,7 @@ function pathToSteps(path) {
|
|
|
326
285
|
return filenameToSteps(pathToFilename(path));
|
|
327
286
|
}
|
|
328
287
|
exports.pathToSteps = pathToSteps;
|
|
329
|
-
function dataToStr(data, encoding) {
|
|
330
|
-
if (encoding === void 0) { encoding = encoding_1.ENCODING_UTF8; }
|
|
288
|
+
function dataToStr(data, encoding = encoding_1.ENCODING_UTF8) {
|
|
331
289
|
if (buffer_1.Buffer.isBuffer(data))
|
|
332
290
|
return data.toString(encoding);
|
|
333
291
|
else if (data instanceof Uint8Array)
|
|
@@ -336,8 +294,7 @@ function dataToStr(data, encoding) {
|
|
|
336
294
|
return String(data);
|
|
337
295
|
}
|
|
338
296
|
exports.dataToStr = dataToStr;
|
|
339
|
-
function dataToBuffer(data, encoding) {
|
|
340
|
-
if (encoding === void 0) { encoding = encoding_1.ENCODING_UTF8; }
|
|
297
|
+
function dataToBuffer(data, encoding = encoding_1.ENCODING_UTF8) {
|
|
341
298
|
if (buffer_1.Buffer.isBuffer(data))
|
|
342
299
|
return data;
|
|
343
300
|
else if (data instanceof Uint8Array)
|
|
@@ -355,7 +312,7 @@ function bufferToEncoding(buffer, encoding) {
|
|
|
355
312
|
exports.bufferToEncoding = bufferToEncoding;
|
|
356
313
|
function nullCheck(path, callback) {
|
|
357
314
|
if (('' + path).indexOf('\u0000') !== -1) {
|
|
358
|
-
|
|
315
|
+
const er = new Error('Path must be a string without null bytes');
|
|
359
316
|
er.code = ENOENT;
|
|
360
317
|
if (typeof callback !== 'function')
|
|
361
318
|
throw er;
|
|
@@ -374,7 +331,7 @@ function _modeToNumber(mode, def) {
|
|
|
374
331
|
return undefined;
|
|
375
332
|
}
|
|
376
333
|
function modeToNumber(mode, def) {
|
|
377
|
-
|
|
334
|
+
const result = _modeToNumber(mode, def);
|
|
378
335
|
if (typeof result !== 'number' || isNaN(result))
|
|
379
336
|
throw new TypeError(ERRSTR.MODE_INT);
|
|
380
337
|
return result;
|
|
@@ -413,11 +370,11 @@ function validateGid(gid) {
|
|
|
413
370
|
throw TypeError(ERRSTR.GID);
|
|
414
371
|
}
|
|
415
372
|
function flattenJSON(nestedJSON) {
|
|
416
|
-
|
|
373
|
+
const flatJSON = {};
|
|
417
374
|
function flatten(pathPrefix, node) {
|
|
418
|
-
for (
|
|
419
|
-
|
|
420
|
-
|
|
375
|
+
for (const path in node) {
|
|
376
|
+
const contentOrNode = node[path];
|
|
377
|
+
const joinedPath = join(pathPrefix, path);
|
|
421
378
|
if (typeof contentOrNode === 'string') {
|
|
422
379
|
flatJSON[joinedPath] = contentOrNode;
|
|
423
380
|
}
|
|
@@ -438,9 +395,23 @@ function flattenJSON(nestedJSON) {
|
|
|
438
395
|
/**
|
|
439
396
|
* `Volume` represents a file system.
|
|
440
397
|
*/
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
398
|
+
class Volume {
|
|
399
|
+
static fromJSON(json, cwd) {
|
|
400
|
+
const vol = new Volume();
|
|
401
|
+
vol.fromJSON(json, cwd);
|
|
402
|
+
return vol;
|
|
403
|
+
}
|
|
404
|
+
static fromNestedJSON(json, cwd) {
|
|
405
|
+
const vol = new Volume();
|
|
406
|
+
vol.fromNestedJSON(json, cwd);
|
|
407
|
+
return vol;
|
|
408
|
+
}
|
|
409
|
+
get promises() {
|
|
410
|
+
if (this.promisesApi === null)
|
|
411
|
+
throw new Error('Promise is not supported in this environment.');
|
|
412
|
+
return this.promisesApi;
|
|
413
|
+
}
|
|
414
|
+
constructor(props = {}) {
|
|
444
415
|
// I-node number counter.
|
|
445
416
|
this.ino = 0;
|
|
446
417
|
// A mapping for i-node numbers to i-nodes (`Node`);
|
|
@@ -456,77 +427,41 @@ var Volume = /** @class */ (function () {
|
|
|
456
427
|
this.maxFiles = 10000;
|
|
457
428
|
// Current number of open files.
|
|
458
429
|
this.openFiles = 0;
|
|
459
|
-
this.promisesApi = (0, promises_1.
|
|
430
|
+
this.promisesApi = (0, promises_1.createPromisesApi)(this);
|
|
460
431
|
this.statWatchers = {};
|
|
461
432
|
this.props = Object.assign({ Node: node_1.Node, Link: node_1.Link, File: node_1.File }, props);
|
|
462
|
-
|
|
433
|
+
const root = this.createLink();
|
|
463
434
|
root.setNode(this.createNode(true));
|
|
464
|
-
|
|
465
|
-
this.StatWatcher =
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
return _super.call(this, self) || this;
|
|
435
|
+
const self = this; // tslint:disable-line no-this-assignment
|
|
436
|
+
this.StatWatcher = class extends StatWatcher {
|
|
437
|
+
constructor() {
|
|
438
|
+
super(self);
|
|
469
439
|
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
function class_1() {
|
|
476
|
-
var args = [];
|
|
477
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
478
|
-
args[_i] = arguments[_i];
|
|
479
|
-
}
|
|
480
|
-
return _super.apply(this, __spreadArray([self], args, false)) || this;
|
|
440
|
+
};
|
|
441
|
+
const _ReadStream = FsReadStream;
|
|
442
|
+
this.ReadStream = class extends _ReadStream {
|
|
443
|
+
constructor(...args) {
|
|
444
|
+
super(self, ...args);
|
|
481
445
|
}
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
function class_2() {
|
|
488
|
-
var args = [];
|
|
489
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
490
|
-
args[_i] = arguments[_i];
|
|
491
|
-
}
|
|
492
|
-
return _super.apply(this, __spreadArray([self], args, false)) || this;
|
|
446
|
+
};
|
|
447
|
+
const _WriteStream = FsWriteStream;
|
|
448
|
+
this.WriteStream = class extends _WriteStream {
|
|
449
|
+
constructor(...args) {
|
|
450
|
+
super(self, ...args);
|
|
493
451
|
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
function FSWatcher() {
|
|
499
|
-
return _super.call(this, self) || this;
|
|
452
|
+
};
|
|
453
|
+
this.FSWatcher = class extends FSWatcher {
|
|
454
|
+
constructor() {
|
|
455
|
+
super(self);
|
|
500
456
|
}
|
|
501
|
-
|
|
502
|
-
}(FSWatcher));
|
|
457
|
+
};
|
|
503
458
|
root.setChild('.', root);
|
|
504
459
|
root.getNode().nlink++;
|
|
505
460
|
root.setChild('..', root);
|
|
506
461
|
root.getNode().nlink++;
|
|
507
462
|
this.root = root;
|
|
508
463
|
}
|
|
509
|
-
|
|
510
|
-
var vol = new Volume();
|
|
511
|
-
vol.fromJSON(json, cwd);
|
|
512
|
-
return vol;
|
|
513
|
-
};
|
|
514
|
-
Volume.fromNestedJSON = function (json, cwd) {
|
|
515
|
-
var vol = new Volume();
|
|
516
|
-
vol.fromNestedJSON(json, cwd);
|
|
517
|
-
return vol;
|
|
518
|
-
};
|
|
519
|
-
Object.defineProperty(Volume.prototype, "promises", {
|
|
520
|
-
get: function () {
|
|
521
|
-
if (this.promisesApi === null)
|
|
522
|
-
throw new Error('Promise is not supported in this environment.');
|
|
523
|
-
return this.promisesApi;
|
|
524
|
-
},
|
|
525
|
-
enumerable: false,
|
|
526
|
-
configurable: true
|
|
527
|
-
});
|
|
528
|
-
Volume.prototype.createLink = function (parent, name, isDirectory, perm) {
|
|
529
|
-
if (isDirectory === void 0) { isDirectory = false; }
|
|
464
|
+
createLink(parent, name, isDirectory = false, perm) {
|
|
530
465
|
if (!parent) {
|
|
531
466
|
return new this.props.Link(this, null, '');
|
|
532
467
|
}
|
|
@@ -534,75 +469,74 @@ var Volume = /** @class */ (function () {
|
|
|
534
469
|
throw new Error('createLink: name cannot be empty');
|
|
535
470
|
}
|
|
536
471
|
return parent.createChild(name, this.createNode(isDirectory, perm));
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
|
|
472
|
+
}
|
|
473
|
+
deleteLink(link) {
|
|
474
|
+
const parent = link.parent;
|
|
540
475
|
if (parent) {
|
|
541
476
|
parent.deleteChild(link);
|
|
542
477
|
return true;
|
|
543
478
|
}
|
|
544
479
|
return false;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
|
|
480
|
+
}
|
|
481
|
+
newInoNumber() {
|
|
482
|
+
const releasedFd = this.releasedInos.pop();
|
|
548
483
|
if (releasedFd)
|
|
549
484
|
return releasedFd;
|
|
550
485
|
else {
|
|
551
486
|
this.ino = (this.ino + 1) % 0xffffffff;
|
|
552
487
|
return this.ino;
|
|
553
488
|
}
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
|
|
489
|
+
}
|
|
490
|
+
newFdNumber() {
|
|
491
|
+
const releasedFd = this.releasedFds.pop();
|
|
557
492
|
return typeof releasedFd === 'number' ? releasedFd : Volume.fd--;
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
var node = new this.props.Node(this.newInoNumber(), perm);
|
|
493
|
+
}
|
|
494
|
+
createNode(isDirectory = false, perm) {
|
|
495
|
+
const node = new this.props.Node(this.newInoNumber(), perm);
|
|
562
496
|
if (isDirectory)
|
|
563
497
|
node.setIsDirectory();
|
|
564
498
|
this.inodes[node.ino] = node;
|
|
565
499
|
return node;
|
|
566
|
-
}
|
|
567
|
-
|
|
500
|
+
}
|
|
501
|
+
getNode(ino) {
|
|
568
502
|
return this.inodes[ino];
|
|
569
|
-
}
|
|
570
|
-
|
|
503
|
+
}
|
|
504
|
+
deleteNode(node) {
|
|
571
505
|
node.del();
|
|
572
506
|
delete this.inodes[node.ino];
|
|
573
507
|
this.releasedInos.push(node.ino);
|
|
574
|
-
}
|
|
508
|
+
}
|
|
575
509
|
// Generates 6 character long random string, used by `mkdtemp`.
|
|
576
|
-
|
|
577
|
-
|
|
510
|
+
genRndStr() {
|
|
511
|
+
const str = (Math.random() + 1).toString(36).substring(2, 8);
|
|
578
512
|
if (str.length === 6)
|
|
579
513
|
return str;
|
|
580
514
|
else
|
|
581
515
|
return this.genRndStr();
|
|
582
|
-
}
|
|
516
|
+
}
|
|
583
517
|
// Returns a `Link` (hard link) referenced by path "split" into steps.
|
|
584
|
-
|
|
518
|
+
getLink(steps) {
|
|
585
519
|
return this.root.walk(steps);
|
|
586
|
-
}
|
|
520
|
+
}
|
|
587
521
|
// Just link `getLink`, but throws a correct user error, if link to found.
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
522
|
+
getLinkOrThrow(filename, funcName) {
|
|
523
|
+
const steps = filenameToSteps(filename);
|
|
524
|
+
const link = this.getLink(steps);
|
|
591
525
|
if (!link)
|
|
592
526
|
throw createError(ENOENT, funcName, filename);
|
|
593
527
|
return link;
|
|
594
|
-
}
|
|
528
|
+
}
|
|
595
529
|
// Just like `getLink`, but also dereference/resolves symbolic links.
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
530
|
+
getResolvedLink(filenameOrSteps) {
|
|
531
|
+
let steps = typeof filenameOrSteps === 'string' ? filenameToSteps(filenameOrSteps) : filenameOrSteps;
|
|
532
|
+
let link = this.root;
|
|
533
|
+
let i = 0;
|
|
600
534
|
while (i < steps.length) {
|
|
601
|
-
|
|
535
|
+
const step = steps[i];
|
|
602
536
|
link = link.getChild(step);
|
|
603
537
|
if (!link)
|
|
604
538
|
return null;
|
|
605
|
-
|
|
539
|
+
const node = link.getNode();
|
|
606
540
|
if (node.isSymlink()) {
|
|
607
541
|
steps = node.symlink.concat(steps.slice(i + 1));
|
|
608
542
|
link = this.root;
|
|
@@ -612,15 +546,15 @@ var Volume = /** @class */ (function () {
|
|
|
612
546
|
i++;
|
|
613
547
|
}
|
|
614
548
|
return link;
|
|
615
|
-
}
|
|
549
|
+
}
|
|
616
550
|
// Just like `getLinkOrThrow`, but also dereference/resolves symbolic links.
|
|
617
|
-
|
|
618
|
-
|
|
551
|
+
getResolvedLinkOrThrow(filename, funcName) {
|
|
552
|
+
const link = this.getResolvedLink(filename);
|
|
619
553
|
if (!link)
|
|
620
554
|
throw createError(ENOENT, funcName, filename);
|
|
621
555
|
return link;
|
|
622
|
-
}
|
|
623
|
-
|
|
556
|
+
}
|
|
557
|
+
resolveSymlinks(link) {
|
|
624
558
|
// let node: Node = link.getNode();
|
|
625
559
|
// while(link && node.isSymlink()) {
|
|
626
560
|
// link = this.getLink(node.symlink);
|
|
@@ -629,38 +563,38 @@ var Volume = /** @class */ (function () {
|
|
|
629
563
|
// }
|
|
630
564
|
// return link;
|
|
631
565
|
return this.getResolvedLink(link.steps.slice(1));
|
|
632
|
-
}
|
|
566
|
+
}
|
|
633
567
|
// Just like `getLinkOrThrow`, but also verifies that the link is a directory.
|
|
634
|
-
|
|
635
|
-
|
|
568
|
+
getLinkAsDirOrThrow(filename, funcName) {
|
|
569
|
+
const link = this.getLinkOrThrow(filename, funcName);
|
|
636
570
|
if (!link.getNode().isDirectory())
|
|
637
571
|
throw createError(ENOTDIR, funcName, filename);
|
|
638
572
|
return link;
|
|
639
|
-
}
|
|
573
|
+
}
|
|
640
574
|
// Get the immediate parent directory of the link.
|
|
641
|
-
|
|
575
|
+
getLinkParent(steps) {
|
|
642
576
|
return this.root.walk(steps, steps.length - 1);
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
577
|
+
}
|
|
578
|
+
getLinkParentAsDirOrThrow(filenameOrSteps, funcName) {
|
|
579
|
+
const steps = filenameOrSteps instanceof Array ? filenameOrSteps : filenameToSteps(filenameOrSteps);
|
|
580
|
+
const link = this.getLinkParent(steps);
|
|
647
581
|
if (!link)
|
|
648
582
|
throw createError(ENOENT, funcName, sep + steps.join(sep));
|
|
649
583
|
if (!link.getNode().isDirectory())
|
|
650
584
|
throw createError(ENOTDIR, funcName, sep + steps.join(sep));
|
|
651
585
|
return link;
|
|
652
|
-
}
|
|
653
|
-
|
|
586
|
+
}
|
|
587
|
+
getFileByFd(fd) {
|
|
654
588
|
return this.fds[String(fd)];
|
|
655
|
-
}
|
|
656
|
-
|
|
589
|
+
}
|
|
590
|
+
getFileByFdOrThrow(fd, funcName) {
|
|
657
591
|
if (!isFd(fd))
|
|
658
592
|
throw TypeError(ERRSTR.FD);
|
|
659
|
-
|
|
593
|
+
const file = this.getFileByFd(fd);
|
|
660
594
|
if (!file)
|
|
661
595
|
throw createError(EBADF, funcName);
|
|
662
596
|
return file;
|
|
663
|
-
}
|
|
597
|
+
}
|
|
664
598
|
/**
|
|
665
599
|
* @todo This is not used anymore. Remove.
|
|
666
600
|
*/
|
|
@@ -689,13 +623,12 @@ var Volume = /** @class */ (function () {
|
|
|
689
623
|
}
|
|
690
624
|
}
|
|
691
625
|
*/
|
|
692
|
-
|
|
693
|
-
var _this = this;
|
|
626
|
+
wrapAsync(method, args, callback) {
|
|
694
627
|
validateCallback(callback);
|
|
695
|
-
(0, setImmediate_1.default)(
|
|
696
|
-
|
|
628
|
+
(0, setImmediate_1.default)(() => {
|
|
629
|
+
let result;
|
|
697
630
|
try {
|
|
698
|
-
result = method.apply(
|
|
631
|
+
result = method.apply(this, args);
|
|
699
632
|
}
|
|
700
633
|
catch (err) {
|
|
701
634
|
callback(err);
|
|
@@ -703,29 +636,26 @@ var Volume = /** @class */ (function () {
|
|
|
703
636
|
}
|
|
704
637
|
callback(null, result);
|
|
705
638
|
});
|
|
706
|
-
}
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
if (json === void 0) { json = {}; }
|
|
711
|
-
var isEmpty = true;
|
|
712
|
-
var children = link.children;
|
|
639
|
+
}
|
|
640
|
+
_toJSON(link = this.root, json = {}, path) {
|
|
641
|
+
let isEmpty = true;
|
|
642
|
+
let children = link.children;
|
|
713
643
|
if (link.getNode().isFile()) {
|
|
714
|
-
children =
|
|
644
|
+
children = { [link.getName()]: link.parent.getChild(link.getName()) };
|
|
715
645
|
link = link.parent;
|
|
716
646
|
}
|
|
717
|
-
for (
|
|
718
|
-
if (
|
|
647
|
+
for (const name in children) {
|
|
648
|
+
if (name === '.' || name === '..') {
|
|
719
649
|
continue;
|
|
720
650
|
}
|
|
721
651
|
isEmpty = false;
|
|
722
|
-
|
|
652
|
+
const child = link.getChild(name);
|
|
723
653
|
if (!child) {
|
|
724
654
|
throw new Error('_toJSON: unexpected undefined');
|
|
725
655
|
}
|
|
726
|
-
|
|
656
|
+
const node = child.getNode();
|
|
727
657
|
if (node.isFile()) {
|
|
728
|
-
|
|
658
|
+
let filename = child.getPath();
|
|
729
659
|
if (path)
|
|
730
660
|
filename = relative(path, filename);
|
|
731
661
|
json[filename] = node.getString();
|
|
@@ -734,25 +664,22 @@ var Volume = /** @class */ (function () {
|
|
|
734
664
|
this._toJSON(child, json, path);
|
|
735
665
|
}
|
|
736
666
|
}
|
|
737
|
-
|
|
667
|
+
let dirPath = link.getPath();
|
|
738
668
|
if (path)
|
|
739
669
|
dirPath = relative(path, dirPath);
|
|
740
670
|
if (dirPath && isEmpty) {
|
|
741
671
|
json[dirPath] = null;
|
|
742
672
|
}
|
|
743
673
|
return json;
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
if (isRelative === void 0) { isRelative = false; }
|
|
748
|
-
var links = [];
|
|
674
|
+
}
|
|
675
|
+
toJSON(paths, json = {}, isRelative = false) {
|
|
676
|
+
const links = [];
|
|
749
677
|
if (paths) {
|
|
750
678
|
if (!(paths instanceof Array))
|
|
751
679
|
paths = [paths];
|
|
752
|
-
for (
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
var link = this.getResolvedLink(filename);
|
|
680
|
+
for (const path of paths) {
|
|
681
|
+
const filename = pathToFilename(path);
|
|
682
|
+
const link = this.getResolvedLink(filename);
|
|
756
683
|
if (!link)
|
|
757
684
|
continue;
|
|
758
685
|
links.push(link);
|
|
@@ -763,19 +690,17 @@ var Volume = /** @class */ (function () {
|
|
|
763
690
|
}
|
|
764
691
|
if (!links.length)
|
|
765
692
|
return json;
|
|
766
|
-
for (
|
|
767
|
-
var link = links_1[_a];
|
|
693
|
+
for (const link of links)
|
|
768
694
|
this._toJSON(link, json, isRelative ? link.getPath() : '');
|
|
769
|
-
}
|
|
770
695
|
return json;
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
for (
|
|
775
|
-
|
|
696
|
+
}
|
|
697
|
+
// TODO: `cwd` should probably not invoke `process.cwd()`.
|
|
698
|
+
fromJSON(json, cwd = process_1.default.cwd()) {
|
|
699
|
+
for (let filename in json) {
|
|
700
|
+
const data = json[filename];
|
|
776
701
|
filename = resolve(filename, cwd);
|
|
777
702
|
if (typeof data === 'string') {
|
|
778
|
-
|
|
703
|
+
const dir = dirname(filename);
|
|
779
704
|
this.mkdirpBase(dir, 511 /* MODE.DIR */);
|
|
780
705
|
this.writeFileSync(filename, data);
|
|
781
706
|
}
|
|
@@ -783,11 +708,11 @@ var Volume = /** @class */ (function () {
|
|
|
783
708
|
this.mkdirpBase(filename, 511 /* MODE.DIR */);
|
|
784
709
|
}
|
|
785
710
|
}
|
|
786
|
-
}
|
|
787
|
-
|
|
711
|
+
}
|
|
712
|
+
fromNestedJSON(json, cwd) {
|
|
788
713
|
this.fromJSON(flattenJSON(json), cwd);
|
|
789
|
-
}
|
|
790
|
-
|
|
714
|
+
}
|
|
715
|
+
reset() {
|
|
791
716
|
this.ino = 0;
|
|
792
717
|
this.inodes = {};
|
|
793
718
|
this.releasedInos = [];
|
|
@@ -796,24 +721,23 @@ var Volume = /** @class */ (function () {
|
|
|
796
721
|
this.openFiles = 0;
|
|
797
722
|
this.root = this.createLink();
|
|
798
723
|
this.root.setNode(this.createNode(true));
|
|
799
|
-
}
|
|
724
|
+
}
|
|
800
725
|
// Legacy interface
|
|
801
|
-
|
|
726
|
+
mountSync(mountpoint, json) {
|
|
802
727
|
this.fromJSON(json, mountpoint);
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
if (resolveSymlinks === void 0) { resolveSymlinks = true; }
|
|
728
|
+
}
|
|
729
|
+
openLink(link, flagsNum, resolveSymlinks = true) {
|
|
806
730
|
if (this.openFiles >= this.maxFiles) {
|
|
807
731
|
// Too many open files.
|
|
808
732
|
throw createError(EMFILE, 'open', link.getPath());
|
|
809
733
|
}
|
|
810
734
|
// Resolve symlinks.
|
|
811
|
-
|
|
735
|
+
let realLink = link;
|
|
812
736
|
if (resolveSymlinks)
|
|
813
737
|
realLink = this.resolveSymlinks(link);
|
|
814
738
|
if (!realLink)
|
|
815
739
|
throw createError(ENOENT, 'open', link.getPath());
|
|
816
|
-
|
|
740
|
+
const node = realLink.getNode();
|
|
817
741
|
// Check whether node is a directory
|
|
818
742
|
if (node.isDirectory()) {
|
|
819
743
|
if ((flagsNum & (O_RDONLY | O_RDWR | O_WRONLY)) !== O_RDONLY)
|
|
@@ -831,23 +755,22 @@ var Volume = /** @class */ (function () {
|
|
|
831
755
|
}
|
|
832
756
|
if (flagsNum & O_RDWR) {
|
|
833
757
|
}
|
|
834
|
-
|
|
758
|
+
const file = new this.props.File(link, node, flagsNum, this.newFdNumber());
|
|
835
759
|
this.fds[file.fd] = file;
|
|
836
760
|
this.openFiles++;
|
|
837
761
|
if (flagsNum & O_TRUNC)
|
|
838
762
|
file.truncate();
|
|
839
763
|
return file;
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
var link = resolveSymlinks ? this.getResolvedLink(steps) : this.getLink(steps);
|
|
764
|
+
}
|
|
765
|
+
openFile(filename, flagsNum, modeNum, resolveSymlinks = true) {
|
|
766
|
+
const steps = filenameToSteps(filename);
|
|
767
|
+
let link = resolveSymlinks ? this.getResolvedLink(steps) : this.getLink(steps);
|
|
845
768
|
if (link && flagsNum & O_EXCL)
|
|
846
769
|
throw createError(EEXIST, 'open', filename);
|
|
847
770
|
// Try creating a new file, if it does not exist.
|
|
848
771
|
if (!link && flagsNum & O_CREAT) {
|
|
849
772
|
// const dirLink: Link = this.getLinkParent(steps);
|
|
850
|
-
|
|
773
|
+
const dirLink = this.getResolvedLink(steps.slice(0, steps.length - 1));
|
|
851
774
|
// if(!dirLink) throw createError(ENOENT, 'open', filename);
|
|
852
775
|
if (!dirLink)
|
|
853
776
|
throw createError(ENOENT, 'open', sep + steps.join(sep));
|
|
@@ -858,54 +781,52 @@ var Volume = /** @class */ (function () {
|
|
|
858
781
|
if (link)
|
|
859
782
|
return this.openLink(link, flagsNum, resolveSymlinks);
|
|
860
783
|
throw createError(ENOENT, 'open', filename);
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
var file = this.openFile(filename, flagsNum, modeNum, resolveSymlinks);
|
|
784
|
+
}
|
|
785
|
+
openBase(filename, flagsNum, modeNum, resolveSymlinks = true) {
|
|
786
|
+
const file = this.openFile(filename, flagsNum, modeNum, resolveSymlinks);
|
|
865
787
|
if (!file)
|
|
866
788
|
throw createError(ENOENT, 'open', filename);
|
|
867
789
|
return file.fd;
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
if (mode === void 0) { mode = 438 /* MODE.DEFAULT */; }
|
|
790
|
+
}
|
|
791
|
+
openSync(path, flags, mode = 438 /* MODE.DEFAULT */) {
|
|
871
792
|
// Validate (1) mode; (2) path; (3) flags - in that order.
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
793
|
+
const modeNum = modeToNumber(mode);
|
|
794
|
+
const fileName = pathToFilename(path);
|
|
795
|
+
const flagsNum = flagsToNumber(flags);
|
|
875
796
|
return this.openBase(fileName, flagsNum, modeNum);
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
797
|
+
}
|
|
798
|
+
open(path, flags, a, b) {
|
|
799
|
+
let mode = a;
|
|
800
|
+
let callback = b;
|
|
880
801
|
if (typeof a === 'function') {
|
|
881
802
|
mode = 438 /* MODE.DEFAULT */;
|
|
882
803
|
callback = a;
|
|
883
804
|
}
|
|
884
805
|
mode = mode || 438 /* MODE.DEFAULT */;
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
806
|
+
const modeNum = modeToNumber(mode);
|
|
807
|
+
const fileName = pathToFilename(path);
|
|
808
|
+
const flagsNum = flagsToNumber(flags);
|
|
888
809
|
this.wrapAsync(this.openBase, [fileName, flagsNum, modeNum], callback);
|
|
889
|
-
}
|
|
890
|
-
|
|
810
|
+
}
|
|
811
|
+
closeFile(file) {
|
|
891
812
|
if (!this.fds[file.fd])
|
|
892
813
|
return;
|
|
893
814
|
this.openFiles--;
|
|
894
815
|
delete this.fds[file.fd];
|
|
895
816
|
this.releasedFds.push(file.fd);
|
|
896
|
-
}
|
|
897
|
-
|
|
817
|
+
}
|
|
818
|
+
closeSync(fd) {
|
|
898
819
|
validateFd(fd);
|
|
899
|
-
|
|
820
|
+
const file = this.getFileByFdOrThrow(fd, 'close');
|
|
900
821
|
this.closeFile(file);
|
|
901
|
-
}
|
|
902
|
-
|
|
822
|
+
}
|
|
823
|
+
close(fd, callback) {
|
|
903
824
|
validateFd(fd);
|
|
904
825
|
this.wrapAsync(this.closeSync, [fd], callback);
|
|
905
|
-
}
|
|
906
|
-
|
|
826
|
+
}
|
|
827
|
+
openFileOrGetById(id, flagsNum, modeNum) {
|
|
907
828
|
if (typeof id === 'number') {
|
|
908
|
-
|
|
829
|
+
const file = this.fds[id];
|
|
909
830
|
if (!file)
|
|
910
831
|
throw createError(ENOENT);
|
|
911
832
|
return file;
|
|
@@ -913,48 +834,47 @@ var Volume = /** @class */ (function () {
|
|
|
913
834
|
else {
|
|
914
835
|
return this.openFile(pathToFilename(id), flagsNum, modeNum);
|
|
915
836
|
}
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
|
|
837
|
+
}
|
|
838
|
+
readBase(fd, buffer, offset, length, position) {
|
|
839
|
+
const file = this.getFileByFdOrThrow(fd);
|
|
919
840
|
return file.read(buffer, Number(offset), Number(length), position);
|
|
920
|
-
}
|
|
921
|
-
|
|
841
|
+
}
|
|
842
|
+
readSync(fd, buffer, offset, length, position) {
|
|
922
843
|
validateFd(fd);
|
|
923
844
|
return this.readBase(fd, buffer, offset, length, position);
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
var _this = this;
|
|
845
|
+
}
|
|
846
|
+
read(fd, buffer, offset, length, position, callback) {
|
|
927
847
|
validateCallback(callback);
|
|
928
848
|
// This `if` branch is from Node.js
|
|
929
849
|
if (length === 0) {
|
|
930
|
-
return process_1.default.nextTick(
|
|
850
|
+
return process_1.default.nextTick(() => {
|
|
931
851
|
if (callback)
|
|
932
852
|
callback(null, 0, buffer);
|
|
933
853
|
});
|
|
934
854
|
}
|
|
935
|
-
(0, setImmediate_1.default)(
|
|
855
|
+
(0, setImmediate_1.default)(() => {
|
|
936
856
|
try {
|
|
937
|
-
|
|
857
|
+
const bytes = this.readBase(fd, buffer, offset, length, position);
|
|
938
858
|
callback(null, bytes, buffer);
|
|
939
859
|
}
|
|
940
860
|
catch (err) {
|
|
941
861
|
callback(err);
|
|
942
862
|
}
|
|
943
863
|
});
|
|
944
|
-
}
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
864
|
+
}
|
|
865
|
+
readFileBase(id, flagsNum, encoding) {
|
|
866
|
+
let result;
|
|
867
|
+
const isUserFd = typeof id === 'number';
|
|
868
|
+
const userOwnsFd = isUserFd && isFd(id);
|
|
869
|
+
let fd;
|
|
950
870
|
if (userOwnsFd)
|
|
951
871
|
fd = id;
|
|
952
872
|
else {
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
873
|
+
const filename = pathToFilename(id);
|
|
874
|
+
const steps = filenameToSteps(filename);
|
|
875
|
+
const link = this.getResolvedLink(steps);
|
|
956
876
|
if (link) {
|
|
957
|
-
|
|
877
|
+
const node = link.getNode();
|
|
958
878
|
if (node.isDirectory())
|
|
959
879
|
throw createError(EISDIR, 'open', link.getPath());
|
|
960
880
|
}
|
|
@@ -969,28 +889,28 @@ var Volume = /** @class */ (function () {
|
|
|
969
889
|
}
|
|
970
890
|
}
|
|
971
891
|
return result;
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
892
|
+
}
|
|
893
|
+
readFileSync(file, options) {
|
|
894
|
+
const opts = getReadFileOptions(options);
|
|
895
|
+
const flagsNum = flagsToNumber(opts.flag);
|
|
976
896
|
return this.readFileBase(file, flagsNum, opts.encoding);
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
897
|
+
}
|
|
898
|
+
readFile(id, a, b) {
|
|
899
|
+
const [opts, callback] = optsAndCbGenerator(getReadFileOptions)(a, b);
|
|
900
|
+
const flagsNum = flagsToNumber(opts.flag);
|
|
981
901
|
this.wrapAsync(this.readFileBase, [id, flagsNum, opts.encoding], callback);
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
|
|
902
|
+
}
|
|
903
|
+
writeBase(fd, buf, offset, length, position) {
|
|
904
|
+
const file = this.getFileByFdOrThrow(fd, 'write');
|
|
985
905
|
return file.write(buf, offset, length, position);
|
|
986
|
-
}
|
|
987
|
-
|
|
906
|
+
}
|
|
907
|
+
writeSync(fd, a, b, c, d) {
|
|
988
908
|
validateFd(fd);
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
909
|
+
let encoding;
|
|
910
|
+
let offset;
|
|
911
|
+
let length;
|
|
912
|
+
let position;
|
|
913
|
+
const isBuffer = typeof a !== 'string';
|
|
994
914
|
if (isBuffer) {
|
|
995
915
|
offset = (b || 0) | 0;
|
|
996
916
|
length = c;
|
|
@@ -1000,7 +920,7 @@ var Volume = /** @class */ (function () {
|
|
|
1000
920
|
position = b;
|
|
1001
921
|
encoding = c;
|
|
1002
922
|
}
|
|
1003
|
-
|
|
923
|
+
const buf = dataToBuffer(a, encoding);
|
|
1004
924
|
if (isBuffer) {
|
|
1005
925
|
if (typeof length === 'undefined') {
|
|
1006
926
|
length = buf.length;
|
|
@@ -1011,19 +931,18 @@ var Volume = /** @class */ (function () {
|
|
|
1011
931
|
length = buf.length;
|
|
1012
932
|
}
|
|
1013
933
|
return this.writeBase(fd, buf, offset, length, position);
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
|
-
var _this = this;
|
|
934
|
+
}
|
|
935
|
+
write(fd, a, b, c, d, e) {
|
|
1017
936
|
validateFd(fd);
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
937
|
+
let offset;
|
|
938
|
+
let length;
|
|
939
|
+
let position;
|
|
940
|
+
let encoding;
|
|
941
|
+
let callback;
|
|
942
|
+
const tipa = typeof a;
|
|
943
|
+
const tipb = typeof b;
|
|
944
|
+
const tipc = typeof c;
|
|
945
|
+
const tipd = typeof d;
|
|
1027
946
|
if (tipa !== 'string') {
|
|
1028
947
|
if (tipb === 'function') {
|
|
1029
948
|
callback = b;
|
|
@@ -1058,7 +977,7 @@ var Volume = /** @class */ (function () {
|
|
|
1058
977
|
callback = d;
|
|
1059
978
|
}
|
|
1060
979
|
}
|
|
1061
|
-
|
|
980
|
+
const buf = dataToBuffer(a, encoding);
|
|
1062
981
|
if (tipa !== 'string') {
|
|
1063
982
|
if (typeof length === 'undefined')
|
|
1064
983
|
length = buf.length;
|
|
@@ -1067,10 +986,10 @@ var Volume = /** @class */ (function () {
|
|
|
1067
986
|
offset = 0;
|
|
1068
987
|
length = buf.length;
|
|
1069
988
|
}
|
|
1070
|
-
|
|
1071
|
-
(0, setImmediate_1.default)(
|
|
989
|
+
const cb = validateCallback(callback);
|
|
990
|
+
(0, setImmediate_1.default)(() => {
|
|
1072
991
|
try {
|
|
1073
|
-
|
|
992
|
+
const bytes = this.writeBase(fd, buf, offset, length, position);
|
|
1074
993
|
if (tipa !== 'string') {
|
|
1075
994
|
cb(null, bytes, buf);
|
|
1076
995
|
}
|
|
@@ -1082,25 +1001,25 @@ var Volume = /** @class */ (function () {
|
|
|
1082
1001
|
cb(err);
|
|
1083
1002
|
}
|
|
1084
1003
|
});
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1004
|
+
}
|
|
1005
|
+
writeFileBase(id, buf, flagsNum, modeNum) {
|
|
1087
1006
|
// console.log('writeFileBase', id, buf, flagsNum, modeNum);
|
|
1088
1007
|
// const node = this.getNodeByIdOrCreate(id, flagsNum, modeNum);
|
|
1089
1008
|
// node.setBuffer(buf);
|
|
1090
|
-
|
|
1091
|
-
|
|
1009
|
+
const isUserFd = typeof id === 'number';
|
|
1010
|
+
let fd;
|
|
1092
1011
|
if (isUserFd)
|
|
1093
1012
|
fd = id;
|
|
1094
1013
|
else {
|
|
1095
1014
|
fd = this.openBase(pathToFilename(id), flagsNum, modeNum);
|
|
1096
1015
|
// fd = this.openSync(id as PathLike, flagsNum, modeNum);
|
|
1097
1016
|
}
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1017
|
+
let offset = 0;
|
|
1018
|
+
let length = buf.length;
|
|
1019
|
+
let position = flagsNum & O_APPEND ? undefined : 0;
|
|
1101
1020
|
try {
|
|
1102
1021
|
while (length > 0) {
|
|
1103
|
-
|
|
1022
|
+
const written = this.writeSync(fd, buf, offset, length, position);
|
|
1104
1023
|
offset += written;
|
|
1105
1024
|
length -= written;
|
|
1106
1025
|
if (position !== undefined)
|
|
@@ -1111,48 +1030,48 @@ var Volume = /** @class */ (function () {
|
|
|
1111
1030
|
if (!isUserFd)
|
|
1112
1031
|
this.closeSync(fd);
|
|
1113
1032
|
}
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1033
|
+
}
|
|
1034
|
+
writeFileSync(id, data, options) {
|
|
1035
|
+
const opts = getWriteFileOptions(options);
|
|
1036
|
+
const flagsNum = flagsToNumber(opts.flag);
|
|
1037
|
+
const modeNum = modeToNumber(opts.mode);
|
|
1038
|
+
const buf = dataToBuffer(data, opts.encoding);
|
|
1120
1039
|
this.writeFileBase(id, buf, flagsNum, modeNum);
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1040
|
+
}
|
|
1041
|
+
writeFile(id, data, a, b) {
|
|
1042
|
+
let options = a;
|
|
1043
|
+
let callback = b;
|
|
1125
1044
|
if (typeof a === 'function') {
|
|
1126
1045
|
options = writeFileDefaults;
|
|
1127
1046
|
callback = a;
|
|
1128
1047
|
}
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1048
|
+
const cb = validateCallback(callback);
|
|
1049
|
+
const opts = getWriteFileOptions(options);
|
|
1050
|
+
const flagsNum = flagsToNumber(opts.flag);
|
|
1051
|
+
const modeNum = modeToNumber(opts.mode);
|
|
1052
|
+
const buf = dataToBuffer(data, opts.encoding);
|
|
1134
1053
|
this.wrapAsync(this.writeFileBase, [id, buf, flagsNum, modeNum], cb);
|
|
1135
|
-
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1054
|
+
}
|
|
1055
|
+
linkBase(filename1, filename2) {
|
|
1056
|
+
const steps1 = filenameToSteps(filename1);
|
|
1057
|
+
const link1 = this.getLink(steps1);
|
|
1139
1058
|
if (!link1)
|
|
1140
1059
|
throw createError(ENOENT, 'link', filename1, filename2);
|
|
1141
|
-
|
|
1060
|
+
const steps2 = filenameToSteps(filename2);
|
|
1142
1061
|
// Check new link directory exists.
|
|
1143
|
-
|
|
1062
|
+
const dir2 = this.getLinkParent(steps2);
|
|
1144
1063
|
if (!dir2)
|
|
1145
1064
|
throw createError(ENOENT, 'link', filename1, filename2);
|
|
1146
|
-
|
|
1065
|
+
const name = steps2[steps2.length - 1];
|
|
1147
1066
|
// Check if new file already exists.
|
|
1148
1067
|
if (dir2.getChild(name))
|
|
1149
1068
|
throw createError(EEXIST, 'link', filename1, filename2);
|
|
1150
|
-
|
|
1069
|
+
const node = link1.getNode();
|
|
1151
1070
|
node.nlink++;
|
|
1152
1071
|
dir2.createChild(name, node);
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1072
|
+
}
|
|
1073
|
+
copyFileBase(src, dest, flags) {
|
|
1074
|
+
const buf = this.readFileSync(src);
|
|
1156
1075
|
if (flags & COPYFILE_EXCL) {
|
|
1157
1076
|
if (this.existsSync(dest)) {
|
|
1158
1077
|
throw createError(EEXIST, 'copyFile', src, dest);
|
|
@@ -1162,17 +1081,17 @@ var Volume = /** @class */ (function () {
|
|
|
1162
1081
|
throw createError(ENOSYS, 'copyFile', src, dest);
|
|
1163
1082
|
}
|
|
1164
1083
|
this.writeFileBase(dest, buf, FLAGS.w, 438 /* MODE.DEFAULT */);
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1084
|
+
}
|
|
1085
|
+
copyFileSync(src, dest, flags) {
|
|
1086
|
+
const srcFilename = pathToFilename(src);
|
|
1087
|
+
const destFilename = pathToFilename(dest);
|
|
1169
1088
|
return this.copyFileBase(srcFilename, destFilename, (flags || 0) | 0);
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1089
|
+
}
|
|
1090
|
+
copyFile(src, dest, a, b) {
|
|
1091
|
+
const srcFilename = pathToFilename(src);
|
|
1092
|
+
const destFilename = pathToFilename(dest);
|
|
1093
|
+
let flags;
|
|
1094
|
+
let callback;
|
|
1176
1095
|
if (typeof a === 'function') {
|
|
1177
1096
|
flags = 0;
|
|
1178
1097
|
callback = a;
|
|
@@ -1183,87 +1102,85 @@ var Volume = /** @class */ (function () {
|
|
|
1183
1102
|
}
|
|
1184
1103
|
validateCallback(callback);
|
|
1185
1104
|
this.wrapAsync(this.copyFileBase, [srcFilename, destFilename, flags], callback);
|
|
1186
|
-
}
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1105
|
+
}
|
|
1106
|
+
linkSync(existingPath, newPath) {
|
|
1107
|
+
const existingPathFilename = pathToFilename(existingPath);
|
|
1108
|
+
const newPathFilename = pathToFilename(newPath);
|
|
1190
1109
|
this.linkBase(existingPathFilename, newPathFilename);
|
|
1191
|
-
}
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1110
|
+
}
|
|
1111
|
+
link(existingPath, newPath, callback) {
|
|
1112
|
+
const existingPathFilename = pathToFilename(existingPath);
|
|
1113
|
+
const newPathFilename = pathToFilename(newPath);
|
|
1195
1114
|
this.wrapAsync(this.linkBase, [existingPathFilename, newPathFilename], callback);
|
|
1196
|
-
}
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1115
|
+
}
|
|
1116
|
+
unlinkBase(filename) {
|
|
1117
|
+
const steps = filenameToSteps(filename);
|
|
1118
|
+
const link = this.getLink(steps);
|
|
1200
1119
|
if (!link)
|
|
1201
1120
|
throw createError(ENOENT, 'unlink', filename);
|
|
1202
1121
|
// TODO: Check if it is file, dir, other...
|
|
1203
1122
|
if (link.length)
|
|
1204
1123
|
throw Error('Dir not empty...');
|
|
1205
1124
|
this.deleteLink(link);
|
|
1206
|
-
|
|
1125
|
+
const node = link.getNode();
|
|
1207
1126
|
node.nlink--;
|
|
1208
1127
|
// When all hard links to i-node are deleted, remove the i-node, too.
|
|
1209
1128
|
if (node.nlink <= 0) {
|
|
1210
1129
|
this.deleteNode(node);
|
|
1211
1130
|
}
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
|
|
1131
|
+
}
|
|
1132
|
+
unlinkSync(path) {
|
|
1133
|
+
const filename = pathToFilename(path);
|
|
1215
1134
|
this.unlinkBase(filename);
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
|
|
1135
|
+
}
|
|
1136
|
+
unlink(path, callback) {
|
|
1137
|
+
const filename = pathToFilename(path);
|
|
1219
1138
|
this.wrapAsync(this.unlinkBase, [filename], callback);
|
|
1220
|
-
}
|
|
1221
|
-
|
|
1222
|
-
|
|
1139
|
+
}
|
|
1140
|
+
symlinkBase(targetFilename, pathFilename) {
|
|
1141
|
+
const pathSteps = filenameToSteps(pathFilename);
|
|
1223
1142
|
// Check if directory exists, where we about to create a symlink.
|
|
1224
|
-
|
|
1143
|
+
const dirLink = this.getLinkParent(pathSteps);
|
|
1225
1144
|
if (!dirLink)
|
|
1226
1145
|
throw createError(ENOENT, 'symlink', targetFilename, pathFilename);
|
|
1227
|
-
|
|
1146
|
+
const name = pathSteps[pathSteps.length - 1];
|
|
1228
1147
|
// Check if new file already exists.
|
|
1229
1148
|
if (dirLink.getChild(name))
|
|
1230
1149
|
throw createError(EEXIST, 'symlink', targetFilename, pathFilename);
|
|
1231
1150
|
// Create symlink.
|
|
1232
|
-
|
|
1151
|
+
const symlink = dirLink.createChild(name);
|
|
1233
1152
|
symlink.getNode().makeSymlink(filenameToSteps(targetFilename));
|
|
1234
1153
|
return symlink;
|
|
1235
|
-
}
|
|
1154
|
+
}
|
|
1236
1155
|
// `type` argument works only on Windows.
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1156
|
+
symlinkSync(target, path, type) {
|
|
1157
|
+
const targetFilename = pathToFilename(target);
|
|
1158
|
+
const pathFilename = pathToFilename(path);
|
|
1240
1159
|
this.symlinkBase(targetFilename, pathFilename);
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1160
|
+
}
|
|
1161
|
+
symlink(target, path, a, b) {
|
|
1162
|
+
const callback = validateCallback(typeof a === 'function' ? a : b);
|
|
1163
|
+
const targetFilename = pathToFilename(target);
|
|
1164
|
+
const pathFilename = pathToFilename(path);
|
|
1246
1165
|
this.wrapAsync(this.symlinkBase, [targetFilename, pathFilename], callback);
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1166
|
+
}
|
|
1167
|
+
realpathBase(filename, encoding) {
|
|
1168
|
+
const steps = filenameToSteps(filename);
|
|
1169
|
+
const realLink = this.getResolvedLink(steps);
|
|
1251
1170
|
if (!realLink)
|
|
1252
1171
|
throw createError(ENOENT, 'realpath', filename);
|
|
1253
1172
|
return (0, encoding_1.strToEncoding)(realLink.getPath() || '/', encoding);
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1173
|
+
}
|
|
1174
|
+
realpathSync(path, options) {
|
|
1256
1175
|
return this.realpathBase(pathToFilename(path), getRealpathOptions(options).encoding);
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1176
|
+
}
|
|
1177
|
+
realpath(path, a, b) {
|
|
1178
|
+
const [opts, callback] = getRealpathOptsAndCb(a, b);
|
|
1179
|
+
const pathFilename = pathToFilename(path);
|
|
1261
1180
|
this.wrapAsync(this.realpathBase, [pathFilename, opts.encoding], callback);
|
|
1262
|
-
}
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
if (throwIfNoEntry === void 0) { throwIfNoEntry = false; }
|
|
1266
|
-
var link = this.getLink(filenameToSteps(filename));
|
|
1181
|
+
}
|
|
1182
|
+
lstatBase(filename, bigint = false, throwIfNoEntry = false) {
|
|
1183
|
+
const link = this.getLink(filenameToSteps(filename));
|
|
1267
1184
|
if (link) {
|
|
1268
1185
|
return Stats_1.default.build(link.getNode(), bigint);
|
|
1269
1186
|
}
|
|
@@ -1273,19 +1190,17 @@ var Volume = /** @class */ (function () {
|
|
|
1273
1190
|
else {
|
|
1274
1191
|
throw createError(ENOENT, 'lstat', filename);
|
|
1275
1192
|
}
|
|
1276
|
-
}
|
|
1277
|
-
|
|
1278
|
-
|
|
1193
|
+
}
|
|
1194
|
+
lstatSync(path, options) {
|
|
1195
|
+
const { throwIfNoEntry = true, bigint = false } = getStatOptions(options);
|
|
1279
1196
|
return this.lstatBase(pathToFilename(path), bigint, throwIfNoEntry);
|
|
1280
|
-
}
|
|
1281
|
-
|
|
1282
|
-
|
|
1197
|
+
}
|
|
1198
|
+
lstat(path, a, b) {
|
|
1199
|
+
const [{ throwIfNoEntry = true, bigint = false }, callback] = getStatOptsAndCb(a, b);
|
|
1283
1200
|
this.wrapAsync(this.lstatBase, [pathToFilename(path), bigint, throwIfNoEntry], callback);
|
|
1284
|
-
}
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
if (throwIfNoEntry === void 0) { throwIfNoEntry = true; }
|
|
1288
|
-
var link = this.getResolvedLink(filenameToSteps(filename));
|
|
1201
|
+
}
|
|
1202
|
+
statBase(filename, bigint = false, throwIfNoEntry = true) {
|
|
1203
|
+
const link = this.getResolvedLink(filenameToSteps(filename));
|
|
1289
1204
|
if (link) {
|
|
1290
1205
|
return Stats_1.default.build(link.getNode(), bigint);
|
|
1291
1206
|
}
|
|
@@ -1295,100 +1210,97 @@ var Volume = /** @class */ (function () {
|
|
|
1295
1210
|
else {
|
|
1296
1211
|
throw createError(ENOENT, 'stat', filename);
|
|
1297
1212
|
}
|
|
1298
|
-
}
|
|
1299
|
-
|
|
1300
|
-
|
|
1213
|
+
}
|
|
1214
|
+
statSync(path, options) {
|
|
1215
|
+
const { bigint = true, throwIfNoEntry = true } = getStatOptions(options);
|
|
1301
1216
|
return this.statBase(pathToFilename(path), bigint, throwIfNoEntry);
|
|
1302
|
-
}
|
|
1303
|
-
|
|
1304
|
-
|
|
1217
|
+
}
|
|
1218
|
+
stat(path, a, b) {
|
|
1219
|
+
const [{ bigint = false, throwIfNoEntry = true }, callback] = getStatOptsAndCb(a, b);
|
|
1305
1220
|
this.wrapAsync(this.statBase, [pathToFilename(path), bigint, throwIfNoEntry], callback);
|
|
1306
|
-
}
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
var file = this.getFileByFd(fd);
|
|
1221
|
+
}
|
|
1222
|
+
fstatBase(fd, bigint = false) {
|
|
1223
|
+
const file = this.getFileByFd(fd);
|
|
1310
1224
|
if (!file)
|
|
1311
1225
|
throw createError(EBADF, 'fstat');
|
|
1312
1226
|
return Stats_1.default.build(file.node, bigint);
|
|
1313
|
-
}
|
|
1314
|
-
|
|
1227
|
+
}
|
|
1228
|
+
fstatSync(fd, options) {
|
|
1315
1229
|
return this.fstatBase(fd, getStatOptions(options).bigint);
|
|
1316
|
-
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1230
|
+
}
|
|
1231
|
+
fstat(fd, a, b) {
|
|
1232
|
+
const [opts, callback] = getStatOptsAndCb(a, b);
|
|
1319
1233
|
this.wrapAsync(this.fstatBase, [fd, opts.bigint], callback);
|
|
1320
|
-
}
|
|
1321
|
-
|
|
1322
|
-
|
|
1234
|
+
}
|
|
1235
|
+
renameBase(oldPathFilename, newPathFilename) {
|
|
1236
|
+
const link = this.getLink(filenameToSteps(oldPathFilename));
|
|
1323
1237
|
if (!link)
|
|
1324
1238
|
throw createError(ENOENT, 'rename', oldPathFilename, newPathFilename);
|
|
1325
1239
|
// TODO: Check if it is directory, if non-empty, we cannot move it, right?
|
|
1326
|
-
|
|
1240
|
+
const newPathSteps = filenameToSteps(newPathFilename);
|
|
1327
1241
|
// Check directory exists for the new location.
|
|
1328
|
-
|
|
1242
|
+
const newPathDirLink = this.getLinkParent(newPathSteps);
|
|
1329
1243
|
if (!newPathDirLink)
|
|
1330
1244
|
throw createError(ENOENT, 'rename', oldPathFilename, newPathFilename);
|
|
1331
1245
|
// TODO: Also treat cases with directories and symbolic links.
|
|
1332
1246
|
// TODO: See: http://man7.org/linux/man-pages/man2/rename.2.html
|
|
1333
1247
|
// Remove hard link from old folder.
|
|
1334
|
-
|
|
1248
|
+
const oldLinkParent = link.parent;
|
|
1335
1249
|
if (oldLinkParent) {
|
|
1336
1250
|
oldLinkParent.deleteChild(link);
|
|
1337
1251
|
}
|
|
1338
1252
|
// Rename should overwrite the new path, if that exists.
|
|
1339
|
-
|
|
1253
|
+
const name = newPathSteps[newPathSteps.length - 1];
|
|
1340
1254
|
link.name = name;
|
|
1341
|
-
link.steps =
|
|
1255
|
+
link.steps = [...newPathDirLink.steps, name];
|
|
1342
1256
|
newPathDirLink.setChild(link.getName(), link);
|
|
1343
|
-
}
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1257
|
+
}
|
|
1258
|
+
renameSync(oldPath, newPath) {
|
|
1259
|
+
const oldPathFilename = pathToFilename(oldPath);
|
|
1260
|
+
const newPathFilename = pathToFilename(newPath);
|
|
1347
1261
|
this.renameBase(oldPathFilename, newPathFilename);
|
|
1348
|
-
}
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1262
|
+
}
|
|
1263
|
+
rename(oldPath, newPath, callback) {
|
|
1264
|
+
const oldPathFilename = pathToFilename(oldPath);
|
|
1265
|
+
const newPathFilename = pathToFilename(newPath);
|
|
1352
1266
|
this.wrapAsync(this.renameBase, [oldPathFilename, newPathFilename], callback);
|
|
1353
|
-
}
|
|
1354
|
-
|
|
1267
|
+
}
|
|
1268
|
+
existsBase(filename) {
|
|
1355
1269
|
return !!this.statBase(filename);
|
|
1356
|
-
}
|
|
1357
|
-
|
|
1270
|
+
}
|
|
1271
|
+
existsSync(path) {
|
|
1358
1272
|
try {
|
|
1359
1273
|
return this.existsBase(pathToFilename(path));
|
|
1360
1274
|
}
|
|
1361
1275
|
catch (err) {
|
|
1362
1276
|
return false;
|
|
1363
1277
|
}
|
|
1364
|
-
}
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
var filename = pathToFilename(path);
|
|
1278
|
+
}
|
|
1279
|
+
exists(path, callback) {
|
|
1280
|
+
const filename = pathToFilename(path);
|
|
1368
1281
|
if (typeof callback !== 'function')
|
|
1369
1282
|
throw Error(ERRSTR.CB);
|
|
1370
|
-
(0, setImmediate_1.default)(
|
|
1283
|
+
(0, setImmediate_1.default)(() => {
|
|
1371
1284
|
try {
|
|
1372
|
-
callback(
|
|
1285
|
+
callback(this.existsBase(filename));
|
|
1373
1286
|
}
|
|
1374
1287
|
catch (err) {
|
|
1375
1288
|
callback(false);
|
|
1376
1289
|
}
|
|
1377
1290
|
});
|
|
1378
|
-
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1291
|
+
}
|
|
1292
|
+
accessBase(filename, mode) {
|
|
1293
|
+
const link = this.getLinkOrThrow(filename, 'access');
|
|
1381
1294
|
// TODO: Verify permissions
|
|
1382
|
-
}
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
var filename = pathToFilename(path);
|
|
1295
|
+
}
|
|
1296
|
+
accessSync(path, mode = F_OK) {
|
|
1297
|
+
const filename = pathToFilename(path);
|
|
1386
1298
|
mode = mode | 0;
|
|
1387
1299
|
this.accessBase(filename, mode);
|
|
1388
|
-
}
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1300
|
+
}
|
|
1301
|
+
access(path, a, b) {
|
|
1302
|
+
let mode = F_OK;
|
|
1303
|
+
let callback;
|
|
1392
1304
|
if (typeof a !== 'function') {
|
|
1393
1305
|
mode = a | 0; // cast to number
|
|
1394
1306
|
callback = validateCallback(b);
|
|
@@ -1396,197 +1308,196 @@ var Volume = /** @class */ (function () {
|
|
|
1396
1308
|
else {
|
|
1397
1309
|
callback = a;
|
|
1398
1310
|
}
|
|
1399
|
-
|
|
1311
|
+
const filename = pathToFilename(path);
|
|
1400
1312
|
this.wrapAsync(this.accessBase, [filename, mode], callback);
|
|
1401
|
-
}
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
var opts = getAppendFileOpts(options);
|
|
1313
|
+
}
|
|
1314
|
+
appendFileSync(id, data, options = appendFileDefaults) {
|
|
1315
|
+
const opts = getAppendFileOpts(options);
|
|
1405
1316
|
// force append behavior when using a supplied file descriptor
|
|
1406
1317
|
if (!opts.flag || isFd(id))
|
|
1407
1318
|
opts.flag = 'a';
|
|
1408
1319
|
this.writeFileSync(id, data, opts);
|
|
1409
|
-
}
|
|
1410
|
-
|
|
1411
|
-
|
|
1320
|
+
}
|
|
1321
|
+
appendFile(id, data, a, b) {
|
|
1322
|
+
const [opts, callback] = getAppendFileOptsAndCb(a, b);
|
|
1412
1323
|
// force append behavior when using a supplied file descriptor
|
|
1413
1324
|
if (!opts.flag || isFd(id))
|
|
1414
1325
|
opts.flag = 'a';
|
|
1415
1326
|
this.writeFile(id, data, opts, callback);
|
|
1416
|
-
}
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1327
|
+
}
|
|
1328
|
+
readdirBase(filename, options) {
|
|
1329
|
+
const steps = filenameToSteps(filename);
|
|
1330
|
+
const link = this.getResolvedLink(steps);
|
|
1420
1331
|
if (!link)
|
|
1421
1332
|
throw createError(ENOENT, 'readdir', filename);
|
|
1422
|
-
|
|
1333
|
+
const node = link.getNode();
|
|
1423
1334
|
if (!node.isDirectory())
|
|
1424
1335
|
throw createError(ENOTDIR, 'scandir', filename);
|
|
1425
1336
|
if (options.withFileTypes) {
|
|
1426
|
-
|
|
1427
|
-
for (
|
|
1428
|
-
|
|
1429
|
-
if (!child ||
|
|
1337
|
+
const list = [];
|
|
1338
|
+
for (const name in link.children) {
|
|
1339
|
+
const child = link.getChild(name);
|
|
1340
|
+
if (!child || name === '.' || name === '..') {
|
|
1430
1341
|
continue;
|
|
1431
1342
|
}
|
|
1432
|
-
|
|
1343
|
+
list.push(Dirent_1.default.build(child, options.encoding));
|
|
1433
1344
|
}
|
|
1434
1345
|
if (!isWin && options.encoding !== 'buffer')
|
|
1435
|
-
|
|
1346
|
+
list.sort((a, b) => {
|
|
1436
1347
|
if (a.name < b.name)
|
|
1437
1348
|
return -1;
|
|
1438
1349
|
if (a.name > b.name)
|
|
1439
1350
|
return 1;
|
|
1440
1351
|
return 0;
|
|
1441
1352
|
});
|
|
1442
|
-
return
|
|
1353
|
+
return list;
|
|
1443
1354
|
}
|
|
1444
|
-
|
|
1445
|
-
for (
|
|
1446
|
-
if (
|
|
1355
|
+
const list = [];
|
|
1356
|
+
for (const name in link.children) {
|
|
1357
|
+
if (name === '.' || name === '..') {
|
|
1447
1358
|
continue;
|
|
1448
1359
|
}
|
|
1449
|
-
list.push((0, encoding_1.strToEncoding)(
|
|
1360
|
+
list.push((0, encoding_1.strToEncoding)(name, options.encoding));
|
|
1450
1361
|
}
|
|
1451
1362
|
if (!isWin && options.encoding !== 'buffer')
|
|
1452
1363
|
list.sort();
|
|
1453
1364
|
return list;
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1365
|
+
}
|
|
1366
|
+
readdirSync(path, options) {
|
|
1367
|
+
const opts = getReaddirOptions(options);
|
|
1368
|
+
const filename = pathToFilename(path);
|
|
1458
1369
|
return this.readdirBase(filename, opts);
|
|
1459
|
-
}
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1370
|
+
}
|
|
1371
|
+
readdir(path, a, b) {
|
|
1372
|
+
const [options, callback] = getReaddirOptsAndCb(a, b);
|
|
1373
|
+
const filename = pathToFilename(path);
|
|
1463
1374
|
this.wrapAsync(this.readdirBase, [filename, options], callback);
|
|
1464
|
-
}
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1375
|
+
}
|
|
1376
|
+
readlinkBase(filename, encoding) {
|
|
1377
|
+
const link = this.getLinkOrThrow(filename, 'readlink');
|
|
1378
|
+
const node = link.getNode();
|
|
1468
1379
|
if (!node.isSymlink())
|
|
1469
1380
|
throw createError(EINVAL, 'readlink', filename);
|
|
1470
|
-
|
|
1381
|
+
const str = sep + node.symlink.join(sep);
|
|
1471
1382
|
return (0, encoding_1.strToEncoding)(str, encoding);
|
|
1472
|
-
}
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1383
|
+
}
|
|
1384
|
+
readlinkSync(path, options) {
|
|
1385
|
+
const opts = getDefaultOpts(options);
|
|
1386
|
+
const filename = pathToFilename(path);
|
|
1476
1387
|
return this.readlinkBase(filename, opts.encoding);
|
|
1477
|
-
}
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1388
|
+
}
|
|
1389
|
+
readlink(path, a, b) {
|
|
1390
|
+
const [opts, callback] = getDefaultOptsAndCb(a, b);
|
|
1391
|
+
const filename = pathToFilename(path);
|
|
1481
1392
|
this.wrapAsync(this.readlinkBase, [filename, opts.encoding], callback);
|
|
1482
|
-
}
|
|
1483
|
-
|
|
1393
|
+
}
|
|
1394
|
+
fsyncBase(fd) {
|
|
1484
1395
|
this.getFileByFdOrThrow(fd, 'fsync');
|
|
1485
|
-
}
|
|
1486
|
-
|
|
1396
|
+
}
|
|
1397
|
+
fsyncSync(fd) {
|
|
1487
1398
|
this.fsyncBase(fd);
|
|
1488
|
-
}
|
|
1489
|
-
|
|
1399
|
+
}
|
|
1400
|
+
fsync(fd, callback) {
|
|
1490
1401
|
this.wrapAsync(this.fsyncBase, [fd], callback);
|
|
1491
|
-
}
|
|
1492
|
-
|
|
1402
|
+
}
|
|
1403
|
+
fdatasyncBase(fd) {
|
|
1493
1404
|
this.getFileByFdOrThrow(fd, 'fdatasync');
|
|
1494
|
-
}
|
|
1495
|
-
|
|
1405
|
+
}
|
|
1406
|
+
fdatasyncSync(fd) {
|
|
1496
1407
|
this.fdatasyncBase(fd);
|
|
1497
|
-
}
|
|
1498
|
-
|
|
1408
|
+
}
|
|
1409
|
+
fdatasync(fd, callback) {
|
|
1499
1410
|
this.wrapAsync(this.fdatasyncBase, [fd], callback);
|
|
1500
|
-
}
|
|
1501
|
-
|
|
1502
|
-
|
|
1411
|
+
}
|
|
1412
|
+
ftruncateBase(fd, len) {
|
|
1413
|
+
const file = this.getFileByFdOrThrow(fd, 'ftruncate');
|
|
1503
1414
|
file.truncate(len);
|
|
1504
|
-
}
|
|
1505
|
-
|
|
1415
|
+
}
|
|
1416
|
+
ftruncateSync(fd, len) {
|
|
1506
1417
|
this.ftruncateBase(fd, len);
|
|
1507
|
-
}
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1418
|
+
}
|
|
1419
|
+
ftruncate(fd, a, b) {
|
|
1420
|
+
const len = typeof a === 'number' ? a : 0;
|
|
1421
|
+
const callback = validateCallback(typeof a === 'number' ? b : a);
|
|
1511
1422
|
this.wrapAsync(this.ftruncateBase, [fd, len], callback);
|
|
1512
|
-
}
|
|
1513
|
-
|
|
1514
|
-
|
|
1423
|
+
}
|
|
1424
|
+
truncateBase(path, len) {
|
|
1425
|
+
const fd = this.openSync(path, 'r+');
|
|
1515
1426
|
try {
|
|
1516
1427
|
this.ftruncateSync(fd, len);
|
|
1517
1428
|
}
|
|
1518
1429
|
finally {
|
|
1519
1430
|
this.closeSync(fd);
|
|
1520
1431
|
}
|
|
1521
|
-
}
|
|
1522
|
-
|
|
1432
|
+
}
|
|
1433
|
+
truncateSync(id, len) {
|
|
1523
1434
|
if (isFd(id))
|
|
1524
1435
|
return this.ftruncateSync(id, len);
|
|
1525
1436
|
this.truncateBase(id, len);
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1437
|
+
}
|
|
1438
|
+
truncate(id, a, b) {
|
|
1439
|
+
const len = typeof a === 'number' ? a : 0;
|
|
1440
|
+
const callback = validateCallback(typeof a === 'number' ? b : a);
|
|
1530
1441
|
if (isFd(id))
|
|
1531
1442
|
return this.ftruncate(id, len, callback);
|
|
1532
1443
|
this.wrapAsync(this.truncateBase, [id, len], callback);
|
|
1533
|
-
}
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1444
|
+
}
|
|
1445
|
+
futimesBase(fd, atime, mtime) {
|
|
1446
|
+
const file = this.getFileByFdOrThrow(fd, 'futimes');
|
|
1447
|
+
const node = file.node;
|
|
1537
1448
|
node.atime = new Date(atime * 1000);
|
|
1538
1449
|
node.mtime = new Date(mtime * 1000);
|
|
1539
|
-
}
|
|
1540
|
-
|
|
1450
|
+
}
|
|
1451
|
+
futimesSync(fd, atime, mtime) {
|
|
1541
1452
|
this.futimesBase(fd, toUnixTimestamp(atime), toUnixTimestamp(mtime));
|
|
1542
|
-
}
|
|
1543
|
-
|
|
1453
|
+
}
|
|
1454
|
+
futimes(fd, atime, mtime, callback) {
|
|
1544
1455
|
this.wrapAsync(this.futimesBase, [fd, toUnixTimestamp(atime), toUnixTimestamp(mtime)], callback);
|
|
1545
|
-
}
|
|
1546
|
-
|
|
1547
|
-
|
|
1456
|
+
}
|
|
1457
|
+
utimesBase(filename, atime, mtime) {
|
|
1458
|
+
const fd = this.openSync(filename, 'r');
|
|
1548
1459
|
try {
|
|
1549
1460
|
this.futimesBase(fd, atime, mtime);
|
|
1550
1461
|
}
|
|
1551
1462
|
finally {
|
|
1552
1463
|
this.closeSync(fd);
|
|
1553
1464
|
}
|
|
1554
|
-
}
|
|
1555
|
-
|
|
1465
|
+
}
|
|
1466
|
+
utimesSync(path, atime, mtime) {
|
|
1556
1467
|
this.utimesBase(pathToFilename(path), toUnixTimestamp(atime), toUnixTimestamp(mtime));
|
|
1557
|
-
}
|
|
1558
|
-
|
|
1468
|
+
}
|
|
1469
|
+
utimes(path, atime, mtime, callback) {
|
|
1559
1470
|
this.wrapAsync(this.utimesBase, [pathToFilename(path), toUnixTimestamp(atime), toUnixTimestamp(mtime)], callback);
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
|
|
1471
|
+
}
|
|
1472
|
+
mkdirBase(filename, modeNum) {
|
|
1473
|
+
const steps = filenameToSteps(filename);
|
|
1563
1474
|
// This will throw if user tries to create root dir `fs.mkdirSync('/')`.
|
|
1564
1475
|
if (!steps.length) {
|
|
1565
1476
|
throw createError(EEXIST, 'mkdir', filename);
|
|
1566
1477
|
}
|
|
1567
|
-
|
|
1478
|
+
const dir = this.getLinkParentAsDirOrThrow(filename, 'mkdir');
|
|
1568
1479
|
// Check path already exists.
|
|
1569
|
-
|
|
1480
|
+
const name = steps[steps.length - 1];
|
|
1570
1481
|
if (dir.getChild(name))
|
|
1571
1482
|
throw createError(EEXIST, 'mkdir', filename);
|
|
1572
1483
|
dir.createChild(name, this.createNode(true, modeNum));
|
|
1573
|
-
}
|
|
1484
|
+
}
|
|
1574
1485
|
/**
|
|
1575
1486
|
* Creates directory tree recursively.
|
|
1576
1487
|
* @param filename
|
|
1577
1488
|
* @param modeNum
|
|
1578
1489
|
*/
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
for (
|
|
1586
|
-
|
|
1490
|
+
mkdirpBase(filename, modeNum) {
|
|
1491
|
+
const fullPath = resolve(filename);
|
|
1492
|
+
const fullPathSansSlash = fullPath.substring(1);
|
|
1493
|
+
const steps = !fullPathSansSlash ? [] : fullPathSansSlash.split(sep);
|
|
1494
|
+
let link = this.root;
|
|
1495
|
+
let created = false;
|
|
1496
|
+
for (let i = 0; i < steps.length; i++) {
|
|
1497
|
+
const step = steps[i];
|
|
1587
1498
|
if (!link.getNode().isDirectory())
|
|
1588
1499
|
throw createError(ENOTDIR, 'mkdir', link.getPath());
|
|
1589
|
-
|
|
1500
|
+
const child = link.getChild(step);
|
|
1590
1501
|
if (child) {
|
|
1591
1502
|
if (child.getNode().isDirectory())
|
|
1592
1503
|
link = child;
|
|
@@ -1599,37 +1510,36 @@ var Volume = /** @class */ (function () {
|
|
|
1599
1510
|
}
|
|
1600
1511
|
}
|
|
1601
1512
|
return created ? fullPath : undefined;
|
|
1602
|
-
}
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1513
|
+
}
|
|
1514
|
+
mkdirSync(path, options) {
|
|
1515
|
+
const opts = getMkdirOptions(options);
|
|
1516
|
+
const modeNum = modeToNumber(opts.mode, 0o777);
|
|
1517
|
+
const filename = pathToFilename(path);
|
|
1607
1518
|
if (opts.recursive)
|
|
1608
1519
|
return this.mkdirpBase(filename, modeNum);
|
|
1609
1520
|
this.mkdirBase(filename, modeNum);
|
|
1610
|
-
}
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1521
|
+
}
|
|
1522
|
+
mkdir(path, a, b) {
|
|
1523
|
+
const opts = getMkdirOptions(a);
|
|
1524
|
+
const callback = validateCallback(typeof a === 'function' ? a : b);
|
|
1525
|
+
const modeNum = modeToNumber(opts.mode, 0o777);
|
|
1526
|
+
const filename = pathToFilename(path);
|
|
1616
1527
|
if (opts.recursive)
|
|
1617
1528
|
this.wrapAsync(this.mkdirpBase, [filename, modeNum], callback);
|
|
1618
1529
|
else
|
|
1619
1530
|
this.wrapAsync(this.mkdirBase, [filename, modeNum], callback);
|
|
1620
|
-
}
|
|
1531
|
+
}
|
|
1621
1532
|
// legacy interface
|
|
1622
|
-
|
|
1623
|
-
return this.mkdirSync(path, { mode
|
|
1624
|
-
}
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
this.mkdir(path, { mode
|
|
1629
|
-
}
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
var filename = prefix + this.genRndStr();
|
|
1533
|
+
mkdirpSync(path, mode) {
|
|
1534
|
+
return this.mkdirSync(path, { mode, recursive: true });
|
|
1535
|
+
}
|
|
1536
|
+
mkdirp(path, a, b) {
|
|
1537
|
+
const mode = typeof a === 'function' ? undefined : a;
|
|
1538
|
+
const callback = validateCallback(typeof a === 'function' ? a : b);
|
|
1539
|
+
this.mkdir(path, { mode, recursive: true }, callback);
|
|
1540
|
+
}
|
|
1541
|
+
mkdtempBase(prefix, encoding, retry = 5) {
|
|
1542
|
+
const filename = prefix + this.genRndStr();
|
|
1633
1543
|
try {
|
|
1634
1544
|
this.mkdirBase(filename, 511 /* MODE.DIR */);
|
|
1635
1545
|
return (0, encoding_1.strToEncoding)(filename, encoding);
|
|
@@ -1644,41 +1554,40 @@ var Volume = /** @class */ (function () {
|
|
|
1644
1554
|
else
|
|
1645
1555
|
throw err;
|
|
1646
1556
|
}
|
|
1647
|
-
}
|
|
1648
|
-
|
|
1649
|
-
|
|
1557
|
+
}
|
|
1558
|
+
mkdtempSync(prefix, options) {
|
|
1559
|
+
const { encoding } = getDefaultOpts(options);
|
|
1650
1560
|
if (!prefix || typeof prefix !== 'string')
|
|
1651
1561
|
throw new TypeError('filename prefix is required');
|
|
1652
1562
|
nullCheck(prefix);
|
|
1653
1563
|
return this.mkdtempBase(prefix, encoding);
|
|
1654
|
-
}
|
|
1655
|
-
|
|
1656
|
-
|
|
1564
|
+
}
|
|
1565
|
+
mkdtemp(prefix, a, b) {
|
|
1566
|
+
const [{ encoding }, callback] = getDefaultOptsAndCb(a, b);
|
|
1657
1567
|
if (!prefix || typeof prefix !== 'string')
|
|
1658
1568
|
throw new TypeError('filename prefix is required');
|
|
1659
1569
|
if (!nullCheck(prefix))
|
|
1660
1570
|
return;
|
|
1661
1571
|
this.wrapAsync(this.mkdtempBase, [prefix, encoding], callback);
|
|
1662
|
-
}
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1572
|
+
}
|
|
1573
|
+
rmdirBase(filename, options) {
|
|
1574
|
+
const opts = getRmdirOptions(options);
|
|
1575
|
+
const link = this.getLinkAsDirOrThrow(filename, 'rmdir');
|
|
1666
1576
|
// Check directory is empty.
|
|
1667
1577
|
if (link.length && !opts.recursive)
|
|
1668
1578
|
throw createError(ENOTEMPTY, 'rmdir', filename);
|
|
1669
1579
|
this.deleteLink(link);
|
|
1670
|
-
}
|
|
1671
|
-
|
|
1580
|
+
}
|
|
1581
|
+
rmdirSync(path, options) {
|
|
1672
1582
|
this.rmdirBase(pathToFilename(path), options);
|
|
1673
|
-
}
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1583
|
+
}
|
|
1584
|
+
rmdir(path, a, b) {
|
|
1585
|
+
const opts = getRmdirOptions(a);
|
|
1586
|
+
const callback = validateCallback(typeof a === 'function' ? a : b);
|
|
1677
1587
|
this.wrapAsync(this.rmdirBase, [pathToFilename(path), opts], callback);
|
|
1678
|
-
}
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
var link = this.getResolvedLink(filename);
|
|
1588
|
+
}
|
|
1589
|
+
rmBase(filename, options = {}) {
|
|
1590
|
+
const link = this.getResolvedLink(filename);
|
|
1682
1591
|
if (!link) {
|
|
1683
1592
|
// "stat" is used to match Node's native error message.
|
|
1684
1593
|
if (!options.force)
|
|
@@ -1691,78 +1600,78 @@ var Volume = /** @class */ (function () {
|
|
|
1691
1600
|
}
|
|
1692
1601
|
}
|
|
1693
1602
|
this.deleteLink(link);
|
|
1694
|
-
}
|
|
1695
|
-
|
|
1603
|
+
}
|
|
1604
|
+
rmSync(path, options) {
|
|
1696
1605
|
this.rmBase(pathToFilename(path), options);
|
|
1697
|
-
}
|
|
1698
|
-
|
|
1699
|
-
|
|
1606
|
+
}
|
|
1607
|
+
rm(path, a, b) {
|
|
1608
|
+
const [opts, callback] = getRmOptsAndCb(a, b);
|
|
1700
1609
|
this.wrapAsync(this.rmBase, [pathToFilename(path), opts], callback);
|
|
1701
|
-
}
|
|
1702
|
-
|
|
1703
|
-
|
|
1610
|
+
}
|
|
1611
|
+
fchmodBase(fd, modeNum) {
|
|
1612
|
+
const file = this.getFileByFdOrThrow(fd, 'fchmod');
|
|
1704
1613
|
file.chmod(modeNum);
|
|
1705
|
-
}
|
|
1706
|
-
|
|
1614
|
+
}
|
|
1615
|
+
fchmodSync(fd, mode) {
|
|
1707
1616
|
this.fchmodBase(fd, modeToNumber(mode));
|
|
1708
|
-
}
|
|
1709
|
-
|
|
1617
|
+
}
|
|
1618
|
+
fchmod(fd, mode, callback) {
|
|
1710
1619
|
this.wrapAsync(this.fchmodBase, [fd, modeToNumber(mode)], callback);
|
|
1711
|
-
}
|
|
1712
|
-
|
|
1713
|
-
|
|
1620
|
+
}
|
|
1621
|
+
chmodBase(filename, modeNum) {
|
|
1622
|
+
const fd = this.openSync(filename, 'r');
|
|
1714
1623
|
try {
|
|
1715
1624
|
this.fchmodBase(fd, modeNum);
|
|
1716
1625
|
}
|
|
1717
1626
|
finally {
|
|
1718
1627
|
this.closeSync(fd);
|
|
1719
1628
|
}
|
|
1720
|
-
}
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1629
|
+
}
|
|
1630
|
+
chmodSync(path, mode) {
|
|
1631
|
+
const modeNum = modeToNumber(mode);
|
|
1632
|
+
const filename = pathToFilename(path);
|
|
1724
1633
|
this.chmodBase(filename, modeNum);
|
|
1725
|
-
}
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1634
|
+
}
|
|
1635
|
+
chmod(path, mode, callback) {
|
|
1636
|
+
const modeNum = modeToNumber(mode);
|
|
1637
|
+
const filename = pathToFilename(path);
|
|
1729
1638
|
this.wrapAsync(this.chmodBase, [filename, modeNum], callback);
|
|
1730
|
-
}
|
|
1731
|
-
|
|
1732
|
-
|
|
1639
|
+
}
|
|
1640
|
+
lchmodBase(filename, modeNum) {
|
|
1641
|
+
const fd = this.openBase(filename, O_RDWR, 0, false);
|
|
1733
1642
|
try {
|
|
1734
1643
|
this.fchmodBase(fd, modeNum);
|
|
1735
1644
|
}
|
|
1736
1645
|
finally {
|
|
1737
1646
|
this.closeSync(fd);
|
|
1738
1647
|
}
|
|
1739
|
-
}
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1648
|
+
}
|
|
1649
|
+
lchmodSync(path, mode) {
|
|
1650
|
+
const modeNum = modeToNumber(mode);
|
|
1651
|
+
const filename = pathToFilename(path);
|
|
1743
1652
|
this.lchmodBase(filename, modeNum);
|
|
1744
|
-
}
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1653
|
+
}
|
|
1654
|
+
lchmod(path, mode, callback) {
|
|
1655
|
+
const modeNum = modeToNumber(mode);
|
|
1656
|
+
const filename = pathToFilename(path);
|
|
1748
1657
|
this.wrapAsync(this.lchmodBase, [filename, modeNum], callback);
|
|
1749
|
-
}
|
|
1750
|
-
|
|
1658
|
+
}
|
|
1659
|
+
fchownBase(fd, uid, gid) {
|
|
1751
1660
|
this.getFileByFdOrThrow(fd, 'fchown').chown(uid, gid);
|
|
1752
|
-
}
|
|
1753
|
-
|
|
1661
|
+
}
|
|
1662
|
+
fchownSync(fd, uid, gid) {
|
|
1754
1663
|
validateUid(uid);
|
|
1755
1664
|
validateGid(gid);
|
|
1756
1665
|
this.fchownBase(fd, uid, gid);
|
|
1757
|
-
}
|
|
1758
|
-
|
|
1666
|
+
}
|
|
1667
|
+
fchown(fd, uid, gid, callback) {
|
|
1759
1668
|
validateUid(uid);
|
|
1760
1669
|
validateGid(gid);
|
|
1761
1670
|
this.wrapAsync(this.fchownBase, [fd, uid, gid], callback);
|
|
1762
|
-
}
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1671
|
+
}
|
|
1672
|
+
chownBase(filename, uid, gid) {
|
|
1673
|
+
const link = this.getResolvedLinkOrThrow(filename, 'chown');
|
|
1674
|
+
const node = link.getNode();
|
|
1766
1675
|
node.chown(uid, gid);
|
|
1767
1676
|
// if(node.isFile() || node.isSymlink()) {
|
|
1768
1677
|
//
|
|
@@ -1771,34 +1680,34 @@ var Volume = /** @class */ (function () {
|
|
|
1771
1680
|
// } else {
|
|
1772
1681
|
// TODO: What do we do here?
|
|
1773
1682
|
// }
|
|
1774
|
-
}
|
|
1775
|
-
|
|
1683
|
+
}
|
|
1684
|
+
chownSync(path, uid, gid) {
|
|
1776
1685
|
validateUid(uid);
|
|
1777
1686
|
validateGid(gid);
|
|
1778
1687
|
this.chownBase(pathToFilename(path), uid, gid);
|
|
1779
|
-
}
|
|
1780
|
-
|
|
1688
|
+
}
|
|
1689
|
+
chown(path, uid, gid, callback) {
|
|
1781
1690
|
validateUid(uid);
|
|
1782
1691
|
validateGid(gid);
|
|
1783
1692
|
this.wrapAsync(this.chownBase, [pathToFilename(path), uid, gid], callback);
|
|
1784
|
-
}
|
|
1785
|
-
|
|
1693
|
+
}
|
|
1694
|
+
lchownBase(filename, uid, gid) {
|
|
1786
1695
|
this.getLinkOrThrow(filename, 'lchown').getNode().chown(uid, gid);
|
|
1787
|
-
}
|
|
1788
|
-
|
|
1696
|
+
}
|
|
1697
|
+
lchownSync(path, uid, gid) {
|
|
1789
1698
|
validateUid(uid);
|
|
1790
1699
|
validateGid(gid);
|
|
1791
1700
|
this.lchownBase(pathToFilename(path), uid, gid);
|
|
1792
|
-
}
|
|
1793
|
-
|
|
1701
|
+
}
|
|
1702
|
+
lchown(path, uid, gid, callback) {
|
|
1794
1703
|
validateUid(uid);
|
|
1795
1704
|
validateGid(gid);
|
|
1796
1705
|
this.wrapAsync(this.lchownBase, [pathToFilename(path), uid, gid], callback);
|
|
1797
|
-
}
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1706
|
+
}
|
|
1707
|
+
watchFile(path, a, b) {
|
|
1708
|
+
const filename = pathToFilename(path);
|
|
1709
|
+
let options = a;
|
|
1710
|
+
let listener = b;
|
|
1802
1711
|
if (typeof options === 'function') {
|
|
1803
1712
|
listener = a;
|
|
1804
1713
|
options = null;
|
|
@@ -1806,15 +1715,15 @@ var Volume = /** @class */ (function () {
|
|
|
1806
1715
|
if (typeof listener !== 'function') {
|
|
1807
1716
|
throw Error('"watchFile()" requires a listener function');
|
|
1808
1717
|
}
|
|
1809
|
-
|
|
1810
|
-
|
|
1718
|
+
let interval = 5007;
|
|
1719
|
+
let persistent = true;
|
|
1811
1720
|
if (options && typeof options === 'object') {
|
|
1812
1721
|
if (typeof options.interval === 'number')
|
|
1813
1722
|
interval = options.interval;
|
|
1814
1723
|
if (typeof options.persistent === 'boolean')
|
|
1815
1724
|
persistent = options.persistent;
|
|
1816
1725
|
}
|
|
1817
|
-
|
|
1726
|
+
let watcher = this.statWatchers[filename];
|
|
1818
1727
|
if (!watcher) {
|
|
1819
1728
|
watcher = new this.StatWatcher();
|
|
1820
1729
|
watcher.start(filename, persistent, interval);
|
|
@@ -1822,10 +1731,10 @@ var Volume = /** @class */ (function () {
|
|
|
1822
1731
|
}
|
|
1823
1732
|
watcher.addListener('change', listener);
|
|
1824
1733
|
return watcher;
|
|
1825
|
-
}
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1734
|
+
}
|
|
1735
|
+
unwatchFile(path, listener) {
|
|
1736
|
+
const filename = pathToFilename(path);
|
|
1737
|
+
const watcher = this.statWatchers[filename];
|
|
1829
1738
|
if (!watcher)
|
|
1830
1739
|
return;
|
|
1831
1740
|
if (typeof listener === 'function') {
|
|
@@ -1838,82 +1747,77 @@ var Volume = /** @class */ (function () {
|
|
|
1838
1747
|
watcher.stop();
|
|
1839
1748
|
delete this.statWatchers[filename];
|
|
1840
1749
|
}
|
|
1841
|
-
}
|
|
1842
|
-
|
|
1750
|
+
}
|
|
1751
|
+
createReadStream(path, options) {
|
|
1843
1752
|
return new this.ReadStream(path, options);
|
|
1844
|
-
}
|
|
1845
|
-
|
|
1753
|
+
}
|
|
1754
|
+
createWriteStream(path, options) {
|
|
1846
1755
|
return new this.WriteStream(path, options);
|
|
1847
|
-
}
|
|
1756
|
+
}
|
|
1848
1757
|
// watch(path: PathLike): FSWatcher;
|
|
1849
1758
|
// watch(path: PathLike, options?: IWatchOptions | string): FSWatcher;
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1759
|
+
watch(path, options, listener) {
|
|
1760
|
+
const filename = pathToFilename(path);
|
|
1761
|
+
let givenOptions = options;
|
|
1853
1762
|
if (typeof options === 'function') {
|
|
1854
1763
|
listener = options;
|
|
1855
1764
|
givenOptions = null;
|
|
1856
1765
|
}
|
|
1857
1766
|
// tslint:disable-next-line prefer-const
|
|
1858
|
-
|
|
1767
|
+
let { persistent, recursive, encoding } = getDefaultOpts(givenOptions);
|
|
1859
1768
|
if (persistent === undefined)
|
|
1860
1769
|
persistent = true;
|
|
1861
1770
|
if (recursive === undefined)
|
|
1862
1771
|
recursive = false;
|
|
1863
|
-
|
|
1772
|
+
const watcher = new this.FSWatcher();
|
|
1864
1773
|
watcher.start(filename, persistent, recursive, encoding);
|
|
1865
1774
|
if (listener) {
|
|
1866
1775
|
watcher.addListener('change', listener);
|
|
1867
1776
|
}
|
|
1868
1777
|
return watcher;
|
|
1869
|
-
}
|
|
1870
|
-
|
|
1871
|
-
* Global file descriptor counter. UNIX file descriptors start from 0 and go sequentially
|
|
1872
|
-
* up, so here, in order not to conflict with them, we choose some big number and descrease
|
|
1873
|
-
* the file descriptor of every new opened file.
|
|
1874
|
-
* @type {number}
|
|
1875
|
-
* @todo This should not be static, right?
|
|
1876
|
-
*/
|
|
1877
|
-
Volume.fd = 0x7fffffff;
|
|
1878
|
-
return Volume;
|
|
1879
|
-
}());
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1880
1780
|
exports.Volume = Volume;
|
|
1781
|
+
/**
|
|
1782
|
+
* Global file descriptor counter. UNIX file descriptors start from 0 and go sequentially
|
|
1783
|
+
* up, so here, in order not to conflict with them, we choose some big number and descrease
|
|
1784
|
+
* the file descriptor of every new opened file.
|
|
1785
|
+
* @type {number}
|
|
1786
|
+
* @todo This should not be static, right?
|
|
1787
|
+
*/
|
|
1788
|
+
Volume.fd = 0x7fffffff;
|
|
1881
1789
|
function emitStop(self) {
|
|
1882
1790
|
self.emit('stop');
|
|
1883
1791
|
}
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
_this.onInterval = function () {
|
|
1792
|
+
class StatWatcher extends events_1.EventEmitter {
|
|
1793
|
+
constructor(vol) {
|
|
1794
|
+
super();
|
|
1795
|
+
this.onInterval = () => {
|
|
1889
1796
|
try {
|
|
1890
|
-
|
|
1891
|
-
if (
|
|
1892
|
-
|
|
1893
|
-
|
|
1797
|
+
const stats = this.vol.statSync(this.filename);
|
|
1798
|
+
if (this.hasChanged(stats)) {
|
|
1799
|
+
this.emit('change', stats, this.prev);
|
|
1800
|
+
this.prev = stats;
|
|
1894
1801
|
}
|
|
1895
1802
|
}
|
|
1896
1803
|
finally {
|
|
1897
|
-
|
|
1804
|
+
this.loop();
|
|
1898
1805
|
}
|
|
1899
1806
|
};
|
|
1900
|
-
|
|
1901
|
-
return _this;
|
|
1807
|
+
this.vol = vol;
|
|
1902
1808
|
}
|
|
1903
|
-
|
|
1809
|
+
loop() {
|
|
1904
1810
|
this.timeoutRef = this.setTimeout(this.onInterval, this.interval);
|
|
1905
|
-
}
|
|
1906
|
-
|
|
1811
|
+
}
|
|
1812
|
+
hasChanged(stats) {
|
|
1907
1813
|
// if(!this.prev) return false;
|
|
1908
1814
|
if (stats.mtimeMs > this.prev.mtimeMs)
|
|
1909
1815
|
return true;
|
|
1910
1816
|
if (stats.nlink !== this.prev.nlink)
|
|
1911
1817
|
return true;
|
|
1912
1818
|
return false;
|
|
1913
|
-
}
|
|
1914
|
-
|
|
1915
|
-
if (persistent === void 0) { persistent = true; }
|
|
1916
|
-
if (interval === void 0) { interval = 5007; }
|
|
1819
|
+
}
|
|
1820
|
+
start(path, persistent = true, interval = 5007) {
|
|
1917
1821
|
this.filename = pathToFilename(path);
|
|
1918
1822
|
this.setTimeout = persistent
|
|
1919
1823
|
? setTimeout.bind(typeof globalThis !== 'undefined' ? globalThis : global)
|
|
@@ -1921,13 +1825,12 @@ var StatWatcher = /** @class */ (function (_super) {
|
|
|
1921
1825
|
this.interval = interval;
|
|
1922
1826
|
this.prev = this.vol.statSync(this.filename);
|
|
1923
1827
|
this.loop();
|
|
1924
|
-
}
|
|
1925
|
-
|
|
1828
|
+
}
|
|
1829
|
+
stop() {
|
|
1926
1830
|
clearTimeout(this.timeoutRef);
|
|
1927
1831
|
process_1.default.nextTick(emitStop, this);
|
|
1928
|
-
}
|
|
1929
|
-
|
|
1930
|
-
}(events_1.EventEmitter));
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1931
1834
|
exports.StatWatcher = StatWatcher;
|
|
1932
1835
|
var pool;
|
|
1933
1836
|
function allocNewPool(poolSize) {
|
|
@@ -1948,7 +1851,7 @@ function FsReadStream(vol, path, options) {
|
|
|
1948
1851
|
this.path = pathToFilename(path);
|
|
1949
1852
|
this.fd = options.fd === undefined ? null : options.fd;
|
|
1950
1853
|
this.flags = options.flags === undefined ? 'r' : options.flags;
|
|
1951
|
-
this.mode = options.mode === undefined ?
|
|
1854
|
+
this.mode = options.mode === undefined ? 0o666 : options.mode;
|
|
1952
1855
|
this.start = options.start;
|
|
1953
1856
|
this.end = options.end;
|
|
1954
1857
|
this.autoClose = options.autoClose === undefined ? true : options.autoClose;
|
|
@@ -1980,7 +1883,7 @@ function FsReadStream(vol, path, options) {
|
|
|
1980
1883
|
}
|
|
1981
1884
|
FsReadStream.prototype.open = function () {
|
|
1982
1885
|
var self = this; // tslint:disable-line no-this-assignment
|
|
1983
|
-
this._vol.open(this.path, this.flags, this.mode,
|
|
1886
|
+
this._vol.open(this.path, this.flags, this.mode, (er, fd) => {
|
|
1984
1887
|
if (er) {
|
|
1985
1888
|
if (self.autoClose) {
|
|
1986
1889
|
if (self.destroy)
|
|
@@ -2044,12 +1947,11 @@ FsReadStream.prototype._read = function (n) {
|
|
|
2044
1947
|
}
|
|
2045
1948
|
};
|
|
2046
1949
|
FsReadStream.prototype._destroy = function (err, cb) {
|
|
2047
|
-
this.close(
|
|
1950
|
+
this.close(err2 => {
|
|
2048
1951
|
cb(err || err2);
|
|
2049
1952
|
});
|
|
2050
1953
|
};
|
|
2051
1954
|
FsReadStream.prototype.close = function (cb) {
|
|
2052
|
-
var _this = this;
|
|
2053
1955
|
var _a;
|
|
2054
1956
|
if (cb)
|
|
2055
1957
|
this.once('close', cb);
|
|
@@ -2058,7 +1960,7 @@ FsReadStream.prototype.close = function (cb) {
|
|
|
2058
1960
|
this.once('open', closeOnOpen);
|
|
2059
1961
|
return;
|
|
2060
1962
|
}
|
|
2061
|
-
return process_1.default.nextTick(
|
|
1963
|
+
return process_1.default.nextTick(() => this.emit('close'));
|
|
2062
1964
|
}
|
|
2063
1965
|
// Since Node 18, there is only a getter for '.closed'.
|
|
2064
1966
|
// The first branch mimics other setters from Readable.
|
|
@@ -2069,11 +1971,11 @@ FsReadStream.prototype.close = function (cb) {
|
|
|
2069
1971
|
else {
|
|
2070
1972
|
this.closed = true;
|
|
2071
1973
|
}
|
|
2072
|
-
this._vol.close(this.fd,
|
|
1974
|
+
this._vol.close(this.fd, er => {
|
|
2073
1975
|
if (er)
|
|
2074
|
-
|
|
1976
|
+
this.emit('error', er);
|
|
2075
1977
|
else
|
|
2076
|
-
|
|
1978
|
+
this.emit('close');
|
|
2077
1979
|
});
|
|
2078
1980
|
this.fd = null;
|
|
2079
1981
|
};
|
|
@@ -2093,7 +1995,7 @@ function FsWriteStream(vol, path, options) {
|
|
|
2093
1995
|
this.path = pathToFilename(path);
|
|
2094
1996
|
this.fd = options.fd === undefined ? null : options.fd;
|
|
2095
1997
|
this.flags = options.flags === undefined ? 'w' : options.flags;
|
|
2096
|
-
this.mode = options.mode === undefined ?
|
|
1998
|
+
this.mode = options.mode === undefined ? 0o666 : options.mode;
|
|
2097
1999
|
this.start = options.start;
|
|
2098
2000
|
this.autoClose = options.autoClose === undefined ? true : !!options.autoClose;
|
|
2099
2001
|
this.pos = undefined;
|
|
@@ -2140,7 +2042,7 @@ FsWriteStream.prototype._write = function (data, encoding, cb) {
|
|
|
2140
2042
|
});
|
|
2141
2043
|
}
|
|
2142
2044
|
var self = this; // tslint:disable-line no-this-assignment
|
|
2143
|
-
this._vol.write(this.fd, data, 0, data.length, this.pos,
|
|
2045
|
+
this._vol.write(this.fd, data, 0, data.length, this.pos, (er, bytes) => {
|
|
2144
2046
|
if (er) {
|
|
2145
2047
|
if (self.autoClose && self.destroy) {
|
|
2146
2048
|
self.destroy();
|
|
@@ -2159,17 +2061,17 @@ FsWriteStream.prototype._writev = function (data, cb) {
|
|
|
2159
2061
|
this._writev(data, cb);
|
|
2160
2062
|
});
|
|
2161
2063
|
}
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2064
|
+
const self = this; // tslint:disable-line no-this-assignment
|
|
2065
|
+
const len = data.length;
|
|
2066
|
+
const chunks = new Array(len);
|
|
2165
2067
|
var size = 0;
|
|
2166
2068
|
for (var i = 0; i < len; i++) {
|
|
2167
2069
|
var chunk = data[i].chunk;
|
|
2168
2070
|
chunks[i] = chunk;
|
|
2169
2071
|
size += chunk.length;
|
|
2170
2072
|
}
|
|
2171
|
-
|
|
2172
|
-
this._vol.write(this.fd, buf, 0, buf.length, this.pos,
|
|
2073
|
+
const buf = buffer_1.Buffer.concat(chunks);
|
|
2074
|
+
this._vol.write(this.fd, buf, 0, buf.length, this.pos, (er, bytes) => {
|
|
2173
2075
|
if (er) {
|
|
2174
2076
|
if (self.destroy)
|
|
2175
2077
|
self.destroy();
|
|
@@ -2182,7 +2084,6 @@ FsWriteStream.prototype._writev = function (data, cb) {
|
|
|
2182
2084
|
this.pos += size;
|
|
2183
2085
|
};
|
|
2184
2086
|
FsWriteStream.prototype.close = function (cb) {
|
|
2185
|
-
var _this = this;
|
|
2186
2087
|
var _a;
|
|
2187
2088
|
if (cb)
|
|
2188
2089
|
this.once('close', cb);
|
|
@@ -2191,7 +2092,7 @@ FsWriteStream.prototype.close = function (cb) {
|
|
|
2191
2092
|
this.once('open', closeOnOpen);
|
|
2192
2093
|
return;
|
|
2193
2094
|
}
|
|
2194
|
-
return process_1.default.nextTick(
|
|
2095
|
+
return process_1.default.nextTick(() => this.emit('close'));
|
|
2195
2096
|
}
|
|
2196
2097
|
// Since Node 18, there is only a getter for '.closed'.
|
|
2197
2098
|
// The first branch mimics other setters from Writable.
|
|
@@ -2202,11 +2103,11 @@ FsWriteStream.prototype.close = function (cb) {
|
|
|
2202
2103
|
else {
|
|
2203
2104
|
this.closed = true;
|
|
2204
2105
|
}
|
|
2205
|
-
this._vol.close(this.fd,
|
|
2106
|
+
this._vol.close(this.fd, er => {
|
|
2206
2107
|
if (er)
|
|
2207
|
-
|
|
2108
|
+
this.emit('error', er);
|
|
2208
2109
|
else
|
|
2209
|
-
|
|
2110
|
+
this.emit('close');
|
|
2210
2111
|
});
|
|
2211
2112
|
this.fd = null;
|
|
2212
2113
|
};
|
|
@@ -2214,30 +2115,28 @@ FsWriteStream.prototype._destroy = FsReadStream.prototype._destroy;
|
|
|
2214
2115
|
// There is no shutdown() for files.
|
|
2215
2116
|
FsWriteStream.prototype.destroySoon = FsWriteStream.prototype.end;
|
|
2216
2117
|
// ---------------------------------------- FSWatcher
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
_this._filenameEncoded = '';
|
|
2118
|
+
class FSWatcher extends events_1.EventEmitter {
|
|
2119
|
+
constructor(vol) {
|
|
2120
|
+
super();
|
|
2121
|
+
this._filename = '';
|
|
2122
|
+
this._filenameEncoded = '';
|
|
2223
2123
|
// _persistent: boolean = true;
|
|
2224
|
-
|
|
2225
|
-
|
|
2124
|
+
this._recursive = false;
|
|
2125
|
+
this._encoding = encoding_1.ENCODING_UTF8;
|
|
2226
2126
|
// inode -> removers
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
if (link.getName() ===
|
|
2230
|
-
|
|
2127
|
+
this._listenerRemovers = new Map();
|
|
2128
|
+
this._onParentChild = (link) => {
|
|
2129
|
+
if (link.getName() === this._getName()) {
|
|
2130
|
+
this._emit('rename');
|
|
2231
2131
|
}
|
|
2232
2132
|
};
|
|
2233
|
-
|
|
2234
|
-
|
|
2133
|
+
this._emit = (type) => {
|
|
2134
|
+
this.emit('change', type, this._filenameEncoded);
|
|
2235
2135
|
};
|
|
2236
|
-
|
|
2237
|
-
|
|
2136
|
+
this._persist = () => {
|
|
2137
|
+
this._timer = setTimeout(this._persist, 1e6);
|
|
2238
2138
|
};
|
|
2239
|
-
|
|
2240
|
-
return _this;
|
|
2139
|
+
this._vol = vol;
|
|
2241
2140
|
// TODO: Emit "error" messages when watching.
|
|
2242
2141
|
// this._handle.onchange = function(status, eventType, filename) {
|
|
2243
2142
|
// if (status < 0) {
|
|
@@ -2252,14 +2151,10 @@ var FSWatcher = /** @class */ (function (_super) {
|
|
|
2252
2151
|
// }
|
|
2253
2152
|
// };
|
|
2254
2153
|
}
|
|
2255
|
-
|
|
2154
|
+
_getName() {
|
|
2256
2155
|
return this._steps[this._steps.length - 1];
|
|
2257
|
-
}
|
|
2258
|
-
|
|
2259
|
-
var _this = this;
|
|
2260
|
-
if (persistent === void 0) { persistent = true; }
|
|
2261
|
-
if (recursive === void 0) { recursive = false; }
|
|
2262
|
-
if (encoding === void 0) { encoding = encoding_1.ENCODING_UTF8; }
|
|
2156
|
+
}
|
|
2157
|
+
start(path, persistent = true, recursive = false, encoding = encoding_1.ENCODING_UTF8) {
|
|
2263
2158
|
this._filename = pathToFilename(path);
|
|
2264
2159
|
this._steps = filenameToSteps(this._filename);
|
|
2265
2160
|
this._filenameEncoded = (0, encoding_1.strToEncoding)(this._filename);
|
|
@@ -2270,34 +2165,34 @@ var FSWatcher = /** @class */ (function (_super) {
|
|
|
2270
2165
|
this._link = this._vol.getLinkOrThrow(this._filename, 'FSWatcher');
|
|
2271
2166
|
}
|
|
2272
2167
|
catch (err) {
|
|
2273
|
-
|
|
2168
|
+
const error = new Error(`watch ${this._filename} ${err.code}`);
|
|
2274
2169
|
error.code = err.code;
|
|
2275
2170
|
error.errno = err.code;
|
|
2276
2171
|
throw error;
|
|
2277
2172
|
}
|
|
2278
|
-
|
|
2173
|
+
const watchLinkNodeChanged = (link) => {
|
|
2279
2174
|
var _a;
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2175
|
+
const filepath = link.getPath();
|
|
2176
|
+
const node = link.getNode();
|
|
2177
|
+
const onNodeChange = () => {
|
|
2178
|
+
let filename = relative(this._filename, filepath);
|
|
2284
2179
|
if (!filename) {
|
|
2285
|
-
filename =
|
|
2180
|
+
filename = this._getName();
|
|
2286
2181
|
}
|
|
2287
|
-
return
|
|
2182
|
+
return this.emit('change', 'change', filename);
|
|
2288
2183
|
};
|
|
2289
2184
|
node.on('change', onNodeChange);
|
|
2290
|
-
|
|
2291
|
-
removers.push(
|
|
2292
|
-
|
|
2185
|
+
const removers = (_a = this._listenerRemovers.get(node.ino)) !== null && _a !== void 0 ? _a : [];
|
|
2186
|
+
removers.push(() => node.removeListener('change', onNodeChange));
|
|
2187
|
+
this._listenerRemovers.set(node.ino, removers);
|
|
2293
2188
|
};
|
|
2294
|
-
|
|
2189
|
+
const watchLinkChildrenChanged = (link) => {
|
|
2295
2190
|
var _a;
|
|
2296
|
-
|
|
2191
|
+
const node = link.getNode();
|
|
2297
2192
|
// when a new link added
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
setTimeout(
|
|
2193
|
+
const onLinkChildAdd = (l) => {
|
|
2194
|
+
this.emit('change', 'rename', relative(this._filename, l.getPath()));
|
|
2195
|
+
setTimeout(() => {
|
|
2301
2196
|
// 1. watch changes of the new link-node
|
|
2302
2197
|
watchLinkNodeChanged(l);
|
|
2303
2198
|
// 2. watch changes of the new link-node's children
|
|
@@ -2305,27 +2200,26 @@ var FSWatcher = /** @class */ (function (_super) {
|
|
|
2305
2200
|
});
|
|
2306
2201
|
};
|
|
2307
2202
|
// when a new link deleted
|
|
2308
|
-
|
|
2203
|
+
const onLinkChildDelete = (l) => {
|
|
2309
2204
|
// remove the listeners of the children nodes
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2205
|
+
const removeLinkNodeListeners = (curLink) => {
|
|
2206
|
+
const ino = curLink.getNode().ino;
|
|
2207
|
+
const removers = this._listenerRemovers.get(ino);
|
|
2313
2208
|
if (removers) {
|
|
2314
|
-
removers.forEach(
|
|
2315
|
-
|
|
2209
|
+
removers.forEach(r => r());
|
|
2210
|
+
this._listenerRemovers.delete(ino);
|
|
2316
2211
|
}
|
|
2317
|
-
Object.values(curLink.children).forEach(
|
|
2212
|
+
Object.values(curLink.children).forEach(childLink => {
|
|
2318
2213
|
if (childLink) {
|
|
2319
2214
|
removeLinkNodeListeners(childLink);
|
|
2320
2215
|
}
|
|
2321
2216
|
});
|
|
2322
2217
|
};
|
|
2323
2218
|
removeLinkNodeListeners(l);
|
|
2324
|
-
|
|
2219
|
+
this.emit('change', 'rename', relative(this._filename, l.getPath()));
|
|
2325
2220
|
};
|
|
2326
2221
|
// children nodes changed
|
|
2327
|
-
Object.entries(link.children).forEach(
|
|
2328
|
-
var name = _a[0], childLink = _a[1];
|
|
2222
|
+
Object.entries(link.children).forEach(([name, childLink]) => {
|
|
2329
2223
|
if (childLink && name !== '.' && name !== '..') {
|
|
2330
2224
|
watchLinkNodeChanged(childLink);
|
|
2331
2225
|
}
|
|
@@ -2333,14 +2227,13 @@ var FSWatcher = /** @class */ (function (_super) {
|
|
|
2333
2227
|
// link children add/remove
|
|
2334
2228
|
link.on('child:add', onLinkChildAdd);
|
|
2335
2229
|
link.on('child:delete', onLinkChildDelete);
|
|
2336
|
-
|
|
2337
|
-
removers.push(
|
|
2230
|
+
const removers = (_a = this._listenerRemovers.get(node.ino)) !== null && _a !== void 0 ? _a : [];
|
|
2231
|
+
removers.push(() => {
|
|
2338
2232
|
link.removeListener('child:add', onLinkChildAdd);
|
|
2339
2233
|
link.removeListener('child:delete', onLinkChildDelete);
|
|
2340
2234
|
});
|
|
2341
2235
|
if (recursive) {
|
|
2342
|
-
Object.entries(link.children).forEach(
|
|
2343
|
-
var name = _a[0], childLink = _a[1];
|
|
2236
|
+
Object.entries(link.children).forEach(([name, childLink]) => {
|
|
2344
2237
|
if (childLink && name !== '.' && name !== '..') {
|
|
2345
2238
|
watchLinkChildrenChanged(childLink);
|
|
2346
2239
|
}
|
|
@@ -2349,7 +2242,7 @@ var FSWatcher = /** @class */ (function (_super) {
|
|
|
2349
2242
|
};
|
|
2350
2243
|
watchLinkNodeChanged(this._link);
|
|
2351
2244
|
watchLinkChildrenChanged(this._link);
|
|
2352
|
-
|
|
2245
|
+
const parent = this._link.parent;
|
|
2353
2246
|
if (parent) {
|
|
2354
2247
|
// parent.on('child:add', this._onParentChild);
|
|
2355
2248
|
parent.setMaxListeners(parent.getMaxListeners() + 1);
|
|
@@ -2357,19 +2250,18 @@ var FSWatcher = /** @class */ (function (_super) {
|
|
|
2357
2250
|
}
|
|
2358
2251
|
if (persistent)
|
|
2359
2252
|
this._persist();
|
|
2360
|
-
}
|
|
2361
|
-
|
|
2253
|
+
}
|
|
2254
|
+
close() {
|
|
2362
2255
|
clearTimeout(this._timer);
|
|
2363
|
-
this._listenerRemovers.forEach(
|
|
2364
|
-
removers.forEach(
|
|
2256
|
+
this._listenerRemovers.forEach(removers => {
|
|
2257
|
+
removers.forEach(r => r());
|
|
2365
2258
|
});
|
|
2366
2259
|
this._listenerRemovers.clear();
|
|
2367
|
-
|
|
2260
|
+
const parent = this._link.parent;
|
|
2368
2261
|
if (parent) {
|
|
2369
2262
|
// parent.removeListener('child:add', this._onParentChild);
|
|
2370
2263
|
parent.removeListener('child:delete', this._onParentChild);
|
|
2371
2264
|
}
|
|
2372
|
-
}
|
|
2373
|
-
|
|
2374
|
-
}(events_1.EventEmitter));
|
|
2265
|
+
}
|
|
2266
|
+
}
|
|
2375
2267
|
exports.FSWatcher = FSWatcher;
|