@zenfs/core 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ApiError.d.ts +51 -14
- package/dist/ApiError.js +60 -34
- package/dist/FileIndex.d.ts +32 -35
- package/dist/FileIndex.js +93 -109
- package/dist/backends/AsyncMirror.d.ts +42 -43
- package/dist/backends/AsyncMirror.js +146 -133
- package/dist/backends/AsyncStore.d.ts +29 -28
- package/dist/backends/AsyncStore.js +139 -189
- package/dist/backends/InMemory.d.ts +16 -13
- package/dist/backends/InMemory.js +29 -14
- package/dist/backends/Locked.d.ts +8 -28
- package/dist/backends/Locked.js +44 -148
- package/dist/backends/OverlayFS.d.ts +26 -34
- package/dist/backends/OverlayFS.js +208 -371
- package/dist/backends/SyncStore.d.ts +54 -72
- package/dist/backends/SyncStore.js +159 -161
- package/dist/backends/backend.d.ts +45 -29
- package/dist/backends/backend.js +83 -13
- package/dist/backends/index.d.ts +6 -7
- package/dist/backends/index.js +5 -6
- package/dist/browser.min.js +5 -7
- package/dist/browser.min.js.map +4 -4
- package/dist/emulation/callbacks.d.ts +36 -67
- package/dist/emulation/callbacks.js +90 -46
- package/dist/emulation/constants.js +1 -1
- package/dist/emulation/promises.d.ts +228 -129
- package/dist/emulation/promises.js +414 -172
- package/dist/emulation/shared.d.ts +10 -10
- package/dist/emulation/shared.js +18 -20
- package/dist/emulation/sync.d.ts +25 -25
- package/dist/emulation/sync.js +187 -73
- package/dist/file.d.ts +166 -170
- package/dist/file.js +199 -218
- package/dist/filesystem.d.ts +68 -241
- package/dist/filesystem.js +59 -383
- package/dist/index.d.ts +7 -44
- package/dist/index.js +13 -52
- package/dist/inode.d.ts +37 -28
- package/dist/inode.js +123 -65
- package/dist/stats.d.ts +21 -19
- package/dist/stats.js +35 -56
- package/dist/utils.d.ts +26 -9
- package/dist/utils.js +73 -102
- package/package.json +4 -3
package/dist/inode.d.ts
CHANGED
|
@@ -1,21 +1,42 @@
|
|
|
1
1
|
import { Stats } from './stats.js';
|
|
2
|
+
export type Ino = bigint;
|
|
3
|
+
export declare const size_max: number;
|
|
4
|
+
/**
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export declare const rootIno: Ino;
|
|
8
|
+
/**
|
|
9
|
+
* Generate 4 random bits at a time
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export declare function randomIno(): Ino;
|
|
2
14
|
/**
|
|
3
15
|
* Generic inode definition that can easily be serialized.
|
|
4
16
|
*/
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
export declare class Inode {
|
|
18
|
+
readonly buffer: ArrayBufferLike;
|
|
19
|
+
get data(): Uint8Array;
|
|
20
|
+
protected view: DataView;
|
|
21
|
+
constructor(buffer?: ArrayBufferLike);
|
|
22
|
+
get ino(): Ino;
|
|
23
|
+
set ino(value: Ino);
|
|
24
|
+
get size(): number;
|
|
25
|
+
set size(value: number);
|
|
26
|
+
get mode(): number;
|
|
27
|
+
set mode(value: number);
|
|
28
|
+
get nlink(): number;
|
|
29
|
+
set nlink(value: number);
|
|
30
|
+
get uid(): number;
|
|
31
|
+
set uid(value: number);
|
|
32
|
+
get gid(): number;
|
|
33
|
+
set gid(value: number);
|
|
34
|
+
get atime(): number;
|
|
35
|
+
set atime(value: number);
|
|
36
|
+
get mtime(): number;
|
|
37
|
+
set mtime(value: number);
|
|
38
|
+
get ctime(): number;
|
|
39
|
+
set ctime(value: number);
|
|
19
40
|
/**
|
|
20
41
|
* Handy function that converts the Inode to a Node Stats object.
|
|
21
42
|
*/
|
|
@@ -23,11 +44,7 @@ export default class Inode {
|
|
|
23
44
|
/**
|
|
24
45
|
* Get the size of this Inode, in bytes.
|
|
25
46
|
*/
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Writes the inode into the start of the buffer.
|
|
29
|
-
*/
|
|
30
|
-
serialize(data?: ArrayBufferLike | ArrayBufferView): Uint8Array;
|
|
47
|
+
sizeof(): number;
|
|
31
48
|
/**
|
|
32
49
|
* Updates the Inode using information from the stats object. Used by file
|
|
33
50
|
* systems at sync time, e.g.:
|
|
@@ -38,13 +55,5 @@ export default class Inode {
|
|
|
38
55
|
* file system.
|
|
39
56
|
* @return True if any changes have occurred.
|
|
40
57
|
*/
|
|
41
|
-
update(stats: Stats): boolean;
|
|
42
|
-
/**
|
|
43
|
-
* @return [Boolean] True if this item is a file.
|
|
44
|
-
*/
|
|
45
|
-
isFile(): boolean;
|
|
46
|
-
/**
|
|
47
|
-
* @return [Boolean] True if this item is a directory.
|
|
48
|
-
*/
|
|
49
|
-
isDirectory(): boolean;
|
|
58
|
+
update(stats: Readonly<Stats>): boolean;
|
|
50
59
|
}
|
package/dist/inode.js
CHANGED
|
@@ -1,54 +1,125 @@
|
|
|
1
|
+
import { S_IFMT } from './emulation/constants.js';
|
|
1
2
|
import { Stats, FileType } from './stats.js';
|
|
2
|
-
|
|
3
|
+
var Offset;
|
|
4
|
+
(function (Offset) {
|
|
5
|
+
Offset[Offset["ino"] = 0] = "ino";
|
|
6
|
+
Offset[Offset["size"] = 8] = "size";
|
|
7
|
+
Offset[Offset["mode"] = 12] = "mode";
|
|
8
|
+
Offset[Offset["nlink"] = 14] = "nlink";
|
|
9
|
+
Offset[Offset["uid"] = 18] = "uid";
|
|
10
|
+
Offset[Offset["gid"] = 22] = "gid";
|
|
11
|
+
Offset[Offset["atime"] = 26] = "atime";
|
|
12
|
+
Offset[Offset["mtime"] = 34] = "mtime";
|
|
13
|
+
Offset[Offset["ctime"] = 42] = "ctime";
|
|
14
|
+
})(Offset || (Offset = {}));
|
|
15
|
+
export const size_max = 2 ** 32 - 1;
|
|
16
|
+
/**
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export const rootIno = 0n;
|
|
20
|
+
/**
|
|
21
|
+
* Generates a random 32 bit integer, then converts to a hex string
|
|
22
|
+
*/
|
|
23
|
+
function _random() {
|
|
24
|
+
return Math.round(Math.random() * 2 ** 32).toString(16);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Generate 4 random bits at a time
|
|
28
|
+
*
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
export function randomIno() {
|
|
32
|
+
return BigInt('0x' + _random() + _random());
|
|
33
|
+
}
|
|
3
34
|
/**
|
|
4
35
|
* Generic inode definition that can easily be serialized.
|
|
5
36
|
*/
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
this.
|
|
20
|
-
this.
|
|
21
|
-
this.
|
|
22
|
-
|
|
37
|
+
export class Inode {
|
|
38
|
+
get data() {
|
|
39
|
+
return new Uint8Array(this.buffer);
|
|
40
|
+
}
|
|
41
|
+
constructor(buffer) {
|
|
42
|
+
const setDefaults = !buffer;
|
|
43
|
+
buffer ?? (buffer = new ArrayBuffer(50));
|
|
44
|
+
this.view = new DataView(buffer);
|
|
45
|
+
this.buffer = buffer;
|
|
46
|
+
if (!setDefaults) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// set defaults on a fresh inode
|
|
50
|
+
this.ino = randomIno();
|
|
51
|
+
this.nlink = 1;
|
|
52
|
+
this.size = 4096;
|
|
53
|
+
const now = Date.now();
|
|
54
|
+
this.atime = now;
|
|
55
|
+
this.mtime = now;
|
|
56
|
+
this.ctime = now;
|
|
57
|
+
}
|
|
58
|
+
get ino() {
|
|
59
|
+
return this.view.getBigUint64(Offset.ino, true);
|
|
60
|
+
}
|
|
61
|
+
set ino(value) {
|
|
62
|
+
this.view.setBigUint64(Offset.ino, value, true);
|
|
63
|
+
}
|
|
64
|
+
get size() {
|
|
65
|
+
return this.view.getUint32(Offset.size, true);
|
|
66
|
+
}
|
|
67
|
+
set size(value) {
|
|
68
|
+
this.view.setUint32(Offset.size, value, true);
|
|
69
|
+
}
|
|
70
|
+
get mode() {
|
|
71
|
+
return this.view.getUint16(Offset.mode, true);
|
|
72
|
+
}
|
|
73
|
+
set mode(value) {
|
|
74
|
+
this.view.setUint16(Offset.mode, value, true);
|
|
75
|
+
}
|
|
76
|
+
get nlink() {
|
|
77
|
+
return this.view.getUint32(Offset.nlink, true);
|
|
78
|
+
}
|
|
79
|
+
set nlink(value) {
|
|
80
|
+
this.view.setUint32(Offset.nlink, value, true);
|
|
81
|
+
}
|
|
82
|
+
get uid() {
|
|
83
|
+
return this.view.getUint32(Offset.uid, true);
|
|
84
|
+
}
|
|
85
|
+
set uid(value) {
|
|
86
|
+
this.view.setUint32(Offset.uid, value, true);
|
|
87
|
+
}
|
|
88
|
+
get gid() {
|
|
89
|
+
return this.view.getUint32(Offset.gid, true);
|
|
90
|
+
}
|
|
91
|
+
set gid(value) {
|
|
92
|
+
this.view.setUint32(Offset.gid, value, true);
|
|
93
|
+
}
|
|
94
|
+
get atime() {
|
|
95
|
+
return this.view.getFloat64(Offset.atime, true);
|
|
96
|
+
}
|
|
97
|
+
set atime(value) {
|
|
98
|
+
this.view.setFloat64(Offset.atime, value, true);
|
|
99
|
+
}
|
|
100
|
+
get mtime() {
|
|
101
|
+
return this.view.getFloat64(Offset.mtime, true);
|
|
102
|
+
}
|
|
103
|
+
set mtime(value) {
|
|
104
|
+
this.view.setFloat64(Offset.mtime, value, true);
|
|
105
|
+
}
|
|
106
|
+
get ctime() {
|
|
107
|
+
return this.view.getFloat64(Offset.ctime, true);
|
|
108
|
+
}
|
|
109
|
+
set ctime(value) {
|
|
110
|
+
this.view.setFloat64(Offset.ctime, value, true);
|
|
23
111
|
}
|
|
24
112
|
/**
|
|
25
113
|
* Handy function that converts the Inode to a Node Stats object.
|
|
26
114
|
*/
|
|
27
115
|
toStats() {
|
|
28
|
-
return new Stats((this.mode &
|
|
116
|
+
return new Stats((this.mode & S_IFMT) === FileType.DIRECTORY ? FileType.DIRECTORY : FileType.FILE, this.size, this.mode, this.atime, this.mtime, this.ctime, this.uid, this.gid);
|
|
29
117
|
}
|
|
30
118
|
/**
|
|
31
119
|
* Get the size of this Inode, in bytes.
|
|
32
120
|
*/
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return 38 + this.id.length;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Writes the inode into the start of the buffer.
|
|
39
|
-
*/
|
|
40
|
-
serialize(data = new Uint8Array(this.getSize())) {
|
|
41
|
-
const view = new DataView('buffer' in data ? data.buffer : data);
|
|
42
|
-
view.setUint32(0, this.size, true);
|
|
43
|
-
view.setUint16(4, this.mode, true);
|
|
44
|
-
view.setFloat64(6, this.atime, true);
|
|
45
|
-
view.setFloat64(14, this.mtime, true);
|
|
46
|
-
view.setFloat64(22, this.ctime, true);
|
|
47
|
-
view.setUint32(30, this.uid, true);
|
|
48
|
-
view.setUint32(34, this.gid, true);
|
|
49
|
-
const buffer = new Uint8Array(view.buffer);
|
|
50
|
-
buffer.set(encode(this.id), 38);
|
|
51
|
-
return buffer;
|
|
121
|
+
sizeof() {
|
|
122
|
+
return this.buffer.byteLength;
|
|
52
123
|
}
|
|
53
124
|
/**
|
|
54
125
|
* Updates the Inode using information from the stats object. Used by file
|
|
@@ -70,19 +141,8 @@ export default class Inode {
|
|
|
70
141
|
this.mode = stats.mode;
|
|
71
142
|
hasChanged = true;
|
|
72
143
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
this.atime = atimeMs;
|
|
76
|
-
hasChanged = true;
|
|
77
|
-
}
|
|
78
|
-
const mtimeMs = stats.mtime.getTime();
|
|
79
|
-
if (this.mtime !== mtimeMs) {
|
|
80
|
-
this.mtime = mtimeMs;
|
|
81
|
-
hasChanged = true;
|
|
82
|
-
}
|
|
83
|
-
const ctimeMs = stats.ctime.getTime();
|
|
84
|
-
if (this.ctime !== ctimeMs) {
|
|
85
|
-
this.ctime = ctimeMs;
|
|
144
|
+
if (this.nlink !== stats.nlink) {
|
|
145
|
+
this.nlink = stats.nlink;
|
|
86
146
|
hasChanged = true;
|
|
87
147
|
}
|
|
88
148
|
if (this.uid !== stats.uid) {
|
|
@@ -93,20 +153,18 @@ export default class Inode {
|
|
|
93
153
|
this.uid = stats.uid;
|
|
94
154
|
hasChanged = true;
|
|
95
155
|
}
|
|
156
|
+
if (this.atime !== stats.atimeMs) {
|
|
157
|
+
this.atime = stats.atimeMs;
|
|
158
|
+
hasChanged = true;
|
|
159
|
+
}
|
|
160
|
+
if (this.mtime !== stats.mtimeMs) {
|
|
161
|
+
this.mtime = stats.mtimeMs;
|
|
162
|
+
hasChanged = true;
|
|
163
|
+
}
|
|
164
|
+
if (this.ctime !== stats.ctimeMs) {
|
|
165
|
+
this.ctime = stats.ctimeMs;
|
|
166
|
+
hasChanged = true;
|
|
167
|
+
}
|
|
96
168
|
return hasChanged;
|
|
97
169
|
}
|
|
98
|
-
// XXX: Copied from Stats. Should reconcile these two into something more
|
|
99
|
-
// compact.
|
|
100
|
-
/**
|
|
101
|
-
* @return [Boolean] True if this item is a file.
|
|
102
|
-
*/
|
|
103
|
-
isFile() {
|
|
104
|
-
return (this.mode & 0xf000) === FileType.FILE;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* @return [Boolean] True if this item is a directory.
|
|
108
|
-
*/
|
|
109
|
-
isDirectory() {
|
|
110
|
-
return (this.mode & 0xf000) === FileType.DIRECTORY;
|
|
111
|
-
}
|
|
112
170
|
}
|
package/dist/stats.d.ts
CHANGED
|
@@ -13,7 +13,6 @@ export declare enum FileType {
|
|
|
13
13
|
* Common code used by both Stats and BigIntStats
|
|
14
14
|
*/
|
|
15
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
16
|
protected abstract _isBigint: boolean;
|
|
18
17
|
protected get _typename(): string;
|
|
19
18
|
protected get _typename_inverse(): string;
|
|
@@ -51,16 +50,20 @@ export declare abstract class StatsCommon<T extends number | bigint> implements
|
|
|
51
50
|
/**
|
|
52
51
|
* Some file systems stash data on stats objects.
|
|
53
52
|
*/
|
|
54
|
-
fileData
|
|
53
|
+
fileData?: Uint8Array;
|
|
55
54
|
atimeMs: T;
|
|
56
|
-
mtimeMs: T;
|
|
57
|
-
ctimeMs: T;
|
|
58
|
-
birthtimeMs: T;
|
|
59
|
-
size: T;
|
|
60
55
|
get atime(): Date;
|
|
56
|
+
set atime(value: Date);
|
|
57
|
+
mtimeMs: T;
|
|
61
58
|
get mtime(): Date;
|
|
59
|
+
set mtime(value: Date);
|
|
60
|
+
ctimeMs: T;
|
|
62
61
|
get ctime(): Date;
|
|
62
|
+
set ctime(value: Date);
|
|
63
|
+
birthtimeMs: T;
|
|
63
64
|
get birthtime(): Date;
|
|
65
|
+
set birthtime(value: Date);
|
|
66
|
+
size: T;
|
|
64
67
|
/**
|
|
65
68
|
* Provides information about a particular entry in the file system.
|
|
66
69
|
* @param itemType Type of the item (FILE, DIRECTORY, SYMLINK, or SOCKET)
|
|
@@ -75,45 +78,48 @@ export declare abstract class StatsCommon<T extends number | bigint> implements
|
|
|
75
78
|
* @param birthtimeMs time of file creation, in milliseconds since epoch
|
|
76
79
|
*/
|
|
77
80
|
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;
|
|
79
81
|
/**
|
|
80
|
-
* @
|
|
82
|
+
* @returns true if this item is a file.
|
|
81
83
|
*/
|
|
82
84
|
isFile(): boolean;
|
|
83
85
|
/**
|
|
84
|
-
* @
|
|
86
|
+
* @returns True if this item is a directory.
|
|
85
87
|
*/
|
|
86
88
|
isDirectory(): boolean;
|
|
87
89
|
/**
|
|
88
|
-
* @
|
|
90
|
+
* @returns true if this item is a symbolic link
|
|
89
91
|
*/
|
|
90
92
|
isSymbolicLink(): boolean;
|
|
93
|
+
isSocket(): boolean;
|
|
94
|
+
isBlockDevice(): boolean;
|
|
95
|
+
isCharacterDevice(): boolean;
|
|
96
|
+
isFIFO(): boolean;
|
|
91
97
|
/**
|
|
92
98
|
* Checks if a given user/group has access to this item
|
|
93
99
|
* @param mode The request access as 4 bits (unused, read, write, execute)
|
|
94
100
|
* @param uid The requesting UID
|
|
95
101
|
* @param gid The requesting GID
|
|
96
|
-
* @returns
|
|
102
|
+
* @returns True if the request has access, false if the request does not
|
|
103
|
+
* @internal
|
|
97
104
|
*/
|
|
98
105
|
hasAccess(mode: number, cred: Cred): boolean;
|
|
99
106
|
/**
|
|
100
107
|
* Convert the current stats object into a cred object
|
|
108
|
+
* @internal
|
|
101
109
|
*/
|
|
102
110
|
getCred(uid?: number, gid?: number): Cred;
|
|
103
111
|
/**
|
|
104
112
|
* Change the mode of the file. We use this helper function to prevent messing
|
|
105
113
|
* up the type of the file, which is encoded in mode.
|
|
114
|
+
* @internal
|
|
106
115
|
*/
|
|
107
116
|
chmod(mode: number): void;
|
|
108
117
|
/**
|
|
109
118
|
* Change the owner user/group of the file.
|
|
110
119
|
* This function makes sure it is a valid UID/GID (that is, a 32 unsigned int)
|
|
120
|
+
* @internal
|
|
111
121
|
*/
|
|
112
122
|
chown(uid: number | bigint, gid: number | bigint): void;
|
|
113
|
-
isSocket(): boolean;
|
|
114
|
-
isBlockDevice(): boolean;
|
|
115
|
-
isCharacterDevice(): boolean;
|
|
116
|
-
isFIFO(): boolean;
|
|
117
123
|
}
|
|
118
124
|
/**
|
|
119
125
|
* Implementation of Node's `Stats`.
|
|
@@ -128,8 +134,6 @@ export declare class Stats extends StatsCommon<number> implements Node.Stats {
|
|
|
128
134
|
* Clones the stats object.
|
|
129
135
|
*/
|
|
130
136
|
static clone(s: Stats): Stats;
|
|
131
|
-
static Deserialize(data: ArrayBufferLike | ArrayBufferView): Stats;
|
|
132
|
-
serialize(): Uint8Array;
|
|
133
137
|
}
|
|
134
138
|
/**
|
|
135
139
|
* Stats with bigint
|
|
@@ -145,6 +149,4 @@ export declare class BigIntStats extends StatsCommon<bigint> implements Node.Big
|
|
|
145
149
|
* Clone a stats object.
|
|
146
150
|
*/
|
|
147
151
|
static clone(s: BigIntStats | Stats): BigIntStats;
|
|
148
|
-
static Deserialize(data: ArrayBufferLike | ArrayBufferView): Stats;
|
|
149
|
-
serialize(): Uint8Array;
|
|
150
152
|
}
|
package/dist/stats.js
CHANGED
|
@@ -13,10 +13,6 @@ export var FileType;
|
|
|
13
13
|
* Common code used by both Stats and BigIntStats
|
|
14
14
|
*/
|
|
15
15
|
export class StatsCommon {
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
17
|
-
static Deserialize(data) {
|
|
18
|
-
throw new ReferenceError('Called static abstract method: StatsCommon.Deserialize()');
|
|
19
|
-
}
|
|
20
16
|
get _typename() {
|
|
21
17
|
return this._isBigint ? 'bigint' : 'number';
|
|
22
18
|
}
|
|
@@ -29,15 +25,27 @@ export class StatsCommon {
|
|
|
29
25
|
get atime() {
|
|
30
26
|
return new Date(Number(this.atimeMs));
|
|
31
27
|
}
|
|
28
|
+
set atime(value) {
|
|
29
|
+
this.atimeMs = this._convert(value.getTime());
|
|
30
|
+
}
|
|
32
31
|
get mtime() {
|
|
33
32
|
return new Date(Number(this.mtimeMs));
|
|
34
33
|
}
|
|
34
|
+
set mtime(value) {
|
|
35
|
+
this.mtimeMs = this._convert(value.getTime());
|
|
36
|
+
}
|
|
35
37
|
get ctime() {
|
|
36
38
|
return new Date(Number(this.ctimeMs));
|
|
37
39
|
}
|
|
40
|
+
set ctime(value) {
|
|
41
|
+
this.ctimeMs = this._convert(value.getTime());
|
|
42
|
+
}
|
|
38
43
|
get birthtime() {
|
|
39
44
|
return new Date(Number(this.birthtimeMs));
|
|
40
45
|
}
|
|
46
|
+
set birthtime(value) {
|
|
47
|
+
this.birthtimeMs = this._convert(value.getTime());
|
|
48
|
+
}
|
|
41
49
|
/**
|
|
42
50
|
* Provides information about a particular entry in the file system.
|
|
43
51
|
* @param itemType Type of the item (FILE, DIRECTORY, SYMLINK, or SOCKET)
|
|
@@ -108,36 +116,49 @@ export class StatsCommon {
|
|
|
108
116
|
}
|
|
109
117
|
// number of 512B blocks allocated
|
|
110
118
|
this.blocks = this._convert(Math.ceil(Number(size) / 512));
|
|
111
|
-
// Check if mode also includes top-most bits, which indicate the file's
|
|
112
|
-
// type.
|
|
119
|
+
// Check if mode also includes top-most bits, which indicate the file's type.
|
|
113
120
|
if ((this.mode & S_IFMT) == 0) {
|
|
114
121
|
this.mode = (this.mode | this._convert(itemType));
|
|
115
122
|
}
|
|
116
123
|
}
|
|
117
124
|
/**
|
|
118
|
-
* @
|
|
125
|
+
* @returns true if this item is a file.
|
|
119
126
|
*/
|
|
120
127
|
isFile() {
|
|
121
128
|
return (this.mode & S_IFMT) === S_IFREG;
|
|
122
129
|
}
|
|
123
130
|
/**
|
|
124
|
-
* @
|
|
131
|
+
* @returns True if this item is a directory.
|
|
125
132
|
*/
|
|
126
133
|
isDirectory() {
|
|
127
134
|
return (this.mode & S_IFMT) === S_IFDIR;
|
|
128
135
|
}
|
|
129
136
|
/**
|
|
130
|
-
* @
|
|
137
|
+
* @returns true if this item is a symbolic link
|
|
131
138
|
*/
|
|
132
139
|
isSymbolicLink() {
|
|
133
140
|
return (this.mode & S_IFMT) === S_IFLNK;
|
|
134
141
|
}
|
|
142
|
+
// Currently unsupported
|
|
143
|
+
isSocket() {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
isBlockDevice() {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
isCharacterDevice() {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
isFIFO() {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
135
155
|
/**
|
|
136
156
|
* Checks if a given user/group has access to this item
|
|
137
157
|
* @param mode The request access as 4 bits (unused, read, write, execute)
|
|
138
158
|
* @param uid The requesting UID
|
|
139
159
|
* @param gid The requesting GID
|
|
140
|
-
* @returns
|
|
160
|
+
* @returns True if the request has access, false if the request does not
|
|
161
|
+
* @internal
|
|
141
162
|
*/
|
|
142
163
|
hasAccess(mode, cred) {
|
|
143
164
|
if (cred.euid === 0 || cred.egid === 0) {
|
|
@@ -159,12 +180,13 @@ export class StatsCommon {
|
|
|
159
180
|
/*
|
|
160
181
|
Result = 0b0xxx (read, write, execute)
|
|
161
182
|
If any bits are set that means the request does not have that permission.
|
|
162
|
-
|
|
183
|
+
*/
|
|
163
184
|
const result = uMode & gMode & wMode;
|
|
164
185
|
return !result;
|
|
165
186
|
}
|
|
166
187
|
/**
|
|
167
188
|
* Convert the current stats object into a cred object
|
|
189
|
+
* @internal
|
|
168
190
|
*/
|
|
169
191
|
getCred(uid = Number(this.uid), gid = Number(this.gid)) {
|
|
170
192
|
return new Cred(uid, gid, Number(this.uid), Number(this.gid), uid, gid);
|
|
@@ -172,6 +194,7 @@ export class StatsCommon {
|
|
|
172
194
|
/**
|
|
173
195
|
* Change the mode of the file. We use this helper function to prevent messing
|
|
174
196
|
* up the type of the file, which is encoded in mode.
|
|
197
|
+
* @internal
|
|
175
198
|
*/
|
|
176
199
|
chmod(mode) {
|
|
177
200
|
this.mode = this._convert((this.mode & S_IFMT) | mode);
|
|
@@ -179,6 +202,7 @@ export class StatsCommon {
|
|
|
179
202
|
/**
|
|
180
203
|
* Change the owner user/group of the file.
|
|
181
204
|
* This function makes sure it is a valid UID/GID (that is, a 32 unsigned int)
|
|
205
|
+
* @internal
|
|
182
206
|
*/
|
|
183
207
|
chown(uid, gid) {
|
|
184
208
|
uid = Number(uid);
|
|
@@ -190,19 +214,6 @@ export class StatsCommon {
|
|
|
190
214
|
this.gid = this._convert(gid);
|
|
191
215
|
}
|
|
192
216
|
}
|
|
193
|
-
// We don't support the following types of files.
|
|
194
|
-
isSocket() {
|
|
195
|
-
return false;
|
|
196
|
-
}
|
|
197
|
-
isBlockDevice() {
|
|
198
|
-
return false;
|
|
199
|
-
}
|
|
200
|
-
isCharacterDevice() {
|
|
201
|
-
return false;
|
|
202
|
-
}
|
|
203
|
-
isFIFO() {
|
|
204
|
-
return false;
|
|
205
|
-
}
|
|
206
217
|
}
|
|
207
218
|
/**
|
|
208
219
|
* Implementation of Node's `Stats`.
|
|
@@ -222,22 +233,6 @@ export class Stats extends StatsCommon {
|
|
|
222
233
|
static clone(s) {
|
|
223
234
|
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
235
|
}
|
|
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
236
|
}
|
|
242
237
|
Stats;
|
|
243
238
|
/**
|
|
@@ -255,21 +250,5 @@ export class BigIntStats extends StatsCommon {
|
|
|
255
250
|
static clone(s) {
|
|
256
251
|
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
252
|
}
|
|
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
253
|
}
|
|
275
254
|
BigIntStats;
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
3
|
/**
|
|
3
4
|
* Grab bag of utility functions used across the code.
|
|
4
5
|
*/
|
|
5
6
|
import { FileSystem } from './filesystem.js';
|
|
6
7
|
import { Cred } from './cred.js';
|
|
7
|
-
import type {
|
|
8
|
+
import type { TextDecoder as _TextDecoder, TextEncoder as _TextEncoder } from 'node:util';
|
|
9
|
+
declare global {
|
|
10
|
+
function setImmediate(callback: () => unknown): void;
|
|
11
|
+
function atob(data: string): string;
|
|
12
|
+
function btoa(data: string): string;
|
|
13
|
+
const TextDecoder: typeof _TextDecoder;
|
|
14
|
+
const TextEncoder: typeof _TextEncoder;
|
|
15
|
+
}
|
|
8
16
|
/**
|
|
9
17
|
* Synchronous recursive makedir.
|
|
10
18
|
* @internal
|
|
11
19
|
*/
|
|
12
20
|
export declare function mkdirpSync(p: string, mode: number, cred: Cred, fs: FileSystem): void;
|
|
13
21
|
/**
|
|
14
|
-
*
|
|
22
|
+
* Calculates levenshtein distance.
|
|
15
23
|
* @internal
|
|
16
24
|
*/
|
|
17
|
-
export declare function
|
|
25
|
+
export declare function levenshtein(a: string, b: string): number;
|
|
18
26
|
/** Waits n ms. */
|
|
19
27
|
export declare function wait(ms: number): Promise<void>;
|
|
20
28
|
/**
|
|
@@ -25,15 +33,24 @@ export declare function toPromise(fn: (...fnArgs: unknown[]) => unknown): (...ar
|
|
|
25
33
|
/**
|
|
26
34
|
* @internal
|
|
27
35
|
*/
|
|
28
|
-
export declare const setImmediate: (
|
|
36
|
+
export declare const setImmediate: typeof globalThis.setImmediate | ((cb: any) => NodeJS.Timeout);
|
|
37
|
+
/**
|
|
38
|
+
* Encodes a string into a buffer
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
export declare function encode(input: string, encoding?: BufferEncoding): Uint8Array;
|
|
42
|
+
/**
|
|
43
|
+
* Decodes a string from a buffer
|
|
44
|
+
* @internal
|
|
45
|
+
*/
|
|
46
|
+
export declare function decode(input?: Uint8Array, encoding?: BufferEncoding): string;
|
|
29
47
|
/**
|
|
48
|
+
* Decodes a directory listing
|
|
30
49
|
* @internal
|
|
31
50
|
*/
|
|
32
|
-
export declare
|
|
33
|
-
export declare function encode(input: string, encoding?: string): Uint8Array;
|
|
34
|
-
export declare function decode(input?: NodeJS.ArrayBufferView | ArrayBuffer, encoding?: string): string;
|
|
51
|
+
export declare function decodeDirListing(data: Uint8Array): Record<string, bigint>;
|
|
35
52
|
/**
|
|
36
|
-
*
|
|
53
|
+
* Encodes a directory listing
|
|
37
54
|
* @internal
|
|
38
55
|
*/
|
|
39
|
-
export declare function
|
|
56
|
+
export declare function encodeDirListing(data: Record<string, bigint>): Uint8Array;
|