file_stream.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. 'use strict';
  2. const path = require('path');
  3. const yazl = require('yazl');
  4. const assert = require('assert');
  5. const stream = require('stream');
  6. const utils = require('../utils');
  7. const ready = require('get-ready');
  8. class ZipFileStream extends stream.Transform {
  9. constructor(opts) {
  10. super(opts);
  11. const sourceType = utils.sourceType(opts.source);
  12. const zipfile = new yazl.ZipFile();
  13. const zipStream = zipfile.outputStream;
  14. zipStream.on('data', data => this.push(data));
  15. zipStream.on('end', () => this.ready(true));
  16. zipfile.on('error', err => this.emit('error', err));
  17. if (sourceType !== 'file') {
  18. assert(opts.relativePath, 'opts.relativePath is required when compressing a buffer, or a stream');
  19. }
  20. if (sourceType) {
  21. this.end();
  22. }
  23. if (sourceType === 'file') {
  24. zipfile.addFile(opts.source, opts.relativePath || path.basename(opts.source), opts.yazl);
  25. } else if (sourceType === 'buffer') {
  26. zipfile.addBuffer(opts.source, opts.relativePath, opts.yazl);
  27. } else if (sourceType === 'stream') {
  28. zipfile.addReadStream(opts.source, opts.relativePath, opts.yazl);
  29. } else { // undefined
  30. const passThrough = this._passThrough = new stream.PassThrough();
  31. this.on('finish', () => passThrough.end());
  32. zipfile.addReadStream(passThrough, opts.relativePath, opts.yazl);
  33. }
  34. zipfile.end(opts.yazl);
  35. }
  36. _transform(chunk, encoding, callback) {
  37. if (this._passThrough) {
  38. this._passThrough.write(chunk, encoding, callback);
  39. }
  40. }
  41. _flush(callback) {
  42. this.ready(callback);
  43. }
  44. }
  45. ready.mixin(ZipFileStream.prototype);
  46. module.exports = ZipFileStream;