codekingpro/portable-devtools
115k
1"use strict";
2var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 if (k2 === undefined) k2 = k;
4 var desc = Object.getOwnPropertyDescriptor(m, k);
5 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 desc = { enumerable: true, get: function() { return m[k]; } };
7 }
8 Object.defineProperty(o, k2, desc);
9}) : (function(o, m, k, k2) {
10 if (k2 === undefined) k2 = k;
11 o[k2] = m[k];
12}));
13var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14 Object.defineProperty(o, "default", { enumerable: true, value: v });
15}) : function(o, v) {
16 o["default"] = v;
17});
18var __importStar = (this && this.__importStar) || (function () {
19 var ownKeys = function(o) {
20 ownKeys = Object.getOwnPropertyNames || function (o) {
21 var ar = [];
22 for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23 return ar;
24 };
25 return ownKeys(o);
26 };
27 return function (mod) {
28 if (mod && mod.__esModule) return mod;
29 var result = {};
30 if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31 __setModuleDefault(result, mod);
32 return result;
33 };
34})();
35var __importDefault = (this && this.__importDefault) || function (mod) {
36 return (mod && mod.__esModule) ? mod : { "default": mod };
37};
38Object.defineProperty(exports, "__esModule", { value: true });
39exports.WriteEntryTar = exports.WriteEntrySync = exports.WriteEntry = void 0;
40const fs_1 = __importDefault(require("fs"));
41const minipass_1 = require("minipass");
42const path_1 = __importDefault(require("path"));
43const header_js_1 = require("./header.js");
44const mode_fix_js_1 = require("./mode-fix.js");
45const normalize_windows_path_js_1 = require("./normalize-windows-path.js");
46const options_js_1 = require("./options.js");
47const pax_js_1 = require("./pax.js");
48const strip_absolute_path_js_1 = require("./strip-absolute-path.js");
49const strip_trailing_slashes_js_1 = require("./strip-trailing-slashes.js");
50const warn_method_js_1 = require("./warn-method.js");
51const winchars = __importStar(require("./winchars.js"));
52const prefixPath = (path, prefix) => {
53 if (!prefix) {
54 return (0, normalize_windows_path_js_1.normalizeWindowsPath)(path);
55 }
56 path = (0, normalize_windows_path_js_1.normalizeWindowsPath)(path).replace(/^\.(\/|$)/, '');
57 return (0, strip_trailing_slashes_js_1.stripTrailingSlashes)(prefix) + '/' + path;
58};
59const maxReadSize = 16 * 1024 * 1024;
60const PROCESS = Symbol('process');
61const FILE = Symbol('file');
62const DIRECTORY = Symbol('directory');
63const SYMLINK = Symbol('symlink');
64const HARDLINK = Symbol('hardlink');
65const HEADER = Symbol('header');
66const READ = Symbol('read');
67const LSTAT = Symbol('lstat');
68const ONLSTAT = Symbol('onlstat');
69const ONREAD = Symbol('onread');
70const ONREADLINK = Symbol('onreadlink');
71const OPENFILE = Symbol('openfile');
72const ONOPENFILE = Symbol('onopenfile');
73const CLOSE = Symbol('close');
74const MODE = Symbol('mode');
75const AWAITDRAIN = Symbol('awaitDrain');
76const ONDRAIN = Symbol('ondrain');
77const PREFIX = Symbol('prefix');
78class WriteEntry extends minipass_1.Minipass {
79 path;
80 portable;
81 myuid = (process.getuid && process.getuid()) || 0;
82 // until node has builtin pwnam functions, this'll have to do
83 myuser = process.env.USER || '';
84 maxReadSize;
85 linkCache;
86 statCache;
87 preservePaths;
88 cwd;
89 strict;
90 mtime;
91 noPax;
92 noMtime;
93 prefix;
94 fd;
95 blockLen = 0;
96 blockRemain = 0;
97 buf;
98 pos = 0;
99 remain = 0;
100 length = 0;
101 offset = 0;
102 win32;
103 absolute;
104 header;
105 type;
106 linkpath;
107 stat;
108 onWriteEntry;
109 #hadError = false;
110 constructor(p, opt_ = {}) {
111 const opt = (0, options_js_1.dealias)(opt_);
112 super();
113 this.path = (0, normalize_windows_path_js_1.normalizeWindowsPath)(p);
114 // suppress atime, ctime, uid, gid, uname, gname
115 this.portable = !!opt.portable;
116 this.maxReadSize = opt.maxReadSize || maxReadSize;
117 this.linkCache = opt.linkCache || new Map();
118 this.statCache = opt.statCache || new Map();
119 this.preservePaths = !!opt.preservePaths;
120 this.cwd = (0, normalize_windows_path_js_1.normalizeWindowsPath)(opt.cwd || process.cwd());
121 this.strict = !!opt.strict;
122 this.noPax = !!opt.noPax;
123 this.noMtime = !!opt.noMtime;
124 this.mtime = opt.mtime;
125 this.prefix =
126 opt.prefix ? (0, normalize_windows_path_js_1.normalizeWindowsPath)(opt.prefix) : undefined;
127 this.onWriteEntry = opt.onWriteEntry;
128 if (typeof opt.onwarn === 'function') {
129 this.on('warn', opt.onwarn);
130 }
131 let pathWarn = false;
132 if (!this.preservePaths) {
133 const [root, stripped] = (0, strip_absolute_path_js_1.stripAbsolutePath)(this.path);
134 if (root && typeof stripped === 'string') {
135 this.path = stripped;
136 pathWarn = root;
137 }
138 }
139 this.win32 = !!opt.win32 || process.platform === 'win32';
140 if (this.win32) {
141 // force the \ to / normalization, since we might not *actually*
142 // be on windows, but want \ to be considered a path separator.
143 this.path = winchars.decode(this.path.replace(/\\/g, '/'));
144 p = p.replace(/\\/g, '/');
145 }
146 this.absolute = (0, normalize_windows_path_js_1.normalizeWindowsPath)(opt.absolute || path_1.default.resolve(this.cwd, p));
147 if (this.path === '') {
148 this.path = './';
149 }
150 if (pathWarn) {
151 this.warn('TAR_ENTRY_INFO', `stripping ${pathWarn} from absolute path`, {
152 entry: this,
153 path: pathWarn + this.path,
154 });
155 }
156 const cs = this.statCache.get(this.absolute);
157 if (cs) {
158 this[ONLSTAT](cs);
159 }
160 else {
161 this[LSTAT]();
162 }
163 }
164 warn(code, message, data = {}) {
165 return (0, warn_method_js_1.warnMethod)(this, code, message, data);
166 }
167 emit(ev, ...data) {
168 if (ev === 'error') {
169 this.#hadError = true;
170 }
171 return super.emit(ev, ...data);
172 }
173 [LSTAT]() {
174 fs_1.default.lstat(this.absolute, (er, stat) => {
175 if (er) {
176 return this.emit('error', er);
177 }
178 this[ONLSTAT](stat);
179 });
180 }
181 [ONLSTAT](stat) {
182 this.statCache.set(this.absolute, stat);
183 this.stat = stat;
184 if (!stat.isFile()) {
185 stat.size = 0;
186 }
187 this.type = getType(stat);
188 this.emit('stat', stat);
189 this[PROCESS]();
190 }
191 [PROCESS]() {
192 switch (this.type) {
193 case 'File':
194 return this[FILE]();
195 case 'Directory':
196 return this[DIRECTORY]();
197 case 'SymbolicLink':
198 return this[SYMLINK]();
199 // unsupported types are ignored.
200 default:
201 return this.end();
202 }
203 }
204 [MODE](mode) {
205 return (0, mode_fix_js_1.modeFix)(mode, this.type === 'Directory', this.portable);
206 }
207 [PREFIX](path) {
208 return prefixPath(path, this.prefix);
209 }
210 [HEADER]() {
211 /* c8 ignore start */
212 if (!this.stat) {
213 throw new Error('cannot write header before stat');
214 }
215 /* c8 ignore stop */
216 if (this.type === 'Directory' && this.portable) {
217 this.noMtime = true;
218 }
219 this.onWriteEntry?.(this);
220 this.header = new header_js_1.Header({
221 path: this[PREFIX](this.path),
222 // only apply the prefix to hard links.
223 linkpath: this.type === 'Link' && this.linkpath !== undefined ?
224 this[PREFIX](this.linkpath)
225 : this.linkpath,
226 // only the permissions and setuid/setgid/sticky bitflags
227 // not the higher-order bits that specify file type
228 mode: this[MODE](this.stat.mode),
229 uid: this.portable ? undefined : this.stat.uid,
230 gid: this.portable ? undefined : this.stat.gid,
231 size: this.stat.size,
232 mtime: this.noMtime ? undefined : this.mtime || this.stat.mtime,
233 /* c8 ignore next */
234 type: this.type === 'Unsupported' ? undefined : this.type,
235 uname: this.portable ? undefined
236 : this.stat.uid === this.myuid ? this.myuser
237 : '',
238 atime: this.portable ? undefined : this.stat.atime,
239 ctime: this.portable ? undefined : this.stat.ctime,
240 });
241 if (this.header.encode() && !this.noPax) {
242 super.write(new pax_js_1.Pax({
243 atime: this.portable ? undefined : this.header.atime,
244 ctime: this.portable ? undefined : this.header.ctime,
245 gid: this.portable ? undefined : this.header.gid,
246 mtime: this.noMtime ? undefined : (this.mtime || this.header.mtime),
247 path: this[PREFIX](this.path),
248 linkpath: this.type === 'Link' && this.linkpath !== undefined ?
249 this[PREFIX](this.linkpath)
250 : this.linkpath,
251 size: this.header.size,
252 uid: this.portable ? undefined : this.header.uid,
253 uname: this.portable ? undefined : this.header.uname,
254 dev: this.portable ? undefined : this.stat.dev,
255 ino: this.portable ? undefined : this.stat.ino,
256 nlink: this.portable ? undefined : this.stat.nlink,
257 }).encode());
258 }
259 const block = this.header?.block;
260 /* c8 ignore start */
261 if (!block) {
262 throw new Error('failed to encode header');
263 }
264 /* c8 ignore stop */
265 super.write(block);
266 }
267 [DIRECTORY]() {
268 /* c8 ignore start */
269 if (!this.stat) {
270 throw new Error('cannot create directory entry without stat');
271 }
272 /* c8 ignore stop */
273 if (this.path.slice(-1) !== '/') {
274 this.path += '/';
275 }
276 this.stat.size = 0;
277 this[HEADER]();
278 this.end();
279 }
280 [SYMLINK]() {
281 fs_1.default.readlink(this.absolute, (er, linkpath) => {
282 if (er) {
283 return this.emit('error', er);
284 }
285 this[ONREADLINK](linkpath);
286 });
287 }
288 [ONREADLINK](linkpath) {
289 this.linkpath = (0, normalize_windows_path_js_1.normalizeWindowsPath)(linkpath);
290 this[HEADER]();
291 this.end();
292 }
293 [HARDLINK](linkpath) {
294 /* c8 ignore start */
295 if (!this.stat) {
296 throw new Error('cannot create link entry without stat');
297 }
298 /* c8 ignore stop */
299 this.type = 'Link';
300 this.linkpath = (0, normalize_windows_path_js_1.normalizeWindowsPath)(path_1.default.relative(this.cwd, linkpath));
301 this.stat.size = 0;
302 this[HEADER]();
303 this.end();
304 }
305 [FILE]() {
306 /* c8 ignore start */
307 if (!this.stat) {
308 throw new Error('cannot create file entry without stat');
309 }
310 /* c8 ignore stop */
311 if (this.stat.nlink > 1) {
312 const linkKey = `${this.stat.dev}:${this.stat.ino}`;
313 const linkpath = this.linkCache.get(linkKey);
314 if (linkpath?.indexOf(this.cwd) === 0) {
315 return this[HARDLINK](linkpath);
316 }
317 this.linkCache.set(linkKey, this.absolute);
318 }
319 this[HEADER]();
320 if (this.stat.size === 0) {
321 return this.end();
322 }
323 this[OPENFILE]();
324 }
325 [OPENFILE]() {
326 fs_1.default.open(this.absolute, 'r', (er, fd) => {
327 if (er) {
328 return this.emit('error', er);
329 }
330 this[ONOPENFILE](fd);
331 });
332 }
333 [ONOPENFILE](fd) {
334 this.fd = fd;
335 if (this.#hadError) {
336 return this[CLOSE]();
337 }
338 /* c8 ignore start */
339 if (!this.stat) {
340 throw new Error('should stat before calling onopenfile');
341 }
342 /* c8 ignore start */
343 this.blockLen = 512 * Math.ceil(this.stat.size / 512);
344 this.blockRemain = this.blockLen;
345 const bufLen = Math.min(this.blockLen, this.maxReadSize);
346 this.buf = Buffer.allocUnsafe(bufLen);
347 this.offset = 0;
348 this.pos = 0;
349 this.remain = this.stat.size;
350 this.length = this.buf.length;
351 this[READ]();
352 }
353 [READ]() {
354 const { fd, buf, offset, length, pos } = this;
355 if (fd === undefined || buf === undefined) {
356 throw new Error('cannot read file without first opening');
357 }
358 fs_1.default.read(fd, buf, offset, length, pos, (er, bytesRead) => {
359 if (er) {
360 // ignoring the error from close(2) is a bad practice, but at
361 // this point we already have an error, don't need another one
362 return this[CLOSE](() => this.emit('error', er));
363 }
364 this[ONREAD](bytesRead);
365 });
366 }
367 /* c8 ignore start */
368 [CLOSE](cb = () => { }) {
369 /* c8 ignore stop */
370 if (this.fd !== undefined)
371 fs_1.default.close(this.fd, cb);
372 }
373 [ONREAD](bytesRead) {
374 if (bytesRead <= 0 && this.remain > 0) {
375 const er = Object.assign(new Error('encountered unexpected EOF'), {
376 path: this.absolute,
377 syscall: 'read',
378 code: 'EOF',
379 });
380 return this[CLOSE](() => this.emit('error', er));
381 }
382 if (bytesRead > this.remain) {
383 const er = Object.assign(new Error('did not encounter expected EOF'), {
384 path: this.absolute,
385 syscall: 'read',
386 code: 'EOF',
387 });
388 return this[CLOSE](() => this.emit('error', er));
389 }
390 /* c8 ignore start */
391 if (!this.buf) {
392 throw new Error('should have created buffer prior to reading');
393 }
394 /* c8 ignore stop */
395 // null out the rest of the buffer, if we could fit the block padding
396 // at the end of this loop, we've incremented bytesRead and this.remain
397 // to be incremented up to the blockRemain level, as if we had expected
398 // to get a null-padded file, and read it until the end. then we will
399 // decrement both remain and blockRemain by bytesRead, and know that we
400 // reached the expected EOF, without any null buffer to append.
401 if (bytesRead === this.remain) {
402 for (let i = bytesRead; i < this.length && bytesRead < this.blockRemain; i++) {
403 this.buf[i + this.offset] = 0;
404 bytesRead++;
405 this.remain++;
406 }
407 }
408 const chunk = this.offset === 0 && bytesRead === this.buf.length ?
409 this.buf
410 : this.buf.subarray(this.offset, this.offset + bytesRead);
411 const flushed = this.write(chunk);
412 if (!flushed) {
413 this[AWAITDRAIN](() => this[ONDRAIN]());
414 }
415 else {
416 this[ONDRAIN]();
417 }
418 }
419 [AWAITDRAIN](cb) {
420 this.once('drain', cb);
421 }
422 write(chunk, encoding, cb) {
423 /* c8 ignore start - just junk to comply with NodeJS.WritableStream */
424 if (typeof encoding === 'function') {
425 cb = encoding;
426 encoding = undefined;
427 }
428 if (typeof chunk === 'string') {
429 chunk = Buffer.from(chunk, typeof encoding === 'string' ? encoding : 'utf8');
430 }
431 /* c8 ignore stop */
432 if (this.blockRemain < chunk.length) {
433 const er = Object.assign(new Error('writing more data than expected'), {
434 path: this.absolute,
435 });
436 return this.emit('error', er);
437 }
438 this.remain -= chunk.length;
439 this.blockRemain -= chunk.length;
440 this.pos += chunk.length;
441 this.offset += chunk.length;
442 return super.write(chunk, null, cb);
443 }
444 [ONDRAIN]() {
445 if (!this.remain) {
446 if (this.blockRemain) {
447 super.write(Buffer.alloc(this.blockRemain));
448 }
449 return this[CLOSE](er => er ? this.emit('error', er) : this.end());
450 }
451 /* c8 ignore start */
452 if (!this.buf) {
453 throw new Error('buffer lost somehow in ONDRAIN');
454 }
455 /* c8 ignore stop */
456 if (this.offset >= this.length) {
457 // if we only have a smaller bit left to read, alloc a smaller buffer
458 // otherwise, keep it the same length it was before.
459 this.buf = Buffer.allocUnsafe(Math.min(this.blockRemain, this.buf.length));
460 this.offset = 0;
461 }
462 this.length = this.buf.length - this.offset;
463 this[READ]();
464 }
465}
466exports.WriteEntry = WriteEntry;
467class WriteEntrySync extends WriteEntry {
468 sync = true;
469 [LSTAT]() {
470 this[ONLSTAT](fs_1.default.lstatSync(this.absolute));
471 }
472 [SYMLINK]() {
473 this[ONREADLINK](fs_1.default.readlinkSync(this.absolute));
474 }
475 [OPENFILE]() {
476 this[ONOPENFILE](fs_1.default.openSync(this.absolute, 'r'));
477 }
478 [READ]() {
479 let threw = true;
480 try {
481 const { fd, buf, offset, length, pos } = this;
482 /* c8 ignore start */
483 if (fd === undefined || buf === undefined) {
484 throw new Error('fd and buf must be set in READ method');
485 }
486 /* c8 ignore stop */
487 const bytesRead = fs_1.default.readSync(fd, buf, offset, length, pos);
488 this[ONREAD](bytesRead);
489 threw = false;
490 }
491 finally {
492 // ignoring the error from close(2) is a bad practice, but at
493 // this point we already have an error, don't need another one
494 if (threw) {
495 try {
496 this[CLOSE](() => { });
497 }
498 catch (er) { }
499 }
500 }
501 }
502 [AWAITDRAIN](cb) {
503 cb();
504 }
505 /* c8 ignore start */
506 [CLOSE](cb = () => { }) {
507 /* c8 ignore stop */
508 if (this.fd !== undefined)
509 fs_1.default.closeSync(this.fd);
510 cb();
511 }
512}
513exports.WriteEntrySync = WriteEntrySync;
514class WriteEntryTar extends minipass_1.Minipass {
515 blockLen = 0;
516 blockRemain = 0;
517 buf = 0;
518 pos = 0;
519 remain = 0;
520 length = 0;
521 preservePaths;
522 portable;
523 strict;
524 noPax;
525 noMtime;
526 readEntry;
527 type;
528 prefix;
529 path;
530 mode;
531 uid;
532 gid;
533 uname;
534 gname;
535 header;
536 mtime;
537 atime;
538 ctime;
539 linkpath;
540 size;
541 onWriteEntry;
542 warn(code, message, data = {}) {
543 return (0, warn_method_js_1.warnMethod)(this, code, message, data);
544 }
545 constructor(readEntry, opt_ = {}) {
546 const opt = (0, options_js_1.dealias)(opt_);
547 super();
548 this.preservePaths = !!opt.preservePaths;
549 this.portable = !!opt.portable;
550 this.strict = !!opt.strict;
551 this.noPax = !!opt.noPax;
552 this.noMtime = !!opt.noMtime;
553 this.onWriteEntry = opt.onWriteEntry;
554 this.readEntry = readEntry;
555 const { type } = readEntry;
556 /* c8 ignore start */
557 if (type === 'Unsupported') {
558 throw new Error('writing entry that should be ignored');
559 }
560 /* c8 ignore stop */
561 this.type = type;
562 if (this.type === 'Directory' && this.portable) {
563 this.noMtime = true;
564 }
565 this.prefix = opt.prefix;
566 this.path = (0, normalize_windows_path_js_1.normalizeWindowsPath)(readEntry.path);
567 this.mode =
568 readEntry.mode !== undefined ?
569 this[MODE](readEntry.mode)
570 : undefined;
571 this.uid = this.portable ? undefined : readEntry.uid;
572 this.gid = this.portable ? undefined : readEntry.gid;
573 this.uname = this.portable ? undefined : readEntry.uname;
574 this.gname = this.portable ? undefined : readEntry.gname;
575 this.size = readEntry.size;
576 this.mtime =
577 this.noMtime ? undefined : opt.mtime || readEntry.mtime;
578 this.atime = this.portable ? undefined : readEntry.atime;
579 this.ctime = this.portable ? undefined : readEntry.ctime;
580 this.linkpath =
581 readEntry.linkpath !== undefined ?
582 (0, normalize_windows_path_js_1.normalizeWindowsPath)(readEntry.linkpath)
583 : undefined;
584 if (typeof opt.onwarn === 'function') {
585 this.on('warn', opt.onwarn);
586 }
587 let pathWarn = false;
588 if (!this.preservePaths) {
589 const [root, stripped] = (0, strip_absolute_path_js_1.stripAbsolutePath)(this.path);
590 if (root && typeof stripped === 'string') {
591 this.path = stripped;
592 pathWarn = root;
593 }
594 }
595 this.remain = readEntry.size;
596 this.blockRemain = readEntry.startBlockSize;
597 this.onWriteEntry?.(this);
598 this.header = new header_js_1.Header({
599 path: this[PREFIX](this.path),
600 linkpath: this.type === 'Link' && this.linkpath !== undefined ?
601 this[PREFIX](this.linkpath)
602 : this.linkpath,
603 // only the permissions and setuid/setgid/sticky bitflags
604 // not the higher-order bits that specify file type
605 mode: this.mode,
606 uid: this.portable ? undefined : this.uid,
607 gid: this.portable ? undefined : this.gid,
608 size: this.size,
609 mtime: this.noMtime ? undefined : this.mtime,
610 type: this.type,
611 uname: this.portable ? undefined : this.uname,
612 atime: this.portable ? undefined : this.atime,
613 ctime: this.portable ? undefined : this.ctime,
614 });
615 if (pathWarn) {
616 this.warn('TAR_ENTRY_INFO', `stripping ${pathWarn} from absolute path`, {
617 entry: this,
618 path: pathWarn + this.path,
619 });
620 }
621 if (this.header.encode() && !this.noPax) {
622 super.write(new pax_js_1.Pax({
623 atime: this.portable ? undefined : this.atime,
624 ctime: this.portable ? undefined : this.ctime,
625 gid: this.portable ? undefined : this.gid,
626 mtime: this.noMtime ? undefined : this.mtime,
627 path: this[PREFIX](this.path),
628 linkpath: this.type === 'Link' && this.linkpath !== undefined ?
629 this[PREFIX](this.linkpath)
630 : this.linkpath,
631 size: this.size,
632 uid: this.portable ? undefined : this.uid,
633 uname: this.portable ? undefined : this.uname,
634 dev: this.portable ? undefined : this.readEntry.dev,
635 ino: this.portable ? undefined : this.readEntry.ino,
636 nlink: this.portable ? undefined : this.readEntry.nlink,
637 }).encode());
638 }
639 const b = this.header?.block;
640 /* c8 ignore start */
641 if (!b)
642 throw new Error('failed to encode header');
643 /* c8 ignore stop */
644 super.write(b);
645 readEntry.pipe(this);
646 }
647 [PREFIX](path) {
648 return prefixPath(path, this.prefix);
649 }
650 [MODE](mode) {
651 return (0, mode_fix_js_1.modeFix)(mode, this.type === 'Directory', this.portable);
652 }
653 write(chunk, encoding, cb) {
654 /* c8 ignore start - just junk to comply with NodeJS.WritableStream */
655 if (typeof encoding === 'function') {
656 cb = encoding;
657 encoding = undefined;
658 }
659 if (typeof chunk === 'string') {
660 chunk = Buffer.from(chunk, typeof encoding === 'string' ? encoding : 'utf8');
661 }
662 /* c8 ignore stop */
663 const writeLen = chunk.length;
664 if (writeLen > this.blockRemain) {
665 throw new Error('writing more to entry than is appropriate');
666 }
667 this.blockRemain -= writeLen;
668 return super.write(chunk, cb);
669 }
670 end(chunk, encoding, cb) {
671 if (this.blockRemain) {
672 super.write(Buffer.alloc(this.blockRemain));
673 }
674 /* c8 ignore start - just junk to comply with NodeJS.WritableStream */
675 if (typeof chunk === 'function') {
676 cb = chunk;
677 encoding = undefined;
678 chunk = undefined;
679 }
680 if (typeof encoding === 'function') {
681 cb = encoding;
682 encoding = undefined;
683 }
684 if (typeof chunk === 'string') {
685 chunk = Buffer.from(chunk, encoding ?? 'utf8');
686 }
687 if (cb)
688 this.once('finish', cb);
689 chunk ? super.end(chunk, cb) : super.end(cb);
690 /* c8 ignore stop */
691 return this;
692 }
693}
694exports.WriteEntryTar = WriteEntryTar;
695const getType = (stat) => stat.isFile() ? 'File'
696 : stat.isDirectory() ? 'Directory'
697 : stat.isSymbolicLink() ? 'SymbolicLink'
698 : 'Unsupported';
699//# sourceMappingURL=write-entry.js.map