import { Injectable } from '@nestjs/common' ; import { CommandBus } from '@nestjs/cqrs' ; import { plainToClass } from 'class-transformer' ; import type { FindConditions } from 'typeorm' ; import { Transactional } from 'typeorm-transactional-cls-hooked' ; import type { PageDto } from '../../common/dto/page.dto' ; import { FileNotImageException , UserNotFoundException } from '../../exceptions' ; import { IFile } from '../../interfaces' ; import { AwsS3Service } from '../../shared/services/aws-s3.service' ; import { ValidatorService } from '../../shared/services/validator.service' ; import type { Optional } from '../../types' ; import { UserRegisterDto } from '../auth/dto/UserRegisterDto' ; import { CreateSettingsCommand } from './commands/create-settings.command' ; import { CreateSettingsDto } from './dtos/create-settings.dto' ; import type { UserDto } from './dtos/user.dto' ; import type { UsersPageOptionsDto } from './dtos/users-page-options.dto' ; import type { UserEntity } from './user.entity' ; import { UserRepository } from './user.repository' ; import type { UserSettingsEntity } from './user-settings.entity' ; @ Injectable ( ) export class UserService { constructor ( private userRepository , private validatorService , private awsS3Service , private commandBus ) { } /**
     * Find single user
     */ findOne ( findData ) { return this . userRepository . findOne ( findData ) ; } async findByUsernameOrEmail ( options ) { const queryBuilder = this . userRepository . createQueryBuilder ( 'user' ) ; if ( options . email ) { queryBuilder . orWhere ( 'user.email = :email' , { email : options . email , } ) ; } if ( options . username ) { queryBuilder . orWhere ( 'user.username = :username' , { username : options . username , } ) ; } return queryBuilder . getOne ( ) ; } @ Transactional ( ) async createUser ( userRegisterDto , file ) { const user = this . userRepository . create ( userRegisterDto ) ; if ( file && ! this . validatorService . isImage ( file . mimetype ) ) { throw new FileNotImageException ( ) ; } if ( file ) { user . avatar = await this . awsS3Service . uploadImage ( file ) ; } await this . userRepository . save ( user ) ; user . settings = await this . createSettings ( user . id , plainToClass ( CreateSettingsDto , { isEmailVerified : false , isPhoneVerified : false , } ) ) ; return user ; } async getUsers ( pageOptionsDto ) { const queryBuilder = this . userRepository . createQueryBuilder ( 'user' ) ; const [ items , pageMetaDto ] = await queryBuilder . paginate ( pageOptionsDto ) ; return items . toPageDto ( pageMetaDto ) ; } async getUser ( userId ) { const queryBuilder = this . userRepository . createQueryBuilder ( 'user' ) ; queryBuilder . where ( 'user.id = :userId' , { userId } ) ; const userEntity = await queryBuilder . getOne ( ) ; if ( ! userEntity ) { throw new UserNotFoundException ( ) ; } return userEntity . toDto ( ) ; } async createSettings ( userId , createSettingsDto ) { return this . commandBus . execute < CreateSettingsCommand , UserSettingsEntity > ( new CreateSettingsCommand ( userId , createSettingsDto ) ) ; } }