@zenfs/core 0.0.12 → 0.1.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/dist/ApiError.d.ts +1 -1
- package/dist/ApiError.js +17 -16
- package/dist/backends/AsyncMirror.js +40 -46
- package/dist/backends/AsyncStore.js +326 -383
- package/dist/backends/FolderAdapter.js +8 -19
- package/dist/backends/Locked.js +91 -137
- package/dist/backends/OverlayFS.js +234 -279
- package/dist/backends/SyncStore.js +2 -2
- package/dist/backends/backend.d.ts +6 -6
- package/dist/browser.min.js +23 -6
- package/dist/browser.min.js.map +4 -4
- package/dist/emulation/callbacks.d.ts +109 -72
- package/dist/emulation/callbacks.js +40 -47
- package/dist/emulation/dir.d.ts +55 -0
- package/dist/emulation/dir.js +104 -0
- package/dist/emulation/fs.d.ts +1 -2
- package/dist/emulation/fs.js +0 -1
- package/dist/emulation/index.d.ts +3 -0
- package/dist/emulation/index.js +3 -0
- package/dist/emulation/promises.d.ts +71 -50
- package/dist/emulation/promises.js +243 -342
- package/dist/emulation/shared.d.ts +14 -0
- package/dist/emulation/shared.js +4 -3
- package/dist/emulation/streams.d.ts +102 -0
- package/dist/emulation/streams.js +55 -0
- package/dist/emulation/sync.d.ts +81 -52
- package/dist/emulation/sync.js +98 -65
- package/dist/file.d.ts +11 -5
- package/dist/file.js +79 -76
- package/dist/filesystem.d.ts +3 -3
- package/dist/filesystem.js +181 -262
- package/dist/index.d.ts +3 -3
- package/dist/index.js +39 -53
- package/dist/stats.d.ts +80 -27
- package/dist/stats.js +142 -93
- package/dist/utils.d.ts +2 -6
- package/dist/utils.js +79 -78
- package/package.json +4 -2
- package/readme.md +2 -40
package/dist/index.js
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ZenFS's main module. This is exposed in the browser via the ZenFS global.
|
|
3
3
|
*/
|
|
4
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
5
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
6
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
7
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
8
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
9
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
10
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
11
|
-
});
|
|
12
|
-
};
|
|
13
4
|
import fs from './emulation/fs.js';
|
|
14
5
|
import { FileSystem } from './filesystem.js';
|
|
15
6
|
import { backends } from './backends/index.js';
|
|
@@ -23,28 +14,25 @@ export function initialize(mounts, uid = 0, gid = 0) {
|
|
|
23
14
|
setCred(new Cred(uid, gid, uid, gid, uid, gid));
|
|
24
15
|
return fs.initialize(mounts);
|
|
25
16
|
}
|
|
26
|
-
function _configure(config) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
17
|
+
async function _configure(config) {
|
|
18
|
+
if ('fs' in config || config instanceof FileSystem) {
|
|
19
|
+
// single FS
|
|
20
|
+
config = { '/': config };
|
|
21
|
+
}
|
|
22
|
+
for (let [point, value] of Object.entries(config)) {
|
|
23
|
+
if (typeof value == 'number') {
|
|
24
|
+
//should never happen
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (value instanceof FileSystem) {
|
|
28
|
+
continue;
|
|
31
29
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
//should never happen
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
point = point.toString(); // so linting stops complaining that point should be declared with const, which can't be done since value is assigned to
|
|
38
|
-
if (value instanceof FileSystem) {
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
if (typeof value == 'string') {
|
|
42
|
-
value = { fs: value };
|
|
43
|
-
}
|
|
44
|
-
config[point] = yield getFileSystem(value);
|
|
30
|
+
if (typeof value == 'string') {
|
|
31
|
+
value = { fs: value };
|
|
45
32
|
}
|
|
46
|
-
|
|
47
|
-
}
|
|
33
|
+
config[point] = await getFileSystem(value);
|
|
34
|
+
}
|
|
35
|
+
return initialize(config);
|
|
48
36
|
}
|
|
49
37
|
export function configure(config, cb) {
|
|
50
38
|
// Promise version
|
|
@@ -57,31 +45,29 @@ export function configure(config, cb) {
|
|
|
57
45
|
.catch(err => cb(err));
|
|
58
46
|
return;
|
|
59
47
|
}
|
|
60
|
-
function _getFileSystem({ fs: fsName, options = {} }) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
const fs = yield _getFileSystem(opt);
|
|
75
|
-
options[prop] = fs;
|
|
76
|
-
}
|
|
77
|
-
const fsc = backends[fsName];
|
|
78
|
-
if (!fsc) {
|
|
79
|
-
throw new ApiError(ErrorCode.EPERM, `File system ${fsName} is not available in ZenFS.`);
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
return fsc.Create(options);
|
|
48
|
+
async function _getFileSystem({ fs: fsName, options = {} }) {
|
|
49
|
+
if (!fsName) {
|
|
50
|
+
throw new ApiError(ErrorCode.EPERM, 'Missing "fs" property on configuration object.');
|
|
51
|
+
}
|
|
52
|
+
if (typeof options !== 'object' || options === null) {
|
|
53
|
+
throw new ApiError(ErrorCode.EINVAL, 'Invalid "options" property on configuration object.');
|
|
54
|
+
}
|
|
55
|
+
const props = Object.keys(options).filter(k => k != 'fs');
|
|
56
|
+
for (const prop of props) {
|
|
57
|
+
const opt = options[prop];
|
|
58
|
+
if (opt === null || typeof opt !== 'object' || !('fs' in opt)) {
|
|
59
|
+
continue;
|
|
83
60
|
}
|
|
84
|
-
|
|
61
|
+
const fs = await _getFileSystem(opt);
|
|
62
|
+
options[prop] = fs;
|
|
63
|
+
}
|
|
64
|
+
const fsc = backends[fsName];
|
|
65
|
+
if (!fsc) {
|
|
66
|
+
throw new ApiError(ErrorCode.EPERM, `File system ${fsName} is not available in ZenFS.`);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
return fsc.Create(options);
|
|
70
|
+
}
|
|
85
71
|
}
|
|
86
72
|
export function getFileSystem(config, cb) {
|
|
87
73
|
// Promise version
|
package/dist/stats.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
import type
|
|
2
|
+
import type * as Node from 'fs';
|
|
3
3
|
import { Cred } from './cred.js';
|
|
4
4
|
/**
|
|
5
5
|
* Indicates the type of the given file. Applied to 'mode'.
|
|
@@ -10,33 +10,53 @@ export declare enum FileType {
|
|
|
10
10
|
SYMLINK
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* Attribute descriptions are from `man 2 stat'
|
|
16
|
-
* @see http://nodejs.org/api/fs.html#fs_class_fs_stats
|
|
17
|
-
* @see http://man7.org/linux/man-pages/man2/stat.2.html
|
|
13
|
+
* Common code used by both Stats and BigIntStats
|
|
18
14
|
*/
|
|
19
|
-
export declare class
|
|
20
|
-
static Deserialize(data: ArrayBufferLike | ArrayBufferView):
|
|
15
|
+
export declare abstract class StatsCommon<T extends number | bigint> implements Node.StatsBase<T> {
|
|
16
|
+
static Deserialize(data: ArrayBufferLike | ArrayBufferView): StatsCommon<number> | StatsCommon<bigint>;
|
|
17
|
+
protected abstract _isBigint: boolean;
|
|
18
|
+
protected get _typename(): string;
|
|
19
|
+
protected get _typename_inverse(): string;
|
|
20
|
+
protected _convert(arg: number | bigint | string | boolean): T;
|
|
21
|
+
blocks: T;
|
|
22
|
+
mode: T;
|
|
21
23
|
/**
|
|
22
|
-
*
|
|
24
|
+
* ID of device containing file
|
|
25
|
+
*/
|
|
26
|
+
dev: T;
|
|
27
|
+
/**
|
|
28
|
+
* inode number
|
|
29
|
+
*/
|
|
30
|
+
ino: T;
|
|
31
|
+
/**
|
|
32
|
+
* device ID (if special file)
|
|
33
|
+
*/
|
|
34
|
+
rdev: T;
|
|
35
|
+
/**
|
|
36
|
+
* number of hard links
|
|
37
|
+
*/
|
|
38
|
+
nlink: T;
|
|
39
|
+
/**
|
|
40
|
+
* blocksize for file system I/O
|
|
41
|
+
*/
|
|
42
|
+
blksize: T;
|
|
43
|
+
/**
|
|
44
|
+
* user ID of owner
|
|
45
|
+
*/
|
|
46
|
+
uid: T;
|
|
47
|
+
/**
|
|
48
|
+
* group ID of owner
|
|
49
|
+
*/
|
|
50
|
+
gid: T;
|
|
51
|
+
/**
|
|
52
|
+
* Some file systems stash data on stats objects.
|
|
23
53
|
*/
|
|
24
|
-
static clone(s: Stats): Stats;
|
|
25
|
-
blocks: number;
|
|
26
|
-
mode: number;
|
|
27
|
-
dev: number;
|
|
28
|
-
ino: number;
|
|
29
|
-
rdev: number;
|
|
30
|
-
nlink: number;
|
|
31
|
-
blksize: number;
|
|
32
|
-
uid: number;
|
|
33
|
-
gid: number;
|
|
34
54
|
fileData: Uint8Array | null;
|
|
35
|
-
atimeMs:
|
|
36
|
-
mtimeMs:
|
|
37
|
-
ctimeMs:
|
|
38
|
-
birthtimeMs:
|
|
39
|
-
size:
|
|
55
|
+
atimeMs: T;
|
|
56
|
+
mtimeMs: T;
|
|
57
|
+
ctimeMs: T;
|
|
58
|
+
birthtimeMs: T;
|
|
59
|
+
size: T;
|
|
40
60
|
get atime(): Date;
|
|
41
61
|
get mtime(): Date;
|
|
42
62
|
get ctime(): Date;
|
|
@@ -54,8 +74,8 @@ export declare class Stats implements StatsBase<number> {
|
|
|
54
74
|
* @param gid the id of the group that owns the file
|
|
55
75
|
* @param birthtimeMs time of file creation, in milliseconds since epoch
|
|
56
76
|
*/
|
|
57
|
-
constructor(itemType
|
|
58
|
-
serialize(): Uint8Array;
|
|
77
|
+
constructor(itemType?: FileType, size?: number | bigint, mode?: number | bigint, atimeMs?: number | bigint, mtimeMs?: number | bigint, ctimeMs?: number | bigint, uid?: number | bigint, gid?: number | bigint, birthtimeMs?: number | bigint);
|
|
78
|
+
abstract serialize(): Uint8Array;
|
|
59
79
|
/**
|
|
60
80
|
* @return [Boolean] True if this item is a file.
|
|
61
81
|
*/
|
|
@@ -89,9 +109,42 @@ export declare class Stats implements StatsBase<number> {
|
|
|
89
109
|
* Change the owner user/group of the file.
|
|
90
110
|
* This function makes sure it is a valid UID/GID (that is, a 32 unsigned int)
|
|
91
111
|
*/
|
|
92
|
-
chown(uid: number, gid: number): void;
|
|
112
|
+
chown(uid: number | bigint, gid: number | bigint): void;
|
|
93
113
|
isSocket(): boolean;
|
|
94
114
|
isBlockDevice(): boolean;
|
|
95
115
|
isCharacterDevice(): boolean;
|
|
96
116
|
isFIFO(): boolean;
|
|
97
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Implementation of Node's `Stats`.
|
|
120
|
+
*
|
|
121
|
+
* Attribute descriptions are from `man 2 stat'
|
|
122
|
+
* @see http://nodejs.org/api/fs.html#fs_class_fs_stats
|
|
123
|
+
* @see http://man7.org/linux/man-pages/man2/stat.2.html
|
|
124
|
+
*/
|
|
125
|
+
export declare class Stats extends StatsCommon<number> implements Node.Stats {
|
|
126
|
+
protected _isBigint: boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Clones the stats object.
|
|
129
|
+
*/
|
|
130
|
+
static clone(s: Stats): Stats;
|
|
131
|
+
static Deserialize(data: ArrayBufferLike | ArrayBufferView): Stats;
|
|
132
|
+
serialize(): Uint8Array;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Stats with bigint
|
|
136
|
+
* @todo Implement with bigint instead of wrapping Stats
|
|
137
|
+
*/
|
|
138
|
+
export declare class BigIntStats extends StatsCommon<bigint> implements Node.BigIntStats {
|
|
139
|
+
protected _isBigint: boolean;
|
|
140
|
+
atimeNs: bigint;
|
|
141
|
+
mtimeNs: bigint;
|
|
142
|
+
ctimeNs: bigint;
|
|
143
|
+
birthtimeNs: bigint;
|
|
144
|
+
/**
|
|
145
|
+
* Clone a stats object.
|
|
146
|
+
*/
|
|
147
|
+
static clone(s: BigIntStats | Stats): BigIntStats;
|
|
148
|
+
static Deserialize(data: ArrayBufferLike | ArrayBufferView): Stats;
|
|
149
|
+
serialize(): Uint8Array;
|
|
150
|
+
}
|
package/dist/stats.js
CHANGED
|
@@ -10,35 +10,33 @@ export var FileType;
|
|
|
10
10
|
FileType[FileType["SYMLINK"] = S_IFLNK] = "SYMLINK";
|
|
11
11
|
})(FileType = FileType || (FileType = {}));
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* Attribute descriptions are from `man 2 stat'
|
|
16
|
-
* @see http://nodejs.org/api/fs.html#fs_class_fs_stats
|
|
17
|
-
* @see http://man7.org/linux/man-pages/man2/stat.2.html
|
|
13
|
+
* Common code used by both Stats and BigIntStats
|
|
18
14
|
*/
|
|
19
|
-
export class
|
|
15
|
+
export class StatsCommon {
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
20
17
|
static Deserialize(data) {
|
|
21
|
-
|
|
22
|
-
const size = view.getUint32(0, true), mode = view.getUint32(4, true), atime = view.getFloat64(8, true), mtime = view.getFloat64(16, true), ctime = view.getFloat64(24, true), uid = view.getUint32(32, true), gid = view.getUint32(36, true);
|
|
23
|
-
return new Stats(mode & S_IFMT, size, mode & ~S_IFMT, atime, mtime, ctime, uid, gid);
|
|
18
|
+
throw new ReferenceError('Called static abstract method: StatsCommon.Deserialize()');
|
|
24
19
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return
|
|
20
|
+
get _typename() {
|
|
21
|
+
return this._isBigint ? 'bigint' : 'number';
|
|
22
|
+
}
|
|
23
|
+
get _typename_inverse() {
|
|
24
|
+
return this._isBigint ? 'number' : 'bigint';
|
|
25
|
+
}
|
|
26
|
+
_convert(arg) {
|
|
27
|
+
return (this._isBigint ? BigInt(arg) : Number(arg));
|
|
30
28
|
}
|
|
31
29
|
get atime() {
|
|
32
|
-
return new Date(this.atimeMs);
|
|
30
|
+
return new Date(Number(this.atimeMs));
|
|
33
31
|
}
|
|
34
32
|
get mtime() {
|
|
35
|
-
return new Date(this.mtimeMs);
|
|
33
|
+
return new Date(Number(this.mtimeMs));
|
|
36
34
|
}
|
|
37
35
|
get ctime() {
|
|
38
|
-
return new Date(this.ctimeMs);
|
|
36
|
+
return new Date(Number(this.ctimeMs));
|
|
39
37
|
}
|
|
40
38
|
get birthtime() {
|
|
41
|
-
return new Date(this.birthtimeMs);
|
|
39
|
+
return new Date(Number(this.birthtimeMs));
|
|
42
40
|
}
|
|
43
41
|
/**
|
|
44
42
|
* Provides information about a particular entry in the file system.
|
|
@@ -53,89 +51,69 @@ export class Stats {
|
|
|
53
51
|
* @param gid the id of the group that owns the file
|
|
54
52
|
* @param birthtimeMs time of file creation, in milliseconds since epoch
|
|
55
53
|
*/
|
|
56
|
-
constructor(itemType, size, mode, atimeMs, mtimeMs, ctimeMs, uid, gid, birthtimeMs) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
this.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
this.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
this.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
54
|
+
constructor(itemType = FileType.FILE, size = -1, mode, atimeMs, mtimeMs, ctimeMs, uid, gid, birthtimeMs) {
|
|
55
|
+
/**
|
|
56
|
+
* ID of device containing file
|
|
57
|
+
*/
|
|
58
|
+
this.dev = this._convert(0);
|
|
59
|
+
/**
|
|
60
|
+
* inode number
|
|
61
|
+
*/
|
|
62
|
+
this.ino = this._convert(0);
|
|
63
|
+
/**
|
|
64
|
+
* device ID (if special file)
|
|
65
|
+
*/
|
|
66
|
+
this.rdev = this._convert(0);
|
|
67
|
+
/**
|
|
68
|
+
* number of hard links
|
|
69
|
+
*/
|
|
70
|
+
this.nlink = this._convert(1);
|
|
71
|
+
/**
|
|
72
|
+
* blocksize for file system I/O
|
|
73
|
+
*/
|
|
74
|
+
this.blksize = this._convert(4096);
|
|
75
|
+
/**
|
|
76
|
+
* user ID of owner
|
|
77
|
+
*/
|
|
78
|
+
this.uid = this._convert(0);
|
|
79
|
+
/**
|
|
80
|
+
* group ID of owner
|
|
81
|
+
*/
|
|
82
|
+
this.gid = this._convert(0);
|
|
83
|
+
/**
|
|
84
|
+
* Some file systems stash data on stats objects.
|
|
85
|
+
*/
|
|
72
86
|
this.fileData = null;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
if (typeof ctimeMs !== 'number') {
|
|
86
|
-
if (!currentTime) {
|
|
87
|
-
currentTime = Date.now();
|
|
88
|
-
}
|
|
89
|
-
ctimeMs = currentTime;
|
|
90
|
-
}
|
|
91
|
-
if (typeof birthtimeMs !== 'number') {
|
|
92
|
-
if (!currentTime) {
|
|
93
|
-
currentTime = Date.now();
|
|
94
|
-
}
|
|
95
|
-
birthtimeMs = currentTime;
|
|
96
|
-
}
|
|
97
|
-
if (typeof uid !== 'number') {
|
|
98
|
-
uid = 0;
|
|
87
|
+
const currentTime = Date.now();
|
|
88
|
+
const resolveT = (v, def) => (typeof v == this._typename ? v : this._convert(typeof v == this._typename_inverse ? v : def));
|
|
89
|
+
this.atimeMs = resolveT(atimeMs, currentTime);
|
|
90
|
+
this.mtimeMs = resolveT(mtimeMs, currentTime);
|
|
91
|
+
this.ctimeMs = resolveT(ctimeMs, currentTime);
|
|
92
|
+
this.birthtimeMs = resolveT(birthtimeMs, currentTime);
|
|
93
|
+
this.uid = resolveT(uid, 0);
|
|
94
|
+
this.gid = resolveT(gid, 0);
|
|
95
|
+
this.size = this._convert(size);
|
|
96
|
+
if (mode) {
|
|
97
|
+
this.mode = this._convert(mode);
|
|
99
98
|
}
|
|
100
|
-
|
|
101
|
-
gid = 0;
|
|
102
|
-
}
|
|
103
|
-
this.atimeMs = atimeMs;
|
|
104
|
-
this.ctimeMs = ctimeMs;
|
|
105
|
-
this.mtimeMs = mtimeMs;
|
|
106
|
-
this.birthtimeMs = birthtimeMs;
|
|
107
|
-
if (!mode) {
|
|
99
|
+
else {
|
|
108
100
|
switch (itemType) {
|
|
109
101
|
case FileType.FILE:
|
|
110
|
-
this.mode = 0o644;
|
|
102
|
+
this.mode = this._convert(0o644);
|
|
111
103
|
break;
|
|
112
104
|
case FileType.DIRECTORY:
|
|
113
105
|
default:
|
|
114
|
-
this.mode = 0o777;
|
|
106
|
+
this.mode = this._convert(0o777);
|
|
115
107
|
}
|
|
116
108
|
}
|
|
117
|
-
else {
|
|
118
|
-
this.mode = mode;
|
|
119
|
-
}
|
|
120
109
|
// number of 512B blocks allocated
|
|
121
|
-
this.blocks = Math.ceil(size / 512);
|
|
110
|
+
this.blocks = this._convert(Math.ceil(Number(size) / 512));
|
|
122
111
|
// Check if mode also includes top-most bits, which indicate the file's
|
|
123
112
|
// type.
|
|
124
113
|
if ((this.mode & S_IFMT) == 0) {
|
|
125
|
-
this.mode
|
|
114
|
+
this.mode = (this.mode | this._convert(itemType));
|
|
126
115
|
}
|
|
127
116
|
}
|
|
128
|
-
serialize() {
|
|
129
|
-
const data = new Uint8Array(32), view = new DataView(data.buffer);
|
|
130
|
-
view.setUint32(0, this.size, true);
|
|
131
|
-
view.setUint32(4, this.mode, true);
|
|
132
|
-
view.setFloat64(8, this.atime.getTime(), true);
|
|
133
|
-
view.setFloat64(16, this.mtime.getTime(), true);
|
|
134
|
-
view.setFloat64(24, this.ctime.getTime(), true);
|
|
135
|
-
view.setUint32(32, this.uid, true);
|
|
136
|
-
view.setUint32(36, this.gid, true);
|
|
137
|
-
return data;
|
|
138
|
-
}
|
|
139
117
|
/**
|
|
140
118
|
* @return [Boolean] True if this item is a file.
|
|
141
119
|
*/
|
|
@@ -188,26 +166,28 @@ export class Stats {
|
|
|
188
166
|
/**
|
|
189
167
|
* Convert the current stats object into a cred object
|
|
190
168
|
*/
|
|
191
|
-
getCred(uid = this.uid, gid = this.gid) {
|
|
192
|
-
return new Cred(uid, gid, this.uid, this.gid, uid, gid);
|
|
169
|
+
getCred(uid = Number(this.uid), gid = Number(this.gid)) {
|
|
170
|
+
return new Cred(uid, gid, Number(this.uid), Number(this.gid), uid, gid);
|
|
193
171
|
}
|
|
194
172
|
/**
|
|
195
173
|
* Change the mode of the file. We use this helper function to prevent messing
|
|
196
174
|
* up the type of the file, which is encoded in mode.
|
|
197
175
|
*/
|
|
198
176
|
chmod(mode) {
|
|
199
|
-
this.mode = (this.mode & S_IFMT) | mode;
|
|
177
|
+
this.mode = this._convert((this.mode & S_IFMT) | mode);
|
|
200
178
|
}
|
|
201
179
|
/**
|
|
202
180
|
* Change the owner user/group of the file.
|
|
203
181
|
* This function makes sure it is a valid UID/GID (that is, a 32 unsigned int)
|
|
204
182
|
*/
|
|
205
183
|
chown(uid, gid) {
|
|
206
|
-
|
|
207
|
-
|
|
184
|
+
uid = Number(uid);
|
|
185
|
+
gid = Number(gid);
|
|
186
|
+
if (!isNaN(uid) && 0 <= uid && uid < 2 ** 32) {
|
|
187
|
+
this.uid = this._convert(uid);
|
|
208
188
|
}
|
|
209
|
-
if (!isNaN(
|
|
210
|
-
this.gid = gid;
|
|
189
|
+
if (!isNaN(gid) && 0 <= gid && gid < 2 ** 32) {
|
|
190
|
+
this.gid = this._convert(gid);
|
|
211
191
|
}
|
|
212
192
|
}
|
|
213
193
|
// We don't support the following types of files.
|
|
@@ -224,3 +204,72 @@ export class Stats {
|
|
|
224
204
|
return false;
|
|
225
205
|
}
|
|
226
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Implementation of Node's `Stats`.
|
|
209
|
+
*
|
|
210
|
+
* Attribute descriptions are from `man 2 stat'
|
|
211
|
+
* @see http://nodejs.org/api/fs.html#fs_class_fs_stats
|
|
212
|
+
* @see http://man7.org/linux/man-pages/man2/stat.2.html
|
|
213
|
+
*/
|
|
214
|
+
export class Stats extends StatsCommon {
|
|
215
|
+
constructor() {
|
|
216
|
+
super(...arguments);
|
|
217
|
+
this._isBigint = false;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Clones the stats object.
|
|
221
|
+
*/
|
|
222
|
+
static clone(s) {
|
|
223
|
+
return new Stats(s.mode & S_IFMT, s.size, s.mode & ~S_IFMT, s.atimeMs, s.mtimeMs, s.ctimeMs, s.uid, s.gid, s.birthtimeMs);
|
|
224
|
+
}
|
|
225
|
+
static Deserialize(data) {
|
|
226
|
+
const view = new DataView('buffer' in data ? data.buffer : data);
|
|
227
|
+
const size = view.getUint32(0, true), mode = view.getUint32(4, true), atime = view.getFloat64(8, true), mtime = view.getFloat64(16, true), ctime = view.getFloat64(24, true), uid = view.getUint32(32, true), gid = view.getUint32(36, true);
|
|
228
|
+
return new Stats(mode & S_IFMT, size, mode & ~S_IFMT, atime, mtime, ctime, uid, gid);
|
|
229
|
+
}
|
|
230
|
+
serialize() {
|
|
231
|
+
const data = new Uint8Array(32), view = new DataView(data.buffer);
|
|
232
|
+
view.setUint32(0, this.size, true);
|
|
233
|
+
view.setUint32(4, this.mode, true);
|
|
234
|
+
view.setFloat64(8, this.atime.getTime(), true);
|
|
235
|
+
view.setFloat64(16, this.mtime.getTime(), true);
|
|
236
|
+
view.setFloat64(24, this.ctime.getTime(), true);
|
|
237
|
+
view.setUint32(32, this.uid, true);
|
|
238
|
+
view.setUint32(36, this.gid, true);
|
|
239
|
+
return data;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
Stats;
|
|
243
|
+
/**
|
|
244
|
+
* Stats with bigint
|
|
245
|
+
* @todo Implement with bigint instead of wrapping Stats
|
|
246
|
+
*/
|
|
247
|
+
export class BigIntStats extends StatsCommon {
|
|
248
|
+
constructor() {
|
|
249
|
+
super(...arguments);
|
|
250
|
+
this._isBigint = true;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Clone a stats object.
|
|
254
|
+
*/
|
|
255
|
+
static clone(s) {
|
|
256
|
+
return new BigIntStats(Number(s.mode) & S_IFMT, BigInt(s.size), BigInt(s.mode) & BigInt(~S_IFMT), BigInt(s.atimeMs), BigInt(s.mtimeMs), BigInt(s.ctimeMs), BigInt(s.uid), BigInt(s.gid), BigInt(s.birthtimeMs));
|
|
257
|
+
}
|
|
258
|
+
static Deserialize(data) {
|
|
259
|
+
const view = new DataView('buffer' in data ? data.buffer : data);
|
|
260
|
+
const size = view.getBigUint64(0, true), mode = view.getBigUint64(4, true), atime = view.getFloat64(8, true), mtime = view.getFloat64(16, true), ctime = view.getFloat64(24, true), uid = view.getBigUint64(32, true), gid = view.getBigUint64(36, true);
|
|
261
|
+
return new Stats(Number(mode) & S_IFMT, size, mode & BigInt(~S_IFMT), atime, mtime, ctime, uid, gid);
|
|
262
|
+
}
|
|
263
|
+
serialize() {
|
|
264
|
+
const data = new Uint8Array(32), view = new DataView(data.buffer);
|
|
265
|
+
view.setBigUint64(0, this.size, true);
|
|
266
|
+
view.setBigUint64(4, this.mode, true);
|
|
267
|
+
view.setFloat64(8, this.atime.getTime(), true);
|
|
268
|
+
view.setFloat64(16, this.mtime.getTime(), true);
|
|
269
|
+
view.setFloat64(24, this.ctime.getTime(), true);
|
|
270
|
+
view.setBigUint64(32, this.uid, true);
|
|
271
|
+
view.setBigUint64(36, this.gid, true);
|
|
272
|
+
return data;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
BigIntStats;
|
package/dist/utils.d.ts
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
import { FileSystem } from './filesystem.js';
|
|
6
6
|
import { Cred } from './cred.js';
|
|
7
7
|
import type { BaseBackendConstructor } from './backends/backend.js';
|
|
8
|
-
import type { TextEncoder as TextEncoderType, TextDecoder as TextDecoderType } from 'node:util';
|
|
9
8
|
/**
|
|
10
9
|
* Synchronous recursive makedir.
|
|
11
10
|
* @internal
|
|
@@ -31,13 +30,10 @@ export declare const setImmediate: (callback: () => unknown) => void;
|
|
|
31
30
|
* @internal
|
|
32
31
|
*/
|
|
33
32
|
export declare const ROOT_NODE_ID: string;
|
|
34
|
-
declare
|
|
35
|
-
export declare
|
|
36
|
-
declare const textDecoder: TextDecoderType;
|
|
37
|
-
export declare const decode: typeof textDecoder.decode;
|
|
33
|
+
export declare function encode(input: string, encoding?: string): Uint8Array;
|
|
34
|
+
export declare function decode(input?: NodeJS.ArrayBufferView | ArrayBuffer, encoding?: string): string;
|
|
38
35
|
/**
|
|
39
36
|
* Generates a random ID.
|
|
40
37
|
* @internal
|
|
41
38
|
*/
|
|
42
39
|
export declare function randomUUID(): string;
|
|
43
|
-
export {};
|