| 18 | import type { Entry, ZipFile as UnzipFile } from 'yauzl'; |
| 19 | |
| 20 | export class ZipFile { |
| 21 | private _fileName: string; |
| 22 | private _zipFile: UnzipFile | undefined; |
| 23 | private _entries = new Map<string, Entry>(); |
| 24 | private _openedPromise: Promise<void>; |
| 25 | |
| 26 | constructor(fileName: string) { |
| 27 | this._fileName = fileName; |
| 28 | this._openedPromise = this._open(); |
| 29 | } |
| 30 | |
| 31 | private async _open() { |
| 32 | await new Promise<UnzipFile>((fulfill, reject) => { |
| 33 | yauzl.open(this._fileName, { autoClose: false }, (e, z) => { |
| 34 | if (e) { |
| 35 | reject(e); |
| 36 | return; |
| 37 | } |
| 38 | this._zipFile = z; |
| 39 | this._zipFile!.on('entry', (entry: Entry) => { |
| 40 | this._entries.set(entry.fileName, entry); |
| 41 | }); |
| 42 | this._zipFile!.on('end', fulfill); |
| 43 | }); |
| 44 | }); |
| 45 | } |
| 46 | |
| 47 | async entries(): Promise<string[]> { |
| 48 | await this._openedPromise; |
| 49 | return [...this._entries.keys()]; |
| 50 | } |
| 51 | |
| 52 | async read(entryPath: string): Promise<Buffer> { |
| 53 | await this._openedPromise; |
| 54 | const entry = this._entries.get(entryPath)!; |
| 55 | if (!entry) |
| 56 | throw new Error(`${entryPath} not found in file ${this._fileName}`); |
| 57 | |
| 58 | return new Promise((resolve, reject) => { |
| 59 | this._zipFile!.openReadStream(entry, (error, readStream) => { |
| 60 | if (error || !readStream) { |
| 61 | reject(error || 'Entry not found'); |
| 62 | return; |
| 63 | } |
| 64 | |
| 65 | const buffers: Buffer[] = []; |
| 66 | readStream.on('data', data => buffers.push(data)); |
| 67 | readStream.on('end', () => resolve(Buffer.concat(buffers))); |
| 68 | }); |
| 69 | }); |
| 70 | } |
| 71 | |
| 72 | close() { |
| 73 | this._zipFile?.close(); |
| 74 | } |
| 75 | } |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…