From c67328c4d66fd1a2c009fe29014b34475ba940ee Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Mon, 28 Feb 2022 09:51:45 -0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20Added=20a=20step=20to=20extract?= =?UTF-8?q?=20comicinfo.xml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models/comic.model.ts | 122 +++++++++++++++---------------- package-lock.json | 79 ++++++++++++-------- package.json | 5 +- services/libraryqueue.service.ts | 21 +++++- utils/file.utils.ts | 14 ++++ utils/uncompression.utils.ts | 98 +++++++++++++++---------- yarn.lock | 31 ++++---- 7 files changed, 217 insertions(+), 153 deletions(-) diff --git a/models/comic.model.ts b/models/comic.model.ts index a7d418e..d25ab16 100644 --- a/models/comic.model.ts +++ b/models/comic.model.ts @@ -1,5 +1,5 @@ const mongoose = require("mongoose"); -var mexp = require('mongoose-elasticsearch-xp').v7; +var mexp = require("mongoose-elasticsearch-xp").v7; const paginate = require("mongoose-paginate-v2"); const { Client } = require("@elastic/elasticsearch"); @@ -12,77 +12,69 @@ export const eSClient = new Client({ }, }); - -const ComicSchema = mongoose.Schema({ - importStatus: { - isImported: Boolean, - tagged: Boolean, - matchedResult: { - score: String, +const ComicSchema = mongoose.Schema( + { + importStatus: { + isImported: Boolean, + tagged: Boolean, + matchedResult: { + score: String, + }, }, - }, - userAddedMetadata: { - tags: [], - }, - sourcedMetadata: { - comicInfo: { - blackAndWhite: String, - characters: [String], - count: String, - genre: String, - manga: String, - month: String, - number: String, - pageCount: String, - pages: [], - publisher: String, - summary: String, - title: String, - writer: String, - year: String, + userAddedMetadata: { + tags: [], }, - comicvine: {}, - shortboxed: {}, - gcd: {}, - }, - rawFileDetails: { - name: { type: String, es_indexed: true }, - filePath: String, - fileSize: Number, - extension: String, - containedIn: String, - pageCount: Number, - cover: { + sourcedMetadata: { + comicInfo: { type: mongoose.Schema.Types.Mixed, default: {} }, + comicvine: { type: mongoose.Schema.Types.Mixed, default: {} }, + shortboxed: {}, + gcd: {}, + }, + rawFileDetails: { + name: { type: String, es_indexed: true }, filePath: String, - stats: Object, + fileSize: Number, + extension: String, + containedIn: String, + pageCount: Number, + cover: { + filePath: String, + stats: Object, + }, + calibreMetadata: { + coverWriteResult: String, + }, }, - calibreMetadata :{ - coverWriteResult: String, - } - }, - inferredMetadata: { - issue: { - name: String, - number: { type: Number, es_indexed: true, required: false, default: 0 }, - year: String, - subtitle: String, - } - }, - acquisition: { - wanted: Boolean, - release: {}, - directconnect: Array, - torrent: { - sourceApplication: String, - magnet: String, - tracker: String, - status: String, + inferredMetadata: { + issue: { + name: String, + number: { + type: Number, + es_indexed: true, + required: false, + default: 0, + }, + year: String, + subtitle: String, + }, }, - usenet: { - sourceApplication: String, + acquisition: { + wanted: Boolean, + release: {}, + directconnect: Array, + torrent: { + sourceApplication: String, + magnet: String, + tracker: String, + status: String, + }, + usenet: { + sourceApplication: String, + }, }, }, -}, { timestamps: true}); + { timestamps: true, minimize: false } +); ComicSchema.plugin(mexp, { client: eSClient, diff --git a/package-lock.json b/package-lock.json index ec3bf2f..b2a2761 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,14 +9,13 @@ "version": "0.0.1", "dependencies": { "@elastic/elasticsearch": "^7.16.0", + "@jorgeferrero/stream-to-buffer": "^2.0.6", "@root/walk": "^1.1.0", "@types/axios": "^0.14.0", "@types/jest": "^25.1.4", "@types/mkdirp": "^1.0.0", "@types/node": "^13.9.8", "@types/string-similarity": "^4.0.0", - "7zip-bin": "^5.1.1", - "7zip-min": "^1.4.0", "axios": "^0.25.0", "axios-retry": "^3.2.4", "bree": "^7.1.5", @@ -55,9 +54,11 @@ }, "devDependencies": { "@types/lodash": "^4.14.168", + "@types/node-7z": "^2.1.4", "@types/unzipper": "^0.10.3", "@typescript-eslint/eslint-plugin": "^4.33.0", "@typescript-eslint/parser": "^4.33.0", + "7zip-bin": "^5.1.1", "eslint": "^7.32.0", "eslint-plugin-import": "^2.20.2", "eslint-plugin-prefer-arrow": "^1.2.2", @@ -1685,6 +1686,11 @@ "node": ">=8" } }, + "node_modules/@jorgeferrero/stream-to-buffer": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@jorgeferrero/stream-to-buffer/-/stream-to-buffer-2.0.6.tgz", + "integrity": "sha512-G7jiBkMwDdYADntdV/qzl9H4Lkch0RyektqXl5+KhktduP4/rE1RaTz0wKZFdC2dKo3S0JaxoUUC3uDeXmI7EQ==" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1951,6 +1957,15 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==" }, + "node_modules/@types/node-7z": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@types/node-7z/-/node-7z-2.1.4.tgz", + "integrity": "sha512-SayS5Cld62m7wRsKtBJheNBYRTVmKK+wTmW16EmYf2FuRTSGHKPx/p2OqAVjeKSQss9qcCKDGG9yv7D+Pi+iNg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/prettier": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.3.tgz", @@ -2151,15 +2166,8 @@ "node_modules/7zip-bin": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz", - "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==" - }, - "node_modules/7zip-min": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/7zip-min/-/7zip-min-1.4.1.tgz", - "integrity": "sha512-xiK95rSNr6cXB7UXVLJdrxtNrlXBqZrMhcKlq0S5Rsg6vVhh+9OSUyQIba8bSAGgHjpETlWXAYEuVfxYGEfCWA==", - "dependencies": { - "7zip-bin": "^5.1.1" - } + "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==", + "dev": true }, "node_modules/abab": { "version": "2.0.5", @@ -4805,9 +4813,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.14.7", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", - "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", "funding": [ { "type": "individual", @@ -13526,9 +13534,9 @@ ] }, "node_modules/simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", "dependencies": { "decompress-response": "^4.2.0", "once": "^1.3.1", @@ -16242,6 +16250,11 @@ } } }, + "@jorgeferrero/stream-to-buffer": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@jorgeferrero/stream-to-buffer/-/stream-to-buffer-2.0.6.tgz", + "integrity": "sha512-G7jiBkMwDdYADntdV/qzl9H4Lkch0RyektqXl5+KhktduP4/rE1RaTz0wKZFdC2dKo3S0JaxoUUC3uDeXmI7EQ==" + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -16495,6 +16508,15 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==" }, + "@types/node-7z": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@types/node-7z/-/node-7z-2.1.4.tgz", + "integrity": "sha512-SayS5Cld62m7wRsKtBJheNBYRTVmKK+wTmW16EmYf2FuRTSGHKPx/p2OqAVjeKSQss9qcCKDGG9yv7D+Pi+iNg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/prettier": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.3.tgz", @@ -16621,15 +16643,8 @@ "7zip-bin": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz", - "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==" - }, - "7zip-min": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/7zip-min/-/7zip-min-1.4.1.tgz", - "integrity": "sha512-xiK95rSNr6cXB7UXVLJdrxtNrlXBqZrMhcKlq0S5Rsg6vVhh+9OSUyQIba8bSAGgHjpETlWXAYEuVfxYGEfCWA==", - "requires": { - "7zip-bin": "^5.1.1" - } + "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==", + "dev": true }, "abab": { "version": "2.0.5", @@ -18707,9 +18722,9 @@ "dev": true }, "follow-redirects": { - "version": "1.14.7", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", - "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==" + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" }, "for-each": { "version": "0.3.3", @@ -25029,9 +25044,9 @@ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" }, "simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", "requires": { "decompress-response": "^4.2.0", "once": "^1.3.1", diff --git a/package.json b/package.json index a048f17..0ae6a85 100644 --- a/package.json +++ b/package.json @@ -21,9 +21,11 @@ "author": "", "devDependencies": { "@types/lodash": "^4.14.168", + "@types/node-7z": "^2.1.4", "@types/unzipper": "^0.10.3", "@typescript-eslint/eslint-plugin": "^4.33.0", "@typescript-eslint/parser": "^4.33.0", + "7zip-bin": "^5.1.1", "eslint": "^7.32.0", "eslint-plugin-import": "^2.20.2", "eslint-plugin-prefer-arrow": "^1.2.2", @@ -38,14 +40,13 @@ }, "dependencies": { "@elastic/elasticsearch": "^7.16.0", + "@jorgeferrero/stream-to-buffer": "^2.0.6", "@root/walk": "^1.1.0", "@types/axios": "^0.14.0", "@types/jest": "^25.1.4", "@types/mkdirp": "^1.0.0", "@types/node": "^13.9.8", "@types/string-similarity": "^4.0.0", - "7zip-bin": "^5.1.1", - "7zip-min": "^1.4.0", "axios": "^0.25.0", "axios-retry": "^3.2.4", "bree": "^7.1.5", diff --git a/services/libraryqueue.service.ts b/services/libraryqueue.service.ts index 3de2744..efde5f4 100644 --- a/services/libraryqueue.service.ts +++ b/services/libraryqueue.service.ts @@ -46,9 +46,11 @@ import BullMQMixin from "moleculer-bull"; import { SandboxedJob } from "moleculer-bull"; import { DbMixin } from "../mixins/db.mixin"; import Comic from "../models/comic.model"; -import { extractCoverFromFile2 } from "../utils/uncompression.utils"; +import { extractComicInfoXMLFromArchive, extractCoverFromFile2 } from "../utils/uncompression.utils"; import { refineQuery } from "filename-parser"; import { io } from "./api.service"; +import { getFileConstituents } from "../utils/file.utils"; +import { USERDATA_DIRECTORY } from "../constants/directories"; const REDIS_URI = process.env.REDIS_URI || `redis://0.0.0.0:6379`; console.log(`REDIS -> ${REDIS_URI}`); @@ -70,12 +72,23 @@ export default class QueueService extends Service { const result = await extractCoverFromFile2( job.data.fileObject ); + const { filePath } = job.data.fileObject; + // get the file constituents and check for comicinfo.xml + // If present, convert the xml into json + // Import it into mongo + const { + extension, + fileNameWithoutExtension, + } = getFileConstituents(filePath); + const targetDirectory = `${USERDATA_DIRECTORY}/covers/${fileNameWithoutExtension}`; + const info = await extractComicInfoXMLFromArchive(filePath, targetDirectory, extension); // infer any issue-related metadata from the filename const { inferredIssueDetails } = refineQuery(result.name); console.log("Issue metadata inferred: ", JSON.stringify(inferredIssueDetails, null, 2)); // write to mongo + console.log("Writing to mongo...") const dbImportResult = await this.broker.call( "library.rawImportToDB", { @@ -91,12 +104,12 @@ export default class QueueService extends Service { issue: inferredIssueDetails, }, sourcedMetadata: { + comicInfo: info, comicvine: {}, }, }, {} ); - return Promise.resolve({ dbImportResult, id: job.id, @@ -156,8 +169,10 @@ export default class QueueService extends Service { "stalled", async (job) => { console.warn( - `The job with the id '${job} got stalled!` + `The job with the id '${job.id} got stalled!` ); + console.log(`${JSON.stringify(job, null, 2)}`); + console.log(`is stalled.`) } ); }); diff --git a/utils/file.utils.ts b/utils/file.utils.ts index 9325441..340d949 100644 --- a/utils/file.utils.ts +++ b/utils/file.utils.ts @@ -96,5 +96,19 @@ export const constructPaths = ( walkedFolder.extension, }); +export const getFileConstituents = (filePath: string) => { + const extension = path.extname(filePath); + const fileNameWithExtension = path.basename(filePath); + const fileNameWithoutExtension = path.basename( + filePath, + path.extname(filePath) + ); + return { + extension, + fileNameWithoutExtension, + fileNameWithExtension, + }; +}; + const filterOutDotFiles = (entities) => entities.filter((ent) => !ent.name.startsWith(".")); diff --git a/utils/uncompression.utils.ts b/utils/uncompression.utils.ts index 7eeeed8..038833a 100644 --- a/utils/uncompression.utils.ts +++ b/utils/uncompression.utils.ts @@ -32,7 +32,8 @@ SOFTWARE. */ const fse = require("fs-extra"); -import path from "path"; +import { promises as fs } from "fs"; +import path, { parse } from "path"; import { IExtractComicBookCoverErrorResponse, @@ -42,11 +43,17 @@ import { ISharpResizedImageStats, } from "threetwo-ui-typings"; -import { constructPaths, explodePath, walkFolder } from "../utils/file.utils"; +import { + explodePath, + getFileConstituents, + walkFolder, +} from "../utils/file.utils"; import { resizeImage } from "./imagetransformation.utils"; import { isNil, isUndefined } from "lodash"; import { convertXMLToJSON } from "./xml.utils"; -const sevenZip = require("7zip-min"); +import sevenBin from "7zip-bin"; +import { extract } from "node-7z"; +const pathTo7zip = sevenBin.path7za; const unrar = require("node-unrar-js"); const { Calibre } = require("node-calibre"); import { USERDATA_DIRECTORY, COMICS_DIRECTORY } from "../constants/directories"; @@ -69,20 +76,17 @@ export const extractCoverFromFile2 = async ( const directoryOptions = { mode: 0o2775, }; - const extension = path.extname(filePath); - const fileNameWithExtension = path.basename(filePath); - const fileNameWithoutExtension = path.basename( - filePath, - path.extname(filePath) - ); + const { + extension, + fileNameWithExtension, + fileNameWithoutExtension, + } = getFileConstituents(filePath); + const targetDirectory = `${USERDATA_DIRECTORY}/covers/${fileNameWithoutExtension}`; await fse.ensureDir(targetDirectory, directoryOptions); console.info(`%s was created.`, targetDirectory); - // 2.1 look for comicinfo.xml - extractFileFromArchive(filePath, targetDirectory, extension); - // 3. extract the cover console.info(`Starting cover extraction...`); let result: string; @@ -173,7 +177,7 @@ export const unrarArchive = async ( } }; -export const extractFileFromRar = async ( +export const extractComicInfoXMLFromRar = async ( filePath: string, fileToExtract: string ) => { @@ -186,55 +190,73 @@ export const extractFileFromRar = async ( data: fileBuffer, }); - const list = extractor.getFileList(); - const listArcHeader = list.arcHeader; // archive header - const fileHeaders = [...list.fileHeaders]; // load the file headers - const extracted = extractor.extract({ files: ["ComicInfo.xml"] }); const files = [...extracted.files]; //load the files - console.log("asdas", files[0]); - if(!isUndefined(files[0])) { - const trin = String.fromCharCode.apply(null, files[0].extraction) - const foo = await convertXMLToJSON(trin); - console.log(foo); + if (!isUndefined(files[0])) { + console.log( + `comicinfo.xml detected in ${filePath}, attempting extraction...` + ); + const fileContents = String.fromCharCode.apply( + null, + files[0].extraction + ); + const parsedJSON = await convertXMLToJSON(fileContents); + console.log(parsedJSON); + return parsedJSON.comicinfo; } } catch (error) { throw new Error(error); } }; -export const extractFileFromZip = async ( +export const extractComicInfoXMLFromZip = async ( filePath: string, outputDirectory: string ) => { - const foo = sevenZip.cmd( - ["e", path.resolve(filePath), outputDirectory, "*.xml"], - (err) => { - console.log(err); + const foo = extract(path.resolve(filePath), outputDirectory, { + $cherryPick: ["*.xml"], + $bin: pathTo7zip, + }); + for await (const chunk of foo) { + if (chunk.status === "extracted") { + console.log( + `comicinfo.xml detected in ${filePath}, attempting extraction...` + ); + const fileContents = await fs.readFile( + path.resolve(`${outputDirectory}/${chunk.file}`), + "utf8" + ); + const parsedJSON = await convertXMLToJSON( + Buffer.from(fileContents) + ); + console.log(parsedJSON); + return parsedJSON.comicinfo; } - ); - return foo; + } }; -export const extractFileFromArchive = async ( +export const extractComicInfoXMLFromArchive = async ( filePath: string, outputDirectory: string, extension: string ) => { - console.log(extension); switch (extension) { case ".cbz": - console.log("cbz"); - extractFileFromZip(filePath, outputDirectory); - break; + console.log( + "Detected file type is cbz, looking for comicinfo.xml..." + ); + return await extractComicInfoXMLFromZip(filePath, outputDirectory); case ".cbr": - console.log("cbr"); - extractFileFromRar(filePath, outputDirectory); - break; + console.log( + "Detected file type is cbr, looking for comicinfo.xml..." + ); + return await extractComicInfoXMLFromRar(filePath, outputDirectory); default: - console.log("error na rao"); + console.log( + "Error inferring filetype for comicinfo.xml extraction." + ); break; } }; diff --git a/yarn.lock b/yarn.lock index 9e56a71..16c5454 100644 --- a/yarn.lock +++ b/yarn.lock @@ -635,6 +635,11 @@ "@types/yargs" "^16.0.0" "chalk" "^4.0.0" +"@jorgeferrero/stream-to-buffer@^2.0.6": + "integrity" "sha512-G7jiBkMwDdYADntdV/qzl9H4Lkch0RyektqXl5+KhktduP4/rE1RaTz0wKZFdC2dKo3S0JaxoUUC3uDeXmI7EQ==" + "resolved" "https://registry.npmjs.org/@jorgeferrero/stream-to-buffer/-/stream-to-buffer-2.0.6.tgz" + "version" "2.0.6" + "@nodelib/fs.scandir@2.1.5": "integrity" "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==" "resolved" "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -974,6 +979,13 @@ "@types/bson" "*" "@types/node" "*" +"@types/node-7z@^2.1.4": + "integrity" "sha512-SayS5Cld62m7wRsKtBJheNBYRTVmKK+wTmW16EmYf2FuRTSGHKPx/p2OqAVjeKSQss9qcCKDGG9yv7D+Pi+iNg==" + "resolved" "https://registry.npmjs.org/@types/node-7z/-/node-7z-2.1.4.tgz" + "version" "2.1.4" + dependencies: + "@types/node" "*" + "@types/node@*", "@types/node@^13.9.8", "@types/node@>=10.0.0": "integrity" "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==" "resolved" "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz" @@ -1095,13 +1107,6 @@ "resolved" "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz" "version" "5.1.1" -"7zip-min@^1.4.0": - "integrity" "sha512-xiK95rSNr6cXB7UXVLJdrxtNrlXBqZrMhcKlq0S5Rsg6vVhh+9OSUyQIba8bSAGgHjpETlWXAYEuVfxYGEfCWA==" - "resolved" "https://registry.npmjs.org/7zip-min/-/7zip-min-1.4.1.tgz" - "version" "1.4.1" - dependencies: - "7zip-bin" "^5.1.1" - "abab@^2.0.0", "abab@^2.0.3", "abab@^2.0.5": "integrity" "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" "resolved" "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz" @@ -3005,9 +3010,9 @@ "version" "3.2.4" "follow-redirects@^1.14.7": - "integrity" "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==" - "resolved" "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz" - "version" "1.14.7" + "integrity" "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + "resolved" "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz" + "version" "1.14.9" "for-each@^0.3.3": "integrity" "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==" @@ -6299,9 +6304,9 @@ "version" "1.0.1" "simple-get@^3.0.3", "simple-get@^3.1.0": - "integrity" "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==" - "resolved" "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz" - "version" "3.1.0" + "integrity" "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==" + "resolved" "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz" + "version" "3.1.1" dependencies: "decompress-response" "^4.2.0" "once" "^1.3.1"