fake-node 0.2.0 → 0.4.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/LICENSE +21 -0
- package/README.md +3 -0
- package/lib/_fs.d.ts +254 -0
- package/lib/_fs.js +750 -0
- package/lib/_fs.js.map +1 -0
- package/lib/buffer.d.ts +9 -0
- package/lib/buffer.js +12 -0
- package/lib/buffer.js.map +1 -0
- package/lib/fs.d.ts +110 -0
- package/lib/fs.js +223 -0
- package/lib/fs.js.map +1 -0
- package/lib/index.d.ts +80 -0
- package/lib/index.js +311 -0
- package/lib/index.js.map +1 -0
- package/lib/os.d.ts +191 -0
- package/lib/os.js +261 -0
- package/lib/os.js.map +1 -0
- package/lib/path.d.ts +55 -0
- package/lib/path.js +105 -0
- package/lib/path.js.map +1 -0
- package/lib/process.d.ts +103 -0
- package/lib/process.js +216 -0
- package/lib/process.js.map +1 -0
- package/lib/querystring.d.ts +7 -0
- package/lib/querystring.js +39 -0
- package/lib/querystring.js.map +1 -0
- package/lib/util.d.ts +145 -0
- package/lib/util.js +460 -0
- package/lib/util.js.map +1 -0
- package/lib/web_only_globals.json +1049 -0
- package/package.json +12 -13
- package/src/_fs.ts +852 -0
- package/src/buffer.ts +13 -0
- package/src/fs.ts +230 -0
- package/src/in_fake_node.d.ts +12 -0
- package/src/index.ts +321 -0
- package/src/os.ts +259 -0
- package/src/path.ts +141 -0
- package/src/process.ts +245 -0
- package/src/querystring.ts +36 -0
- package/src/util.ts +521 -0
- package/index.js +0 -171
- package/index.ts +0 -148
- package/tsconfig.json +0 -10
- /package/{web_only_globals.json → src/web_only_globals.json} +0 -0
package/lib/_fs.js
ADDED
@@ -0,0 +1,750 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.DEFAULT_FILES = exports.FileSystem = exports.Directory = exports.RegularFile = exports.FileObject = exports.currentExportFormatVersion = exports.BigIntStatFs = exports.StatFs = exports.BigIntStats = exports.Stats = exports.gidGetter = exports.uidGetter = exports.cwdGetter = exports.constants = void 0;
|
4
|
+
exports.normalize = normalize;
|
5
|
+
exports.setCwdGetter = setCwdGetter;
|
6
|
+
exports.setUidGetter = setUidGetter;
|
7
|
+
exports.setGidGetter = setGidGetter;
|
8
|
+
exports.resolve = resolve;
|
9
|
+
exports.parsePathArg = parsePathArg;
|
10
|
+
exports.parseFlag = parseFlag;
|
11
|
+
exports.parseTimeArg = parseTimeArg;
|
12
|
+
exports.parseDataArg = parseDataArg;
|
13
|
+
exports.parseModeArg = parseModeArg;
|
14
|
+
/// <reference path="./in_fake_node.d.ts" />
|
15
|
+
const buffer_1 = require("./buffer");
|
16
|
+
const F_OK = 0;
|
17
|
+
const X_OK = 1;
|
18
|
+
const W_OK = 2;
|
19
|
+
const R_OK = 4;
|
20
|
+
const COPYFILE_EXCL = 1;
|
21
|
+
const COPYFILE_FICLONE = 2;
|
22
|
+
const COPYFILE_FICLONE_FORCE = 4;
|
23
|
+
const O_RDONLY = 1;
|
24
|
+
const O_WRONLY = 2;
|
25
|
+
const O_RDWR = O_RDONLY | O_WRONLY;
|
26
|
+
const O_CREAT = 4;
|
27
|
+
const O_EXCL = 8;
|
28
|
+
const O_NOCTTY = 16;
|
29
|
+
const O_TRUNC = 32;
|
30
|
+
const O_APPEND = 64;
|
31
|
+
const O_DIRECTORY = 128;
|
32
|
+
const O_NOATIME = 256;
|
33
|
+
const O_NOFOLLOW = 512;
|
34
|
+
const O_SYNC = 1024;
|
35
|
+
const O_DSYNC = 2048;
|
36
|
+
const O_SYMLINK = 4096;
|
37
|
+
const O_DIRECT = 8192;
|
38
|
+
const O_NONBLOCK = 16384;
|
39
|
+
const UV_FS_O_FILEMAP = 32768;
|
40
|
+
const S_IMFT = 0xF000;
|
41
|
+
const S_IFREG = 0x8000;
|
42
|
+
const S_IFDIR = 0x4000;
|
43
|
+
const S_IFCHR = 0x2000;
|
44
|
+
const S_IFBLK = 0x6000;
|
45
|
+
const S_IFIFO = 0x1000;
|
46
|
+
const S_IFLNK = 0xA000;
|
47
|
+
const S_IFSOCK = 0xC000;
|
48
|
+
const S_IRWXU = 0o700;
|
49
|
+
const S_IRUSR = 0o400;
|
50
|
+
const S_IWUSR = 0o200;
|
51
|
+
const S_IXUSR = 0o100;
|
52
|
+
const S_IRWXG = 0o070;
|
53
|
+
const S_IRGRP = 0o040;
|
54
|
+
const S_IWGRP = 0o020;
|
55
|
+
const S_IXGRP = 0o010;
|
56
|
+
const S_IRWXO = 0o007;
|
57
|
+
const S_IROTH = 0o004;
|
58
|
+
const S_IWOTH = 0o002;
|
59
|
+
const S_IXOTH = 0o001;
|
60
|
+
exports.constants = { F_OK, X_OK, W_OK, R_OK, COPYFILE_EXCL, COPYFILE_FICLONE, COPYFILE_FICLONE_FORCE, O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND, O_DIRECTORY, O_NOATIME, O_NOFOLLOW, O_SYNC, O_DSYNC, O_SYMLINK, O_DIRECT, O_NONBLOCK, UV_FS_O_FILEMAP, S_IMFT, S_IFREG, S_IFDIR, S_IFCHR, S_IFBLK, S_IFIFO, S_IFLNK, S_IFSOCK, S_IRWXU, S_IRUSR, S_IWUSR, S_IXUSR, S_IRWXG, S_IRGRP, S_IWGRP, S_IXGRP, S_IRWXO, S_IROTH, S_IWOTH, S_IXOTH };
|
61
|
+
// functions copied over from path module so they can be used outside of fake-node
|
62
|
+
function normalize(path) {
|
63
|
+
let out = [];
|
64
|
+
for (const segment of path.split('/')) {
|
65
|
+
if (segment === '' || segment === '.') {
|
66
|
+
continue;
|
67
|
+
}
|
68
|
+
else if (segment === '..') {
|
69
|
+
out.pop();
|
70
|
+
}
|
71
|
+
else {
|
72
|
+
out.push(segment);
|
73
|
+
}
|
74
|
+
}
|
75
|
+
return out.join('/');
|
76
|
+
}
|
77
|
+
let cwdGetter = () => __fakeNode_process__.cwd;
|
78
|
+
exports.cwdGetter = cwdGetter;
|
79
|
+
let uidGetter = () => __fakeNode_process__.uid;
|
80
|
+
exports.uidGetter = uidGetter;
|
81
|
+
let gidGetter = () => __fakeNode_process__.gid;
|
82
|
+
exports.gidGetter = gidGetter;
|
83
|
+
function setCwdGetter(newGetter) {
|
84
|
+
exports.cwdGetter = newGetter;
|
85
|
+
}
|
86
|
+
function setUidGetter(newGetter) {
|
87
|
+
exports.uidGetter = newGetter;
|
88
|
+
}
|
89
|
+
function setGidGetter(newGetter) {
|
90
|
+
exports.gidGetter = newGetter;
|
91
|
+
}
|
92
|
+
function resolve(...paths) {
|
93
|
+
let out = '';
|
94
|
+
for (let i = paths.length - 1; i >= 0; i--) {
|
95
|
+
out += paths[i];
|
96
|
+
if (out.startsWith('/')) {
|
97
|
+
return out;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
return (0, exports.cwdGetter)() + out;
|
101
|
+
}
|
102
|
+
function parsePathArg(arg) {
|
103
|
+
let out;
|
104
|
+
if (typeof arg === 'string') {
|
105
|
+
out = arg;
|
106
|
+
}
|
107
|
+
else if (arg instanceof buffer_1.Buffer) {
|
108
|
+
out = arg.toString('utf-8');
|
109
|
+
}
|
110
|
+
else if (arg instanceof URL) {
|
111
|
+
if (arg.protocol === 'file:') {
|
112
|
+
out = arg.pathname;
|
113
|
+
return normalize(resolve(arg.pathname));
|
114
|
+
}
|
115
|
+
else {
|
116
|
+
throw new TypeError(`invalid file URL: ${arg}`);
|
117
|
+
}
|
118
|
+
}
|
119
|
+
else {
|
120
|
+
throw new TypeError(`invalid path: ${arg}`);
|
121
|
+
}
|
122
|
+
return resolve(normalize(out));
|
123
|
+
}
|
124
|
+
const flags = {
|
125
|
+
'a': O_CREAT | O_APPEND,
|
126
|
+
'ax': O_CREAT | O_EXCL | O_APPEND,
|
127
|
+
'a+': O_RDONLY | O_CREAT | O_APPEND,
|
128
|
+
'ax+': O_RDONLY | O_CREAT | O_EXCL | O_APPEND,
|
129
|
+
'as': O_CREAT | O_APPEND | O_SYNC,
|
130
|
+
'as+': O_RDONLY | O_CREAT | O_APPEND | O_SYNC,
|
131
|
+
'r': O_RDONLY,
|
132
|
+
'rs': O_RDONLY | O_SYNC,
|
133
|
+
'r+': O_RDONLY | O_WRONLY,
|
134
|
+
'rs+': O_RDONLY | O_WRONLY | O_SYNC,
|
135
|
+
'w': O_WRONLY | O_CREAT | O_TRUNC,
|
136
|
+
'wx': O_WRONLY | O_CREAT | O_EXCL | O_TRUNC,
|
137
|
+
'w+': O_RDONLY | O_WRONLY | O_CREAT | O_TRUNC,
|
138
|
+
'wx+': O_RDONLY | O_WRONLY | O_CREAT | O_EXCL | O_TRUNC,
|
139
|
+
};
|
140
|
+
function parseFlag(flag) {
|
141
|
+
if (typeof flag === 'string') {
|
142
|
+
return flags[flag];
|
143
|
+
}
|
144
|
+
else {
|
145
|
+
return flag;
|
146
|
+
}
|
147
|
+
}
|
148
|
+
function parseTimeArg(time) {
|
149
|
+
if (typeof time === 'bigint') {
|
150
|
+
return time;
|
151
|
+
}
|
152
|
+
else if (typeof time === 'number') {
|
153
|
+
return BigInt(time * 1000000000);
|
154
|
+
}
|
155
|
+
else if (typeof time === 'string') {
|
156
|
+
let timestamp = Date.parse(time);
|
157
|
+
if (Number.isNaN(timestamp)) {
|
158
|
+
timestamp = parseInt(time);
|
159
|
+
if (Number.isNaN(timestamp)) {
|
160
|
+
throw new TypeError(`invalid time argument ${time}`);
|
161
|
+
}
|
162
|
+
else {
|
163
|
+
return BigInt(timestamp * 1000000);
|
164
|
+
}
|
165
|
+
}
|
166
|
+
else {
|
167
|
+
return BigInt(timestamp * 1000000);
|
168
|
+
}
|
169
|
+
}
|
170
|
+
else if (time instanceof Date) {
|
171
|
+
return BigInt(time.valueOf() * 1000000);
|
172
|
+
}
|
173
|
+
else {
|
174
|
+
throw new TypeError(`invalid time value: ${time}`);
|
175
|
+
}
|
176
|
+
}
|
177
|
+
function parseDataArg(data, encoding = 'utf8') {
|
178
|
+
if (typeof data === 'string') {
|
179
|
+
if (encoding === 'utf8') {
|
180
|
+
return (new TextEncoder()).encode(data);
|
181
|
+
}
|
182
|
+
else {
|
183
|
+
// @ts-ignore
|
184
|
+
return new Uint8Array(buffer_1.Buffer.from(data, encoding));
|
185
|
+
}
|
186
|
+
}
|
187
|
+
else if (data instanceof DataView || data instanceof Int8Array || data instanceof Uint8Array || data instanceof Uint8ClampedArray || data instanceof Int16Array || data instanceof Uint16Array || data instanceof Int32Array || data instanceof Uint32Array || data instanceof Float32Array || data instanceof Float64Array || data instanceof BigInt64Array || data instanceof BigUint64Array) {
|
188
|
+
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
189
|
+
}
|
190
|
+
else if (data !== null && typeof data[Symbol.iterator] === 'function') {
|
191
|
+
return new Uint8Array(data);
|
192
|
+
}
|
193
|
+
else {
|
194
|
+
throw new TypeError(`invalid binary data: ${data}`);
|
195
|
+
}
|
196
|
+
}
|
197
|
+
const STRING_MODE_ARG_REGEX = /^([r-][w-][x-]){3}$/;
|
198
|
+
function parseModeArg(mode) {
|
199
|
+
if (typeof mode === 'number') {
|
200
|
+
return mode;
|
201
|
+
}
|
202
|
+
else {
|
203
|
+
if (!mode.match(STRING_MODE_ARG_REGEX)) {
|
204
|
+
throw new TypeError(`invalid chmod mode: ${mode}`);
|
205
|
+
}
|
206
|
+
// @ts-ignore
|
207
|
+
return parseInt('0b' + mode.replaceAll('-', '0').replace(/[rwx]/g, '1'));
|
208
|
+
}
|
209
|
+
}
|
210
|
+
class BaseStats {
|
211
|
+
isBlockDevice() {
|
212
|
+
return (Number(this.mode) & S_IFBLK) === S_IFBLK;
|
213
|
+
}
|
214
|
+
isCharacterDevice() {
|
215
|
+
return (Number(this.mode) & S_IFCHR) === S_IFCHR;
|
216
|
+
}
|
217
|
+
isDirectory() {
|
218
|
+
return (Number(this.mode) & S_IFDIR) === S_IFDIR;
|
219
|
+
}
|
220
|
+
isFIFO() {
|
221
|
+
return (Number(this.mode) & S_IFIFO) === S_IFIFO;
|
222
|
+
}
|
223
|
+
isFile() {
|
224
|
+
return (Number(this.mode) & S_IFREG) === S_IFREG;
|
225
|
+
}
|
226
|
+
isSocket() {
|
227
|
+
return (Number(this.mode) & S_IFSOCK) === S_IFSOCK;
|
228
|
+
}
|
229
|
+
isSymbolicLink() {
|
230
|
+
return (Number(this.mode) & S_IFLNK) === S_IFLNK;
|
231
|
+
}
|
232
|
+
}
|
233
|
+
class Stats extends BaseStats {
|
234
|
+
dev = -1;
|
235
|
+
ino = -1;
|
236
|
+
mode = -1;
|
237
|
+
nlink = -1;
|
238
|
+
uid = -1;
|
239
|
+
gid = -1;
|
240
|
+
rdev = -1;
|
241
|
+
size = -1;
|
242
|
+
blksize = -1;
|
243
|
+
blocks = -1;
|
244
|
+
atimeMs = -1;
|
245
|
+
mtimeMs = -1;
|
246
|
+
ctimeMs = -1;
|
247
|
+
birthtimeMs = -1;
|
248
|
+
atime = new Date(0);
|
249
|
+
mtime = new Date(0);
|
250
|
+
ctime = new Date(0);
|
251
|
+
birthtime = new Date(0);
|
252
|
+
}
|
253
|
+
exports.Stats = Stats;
|
254
|
+
class BigIntStats extends BaseStats {
|
255
|
+
dev = -1n;
|
256
|
+
ino = -1n;
|
257
|
+
mode = -1n;
|
258
|
+
nlink = -1n;
|
259
|
+
uid = -1n;
|
260
|
+
gid = -1n;
|
261
|
+
rdev = -1n;
|
262
|
+
size = -1n;
|
263
|
+
blksize = -1n;
|
264
|
+
blocks = -1n;
|
265
|
+
atimeMs = -1n;
|
266
|
+
mtimeMs = -1n;
|
267
|
+
ctimeMs = -1n;
|
268
|
+
birthtimeMs = -1n;
|
269
|
+
atimeNs = -1n;
|
270
|
+
mtimeNs = -1n;
|
271
|
+
ctimeNs = -1n;
|
272
|
+
birthtimeNs = -1n;
|
273
|
+
atime = new Date(0);
|
274
|
+
mtime = new Date(0);
|
275
|
+
ctime = new Date(0);
|
276
|
+
birthtime = new Date(0);
|
277
|
+
}
|
278
|
+
exports.BigIntStats = BigIntStats;
|
279
|
+
class StatFs {
|
280
|
+
bavail = -1;
|
281
|
+
bfree = -1;
|
282
|
+
blocks = -1;
|
283
|
+
bsize = -1;
|
284
|
+
ffree = -1;
|
285
|
+
files = -1;
|
286
|
+
type = -1;
|
287
|
+
}
|
288
|
+
exports.StatFs = StatFs;
|
289
|
+
class BigIntStatFs {
|
290
|
+
bavail = -1n;
|
291
|
+
bfree = -1n;
|
292
|
+
blocks = -1n;
|
293
|
+
bsize = -1n;
|
294
|
+
ffree = -1n;
|
295
|
+
files = -1n;
|
296
|
+
type = -1n;
|
297
|
+
}
|
298
|
+
exports.BigIntStatFs = BigIntStatFs;
|
299
|
+
exports.currentExportFormatVersion = 1;
|
300
|
+
class FileObject {
|
301
|
+
mode;
|
302
|
+
uid;
|
303
|
+
gid;
|
304
|
+
birthtime;
|
305
|
+
atime;
|
306
|
+
mtime;
|
307
|
+
ctime;
|
308
|
+
rdev = -1;
|
309
|
+
constructor({ mode, uid, gid }) {
|
310
|
+
this.mode = mode ?? 0o6440;
|
311
|
+
this.uid = uid;
|
312
|
+
this.gid = gid;
|
313
|
+
;
|
314
|
+
this.birthtime = BigInt(Math.round(performance.now() * 1e9));
|
315
|
+
this.atime = this.birthtime;
|
316
|
+
this.mtime = this.birthtime;
|
317
|
+
this.ctime = this.birthtime;
|
318
|
+
}
|
319
|
+
setAtime() {
|
320
|
+
this.atime = BigInt(Math.round(performance.now() * 1e9));
|
321
|
+
}
|
322
|
+
setMtime() {
|
323
|
+
this.mtime = BigInt(Math.round(performance.now() * 1e9));
|
324
|
+
}
|
325
|
+
setCtime() {
|
326
|
+
this.ctime = BigInt(Math.round(performance.now() * 1e9));
|
327
|
+
}
|
328
|
+
access(mode = F_OK) {
|
329
|
+
const parsed = parseModeArg(mode);
|
330
|
+
const chmodInfo = (this.mode >> 3) & 0o777;
|
331
|
+
let perms;
|
332
|
+
if ((0, exports.uidGetter)() === this.uid) {
|
333
|
+
perms = (chmodInfo >> 6) & 7;
|
334
|
+
}
|
335
|
+
else if ((0, exports.gidGetter)() === this.gid) {
|
336
|
+
perms = (chmodInfo >> 3) & 7;
|
337
|
+
}
|
338
|
+
else {
|
339
|
+
perms = chmodInfo & 7;
|
340
|
+
}
|
341
|
+
if ((((parsed & X_OK) === X_OK) && !((perms & X_OK) === X_OK)) || (((parsed & W_OK) === W_OK) && !((perms & W_OK) === W_OK)) || (((parsed & R_OK) === R_OK) && !((perms & R_OK) === R_OK))) {
|
342
|
+
throw new Error(`mode ${mode} and permissions ${chmodInfo} are not compatible`);
|
343
|
+
}
|
344
|
+
}
|
345
|
+
chmod(mode) {
|
346
|
+
mode = parseModeArg(mode);
|
347
|
+
this.mode &= 0o170007;
|
348
|
+
this.mode |= mode << 3;
|
349
|
+
this.setCtime();
|
350
|
+
}
|
351
|
+
chown(uid, gid) {
|
352
|
+
this.uid = uid;
|
353
|
+
this.gid = gid;
|
354
|
+
this.setCtime();
|
355
|
+
}
|
356
|
+
cp() {
|
357
|
+
return new FileObject({ mode: this.mode, uid: this.uid, gid: this.gid });
|
358
|
+
}
|
359
|
+
cpr() {
|
360
|
+
return this.cp();
|
361
|
+
}
|
362
|
+
get size() {
|
363
|
+
return 0;
|
364
|
+
}
|
365
|
+
utimes(atime, mtime) {
|
366
|
+
this.atime = parseTimeArg(atime);
|
367
|
+
this.mtime = parseTimeArg(mtime);
|
368
|
+
}
|
369
|
+
stat(bigint = false) {
|
370
|
+
if (bigint) {
|
371
|
+
let out = new BigIntStats();
|
372
|
+
out.dev = 0n;
|
373
|
+
out.ino = 0n;
|
374
|
+
out.mode = BigInt(this.mode);
|
375
|
+
out.nlink = -1n;
|
376
|
+
out.uid = BigInt(this.uid);
|
377
|
+
out.gid = BigInt(this.gid);
|
378
|
+
out.rdev = BigInt(this.rdev);
|
379
|
+
out.size = BigInt(this.size);
|
380
|
+
out.blksize = 4096n;
|
381
|
+
out.blocks = BigInt(Math.ceil(this.size / 4096));
|
382
|
+
out.atimeMs = this.atime / 1000000n;
|
383
|
+
out.mtimeMs = this.mtime / 1000000n;
|
384
|
+
out.ctimeMs = this.ctime / 1000000n;
|
385
|
+
out.birthtimeMs = this.birthtime / 1000000n;
|
386
|
+
out.atimeNs = this.atime;
|
387
|
+
out.mtimeNs = this.mtime;
|
388
|
+
out.ctimeNs = this.ctime;
|
389
|
+
out.birthtimeNs = this.birthtime;
|
390
|
+
out.atime = new Date(Number(this.atime / 1000000n));
|
391
|
+
out.mtime = new Date(Number(this.mtime / 1000000n));
|
392
|
+
out.ctime = new Date(Number(this.ctime / 1000000n));
|
393
|
+
out.birthtime = new Date(Number(this.birthtime / 1000000n));
|
394
|
+
return out;
|
395
|
+
}
|
396
|
+
else {
|
397
|
+
let out = new Stats();
|
398
|
+
out.dev = 0;
|
399
|
+
out.ino = 0;
|
400
|
+
out.mode = this.mode;
|
401
|
+
out.nlink = -1;
|
402
|
+
out.uid = this.uid;
|
403
|
+
out.gid = this.gid;
|
404
|
+
out.rdev = this.rdev;
|
405
|
+
out.size = this.size;
|
406
|
+
out.blksize = 4096;
|
407
|
+
out.blocks = Math.ceil(this.size / 4096);
|
408
|
+
out.atimeMs = Number(this.atime / 1000000n);
|
409
|
+
out.mtimeMs = Number(this.mtime / 1000000n);
|
410
|
+
out.ctimeMs = Number(this.ctime / 1000000n);
|
411
|
+
out.birthtimeMs = Number(this.birthtime / 1000000n);
|
412
|
+
out.atime = new Date(Number(this.atime / 1000000n));
|
413
|
+
out.mtime = new Date(Number(this.mtime / 1000000n));
|
414
|
+
out.ctime = new Date(Number(this.ctime / 1000000n));
|
415
|
+
out.birthtime = new Date(Number(this.birthtime / 1000000n));
|
416
|
+
return out;
|
417
|
+
}
|
418
|
+
}
|
419
|
+
_export() {
|
420
|
+
let buffer = new ArrayBuffer(10);
|
421
|
+
let view = new DataView(buffer);
|
422
|
+
view.setUint16(0, this.mode, true);
|
423
|
+
view.setUint16(2, this.uid, true);
|
424
|
+
view.setUint16(4, this.gid, true);
|
425
|
+
view.setUint32(6, this.size, true);
|
426
|
+
return new Uint8Array(buffer);
|
427
|
+
}
|
428
|
+
static _import(data, version = exports.currentExportFormatVersion) {
|
429
|
+
let view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
430
|
+
return {
|
431
|
+
mode: view.getUint16(0, true),
|
432
|
+
uid: view.getUint16(2, true),
|
433
|
+
gid: view.getUint16(4, true),
|
434
|
+
size: view.getUint16(6, true),
|
435
|
+
birthtime: 0n,
|
436
|
+
atime: 0n,
|
437
|
+
mtime: 0n,
|
438
|
+
ctime: 0n,
|
439
|
+
};
|
440
|
+
}
|
441
|
+
export() {
|
442
|
+
return this._export();
|
443
|
+
}
|
444
|
+
}
|
445
|
+
exports.FileObject = FileObject;
|
446
|
+
class RegularFile extends FileObject {
|
447
|
+
data;
|
448
|
+
constructor(data, { mode = 0o6440, encoding, ...params }) {
|
449
|
+
super({ mode: mode | S_IFREG, ...params });
|
450
|
+
this.data = parseDataArg(data, encoding);
|
451
|
+
}
|
452
|
+
cp() {
|
453
|
+
return new RegularFile(new Uint8Array(this.data), { mode: this.mode, uid: this.uid, gid: this.gid });
|
454
|
+
}
|
455
|
+
read(encoding = 'utf8', start = 0, length = -1) {
|
456
|
+
if (encoding === 'uint8array') {
|
457
|
+
return this.data;
|
458
|
+
}
|
459
|
+
else if (encoding === 'buffer') {
|
460
|
+
return buffer_1.Buffer.from(this.data);
|
461
|
+
}
|
462
|
+
else {
|
463
|
+
return (new TextDecoder(encoding)).decode(this.data);
|
464
|
+
}
|
465
|
+
}
|
466
|
+
write(data, position, encoding_or_length) {
|
467
|
+
const encoding = typeof encoding_or_length === 'string' ? encoding_or_length : 'utf8';
|
468
|
+
const length = typeof encoding_or_length === 'number' ? encoding_or_length : -1;
|
469
|
+
const array = parseDataArg(data, encoding);
|
470
|
+
if (position === 0 && length === -1) {
|
471
|
+
this.data = array;
|
472
|
+
}
|
473
|
+
else if (length === -1) {
|
474
|
+
this.data.set(array, position);
|
475
|
+
}
|
476
|
+
else {
|
477
|
+
this.data.set(array.slice(0, length), position);
|
478
|
+
}
|
479
|
+
this.setMtime();
|
480
|
+
}
|
481
|
+
append(data, encoding = 'utf8') {
|
482
|
+
const array = parseDataArg(data, encoding);
|
483
|
+
let newData = new Uint8Array(this.data.length + array.length);
|
484
|
+
newData.set(this.data, 0);
|
485
|
+
newData.set(array, this.data.length);
|
486
|
+
this.data = newData;
|
487
|
+
this.setMtime();
|
488
|
+
}
|
489
|
+
get size() {
|
490
|
+
return this.data.length;
|
491
|
+
}
|
492
|
+
export() {
|
493
|
+
let out = new Uint8Array(10 + this.size);
|
494
|
+
out.set(this._export(), 0);
|
495
|
+
out.set(this.data, 10);
|
496
|
+
return out;
|
497
|
+
}
|
498
|
+
static import(data, version = exports.currentExportFormatVersion) {
|
499
|
+
const info = this._import(data, version);
|
500
|
+
let out = new RegularFile(data.slice(10, 10 + info.size), info);
|
501
|
+
out.atime = info.atime;
|
502
|
+
out.mtime = info.mtime;
|
503
|
+
out.ctime = info.ctime;
|
504
|
+
out.birthtime = info.birthtime;
|
505
|
+
return out;
|
506
|
+
}
|
507
|
+
}
|
508
|
+
exports.RegularFile = RegularFile;
|
509
|
+
class Directory extends FileObject {
|
510
|
+
files;
|
511
|
+
constructor(files = new Map(), { mode = 0o7770, ...params }) {
|
512
|
+
super({ mode: mode | S_IFDIR, ...params });
|
513
|
+
if (files instanceof Map) {
|
514
|
+
this.files = files;
|
515
|
+
}
|
516
|
+
else {
|
517
|
+
this.files = new Map(Object.entries(files));
|
518
|
+
}
|
519
|
+
}
|
520
|
+
cp() {
|
521
|
+
return new Directory(this.files.entries(), { mode: this.mode, uid: this.uid, gid: this.gid });
|
522
|
+
}
|
523
|
+
cpr() {
|
524
|
+
return new Directory(new Map(Array.from(this.files.entries()).map(([name, file]) => [name, file.cpr()])), { mode: this.mode, uid: this.uid, gid: this.gid });
|
525
|
+
}
|
526
|
+
get size() {
|
527
|
+
return this.files.size;
|
528
|
+
}
|
529
|
+
get recursiveSize() {
|
530
|
+
let out = this.files.size;
|
531
|
+
for (let file of this.files.values()) {
|
532
|
+
if (file instanceof Directory) {
|
533
|
+
out += file.recursiveSize;
|
534
|
+
}
|
535
|
+
}
|
536
|
+
return out;
|
537
|
+
}
|
538
|
+
get(path) {
|
539
|
+
const segments = parsePathArg(path).slice(1).split('/');
|
540
|
+
let file = this;
|
541
|
+
for (let i = 0; i < segments.length; i++) {
|
542
|
+
const segment = segments[i];
|
543
|
+
if (file instanceof Directory) {
|
544
|
+
const newFile = file.files.get(segment);
|
545
|
+
if (newFile === undefined) {
|
546
|
+
throw new TypeError(`${segments.slice(0, i + 1).join('/')} does not exist`);
|
547
|
+
}
|
548
|
+
file = newFile;
|
549
|
+
}
|
550
|
+
else {
|
551
|
+
throw new TypeError(`${segments.slice(0, i).join('/')} is not a directory`);
|
552
|
+
}
|
553
|
+
}
|
554
|
+
return file;
|
555
|
+
}
|
556
|
+
getRegular(path) {
|
557
|
+
const file = this.get(path);
|
558
|
+
if (!(file instanceof RegularFile)) {
|
559
|
+
throw new TypeError(`${path} is not a regular file`);
|
560
|
+
}
|
561
|
+
return file;
|
562
|
+
}
|
563
|
+
getDir(path) {
|
564
|
+
const file = this.get(path);
|
565
|
+
if (!(file instanceof Directory)) {
|
566
|
+
throw new TypeError(`${path} is not a directory`);
|
567
|
+
}
|
568
|
+
return file;
|
569
|
+
}
|
570
|
+
lget(path) {
|
571
|
+
return this.get(path);
|
572
|
+
}
|
573
|
+
exists(path) {
|
574
|
+
const segments = parsePathArg(path).split('/');
|
575
|
+
let file = this;
|
576
|
+
for (let i = 0; i < segments.length; i++) {
|
577
|
+
const segment = segments[i];
|
578
|
+
if (file instanceof Directory) {
|
579
|
+
const newFile = file.files.get(segment);
|
580
|
+
if (newFile === undefined) {
|
581
|
+
return false;
|
582
|
+
}
|
583
|
+
}
|
584
|
+
else {
|
585
|
+
throw new TypeError(`${segments.slice(0, i).join('/')} is not a directory`);
|
586
|
+
}
|
587
|
+
}
|
588
|
+
return true;
|
589
|
+
}
|
590
|
+
link(path, file) {
|
591
|
+
this.files.set(parsePathArg(path), file);
|
592
|
+
}
|
593
|
+
unlink(path) {
|
594
|
+
const parsed = parsePathArg(path);
|
595
|
+
let file = this.files.get(parsePathArg(parsed));
|
596
|
+
if (file === undefined) {
|
597
|
+
throw new TypeError(`${path} does not exist`);
|
598
|
+
}
|
599
|
+
this.files.delete(parsed);
|
600
|
+
return file;
|
601
|
+
}
|
602
|
+
symlink(target, path) {
|
603
|
+
throw new TypeError('symlinks are not supported in fake-node');
|
604
|
+
}
|
605
|
+
mkdir(path, recursive = false, mode = 0o7770) {
|
606
|
+
const parsed = parsePathArg(path);
|
607
|
+
if (recursive) {
|
608
|
+
const segments = parsed.split('/');
|
609
|
+
let file = this;
|
610
|
+
for (let i = 0; i < segments.length; i++) {
|
611
|
+
const segment = segments[i];
|
612
|
+
if (file.exists(segment)) {
|
613
|
+
throw new TypeError(`cannot create ${path}: ${segments.slice(0, i).join('/')} exists`);
|
614
|
+
}
|
615
|
+
file = file.mkdir(path);
|
616
|
+
}
|
617
|
+
return file;
|
618
|
+
}
|
619
|
+
else {
|
620
|
+
let file = new Directory(new Map(), { uid: this.uid, gid: this.gid, mode: parseModeArg(mode) });
|
621
|
+
this.files.set(parsed, file);
|
622
|
+
return file;
|
623
|
+
}
|
624
|
+
}
|
625
|
+
readFrom(path, encoding = 'utf8', start = 0, length = -1) {
|
626
|
+
// @ts-ignore
|
627
|
+
return this.getRegular(path).read(encoding, start, length);
|
628
|
+
}
|
629
|
+
writeTo(path, data, position, encoding_or_length) {
|
630
|
+
if (this.exists(path)) {
|
631
|
+
// @ts-ignore
|
632
|
+
this.getRegular(path).write(data, position, encoding_or_length);
|
633
|
+
}
|
634
|
+
else {
|
635
|
+
this.files.set(parsePathArg(path).slice(1), new RegularFile(data, { uid: this.uid, gid: this.gid }));
|
636
|
+
}
|
637
|
+
}
|
638
|
+
export() {
|
639
|
+
const encoder = new TextEncoder();
|
640
|
+
let entries = Array.from(this.files.entries().map(([name, data]) => [encoder.encode(name), data.export()]));
|
641
|
+
let size = entries.map(([name, data]) => 1 + name.length + data.length).reduce((x, y) => x + y);
|
642
|
+
let out = new Uint8Array(10 + size);
|
643
|
+
out.set(this._export(), 0);
|
644
|
+
let offset = 10;
|
645
|
+
for (const [name, data] of entries) {
|
646
|
+
out[offset] = name.length;
|
647
|
+
out.set(name, offset + 1);
|
648
|
+
offset += 1 + name.length;
|
649
|
+
out.set(data, offset);
|
650
|
+
offset += data.length;
|
651
|
+
}
|
652
|
+
return out;
|
653
|
+
}
|
654
|
+
static import(data, version = exports.currentExportFormatVersion) {
|
655
|
+
const decoder = new TextDecoder();
|
656
|
+
const info = this._import(data, version);
|
657
|
+
let offset = 10;
|
658
|
+
let entries = [];
|
659
|
+
for (let i = 0; i < info.size; i++) {
|
660
|
+
const nameLength = data[offset];
|
661
|
+
offset++;
|
662
|
+
const name = decoder.decode(data.slice(offset, offset + nameLength));
|
663
|
+
offset += nameLength;
|
664
|
+
const meta = this._import(data.slice(offset, offset + 10), version);
|
665
|
+
const fileData = data.slice(offset, offset + 10 + meta.size);
|
666
|
+
offset += 10 + meta.size;
|
667
|
+
let file;
|
668
|
+
if ((meta.mode & S_IFREG) === S_IFREG) {
|
669
|
+
file = RegularFile.import(fileData);
|
670
|
+
}
|
671
|
+
else if ((meta.mode & S_IFDIR) === S_IFDIR) {
|
672
|
+
file = Directory.import(fileData);
|
673
|
+
}
|
674
|
+
else {
|
675
|
+
throw new TypeError(`invalid file mode: ${meta.mode}`);
|
676
|
+
}
|
677
|
+
entries.push([name, file]);
|
678
|
+
}
|
679
|
+
let out = new Directory(new Map(entries), info);
|
680
|
+
out.atime = info.atime;
|
681
|
+
out.mtime = info.mtime;
|
682
|
+
out.ctime = info.ctime;
|
683
|
+
out.birthtime = info.birthtime;
|
684
|
+
return out;
|
685
|
+
}
|
686
|
+
}
|
687
|
+
exports.Directory = Directory;
|
688
|
+
class FileSystem extends Directory {
|
689
|
+
fileDescriptors = [];
|
690
|
+
constructor(files = exports.DEFAULT_FILES) {
|
691
|
+
super(files, { uid: 0, gid: 0 });
|
692
|
+
}
|
693
|
+
getfd(fd) {
|
694
|
+
const out = this.fileDescriptors[fd];
|
695
|
+
if (out === null) {
|
696
|
+
throw new TypeError(`file descriptor ${fd} is not accessible`);
|
697
|
+
}
|
698
|
+
return out;
|
699
|
+
}
|
700
|
+
getfdRegular(fd) {
|
701
|
+
const out = this.fileDescriptors[fd];
|
702
|
+
if (out === null) {
|
703
|
+
throw new TypeError(`file descriptor ${fd} is not accessible`);
|
704
|
+
}
|
705
|
+
else if (!(out instanceof RegularFile)) {
|
706
|
+
throw new TypeError(`file descriptor ${fd} is not a regular file`);
|
707
|
+
}
|
708
|
+
return out;
|
709
|
+
}
|
710
|
+
open(path, flags, mode = 'r') {
|
711
|
+
return this.fileDescriptors.push(this.get(path));
|
712
|
+
}
|
713
|
+
statfs(bigint) {
|
714
|
+
if (bigint) {
|
715
|
+
let out = new BigIntStatFs();
|
716
|
+
out.bavail = -1n;
|
717
|
+
out.bfree = -1n;
|
718
|
+
out.blocks = -1n;
|
719
|
+
out.bsize = -1n;
|
720
|
+
out.ffree = -1n;
|
721
|
+
out.files = BigInt(this.recursiveSize);
|
722
|
+
out.type = 61267n;
|
723
|
+
return out;
|
724
|
+
}
|
725
|
+
else {
|
726
|
+
let out = new StatFs();
|
727
|
+
out.bavail = Infinity;
|
728
|
+
out.bfree = Infinity;
|
729
|
+
out.blocks = Infinity;
|
730
|
+
out.bsize = Infinity;
|
731
|
+
out.ffree = Infinity;
|
732
|
+
out.files = this.recursiveSize;
|
733
|
+
out.type = 61267;
|
734
|
+
return out;
|
735
|
+
}
|
736
|
+
}
|
737
|
+
fsExport() {
|
738
|
+
const data = this.export();
|
739
|
+
let out = new Uint8Array(1 + data.length);
|
740
|
+
out[0] = exports.currentExportFormatVersion;
|
741
|
+
out.set(data, 1);
|
742
|
+
return out;
|
743
|
+
}
|
744
|
+
static fsImport(data) {
|
745
|
+
return new FileSystem(Directory.import(data.slice(1), data[0]).files);
|
746
|
+
}
|
747
|
+
}
|
748
|
+
exports.FileSystem = FileSystem;
|
749
|
+
exports.DEFAULT_FILES = new Map();
|
750
|
+
//# sourceMappingURL=_fs.js.map
|