reafactor(image): upload image using gm library
gitea/salix/pipeline/head There was a failure building this commit Details

This commit is contained in:
Joan Sanchez 2023-04-14 13:04:40 +02:00
parent 32c5ced55b
commit 35f94c58b7
6 changed files with 108 additions and 601 deletions

View File

@ -1,7 +1,6 @@
const UserError = require('vn-loopback/util/user-error'); const UserError = require('vn-loopback/util/user-error');
const fs = require('fs-extra'); const fs = require('fs/promises');
const path = require('path'); const path = require('path');
const uuid = require('uuid');
module.exports = Self => { module.exports = Self => {
Self.remoteMethodCtx('upload', { Self.remoteMethodCtx('upload', {
@ -36,7 +35,7 @@ module.exports = Self => {
const fileOptions = {}; const fileOptions = {};
const args = ctx.args; const args = ctx.args;
let srcFile; let tempFilePath;
try { try {
const hasWriteRole = await models.ImageCollection.hasWriteRole(ctx, args.collection); const hasWriteRole = await models.ImageCollection.hasWriteRole(ctx, args.collection);
if (!hasWriteRole) if (!hasWriteRole)
@ -53,15 +52,20 @@ module.exports = Self => {
}); });
const file = await TempContainer.getFile(tempContainer.name, uploadedFile.name); 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`; const fileName = `${args.id}.png`;
await models.Image.registerImage(args.collection, srcFile, fileName, args.id);
} catch (e) {
if (fs.existsSync(srcFile))
await fs.unlink(srcFile);
throw e; await models.Image.resize({
collectionName: args.collection,
srcFile: tempFilePath,
fileName: fileName,
entityId: args.id
});
} finally {
try {
await fs.unlink(tempFilePath);
} catch (error) { }
} }
}; };
}; };

View File

@ -1,161 +1,108 @@
const fs = require('fs-extra'); const fs = require('fs-extra');
const sharp = require('sharp');
const path = require('path'); const path = require('path');
const readChunk = require('read-chunk'); const gm = require('gm');
const imageType = require('image-type');
const bmp = require('bmp-js');
module.exports = Self => { module.exports = Self => {
require('../methods/image/download')(Self); require('../methods/image/download')(Self);
require('../methods/image/upload')(Self); require('../methods/image/upload')(Self);
// Function extracted from jimp package (utils) Self.resize = async function({collectionName, srcFile, fileName, entityId}) {
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) => {
const models = Self.app.models; 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: [ fields: [
'id', 'id',
'name',
'maxWidth', 'maxWidth',
'maxHeight', 'maxHeight',
'model', 'model',
'property' 'property',
], ],
where: {name: collectionName}, where: {name: collectionName},
include: { include: {
relation: 'sizes', relation: 'sizes',
scope: { scope: {
fields: ['width', 'height', 'crop'] fields: ['width', 'height', 'crop'],
},
},
} }
} );
}, myOptions);
const data = { // Insert image row
await models.Image.upsertWithWhere(
{
name: fileName, name: fileName,
collectionFk: collectionName collectionFk: collectionName
}; },
const newImage = await Self.upsertWithWhere(data, { {
name: fileName, name: fileName,
collectionFk: collectionName, collectionFk: collectionName,
updated: Date.vnNow() updated: Date.vnNow() / 1000,
}, 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'
};
}
const resizeOpts = {
withoutEnlargement: true,
fit: 'inside'
};
await fs.mkdir(dstDir, {recursive: true});
await sharp(imgSrc, sharpOptions)
.resize(collection.maxWidth, collection.maxHeight, resizeOpts)
.png()
.toFile(dstFile);
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'
};
await fs.mkdir(dstDir, {recursive: true});
await sharp(imgSrc, sharpOptions)
.resize(size.width, size.height, resizeOpts)
.png()
.toFile(dstFile);
} }
);
// Update entity image file name
const model = models[collection.model]; const model = models[collection.model];
if (!model) throw new Error('No matching model found');
if (!model) const entity = await model.findById(entityId);
throw new Error('Matching model not found'); if (entity) {
await entity.updateAttribute(
const item = await model.findById(entityId, null, myOptions);
if (item) {
await item.updateAttribute(
collection.property, collection.property,
fileName, fileName
myOptions
); );
} }
if (fs.existsSync(srcFilePath)) // Resize
await fs.unlink(srcFilePath); const container = await models.ImageContainer.container(
collectionName
);
const rootPath = container.client.root;
const collectionDir = path.join(rootPath, collectionName);
await tx.commit(); // To max size
const {maxWidth, maxHeight} = collection;
const fullSizePath = path.join(collectionDir, 'full');
const toFullSizePath = `${fullSizePath}/${fileName}`;
return newImage; await fs.mkdir(fullSizePath, {recursive: true});
} catch (e) { await new Promise((resolve, reject) => {
await tx.rollback(); gm(srcFile)
throw e; .resize(maxWidth, maxHeight, '>')
.setFormat('png')
.write(toFullSizePath, function(err) {
if (err) reject(err);
if (!err) resolve();
});
});
// 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(srcFile);
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();
});
});
} }
}; };
}; };

View File

@ -162,14 +162,8 @@ export default class UploadPhoto extends Component {
if (!this.newPhoto.files) if (!this.newPhoto.files)
throw new Error(`Select an image`); throw new Error(`Select an image`);
const viewportType = this.viewportSelection;
const output = viewportType.output;
const options = { const options = {
type: 'blob', type: 'blob',
size: {
width: output.width,
height: output.height
}
}; };
return this.editor.result(options) return this.editor.result(options)
.then(blob => this.newPhoto.blob = blob) .then(blob => this.newPhoto.blob = blob)

View File

@ -1,9 +1,7 @@
const axios = require('axios'); const axios = require('axios');
const uuid = require('uuid');
const fs = require('fs/promises'); const fs = require('fs/promises');
const {createWriteStream} = require('fs'); const {createWriteStream} = require('fs');
const path = require('path'); const path = require('path');
const gm = require('gm');
module.exports = Self => { module.exports = Self => {
Self.remoteMethod('download', { Self.remoteMethod('download', {
@ -27,13 +25,9 @@ module.exports = Self => {
const maxAttempts = 3; const maxAttempts = 3;
const collectionName = 'catalog'; const collectionName = 'catalog';
const tx = await Self.beginTransaction({});
let tempFilePath; let tempFilePath;
let queueRow; let queueRow;
try { try {
const myOptions = { transaction: tx };
queueRow = await Self.findOne( queueRow = await Self.findOne(
{ {
fields: ['id', 'itemFk', 'url', 'attempts'], fields: ['id', 'itemFk', 'url', 'attempts'],
@ -44,58 +38,14 @@ module.exports = Self => {
}, },
}, },
order: 'priority, attempts, updated', order: 'priority, attempts, updated',
}, }
myOptions
); );
if (!queueRow) return; if (!queueRow) return;
const collection = await models.ImageCollection.findOne( const fileName = `${queueRow.itemFk}.png`;
{
fields: [
'id',
'maxWidth',
'maxHeight',
'model',
'property',
],
where: { name: collectionName },
include: {
relation: 'sizes',
scope: {
fields: ['width', 'height', 'crop'],
},
},
},
myOptions
);
const fileName = `${uuid.v4()}.png`;
tempFilePath = path.join(tempPath, fileName); 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 // Download remote image
const response = await axios.get(queueRow.url, { const response = await axios.get(queueRow.url, {
responseType: 'stream', responseType: 'stream',
@ -108,71 +58,22 @@ module.exports = Self => {
writeStream.on('error', error => reject(error)); writeStream.on('error', error => reject(error));
}); });
// Resize await models.Image.resize({
const container = await models.ImageContainer.container( collectionName: collectionName,
collectionName srcFile: tempFilePath,
); fileName: fileName,
const rootPath = container.client.root; entityId: queueRow.itemFk
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();
}); });
});
// 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 { try {
await fs.unlink(tempFilePath); await fs.unlink(tempFilePath);
} catch (error) { } } catch (error) { }
await queueRow.destroy(myOptions); await queueRow.destroy();
// Restart queue // Restart queue
Self.download(); Self.download();
await tx.commit();
} catch (error) { } catch (error) {
await tx.rollback();
if (queueRow.attempts < maxAttempts) { if (queueRow.attempts < maxAttempts) {
await queueRow.updateAttributes({ await queueRow.updateAttributes({
error: error, error: error,

364
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "salix-back", "name": "salix-back",
"version": "23.08.01", "version": "23.12.01",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "salix-back", "name": "salix-back",
"version": "23.08.01", "version": "23.12.01",
"license": "GPL-3.0", "license": "GPL-3.0",
"dependencies": { "dependencies": {
"axios": "^1.2.2", "axios": "^1.2.2",
@ -41,7 +41,6 @@
"puppeteer": "^18.0.5", "puppeteer": "^18.0.5",
"read-chunk": "^3.2.0", "read-chunk": "^3.2.0",
"require-yaml": "0.0.1", "require-yaml": "0.0.1",
"sharp": "^0.31.3",
"smbhash": "0.0.1", "smbhash": "0.0.1",
"strong-error-handler": "^2.3.2", "strong-error-handler": "^2.3.2",
"uuid": "^3.3.3", "uuid": "^3.3.3",
@ -5444,17 +5443,6 @@
"node": ">=0.10.0" "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": { "node_modules/color-convert": {
"version": "2.0.1", "version": "2.0.1",
"license": "MIT", "license": "MIT",
@ -5469,14 +5457,6 @@
"version": "1.1.4", "version": "1.1.4",
"license": "MIT" "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": { "node_modules/color-support": {
"version": "1.1.3", "version": "1.1.3",
"license": "ISC", "license": "ISC",
@ -6149,6 +6129,7 @@
}, },
"node_modules/deep-extend": { "node_modules/deep-extend": {
"version": "0.6.0", "version": "0.6.0",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=4.0.0" "node": ">=4.0.0"
@ -7630,13 +7611,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/expand-template": {
"version": "2.0.3",
"license": "(MIT OR WTFPL)",
"engines": {
"node": ">=6"
}
},
"node_modules/expand-tilde": { "node_modules/expand-tilde": {
"version": "2.0.2", "version": "2.0.2",
"dev": true, "dev": true,
@ -8891,10 +8865,6 @@
"assert-plus": "^1.0.0" "assert-plus": "^1.0.0"
} }
}, },
"node_modules/github-from-package": {
"version": "0.0.0",
"license": "MIT"
},
"node_modules/glob": { "node_modules/glob": {
"version": "7.2.0", "version": "7.2.0",
"license": "ISC", "license": "ISC",
@ -11516,6 +11486,7 @@
}, },
"node_modules/ini": { "node_modules/ini": {
"version": "1.3.8", "version": "1.3.8",
"dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/internal-ip": { "node_modules/internal-ip": {
@ -11645,10 +11616,6 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/is-arrayish": {
"version": "0.3.2",
"license": "MIT"
},
"node_modules/is-bigint": { "node_modules/is-bigint": {
"version": "1.0.4", "version": "1.0.4",
"dev": true, "dev": true,
@ -15610,10 +15577,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/napi-build-utils": {
"version": "1.0.2",
"license": "MIT"
},
"node_modules/natural-compare": { "node_modules/natural-compare": {
"version": "1.4.0", "version": "1.4.0",
"dev": true, "dev": true,
@ -15655,43 +15618,6 @@
"node": ">=4.0.0" "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": { "node_modules/node-addon-api": {
"version": "5.0.0", "version": "5.0.0",
"license": "MIT" "license": "MIT"
@ -17539,30 +17465,6 @@
"node": ">=0.10.0" "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": { "node_modules/precond": {
"version": "0.2.3", "version": "0.2.3",
"engines": { "engines": {
@ -18057,6 +17959,7 @@
}, },
"node_modules/rc": { "node_modules/rc": {
"version": "1.2.8", "version": "1.2.8",
"dev": true,
"license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
"dependencies": { "dependencies": {
"deep-extend": "^0.6.0", "deep-extend": "^0.6.0",
@ -19786,55 +19689,6 @@
"node": ">=8" "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": { "node_modules/shebang-command": {
"version": "2.0.0", "version": "2.0.0",
"license": "MIT", "license": "MIT",
@ -19893,77 +19747,6 @@
"version": "3.0.7", "version": "3.0.7",
"license": "ISC" "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": { "node_modules/simple-update-notifier": {
"version": "1.0.7", "version": "1.0.7",
"dev": true, "dev": true,
@ -20864,6 +20647,7 @@
}, },
"node_modules/strip-json-comments": { "node_modules/strip-json-comments": {
"version": "2.0.1", "version": "2.0.1",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
@ -30018,13 +29802,6 @@
"object-visit": "^1.0.0" "object-visit": "^1.0.0"
} }
}, },
"color": {
"version": "4.2.3",
"requires": {
"color-convert": "^2.0.1",
"color-string": "^1.9.0"
}
},
"color-convert": { "color-convert": {
"version": "2.0.1", "version": "2.0.1",
"requires": { "requires": {
@ -30034,13 +29811,6 @@
"color-name": { "color-name": {
"version": "1.1.4" "version": "1.1.4"
}, },
"color-string": {
"version": "1.9.1",
"requires": {
"color-name": "^1.0.0",
"simple-swizzle": "^0.2.2"
}
},
"color-support": { "color-support": {
"version": "1.1.3" "version": "1.1.3"
}, },
@ -30487,7 +30257,8 @@
} }
}, },
"deep-extend": { "deep-extend": {
"version": "0.6.0" "version": "0.6.0",
"dev": true
}, },
"deep-is": { "deep-is": {
"version": "0.1.4" "version": "0.1.4"
@ -31501,9 +31272,6 @@
} }
} }
}, },
"expand-template": {
"version": "2.0.3"
},
"expand-tilde": { "expand-tilde": {
"version": "2.0.2", "version": "2.0.2",
"dev": true, "dev": true,
@ -32389,9 +32157,6 @@
"assert-plus": "^1.0.0" "assert-plus": "^1.0.0"
} }
}, },
"github-from-package": {
"version": "0.0.0"
},
"glob": { "glob": {
"version": "7.2.0", "version": "7.2.0",
"requires": { "requires": {
@ -34296,7 +34061,8 @@
"version": "2.0.4" "version": "2.0.4"
}, },
"ini": { "ini": {
"version": "1.3.8" "version": "1.3.8",
"dev": true
}, },
"internal-ip": { "internal-ip": {
"version": "4.3.0", "version": "4.3.0",
@ -34372,9 +34138,6 @@
"has-tostringtag": "^1.0.0" "has-tostringtag": "^1.0.0"
} }
}, },
"is-arrayish": {
"version": "0.3.2"
},
"is-bigint": { "is-bigint": {
"version": "1.0.4", "version": "1.0.4",
"dev": true, "dev": true,
@ -37151,9 +36914,6 @@
"to-regex": "^3.0.1" "to-regex": "^3.0.1"
} }
}, },
"napi-build-utils": {
"version": "1.0.2"
},
"natural-compare": { "natural-compare": {
"version": "1.4.0", "version": "1.4.0",
"dev": true "dev": true
@ -37182,29 +36942,6 @@
"nocache": { "nocache": {
"version": "2.1.0" "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": { "node-addon-api": {
"version": "5.0.0" "version": "5.0.0"
}, },
@ -38439,23 +38176,6 @@
"version": "3.3.1", "version": "3.3.1",
"dev": true "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": { "precond": {
"version": "0.2.3" "version": "0.2.3"
}, },
@ -38789,6 +38509,7 @@
}, },
"rc": { "rc": {
"version": "1.2.8", "version": "1.2.8",
"dev": true,
"requires": { "requires": {
"deep-extend": "^0.6.0", "deep-extend": "^0.6.0",
"ini": "~1.3.0", "ini": "~1.3.0",
@ -40001,38 +39722,6 @@
"kind-of": "^6.0.2" "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": { "shebang-command": {
"version": "2.0.0", "version": "2.0.0",
"requires": { "requires": {
@ -40073,34 +39762,6 @@
"signal-exit": { "signal-exit": {
"version": "3.0.7" "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": { "simple-update-notifier": {
"version": "1.0.7", "version": "1.0.7",
"dev": true, "dev": true,
@ -40746,7 +40407,8 @@
} }
}, },
"strip-json-comments": { "strip-json-comments": {
"version": "2.0.1" "version": "2.0.1",
"dev": true
}, },
"strong-error-handler": { "strong-error-handler": {
"version": "2.3.2", "version": "2.3.2",

View File

@ -44,7 +44,6 @@
"puppeteer": "^18.0.5", "puppeteer": "^18.0.5",
"read-chunk": "^3.2.0", "read-chunk": "^3.2.0",
"require-yaml": "0.0.1", "require-yaml": "0.0.1",
"sharp": "^0.31.3",
"smbhash": "0.0.1", "smbhash": "0.0.1",
"strong-error-handler": "^2.3.2", "strong-error-handler": "^2.3.2",
"uuid": "^3.3.3", "uuid": "^3.3.3",