@shockpkg/core
Version:
shockpkg core
175 lines (148 loc) • 3.97 kB
JavaScript
import _initializerDefineProperty from "@babel/runtime/helpers/initializerDefineProperty.js";
import _applyDecoratedDescriptor from "@babel/runtime/helpers/applyDecoratedDescriptor.js";
import _initializerWarningHelper from "@babel/runtime/helpers/initializerWarningHelper.js";
var _dec, _class, _descriptor, _temp;
/* eslint-disable max-classes-per-file */
// tslint:disable max-classes-per-file
import { promisify as utilPromisify } from 'util';
import yauzl from 'yauzl';
import { property } from "./decorators.mjs";
const yauzlOpen = yauzl.open.bind(yauzl);
const yauzlOpenP = utilPromisify(yauzlOpen);
const yauzlFromRAR = yauzl.fromRandomAccessReader.bind(yauzl);
const yauzlFromRARP = utilPromisify(yauzlFromRAR);
const openOpts = {
lazyEntries: true
};
/**
* Streamer Random Access Read wrapper class.
*
* @param streamer ZipStreamer function.
*/
class StreamerRAR extends yauzl.RandomAccessReader {
/**
* Streamer instance.
*/
constructor(streamer) {
super();
this.__streamer = void 0;
this.__streamer = streamer;
}
/**
* Read stream from range.
*
* @param start Range start.
* @param end Range end.
* @returns Readable stream.
*/
// eslint-disable-next-line @typescript-eslint/member-naming
_readStreamForRange(start, end) {
return this.__streamer(start, end);
}
}
/**
* Zip file reader class.
*/
export let Zip = (_dec = property(false), (_class = (_temp = class Zip extends Object {
/**
* The zipfile instance, generic type to avoid dependency.
*/
constructor() {
super();
_initializerDefineProperty(this, "_zipfile", _descriptor, this);
}
/**
* Open with a file.
*
* @param file File path.
*/
async openFile(file) {
this._zipfile = await yauzlOpenP(file, openOpts);
}
/**
* Open with a streamer.
*
* @param streamer Streamer function.
* @param totalSize Total size of file.
*/
async openStreamer(streamer, totalSize) {
const reader = new StreamerRAR(streamer);
this._zipfile = await yauzlFromRARP(reader, totalSize, openOpts);
}
/**
* Read zip file entries.
* To stop reading and close file, return false from itter.
*
* @param itter Callback function.
*/
async read(itter) {
const zipfile = this._zipfile;
if (!zipfile) {
throw new Error('Zip instance not opened');
}
this._zipfile = null;
await new Promise((resolve, reject) => {
let error = null;
const next = err => {
if (err) {
error = err;
zipfile.close();
return;
}
zipfile.readEntry();
};
zipfile.on('error', next);
zipfile.on('entry', async entry => {
const path = entry.fileName.replace(/\\/g, '/');
const dir = path.endsWith('/');
const {
crc32
} = entry;
const sizeC = entry.compressedSize;
const sizeD = entry.uncompressedSize;
const stream = async () => {
const open = zipfile.openReadStream.bind(zipfile);
const openP = utilPromisify(open);
const r = await openP(entry);
return r;
};
let done = false;
try {
done = await itter({
path,
dir,
crc32,
sizeC,
sizeD,
stream
});
} catch (err) {
next(err);
return;
}
if (done) {
zipfile.close();
} else {
next(null);
return;
}
});
zipfile.on('close', () => {
if (error) {
reject(error);
return;
}
resolve();
});
next(null);
});
}
}, _temp), (_descriptor = _applyDecoratedDescriptor(_class.prototype, "_zipfile", [_dec], {
configurable: true,
enumerable: true,
writable: true,
initializer: function () {
return null;
}
})), _class));
//# sourceMappingURL=zip.mjs.map