565a59855593ba0d101ea927456d8d490b97efb84a93b20b3371b6b77b07a087f11e37fab20ab2fe67181f74ed6df71ddc0de836d63fc3aaeec153cde7f25a 24 KB

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