ZipStreamer.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*const fs = require('fs-extra');
  2. const path = require('path');
  3. const zipStream = require('zip-stream');*/
  4. const StreamUnzip = require('./node_stream_zip_changed');
  5. class ZipStreamer {
  6. constructor() {
  7. }
  8. //TODO: сделать рекурсивный обход директорий, пока только файлы
  9. //files = ['filename', 'dirname/']
  10. /* zip-stream 2.1.3 => 4.1.0 Актуализировать!
  11. pack(zipFile, files, options, entryCallback) {
  12. return new Promise((resolve, reject) => { (async() => {
  13. entryCallback = (entryCallback ? entryCallback : () => {});
  14. const zip = new zipStream(options);
  15. const outputStream = fs.createWriteStream(zipFile);
  16. outputStream.on('error', reject);
  17. outputStream.on('finish', async() => {
  18. let file = {path: zipFile};
  19. try {
  20. file.size = (await fs.stat(zipFile)).size;
  21. } catch (e) {
  22. reject(e);
  23. }
  24. resolve(file);
  25. });
  26. zip.on('error', reject);
  27. zip.pipe(outputStream);
  28. const zipAddEntry = (filename) => {
  29. return new Promise((resolve, reject) => {
  30. const basename = path.basename(filename);
  31. const source = fs.createReadStream(filename);
  32. zip.entry(source, {name: basename}, (err, entry) => {
  33. if (err) reject(err);
  34. resolve(entry);
  35. });
  36. });
  37. };
  38. for (const filename of files) {
  39. const entry = await zipAddEntry(filename);
  40. entryCallback({path: entry.name, size: entry.size, compressedSize: entry.csize});
  41. }
  42. zip.finish();
  43. })().catch(reject); });
  44. }
  45. */
  46. unpack(zipFile, outputDir, options, entryCallback) {
  47. return new Promise((resolve, reject) => {
  48. entryCallback = (entryCallback ? entryCallback : () => {});
  49. const {
  50. limitFileSize = 0,
  51. limitFileCount = 0,
  52. decodeEntryNameCallback = false,
  53. } = options;
  54. const unzip = new StreamUnzip({file: zipFile, skipEntryNameValidation: true});
  55. unzip.on('error', reject);
  56. let files = [];
  57. unzip.on('extract', (en) => {
  58. const entry = {path: en.name, size: en.size, compressedSize: en.compressedSize};
  59. entryCallback(entry);
  60. files.push(entry);
  61. });
  62. unzip.on('ready', () => {
  63. if (limitFileCount || limitFileSize || decodeEntryNameCallback) {
  64. const entries = Object.values(unzip.entries());
  65. if (limitFileCount && entries.length > limitFileCount) {
  66. reject(new Error('Слишком много файлов'));
  67. return;
  68. }
  69. for (const entry of entries) {
  70. if (limitFileSize && !entry.isDirectory && entry.size > limitFileSize) {
  71. reject(new Error('Файл слишком большой'));
  72. return;
  73. }
  74. if (decodeEntryNameCallback) {
  75. entry.name = (decodeEntryNameCallback(entry.nameRaw)).toString();
  76. }
  77. }
  78. }
  79. unzip.extract(null, outputDir, (err) => {
  80. if (err) {
  81. reject(err);
  82. return;
  83. }
  84. try {
  85. unzip.close();
  86. resolve(files);
  87. } catch (e) {
  88. reject(e);
  89. }
  90. });
  91. });
  92. });
  93. }
  94. }
  95. module.exports = ZipStreamer;