[chore] removed jszip and node-stream-zip packages

This commit is contained in:
silentrald
2024-11-09 01:28:43 +08:00
parent 2b37972dd4
commit dd08f418d5
4 changed files with 59 additions and 39 deletions
+6 -13
View File
@@ -32,11 +32,9 @@
"got": "^14.4.4",
"history": "^5.3.0",
"is-elevated": "^4.0.0",
"jszip": "^3.10.1",
"md5-file": "^5.0.0",
"node-abi": "^3.65.0",
"node-fetch": "^3.3.2",
"node-stream-zip": "^1.15.0",
"pako": "^2.1.0",
"protobufjs": "^7.4.0",
"qrcode.react": "^4.0.1",
@@ -13897,6 +13895,7 @@
},
"node_modules/immediate": {
"version": "3.0.6",
"dev": true,
"license": "MIT"
},
"node_modules/immutable": {
@@ -15813,6 +15812,7 @@
},
"node_modules/jszip": {
"version": "3.10.1",
"dev": true,
"license": "(MIT OR GPL-3.0-or-later)",
"dependencies": {
"lie": "~3.3.0",
@@ -15823,10 +15823,12 @@
},
"node_modules/jszip/node_modules/pako": {
"version": "1.0.11",
"dev": true,
"license": "(MIT AND Zlib)"
},
"node_modules/jszip/node_modules/readable-stream": {
"version": "2.3.7",
"dev": true,
"license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
@@ -15944,6 +15946,7 @@
},
"node_modules/lie": {
"version": "3.3.0",
"dev": true,
"license": "MIT",
"dependencies": {
"immediate": "~3.0.5"
@@ -17230,17 +17233,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/node-stream-zip": {
"version": "1.15.0",
"license": "MIT",
"engines": {
"node": ">=0.12.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/antelle"
}
},
"node_modules/nopt": {
"version": "6.0.0",
"dev": true,
@@ -20047,6 +20039,7 @@
},
"node_modules/setimmediate": {
"version": "1.0.5",
"dev": true,
"license": "MIT"
},
"node_modules/setprototypeof": {
-2
View File
@@ -225,11 +225,9 @@
"got": "^14.4.4",
"history": "^5.3.0",
"is-elevated": "^4.0.0",
"jszip": "^3.10.1",
"md5-file": "^5.0.0",
"node-abi": "^3.65.0",
"node-fetch": "^3.3.2",
"node-stream-zip": "^1.15.0",
"pako": "^2.1.0",
"protobufjs": "^7.4.0",
"qrcode.react": "^4.0.1",
+25 -10
View File
@@ -23,6 +23,8 @@ export interface ZipExtractOptions {
};
export interface ZipProcessOptions {
// Stops the extraction immediately when set to true
terminate?: (entry: ZipEntry) => boolean;
getBuffer?: boolean;
};
@@ -96,7 +98,8 @@ function handleExtractZip(
zipEntry.buffer = undefined;
if (options?.terminate?.(zipEntry)) {
return readStream.destroy();
readStream.destroy();
return zip.close();
}
if (options?.condition) {
@@ -129,23 +132,28 @@ function handleExtractZip(
// @params loop - this should not throw an error
export function processZip<T>(
zipPath: string,
data: string | Buffer,
options: Readonly<ZipProcessOptions>,
loop: (accumulator: T, entry: ZipEntry) => T,
initValue: T
): Promise<T> {
return new Promise((resolve, reject) => {
yauzl.open(zipPath, {
lazyEntries: true,
decodeStrings: true,
},
(openError, zip) => {
const callback = (openError: Error, zip: yauzl.ZipFile) => {
if (openError) return reject(openError);
handleProcessZip<T>(
zip, options, loop, initValue,
resolve, reject
);
});
}
if (typeof data === "string") {
yauzl.open(data, {
lazyEntries: true,
decodeStrings: true,
}, callback);
} else {
yauzl.fromBuffer(data, callback);
}
});
}
@@ -177,14 +185,21 @@ async function handleProcessZip<T>(
zip.openReadStream(entry, (readError, readStream) => {
if (readError) return reject(readError);
zipEntry.name = entry.fileName;
zipEntry.directory = false;
zipEntry.buffer = undefined;
if (options?.terminate?.(zipEntry)) {
readStream.destroy();
zip.close();
return;
}
const chunks: Buffer[] = [];
readStream.on("data", data => {
chunks.push(data);
});
readStream.on("end", () => {
zipEntry.name = entry.fileName;
zipEntry.directory = false;
zipEntry.buffer = Buffer.concat(chunks);
accumulator = loop(accumulator, zipEntry);
zip.readEntry();
+28 -14
View File
@@ -1,4 +1,3 @@
import JSZip from "jszip";
import fetch from "node-fetch";
import { CustomError } from "../../shared/models/exceptions/custom-error.class";
import { mkdirs, createWriteStream, pathExists, WriteStream } from "fs-extra";
@@ -7,6 +6,7 @@ import { inflate } from "pako"
import { EMPTY, Observable, ReplaySubject, Subscriber, catchError, filter, from, lastValueFrom, mergeMap, scan, share, tap } from "rxjs";
import { Progression, hashFile } from "../helpers/fs.helpers";
import { OculusDownloaderErrorCodes } from "../../shared/models/bs-version-download/oculus-download.model";
import { processZip } from "main/helpers/zip.helpers";
export class OculusDownloader {
@@ -23,26 +23,40 @@ export class OculusDownloader {
return `https://securecdn.oculus.com/binaries/segment/?access_token=${token}&binary_id=${binaryId}&segment_sha256=${segmentSha256}`;
}
private async downloadManifestZip(manifestUrl: string): Promise<JSZip> {
private async downloadManifestZip(manifestUrl: string): Promise<Buffer> {
const response = await fetch(manifestUrl);
const arrBuffer = await response.arrayBuffer();
return JSZip.loadAsync(arrBuffer);
return Buffer.from(arrBuffer);
}
private async getManifest(): Promise<OculusManifest> {
const downloadUrl = this.getDownloadManifestUrl(this.options.accessToken, this.options.binaryId);
const manifestZip = await this.downloadManifestZip(downloadUrl).catch(err => CustomError.throw(err, "DOWNLOAD_MANIFEST_FAILED"));
const manifestFile = manifestZip.file("manifest.json");
const buffer = await this.downloadManifestZip(downloadUrl)
.catch(err => CustomError.throw(err, "DOWNLOAD_MANIFEST_FAILED"));
if(!manifestFile){
let found = false;
let manifestString: string | null = null;
// NOTE: Might be better to do get file in zip.helpers
await processZip(buffer, {
terminate: () => found,
getBuffer: true,
}, (_, entry): void => {
if (entry.name !== "manifest.json") return;
found = true;
manifestString = entry.buffer.toString();
}, undefined);
if(!manifestString) {
throw new CustomError("Manifest file not found", "MANIFEST_FILE_NOT_FOUND");
}
return manifestFile.async("text").then(JSON.parse).catch(err => CustomError.throw(err, "PARSE_MANIFEST_FILE_FAILED"));
return JSON.parse(manifestString)
.catch((err: Error) => CustomError.throw(err, "PARSE_MANIFEST_FILE_FAILED"));
}
private downloadManifestFile(file: OculusManifestFile, destination: string): Observable<Progression<OculusManifestFile>> {
const downloadSegment = async (segment: OculusManifestFileSegment): Promise<ArrayBuffer> => {
const segmentUrl = this.getDownloadSegmentUrl(this.options.accessToken, this.options.binaryId, segment[1]);
const response = await fetch(segmentUrl);
@@ -66,11 +80,11 @@ export class OculusDownloader {
const arrBuffer = await downloadSegment(segment);
const inflated = inflate(arrBuffer);
await writeStream.write(inflated);
writeStream.write(inflated);
progress.current += inflated.byteLength;
progress.diff = inflated.byteLength;
sub.next(progress);
}
@@ -86,7 +100,7 @@ export class OculusDownloader {
});
}
private isFileIntegrityValid(file: OculusFileWithName, folder: string): Promise<boolean> {
private async isFileIntegrityValid(file: OculusFileWithName, folder: string): Promise<boolean> {
const [fileName, fileData] = file;
const destination = path.join(folder, fileName);
@@ -138,7 +152,7 @@ export class OculusDownloader {
if(this.isDownloading){
throw new CustomError("Already downloading", "ALREADY_DOWNLOADING");
}
this.options = options;
this.isDownloading = true;
@@ -182,7 +196,7 @@ export class OculusDownloader {
})));
const integrity = await lastValueFrom(this.verifyIntegrity(manifest, options.destination)).catch(err => CustomError.throw(err, "VERIFY_INTEGRITY_FAILED"));
if(integrity.data.length > 0){
throw new CustomError("Some files failed to download", "SOME_FILES_FAILED_TO_DOWNLOAD", integrity.data);
}
@@ -242,4 +256,4 @@ interface Logger {
info: (...args: unknown[]) => void;
warn: (...args: unknown[]) => void;
error: (...args: unknown[]) => void;
}
}