index.js
7.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
"use strict";
/**
* Constants (defined in `stat.h`).
*/
const S_IFMT = 61440; /* 0170000 type of file */
const S_IFIFO = 4096; /* 0010000 named pipe (fifo) */
const S_IFCHR = 8192; /* 0020000 character special */
const S_IFDIR = 16384; /* 0040000 directory */
const S_IFBLK = 24576; /* 0060000 block special */
const S_IFREG = 32768; /* 0100000 regular */
const S_IFLNK = 40960; /* 0120000 symbolic link */
const S_IFSOCK = 49152; /* 0140000 socket */
const S_IFWHT = 57344; /* 0160000 whiteout */
const S_ISUID = 2048; /* 0004000 set user id on execution */
const S_ISGID = 1024; /* 0002000 set group id on execution */
const S_ISVTX = 512; /* 0001000 save swapped text even after use */
const S_IRUSR = 256; /* 0000400 read permission, owner */
const S_IWUSR = 128; /* 0000200 write permission, owner */
const S_IXUSR = 64; /* 0000100 execute/search permission, owner */
const S_IRGRP = 32; /* 0000040 read permission, group */
const S_IWGRP = 16; /* 0000020 write permission, group */
const S_IXGRP = 8; /* 0000010 execute/search permission, group */
const S_IROTH = 4; /* 0000004 read permission, others */
const S_IWOTH = 2; /* 0000002 write permission, others */
const S_IXOTH = 1; /* 0000001 execute/search permission, others */
function createMode(stat) {
return new createMode.Mode(stat);
}
(function (createMode) {
function isStatsMode(v) {
return v && typeof v.mode === 'number';
}
createMode.isStatsMode = isStatsMode;
class RWX {
constructor(stat) {
this.stat = stat;
}
get read() {
return Boolean(this.stat.mode & this.constructor.r);
}
set read(v) {
if (v) {
this.stat.mode |= this.constructor.r;
}
else {
this.stat.mode &= ~this.constructor.r;
}
}
get write() {
return Boolean(this.stat.mode & this.constructor.w);
}
set write(v) {
if (v) {
this.stat.mode |= this.constructor.w;
}
else {
this.stat.mode &= ~this.constructor.w;
}
}
get execute() {
return Boolean(this.stat.mode & this.constructor.x);
}
set execute(v) {
if (v) {
this.stat.mode |= this.constructor.x;
}
else {
this.stat.mode &= ~this.constructor.x;
}
}
}
createMode.RWX = RWX;
class Owner extends RWX {
}
Owner.r = S_IRUSR;
Owner.w = S_IWUSR;
Owner.x = S_IXUSR;
createMode.Owner = Owner;
class Group extends RWX {
}
Group.r = S_IRGRP;
Group.w = S_IWGRP;
Group.x = S_IXGRP;
createMode.Group = Group;
class Others extends RWX {
}
Others.r = S_IROTH;
Others.w = S_IWOTH;
Others.x = S_IXOTH;
createMode.Others = Others;
class Mode {
constructor(stat) {
if (typeof stat === 'number') {
this.stat = { mode: stat };
}
else if (isStatsMode(stat)) {
this.stat = stat;
}
else {
this.stat = { mode: 0 };
}
this.owner = new Owner(this.stat);
this.group = new Group(this.stat);
this.others = new Others(this.stat);
}
checkModeProperty(property, set) {
const { mode } = this.stat;
if (set) {
this.stat.mode = ((mode | S_IFMT) & property) | (mode & ~S_IFMT);
}
return (mode & S_IFMT) === property;
}
isDirectory(v) {
return this.checkModeProperty(S_IFDIR, v);
}
isFile(v) {
return this.checkModeProperty(S_IFREG, v);
}
isBlockDevice(v) {
return this.checkModeProperty(S_IFBLK, v);
}
isCharacterDevice(v) {
return this.checkModeProperty(S_IFCHR, v);
}
isSymbolicLink(v) {
return this.checkModeProperty(S_IFLNK, v);
}
isFIFO(v) {
return this.checkModeProperty(S_IFIFO, v);
}
isSocket(v) {
return this.checkModeProperty(S_IFSOCK, v);
}
/**
* Returns an octal representation of the `mode`, eg. "0754".
*
* http://en.wikipedia.org/wiki/File_system_permissions#Numeric_notation
*
* @return {String}
* @api public
*/
toOctal() {
const octal = this.stat.mode & 4095 /* 07777 */;
return `0000${octal.toString(8)}`.slice(-4);
}
/**
* Returns a String representation of the `mode`.
* The output resembles something similar to what `ls -l` would output.
*
* http://en.wikipedia.org/wiki/Unix_file_types
*
* @return {String}
* @api public
*/
toString() {
const str = [];
// file type
if (this.isDirectory()) {
str.push('d');
}
else if (this.isFile()) {
str.push('-');
}
else if (this.isBlockDevice()) {
str.push('b');
}
else if (this.isCharacterDevice()) {
str.push('c');
}
else if (this.isSymbolicLink()) {
str.push('l');
}
else if (this.isFIFO()) {
str.push('p');
}
else if (this.isSocket()) {
str.push('s');
}
else {
const mode = this.valueOf();
const err = new TypeError(`Unexpected "file type": mode=${mode}`);
//err.stat = this.stat;
//err.mode = mode;
throw err;
}
// owner read, write, execute
str.push(this.owner.read ? 'r' : '-');
str.push(this.owner.write ? 'w' : '-');
if (this.setuid) {
str.push(this.owner.execute ? 's' : 'S');
}
else {
str.push(this.owner.execute ? 'x' : '-');
}
// group read, write, execute
str.push(this.group.read ? 'r' : '-');
str.push(this.group.write ? 'w' : '-');
if (this.setgid) {
str.push(this.group.execute ? 's' : 'S');
}
else {
str.push(this.group.execute ? 'x' : '-');
}
// others read, write, execute
str.push(this.others.read ? 'r' : '-');
str.push(this.others.write ? 'w' : '-');
if (this.sticky) {
str.push(this.others.execute ? 't' : 'T');
}
else {
str.push(this.others.execute ? 'x' : '-');
}
return str.join('');
}
valueOf() {
return this.stat.mode;
}
get setuid() {
return Boolean(this.stat.mode & S_ISUID);
}
set setuid(v) {
if (v) {
this.stat.mode |= S_ISUID;
}
else {
this.stat.mode &= ~S_ISUID;
}
}
get setgid() {
return Boolean(this.stat.mode & S_ISGID);
}
set setgid(v) {
if (v) {
this.stat.mode |= S_ISGID;
}
else {
this.stat.mode &= ~S_ISGID;
}
}
get sticky() {
return Boolean(this.stat.mode & S_ISVTX);
}
set sticky(v) {
if (v) {
this.stat.mode |= S_ISVTX;
}
else {
this.stat.mode &= ~S_ISVTX;
}
}
}
createMode.Mode = Mode;
// So that `instanceof` checks work as expected
createMode.prototype = Mode.prototype;
})(createMode || (createMode = {}));
module.exports = createMode;
//# sourceMappingURL=index.js.map