From dce2003eb7cd66671abe17f5dbdbf33cef710ae7 Mon Sep 17 00:00:00 2001 From: ognjenkurtic Date: Sat, 20 Jan 2024 22:50:45 +0100 Subject: [PATCH] Implement generic map method for prisma mapping --- .../agents/bpiMessagesStorage.agent.ts | 15 +-- .../agents/bpiSubjectAccountsStorage.agent.ts | 14 +- .../agents/bpiSubjectsStorage.agent.ts | 24 +--- .../agents/bpiAccountsStorage.agent.ts | 16 +-- .../agents/transactionStorage.agent.ts | 24 +--- .../agents/workflowsStorage.agent.ts | 12 +- .../agents/workgroupStorage.agent.ts | 8 +- .../agents/workstepsStorage.agent.ts | 12 +- .../bri-3/src/shared/prisma/prisma.mapper.ts | 124 +----------------- 9 files changed, 44 insertions(+), 205 deletions(-) diff --git a/examples/bri-3/src/bri/communication/agents/bpiMessagesStorage.agent.ts b/examples/bri-3/src/bri/communication/agents/bpiMessagesStorage.agent.ts index c46d4012f..1c637359b 100644 --- a/examples/bri-3/src/bri/communication/agents/bpiMessagesStorage.agent.ts +++ b/examples/bri-3/src/bri/communication/agents/bpiMessagesStorage.agent.ts @@ -22,8 +22,7 @@ export class BpiMessageStorageAgent { return undefined; } - const bpiMessage = - this.mapper.mapBpiMessagePrismaModelToDomainObject(bpiMessageModel); + const bpiMessage = this.mapper.map(bpiMessageModel, BpiMessage); bpiMessage.updateContent( await this.encryptionService.decrypt(bpiMessage.content), ); @@ -35,9 +34,7 @@ export class BpiMessageStorageAgent { const bpiMessageModels = await this.prisma.message.findMany(); return bpiMessageModels.map((bpiMessageModel) => { - return this.mapper.mapBpiMessagePrismaModelToDomainObject( - bpiMessageModel, - ); + return this.mapper.map(bpiMessageModel, BpiMessage); }); } @@ -54,9 +51,7 @@ export class BpiMessageStorageAgent { include: { fromBpiSubject: true, toBpiSubject: true }, }); - return this.mapper.mapBpiMessagePrismaModelToDomainObject( - newBpiMessageModel, - ); + return this.mapper.map(newBpiMessageModel, BpiMessage); } async updateBpiMessage(bpiMessage: BpiMessage): Promise { @@ -73,9 +68,7 @@ export class BpiMessageStorageAgent { include: { fromBpiSubject: true, toBpiSubject: true }, }); - return this.mapper.mapBpiMessagePrismaModelToDomainObject( - updatedBpiMessageModel, - ); + return this.mapper.map(updatedBpiMessageModel, BpiMessage); } async deleteBpiMessage(bpiMessage: BpiMessage): Promise { diff --git a/examples/bri-3/src/bri/identity/bpiSubjectAccounts/agents/bpiSubjectAccountsStorage.agent.ts b/examples/bri-3/src/bri/identity/bpiSubjectAccounts/agents/bpiSubjectAccountsStorage.agent.ts index 0b5003b0e..db53c47fe 100644 --- a/examples/bri-3/src/bri/identity/bpiSubjectAccounts/agents/bpiSubjectAccountsStorage.agent.ts +++ b/examples/bri-3/src/bri/identity/bpiSubjectAccounts/agents/bpiSubjectAccountsStorage.agent.ts @@ -26,9 +26,7 @@ export class BpiSubjectAccountStorageAgent { return undefined; } - return this.mapper.mapBpiSubjectAccountPrismaModelToDomainObject( - bpiSubjectAccountModel, - ); + return this.mapper.map(bpiSubjectAccountModel, BpiSubjectAccount); } async getAllBpiSubjectAccounts(): Promise { @@ -37,7 +35,7 @@ export class BpiSubjectAccountStorageAgent { include: { ownerBpiSubject: true, creatorBpiSubject: true }, }); return bpiSubjectAccountsModels.map((bp) => { - return this.mapper.mapBpiSubjectAccountPrismaModelToDomainObject(bp); + return this.mapper.map(bp, BpiSubjectAccount); }); } @@ -57,9 +55,7 @@ export class BpiSubjectAccountStorageAgent { include: { ownerBpiSubject: true, creatorBpiSubject: true }, }); - return this.mapper.mapBpiSubjectAccountPrismaModelToDomainObject( - newBpiSubjectAccountModel, - ); + return this.mapper.map(newBpiSubjectAccountModel, BpiSubjectAccount); } async updateBpiSubjectAccount( @@ -79,9 +75,7 @@ export class BpiSubjectAccountStorageAgent { include: { ownerBpiSubject: true, creatorBpiSubject: true }, }); - return this.mapper.mapBpiSubjectAccountPrismaModelToDomainObject( - newBpiSubjectAccountModel, - ); + return this.mapper.map(newBpiSubjectAccountModel, BpiSubjectAccount); } async deleteBpiSubjectAccount( diff --git a/examples/bri-3/src/bri/identity/bpiSubjects/agents/bpiSubjectsStorage.agent.ts b/examples/bri-3/src/bri/identity/bpiSubjects/agents/bpiSubjectsStorage.agent.ts index b34cd9b93..36ae817c6 100644 --- a/examples/bri-3/src/bri/identity/bpiSubjects/agents/bpiSubjectsStorage.agent.ts +++ b/examples/bri-3/src/bri/identity/bpiSubjects/agents/bpiSubjectsStorage.agent.ts @@ -29,15 +29,13 @@ export class BpiSubjectStorageAgent extends PrismaService { return undefined; } - return this.mapper.mapBpiSubjectPrismaModelToDomainObject(bpiSubjectModel); + return this.mapper.map(bpiSubjectModel, BpiSubject); } async getAllBpiSubjects(): Promise { const bpiSubjectModels = await this.prisma.bpiSubject.findMany(); return bpiSubjectModels.map((bpiSubjectModel) => { - return this.mapper.mapBpiSubjectPrismaModelToDomainObject( - bpiSubjectModel, - ); + return this.mapper.map(bpiSubjectModel, BpiSubject); }); } @@ -49,9 +47,7 @@ export class BpiSubjectStorageAgent extends PrismaService { include: { roles: true }, }); return bpiSubjectModels.map((bpiSubjectModel) => { - return this.mapper.mapBpiSubjectPrismaModelToDomainObject( - bpiSubjectModel, - ); + return this.mapper.map(bpiSubjectModel, BpiSubject); }); } @@ -65,9 +61,7 @@ export class BpiSubjectStorageAgent extends PrismaService { if (!bpiSubjectRole) { throw new NotFoundException(NOT_FOUND_ERR_MESSAGE); } - return this.mapper.mapBpiSubjectRolePrismaModelToDomainObject( - bpiSubjectRole, - ); + return this.mapper.map(bpiSubjectRole, BpiSubjectRole); } async storeNewBpiSubject(bpiSubject: BpiSubject): Promise { @@ -85,9 +79,7 @@ export class BpiSubjectStorageAgent extends PrismaService { }, }); - return this.mapper.mapBpiSubjectPrismaModelToDomainObject( - newBpiSubjectModel, - ); + return this.mapper.map(newBpiSubjectModel, BpiSubject); } async updateBpiSubject(bpiSubject: BpiSubject): Promise { @@ -104,9 +96,7 @@ export class BpiSubjectStorageAgent extends PrismaService { }, }, }); - return this.mapper.mapBpiSubjectPrismaModelToDomainObject( - updatedBpiSubjectModel, - ); + return this.mapper.map(updatedBpiSubjectModel, BpiSubject); } async deleteBpiSubject(bpiSubject: BpiSubject): Promise { @@ -127,6 +117,6 @@ export class BpiSubjectStorageAgent extends PrismaService { if (!bpiSubjectModel) { throw new NotFoundException(NOT_FOUND_ERR_MESSAGE); } - return this.mapper.mapBpiSubjectPrismaModelToDomainObject(bpiSubjectModel); + return this.mapper.map(bpiSubjectModel, BpiSubject); } } diff --git a/examples/bri-3/src/bri/state/bpiAccounts/agents/bpiAccountsStorage.agent.ts b/examples/bri-3/src/bri/state/bpiAccounts/agents/bpiAccountsStorage.agent.ts index da9036cc3..47ca5d6ef 100644 --- a/examples/bri-3/src/bri/state/bpiAccounts/agents/bpiAccountsStorage.agent.ts +++ b/examples/bri-3/src/bri/state/bpiAccounts/agents/bpiAccountsStorage.agent.ts @@ -34,7 +34,7 @@ export class BpiAccountStorageAgent { throw new NotFoundException(NOT_FOUND_ERR_MESSAGE); } - return this.mapper.mapBpiAccountPrismaModelToDomainObject(bpiAccountModel); + return this.mapper.map(bpiAccountModel, BpiAccount); } async getAllBpiAccounts(): Promise { @@ -50,7 +50,7 @@ export class BpiAccountStorageAgent { }); return bpiAccountModels.map((bp) => { - return this.mapper.mapBpiAccountPrismaModelToDomainObject(bp); + return this.mapper.map(bp, BpiAccount); }); } @@ -87,9 +87,7 @@ export class BpiAccountStorageAgent { }, }); - return this.mapper.mapBpiAccountPrismaModelToDomainObject( - newBpiAccountModel, - ); + return this.mapper.map(newBpiAccountModel, BpiAccount); } async updateBpiAccount(bpiAccount: BpiAccount): Promise { @@ -103,9 +101,7 @@ export class BpiAccountStorageAgent { }, }); - return this.mapper.mapBpiAccountPrismaModelToDomainObject( - newBpiAccountModel, - ); + return this.mapper.map(newBpiAccountModel, BpiAccount); } async deleteBpiAccount(bpiAccount: BpiAccount): Promise { @@ -144,8 +140,6 @@ export class BpiAccountStorageAgent { return undefined; } - return this.mapper.mapBpiAccountStateTreeLeafValuePrismaModelToDomainObject( - stateLeafValues, - ); + return this.mapper.map(stateLeafValues, StateTreeLeafValueContent); } } diff --git a/examples/bri-3/src/bri/transactions/agents/transactionStorage.agent.ts b/examples/bri-3/src/bri/transactions/agents/transactionStorage.agent.ts index f21cc92e2..4fb594268 100644 --- a/examples/bri-3/src/bri/transactions/agents/transactionStorage.agent.ts +++ b/examples/bri-3/src/bri/transactions/agents/transactionStorage.agent.ts @@ -17,9 +17,7 @@ export class TransactionStorageAgent { include: { fromBpiSubjectAccount: true, toBpiSubjectAccount: true }, }); return transactionModels.map((transactionModel) => { - return this.mapper.mapTransactionPrismaModelToDomainObject( - transactionModel, - ); + return this.mapper.map(transactionModel, Transaction); }); } @@ -46,9 +44,7 @@ export class TransactionStorageAgent { throw new NotFoundException(NOT_FOUND_ERR_MESSAGE); } - return this.mapper.mapTransactionPrismaModelToDomainObject( - transactionModel, - ); + return this.mapper.map(transactionModel, Transaction); } async getTopNTransactionsByStatus( @@ -75,9 +71,7 @@ export class TransactionStorageAgent { }); return transactionModels.map((transactionModel) => { - return this.mapper.mapTransactionPrismaModelToDomainObject( - transactionModel, - ); + return this.mapper.map(transactionModel, Transaction); }); } @@ -110,9 +104,7 @@ export class TransactionStorageAgent { }, }); - return this.mapper.mapTransactionPrismaModelToDomainObject( - newTransactionModel, - ); + return this.mapper.map(newTransactionModel, Transaction); } async updateTransaction(transaction: Transaction): Promise { @@ -124,9 +116,7 @@ export class TransactionStorageAgent { }, }); - return this.mapper.mapTransactionPrismaModelToDomainObject( - updatedTransactionModel, - ); + return this.mapper.map(updatedTransactionModel, Transaction); } async updateTransactionStatus( @@ -141,9 +131,7 @@ export class TransactionStorageAgent { }, }); - return this.mapper.mapTransactionPrismaModelToDomainObject( - updatedTransaction, - ); + return this.mapper.map(updatedTransaction, Transaction); } async deleteTransaction(transaction: Transaction): Promise { diff --git a/examples/bri-3/src/bri/workgroup/workflows/agents/workflowsStorage.agent.ts b/examples/bri-3/src/bri/workgroup/workflows/agents/workflowsStorage.agent.ts index c67715eca..9e6ace341 100644 --- a/examples/bri-3/src/bri/workgroup/workflows/agents/workflowsStorage.agent.ts +++ b/examples/bri-3/src/bri/workgroup/workflows/agents/workflowsStorage.agent.ts @@ -24,7 +24,7 @@ export class WorkflowStorageAgent { throw new NotFoundException(WORKFLOW_NOT_FOUND_ERR_MESSAGE); } - return this.mapper.mapWorkflowPrismaModelToDomainObject(workflowModel); + return this.mapper.map(workflowModel, Workflow); } async getAllWorkflows(): Promise { @@ -32,7 +32,7 @@ export class WorkflowStorageAgent { include: { worksteps: true }, }); return workflowModels.map((w) => { - return this.mapper.mapWorkflowPrismaModelToDomainObject(w); + return this.mapper.map(w, Workflow); }); } @@ -44,7 +44,7 @@ export class WorkflowStorageAgent { include: { worksteps: true }, }); return workflowModels.map((w) => { - return this.mapper.mapWorkflowPrismaModelToDomainObject(w); + return this.mapper.map(w, Workflow); }); } @@ -71,7 +71,7 @@ export class WorkflowStorageAgent { }, }); - return this.mapper.mapWorkflowPrismaModelToDomainObject(newWorkflowModel); + return this.mapper.map(newWorkflowModel, Workflow); } async updateWorkflow(workflow: Workflow): Promise { @@ -95,9 +95,7 @@ export class WorkflowStorageAgent { }, }); - return this.mapper.mapWorkflowPrismaModelToDomainObject( - updatedWorkflowModel, - ); + return this.mapper.map(updatedWorkflowModel, Workflow); } async deleteWorkflow(workflow: Workflow): Promise { diff --git a/examples/bri-3/src/bri/workgroup/workgroups/agents/workgroupStorage.agent.ts b/examples/bri-3/src/bri/workgroup/workgroups/agents/workgroupStorage.agent.ts index e0d138747..f04df5e0e 100644 --- a/examples/bri-3/src/bri/workgroup/workgroups/agents/workgroupStorage.agent.ts +++ b/examples/bri-3/src/bri/workgroup/workgroups/agents/workgroupStorage.agent.ts @@ -28,7 +28,7 @@ export class WorkgroupStorageAgent { throw new NotFoundException(WORKGROUP_NOT_FOUND_ERR_MESSAGE); } - return this.mapper.mapWorkgroupPrismaModelToDomainObject(workgroupModel); + return this.mapper.map(workgroupModel, Workgroup); } async createNewWorkgroup(workgroup: Workgroup): Promise { @@ -67,7 +67,7 @@ export class WorkgroupStorageAgent { }, }); - return this.mapper.mapWorkgroupPrismaModelToDomainObject(newWorkgroupModel); + return this.mapper.map(newWorkgroupModel, Workgroup); } async updateWorkgroup(workgroup: Workgroup): Promise { @@ -105,9 +105,7 @@ export class WorkgroupStorageAgent { }, }); - return this.mapper.mapWorkgroupPrismaModelToDomainObject( - updatedWorkgroupModel, - ); + return this.mapper.map(updatedWorkgroupModel, Workgroup); } async deleteWorkgroup(workgroup: Workgroup): Promise { diff --git a/examples/bri-3/src/bri/workgroup/worksteps/agents/workstepsStorage.agent.ts b/examples/bri-3/src/bri/workgroup/worksteps/agents/workstepsStorage.agent.ts index 25c1947fc..a095c1239 100644 --- a/examples/bri-3/src/bri/workgroup/worksteps/agents/workstepsStorage.agent.ts +++ b/examples/bri-3/src/bri/workgroup/worksteps/agents/workstepsStorage.agent.ts @@ -23,13 +23,13 @@ export class WorkstepStorageAgent { throw new NotFoundException(NOT_FOUND_ERR_MESSAGE); } - return this.mapper.mapWorkstepPrismaModelToDomainObject(workstepModel); + return this.mapper.map(workstepModel, Workstep); } async getAllWorksteps(): Promise { const workstepModels = await this.prisma.workstep.findMany(); return workstepModels.map((workstepModel) => { - return this.mapper.mapWorkstepPrismaModelToDomainObject(workstepModel); + return this.mapper.map(workstepModel, Workstep); }); } @@ -40,7 +40,7 @@ export class WorkstepStorageAgent { }, }); return workstepModels.map((w) => { - return this.mapper.mapWorkstepPrismaModelToDomainObject(w); + return this.mapper.map(w, Workstep); }); } @@ -48,7 +48,7 @@ export class WorkstepStorageAgent { const newWorkstepModel = await this.prisma.workstep.create({ data: workstep, }); - return this.mapper.mapWorkstepPrismaModelToDomainObject(newWorkstepModel); + return this.mapper.map(newWorkstepModel, Workstep); } async updateWorkstep(workstep: Workstep): Promise { @@ -56,9 +56,7 @@ export class WorkstepStorageAgent { where: { id: workstep.id }, data: workstep, }); - return this.mapper.mapWorkstepPrismaModelToDomainObject( - updatedWorkstepModel, - ); + return this.mapper.map(updatedWorkstepModel, Workstep); } async deleteWorkstep(workstep: Workstep): Promise { diff --git a/examples/bri-3/src/shared/prisma/prisma.mapper.ts b/examples/bri-3/src/shared/prisma/prisma.mapper.ts index ba978ea36..e250c882b 100644 --- a/examples/bri-3/src/shared/prisma/prisma.mapper.ts +++ b/examples/bri-3/src/shared/prisma/prisma.mapper.ts @@ -1,36 +1,14 @@ import { Injectable } from '@nestjs/common'; -import { - BpiAccount as BpiAccountPrismaModel, - BpiAccountStateTreeLeafValue as BpiAccountStateTreeLeafValuePrismaModel, - BpiMerkleTree as BpiMerkleTreePrismaModel, - Message as BpiMessagePrismaModel, - BpiSubjectAccount as BpiSubjectAccountPrismaModel, - BpiSubject as BpiSubjectPrismaModel, - BpiSubjectRole as BpiSubjectRolePrismaModel, - Transaction as TransactionPrismaModel, - Workflow as WorkflowPrismaModel, - Workgroup as WorkgroupPrismaModel, - Workstep as WorkstepPrismaModel, -} from '@prisma/client'; -import { BpiMessage } from '../../bri/communication/models/bpiMessage'; -import { BpiSubjectAccount } from '../../bri/identity/bpiSubjectAccounts/models/bpiSubjectAccount'; -import { BpiSubject } from '../../bri/identity/bpiSubjects/models/bpiSubject'; -import { BpiSubjectRole } from '../../bri/identity/bpiSubjects/models/bpiSubjectRole'; +import { BpiMerkleTree as BpiMerkleTreePrismaModel } from '@prisma/client'; import { BpiMerkleTree } from '../../bri/merkleTree/models/bpiMerkleTree'; -import { BpiAccount } from '../../bri/state/bpiAccounts/models/bpiAccount'; -import { StateTreeLeafValueContent } from '../../bri/state/models/stateTreeLeafValueContent'; -import { Transaction } from '../../bri/transactions/models/transaction'; -import { Workflow } from '../../bri/workgroup/workflows/models/workflow'; -import { Workgroup } from '../../bri/workgroup/workgroups/models/workgroup'; -import { Workstep } from '../../bri/workgroup/worksteps/models/workstep'; import { MerkleTreeService } from '../../bri/merkleTree/services/merkleTree.service'; import MerkleTree from 'merkletreejs'; -// We do mapping from prisma models to domain objects using simple Object.assign +// We do mapping from prisma models to domain objects using simple Object.assign in a generic Map method below, // since automapper is not happy working with types, which is how Prisma generates database entities. // For these mappings to work, the convention is that the domain objects have the same properties as the // prisma models. In case there is a need to do something custom during mapping, it can be implemented -// in the appropriate method below. +// in a separate method below. interface IConstructor { new (...args: any[]): T; @@ -40,100 +18,8 @@ interface IConstructor { export class PrismaMapper { constructor(private readonly merkleTreeService: MerkleTreeService) {} - public mapBpiSubjectPrismaModelToDomainObject( - source: BpiSubjectPrismaModel, - ): BpiSubject { - const target = this.activator(BpiSubject); - - Object.assign(target, source); - - return target; - } - - public mapBpiSubjectRolePrismaModelToDomainObject( - source: BpiSubjectRolePrismaModel, - ): BpiSubjectRole { - const target = this.activator(BpiSubjectRole); - - Object.assign(target, source); - - return target; - } - - public mapBpiMessagePrismaModelToDomainObject( - source: BpiMessagePrismaModel, - ): BpiMessage { - const target = this.activator(BpiMessage); - - Object.assign(target, source); - - return target; - } - - public mapBpiAccountPrismaModelToDomainObject( - source: BpiAccountPrismaModel, - ): BpiAccount { - const target = this.activator(BpiAccount); - - Object.assign(target, source); - - return target; - } - - public mapBpiAccountStateTreeLeafValuePrismaModelToDomainObject( - source: BpiAccountStateTreeLeafValuePrismaModel, - ): StateTreeLeafValueContent { - const target = this.activator(StateTreeLeafValueContent); - - Object.assign(target, source); - - return target; - } - - public mapBpiSubjectAccountPrismaModelToDomainObject( - source: BpiSubjectAccountPrismaModel, - ): BpiSubjectAccount { - const target = this.activator(BpiSubjectAccount); - - Object.assign(target, source); - - return target; - } - - public mapTransactionPrismaModelToDomainObject( - source: TransactionPrismaModel, - ): Transaction { - const target = this.activator(Transaction); - - Object.assign(target, source); - - return target; - } - - public mapWorkflowPrismaModelToDomainObject( - source: WorkflowPrismaModel, - ): Workflow { - const target = this.activator(Workflow); - - Object.assign(target, source); - - return target; - } - - public mapWorkgroupPrismaModelToDomainObject( - source: WorkgroupPrismaModel, - ): Workgroup { - const target = this.activator(Workgroup); - - Object.assign(target, source); - - return target; - } - - public mapWorkstepPrismaModelToDomainObject( - source: WorkstepPrismaModel, - ): Workstep { - const target = this.activator(Workstep); + public map(source: any, targetType: IConstructor): T { + const target = this.activator(targetType); Object.assign(target, source);