3f2d66fd2ecef58349e3116ba988bc8b3eb78ba618980703922e7970dbebb3e4b8602e18d7a8fac68c4ffa77451aab9e384588bead5b709d8f880446cee264 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // tar -t
  2. import * as fsm from '@isaacs/fs-minipass';
  3. import fs from 'node:fs';
  4. import { dirname, parse } from 'path';
  5. import { makeCommand } from './make-command.js';
  6. import { Parser } from './parse.js';
  7. import { stripTrailingSlashes } from './strip-trailing-slashes.js';
  8. const onReadEntryFunction = (opt) => {
  9. const onReadEntry = opt.onReadEntry;
  10. opt.onReadEntry =
  11. onReadEntry ?
  12. e => {
  13. onReadEntry(e);
  14. e.resume();
  15. }
  16. : e => e.resume();
  17. };
  18. // construct a filter that limits the file entries listed
  19. // include child entries if a dir is included
  20. export const filesFilter = (opt, files) => {
  21. const map = new Map(files.map(f => [stripTrailingSlashes(f), true]));
  22. const filter = opt.filter;
  23. const mapHas = (file, r = '') => {
  24. const root = r || parse(file).root || '.';
  25. let ret;
  26. if (file === root)
  27. ret = false;
  28. else {
  29. const m = map.get(file);
  30. if (m !== undefined) {
  31. ret = m;
  32. }
  33. else {
  34. ret = mapHas(dirname(file), root);
  35. }
  36. }
  37. map.set(file, ret);
  38. return ret;
  39. };
  40. opt.filter =
  41. filter ?
  42. (file, entry) => filter(file, entry) && mapHas(stripTrailingSlashes(file))
  43. : file => mapHas(stripTrailingSlashes(file));
  44. };
  45. const listFileSync = (opt) => {
  46. const p = new Parser(opt);
  47. const file = opt.file;
  48. let fd;
  49. try {
  50. const stat = fs.statSync(file);
  51. const readSize = opt.maxReadSize || 16 * 1024 * 1024;
  52. if (stat.size < readSize) {
  53. p.end(fs.readFileSync(file));
  54. }
  55. else {
  56. let pos = 0;
  57. const buf = Buffer.allocUnsafe(readSize);
  58. fd = fs.openSync(file, 'r');
  59. while (pos < stat.size) {
  60. const bytesRead = fs.readSync(fd, buf, 0, readSize, pos);
  61. pos += bytesRead;
  62. p.write(buf.subarray(0, bytesRead));
  63. }
  64. p.end();
  65. }
  66. }
  67. finally {
  68. if (typeof fd === 'number') {
  69. try {
  70. fs.closeSync(fd);
  71. /* c8 ignore next */
  72. }
  73. catch (er) { }
  74. }
  75. }
  76. };
  77. const listFile = (opt, _files) => {
  78. const parse = new Parser(opt);
  79. const readSize = opt.maxReadSize || 16 * 1024 * 1024;
  80. const file = opt.file;
  81. const p = new Promise((resolve, reject) => {
  82. parse.on('error', reject);
  83. parse.on('end', resolve);
  84. fs.stat(file, (er, stat) => {
  85. if (er) {
  86. reject(er);
  87. }
  88. else {
  89. const stream = new fsm.ReadStream(file, {
  90. readSize: readSize,
  91. size: stat.size,
  92. });
  93. stream.on('error', reject);
  94. stream.pipe(parse);
  95. }
  96. });
  97. });
  98. return p;
  99. };
  100. export const list = makeCommand(listFileSync, listFile, opt => new Parser(opt), opt => new Parser(opt), (opt, files) => {
  101. if (files?.length)
  102. filesFilter(opt, files);
  103. if (!opt.noResume)
  104. onReadEntryFunction(opt);
  105. });
  106. //# sourceMappingURL=list.js.map