diff --git a/back/methods/image/upload.js b/back/methods/image/upload.js index 143da275e..1de0064f6 100644 --- a/back/methods/image/upload.js +++ b/back/methods/image/upload.js @@ -1,7 +1,6 @@ const UserError = require('vn-loopback/util/user-error'); -const fs = require('fs-extra'); +const fs = require('fs/promises'); const path = require('path'); -const uuid = require('uuid'); module.exports = Self => { Self.remoteMethodCtx('upload', { @@ -36,7 +35,7 @@ module.exports = Self => { const fileOptions = {}; const args = ctx.args; - let srcFile; + let tempFilePath; try { const hasWriteRole = await models.ImageCollection.hasWriteRole(ctx, args.collection); if (!hasWriteRole) @@ -53,15 +52,20 @@ module.exports = Self => { }); const file = await TempContainer.getFile(tempContainer.name, uploadedFile.name); - srcFile = path.join(file.client.root, file.container, file.name); + tempFilePath = path.join(file.client.root, file.container, file.name); - const fileName = `${uuid.v4()}.png`; - await models.Image.registerImage(args.collection, srcFile, fileName, args.id); - } catch (e) { - if (fs.existsSync(srcFile)) - await fs.unlink(srcFile); + const fileName = `${args.id}.png`; - throw e; + await models.Image.resize({ + collectionName: args.collection, + srcFile: tempFilePath, + fileName: fileName, + entityId: args.id + }); + } finally { + try { + await fs.unlink(tempFilePath); + } catch (error) { } } }; }; diff --git a/back/models/image.js b/back/models/image.js index 3d3b03879..61c6199b8 100644 --- a/back/models/image.js +++ b/back/models/image.js @@ -1,161 +1,110 @@ const fs = require('fs-extra'); -const sharp = require('sharp'); const path = require('path'); -const readChunk = require('read-chunk'); -const imageType = require('image-type'); -const bmp = require('bmp-js'); +const gm = require('gm'); module.exports = Self => { require('../methods/image/download')(Self); require('../methods/image/upload')(Self); - // Function extracted from jimp package (utils) - function scan(image, x, y, w, h, f) { - // round input - x = Math.round(x); - y = Math.round(y); - w = Math.round(w); - h = Math.round(h); - - for (let _y = y; _y < y + h; _y++) { - for (let _x = x; _x < x + w; _x++) { - const idx = (image.bitmap.width * _y + _x) << 2; - f.call(image, _x, _y, idx); - } - } - - return image; - } - - // Function extracted from jimp package (type-bmp) - function fromAGBR(bitmap) { - return scan({bitmap}, 0, 0, bitmap.width, bitmap.height, function( - x, - y, - index - ) { - const alpha = this.bitmap.data[index + 0]; - const blue = this.bitmap.data[index + 1]; - const green = this.bitmap.data[index + 2]; - const red = this.bitmap.data[index + 3]; - - this.bitmap.data[index + 0] = red; - this.bitmap.data[index + 1] = green; - this.bitmap.data[index + 2] = blue; - this.bitmap.data[index + 3] = bitmap.is_with_alpha ? alpha : 0xff; - }).bitmap; - } - - Self.registerImage = async(collectionName, srcFilePath, fileName, entityId) => { + Self.resize = async function({collectionName, srcFile, fileName, entityId}) { const models = Self.app.models; - const tx = await Self.beginTransaction({}); - const myOptions = {transaction: tx}; - try { - const collection = await models.ImageCollection.findOne({ + const collection = await models.ImageCollection.findOne( + { fields: [ 'id', - 'name', 'maxWidth', 'maxHeight', 'model', - 'property' + 'property', ], where: {name: collectionName}, include: { relation: 'sizes', scope: { - fields: ['width', 'height', 'crop'] - } - } - }, myOptions); + fields: ['width', 'height', 'crop'], + }, + }, + } + ); - const data = { + // Insert image row + await models.Image.upsertWithWhere( + { name: fileName, collectionFk: collectionName - }; - const newImage = await Self.upsertWithWhere(data, { + }, + { name: fileName, collectionFk: collectionName, - updated: Date.vnNow() - }, myOptions); - - // Resizes and saves the image - const container = await models.ImageContainer.container(collectionName); - const rootPath = container.client.root; - const collectionDir = path.join(rootPath, collectionName); - const dstDir = path.join(collectionDir, 'full'); - const dstFile = path.join(dstDir, fileName); - - const buffer = readChunk.sync(srcFilePath, 0, 12); - const type = imageType(buffer); - - let sharpOptions; - let imgSrc = srcFilePath; - if (type.mime == 'image/bmp') { - const bmpBuffer = fs.readFileSync(srcFilePath); - const bmpData = fromAGBR(bmp.decode(bmpBuffer)); - imgSrc = bmpData.data; - sharpOptions = { - raw: { - width: bmpData.width, - height: bmpData.height, - channels: 4 - }, - failOn: 'none' - }; + updated: Date.vnNow() / 1000, } + ); - const resizeOpts = { - withoutEnlargement: true, - fit: 'inside' - }; + // Update entity image file name + const model = models[collection.model]; + if (!model) throw new Error('No matching model found'); - await fs.mkdir(dstDir, {recursive: true}); - await sharp(imgSrc, sharpOptions) - .resize(collection.maxWidth, collection.maxHeight, resizeOpts) - .png() - .toFile(dstFile); + const entity = await model.findById(entityId); + if (entity) { + await entity.updateAttribute( + collection.property, + fileName + ); + } - const sizes = collection.sizes(); - for (let size of sizes) { - const dstDir = path.join(collectionDir, `${size.width}x${size.height}`); - const dstFile = path.join(dstDir, fileName); - const resizeOpts = { - withoutEnlargement: true, - fit: size.crop ? 'cover' : 'inside' - }; + // Resize + const container = await models.ImageContainer.container( + collectionName + ); + const rootPath = container.client.root; + const collectionDir = path.join(rootPath, collectionName); - await fs.mkdir(dstDir, {recursive: true}); - await sharp(imgSrc, sharpOptions) - .resize(size.width, size.height, resizeOpts) - .png() - .toFile(dstFile); - } + // To max size + const {maxWidth, maxHeight} = collection; + const fullSizePath = path.join(collectionDir, 'full'); + const toFullSizePath = `${fullSizePath}/${fileName}`; - const model = models[collection.model]; + await fs.mkdir(fullSizePath, {recursive: true}); + await new Promise((resolve, reject) => { + gm(srcFile) + .resize(maxWidth, maxHeight, '>') + .setFormat('png') + .quality(100) + .write(toFullSizePath, function(err) { + if (err) reject(err); + if (!err) resolve(); + }); + }); - if (!model) - throw new Error('Matching model not found'); + // To collection sizes + for (const size of collection.sizes()) { + const {width, height} = size; - const item = await model.findById(entityId, null, myOptions); - if (item) { - await item.updateAttribute( - collection.property, - fileName, - myOptions - ); - } + const sizePath = path.join(collectionDir, `${width}x${height}`); + const toSizePath = `${sizePath}/${fileName}`; - if (fs.existsSync(srcFilePath)) - await fs.unlink(srcFilePath); + await fs.mkdir(sizePath, {recursive: true}); + await new Promise((resolve, reject) => { + const gmInstance = gm(srcFile); - await tx.commit(); + if (size.crop) { + gmInstance + .resize(width, height, '^') + .gravity('Center') + .crop(width, height); + } - return newImage; - } catch (e) { - await tx.rollback(); - throw e; + if (!size.crop) gmInstance.resize(width, height, '>'); + + gmInstance + .setFormat('png') + .quality(100) + .write(toSizePath, function(err) { + if (err) reject(err); + if (!err) resolve(); + }); + }); } }; }; diff --git a/front/salix/components/upload-photo/index.js b/front/salix/components/upload-photo/index.js index da1fda923..c9774d037 100644 --- a/front/salix/components/upload-photo/index.js +++ b/front/salix/components/upload-photo/index.js @@ -162,14 +162,8 @@ export default class UploadPhoto extends Component { if (!this.newPhoto.files) throw new Error(`Select an image`); - const viewportType = this.viewportSelection; - const output = viewportType.output; const options = { type: 'blob', - size: { - width: output.width, - height: output.height - } }; return this.editor.result(options) .then(blob => this.newPhoto.blob = blob) diff --git a/modules/item/back/methods/item-image-queue/download.js b/modules/item/back/methods/item-image-queue/download.js index 5f1b460fc..eb952daa4 100644 --- a/modules/item/back/methods/item-image-queue/download.js +++ b/modules/item/back/methods/item-image-queue/download.js @@ -1,9 +1,7 @@ const axios = require('axios'); -const uuid = require('uuid'); const fs = require('fs/promises'); const {createWriteStream} = require('fs'); const path = require('path'); -const gm = require('gm'); module.exports = Self => { Self.remoteMethod('download', { @@ -27,13 +25,9 @@ module.exports = Self => { const maxAttempts = 3; const collectionName = 'catalog'; - const tx = await Self.beginTransaction({}); - let tempFilePath; let queueRow; try { - const myOptions = {transaction: tx}; - queueRow = await Self.findOne( { fields: ['id', 'itemFk', 'url', 'attempts'], @@ -44,58 +38,14 @@ module.exports = Self => { }, }, order: 'priority, attempts, updated', - }, - myOptions + } ); if (!queueRow) return; - const collection = await models.ImageCollection.findOne( - { - fields: [ - 'id', - 'maxWidth', - 'maxHeight', - 'model', - 'property', - ], - where: {name: collectionName}, - include: { - relation: 'sizes', - scope: { - fields: ['width', 'height', 'crop'], - }, - }, - }, - myOptions - ); - - const fileName = `${uuid.v4()}.png`; + const fileName = `${queueRow.itemFk}.png`; tempFilePath = path.join(tempPath, fileName); - // Insert image row - await models.Image.create( - { - name: fileName, - collectionFk: collectionName, - updated: Date.vnNow(), - }, - myOptions - ); - - // Update item - const model = models[collection.model]; - if (!model) throw new Error('No matching model found'); - - const item = await model.findById(queueRow.itemFk, null, myOptions); - if (item) { - await item.updateAttribute( - collection.property, - fileName, - myOptions - ); - } - // Download remote image const response = await axios.get(queueRow.url, { responseType: 'stream', @@ -108,71 +58,22 @@ module.exports = Self => { writeStream.on('error', error => reject(error)); }); - // Resize - const container = await models.ImageContainer.container( - collectionName - ); - const rootPath = container.client.root; - const collectionDir = path.join(rootPath, collectionName); - - // To max size - const {maxWidth, maxHeight} = collection; - const fullSizePath = path.join(collectionDir, 'full'); - const toFullSizePath = `${fullSizePath}/${fileName}`; - - await fs.mkdir(fullSizePath, {recursive: true}); - await new Promise((resolve, reject) => { - gm(tempFilePath) - .resize(maxWidth, maxHeight, '>') - .setFormat('png') - .write(toFullSizePath, function(err) { - if (err) reject(err); - if (!err) resolve(); - }); + await models.Image.resize({ + collectionName: collectionName, + srcFile: tempFilePath, + fileName: fileName, + entityId: queueRow.itemFk }); - // To collection sizes - for (const size of collection.sizes()) { - const {width, height} = size; - - const sizePath = path.join(collectionDir, `${width}x${height}`); - const toSizePath = `${sizePath}/${fileName}`; - - await fs.mkdir(sizePath, {recursive: true}); - await new Promise((resolve, reject) => { - const gmInstance = gm(tempFilePath); - - if (size.crop) { - gmInstance - .resize(width, height, '^') - .gravity('Center') - .crop(width, height); - } - - if (!size.crop) gmInstance.resize(width, height, '>'); - - gmInstance - .setFormat('png') - .write(toSizePath, function(err) { - if (err) reject(err); - if (!err) resolve(); - }); - }); - } - try { await fs.unlink(tempFilePath); } catch (error) { } - await queueRow.destroy(myOptions); + await queueRow.destroy(); // Restart queue Self.download(); - - await tx.commit(); } catch (error) { - await tx.rollback(); - if (queueRow.attempts < maxAttempts) { await queueRow.updateAttributes({ error: error, diff --git a/package-lock.json b/package-lock.json index 7e86dbba9..e59a073c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "salix-back", - "version": "23.08.01", + "version": "23.12.01", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "salix-back", - "version": "23.08.01", + "version": "23.12.01", "license": "GPL-3.0", "dependencies": { "axios": "^1.2.2", @@ -41,7 +41,6 @@ "puppeteer": "^18.0.5", "read-chunk": "^3.2.0", "require-yaml": "0.0.1", - "sharp": "^0.31.3", "smbhash": "0.0.1", "strong-error-handler": "^2.3.2", "uuid": "^3.3.3", @@ -5444,17 +5443,6 @@ "node": ">=0.10.0" } }, - "node_modules/color": { - "version": "4.2.3", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "license": "MIT", @@ -5469,14 +5457,6 @@ "version": "1.1.4", "license": "MIT" }, - "node_modules/color-string": { - "version": "1.9.1", - "license": "MIT", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, "node_modules/color-support": { "version": "1.1.3", "license": "ISC", @@ -6149,6 +6129,7 @@ }, "node_modules/deep-extend": { "version": "0.6.0", + "dev": true, "license": "MIT", "engines": { "node": ">=4.0.0" @@ -7630,13 +7611,6 @@ "node": ">=0.10.0" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "license": "(MIT OR WTFPL)", - "engines": { - "node": ">=6" - } - }, "node_modules/expand-tilde": { "version": "2.0.2", "dev": true, @@ -8891,10 +8865,6 @@ "assert-plus": "^1.0.0" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "license": "MIT" - }, "node_modules/glob": { "version": "7.2.0", "license": "ISC", @@ -11516,6 +11486,7 @@ }, "node_modules/ini": { "version": "1.3.8", + "dev": true, "license": "ISC" }, "node_modules/internal-ip": { @@ -11645,10 +11616,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "license": "MIT" - }, "node_modules/is-bigint": { "version": "1.0.4", "dev": true, @@ -15610,10 +15577,6 @@ "node": ">=0.10.0" } }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "license": "MIT" - }, "node_modules/natural-compare": { "version": "1.4.0", "dev": true, @@ -15655,43 +15618,6 @@ "node": ">=4.0.0" } }, - "node_modules/node-abi": { - "version": "3.28.0", - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-abi/node_modules/lru-cache": { - "version": "6.0.0", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-abi/node_modules/semver": { - "version": "7.3.8", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-abi/node_modules/yallist": { - "version": "4.0.0", - "license": "ISC" - }, "node_modules/node-addon-api": { "version": "5.0.0", "license": "MIT" @@ -17539,30 +17465,6 @@ "node": ">=0.10.0" } }, - "node_modules/prebuild-install": { - "version": "7.1.1", - "license": "MIT", - "dependencies": { - "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": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/precond": { "version": "0.2.3", "engines": { @@ -18057,6 +17959,7 @@ }, "node_modules/rc": { "version": "1.2.8", + "dev": true, "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { "deep-extend": "^0.6.0", @@ -19786,55 +19689,6 @@ "node": ">=8" } }, - "node_modules/sharp": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.3.tgz", - "integrity": "sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==", - "hasInstallScript": true, - "dependencies": { - "color": "^4.2.3", - "detect-libc": "^2.0.1", - "node-addon-api": "^5.0.0", - "prebuild-install": "^7.1.1", - "semver": "^7.3.8", - "simple-get": "^4.0.1", - "tar-fs": "^2.1.1", - "tunnel-agent": "^0.6.0" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/sharp/node_modules/lru-cache": { - "version": "6.0.0", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/sharp/node_modules/semver": { - "version": "7.3.8", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/sharp/node_modules/yallist": { - "version": "4.0.0", - "license": "ISC" - }, "node_modules/shebang-command": { "version": "2.0.0", "license": "MIT", @@ -19893,77 +19747,6 @@ "version": "3.0.7", "license": "ISC" }, - "node_modules/simple-concat": { - "version": "1.0.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/simple-get": { - "version": "4.0.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/simple-get/node_modules/decompress-response": { - "version": "6.0.0", - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/simple-get/node_modules/mimic-response": { - "version": "3.1.0", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, "node_modules/simple-update-notifier": { "version": "1.0.7", "dev": true, @@ -20864,6 +20647,7 @@ }, "node_modules/strip-json-comments": { "version": "2.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -30018,13 +29802,6 @@ "object-visit": "^1.0.0" } }, - "color": { - "version": "4.2.3", - "requires": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - } - }, "color-convert": { "version": "2.0.1", "requires": { @@ -30034,13 +29811,6 @@ "color-name": { "version": "1.1.4" }, - "color-string": { - "version": "1.9.1", - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, "color-support": { "version": "1.1.3" }, @@ -30487,7 +30257,8 @@ } }, "deep-extend": { - "version": "0.6.0" + "version": "0.6.0", + "dev": true }, "deep-is": { "version": "0.1.4" @@ -31501,9 +31272,6 @@ } } }, - "expand-template": { - "version": "2.0.3" - }, "expand-tilde": { "version": "2.0.2", "dev": true, @@ -32389,9 +32157,6 @@ "assert-plus": "^1.0.0" } }, - "github-from-package": { - "version": "0.0.0" - }, "glob": { "version": "7.2.0", "requires": { @@ -34296,7 +34061,8 @@ "version": "2.0.4" }, "ini": { - "version": "1.3.8" + "version": "1.3.8", + "dev": true }, "internal-ip": { "version": "4.3.0", @@ -34372,9 +34138,6 @@ "has-tostringtag": "^1.0.0" } }, - "is-arrayish": { - "version": "0.3.2" - }, "is-bigint": { "version": "1.0.4", "dev": true, @@ -37151,9 +36914,6 @@ "to-regex": "^3.0.1" } }, - "napi-build-utils": { - "version": "1.0.2" - }, "natural-compare": { "version": "1.4.0", "dev": true @@ -37182,29 +36942,6 @@ "nocache": { "version": "2.1.0" }, - "node-abi": { - "version": "3.28.0", - "requires": { - "semver": "^7.3.5" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.3.8", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0" - } - } - }, "node-addon-api": { "version": "5.0.0" }, @@ -38439,23 +38176,6 @@ "version": "3.3.1", "dev": true }, - "prebuild-install": { - "version": "7.1.1", - "requires": { - "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": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - } - }, "precond": { "version": "0.2.3" }, @@ -38789,6 +38509,7 @@ }, "rc": { "version": "1.2.8", + "dev": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -40001,38 +39722,6 @@ "kind-of": "^6.0.2" } }, - "sharp": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.3.tgz", - "integrity": "sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==", - "requires": { - "color": "^4.2.3", - "detect-libc": "^2.0.1", - "node-addon-api": "^5.0.0", - "prebuild-install": "^7.1.1", - "semver": "^7.3.8", - "simple-get": "^4.0.1", - "tar-fs": "^2.1.1", - "tunnel-agent": "^0.6.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.3.8", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0" - } - } - }, "shebang-command": { "version": "2.0.0", "requires": { @@ -40073,34 +39762,6 @@ "signal-exit": { "version": "3.0.7" }, - "simple-concat": { - "version": "1.0.1" - }, - "simple-get": { - "version": "4.0.1", - "requires": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - }, - "dependencies": { - "decompress-response": { - "version": "6.0.0", - "requires": { - "mimic-response": "^3.1.0" - } - }, - "mimic-response": { - "version": "3.1.0" - } - } - }, - "simple-swizzle": { - "version": "0.2.2", - "requires": { - "is-arrayish": "^0.3.1" - } - }, "simple-update-notifier": { "version": "1.0.7", "dev": true, @@ -40746,7 +40407,8 @@ } }, "strip-json-comments": { - "version": "2.0.1" + "version": "2.0.1", + "dev": true }, "strong-error-handler": { "version": "2.3.2", diff --git a/package.json b/package.json index 8fa177646..5ab8991fc 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,6 @@ "puppeteer": "^18.0.5", "read-chunk": "^3.2.0", "require-yaml": "0.0.1", - "sharp": "^0.31.3", "smbhash": "0.0.1", "strong-error-handler": "^2.3.2", "uuid": "^3.3.3",