UNPKG

13.3 kBJavaScriptView Raw
1"use strict";
2var __extends = (this && this.__extends) || (function () {
3 var extendStatics = function (d, b) {
4 extendStatics = Object.setPrototypeOf ||
5 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
7 return extendStatics(d, b);
8 };
9 return function (d, b) {
10 extendStatics(d, b);
11 function __() { this.constructor = d; }
12 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13 };
14})();
15Object.defineProperty(exports, "__esModule", { value: true });
16exports.File = exports.Link = exports.Node = exports.SEP = void 0;
17var process_1 = require("./process");
18var buffer_1 = require("./internal/buffer");
19var constants_1 = require("./constants");
20var events_1 = require("events");
21var Stats_1 = require("./Stats");
22var S_IFMT = constants_1.constants.S_IFMT, S_IFDIR = constants_1.constants.S_IFDIR, S_IFREG = constants_1.constants.S_IFREG, S_IFLNK = constants_1.constants.S_IFLNK, O_APPEND = constants_1.constants.O_APPEND;
23exports.SEP = '/';
24/**
25 * Node in a file system (like i-node, v-node).
26 */
27var Node = /** @class */ (function (_super) {
28 __extends(Node, _super);
29 function Node(ino, perm) {
30 if (perm === void 0) { perm = 438; }
31 var _this = _super.call(this) || this;
32 // User ID and group ID.
33 _this.uid = process_1.default.getuid();
34 _this.gid = process_1.default.getgid();
35 _this.atime = new Date();
36 _this.mtime = new Date();
37 _this.ctime = new Date();
38 _this.perm = 438; // Permissions `chmod`, `fchmod`
39 _this.mode = S_IFREG; // S_IFDIR, S_IFREG, etc.. (file by default?)
40 // Number of hard links pointing at this Node.
41 _this.nlink = 1;
42 _this.perm = perm;
43 _this.mode |= perm;
44 _this.ino = ino;
45 return _this;
46 }
47 Node.prototype.getString = function (encoding) {
48 if (encoding === void 0) { encoding = 'utf8'; }
49 return this.getBuffer().toString(encoding);
50 };
51 Node.prototype.setString = function (str) {
52 // this.setBuffer(bufferFrom(str, 'utf8'));
53 this.buf = buffer_1.bufferFrom(str, 'utf8');
54 this.touch();
55 };
56 Node.prototype.getBuffer = function () {
57 if (!this.buf)
58 this.setBuffer(buffer_1.bufferAllocUnsafe(0));
59 return buffer_1.bufferFrom(this.buf); // Return a copy.
60 };
61 Node.prototype.setBuffer = function (buf) {
62 this.buf = buffer_1.bufferFrom(buf); // Creates a copy of data.
63 this.touch();
64 };
65 Node.prototype.getSize = function () {
66 return this.buf ? this.buf.length : 0;
67 };
68 Node.prototype.setModeProperty = function (property) {
69 this.mode = (this.mode & ~S_IFMT) | property;
70 };
71 Node.prototype.setIsFile = function () {
72 this.setModeProperty(S_IFREG);
73 };
74 Node.prototype.setIsDirectory = function () {
75 this.setModeProperty(S_IFDIR);
76 };
77 Node.prototype.setIsSymlink = function () {
78 this.setModeProperty(S_IFLNK);
79 };
80 Node.prototype.isFile = function () {
81 return (this.mode & S_IFMT) === S_IFREG;
82 };
83 Node.prototype.isDirectory = function () {
84 return (this.mode & S_IFMT) === S_IFDIR;
85 };
86 Node.prototype.isSymlink = function () {
87 // return !!this.symlink;
88 return (this.mode & S_IFMT) === S_IFLNK;
89 };
90 Node.prototype.makeSymlink = function (steps) {
91 this.symlink = steps;
92 this.setIsSymlink();
93 };
94 Node.prototype.write = function (buf, off, len, pos) {
95 if (off === void 0) { off = 0; }
96 if (len === void 0) { len = buf.length; }
97 if (pos === void 0) { pos = 0; }
98 if (!this.buf)
99 this.buf = buffer_1.bufferAllocUnsafe(0);
100 if (pos + len > this.buf.length) {
101 var newBuf = buffer_1.bufferAllocUnsafe(pos + len);
102 this.buf.copy(newBuf, 0, 0, this.buf.length);
103 this.buf = newBuf;
104 }
105 buf.copy(this.buf, pos, off, off + len);
106 this.touch();
107 return len;
108 };
109 // Returns the number of bytes read.
110 Node.prototype.read = function (buf, off, len, pos) {
111 if (off === void 0) { off = 0; }
112 if (len === void 0) { len = buf.byteLength; }
113 if (pos === void 0) { pos = 0; }
114 if (!this.buf)
115 this.buf = buffer_1.bufferAllocUnsafe(0);
116 var actualLen = len;
117 if (actualLen > buf.byteLength) {
118 actualLen = buf.byteLength;
119 }
120 if (actualLen + pos > this.buf.length) {
121 actualLen = this.buf.length - pos;
122 }
123 this.buf.copy(buf, off, pos, pos + actualLen);
124 return actualLen;
125 };
126 Node.prototype.truncate = function (len) {
127 if (len === void 0) { len = 0; }
128 if (!len)
129 this.buf = buffer_1.bufferAllocUnsafe(0);
130 else {
131 if (!this.buf)
132 this.buf = buffer_1.bufferAllocUnsafe(0);
133 if (len <= this.buf.length) {
134 this.buf = this.buf.slice(0, len);
135 }
136 else {
137 var buf = buffer_1.bufferAllocUnsafe(0);
138 this.buf.copy(buf);
139 buf.fill(0, len);
140 }
141 }
142 this.touch();
143 };
144 Node.prototype.chmod = function (perm) {
145 this.perm = perm;
146 this.mode = (this.mode & ~511) | perm;
147 this.touch();
148 };
149 Node.prototype.chown = function (uid, gid) {
150 this.uid = uid;
151 this.gid = gid;
152 this.touch();
153 };
154 Node.prototype.touch = function () {
155 this.mtime = new Date();
156 this.emit('change', this);
157 };
158 Node.prototype.canRead = function (uid, gid) {
159 if (uid === void 0) { uid = process_1.default.getuid(); }
160 if (gid === void 0) { gid = process_1.default.getgid(); }
161 if (this.perm & 4 /* IROTH */) {
162 return true;
163 }
164 if (gid === this.gid) {
165 if (this.perm & 32 /* IRGRP */) {
166 return true;
167 }
168 }
169 if (uid === this.uid) {
170 if (this.perm & 256 /* IRUSR */) {
171 return true;
172 }
173 }
174 return false;
175 };
176 Node.prototype.canWrite = function (uid, gid) {
177 if (uid === void 0) { uid = process_1.default.getuid(); }
178 if (gid === void 0) { gid = process_1.default.getgid(); }
179 if (this.perm & 2 /* IWOTH */) {
180 return true;
181 }
182 if (gid === this.gid) {
183 if (this.perm & 16 /* IWGRP */) {
184 return true;
185 }
186 }
187 if (uid === this.uid) {
188 if (this.perm & 128 /* IWUSR */) {
189 return true;
190 }
191 }
192 return false;
193 };
194 Node.prototype.del = function () {
195 this.emit('delete', this);
196 };
197 Node.prototype.toJSON = function () {
198 return {
199 ino: this.ino,
200 uid: this.uid,
201 gid: this.gid,
202 atime: this.atime.getTime(),
203 mtime: this.mtime.getTime(),
204 ctime: this.ctime.getTime(),
205 perm: this.perm,
206 mode: this.mode,
207 nlink: this.nlink,
208 symlink: this.symlink,
209 data: this.getString(),
210 };
211 };
212 return Node;
213}(events_1.EventEmitter));
214exports.Node = Node;
215/**
216 * Represents a hard link that points to an i-node `node`.
217 */
218var Link = /** @class */ (function (_super) {
219 __extends(Link, _super);
220 function Link(vol, parent, name) {
221 var _this = _super.call(this) || this;
222 _this.children = {};
223 // Path to this node as Array: ['usr', 'bin', 'node'].
224 _this.steps = [];
225 // "i-node" number of the node.
226 _this.ino = 0;
227 // Number of children.
228 _this.length = 0;
229 _this.vol = vol;
230 _this.parent = parent;
231 _this.steps = parent ? parent.steps.concat([name]) : [name];
232 return _this;
233 }
234 Link.prototype.setNode = function (node) {
235 this.node = node;
236 this.ino = node.ino;
237 };
238 Link.prototype.getNode = function () {
239 return this.node;
240 };
241 Link.prototype.createChild = function (name, node) {
242 if (node === void 0) { node = this.vol.createNode(); }
243 var link = new Link(this.vol, this, name);
244 link.setNode(node);
245 if (node.isDirectory()) {
246 // link.setChild('.', link);
247 // link.getNode().nlink++;
248 // link.setChild('..', this);
249 // this.getNode().nlink++;
250 }
251 this.setChild(name, link);
252 return link;
253 };
254 Link.prototype.setChild = function (name, link) {
255 if (link === void 0) { link = new Link(this.vol, this, name); }
256 this.children[name] = link;
257 link.parent = this;
258 this.length++;
259 this.emit('child:add', link, this);
260 return link;
261 };
262 Link.prototype.deleteChild = function (link) {
263 delete this.children[link.getName()];
264 this.length--;
265 this.emit('child:delete', link, this);
266 };
267 Link.prototype.getChild = function (name) {
268 if (Object.hasOwnProperty.call(this.children, name)) {
269 return this.children[name];
270 }
271 };
272 Link.prototype.getPath = function () {
273 return this.steps.join(exports.SEP);
274 };
275 Link.prototype.getName = function () {
276 return this.steps[this.steps.length - 1];
277 };
278 // del() {
279 // const parent = this.parent;
280 // if(parent) {
281 // parent.deleteChild(link);
282 // }
283 // this.parent = null;
284 // this.vol = null;
285 // }
286 /**
287 * Walk the tree path and return the `Link` at that location, if any.
288 * @param steps {string[]} Desired location.
289 * @param stop {number} Max steps to go into.
290 * @param i {number} Current step in the `steps` array.
291 *
292 * @return {Link|null}
293 */
294 Link.prototype.walk = function (steps, stop, i) {
295 if (stop === void 0) { stop = steps.length; }
296 if (i === void 0) { i = 0; }
297 if (i >= steps.length)
298 return this;
299 if (i >= stop)
300 return this;
301 var step = steps[i];
302 var link = this.getChild(step);
303 if (!link)
304 return null;
305 return link.walk(steps, stop, i + 1);
306 };
307 Link.prototype.toJSON = function () {
308 return {
309 steps: this.steps,
310 ino: this.ino,
311 children: Object.keys(this.children),
312 };
313 };
314 return Link;
315}(events_1.EventEmitter));
316exports.Link = Link;
317/**
318 * Represents an open file (file descriptor) that points to a `Link` (Hard-link) and a `Node`.
319 */
320var File = /** @class */ (function () {
321 /**
322 * Open a Link-Node pair. `node` is provided separately as that might be a different node
323 * rather the one `link` points to, because it might be a symlink.
324 * @param link
325 * @param node
326 * @param flags
327 * @param fd
328 */
329 function File(link, node, flags, fd) {
330 /**
331 * A cursor/offset position in a file, where data will be written on write.
332 * User can "seek" this position.
333 */
334 this.position = 0;
335 this.link = link;
336 this.node = node;
337 this.flags = flags;
338 this.fd = fd;
339 }
340 File.prototype.getString = function (encoding) {
341 if (encoding === void 0) { encoding = 'utf8'; }
342 return this.node.getString();
343 };
344 File.prototype.setString = function (str) {
345 this.node.setString(str);
346 };
347 File.prototype.getBuffer = function () {
348 return this.node.getBuffer();
349 };
350 File.prototype.setBuffer = function (buf) {
351 this.node.setBuffer(buf);
352 };
353 File.prototype.getSize = function () {
354 return this.node.getSize();
355 };
356 File.prototype.truncate = function (len) {
357 this.node.truncate(len);
358 };
359 File.prototype.seekTo = function (position) {
360 this.position = position;
361 };
362 File.prototype.stats = function () {
363 return Stats_1.default.build(this.node);
364 };
365 File.prototype.write = function (buf, offset, length, position) {
366 if (offset === void 0) { offset = 0; }
367 if (length === void 0) { length = buf.length; }
368 if (typeof position !== 'number')
369 position = this.position;
370 if (this.flags & O_APPEND)
371 position = this.getSize();
372 var bytes = this.node.write(buf, offset, length, position);
373 this.position = position + bytes;
374 return bytes;
375 };
376 File.prototype.read = function (buf, offset, length, position) {
377 if (offset === void 0) { offset = 0; }
378 if (length === void 0) { length = buf.byteLength; }
379 if (typeof position !== 'number')
380 position = this.position;
381 var bytes = this.node.read(buf, offset, length, position);
382 this.position = position + bytes;
383 return bytes;
384 };
385 File.prototype.chmod = function (perm) {
386 this.node.chmod(perm);
387 };
388 File.prototype.chown = function (uid, gid) {
389 this.node.chown(uid, gid);
390 };
391 return File;
392}());
393exports.File = File;