UNPKG

get-express-starter

Version:

Get production ready express boilerplate with a single command

152 lines (130 loc) 4.33 kB
const httpStatus = require('http-status'); const { User } = require('../models'); const ApiError = require('../utils/ApiError'); /** * Create a new user. * @param {Object} userBody - The user data to create. * @returns {Promise<User>} The created user. * @throws {ApiError} If the email is already taken. */ const createUser = async (userBody) => { if (await User.isEmailTaken(userBody.email)) { throw new ApiError(httpStatus.BAD_REQUEST, 'Email already taken'); } return User.create(userBody); }; /** * Insert multiple users into the database. * @param {Array<Object>} users - An array of user data to insert. * @returns {Promise<Object>} An object containing inserted and failed users. */ const bulkInsertUsers = async (users) => { const failed = []; const inserted = []; const emails = users.map((user) => user.email); const existingUsers = await User.find({ email: { $in: emails } }); const existingEmails = new Set(existingUsers.map((user) => user.email)); const newUsers = []; users.forEach((user) => { if (existingEmails.has(user.email)) { failed.push({ email: user.email, reason: 'Email already taken' }); } else { newUsers.push(user); } }); //! ---> Password is not hashed and schema is not validated if (newUsers.length > 0) { try { const insertedUsers = await User.insertMany(newUsers); insertedUsers.forEach((user) => inserted.push({ email: user.email })); } catch (error) { newUsers.forEach((user) => { failed.push({ email: user.email, reason: error.message }); }); } } return { inserted, failed }; }; /** * Query users with filtering and pagination options. * @param {Object} filter - The filter criteria for querying users. * @param {Object} options - The pagination options. * @returns {Promise<Array<User>>} A paginated list of users. */ const queryUsers = async (filter, options) => { const users = await User.paginate(filter, options); return users; }; /** * Get a user by their ID. * @param {string} id - The ID of the user to retrieve. * @returns {Promise<User>} The user object. * @throws {ApiError} If the user is not found. */ const getUserById = async (id) => { const user = await User.findById(id); if (!user) { throw new ApiError(httpStatus.NOT_FOUND, 'User not found'); } return user; }; /** * Get a user by their email address. * @param {string} email - The email of the user to retrieve. * @returns {Promise<User|null>} The user object or null if not found. */ const getUserByEmail = async (email) => { return User.findOne({ email }); }; /** * Update a user's details by their ID. * @param {string} userId - The ID of the user to update. * @param {Object} updateBody - The updated user data. * @returns {Promise<User>} The updated user object. * @throws {ApiError} If the email is already taken. */ const updateUserById = async (userId, updateBody) => { const user = await getUserById(userId); if (updateBody.email && (await User.isEmailTaken(updateBody.email, userId))) { throw new ApiError(httpStatus.BAD_REQUEST, 'Email already taken'); } Object.assign(user, updateBody); await user.save(); return user; }; /** * Change a user's password. * @param {string} userId - The ID of the user. * @param {Object} requestBody - The request body containing old and new passwords. * @returns {Promise<User>} The updated user object. * @throws {ApiError} If the old password is incorrect. */ const changePassword = async (userId, requestBody) => { const { oldPassword, newPassword } = requestBody; const user = await getUserById(userId); if (!(await user.isPasswordMatch(oldPassword))) { throw new ApiError(httpStatus.UNAUTHORIZED, 'Incorrect password'); } const updatedUser = await updateUserById(userId, { password: newPassword }); return updatedUser; }; /** * Delete a user by their ID. * @param {string} userId - The ID of the user to delete. * @returns {Promise<User>} The deleted user object. */ const deleteUserById = async (userId) => { const user = await getUserById(userId); await user.deleteOne({ _id: userId }); return user; }; module.exports = { createUser, bulkInsertUsers, queryUsers, getUserById, getUserByEmail, updateUserById, changePassword, deleteUserById, };