From 291e6567577bec1a462b6b3cd8885f60eef42e49 Mon Sep 17 00:00:00 2001 From: Supan Adit Pratama Date: Sun, 10 Nov 2024 10:22:26 +0700 Subject: [PATCH] wip: process for typeorm --- libs/typeorm/src/config.module-definition.ts | 7 ---- libs/typeorm/src/constants.ts | 1 + .../config-module-options.interface.ts | 7 ++-- libs/typeorm/src/processes/create.process.ts | 13 +++++++ libs/typeorm/src/processes/delete.process.ts | 14 ++++++++ libs/typeorm/src/processes/index.ts | 7 ++++ libs/typeorm/src/processes/list.process.ts | 8 +++++ .../src/processes/pagination.process.ts | 20 +++++++++++ libs/typeorm/src/processes/read.process.ts | 13 +++++++ libs/typeorm/src/processes/typeorm.process.ts | 16 +++++++++ libs/typeorm/src/processes/update.process.ts | 17 +++++++++ libs/typeorm/src/typeorm.module.ts | 34 +++++++++++------- libs/typeorm/src/typeorm.service.ts | 6 +++- src/app.module.ts | 36 ++----------------- .../{ => prisma}/custom/custom.controller.ts | 0 .../{ => prisma}/custom/custom.module.ts | 0 .../custom/domain/custom.list.process.ts | 0 .../custom/domain/custom.read.process.ts | 1 + .../{ => prisma}/simple/simple.controller.ts | 0 .../{ => prisma}/simple/simple.module.ts | 0 20 files changed, 144 insertions(+), 56 deletions(-) delete mode 100644 libs/typeorm/src/config.module-definition.ts create mode 100644 libs/typeorm/src/processes/create.process.ts create mode 100644 libs/typeorm/src/processes/delete.process.ts create mode 100644 libs/typeorm/src/processes/index.ts create mode 100644 libs/typeorm/src/processes/list.process.ts create mode 100644 libs/typeorm/src/processes/pagination.process.ts create mode 100644 libs/typeorm/src/processes/read.process.ts create mode 100644 libs/typeorm/src/processes/typeorm.process.ts create mode 100644 libs/typeorm/src/processes/update.process.ts rename src/example/{ => prisma}/custom/custom.controller.ts (100%) rename src/example/{ => prisma}/custom/custom.module.ts (100%) rename src/example/{ => prisma}/custom/domain/custom.list.process.ts (100%) rename src/example/{ => prisma}/custom/domain/custom.read.process.ts (99%) rename src/example/{ => prisma}/simple/simple.controller.ts (100%) rename src/example/{ => prisma}/simple/simple.module.ts (100%) diff --git a/libs/typeorm/src/config.module-definition.ts b/libs/typeorm/src/config.module-definition.ts deleted file mode 100644 index d146d7d..0000000 --- a/libs/typeorm/src/config.module-definition.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ConfigurableModuleBuilder } from '@nestjs/common'; -import { TypeORMModuleOptions } from './interfaces'; - -export const { ConfigurableModuleClass } = - new ConfigurableModuleBuilder() - .setClassMethodName('forRoot') - .build(); diff --git a/libs/typeorm/src/constants.ts b/libs/typeorm/src/constants.ts index f8b73de..7919416 100644 --- a/libs/typeorm/src/constants.ts +++ b/libs/typeorm/src/constants.ts @@ -1,2 +1,3 @@ export const TYPEORM_DATASOURCE = 'TYPEORM_DATASOURCE'; export const TYPEORM_REPOSITORY = 'TYPEORM_REPOSITORY'; +export const TYPEORM_WHERE_CLAUSE = 'TYPEORM_WHERE_CLAUSE'; diff --git a/libs/typeorm/src/interfaces/config-module-options.interface.ts b/libs/typeorm/src/interfaces/config-module-options.interface.ts index 3e6cc26..596fc01 100644 --- a/libs/typeorm/src/interfaces/config-module-options.interface.ts +++ b/libs/typeorm/src/interfaces/config-module-options.interface.ts @@ -1,5 +1,8 @@ -export interface TypeORMModuleOptions { - entity; +import { EntityTarget, FindOptionsWhere, ObjectLiteral } from "typeorm"; + +export interface TypeORMModuleOptions { + entity: EntityTarget; synchronize?: boolean; entities: string[]; + uniqueWhereClause: FindOptionsWhere; } diff --git a/libs/typeorm/src/processes/create.process.ts b/libs/typeorm/src/processes/create.process.ts new file mode 100644 index 0000000..116715d --- /dev/null +++ b/libs/typeorm/src/processes/create.process.ts @@ -0,0 +1,13 @@ +import { CreateProcess } from '@aditama-labs/nest-autocrud/skeleton'; +import { TypeORMProcess } from './typeorm.process'; + +export class TypeORMCreateProcess + extends TypeORMProcess + implements CreateProcess +{ + public payload; + + async process() { + this.result = await this.service.getRepository().save(this.payload); + } +} diff --git a/libs/typeorm/src/processes/delete.process.ts b/libs/typeorm/src/processes/delete.process.ts new file mode 100644 index 0000000..9efb4a9 --- /dev/null +++ b/libs/typeorm/src/processes/delete.process.ts @@ -0,0 +1,14 @@ +import { DeleteProcess } from '@aditama-labs/nest-autocrud/skeleton'; +import { TypeORMProcess } from './typeorm.process'; + +export class TypeORMDeleteProcess + extends TypeORMProcess + implements DeleteProcess +{ + public identityData; + public identityKey: string = 'id'; + + async process() { + this.result = await this.service.getRepository().delete(this.uniqueWhereClause); + } +} diff --git a/libs/typeorm/src/processes/index.ts b/libs/typeorm/src/processes/index.ts new file mode 100644 index 0000000..b574216 --- /dev/null +++ b/libs/typeorm/src/processes/index.ts @@ -0,0 +1,7 @@ +export * from './create.process'; +export * from './delete.process'; +export * from './list.process'; +export * from './pagination.process'; +export * from './read.process'; +export * from './update.process'; + diff --git a/libs/typeorm/src/processes/list.process.ts b/libs/typeorm/src/processes/list.process.ts new file mode 100644 index 0000000..f446c28 --- /dev/null +++ b/libs/typeorm/src/processes/list.process.ts @@ -0,0 +1,8 @@ +import { ListProcess } from '@aditama-labs/nest-autocrud/skeleton'; +import { TypeORMProcess } from './typeorm.process'; + +export class TypeORMListProcess extends TypeORMProcess implements ListProcess { + async process() { + this.result = await this.service.getRepository().find(); + } +} diff --git a/libs/typeorm/src/processes/pagination.process.ts b/libs/typeorm/src/processes/pagination.process.ts new file mode 100644 index 0000000..41ed610 --- /dev/null +++ b/libs/typeorm/src/processes/pagination.process.ts @@ -0,0 +1,20 @@ +import { PaginationProcess } from '@aditama-labs/nest-autocrud/skeleton'; +import { IPaginationParam } from '@aditama-labs/nest-autocrud/skeleton/src/interfaces/pagination-param.interface'; +import { TypeORMProcess } from './typeorm.process'; + +export class TypeORMPaginationProcess + extends TypeORMProcess + implements PaginationProcess +{ + params: IPaginationParam; + + async process() { + const { page, limit } = this.params; + const skip = (page - 1) * limit; + + this.result = await this.service.getRepository().find({ + skip, + take: limit, + }); + } +} diff --git a/libs/typeorm/src/processes/read.process.ts b/libs/typeorm/src/processes/read.process.ts new file mode 100644 index 0000000..aae49cf --- /dev/null +++ b/libs/typeorm/src/processes/read.process.ts @@ -0,0 +1,13 @@ +import { ReadProcess } from '@aditama-labs/nest-autocrud/skeleton'; +import { TypeORMProcess } from './typeorm.process'; + +export class TypeORMReadProcess extends TypeORMProcess implements ReadProcess { + public identityData; + public identityKey: string = 'id'; + + async process() { + this.result = await this.service.getRepository().findOne({ + where: this.uniqueWhereClause, + }); + } +} diff --git a/libs/typeorm/src/processes/typeorm.process.ts b/libs/typeorm/src/processes/typeorm.process.ts new file mode 100644 index 0000000..1536697 --- /dev/null +++ b/libs/typeorm/src/processes/typeorm.process.ts @@ -0,0 +1,16 @@ +import { DefaultProcess } from '@aditama-labs/nest-autocrud/skeleton'; +import { Inject, Injectable } from '@nestjs/common'; +import { TypeORMService } from '../typeorm.service'; +import { TYPEORM_WHERE_CLAUSE } from '../constants'; +import { FindOptionsWhere } from 'typeorm'; + +@Injectable() +export class TypeORMProcess extends DefaultProcess { + constructor( + public service: TypeORMService, + @Inject(TYPEORM_WHERE_CLAUSE) + public uniqueWhereClause: FindOptionsWhere, + ) { + super(); + } +} diff --git a/libs/typeorm/src/processes/update.process.ts b/libs/typeorm/src/processes/update.process.ts new file mode 100644 index 0000000..4eff20c --- /dev/null +++ b/libs/typeorm/src/processes/update.process.ts @@ -0,0 +1,17 @@ +import { UpdateProcess } from '@aditama-labs/nest-autocrud/skeleton'; +import { TypeORMProcess } from './typeorm.process'; + +export class TypeORMUpdateProcess + extends TypeORMProcess + implements UpdateProcess +{ + public identityData; + public identityKey: string = 'id'; + public payload; + + async process() { + this.result = await this.service + .getRepository() + .update(this.uniqueWhereClause, this.payload); + } +} diff --git a/libs/typeorm/src/typeorm.module.ts b/libs/typeorm/src/typeorm.module.ts index 29f7092..71b292d 100644 --- a/libs/typeorm/src/typeorm.module.ts +++ b/libs/typeorm/src/typeorm.module.ts @@ -1,9 +1,12 @@ import { DynamicModule, Module } from '@nestjs/common'; -import { TypeormService } from './typeorm.service'; +import { DataSource, ObjectLiteral } from 'typeorm'; +import { + TYPEORM_DATASOURCE, + TYPEORM_REPOSITORY, + TYPEORM_WHERE_CLAUSE, +} from './constants'; import { TypeORMModuleOptions } from './interfaces'; -import { ConfigurableModuleClass } from './config.module-definition'; -import { DataSource } from 'typeorm'; -import { TYPEORM_DATASOURCE, TYPEORM_REPOSITORY } from './constants'; +import { TypeORMService } from './typeorm.service'; const getDatabaseCredential = ( synchronize?: boolean, @@ -44,13 +47,13 @@ const getDatabaseCredential = ( }; }; -@Module({ - providers: [TypeormService], - exports: [TypeormService], -}) -export class TypeORMModule extends ConfigurableModuleClass { - static forRoot(options: TypeORMModuleOptions): DynamicModule { +@Module({}) +export class TypeORMModule { + static forRoot( + options: TypeORMModuleOptions, + ): DynamicModule { let providers = [ + TypeORMService, { provide: TYPEORM_DATASOURCE, useFactory: async () => { @@ -69,8 +72,15 @@ export class TypeORMModule extends ConfigurableModuleClass { ]; return { - ...super.forRoot(options), - providers, + module: TypeORMModule, + providers: [ + ...providers, + { + provide: TYPEORM_WHERE_CLAUSE, + useValue: options.uniqueWhereClause, + }, + ], + exports: providers, }; } } diff --git a/libs/typeorm/src/typeorm.service.ts b/libs/typeorm/src/typeorm.service.ts index 405bcd6..bc9ca35 100644 --- a/libs/typeorm/src/typeorm.service.ts +++ b/libs/typeorm/src/typeorm.service.ts @@ -3,9 +3,13 @@ import { Repository } from 'typeorm'; import { TYPEORM_REPOSITORY } from './constants'; @Injectable() -export class TypeormService { +export class TypeORMService { constructor( @Inject(TYPEORM_REPOSITORY) private repository: Repository, ) {} + + public getRepository(): Repository{ + return this.repository; + } } diff --git a/src/app.module.ts b/src/app.module.ts index 4fd1ccb..d3bf012 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,43 +1,11 @@ import { Module } from '@nestjs/common'; -import { SimpleModule } from './example/simple/simple.module'; -import { CustomModule } from './example/custom/custom.module'; -import { TypeOrmModule } from '@nestjs/typeorm'; - -const getDatabaseCredential = (): any => { - const url = new URL(process.env.DATABASE_URL); - - // Extract the necessary components - let protocol; - switch(url.protocol){ - case 'postgresql': - protocol = 'postgres'; - break; - case 'mysql': - protocol = 'mysql'; - break; - } - const username = url.username; - const password = url.password; - const host = url.hostname; - const port = url.port; - const databaseName = url.pathname.substring(1); // Remove the leading slash - return { - type: protocol, - host: host, - port: port, - username: username, - password: password, - database: databaseName, - entities: [], - synchronize: true, - }; -}; +import { CustomModule } from './example/prisma/custom/custom.module'; +import { SimpleModule } from './example/prisma/simple/simple.module'; @Module({ imports: [ SimpleModule, CustomModule, - TypeOrmModule.forRoot(getDatabaseCredential()), ], controllers: [], providers: [], diff --git a/src/example/custom/custom.controller.ts b/src/example/prisma/custom/custom.controller.ts similarity index 100% rename from src/example/custom/custom.controller.ts rename to src/example/prisma/custom/custom.controller.ts diff --git a/src/example/custom/custom.module.ts b/src/example/prisma/custom/custom.module.ts similarity index 100% rename from src/example/custom/custom.module.ts rename to src/example/prisma/custom/custom.module.ts diff --git a/src/example/custom/domain/custom.list.process.ts b/src/example/prisma/custom/domain/custom.list.process.ts similarity index 100% rename from src/example/custom/domain/custom.list.process.ts rename to src/example/prisma/custom/domain/custom.list.process.ts diff --git a/src/example/custom/domain/custom.read.process.ts b/src/example/prisma/custom/domain/custom.read.process.ts similarity index 99% rename from src/example/custom/domain/custom.read.process.ts rename to src/example/prisma/custom/domain/custom.read.process.ts index 5dcf0da..b3fdba4 100644 --- a/src/example/custom/domain/custom.read.process.ts +++ b/src/example/prisma/custom/domain/custom.read.process.ts @@ -11,6 +11,7 @@ export class CustomReadProcess extends PrismaReadProcess { console.log(await this.prisma.user.findMany()); console.log('The ID requested in path parameter', this.identityData); } + async after(): Promise { this.customResult = { ...super.output(), diff --git a/src/example/simple/simple.controller.ts b/src/example/prisma/simple/simple.controller.ts similarity index 100% rename from src/example/simple/simple.controller.ts rename to src/example/prisma/simple/simple.controller.ts diff --git a/src/example/simple/simple.module.ts b/src/example/prisma/simple/simple.module.ts similarity index 100% rename from src/example/simple/simple.module.ts rename to src/example/prisma/simple/simple.module.ts