mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-29 13:46:18 +01:00
64 lines
2.1 KiB
JavaScript
64 lines
2.1 KiB
JavaScript
|
|
const sharp = require('sharp');
|
||
|
|
const fetch = require('node-fetch');
|
||
|
|
const fs = require('fs').promises;
|
||
|
|
const User = require('~/models/User');
|
||
|
|
const { getFirebaseStorage } = require('~/server/services/Files/Firebase/initialize');
|
||
|
|
const firebaseStrategy = require('./firebaseStrategy');
|
||
|
|
const localStrategy = require('./localStrategy');
|
||
|
|
const { logger } = require('~/config');
|
||
|
|
|
||
|
|
async function convertToWebP(inputBuffer) {
|
||
|
|
return sharp(inputBuffer).resize({ width: 150 }).toFormat('webp').toBuffer();
|
||
|
|
}
|
||
|
|
|
||
|
|
async function uploadAvatar(userId, input, manual) {
|
||
|
|
try {
|
||
|
|
if (userId === undefined) {
|
||
|
|
throw new Error('User ID is undefined');
|
||
|
|
}
|
||
|
|
const _id = userId;
|
||
|
|
// TODO: remove direct use of Model, `User`
|
||
|
|
const oldUser = await User.findOne({ _id });
|
||
|
|
let imageBuffer;
|
||
|
|
if (typeof input === 'string') {
|
||
|
|
const response = await fetch(input);
|
||
|
|
|
||
|
|
if (!response.ok) {
|
||
|
|
throw new Error(`Failed to fetch image from URL. Status: ${response.status}`);
|
||
|
|
}
|
||
|
|
imageBuffer = await response.buffer();
|
||
|
|
} else if (input instanceof Buffer) {
|
||
|
|
imageBuffer = input;
|
||
|
|
} else if (typeof input === 'object' && input instanceof File) {
|
||
|
|
const fileContent = await fs.readFile(input.path);
|
||
|
|
imageBuffer = Buffer.from(fileContent);
|
||
|
|
} else {
|
||
|
|
throw new Error('Invalid input type. Expected URL, Buffer, or File.');
|
||
|
|
}
|
||
|
|
const { width, height } = await sharp(imageBuffer).metadata();
|
||
|
|
const minSize = Math.min(width, height);
|
||
|
|
const squaredBuffer = await sharp(imageBuffer)
|
||
|
|
.extract({
|
||
|
|
left: Math.floor((width - minSize) / 2),
|
||
|
|
top: Math.floor((height - minSize) / 2),
|
||
|
|
width: minSize,
|
||
|
|
height: minSize,
|
||
|
|
})
|
||
|
|
.toBuffer();
|
||
|
|
const webPBuffer = await convertToWebP(squaredBuffer);
|
||
|
|
const storage = getFirebaseStorage();
|
||
|
|
if (storage) {
|
||
|
|
const url = await firebaseStrategy(userId, webPBuffer, oldUser, manual);
|
||
|
|
return url;
|
||
|
|
}
|
||
|
|
|
||
|
|
const url = await localStrategy(userId, webPBuffer, oldUser, manual);
|
||
|
|
return url;
|
||
|
|
} catch (error) {
|
||
|
|
logger.error('Error uploading the avatar:', error);
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
module.exports = uploadAvatar;
|