import { sha512 } from 'js-sha512';
import { UsuarioModel } from './models/usuarioModel.js';
import { uploadImage } from '../utils/uploadImageToCloudinary.js';
/**
* Crea un nuevo usuario en la base de datos y en Firebase Authentication.
* Encripta la contraseña del usuario antes de guardarla y opcionalmente sube la imagen de perfil.
*
* @async
* @function create
* @param {Object} data - Datos del usuario a crear.
* @param {string} data.password - Contraseña del usuario que será encriptada.
* @param {Object} [data.fotoPerfil] - Ruta de la imagen de perfil para subir (opcional).
* @returns {Promise<Object>} El usuario creado.
*/
async function create(data) {
data.password = sha512(data.password);
if (data.fotoPerfil) {
data.fotoPerfil = await uploadImage(data.fotoPerfil);
}
return await new UsuarioModel(data).save();
}
/**
* Lista todos los usuarios ordenados por fecha de creación de forma descendente.
*
* @async
* @function list
* @returns {Promise<Array<Object>>} Lista de usuarios ordenada.
*/
async function list() {
return await UsuarioModel.find().sort({ createdAt: 'desc' }).exec();
}
/**
* Obtiene un usuario por su ID.
*
* @async
* @function getOne
* @param {string} id - ID único del usuario.
* @returns {Promise<Object|null>} El usuario encontrado o null si no existe.
*/
async function getOne(id) {
const params = { _id: id };
return await UsuarioModel.findOne(params).exec();
}
/**
* Elimina un usuario por su ID.
*
* @async
* @function remove
* @param {string} id - ID único del usuario a eliminar.
* @returns {Promise<Object|null>} El usuario eliminado o null si no existe.
*/
async function remove(id) {
return await UsuarioModel.findOneAndDelete({ _id: id }).exec();
}
/**
* Actualiza un usuario por su ID con los datos proporcionados en la base de datos y en Firebase Authentication.
* Si se incluye una nueva contraseña, esta será encriptada.
* Si se incluye una nueva imagen de perfil, será subida antes de actualizar.
*
* @async
* @function update
* @param {string} id - ID único del usuario a actualizar.
* @param {Object} data - Datos del usuario a actualizar.
* @param {string} [data.password] - Nueva contraseña del usuario (opcional).
* @param {Object} [data.fotoPerfil] - Nueva imagen de perfil para subir (opcional).
* @returns {Promise<Object|null>} El usuario actualizado o null si no existe.
*/
async function update(id, data) {
if (data.password) {
data.password = sha512(data.password);
}
if (data.fotoPerfil) {
data.fotoPerfil = await uploadImage(data.fotoPerfil);
}
try {
// Actualizar usuario en la base de datos
const updatedUser = await UsuarioModel.findOneAndUpdate({ _id: id }, data, {
new: true,
runValidators: true,
}).exec();
if (!updatedUser) {
return null;
}
return updatedUser;
} catch (error) {
throw error;
}
}
/**
* Obtiene un usuario por su correo electrónico y contraseña.
*
* @async
* @function getOneByEmailAndPassword
* @param {string} email - Correo electrónico del usuario.
* @param {string} password - Contraseña del usuario.
* @returns {Promise<Object|null>} El usuario encontrado o null si no existe.
*/
async function getOneByEmailAndPassword(email, password) {
return await UsuarioModel.findOne({ email, password }).exec();
}
/**
* Repositorio de usuarios que contiene las operaciones principales sobre la base de datos.
*
* @namespace usuariosRepository
* @property {Function} list - Lista todos los usuarios.
* @property {Function} create - Crea un nuevo usuario.
* @property {Function} getOne - Obtiene un usuario por su ID.
* @property {Function} remove - Elimina un usuario por su ID.
* @property {Function} update - Actualiza un usuario por su ID.
* @property {Function} getOneByEmailAndPassword - Obtiene un usuario por email y contraseña.
*/
export const usuariosRepository = {
list,
create,
getOne,
remove,
update,
getOneByEmailAndPassword
};