import dayjs from 'dayjs' ; import { QueryResponse } from 'dynamoose/dist/DocumentRetriever' ; import { ModelType } from 'dynamoose/dist/General' ; import { v4 as uuidv4 } from 'uuid' ; import { User as UserModel } from '../dynamo/schemas/usersSchema' ; import { IUserRepo } from '../../domain/user/IUserRepo' ; import User from '../../domain/user/user' ; import { PersistedUserData , ToBePersistedUserData } from './declarations' ; export class UserDynamoRepo implements IUserRepo { constructor ( private readonly userModel ) { } return public nextIdentity ( ) { return uuidv4 ( ) ; } returns { Promise < User [ ] > } public async all ( ) { return ( await this . userModel . scan ( ) . all ( ) . exec ( ) as QueryResponse < UserModel > ) . map ( ( userModel ) => new User ( userModel ) ) ; } param { string } userId returns { Promise < User | null > } public async findById ( userId ) { const userData = await this . userModel . get ( userId ) ; return userData && new User ( userData ) ; } param { string } email returns { Promise < User | null > } public async findByEmail ( email ) { const userRecord = await this . userModel . query ( 'email' ) . eq ( email ) . using ( 'index_email' ) . exec ( ) as QueryResponse < UserModel > ; return userRecord . length > 0 ? new User ( userRecord [ 0 ] ) : null ; } param { string } username returns { Promise < User | null > } public async findByUsername ( username ) { const userRecord = await this . userModel . query ( 'username' ) . eq ( username ) . using ( 'index_username' ) . exec ( ) as QueryResponse < UserModel > ; return userRecord . length > 0 ? new User ( userRecord [ 0 ] ) : null ; } return { Promise < number > } public async count ( ) { return ( await this . userModel . scan ( ) . all ( ) . count ( ) . exec ( ) ) . count as number ; } param { User } user returns { Promise < User > } public async persist ( user ) { const dataToBePersisted = this . getDataToBePersisted ( user ) ; if ( user . createdAt ) { const updatedUser = await this . userModel . update ( { _id : user . _id } , dataToBePersisted ) ; user . updateDates ( dayjs ( updatedUser . updatedAt ) ) ; } else { const createdUser = await this . userModel . create ( dataToBePersisted ) ; user . updateDates ( dayjs ( createdUser . updatedAt ) ) ; } return user ; } private getDataToBePersisted ( user ) { return { _id : user . _id , email : user . email , ... ( user . username && { username : user . username } ) , } ; } } export default ( userModel ) : UserDynamoRepo => { return new UserDynamoRepo ( userModel ) ; } ;