diff --git a/constants/allowedFileFormats.ts b/constants/allowedFileFormats.ts new file mode 100644 index 0000000..a9e5c2e --- /dev/null +++ b/constants/allowedFileFormats.ts @@ -0,0 +1 @@ +export const IMPORT_IMAGE_FILE_FORMATS = [".jpg", ".jpeg", ".bmp", ".png", ".gif"] \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 671c771..f1b9deb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -46,7 +46,7 @@ "node-7z-forall": "^2.1.5", "node-calibre": "^2.1.1", "node-unrar-js": "^1.0.5", - "sharp": "^0.28.3", + "sharp": "^0.30.3", "socket.io": "^4.4.0", "threetwo-ui-typings": "^1.0.13", "through2": "^4.0.2", @@ -3276,12 +3276,15 @@ "dev": true }, "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.1.tgz", + "integrity": "sha512-MFJr0uY4RvTQUKvPq7dh9grVOTYSFeXja2mBXioCGjnjJoXrAp9jJ1NQTDR73c9nwBSAQiNKloKl5zq9WB9UPw==", "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" } }, "node_modules/color-convert": { @@ -3306,6 +3309,22 @@ "simple-swizzle": "^0.2.2" } }, + "node_modules/color/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, "node_modules/combine-errors": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/combine-errors/-/combine-errors-3.0.3.tgz", @@ -3688,14 +3707,11 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", "engines": { - "node": ">=0.10" + "node": ">=8" } }, "node_modules/detect-newline": { @@ -9413,25 +9429,20 @@ } }, "node_modules/node-abi": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", - "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.8.0.tgz", + "integrity": "sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw==", "dependencies": { - "semver": "^5.4.1" - } - }, - "node_modules/node-abi/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" } }, "node_modules/node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" }, "node_modules/node-calibre": { "version": "2.1.1", @@ -12770,21 +12781,21 @@ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" }, "node_modules/prebuild-install": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", - "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.0.1.tgz", + "integrity": "sha512-QBSab31WqkyxpnMWQxubYAHR5S9B2+r81ucocew34Fkl98FhvKIF50jIJnNOBmAZfyNV7vE5T6gd3hTVWgY6tg==", "dependencies": { - "detect-libc": "^1.0.3", + "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", - "node-abi": "^2.21.0", + "node-abi": "^3.3.0", "npmlog": "^4.0.1", "pump": "^3.0.0", "rc": "^1.2.7", - "simple-get": "^3.0.3", + "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, @@ -12792,7 +12803,56 @@ "prebuild-install": "bin.js" }, "engines": { - "node": ">=6" + "node": ">=10" + } + }, + "node_modules/prebuild-install/node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prebuild-install/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prebuild-install/node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" } }, "node_modules/prelude-ls": { @@ -13535,25 +13595,74 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "node_modules/sharp": { - "version": "0.28.3", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.28.3.tgz", - "integrity": "sha512-21GEP45Rmr7q2qcmdnjDkNP04Ooh5v0laGS5FDpojOO84D1DJwUijLiSq8XNNM6e8aGXYtoYRh3sVNdm8NodMA==", + "version": "0.30.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.30.3.tgz", + "integrity": "sha512-rjpfJFK58ZOFSG8sxYSo3/JQb4ej095HjXp9X7gVu7gEn1aqSG8TCW29h/Rr31+PXrFADo1H/vKfw0uhMQWFtg==", "hasInstallScript": true, "dependencies": { - "color": "^3.1.3", - "detect-libc": "^1.0.3", - "node-addon-api": "^3.2.0", - "prebuild-install": "^6.1.2", + "color": "^4.2.1", + "detect-libc": "^2.0.1", + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1", "semver": "^7.3.5", - "simple-get": "^3.1.0", + "simple-get": "^4.0.1", "tar-fs": "^2.1.1", "tunnel-agent": "^0.6.0" }, + "engines": { + "node": ">=12.13.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/sharp/node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, "engines": { "node": ">=10" }, "funding": { - "url": "https://opencollective.com/libvips" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sharp/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sharp/node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" } }, "node_modules/shebang-command": { @@ -17581,12 +17690,27 @@ "dev": true }, "color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.1.tgz", + "integrity": "sha512-MFJr0uY4RvTQUKvPq7dh9grVOTYSFeXja2mBXioCGjnjJoXrAp9jJ1NQTDR73c9nwBSAQiNKloKl5zq9WB9UPw==", "requires": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "dependencies": { + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + } } }, "color-convert": { @@ -17913,9 +18037,9 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" }, "detect-newline": { "version": "3.1.0", @@ -22151,24 +22275,17 @@ } }, "node-abi": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", - "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.8.0.tgz", + "integrity": "sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw==", "requires": { - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } + "semver": "^7.3.5" } }, "node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" }, "node-calibre": { "version": "2.1.1", @@ -24566,23 +24683,48 @@ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" }, "prebuild-install": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", - "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.0.1.tgz", + "integrity": "sha512-QBSab31WqkyxpnMWQxubYAHR5S9B2+r81ucocew34Fkl98FhvKIF50jIJnNOBmAZfyNV7vE5T6gd3hTVWgY6tg==", "requires": { - "detect-libc": "^1.0.3", + "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", - "node-abi": "^2.21.0", + "node-abi": "^3.3.0", "npmlog": "^4.0.1", "pump": "^3.0.0", "rc": "^1.2.7", - "simple-get": "^3.0.3", + "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" + }, + "dependencies": { + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "requires": { + "mimic-response": "^3.1.0" + } + }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + }, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "requires": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + } } }, "prelude-ls": { @@ -25138,18 +25280,43 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "sharp": { - "version": "0.28.3", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.28.3.tgz", - "integrity": "sha512-21GEP45Rmr7q2qcmdnjDkNP04Ooh5v0laGS5FDpojOO84D1DJwUijLiSq8XNNM6e8aGXYtoYRh3sVNdm8NodMA==", + "version": "0.30.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.30.3.tgz", + "integrity": "sha512-rjpfJFK58ZOFSG8sxYSo3/JQb4ej095HjXp9X7gVu7gEn1aqSG8TCW29h/Rr31+PXrFADo1H/vKfw0uhMQWFtg==", "requires": { - "color": "^3.1.3", - "detect-libc": "^1.0.3", - "node-addon-api": "^3.2.0", - "prebuild-install": "^6.1.2", + "color": "^4.2.1", + "detect-libc": "^2.0.1", + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1", "semver": "^7.3.5", - "simple-get": "^3.1.0", + "simple-get": "^4.0.1", "tar-fs": "^2.1.1", "tunnel-agent": "^0.6.0" + }, + "dependencies": { + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "requires": { + "mimic-response": "^3.1.0" + } + }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + }, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "requires": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + } } }, "shebang-command": { diff --git a/package.json b/package.json index 5086804..bfe7493 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "node-7z-forall": "^2.1.5", "node-calibre": "^2.1.1", "node-unrar-js": "^1.0.5", - "sharp": "^0.28.3", + "sharp": "^0.30.3", "socket.io": "^4.4.0", "threetwo-ui-typings": "^1.0.13", "through2": "^4.0.2", diff --git a/services/libraryqueue.service.ts b/services/libraryqueue.service.ts index 0a40f19..db6a560 100644 --- a/services/libraryqueue.service.ts +++ b/services/libraryqueue.service.ts @@ -77,7 +77,6 @@ export default class QueueService extends Service { Object.assign(result, { fileSize: job.data.fileObject.fileSize, }); - console.log("KEYSS TO THE KINGDOM:", result) const { name, filePath, diff --git a/tsconfig.json b/tsconfig.json index f9c6b3c..4e82040 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,8 @@ "sourceMap": true, "pretty": true, "target": "es6", - "outDir": "dist" + "outDir": "dist", + "lib": ["es5", "es6", "dom", "dom.iterable"] }, "include": ["./**/*"], "exclude": [ diff --git a/utils/uncompression.utils.ts b/utils/uncompression.utils.ts index 2828b5d..5d48e82 100644 --- a/utils/uncompression.utils.ts +++ b/utils/uncompression.utils.ts @@ -36,6 +36,7 @@ import { createReadStream, promises as fs, readFileSync, + existsSync, } from "fs"; const fse = require("fs-extra"); const Unrar = require("unrar"); @@ -44,13 +45,25 @@ import { list, extract, onlyArchive } from "node-7z-forall"; import { IExtractedComicBookCoverFile } from "threetwo-ui-typings"; import sharp from "sharp"; import { getFileConstituents } from "../utils/file.utils"; -import { isNil, isUndefined, remove } from "lodash"; +import { flatten, isEmpty, isNil, isUndefined, remove } from "lodash"; import { convertXMLToJSON } from "./xml.utils"; import { USERDATA_DIRECTORY, COMICS_DIRECTORY } from "../constants/directories"; - +import { IMPORT_IMAGE_FILE_FORMATS } from "../constants/allowedFileFormats"; +interface RarFile { + name: string; + type: string; + size?: string; + packedSize?: string; + ratio?: string; + mtime: string; + attributes: string; + crc32: string; + hostOS: string; + compression: string; +} export const extractComicInfoXMLFromRar = async ( filePath: string -): Promise> => { +): Promise => { const result = { filePath, }; @@ -64,82 +77,104 @@ export const extractComicInfoXMLFromRar = async ( const targetDirectory = `${USERDATA_DIRECTORY}/covers/${fileNameWithoutExtension}`; await fse.ensureDir(targetDirectory, directoryOptions); console.info(`%s was created.`, targetDirectory); - return new Promise((resolve, reject) => { - const archive = new Unrar({ - path: path.resolve(filePath), - bin: `/usr/local/bin/unrar`, // this will change depending on Docker base OS + const archive = new Unrar({ + path: path.resolve(filePath), + bin: `/usr/local/bin/unrar`, // this will change depending on Docker base OS + }); + const filesInArchive: [RarFile] = await new Promise((resolve, reject) => { + return archive.list((err, entries) => { + resolve(entries); }); + }); - archive.list(async (err, entries) => { - remove(entries, ({ type }) => type === "Directory"); - const comicInfoXML = remove( - entries, - ({ name }) => name.toLowerCase() === "comicinfo.xml" + remove(filesInArchive, ({ type }) => type === "Directory"); + const comicInfoXML = remove( + filesInArchive, + ({ name }) => path.basename(name).toLowerCase() === "comicinfo.xml" + ); + remove( + filesInArchive, + ({ name }) => !IMPORT_IMAGE_FILE_FORMATS.includes(path.extname(name)) + ); + const files = filesInArchive.sort((a, b) => { + if (!isUndefined(a) && !isUndefined(b)) { + return path + .basename(a.name) + .toLowerCase() + .localeCompare(path.basename(b.name).toLowerCase()); + } + }); + const comicInfoXMLFilePromise = new Promise((resolve, reject) => { + let comicinfostring = ""; + if (!isUndefined(comicInfoXML[0])) { + const writeStream = createWriteStream( + `${targetDirectory}/${comicInfoXML[0].name}` ); - const files = entries.sort((a, b) => { - if (!isUndefined(a) && !isUndefined(b)) { - return a.name - .toLowerCase() - .localeCompare(b.name.toLowerCase()); - } - }); - const filesToWriteToDisk = [files[0].name, comicInfoXML[0]["name"]]; - remove(filesToWriteToDisk, (file) => !isNil(file.name)); - if (!isUndefined(comicInfoXML[0]["name"])) { - let comicinfostring = ""; - const writeStream = createWriteStream( - `${targetDirectory}/${comicInfoXML[0]["name"]}` + archive.stream(comicInfoXML[0]["name"]).pipe(writeStream); + writeStream.on("finish", async () => { + const readStream = createReadStream( + `${targetDirectory}/${comicInfoXML[0].name}` ); - - await archive.stream(comicInfoXML[0]["name"]).pipe(writeStream); - writeStream.on("finish", async () => { - const readStream = createReadStream( - `${targetDirectory}/${comicInfoXML[0]["name"]}` - ); - readStream.on("data", (data) => { - comicinfostring += data; - }); - readStream.on("error", (error) => reject(error)); - readStream.on("end", async () => { + readStream.on("data", (data) => { + comicinfostring += data; + }); + readStream.on("error", (error) => reject(error)); + readStream.on("end", async () => { + if ( + existsSync( + `${targetDirectory}/${path.basename( + comicInfoXML[0].name + )}` + ) + ) { const comicInfoJSON = await convertXMLToJSON( comicinfostring.toString() ); - Object.assign(result, { - comicInfoJSON: comicInfoJSON.comicinfo, - }); - }); + + resolve({ comicInfoJSON: comicInfoJSON.comicinfo }); + } + }); + }); + } else { + resolve({ comicInfoJSON: null }); + } + }); + + const coverFilePromise = new Promise((resolve, reject) => { + const coverFile = path.basename(files[0].name); + const sharpStream = sharp().resize(275); + const coverExtractionStream = archive.stream(files[0].name); + const resizeStream = coverExtractionStream.pipe(sharpStream); + + resizeStream.toFile(`${targetDirectory}/${coverFile}`, (err, info) => { + if (err) { + reject(err); + } + if (existsSync(`${targetDirectory}/${coverFile}`)) { + // orchestrate result + console.log("ASDAsd"); + resolve({ + name: fileNameWithoutExtension, + extension, + containedIn: targetDirectory, + cover: { + filePath: path.relative( + process.cwd(), + `${targetDirectory}/${coverFile}` + ), + }, }); } - - const sharpStream = sharp().resize(275); - const coverExtractionStream = archive.stream(files[0].name); - await coverExtractionStream - .pipe(sharpStream) - .toFile(`${targetDirectory}/${files[0].name}`); - // orchestrate result - Object.assign(result, { - name: fileNameWithoutExtension, - extension, - containedIn: targetDirectory, - cover: { - filePath: path.relative( - process.cwd(), - `${targetDirectory}/${files[0].name}` - ), - }, - }); - resolve(result); }); }); + + return Promise.all([comicInfoXMLFilePromise, coverFilePromise]); }; export const extractComicInfoXMLFromZip = async ( filePath: string -): Promise> => { - const result = { - filePath, - }; +): Promise => { // Create the target directory const directoryOptions = { mode: 0o2775, @@ -149,81 +184,108 @@ export const extractComicInfoXMLFromZip = async ( const targetDirectory = `${USERDATA_DIRECTORY}/covers/${fileNameWithoutExtension}`; await fse.ensureDir(targetDirectory, directoryOptions); console.info(`%s was created.`, targetDirectory); - let sortedFiles = []; - const filesToWriteToDisk = []; - return await list(filePath) - .progress((files) => { - // Do stuff with files... - sortedFiles = files.sort((a, b) => { - if (!isUndefined(a) && !isUndefined(b)) { - return a.name - .toLowerCase() - .localeCompare(b.name.toLowerCase()); - } - }); - const comicInfoXML = remove( - sortedFiles, - (file) => file.name.toLowerCase() === "comicinfo.xml" + let filesFromArchive = []; + let filesToWriteToDisk = { coverFile: null, comicInfoXML: null }; + const extractionTargets = []; + + await list(filePath).progress((files) => { + filesFromArchive.push(...files); + return filesFromArchive; + }); + remove( + filesFromArchive, + ({ name }) => !IMPORT_IMAGE_FILE_FORMATS.includes(path.extname(name)) + ); + remove( + filesFromArchive, + (file) => file.attr === "D...." && file.size === 0 + ); + const comicInfoXMLFileObject = remove( + filesFromArchive, + (file) => path.basename(file.name.toLowerCase()) === "comicinfo.xml" + ); + if (!isEmpty(comicInfoXMLFileObject)) { + filesToWriteToDisk.comicInfoXML = comicInfoXMLFileObject[0].name; + extractionTargets.push(filesToWriteToDisk.comicInfoXML); + } + + filesToWriteToDisk.coverFile = filesFromArchive[0].name; + extractionTargets.push(filesToWriteToDisk.coverFile); + await extract(path.resolve(filePath), targetDirectory, { + r: true, + raw: [...extractionTargets], + }); + + // ComicInfoXML detection, parsing and conversion to JSON + // Write ComicInfo.xml to disk + let comicinfostring = ""; + + const comicInfoXMLPromise = new Promise((resolve, reject) => { + if ( + !isNil(filesToWriteToDisk.comicInfoXML) && + existsSync( + `${targetDirectory}/${path.basename( + filesToWriteToDisk.comicInfoXML + )}` + ) + ) { + let comicinfoString = ""; + const comicInfoXMLStream = createReadStream( + `${targetDirectory}/${path.basename( + filesToWriteToDisk.comicInfoXML + )}` ); - if (!isUndefined(comicInfoXML)) { - filesToWriteToDisk.push(comicInfoXML[0].name); - } - filesToWriteToDisk.push(sortedFiles[0].name); - }) - .then((d) => { - return extract(path.resolve(filePath), targetDirectory, { - r: true, - raw: [...filesToWriteToDisk], - }) - .progress((files) => { - console.log(files); - }) - .then(() => { - const coverFile = filesToWriteToDisk.find( - (file) => file.toLowerCase() !== "comicinfo.xml" - ); - Object.assign(result, { + comicInfoXMLStream.on("data", (data) => (comicinfoString += data)); + comicInfoXMLStream.on("end", async () => { + const comicInfoJSON = await convertXMLToJSON( + comicinfoString.toString() + ); + resolve({ + comicInfoJSON: comicInfoJSON.comicinfo, + }); + }); + } else { + resolve({ + comicInfoJSON: null, + }); + } + }); + // Write the cover to disk + const coverFilePromise = new Promise((resolve, reject) => { + const sharpStream = sharp().resize(275); + const coverStream = createReadStream( + `${targetDirectory}/${path.basename(filesToWriteToDisk.coverFile)}` + ); + coverStream + .pipe(sharpStream) + .toFile( + `${targetDirectory}/${path.basename( + filesToWriteToDisk.coverFile + )}`, + (err, info) => { + if (err) { + reject(err); + } + // Update metadata + resolve({ + filePath, name: fileNameWithoutExtension, extension, containedIn: targetDirectory, cover: { filePath: path.relative( process.cwd(), - `${targetDirectory}/${coverFile}` + `${targetDirectory}/${path.basename( + filesToWriteToDisk.coverFile + )}` ), }, }); - // ComicInfoXML detection, parsing and conversion to JSON - let comicinfostring = ""; - const comicInfoFile = filesToWriteToDisk.find( - (file) => file.toLowerCase() === "comicinfo.xml" - ); - return new Promise((resolve, reject) => { - const comicInfoXMLStream = createReadStream( - `${targetDirectory}/${comicInfoFile}` - ); - comicInfoXMLStream.on("data", (data) => { - comicinfostring += data; - }); - comicInfoXMLStream.on("error", (error) => - console.log(error) - ); - comicInfoXMLStream.on("end", async () => { - const comicInfoJSON = await convertXMLToJSON( - comicinfostring.toString() - ); - Object.assign(result, { - comicInfoJSON: comicInfoJSON.comicinfo, - }); + } + ); + }); - resolve(result); - }); - }); - }) - .catch((error) => { - console.log(error); - }); - }); + return Promise.all([comicInfoXMLPromise, coverFilePromise]); }; export const extractFromArchive = async (filePath: string) => { @@ -233,13 +295,16 @@ export const extractFromArchive = async (filePath: string) => { console.log( "Detected file type is cbz, looking for comicinfo.xml..." ); - return await extractComicInfoXMLFromZip(filePath); + const result = await extractComicInfoXMLFromZip(filePath); + return Object.assign({}, ...result); case ".cbr": console.log( "Detected file type is cbr, looking for comicinfo.xml..." ); - return await extractComicInfoXMLFromRar(filePath); + const CbrResult = await extractComicInfoXMLFromRar(filePath); + console.log(CbrResult); + return Object.assign({}, ...CbrResult); default: console.log( diff --git a/yarn.lock b/yarn.lock index 3629674..1a46eef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1950,7 +1950,7 @@ "resolved" "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz" "version" "1.0.1" -"color-convert@^1.9.0", "color-convert@^1.9.3": +"color-convert@^1.9.0": "integrity" "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==" "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" "version" "1.9.3" @@ -1974,7 +1974,7 @@ "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" "version" "1.1.4" -"color-string@^1.6.0": +"color-string@^1.9.0": "integrity" "sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==" "resolved" "https://registry.npmjs.org/color-string/-/color-string-1.9.0.tgz" "version" "1.9.0" @@ -1985,13 +1985,13 @@ "color-support@^1.1.2": "version" "1.1.3" -"color@^3.1.3": - "integrity" "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==" - "resolved" "https://registry.npmjs.org/color/-/color-3.2.1.tgz" - "version" "3.2.1" +"color@^4.2.1": + "integrity" "sha512-MFJr0uY4RvTQUKvPq7dh9grVOTYSFeXja2mBXioCGjnjJoXrAp9jJ1NQTDR73c9nwBSAQiNKloKl5zq9WB9UPw==" + "resolved" "https://registry.npmjs.org/color/-/color-4.2.1.tgz" + "version" "4.2.1" dependencies: - "color-convert" "^1.9.3" - "color-string" "^1.6.0" + "color-convert" "^2.0.1" + "color-string" "^1.9.0" "colors@1.4.0": "version" "1.4.0" @@ -2264,6 +2264,13 @@ dependencies: "mimic-response" "^2.0.0" +"decompress-response@^6.0.0": + "integrity" "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==" + "resolved" "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz" + "version" "6.0.0" + dependencies: + "mimic-response" "^3.1.0" + "dedent@^0.7.0": "integrity" "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" "resolved" "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz" @@ -2331,10 +2338,10 @@ "resolved" "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz" "version" "1.0.4" -"detect-libc@^1.0.3": - "integrity" "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" - "resolved" "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz" - "version" "1.0.3" +"detect-libc@^2.0.0", "detect-libc@^2.0.1": + "integrity" "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" + "resolved" "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz" + "version" "2.0.1" "detect-newline@^3.0.0": "integrity" "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==" @@ -4844,6 +4851,11 @@ "resolved" "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz" "version" "2.1.0" +"mimic-response@^3.1.0": + "integrity" "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + "resolved" "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz" + "version" "3.1.0" + "minimatch@^3.0.4": "integrity" "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==" "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" @@ -5176,17 +5188,17 @@ "system-installer" "^1.1.6" "when" "^3.7.8" -"node-abi@^2.21.0": - "integrity" "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==" - "resolved" "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz" - "version" "2.30.1" +"node-abi@^3.3.0": + "integrity" "sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw==" + "resolved" "https://registry.npmjs.org/node-abi/-/node-abi-3.8.0.tgz" + "version" "3.8.0" dependencies: - "semver" "^5.4.1" + "semver" "^7.3.5" -"node-addon-api@^3.2.0": - "integrity" "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" - "resolved" "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz" - "version" "3.2.1" +"node-addon-api@^4.3.0": + "integrity" "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + "resolved" "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz" + "version" "4.3.0" "node-calibre@^2.1.1": "integrity" "sha512-t68lVmU+VznsivQKM6Fr1HSRQ2+m54OouiDkeCzRUQJO3N4h9l60DlcHFu2HAn6Kw5nsZEbOtnkk5OBhhOErxA==" @@ -5749,22 +5761,22 @@ "resolved" "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz" "version" "1.1.0" -"prebuild-install@^6.1.2": - "integrity" "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==" - "resolved" "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz" - "version" "6.1.4" +"prebuild-install@^7.0.1": + "integrity" "sha512-QBSab31WqkyxpnMWQxubYAHR5S9B2+r81ucocew34Fkl98FhvKIF50jIJnNOBmAZfyNV7vE5T6gd3hTVWgY6tg==" + "resolved" "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.0.1.tgz" + "version" "7.0.1" dependencies: - "detect-libc" "^1.0.3" + "detect-libc" "^2.0.0" "expand-template" "^2.0.3" "github-from-package" "0.0.0" "minimist" "^1.2.3" "mkdirp-classic" "^0.5.3" "napi-build-utils" "^1.0.1" - "node-abi" "^2.21.0" + "node-abi" "^3.3.0" "npmlog" "^4.0.1" "pump" "^3.0.0" "rc" "^1.2.7" - "simple-get" "^3.0.3" + "simple-get" "^4.0.0" "tar-fs" "^2.0.0" "tunnel-agent" "^0.6.0" @@ -6231,11 +6243,6 @@ dependencies: "lru-cache" "^6.0.0" -"semver@^5.4.1": - "integrity" "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - "resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" - "version" "5.7.1" - "semver@^6.0.0": "integrity" "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" "resolved" "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" @@ -6293,17 +6300,17 @@ "resolved" "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" "version" "1.2.0" -"sharp@^0.28.3": - "integrity" "sha512-21GEP45Rmr7q2qcmdnjDkNP04Ooh5v0laGS5FDpojOO84D1DJwUijLiSq8XNNM6e8aGXYtoYRh3sVNdm8NodMA==" - "resolved" "https://registry.npmjs.org/sharp/-/sharp-0.28.3.tgz" - "version" "0.28.3" +"sharp@^0.30.3": + "integrity" "sha512-rjpfJFK58ZOFSG8sxYSo3/JQb4ej095HjXp9X7gVu7gEn1aqSG8TCW29h/Rr31+PXrFADo1H/vKfw0uhMQWFtg==" + "resolved" "https://registry.npmjs.org/sharp/-/sharp-0.30.3.tgz" + "version" "0.30.3" dependencies: - "color" "^3.1.3" - "detect-libc" "^1.0.3" - "node-addon-api" "^3.2.0" - "prebuild-install" "^6.1.2" + "color" "^4.2.1" + "detect-libc" "^2.0.1" + "node-addon-api" "^4.3.0" + "prebuild-install" "^7.0.1" "semver" "^7.3.5" - "simple-get" "^3.1.0" + "simple-get" "^4.0.1" "tar-fs" "^2.1.1" "tunnel-agent" "^0.6.0" @@ -6343,7 +6350,7 @@ "resolved" "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz" "version" "1.0.1" -"simple-get@^3.0.3", "simple-get@^3.1.0": +"simple-get@^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" @@ -6352,6 +6359,24 @@ "once" "^1.3.1" "simple-concat" "^1.0.0" +"simple-get@^4.0.0": + "integrity" "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==" + "resolved" "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz" + "version" "4.0.1" + dependencies: + "decompress-response" "^6.0.0" + "once" "^1.3.1" + "simple-concat" "^1.0.0" + +"simple-get@^4.0.1": + "integrity" "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==" + "resolved" "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz" + "version" "4.0.1" + dependencies: + "decompress-response" "^6.0.0" + "once" "^1.3.1" + "simple-concat" "^1.0.0" + "simple-swizzle@^0.2.2": "integrity" "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=" "resolved" "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz"