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