@@ -15,25 +15,17 @@
|
||||
*/
|
||||
|
||||
import archiver from 'archiver';
|
||||
import unzipper2, { Entry } from 'yauzl';
|
||||
import yauzl, { Entry } from 'yauzl';
|
||||
import fs from 'fs-extra';
|
||||
import platformPath from 'path';
|
||||
import { Readable } from 'stream';
|
||||
// import unzipper, { Entry } from 'unzipper';
|
||||
import {
|
||||
ReadTreeResponse,
|
||||
ReadTreeResponseDirOptions,
|
||||
ReadTreeResponseFile,
|
||||
} from '../types';
|
||||
import { streamToBuffer } from './util';
|
||||
|
||||
const streamToBuffer = async (stream: Readable): Promise<Buffer> => {
|
||||
const buffers: Buffer[] = [];
|
||||
return new Promise((resolve, reject) => {
|
||||
stream.on('data', (data: Buffer) => buffers.push(data));
|
||||
stream.on('error', reject);
|
||||
stream.on('end', () => resolve(Buffer.concat(buffers)));
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Wraps a zip archive stream into a tree response reader.
|
||||
*/
|
||||
@@ -144,7 +136,7 @@ export class ZipArchiveResponse implements ReadTreeResponse {
|
||||
callback: (entry: Entry, content: Readable) => Promise<void>,
|
||||
): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
unzipper2.open(zip, { lazyEntries: true }, (err, zipfile) => {
|
||||
yauzl.open(zip, { lazyEntries: true }, (err, zipfile) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
|
||||
@@ -18,36 +18,18 @@
|
||||
// containing any character except `/` one or more times, and ending with a `/`
|
||||
// e.g. Will match `dirA/` in `dirA/dirB/file.ext`
|
||||
const directoryNameRegex = /^[^\/]+\//;
|
||||
|
||||
import { Readable } from 'stream';
|
||||
// Removes the first segment of a forward-slash-separated path
|
||||
export function stripFirstDirectoryFromPath(path: string): string {
|
||||
return path.replace(directoryNameRegex, '');
|
||||
}
|
||||
|
||||
// Some corrupted ZIP files cause the zlib inflater to hang indefinitely.
|
||||
// This is a workaround to bail on stuck streams after 3 seconds.
|
||||
// Related: https://github.com/ZJONSSON/node-unzipper/issues/213
|
||||
export async function streamToTimeoutPromise<T>(
|
||||
stream: NodeJS.ReadableStream,
|
||||
options: {
|
||||
timeoutMs: number;
|
||||
eventName: string;
|
||||
getError: (data: T) => Error;
|
||||
},
|
||||
) {
|
||||
let lastEntryTimeout: NodeJS.Timeout | undefined;
|
||||
stream.on(options.eventName, (data: T) => {
|
||||
clearTimeout(lastEntryTimeout);
|
||||
|
||||
lastEntryTimeout = setTimeout(() => {
|
||||
stream.emit('error', options.getError(data));
|
||||
}, options.timeoutMs);
|
||||
});
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
stream.on('finish', resolve);
|
||||
// Concats the data into a buffer.
|
||||
export const streamToBuffer = async (stream: Readable): Promise<Buffer> => {
|
||||
const buffers: Buffer[] = [];
|
||||
return new Promise((resolve, reject) => {
|
||||
stream.on('data', (data: Buffer) => buffers.push(data));
|
||||
stream.on('error', reject);
|
||||
stream.on('end', () => resolve(Buffer.concat(buffers)));
|
||||
});
|
||||
|
||||
clearTimeout(lastEntryTimeout);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user