UNPKG

zip-saver

Version:

<h1 align="center"> Easy way to merge multiple files into one zip file in <code>javascript</code> </h1>

2 lines (1 loc) 5.26 kB
"use strict";function e(e,t,i,n){return new(i||(i=Promise))((function(r,s){function o(e){try{l(n.next(e))}catch(e){s(e)}}function a(e){try{l(n.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?r(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(o,a)}l((n=n.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class t{constructor(e){this.bufferArray=new Uint8Array(e),this.dataView=new DataView(this.bufferArray.buffer)}getBuffer(){return this.bufferArray.buffer}getUint8(){return this.bufferArray}setUint16(e,t){this.dataView.setUint16(e,t,!0)}setUint32(e,t){this.dataView.setUint32(e,t,!0)}setUint8(e,t){this.dataView.setUint8(e,t)}setBuffer(e,t){this.bufferArray.set(t,e)}}class i{static generateHeader(e){const i=new TextEncoder,n=e.reduce(((e,t)=>e+46+i.encode(t.name).length+i.encode(t.comment).length),0),r=e.reduce(((e,t)=>e+t.getOffset()),0),s=new t(n+22);for(let t=0,n=0,r=0;t<e.length;t++){const o=e[t];s.setUint32(n,33639248),s.setUint16(n+4,20),s.setBuffer(n+6,o.localFileHeader.getUint8().slice(4,30));const a=i.encode(o.comment);s.setUint16(n+32,a.length),s.setUint32(n+42,r);const l=i.encode(o.name);s.setBuffer(n+46,l),s.setBuffer(n+46+l.length,a),n+=46+a.length+l.length,r+=o.getOffset()}const o=n;return s.setUint32(o,101010256),s.setUint16(o+4,0),s.setUint16(o+6,0),s.setUint16(o+8,e.length),s.setUint16(o+10,e.length),s.setUint32(o+12,n),s.setUint32(o+16,r),s.getUint8()}}class n{constructor(){this.crc=4294967295}append(e){let t=0|this.crc;const i=n.table;for(let n=0;n<e.length;n++)t=t>>>8^i[255&(t^e[n])];this.crc=t}get value(){return~this.crc}}n.table=(()=>{const e=new Array(256);for(let t=0;t<256;t++){let i=t;for(let e=0;e<8;e++)i=1&i?i>>>1^3988292384:i>>>1;e[t]=i}return e})();class r{getOffset(){if(!this.closed)throw new Error("this file is not ready");return this.offset}constructor(e){this.crc=new n,this.fileData=new Uint8Array,this.offset=0,this.closed=!1,this.name=e.name.trim(),this.level=e.compressionMethod||0,this.isDir=e.isDir||!1,this.comment=e.comment||"",this.compressedLength=e.compressedLength||0,this.uncompressedLength=e.uncompressedLength||0,this.originBlob=e.originBlob,this.lastModified=e.lastModified||Date.now(),this.localFileHeader=this.generateHeader()}generateHeader(){const e=(new TextEncoder).encode(this.name),i=new t(30+e.length);i.setUint32(0,67324752),i.setUint16(4,20),i.setUint16(6,2056),i.setUint16(8,0);const n=new Date(this.lastModified||Date.now());return i.setUint16(10,n.getUTCHours()<<11|n.getUTCMinutes()<<5|n.getUTCSeconds()/2),i.setUint16(12,n.getUTCDate()|n.getUTCMonth()+1<<5|n.getUTCFullYear()-1980<<9),i.setUint16(26,e.length),i.setBuffer(30,e),this.localFileHeader=i,this.offset=30+e.length,i}getCompressedData(e){return e}append(e){const t=this.getCompressedData(e);this.crc.append(e),this.offset+=t.length,this.compressedLength+=t.length,this.uncompressedLength+=e.length,this.fileData=new Uint8Array([...this.fileData,...t])}generateDataDescriptor(){const e=new t(16);e.setUint32(0,134695760),this.localFileHeader.setUint32(14,this.crc.value),this.localFileHeader.setUint32(18,this.compressedLength),this.localFileHeader.setUint32(22,this.uncompressedLength),e.setUint32(4,this.crc.value),e.setUint32(8,this.compressedLength),e.setUint32(12,this.uncompressedLength),this.dataDescriptor=e,this.offset+=16}finish(){if(this.closed)throw new Error("this file is already closed");this.generateDataDescriptor(),this.closed=!0}factory(){return e(this,void 0,void 0,(function*(){if(this.closed)throw new Error("this file is already closed");if(!this.originBlob)throw new Error("this file is empty");return this.append(new Uint8Array(yield this.originBlob.arrayBuffer())),this.finish(),this}))}closeStream(){if(this.closed)throw new Error("this file is already closed");return this.finish(),this.dataDescriptor}getUint8(){if(!this.closed||!this.dataDescriptor)throw new Error("this file is not ready");return new Uint8Array([...this.localFileHeader.getUint8(),...this.fileData,...this.dataDescriptor.getUint8()])}}const s=e=>void 0!==e.blob;exports.createZip=function(t){return e(this,void 0,void 0,(function*(){const e=yield Promise.all(t.map((e=>new r({name:e.name,originBlob:s(e)?e.blob:e,lastModified:e.lastModified}).factory()))),n=i.generateHeader(e),o=e.map((e=>e.getUint8()));return new Blob([...o,n],{type:"application/zip"})}))},exports.createZipStream=function(){let e;const t=[];let n;return{readableStream:new ReadableStream({start(e){n=e}}),controller:n,createFile:function(t){if(e)throw new Error("a file is in progress");const i=new r({name:t.filename,lastModified:t.lastModified});if(e=i,!n)throw new Error("ReadableStream initialization failed");n.enqueue(i.localFileHeader.getUint8())},enqueue:function(t){if(!e)throw new Error("no file is in progress");if(e.append(t),!n)throw new Error("ReadableStream initialization failed");n.enqueue(t)},closeFile:function(){if(!e)throw new Error("no file is in progress");const i=e.closeStream();if(!n)throw new Error("ReadableStream initialization failed");n.enqueue(i.getUint8()),t.push(e),e=void 0},closeZip:function(){if(e)throw new Error("a file is in progress");const r=i.generateHeader(t);if(!n)throw new Error("ReadableStream initialization failed");n.enqueue(r),n.close()}}};