@jjrawlins/cdk-git-tagger 0.0.0 → 0.0.1
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/.jsii +268 -24
- package/jjrawlinscdkgittagger/GitUrlTagger.go +100 -0
- package/jjrawlinscdkgittagger/GitUrlTaggerProps.go +14 -0
- package/jjrawlinscdkgittagger/GitUrlTagger__checks.go +36 -0
- package/jjrawlinscdkgittagger/GitUrlTagger__no_checks.go +18 -0
- package/jjrawlinscdkgittagger/LICENSE +202 -0
- package/jjrawlinscdkgittagger/README.md +60 -0
- package/jjrawlinscdkgittagger/go.mod +13 -0
- package/jjrawlinscdkgittagger/internal/types.go +5 -0
- package/jjrawlinscdkgittagger/jsii/jsii.go +30 -0
- package/jjrawlinscdkgittagger/main.go +30 -0
- package/jjrawlinscdkgittagger/version +1 -0
- package/lib/GitUrlTagger.d.ts +1 -0
- package/lib/GitUrlTagger.js +7 -4
- package/package.json +18 -17
- package/.git-url-tagger.json +0 -1
- package/node_modules/mock-fs/lib/binding.js +0 -1527
- package/node_modules/mock-fs/lib/bypass.js +0 -63
- package/node_modules/mock-fs/lib/descriptor.js +0 -128
- package/node_modules/mock-fs/lib/directory.js +0 -112
- package/node_modules/mock-fs/lib/error.js +0 -64
- package/node_modules/mock-fs/lib/file.js +0 -127
- package/node_modules/mock-fs/lib/filesystem.js +0 -392
- package/node_modules/mock-fs/lib/index.js +0 -219
- package/node_modules/mock-fs/lib/item.js +0 -338
- package/node_modules/mock-fs/lib/loader.js +0 -121
- package/node_modules/mock-fs/lib/readfilecontext.js +0 -153
- package/node_modules/mock-fs/lib/symlink.js +0 -59
- package/node_modules/mock-fs/license.md +0 -49
- package/node_modules/mock-fs/package.json +0 -66
- package/node_modules/mock-fs/readme.md +0 -290
|
@@ -1,1527 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const File = require('./file.js');
|
|
5
|
-
const FileDescriptor = require('./descriptor.js');
|
|
6
|
-
const Directory = require('./directory.js');
|
|
7
|
-
const SymbolicLink = require('./symlink.js');
|
|
8
|
-
const {FSError} = require('./error.js');
|
|
9
|
-
const constants = require('constants');
|
|
10
|
-
const {getPathParts, getRealPath} = require('./filesystem.js');
|
|
11
|
-
|
|
12
|
-
const MODE_TO_KTYPE = {
|
|
13
|
-
[constants.S_IFREG]: constants.UV_DIRENT_FILE,
|
|
14
|
-
[constants.S_IFDIR]: constants.UV_DIRENT_DIR,
|
|
15
|
-
[constants.S_IFBLK]: constants.UV_DIRENT_BLOCK,
|
|
16
|
-
[constants.S_IFCHR]: constants.UV_DIRENT_CHAR,
|
|
17
|
-
[constants.S_IFLNK]: constants.UV_DIRENT_LINK,
|
|
18
|
-
[constants.S_IFIFO]: constants.UV_DIRENT_FIFO,
|
|
19
|
-
[constants.S_IFSOCK]: constants.UV_DIRENT_SOCKET,
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
/** Workaround for optimizations in node 8+ */
|
|
23
|
-
const fsBinding = process.binding('fs');
|
|
24
|
-
const kUsePromises = fsBinding.kUsePromises;
|
|
25
|
-
let statValues;
|
|
26
|
-
let bigintStatValues;
|
|
27
|
-
if (fsBinding.statValues) {
|
|
28
|
-
statValues = fsBinding.statValues; // node 10+
|
|
29
|
-
bigintStatValues = fsBinding.bigintStatValues;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const MAX_LINKS = 50;
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Call the provided function and either return the result or call the callback
|
|
36
|
-
* with it (depending on if a callback is provided).
|
|
37
|
-
* @param {function()} callback Optional callback.
|
|
38
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
39
|
-
* @param {object} thisArg This argument for the following function.
|
|
40
|
-
* @param {function()} func Function to call.
|
|
41
|
-
* @return {*} Return (if callback is not provided).
|
|
42
|
-
*/
|
|
43
|
-
function maybeCallback(callback, ctx, thisArg, func) {
|
|
44
|
-
let err = null;
|
|
45
|
-
let val;
|
|
46
|
-
|
|
47
|
-
if (usePromises(callback)) {
|
|
48
|
-
// support nodejs v10+ fs.promises
|
|
49
|
-
try {
|
|
50
|
-
val = func.call(thisArg);
|
|
51
|
-
} catch (e) {
|
|
52
|
-
err = e;
|
|
53
|
-
}
|
|
54
|
-
return new Promise(function (resolve, reject) {
|
|
55
|
-
setImmediate(function () {
|
|
56
|
-
if (err) {
|
|
57
|
-
reject(err);
|
|
58
|
-
} else {
|
|
59
|
-
resolve(val);
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
} else if (callback && typeof callback === 'function') {
|
|
64
|
-
try {
|
|
65
|
-
val = func.call(thisArg);
|
|
66
|
-
} catch (e) {
|
|
67
|
-
err = e;
|
|
68
|
-
}
|
|
69
|
-
setImmediate(function () {
|
|
70
|
-
if (val === undefined) {
|
|
71
|
-
callback(err);
|
|
72
|
-
} else {
|
|
73
|
-
callback(err, val);
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
} else if (ctx && typeof ctx === 'object') {
|
|
77
|
-
try {
|
|
78
|
-
return func.call(thisArg);
|
|
79
|
-
} catch (e) {
|
|
80
|
-
// default to errno for UNKNOWN
|
|
81
|
-
ctx.code = e.code || 'UNKNOWN';
|
|
82
|
-
ctx.errno = e.errno || FSError.codes.UNKNOWN.errno;
|
|
83
|
-
}
|
|
84
|
-
} else {
|
|
85
|
-
return func.call(thisArg);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function usePromises(callback) {
|
|
90
|
-
return kUsePromises && callback === kUsePromises;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* set syscall property on context object, only for nodejs v10+.
|
|
95
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
96
|
-
* @param {string} syscall Name of syscall.
|
|
97
|
-
*/
|
|
98
|
-
function markSyscall(ctx, syscall) {
|
|
99
|
-
if (ctx && typeof ctx === 'object') {
|
|
100
|
-
ctx.syscall = syscall;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Handle FSReqWrap oncomplete.
|
|
106
|
-
* @param {Function} callback The callback.
|
|
107
|
-
* @return {Function} The normalized callback.
|
|
108
|
-
*/
|
|
109
|
-
function normalizeCallback(callback) {
|
|
110
|
-
if (callback && typeof callback.oncomplete === 'function') {
|
|
111
|
-
// Unpack callback from FSReqWrap
|
|
112
|
-
callback = callback.oncomplete.bind(callback);
|
|
113
|
-
}
|
|
114
|
-
return callback;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function getDirentType(mode) {
|
|
118
|
-
const ktype = MODE_TO_KTYPE[mode & constants.S_IFMT];
|
|
119
|
-
|
|
120
|
-
if (ktype === undefined) {
|
|
121
|
-
return constants.UV_DIRENT_UNKNOWN;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return ktype;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function notImplemented() {
|
|
128
|
-
throw new Error('Method not implemented');
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function deBuffer(p) {
|
|
132
|
-
return Buffer.isBuffer(p) ? p.toString() : p;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Create a new binding with the given file system.
|
|
137
|
-
* @param {FileSystem} system Mock file system.
|
|
138
|
-
* @class
|
|
139
|
-
*/
|
|
140
|
-
function Binding(system) {
|
|
141
|
-
/**
|
|
142
|
-
* Mock file system.
|
|
143
|
-
* @type {FileSystem}
|
|
144
|
-
*/
|
|
145
|
-
this._system = system;
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Lookup of open files.
|
|
149
|
-
* @type {Object<number, FileDescriptor>}
|
|
150
|
-
*/
|
|
151
|
-
this._openFiles = {};
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Counter for file descriptors.
|
|
155
|
-
* @type {number}
|
|
156
|
-
*/
|
|
157
|
-
this._counter = -1;
|
|
158
|
-
|
|
159
|
-
const stdin = new FileDescriptor(constants.O_RDWR);
|
|
160
|
-
stdin.setItem(new File.StandardInput());
|
|
161
|
-
this.trackDescriptor(stdin);
|
|
162
|
-
|
|
163
|
-
const stdout = new FileDescriptor(constants.O_RDWR);
|
|
164
|
-
stdout.setItem(new File.StandardOutput());
|
|
165
|
-
this.trackDescriptor(stdout);
|
|
166
|
-
|
|
167
|
-
const stderr = new FileDescriptor(constants.O_RDWR);
|
|
168
|
-
stderr.setItem(new File.StandardError());
|
|
169
|
-
this.trackDescriptor(stderr);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Get the file system underlying this binding.
|
|
174
|
-
* @return {FileSystem} The underlying file system.
|
|
175
|
-
*/
|
|
176
|
-
Binding.prototype.getSystem = function () {
|
|
177
|
-
return this._system;
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Reset the file system underlying this binding.
|
|
182
|
-
* @param {FileSystem} system The new file system.
|
|
183
|
-
*/
|
|
184
|
-
Binding.prototype.setSystem = function (system) {
|
|
185
|
-
this._system = system;
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Get a file descriptor.
|
|
190
|
-
* @param {number} fd File descriptor identifier.
|
|
191
|
-
* @return {FileDescriptor} File descriptor.
|
|
192
|
-
*/
|
|
193
|
-
Binding.prototype.getDescriptorById = function (fd) {
|
|
194
|
-
if (!this._openFiles.hasOwnProperty(fd)) {
|
|
195
|
-
throw new FSError('EBADF');
|
|
196
|
-
}
|
|
197
|
-
return this._openFiles[fd];
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Keep track of a file descriptor as open.
|
|
202
|
-
* @param {FileDescriptor} descriptor The file descriptor.
|
|
203
|
-
* @return {number} Identifier for file descriptor.
|
|
204
|
-
*/
|
|
205
|
-
Binding.prototype.trackDescriptor = function (descriptor) {
|
|
206
|
-
const fd = ++this._counter;
|
|
207
|
-
this._openFiles[fd] = descriptor;
|
|
208
|
-
return fd;
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Stop tracking a file descriptor as open.
|
|
213
|
-
* @param {number} fd Identifier for file descriptor.
|
|
214
|
-
*/
|
|
215
|
-
Binding.prototype.untrackDescriptorById = function (fd) {
|
|
216
|
-
if (!this._openFiles.hasOwnProperty(fd)) {
|
|
217
|
-
throw new FSError('EBADF');
|
|
218
|
-
}
|
|
219
|
-
delete this._openFiles[fd];
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Resolve the canonicalized absolute pathname.
|
|
224
|
-
* @param {string|Buffer} filepath The file path.
|
|
225
|
-
* @param {string} encoding The encoding for the return.
|
|
226
|
-
* @param {Function} callback The callback.
|
|
227
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
228
|
-
* @return {string|Buffer} The real path.
|
|
229
|
-
*/
|
|
230
|
-
Binding.prototype.realpath = function (filepath, encoding, callback, ctx) {
|
|
231
|
-
markSyscall(ctx, 'realpath');
|
|
232
|
-
|
|
233
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
234
|
-
let realPath;
|
|
235
|
-
filepath = deBuffer(filepath);
|
|
236
|
-
const resolved = path.resolve(filepath);
|
|
237
|
-
const parts = getPathParts(resolved);
|
|
238
|
-
let item = this._system.getRoot();
|
|
239
|
-
let itemPath = '/';
|
|
240
|
-
let name, i, ii;
|
|
241
|
-
for (i = 0, ii = parts.length; i < ii; ++i) {
|
|
242
|
-
name = parts[i];
|
|
243
|
-
while (item instanceof SymbolicLink) {
|
|
244
|
-
itemPath = path.resolve(path.dirname(itemPath), item.getPath());
|
|
245
|
-
item = this._system.getItem(itemPath);
|
|
246
|
-
}
|
|
247
|
-
if (!item) {
|
|
248
|
-
throw new FSError('ENOENT', filepath);
|
|
249
|
-
}
|
|
250
|
-
if (item instanceof Directory) {
|
|
251
|
-
itemPath = path.resolve(itemPath, name);
|
|
252
|
-
item = item.getItem(name);
|
|
253
|
-
} else {
|
|
254
|
-
throw new FSError('ENOTDIR', filepath);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
if (item) {
|
|
258
|
-
while (item instanceof SymbolicLink) {
|
|
259
|
-
itemPath = path.resolve(path.dirname(itemPath), item.getPath());
|
|
260
|
-
item = this._system.getItem(itemPath);
|
|
261
|
-
}
|
|
262
|
-
realPath = itemPath;
|
|
263
|
-
} else {
|
|
264
|
-
throw new FSError('ENOENT', filepath);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// Remove win32 file namespace prefix \\?\
|
|
268
|
-
realPath = getRealPath(realPath);
|
|
269
|
-
|
|
270
|
-
if (encoding === 'buffer') {
|
|
271
|
-
realPath = Buffer.from(realPath);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
return realPath;
|
|
275
|
-
});
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
function fillStats(stats, bigint) {
|
|
279
|
-
const target = bigint ? bigintStatValues : statValues;
|
|
280
|
-
for (let i = 0; i < 36; i++) {
|
|
281
|
-
target[i] = stats[i];
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* Stat an item.
|
|
287
|
-
* @param {string} filepath Path.
|
|
288
|
-
* @param {boolean} bigint Use BigInt.
|
|
289
|
-
* @param {function(Error, Float64Array|BigUint64Array)} callback Callback (optional).
|
|
290
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
291
|
-
* @return {Float64Array|BigUint64Array|undefined} Stats or undefined (if sync).
|
|
292
|
-
*/
|
|
293
|
-
Binding.prototype.stat = function (filepath, bigint, callback, ctx) {
|
|
294
|
-
markSyscall(ctx, 'stat');
|
|
295
|
-
|
|
296
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
297
|
-
filepath = deBuffer(filepath);
|
|
298
|
-
let item = this._system.getItem(filepath);
|
|
299
|
-
if (item instanceof SymbolicLink) {
|
|
300
|
-
item = this._system.getItem(
|
|
301
|
-
path.resolve(path.dirname(filepath), item.getPath())
|
|
302
|
-
);
|
|
303
|
-
}
|
|
304
|
-
if (!item) {
|
|
305
|
-
throw new FSError('ENOENT', filepath);
|
|
306
|
-
}
|
|
307
|
-
const stats = item.getStats(bigint);
|
|
308
|
-
fillStats(stats, bigint);
|
|
309
|
-
return stats;
|
|
310
|
-
});
|
|
311
|
-
};
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Stat an item.
|
|
315
|
-
* @param {string} filepath Path.
|
|
316
|
-
* @param {boolean} bigint Use BigInt.
|
|
317
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
318
|
-
* @return {Float64Array|BigUint64Array|undefined} Stats or undefined if sync.
|
|
319
|
-
*/
|
|
320
|
-
Binding.prototype.statSync = function (filepath, bigint, ctx) {
|
|
321
|
-
return this.stat(filepath, bigint, undefined, ctx);
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Stat an item.
|
|
326
|
-
* @param {number} fd File descriptor.
|
|
327
|
-
* @param {boolean} bigint Use BigInt.
|
|
328
|
-
* @param {function(Error, Float64Array|BigUint64Array)} callback Callback (optional).
|
|
329
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
330
|
-
* @return {Float64Array|BigUint64Array|undefined} Stats or undefined (if sync).
|
|
331
|
-
*/
|
|
332
|
-
Binding.prototype.fstat = function (fd, bigint, callback, ctx) {
|
|
333
|
-
markSyscall(ctx, 'fstat');
|
|
334
|
-
|
|
335
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
336
|
-
const descriptor = this.getDescriptorById(fd);
|
|
337
|
-
const item = descriptor.getItem();
|
|
338
|
-
const stats = item.getStats(bigint);
|
|
339
|
-
fillStats(stats, bigint);
|
|
340
|
-
return stats;
|
|
341
|
-
});
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* Close a file descriptor.
|
|
346
|
-
* @param {number} fd File descriptor.
|
|
347
|
-
* @param {function(Error)} callback Callback (optional).
|
|
348
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
349
|
-
* @return {*} The return if no callback.
|
|
350
|
-
*/
|
|
351
|
-
Binding.prototype.close = function (fd, callback, ctx) {
|
|
352
|
-
markSyscall(ctx, 'close');
|
|
353
|
-
|
|
354
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
355
|
-
this.untrackDescriptorById(fd);
|
|
356
|
-
});
|
|
357
|
-
};
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* Close a file descriptor.
|
|
361
|
-
* @param {number} fd File descriptor.
|
|
362
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
363
|
-
* @return {*} The return.
|
|
364
|
-
*/
|
|
365
|
-
Binding.prototype.closeSync = function (fd, ctx) {
|
|
366
|
-
return this.close(fd, undefined, ctx);
|
|
367
|
-
};
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* Open and possibly create a file.
|
|
371
|
-
* @param {string} pathname File path.
|
|
372
|
-
* @param {number} flags Flags.
|
|
373
|
-
* @param {number} mode Mode.
|
|
374
|
-
* @param {function(Error, string)} callback Callback (optional).
|
|
375
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
376
|
-
* @return {string} File descriptor (if sync).
|
|
377
|
-
*/
|
|
378
|
-
Binding.prototype.open = function (pathname, flags, mode, callback, ctx) {
|
|
379
|
-
markSyscall(ctx, 'open');
|
|
380
|
-
|
|
381
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
382
|
-
pathname = deBuffer(pathname);
|
|
383
|
-
const descriptor = new FileDescriptor(flags, usePromises(callback));
|
|
384
|
-
let item = this._system.getItem(pathname);
|
|
385
|
-
while (item instanceof SymbolicLink) {
|
|
386
|
-
item = this._system.getItem(
|
|
387
|
-
path.resolve(path.dirname(pathname), item.getPath())
|
|
388
|
-
);
|
|
389
|
-
}
|
|
390
|
-
if (descriptor.isExclusive() && item) {
|
|
391
|
-
throw new FSError('EEXIST', pathname);
|
|
392
|
-
}
|
|
393
|
-
if (descriptor.isCreate() && !item) {
|
|
394
|
-
const parent = this._system.getItem(path.dirname(pathname));
|
|
395
|
-
if (!parent) {
|
|
396
|
-
throw new FSError('ENOENT', pathname);
|
|
397
|
-
}
|
|
398
|
-
if (!(parent instanceof Directory)) {
|
|
399
|
-
throw new FSError('ENOTDIR', pathname);
|
|
400
|
-
}
|
|
401
|
-
item = new File();
|
|
402
|
-
if (mode) {
|
|
403
|
-
item.setMode(mode);
|
|
404
|
-
}
|
|
405
|
-
parent.addItem(path.basename(pathname), item);
|
|
406
|
-
}
|
|
407
|
-
if (descriptor.isRead()) {
|
|
408
|
-
if (!item) {
|
|
409
|
-
throw new FSError('ENOENT', pathname);
|
|
410
|
-
}
|
|
411
|
-
if (!item.canRead()) {
|
|
412
|
-
throw new FSError('EACCES', pathname);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
if (descriptor.isWrite() && !item.canWrite()) {
|
|
416
|
-
throw new FSError('EACCES', pathname);
|
|
417
|
-
}
|
|
418
|
-
if (
|
|
419
|
-
item instanceof Directory &&
|
|
420
|
-
(descriptor.isTruncate() || descriptor.isAppend())
|
|
421
|
-
) {
|
|
422
|
-
throw new FSError('EISDIR', pathname);
|
|
423
|
-
}
|
|
424
|
-
if (descriptor.isTruncate()) {
|
|
425
|
-
if (!(item instanceof File)) {
|
|
426
|
-
throw new FSError('EBADF');
|
|
427
|
-
}
|
|
428
|
-
item.setContent('');
|
|
429
|
-
}
|
|
430
|
-
if (descriptor.isTruncate() || descriptor.isAppend()) {
|
|
431
|
-
descriptor.setPosition(item.getContent().length);
|
|
432
|
-
}
|
|
433
|
-
descriptor.setItem(item);
|
|
434
|
-
return this.trackDescriptor(descriptor);
|
|
435
|
-
});
|
|
436
|
-
};
|
|
437
|
-
|
|
438
|
-
/**
|
|
439
|
-
* Open and possibly create a file.
|
|
440
|
-
* @param {string} pathname File path.
|
|
441
|
-
* @param {number} flags Flags.
|
|
442
|
-
* @param {number} mode Mode.
|
|
443
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
444
|
-
* @return {string} File descriptor.
|
|
445
|
-
*/
|
|
446
|
-
Binding.prototype.openSync = function (pathname, flags, mode, ctx) {
|
|
447
|
-
return this.open(pathname, flags, mode, undefined, ctx);
|
|
448
|
-
};
|
|
449
|
-
|
|
450
|
-
/**
|
|
451
|
-
* Open a file handler. A new api in nodejs v10+ for fs.promises
|
|
452
|
-
* @param {string} pathname File path.
|
|
453
|
-
* @param {number} flags Flags.
|
|
454
|
-
* @param {number} mode Mode.
|
|
455
|
-
* @param {Function} callback Callback (optional), expecting kUsePromises in nodejs v10+.
|
|
456
|
-
* @return {string} The file handle.
|
|
457
|
-
*/
|
|
458
|
-
Binding.prototype.openFileHandle = function (pathname, flags, mode, callback) {
|
|
459
|
-
const self = this;
|
|
460
|
-
|
|
461
|
-
return this.open(pathname, flags, mode, kUsePromises).then(function (fd) {
|
|
462
|
-
// nodejs v10+ fs.promises FileHandler constructor only ask these three properties.
|
|
463
|
-
return {
|
|
464
|
-
getAsyncId: notImplemented,
|
|
465
|
-
fd: fd,
|
|
466
|
-
close: function () {
|
|
467
|
-
return self.close(fd, kUsePromises);
|
|
468
|
-
},
|
|
469
|
-
};
|
|
470
|
-
});
|
|
471
|
-
};
|
|
472
|
-
|
|
473
|
-
/**
|
|
474
|
-
* Read from a file descriptor.
|
|
475
|
-
* @param {string} fd File descriptor.
|
|
476
|
-
* @param {Buffer} buffer Buffer that the contents will be written to.
|
|
477
|
-
* @param {number} offset Offset in the buffer to start writing to.
|
|
478
|
-
* @param {number} length Number of bytes to read.
|
|
479
|
-
* @param {?number} position Where to begin reading in the file. If null,
|
|
480
|
-
* data will be read from the current file position.
|
|
481
|
-
* @param {function(Error, number, Buffer)} callback Callback (optional) called
|
|
482
|
-
* with any error, number of bytes read, and the buffer.
|
|
483
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
484
|
-
* @return {number} Number of bytes read (if sync).
|
|
485
|
-
*/
|
|
486
|
-
Binding.prototype.read = function (
|
|
487
|
-
fd,
|
|
488
|
-
buffer,
|
|
489
|
-
offset,
|
|
490
|
-
length,
|
|
491
|
-
position,
|
|
492
|
-
callback,
|
|
493
|
-
ctx
|
|
494
|
-
) {
|
|
495
|
-
markSyscall(ctx, 'read');
|
|
496
|
-
|
|
497
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
498
|
-
const descriptor = this.getDescriptorById(fd);
|
|
499
|
-
if (!descriptor.isRead()) {
|
|
500
|
-
throw new FSError('EBADF');
|
|
501
|
-
}
|
|
502
|
-
const file = descriptor.getItem();
|
|
503
|
-
if (file instanceof Directory) {
|
|
504
|
-
throw new FSError('EISDIR');
|
|
505
|
-
}
|
|
506
|
-
if (!(file instanceof File)) {
|
|
507
|
-
// deleted or not a regular file
|
|
508
|
-
throw new FSError('EBADF');
|
|
509
|
-
}
|
|
510
|
-
if (typeof position !== 'number' || position < 0) {
|
|
511
|
-
position = descriptor.getPosition();
|
|
512
|
-
}
|
|
513
|
-
const content = file.getContent();
|
|
514
|
-
const start = Math.min(position, content.length);
|
|
515
|
-
const end = Math.min(position + length, content.length);
|
|
516
|
-
const read = start < end ? content.copy(buffer, offset, start, end) : 0;
|
|
517
|
-
descriptor.setPosition(position + read);
|
|
518
|
-
return read;
|
|
519
|
-
});
|
|
520
|
-
};
|
|
521
|
-
|
|
522
|
-
/**
|
|
523
|
-
* Write to a file descriptor given a buffer.
|
|
524
|
-
* @param {string} src Source file.
|
|
525
|
-
* @param {string} dest Destination file.
|
|
526
|
-
* @param {number} flags Modifiers for copy operation.
|
|
527
|
-
* @param {function(Error)} callback Callback (optional) called
|
|
528
|
-
* with any error.
|
|
529
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
530
|
-
* @return {*} The return if no callback is provided.
|
|
531
|
-
*/
|
|
532
|
-
Binding.prototype.copyFile = function (src, dest, flags, callback, ctx) {
|
|
533
|
-
markSyscall(ctx, 'copyfile');
|
|
534
|
-
|
|
535
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
536
|
-
src = deBuffer(src);
|
|
537
|
-
dest = deBuffer(dest);
|
|
538
|
-
const srcFd = this.open(src, constants.O_RDONLY);
|
|
539
|
-
|
|
540
|
-
try {
|
|
541
|
-
const srcDescriptor = this.getDescriptorById(srcFd);
|
|
542
|
-
if (!srcDescriptor.isRead()) {
|
|
543
|
-
throw new FSError('EBADF');
|
|
544
|
-
}
|
|
545
|
-
const srcFile = srcDescriptor.getItem();
|
|
546
|
-
if (!(srcFile instanceof File)) {
|
|
547
|
-
throw new FSError('EBADF');
|
|
548
|
-
}
|
|
549
|
-
const srcContent = srcFile.getContent();
|
|
550
|
-
|
|
551
|
-
let destFlags =
|
|
552
|
-
constants.O_WRONLY | constants.O_CREAT | constants.O_TRUNC;
|
|
553
|
-
|
|
554
|
-
if ((flags & constants.COPYFILE_EXCL) === constants.COPYFILE_EXCL) {
|
|
555
|
-
destFlags |= constants.O_EXCL;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
const destFd = this.open(dest, destFlags);
|
|
559
|
-
|
|
560
|
-
try {
|
|
561
|
-
this.writeBuffer(destFd, srcContent, 0, srcContent.length, 0);
|
|
562
|
-
} finally {
|
|
563
|
-
this.close(destFd);
|
|
564
|
-
}
|
|
565
|
-
} finally {
|
|
566
|
-
this.close(srcFd);
|
|
567
|
-
}
|
|
568
|
-
});
|
|
569
|
-
};
|
|
570
|
-
|
|
571
|
-
/**
|
|
572
|
-
* Write to a file descriptor given a buffer.
|
|
573
|
-
* @param {string} src Source file.
|
|
574
|
-
* @param {string} dest Destination file.
|
|
575
|
-
* @param {number} flags Modifiers for copy operation.
|
|
576
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
577
|
-
* @return {*} The return if no callback is provided.
|
|
578
|
-
*/
|
|
579
|
-
Binding.prototype.copyFileSync = function (src, dest, flags, ctx) {
|
|
580
|
-
return this.copyFile(src, dest, flags, undefined, ctx);
|
|
581
|
-
};
|
|
582
|
-
|
|
583
|
-
/**
|
|
584
|
-
* Write to a file descriptor given a buffer.
|
|
585
|
-
* @param {string} fd File descriptor.
|
|
586
|
-
* @param {Array<Buffer>} buffers Array of buffers with contents to write.
|
|
587
|
-
* @param {?number} position Where to begin writing in the file. If null,
|
|
588
|
-
* data will be written to the current file position.
|
|
589
|
-
* @param {function(Error, number, Buffer)} callback Callback (optional) called
|
|
590
|
-
* with any error, number of bytes written, and the buffer.
|
|
591
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
592
|
-
* @return {number} Number of bytes written (if sync).
|
|
593
|
-
*/
|
|
594
|
-
Binding.prototype.writeBuffers = function (
|
|
595
|
-
fd,
|
|
596
|
-
buffers,
|
|
597
|
-
position,
|
|
598
|
-
callback,
|
|
599
|
-
ctx
|
|
600
|
-
) {
|
|
601
|
-
markSyscall(ctx, 'write');
|
|
602
|
-
|
|
603
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
604
|
-
const descriptor = this.getDescriptorById(fd);
|
|
605
|
-
if (!descriptor.isWrite()) {
|
|
606
|
-
throw new FSError('EBADF');
|
|
607
|
-
}
|
|
608
|
-
const file = descriptor.getItem();
|
|
609
|
-
if (!(file instanceof File)) {
|
|
610
|
-
// not a regular file
|
|
611
|
-
throw new FSError('EBADF');
|
|
612
|
-
}
|
|
613
|
-
if (typeof position !== 'number' || position < 0) {
|
|
614
|
-
position = descriptor.getPosition();
|
|
615
|
-
}
|
|
616
|
-
let content = file.getContent();
|
|
617
|
-
const newContent = Buffer.concat(buffers);
|
|
618
|
-
const newLength = position + newContent.length;
|
|
619
|
-
if (content.length < newLength) {
|
|
620
|
-
const tempContent = Buffer.alloc(newLength);
|
|
621
|
-
content.copy(tempContent);
|
|
622
|
-
content = tempContent;
|
|
623
|
-
}
|
|
624
|
-
const written = newContent.copy(content, position);
|
|
625
|
-
file.setContent(content);
|
|
626
|
-
descriptor.setPosition(newLength);
|
|
627
|
-
return written;
|
|
628
|
-
});
|
|
629
|
-
};
|
|
630
|
-
|
|
631
|
-
/**
|
|
632
|
-
* Write to a file descriptor given a buffer.
|
|
633
|
-
* @param {string} fd File descriptor.
|
|
634
|
-
* @param {Buffer} buffer Buffer with contents to write.
|
|
635
|
-
* @param {number} offset Offset in the buffer to start writing from.
|
|
636
|
-
* @param {number} length Number of bytes to write.
|
|
637
|
-
* @param {?number} position Where to begin writing in the file. If null,
|
|
638
|
-
* data will be written to the current file position.
|
|
639
|
-
* @param {function(Error, number, Buffer)} callback Callback (optional) called
|
|
640
|
-
* with any error, number of bytes written, and the buffer.
|
|
641
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
642
|
-
* @return {number} Number of bytes written (if sync).
|
|
643
|
-
*/
|
|
644
|
-
Binding.prototype.writeBuffer = function (
|
|
645
|
-
fd,
|
|
646
|
-
buffer,
|
|
647
|
-
offset,
|
|
648
|
-
length,
|
|
649
|
-
position,
|
|
650
|
-
callback,
|
|
651
|
-
ctx
|
|
652
|
-
) {
|
|
653
|
-
markSyscall(ctx, 'write');
|
|
654
|
-
|
|
655
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
656
|
-
const descriptor = this.getDescriptorById(fd);
|
|
657
|
-
if (!descriptor.isWrite()) {
|
|
658
|
-
throw new FSError('EBADF');
|
|
659
|
-
}
|
|
660
|
-
const file = descriptor.getItem();
|
|
661
|
-
if (!(file instanceof File)) {
|
|
662
|
-
// not a regular file
|
|
663
|
-
throw new FSError('EBADF');
|
|
664
|
-
}
|
|
665
|
-
if (typeof position !== 'number' || position < 0) {
|
|
666
|
-
position = descriptor.getPosition();
|
|
667
|
-
}
|
|
668
|
-
let content = file.getContent();
|
|
669
|
-
const newLength = position + length;
|
|
670
|
-
if (content.length < newLength) {
|
|
671
|
-
const newContent = Buffer.alloc(newLength);
|
|
672
|
-
content.copy(newContent);
|
|
673
|
-
content = newContent;
|
|
674
|
-
}
|
|
675
|
-
const sourceEnd = Math.min(offset + length, buffer.length);
|
|
676
|
-
const written = Buffer.from(buffer).copy(
|
|
677
|
-
content,
|
|
678
|
-
position,
|
|
679
|
-
offset,
|
|
680
|
-
sourceEnd
|
|
681
|
-
);
|
|
682
|
-
file.setContent(content);
|
|
683
|
-
descriptor.setPosition(newLength);
|
|
684
|
-
// If we're in fs.promises / FileHandle we need to return a promise
|
|
685
|
-
// Both fs.promises.open().then(fd => fs.write())
|
|
686
|
-
// and fs.openSync().writeSync() use this function
|
|
687
|
-
// without a callback, so we have to check if the descriptor was opened
|
|
688
|
-
// with kUsePromises
|
|
689
|
-
return descriptor.isPromise() ? Promise.resolve(written) : written;
|
|
690
|
-
});
|
|
691
|
-
};
|
|
692
|
-
|
|
693
|
-
/**
|
|
694
|
-
* Write to a file descriptor given a string.
|
|
695
|
-
* @param {string} fd File descriptor.
|
|
696
|
-
* @param {string} string String with contents to write.
|
|
697
|
-
* @param {number} position Where to begin writing in the file. If null,
|
|
698
|
-
* data will be written to the current file position.
|
|
699
|
-
* @param {string} encoding String encoding.
|
|
700
|
-
* @param {function(Error, number, string)} callback Callback (optional) called
|
|
701
|
-
* with any error, number of bytes written, and the string.
|
|
702
|
-
* @param {object} ctx The context.
|
|
703
|
-
* @return {number} Number of bytes written (if sync).
|
|
704
|
-
*/
|
|
705
|
-
Binding.prototype.writeString = function (
|
|
706
|
-
fd,
|
|
707
|
-
string,
|
|
708
|
-
position,
|
|
709
|
-
encoding,
|
|
710
|
-
callback,
|
|
711
|
-
ctx
|
|
712
|
-
) {
|
|
713
|
-
markSyscall(ctx, 'write');
|
|
714
|
-
|
|
715
|
-
const buffer = Buffer.from(string, encoding);
|
|
716
|
-
let wrapper;
|
|
717
|
-
if (callback && callback !== kUsePromises) {
|
|
718
|
-
if (callback.oncomplete) {
|
|
719
|
-
callback = callback.oncomplete.bind(callback);
|
|
720
|
-
}
|
|
721
|
-
wrapper = function (err, written, returned) {
|
|
722
|
-
callback(err, written, returned && string);
|
|
723
|
-
};
|
|
724
|
-
}
|
|
725
|
-
return this.writeBuffer(fd, buffer, 0, string.length, position, wrapper, ctx);
|
|
726
|
-
};
|
|
727
|
-
|
|
728
|
-
/**
|
|
729
|
-
* Rename a file.
|
|
730
|
-
* @param {string} oldPath Old pathname.
|
|
731
|
-
* @param {string} newPath New pathname.
|
|
732
|
-
* @param {function(Error)} callback Callback (optional).
|
|
733
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
734
|
-
* @return {undefined}
|
|
735
|
-
*/
|
|
736
|
-
Binding.prototype.rename = function (oldPath, newPath, callback, ctx) {
|
|
737
|
-
markSyscall(ctx, 'rename');
|
|
738
|
-
|
|
739
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
740
|
-
oldPath = deBuffer(oldPath);
|
|
741
|
-
newPath = deBuffer(newPath);
|
|
742
|
-
const oldItem = this._system.getItem(oldPath);
|
|
743
|
-
if (!oldItem) {
|
|
744
|
-
throw new FSError('ENOENT', oldPath);
|
|
745
|
-
}
|
|
746
|
-
const oldParent = this._system.getItem(path.dirname(oldPath));
|
|
747
|
-
const oldName = path.basename(oldPath);
|
|
748
|
-
const newItem = this._system.getItem(newPath);
|
|
749
|
-
const newParent = this._system.getItem(path.dirname(newPath));
|
|
750
|
-
const newName = path.basename(newPath);
|
|
751
|
-
if (newItem) {
|
|
752
|
-
// make sure they are the same type
|
|
753
|
-
if (oldItem instanceof File) {
|
|
754
|
-
if (newItem instanceof Directory) {
|
|
755
|
-
throw new FSError('EISDIR', newPath);
|
|
756
|
-
}
|
|
757
|
-
} else if (oldItem instanceof Directory) {
|
|
758
|
-
if (!(newItem instanceof Directory)) {
|
|
759
|
-
throw new FSError('ENOTDIR', newPath);
|
|
760
|
-
}
|
|
761
|
-
if (newItem.list().length > 0) {
|
|
762
|
-
throw new FSError('ENOTEMPTY', newPath);
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
newParent.removeItem(newName);
|
|
766
|
-
} else {
|
|
767
|
-
if (!newParent) {
|
|
768
|
-
throw new FSError('ENOENT', newPath);
|
|
769
|
-
}
|
|
770
|
-
if (!(newParent instanceof Directory)) {
|
|
771
|
-
throw new FSError('ENOTDIR', newPath);
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
oldParent.removeItem(oldName);
|
|
775
|
-
newParent.addItem(newName, oldItem);
|
|
776
|
-
});
|
|
777
|
-
};
|
|
778
|
-
|
|
779
|
-
/**
|
|
780
|
-
* Rename a file.
|
|
781
|
-
* @param {string} oldPath Old pathname.
|
|
782
|
-
* @param {string} newPath New pathname.
|
|
783
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
784
|
-
* @return {undefined}
|
|
785
|
-
*/
|
|
786
|
-
Binding.prototype.renameSync = function (oldPath, newPath, ctx) {
|
|
787
|
-
return this.rename(oldPath, newPath, undefined, ctx);
|
|
788
|
-
};
|
|
789
|
-
|
|
790
|
-
/**
|
|
791
|
-
* Read a directory.
|
|
792
|
-
* @param {string} dirpath Path to directory.
|
|
793
|
-
* @param {string} encoding The encoding ('utf-8' or 'buffer').
|
|
794
|
-
* @param {boolean} withFileTypes whether or not to return fs.Dirent objects
|
|
795
|
-
* @param {function(Error, (Array.<string>|Array.<Buffer>)} callback Callback
|
|
796
|
-
* (optional) called with any error or array of items in the directory.
|
|
797
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
798
|
-
* @return {Array<string> | Array<Buffer>} Array of items in directory (if sync).
|
|
799
|
-
*/
|
|
800
|
-
Binding.prototype.readdir = function (
|
|
801
|
-
dirpath,
|
|
802
|
-
encoding,
|
|
803
|
-
withFileTypes,
|
|
804
|
-
callback,
|
|
805
|
-
ctx
|
|
806
|
-
) {
|
|
807
|
-
markSyscall(ctx, 'scandir');
|
|
808
|
-
|
|
809
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
810
|
-
dirpath = deBuffer(dirpath);
|
|
811
|
-
let dpath = dirpath;
|
|
812
|
-
let dir = this._system.getItem(dirpath);
|
|
813
|
-
while (dir instanceof SymbolicLink) {
|
|
814
|
-
dpath = path.resolve(path.dirname(dpath), dir.getPath());
|
|
815
|
-
dir = this._system.getItem(dpath);
|
|
816
|
-
}
|
|
817
|
-
if (!dir) {
|
|
818
|
-
throw new FSError('ENOENT', dirpath);
|
|
819
|
-
}
|
|
820
|
-
if (!(dir instanceof Directory)) {
|
|
821
|
-
throw new FSError('ENOTDIR', dirpath);
|
|
822
|
-
}
|
|
823
|
-
if (!dir.canRead()) {
|
|
824
|
-
throw new FSError('EACCES', dirpath);
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
let list = dir.list();
|
|
828
|
-
if (encoding === 'buffer') {
|
|
829
|
-
list = list.map(function (item) {
|
|
830
|
-
return Buffer.from(item);
|
|
831
|
-
});
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
if (withFileTypes === true) {
|
|
835
|
-
const types = list.map(function (name) {
|
|
836
|
-
const stats = dir.getItem(name).getStats();
|
|
837
|
-
|
|
838
|
-
return getDirentType(stats.mode);
|
|
839
|
-
});
|
|
840
|
-
list = [list, types];
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
return list;
|
|
844
|
-
});
|
|
845
|
-
};
|
|
846
|
-
|
|
847
|
-
/**
|
|
848
|
-
* Read file as utf8 string.
|
|
849
|
-
* @param {string} name file to write.
|
|
850
|
-
* @param {number} flags Flags.
|
|
851
|
-
* @return {string} the file content.
|
|
852
|
-
*/
|
|
853
|
-
Binding.prototype.readFileUtf8 = function (name, flags) {
|
|
854
|
-
const fd = this.open(name, flags);
|
|
855
|
-
const descriptor = this.getDescriptorById(fd);
|
|
856
|
-
|
|
857
|
-
if (!descriptor.isRead()) {
|
|
858
|
-
throw new FSError('EBADF');
|
|
859
|
-
}
|
|
860
|
-
const file = descriptor.getItem();
|
|
861
|
-
if (file instanceof Directory) {
|
|
862
|
-
throw new FSError('EISDIR');
|
|
863
|
-
}
|
|
864
|
-
if (!(file instanceof File)) {
|
|
865
|
-
// deleted or not a regular file
|
|
866
|
-
throw new FSError('EBADF');
|
|
867
|
-
}
|
|
868
|
-
const content = file.getContent();
|
|
869
|
-
return content.toString('utf8');
|
|
870
|
-
};
|
|
871
|
-
|
|
872
|
-
/**
|
|
873
|
-
* Write a utf8 string.
|
|
874
|
-
* @param {string} filepath file to write.
|
|
875
|
-
* @param {string} data data to write to filepath.
|
|
876
|
-
* @param {number} flags Flags.
|
|
877
|
-
* @param {number} mode Mode.
|
|
878
|
-
*/
|
|
879
|
-
Binding.prototype.writeFileUtf8 = function (filepath, data, flags, mode) {
|
|
880
|
-
const destFd = this.open(filepath, flags, mode);
|
|
881
|
-
this.writeBuffer(destFd, data, 0, data.length);
|
|
882
|
-
};
|
|
883
|
-
|
|
884
|
-
/**
|
|
885
|
-
* Create a directory.
|
|
886
|
-
* @param {string} pathname Path to new directory.
|
|
887
|
-
* @param {number} mode Permissions.
|
|
888
|
-
* @param {boolean} recursive Recursively create deep directory. (added in nodejs v10+)
|
|
889
|
-
* @param {function(Error)} callback Optional callback.
|
|
890
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
891
|
-
* @return {*} The return if no callback is provided.
|
|
892
|
-
*/
|
|
893
|
-
Binding.prototype.mkdir = function (pathname, mode, recursive, callback, ctx) {
|
|
894
|
-
markSyscall(ctx, 'mkdir');
|
|
895
|
-
|
|
896
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
897
|
-
pathname = deBuffer(pathname);
|
|
898
|
-
const item = this._system.getItem(pathname);
|
|
899
|
-
if (item) {
|
|
900
|
-
if (recursive && item instanceof Directory) {
|
|
901
|
-
// silently pass existing folder in recursive mode
|
|
902
|
-
return;
|
|
903
|
-
}
|
|
904
|
-
throw new FSError('EEXIST', pathname);
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
const _mkdir = function (_pathname) {
|
|
908
|
-
const parentDir = path.dirname(_pathname);
|
|
909
|
-
let parent = this._system.getItem(parentDir);
|
|
910
|
-
if (!parent) {
|
|
911
|
-
if (!recursive) {
|
|
912
|
-
throw new FSError('ENOENT', _pathname);
|
|
913
|
-
}
|
|
914
|
-
parent = _mkdir(parentDir, true);
|
|
915
|
-
}
|
|
916
|
-
this.access(parentDir, parseInt('0002', 8));
|
|
917
|
-
const dir = new Directory();
|
|
918
|
-
if (mode) {
|
|
919
|
-
dir.setMode(mode);
|
|
920
|
-
}
|
|
921
|
-
return parent.addItem(path.basename(_pathname), dir);
|
|
922
|
-
}.bind(this);
|
|
923
|
-
|
|
924
|
-
_mkdir(pathname);
|
|
925
|
-
});
|
|
926
|
-
};
|
|
927
|
-
|
|
928
|
-
/**
|
|
929
|
-
* Remove a directory.
|
|
930
|
-
* @param {string} pathname Path to directory.
|
|
931
|
-
* @param {function(Error)} callback Optional callback.
|
|
932
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
933
|
-
* @return {*} The return if no callback is provided.
|
|
934
|
-
*/
|
|
935
|
-
Binding.prototype.rmdir = function (pathname, callback, ctx) {
|
|
936
|
-
markSyscall(ctx, 'rmdir');
|
|
937
|
-
|
|
938
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
939
|
-
pathname = deBuffer(pathname);
|
|
940
|
-
const item = this._system.getItem(pathname);
|
|
941
|
-
if (!item) {
|
|
942
|
-
throw new FSError('ENOENT', pathname);
|
|
943
|
-
}
|
|
944
|
-
if (!(item instanceof Directory)) {
|
|
945
|
-
throw new FSError('ENOTDIR', pathname);
|
|
946
|
-
}
|
|
947
|
-
if (item.list().length > 0) {
|
|
948
|
-
throw new FSError('ENOTEMPTY', pathname);
|
|
949
|
-
}
|
|
950
|
-
this.access(path.dirname(pathname), parseInt('0002', 8));
|
|
951
|
-
const parent = this._system.getItem(path.dirname(pathname));
|
|
952
|
-
parent.removeItem(path.basename(pathname));
|
|
953
|
-
});
|
|
954
|
-
};
|
|
955
|
-
|
|
956
|
-
const PATH_CHARS =
|
|
957
|
-
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
|
958
|
-
|
|
959
|
-
const MAX_ATTEMPTS = 62 * 62 * 62;
|
|
960
|
-
|
|
961
|
-
/**
|
|
962
|
-
* Create a directory based on a template.
|
|
963
|
-
* See http://web.mit.edu/freebsd/head/lib/libc/stdio/mktemp.c
|
|
964
|
-
* @param {string} prefix Path template (trailing Xs will be replaced).
|
|
965
|
-
* @param {string} encoding The encoding ('utf-8' or 'buffer').
|
|
966
|
-
* @param {function(Error, string)} callback Optional callback.
|
|
967
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
968
|
-
* @return {*} The return if no callback is provided.
|
|
969
|
-
*/
|
|
970
|
-
Binding.prototype.mkdtemp = function (prefix, encoding, callback, ctx) {
|
|
971
|
-
if (encoding && typeof encoding !== 'string') {
|
|
972
|
-
callback = encoding;
|
|
973
|
-
encoding = 'utf-8';
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
markSyscall(ctx, 'mkdtemp');
|
|
977
|
-
|
|
978
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
979
|
-
prefix = prefix.replace(/X{0,6}$/, 'XXXXXX');
|
|
980
|
-
const parentPath = path.dirname(prefix);
|
|
981
|
-
const parent = this._system.getItem(parentPath);
|
|
982
|
-
if (!parent) {
|
|
983
|
-
throw new FSError('ENOENT', prefix);
|
|
984
|
-
}
|
|
985
|
-
if (!(parent instanceof Directory)) {
|
|
986
|
-
throw new FSError('ENOTDIR', prefix);
|
|
987
|
-
}
|
|
988
|
-
this.access(parentPath, parseInt('0002', 8));
|
|
989
|
-
const template = path.basename(prefix);
|
|
990
|
-
let unique = false;
|
|
991
|
-
let count = 0;
|
|
992
|
-
let name;
|
|
993
|
-
while (!unique && count < MAX_ATTEMPTS) {
|
|
994
|
-
let position = template.length - 1;
|
|
995
|
-
let replacement = '';
|
|
996
|
-
while (template.charAt(position) === 'X') {
|
|
997
|
-
replacement += PATH_CHARS.charAt(
|
|
998
|
-
Math.floor(PATH_CHARS.length * Math.random())
|
|
999
|
-
);
|
|
1000
|
-
position -= 1;
|
|
1001
|
-
}
|
|
1002
|
-
const candidate = template.slice(0, position + 1) + replacement;
|
|
1003
|
-
if (!parent.getItem(candidate)) {
|
|
1004
|
-
name = candidate;
|
|
1005
|
-
unique = true;
|
|
1006
|
-
}
|
|
1007
|
-
count += 1;
|
|
1008
|
-
}
|
|
1009
|
-
if (!name) {
|
|
1010
|
-
throw new FSError('EEXIST', prefix);
|
|
1011
|
-
}
|
|
1012
|
-
const dir = new Directory();
|
|
1013
|
-
parent.addItem(name, dir);
|
|
1014
|
-
let uniquePath = path.join(parentPath, name);
|
|
1015
|
-
if (encoding === 'buffer') {
|
|
1016
|
-
uniquePath = Buffer.from(uniquePath);
|
|
1017
|
-
}
|
|
1018
|
-
return uniquePath;
|
|
1019
|
-
});
|
|
1020
|
-
};
|
|
1021
|
-
|
|
1022
|
-
/**
|
|
1023
|
-
* Truncate a file.
|
|
1024
|
-
* @param {number} fd File descriptor.
|
|
1025
|
-
* @param {number} len Number of bytes.
|
|
1026
|
-
* @param {function(Error)} callback Optional callback.
|
|
1027
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1028
|
-
* @return {*} The return if no callback is provided.
|
|
1029
|
-
*/
|
|
1030
|
-
Binding.prototype.ftruncate = function (fd, len, callback, ctx) {
|
|
1031
|
-
markSyscall(ctx, 'ftruncate');
|
|
1032
|
-
|
|
1033
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1034
|
-
const descriptor = this.getDescriptorById(fd);
|
|
1035
|
-
if (!descriptor.isWrite()) {
|
|
1036
|
-
throw new FSError('EINVAL');
|
|
1037
|
-
}
|
|
1038
|
-
const file = descriptor.getItem();
|
|
1039
|
-
if (!(file instanceof File)) {
|
|
1040
|
-
throw new FSError('EINVAL');
|
|
1041
|
-
}
|
|
1042
|
-
const content = file.getContent();
|
|
1043
|
-
const newContent = Buffer.alloc(len);
|
|
1044
|
-
content.copy(newContent);
|
|
1045
|
-
file.setContent(newContent);
|
|
1046
|
-
});
|
|
1047
|
-
};
|
|
1048
|
-
|
|
1049
|
-
/**
|
|
1050
|
-
* Legacy support.
|
|
1051
|
-
* @param {number} fd File descriptor.
|
|
1052
|
-
* @param {number} len Number of bytes.
|
|
1053
|
-
* @param {function(Error)} callback Optional callback.
|
|
1054
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1055
|
-
*/
|
|
1056
|
-
Binding.prototype.truncate = Binding.prototype.ftruncate;
|
|
1057
|
-
|
|
1058
|
-
/**
|
|
1059
|
-
* Change user and group owner.
|
|
1060
|
-
* @param {string} pathname Path.
|
|
1061
|
-
* @param {number} uid User id.
|
|
1062
|
-
* @param {number} gid Group id.
|
|
1063
|
-
* @param {function(Error)} callback Optional callback.
|
|
1064
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1065
|
-
* @return {*} The return if no callback is provided.
|
|
1066
|
-
*/
|
|
1067
|
-
Binding.prototype.chown = function (pathname, uid, gid, callback, ctx) {
|
|
1068
|
-
markSyscall(ctx, 'chown');
|
|
1069
|
-
|
|
1070
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1071
|
-
pathname = deBuffer(pathname);
|
|
1072
|
-
const item = this._system.getItem(pathname);
|
|
1073
|
-
if (!item) {
|
|
1074
|
-
throw new FSError('ENOENT', pathname);
|
|
1075
|
-
}
|
|
1076
|
-
item.setUid(uid);
|
|
1077
|
-
item.setGid(gid);
|
|
1078
|
-
});
|
|
1079
|
-
};
|
|
1080
|
-
|
|
1081
|
-
/**
|
|
1082
|
-
* Change user and group owner.
|
|
1083
|
-
* @param {number} fd File descriptor.
|
|
1084
|
-
* @param {number} uid User id.
|
|
1085
|
-
* @param {number} gid Group id.
|
|
1086
|
-
* @param {function(Error)} callback Optional callback.
|
|
1087
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1088
|
-
* @return {*} The return if no callback is provided.
|
|
1089
|
-
*/
|
|
1090
|
-
Binding.prototype.fchown = function (fd, uid, gid, callback, ctx) {
|
|
1091
|
-
markSyscall(ctx, 'fchown');
|
|
1092
|
-
|
|
1093
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1094
|
-
const descriptor = this.getDescriptorById(fd);
|
|
1095
|
-
const item = descriptor.getItem();
|
|
1096
|
-
item.setUid(uid);
|
|
1097
|
-
item.setGid(gid);
|
|
1098
|
-
});
|
|
1099
|
-
};
|
|
1100
|
-
|
|
1101
|
-
/**
|
|
1102
|
-
* Change permissions.
|
|
1103
|
-
* @param {string} pathname Path.
|
|
1104
|
-
* @param {number} mode Mode.
|
|
1105
|
-
* @param {function(Error)} callback Optional callback.
|
|
1106
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1107
|
-
* @return {*} The return if no callback is provided.
|
|
1108
|
-
*/
|
|
1109
|
-
Binding.prototype.chmod = function (pathname, mode, callback, ctx) {
|
|
1110
|
-
markSyscall(ctx, 'chmod');
|
|
1111
|
-
|
|
1112
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1113
|
-
pathname = deBuffer(pathname);
|
|
1114
|
-
const item = this._system.getItem(pathname);
|
|
1115
|
-
if (!item) {
|
|
1116
|
-
throw new FSError('ENOENT', pathname);
|
|
1117
|
-
}
|
|
1118
|
-
item.setMode(mode);
|
|
1119
|
-
});
|
|
1120
|
-
};
|
|
1121
|
-
|
|
1122
|
-
/**
|
|
1123
|
-
* Change permissions.
|
|
1124
|
-
* @param {number} fd File descriptor.
|
|
1125
|
-
* @param {number} mode Mode.
|
|
1126
|
-
* @param {function(Error)} callback Optional callback.
|
|
1127
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1128
|
-
* @return {*} The return if no callback is provided.
|
|
1129
|
-
*/
|
|
1130
|
-
Binding.prototype.fchmod = function (fd, mode, callback, ctx) {
|
|
1131
|
-
markSyscall(ctx, 'fchmod');
|
|
1132
|
-
|
|
1133
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1134
|
-
const descriptor = this.getDescriptorById(fd);
|
|
1135
|
-
const item = descriptor.getItem();
|
|
1136
|
-
item.setMode(mode);
|
|
1137
|
-
});
|
|
1138
|
-
};
|
|
1139
|
-
|
|
1140
|
-
/**
|
|
1141
|
-
* Delete a named item.
|
|
1142
|
-
* @param {string} pathname Path to item.
|
|
1143
|
-
* @param {function(Error)} callback Optional callback.
|
|
1144
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1145
|
-
* @return {*} The return if no callback is provided.
|
|
1146
|
-
*/
|
|
1147
|
-
Binding.prototype.unlink = function (pathname, callback, ctx) {
|
|
1148
|
-
markSyscall(ctx, 'unlink');
|
|
1149
|
-
|
|
1150
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1151
|
-
pathname = deBuffer(pathname);
|
|
1152
|
-
const item = this._system.getItem(pathname);
|
|
1153
|
-
if (!item) {
|
|
1154
|
-
throw new FSError('ENOENT', pathname);
|
|
1155
|
-
}
|
|
1156
|
-
if (item instanceof Directory) {
|
|
1157
|
-
throw new FSError('EPERM', pathname);
|
|
1158
|
-
}
|
|
1159
|
-
const parent = this._system.getItem(path.dirname(pathname));
|
|
1160
|
-
parent.removeItem(path.basename(pathname));
|
|
1161
|
-
});
|
|
1162
|
-
};
|
|
1163
|
-
|
|
1164
|
-
/**
|
|
1165
|
-
* Delete a named item.
|
|
1166
|
-
* @param {string} pathname Path to item.
|
|
1167
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1168
|
-
* @return {*} The return if no callback is provided.
|
|
1169
|
-
*/
|
|
1170
|
-
Binding.prototype.unlinkSync = function (pathname, ctx) {
|
|
1171
|
-
return this.unlink(pathname, undefined, ctx);
|
|
1172
|
-
};
|
|
1173
|
-
|
|
1174
|
-
/**
|
|
1175
|
-
* Update timestamps.
|
|
1176
|
-
* @param {string} pathname Path to item.
|
|
1177
|
-
* @param {number} atime Access time (in seconds).
|
|
1178
|
-
* @param {number} mtime Modification time (in seconds).
|
|
1179
|
-
* @param {function(Error)} callback Optional callback.
|
|
1180
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1181
|
-
* @return {*} The return if no callback is provided.
|
|
1182
|
-
*/
|
|
1183
|
-
Binding.prototype.utimes = function (pathname, atime, mtime, callback, ctx) {
|
|
1184
|
-
markSyscall(ctx, 'utimes');
|
|
1185
|
-
|
|
1186
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1187
|
-
let filepath = deBuffer(pathname);
|
|
1188
|
-
let item = this._system.getItem(filepath);
|
|
1189
|
-
let links = 0;
|
|
1190
|
-
while (item instanceof SymbolicLink) {
|
|
1191
|
-
if (links > MAX_LINKS) {
|
|
1192
|
-
throw new FSError('ELOOP', filepath);
|
|
1193
|
-
}
|
|
1194
|
-
filepath = path.resolve(path.dirname(filepath), item.getPath());
|
|
1195
|
-
item = this._system.getItem(filepath);
|
|
1196
|
-
++links;
|
|
1197
|
-
}
|
|
1198
|
-
if (!item) {
|
|
1199
|
-
throw new FSError('ENOENT', pathname);
|
|
1200
|
-
}
|
|
1201
|
-
item.setATime(new Date(atime * 1000));
|
|
1202
|
-
item.setMTime(new Date(mtime * 1000));
|
|
1203
|
-
});
|
|
1204
|
-
};
|
|
1205
|
-
|
|
1206
|
-
/**
|
|
1207
|
-
* Update timestamps.
|
|
1208
|
-
* @param {string} pathname Path to item.
|
|
1209
|
-
* @param {number} atime Access time (in seconds).
|
|
1210
|
-
* @param {number} mtime Modification time (in seconds).
|
|
1211
|
-
* @param {function(Error)} callback Optional callback.
|
|
1212
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1213
|
-
* @return {*} The return if no callback is provided.
|
|
1214
|
-
*/
|
|
1215
|
-
Binding.prototype.lutimes = function (pathname, atime, mtime, callback, ctx) {
|
|
1216
|
-
markSyscall(ctx, 'utimes');
|
|
1217
|
-
|
|
1218
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1219
|
-
pathname = deBuffer(pathname);
|
|
1220
|
-
const item = this._system.getItem(pathname);
|
|
1221
|
-
if (!item) {
|
|
1222
|
-
throw new FSError('ENOENT', pathname);
|
|
1223
|
-
}
|
|
1224
|
-
// lutimes doesn't follow symlink
|
|
1225
|
-
item.setATime(new Date(atime * 1000));
|
|
1226
|
-
item.setMTime(new Date(mtime * 1000));
|
|
1227
|
-
});
|
|
1228
|
-
};
|
|
1229
|
-
|
|
1230
|
-
/**
|
|
1231
|
-
* Update timestamps.
|
|
1232
|
-
* @param {number} fd File descriptor.
|
|
1233
|
-
* @param {number} atime Access time (in seconds).
|
|
1234
|
-
* @param {number} mtime Modification time (in seconds).
|
|
1235
|
-
* @param {function(Error)} callback Optional callback.
|
|
1236
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1237
|
-
* @return {*} The return if no callback is provided.
|
|
1238
|
-
*/
|
|
1239
|
-
Binding.prototype.futimes = function (fd, atime, mtime, callback, ctx) {
|
|
1240
|
-
markSyscall(ctx, 'futimes');
|
|
1241
|
-
|
|
1242
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1243
|
-
const descriptor = this.getDescriptorById(fd);
|
|
1244
|
-
let item = descriptor.getItem();
|
|
1245
|
-
let filepath = this._system.getFilepath(item);
|
|
1246
|
-
let links = 0;
|
|
1247
|
-
while (item instanceof SymbolicLink) {
|
|
1248
|
-
if (links > MAX_LINKS) {
|
|
1249
|
-
throw new FSError('ELOOP', filepath);
|
|
1250
|
-
}
|
|
1251
|
-
filepath = path.resolve(path.dirname(filepath), item.getPath());
|
|
1252
|
-
item = this._system.getItem(filepath);
|
|
1253
|
-
++links;
|
|
1254
|
-
}
|
|
1255
|
-
item.setATime(new Date(atime * 1000));
|
|
1256
|
-
item.setMTime(new Date(mtime * 1000));
|
|
1257
|
-
});
|
|
1258
|
-
};
|
|
1259
|
-
|
|
1260
|
-
/**
|
|
1261
|
-
* Synchronize in-core state with storage device.
|
|
1262
|
-
* @param {number} fd File descriptor.
|
|
1263
|
-
* @param {function(Error)} callback Optional callback.
|
|
1264
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1265
|
-
* @return {*} The return if no callback is provided.
|
|
1266
|
-
*/
|
|
1267
|
-
Binding.prototype.fsync = function (fd, callback, ctx) {
|
|
1268
|
-
markSyscall(ctx, 'fsync');
|
|
1269
|
-
|
|
1270
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1271
|
-
this.getDescriptorById(fd);
|
|
1272
|
-
});
|
|
1273
|
-
};
|
|
1274
|
-
|
|
1275
|
-
/**
|
|
1276
|
-
* Synchronize in-core metadata state with storage device.
|
|
1277
|
-
* @param {number} fd File descriptor.
|
|
1278
|
-
* @param {function(Error)} callback Optional callback.
|
|
1279
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1280
|
-
* @return {*} The return if no callback is provided.
|
|
1281
|
-
*/
|
|
1282
|
-
Binding.prototype.fdatasync = function (fd, callback, ctx) {
|
|
1283
|
-
markSyscall(ctx, 'fdatasync');
|
|
1284
|
-
|
|
1285
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1286
|
-
this.getDescriptorById(fd);
|
|
1287
|
-
});
|
|
1288
|
-
};
|
|
1289
|
-
|
|
1290
|
-
/**
|
|
1291
|
-
* Create a hard link.
|
|
1292
|
-
* @param {string} srcPath The existing file.
|
|
1293
|
-
* @param {string} destPath The new link to create.
|
|
1294
|
-
* @param {function(Error)} callback Optional callback.
|
|
1295
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1296
|
-
* @return {*} The return if no callback is provided.
|
|
1297
|
-
*/
|
|
1298
|
-
Binding.prototype.link = function (srcPath, destPath, callback, ctx) {
|
|
1299
|
-
markSyscall(ctx, 'link');
|
|
1300
|
-
|
|
1301
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1302
|
-
srcPath = deBuffer(srcPath);
|
|
1303
|
-
destPath = deBuffer(destPath);
|
|
1304
|
-
const item = this._system.getItem(srcPath);
|
|
1305
|
-
if (!item) {
|
|
1306
|
-
throw new FSError('ENOENT', srcPath);
|
|
1307
|
-
}
|
|
1308
|
-
if (item instanceof Directory) {
|
|
1309
|
-
throw new FSError('EPERM', srcPath);
|
|
1310
|
-
}
|
|
1311
|
-
if (this._system.getItem(destPath)) {
|
|
1312
|
-
throw new FSError('EEXIST', destPath);
|
|
1313
|
-
}
|
|
1314
|
-
const parent = this._system.getItem(path.dirname(destPath));
|
|
1315
|
-
if (!parent) {
|
|
1316
|
-
throw new FSError('ENOENT', destPath);
|
|
1317
|
-
}
|
|
1318
|
-
if (!(parent instanceof Directory)) {
|
|
1319
|
-
throw new FSError('ENOTDIR', destPath);
|
|
1320
|
-
}
|
|
1321
|
-
parent.addItem(path.basename(destPath), item);
|
|
1322
|
-
});
|
|
1323
|
-
};
|
|
1324
|
-
|
|
1325
|
-
/**
|
|
1326
|
-
* Create a symbolic link.
|
|
1327
|
-
* @param {string} srcPath Path from link to the source file.
|
|
1328
|
-
* @param {string} destPath Path for the generated link.
|
|
1329
|
-
* @param {string} type Ignored (used for Windows only).
|
|
1330
|
-
* @param {function(Error)} callback Optional callback.
|
|
1331
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1332
|
-
* @return {*} The return if no callback is provided.
|
|
1333
|
-
*/
|
|
1334
|
-
Binding.prototype.symlink = function (srcPath, destPath, type, callback, ctx) {
|
|
1335
|
-
markSyscall(ctx, 'symlink');
|
|
1336
|
-
|
|
1337
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1338
|
-
srcPath = deBuffer(srcPath);
|
|
1339
|
-
destPath = deBuffer(destPath);
|
|
1340
|
-
if (this._system.getItem(destPath)) {
|
|
1341
|
-
throw new FSError('EEXIST', destPath);
|
|
1342
|
-
}
|
|
1343
|
-
const parent = this._system.getItem(path.dirname(destPath));
|
|
1344
|
-
if (!parent) {
|
|
1345
|
-
throw new FSError('ENOENT', destPath);
|
|
1346
|
-
}
|
|
1347
|
-
if (!(parent instanceof Directory)) {
|
|
1348
|
-
throw new FSError('ENOTDIR', destPath);
|
|
1349
|
-
}
|
|
1350
|
-
const link = new SymbolicLink();
|
|
1351
|
-
link.setPath(srcPath);
|
|
1352
|
-
parent.addItem(path.basename(destPath), link);
|
|
1353
|
-
});
|
|
1354
|
-
};
|
|
1355
|
-
|
|
1356
|
-
/**
|
|
1357
|
-
* Create a symbolic link.
|
|
1358
|
-
* @param {string} srcPath Path from link to the source file.
|
|
1359
|
-
* @param {string} destPath Path for the generated link.
|
|
1360
|
-
* @param {string} type Ignored (used for Windows only).
|
|
1361
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1362
|
-
* @return {*} The return if no callback is provided.
|
|
1363
|
-
*/
|
|
1364
|
-
Binding.prototype.symlinkSync = function (srcPath, destPath, type, ctx) {
|
|
1365
|
-
return this.symlink(srcPath, destPath, type, undefined, ctx);
|
|
1366
|
-
};
|
|
1367
|
-
|
|
1368
|
-
/**
|
|
1369
|
-
* Read the contents of a symbolic link.
|
|
1370
|
-
* @param {string} pathname Path to symbolic link.
|
|
1371
|
-
* @param {string} encoding The encoding ('utf-8' or 'buffer').
|
|
1372
|
-
* @param {function(Error, (string|Buffer))} callback Optional callback.
|
|
1373
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1374
|
-
* @return {string|Buffer} Symbolic link contents (path to source).
|
|
1375
|
-
*/
|
|
1376
|
-
Binding.prototype.readlink = function (pathname, encoding, callback, ctx) {
|
|
1377
|
-
if (encoding && typeof encoding !== 'string') {
|
|
1378
|
-
// this would not happend in nodejs v10+
|
|
1379
|
-
callback = encoding;
|
|
1380
|
-
encoding = 'utf-8';
|
|
1381
|
-
}
|
|
1382
|
-
|
|
1383
|
-
markSyscall(ctx, 'readlink');
|
|
1384
|
-
|
|
1385
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1386
|
-
pathname = deBuffer(pathname);
|
|
1387
|
-
const link = this._system.getItem(pathname);
|
|
1388
|
-
if (!link) {
|
|
1389
|
-
throw new FSError('ENOENT', pathname);
|
|
1390
|
-
}
|
|
1391
|
-
if (!(link instanceof SymbolicLink)) {
|
|
1392
|
-
throw new FSError('EINVAL', pathname);
|
|
1393
|
-
}
|
|
1394
|
-
let linkPath = link.getPath();
|
|
1395
|
-
if (encoding === 'buffer') {
|
|
1396
|
-
linkPath = Buffer.from(linkPath);
|
|
1397
|
-
}
|
|
1398
|
-
return linkPath;
|
|
1399
|
-
});
|
|
1400
|
-
};
|
|
1401
|
-
|
|
1402
|
-
/**
|
|
1403
|
-
* Stat an item.
|
|
1404
|
-
* @param {string} filepath Path.
|
|
1405
|
-
* @param {boolean} bigint Use BigInt.
|
|
1406
|
-
* @param {function(Error, Float64Array|BigUint64Array)} callback Callback (optional).
|
|
1407
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1408
|
-
* @return {Float64Array|BigUint64Array|undefined} Stats or undefined (if sync).
|
|
1409
|
-
*/
|
|
1410
|
-
Binding.prototype.lstat = function (filepath, bigint, callback, ctx) {
|
|
1411
|
-
markSyscall(ctx, 'lstat');
|
|
1412
|
-
|
|
1413
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1414
|
-
filepath = deBuffer(filepath);
|
|
1415
|
-
const item = this._system.getItem(filepath);
|
|
1416
|
-
if (!item) {
|
|
1417
|
-
throw new FSError('ENOENT', filepath);
|
|
1418
|
-
}
|
|
1419
|
-
const stats = item.getStats(bigint);
|
|
1420
|
-
fillStats(stats, bigint);
|
|
1421
|
-
return stats;
|
|
1422
|
-
});
|
|
1423
|
-
};
|
|
1424
|
-
|
|
1425
|
-
/**
|
|
1426
|
-
* Tests user permissions.
|
|
1427
|
-
* @param {string} filepath Path.
|
|
1428
|
-
* @param {number} mode Mode.
|
|
1429
|
-
* @param {function(Error)} callback Callback (optional).
|
|
1430
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1431
|
-
* @return {*} The return if no callback is provided.
|
|
1432
|
-
*/
|
|
1433
|
-
Binding.prototype.access = function (filepath, mode, callback, ctx) {
|
|
1434
|
-
markSyscall(ctx, 'access');
|
|
1435
|
-
|
|
1436
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1437
|
-
filepath = deBuffer(filepath);
|
|
1438
|
-
let item = this._system.getItem(filepath);
|
|
1439
|
-
let links = 0;
|
|
1440
|
-
while (item instanceof SymbolicLink) {
|
|
1441
|
-
if (links > MAX_LINKS) {
|
|
1442
|
-
throw new FSError('ELOOP', filepath);
|
|
1443
|
-
}
|
|
1444
|
-
filepath = path.resolve(path.dirname(filepath), item.getPath());
|
|
1445
|
-
item = this._system.getItem(filepath);
|
|
1446
|
-
++links;
|
|
1447
|
-
}
|
|
1448
|
-
if (!item) {
|
|
1449
|
-
throw new FSError('ENOENT', filepath);
|
|
1450
|
-
}
|
|
1451
|
-
if (mode && process.getuid && process.getgid) {
|
|
1452
|
-
if (mode & constants.R_OK && !item.canRead()) {
|
|
1453
|
-
throw new FSError('EACCES', filepath);
|
|
1454
|
-
}
|
|
1455
|
-
if (mode & constants.W_OK && !item.canWrite()) {
|
|
1456
|
-
throw new FSError('EACCES', filepath);
|
|
1457
|
-
}
|
|
1458
|
-
if (mode & constants.X_OK && !item.canExecute()) {
|
|
1459
|
-
throw new FSError('EACCES', filepath);
|
|
1460
|
-
}
|
|
1461
|
-
}
|
|
1462
|
-
});
|
|
1463
|
-
};
|
|
1464
|
-
|
|
1465
|
-
/**
|
|
1466
|
-
* Tests user permissions.
|
|
1467
|
-
* @param {string} filepath Path.
|
|
1468
|
-
* @param {number} mode Mode.
|
|
1469
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1470
|
-
* @return {*} The return if no callback is provided.
|
|
1471
|
-
*/
|
|
1472
|
-
Binding.prototype.accessSync = function (filepath, mode, ctx) {
|
|
1473
|
-
return this.access(filepath, mode, undefined, ctx);
|
|
1474
|
-
};
|
|
1475
|
-
|
|
1476
|
-
/**
|
|
1477
|
-
* Tests whether or not the given path exists.
|
|
1478
|
-
* @param {string} filepath Path.
|
|
1479
|
-
* @param {function(Error)} callback Callback (optional).
|
|
1480
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1481
|
-
* @return {*} The return if no callback is provided.
|
|
1482
|
-
*/
|
|
1483
|
-
Binding.prototype.exists = function (filepath, callback, ctx) {
|
|
1484
|
-
markSyscall(ctx, 'exists');
|
|
1485
|
-
|
|
1486
|
-
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
|
|
1487
|
-
filepath = deBuffer(filepath);
|
|
1488
|
-
let item;
|
|
1489
|
-
try {
|
|
1490
|
-
item = this._system.getItem(filepath);
|
|
1491
|
-
} catch {
|
|
1492
|
-
// ignore errors
|
|
1493
|
-
// see https://github.com/nodejs/node/blob/v22.11.0/lib/fs.js#L255-L257
|
|
1494
|
-
return false;
|
|
1495
|
-
}
|
|
1496
|
-
|
|
1497
|
-
if (item) {
|
|
1498
|
-
if (item instanceof SymbolicLink) {
|
|
1499
|
-
return this.exists(item.getPath(), callback, ctx);
|
|
1500
|
-
}
|
|
1501
|
-
return true;
|
|
1502
|
-
}
|
|
1503
|
-
return false;
|
|
1504
|
-
});
|
|
1505
|
-
};
|
|
1506
|
-
|
|
1507
|
-
/**
|
|
1508
|
-
* Tests whether or not the given path exists.
|
|
1509
|
-
* @param {string} filepath Path.
|
|
1510
|
-
* @param {object} ctx Context object (optional), only for nodejs v10+.
|
|
1511
|
-
* @return {*} The return if no callback is provided.
|
|
1512
|
-
*/
|
|
1513
|
-
Binding.prototype.existsSync = function (filepath, ctx) {
|
|
1514
|
-
return this.exists(filepath, undefined, ctx);
|
|
1515
|
-
};
|
|
1516
|
-
|
|
1517
|
-
/**
|
|
1518
|
-
* Not yet implemented.
|
|
1519
|
-
* @type {function()}
|
|
1520
|
-
*/
|
|
1521
|
-
Binding.prototype.StatWatcher = notImplemented;
|
|
1522
|
-
|
|
1523
|
-
/**
|
|
1524
|
-
* Export the binding constructor.
|
|
1525
|
-
* @type {function()}
|
|
1526
|
-
*/
|
|
1527
|
-
module.exports = Binding;
|