UNPKG

nhb-express

Version:

Minimal Express + TypeScript scaffolder with modular structure and flexible stack choices.

132 lines (117 loc) 3.03 kB
import { db } from '#/drizzle'; import { users } from '#/drizzle/schema/users'; import { ErrorWithStatus } from '@/errors/ErrorWithStatus'; import type { TPlainUser, UpdateUser } from '@/modules/user/user.types'; import { findUserByEmail, userCols } from '@/modules/user/user.utils'; import type { TEmail, TQueries } from '@/types'; import { eq, ilike, or, type SQL } from 'drizzle-orm'; import { isNotEmptyObject, isString, isValidObject, pickFields, sanitizeData, } from 'nhb-toolbox'; import { STATUS_CODES } from 'nhb-toolbox/constants'; class UserServices { /** * * Get all users from database. * @param query Optional query parameters to pass. * @returns All users that matched the query as an array. */ async getAllUsersFromDB(query?: TQueries<TPlainUser>) { const queries = pickFields(query!, [ 'first_name', 'last_name', 'email', 'role', 'user_name', ]); const filters: SQL[] = isValidObject(queries) ? Object.entries(sanitizeData(queries, { ignoreNullish: true })).map( ([key, value]) => { if (isString(value)) { return ilike(users[key as keyof TPlainUser], `%${value}%`); } return eq(users[key as keyof TPlainUser], value!); } ) : []; return await db .select(userCols) .from(users) .orderBy(users.id) .where(or(...filters)); } /** * * Retrieve a user from DB. * @param id ID of user in integer form. * @returns The matched user against the provided id. */ async getUserByIdFromDB(id: number) { const user = await db.query.users.findFirst({ where: eq(users.id, id), columns: { password: false }, }); if (!user) { throw new ErrorWithStatus( 'Not Found Error', `User not found with id ${id}!`, STATUS_CODES.NOT_FOUND, 'GET users/:id' ); } return user; } /** * * Delete a user from DB. * @param id ID of the user to delete. * @returns Deleted user's id as `{ deleted_id: number }` */ async deleteUserByIdFromDB(id: number) { const [res] = await db .delete(users) .where(eq(users.id, id)) .returning({ deleted_id: users.id }); if (!res) { throw new ErrorWithStatus( 'Delete Error', `Cannot delete user with id ${id}!`, STATUS_CODES.NOT_FOUND, 'DELETE users/:id' ); } return res; } /** * * Update a user in DB by id. * @param id ID to find user from DB. * @param payload Fields to update in user. */ async updateUserInDB(id: number, payload: UpdateUser) { if (!isNotEmptyObject(payload)) { throw new ErrorWithStatus( 'Empty Payload', `Your payload is empty for user with id ${id}!`, STATUS_CODES.BAD_REQUEST, 'PATCH users/:id' ); } const [res] = await db .update(users) .set(payload) .where(eq(users.id, id)) .returning(userCols); if (!res) { throw new ErrorWithStatus( 'Update Error', `Cannot update user with id ${id}!`, STATUS_CODES.NOT_FOUND, 'PATCH users/:id' ); } return res; } } export const userServices = new UserServices();