diff --git a/.gitignore b/.gitignore index 5f94540..a8cff25 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ yarn-debug.log* yarn-error.log* lerna-debug.log* +pnpm-lock.yaml + # OS .DS_Store @@ -39,4 +41,4 @@ lerna-debug.log* .env #Docker - +postgres-data \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d1341fc --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +services: + posetgres: + image: postgres:15 + restart: always + ports: + - '5432:5432' + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + volumes: + - ./postgres-data:/var/lib/postgresql/data diff --git a/libs/prisma/.gitignore b/libs/prisma/.gitignore new file mode 100644 index 0000000..11ddd8d --- /dev/null +++ b/libs/prisma/.gitignore @@ -0,0 +1,3 @@ +node_modules +# Keep environment variables out of version control +.env diff --git a/libs/prisma/README.md b/libs/prisma/README.md new file mode 100644 index 0000000..3d01826 --- /dev/null +++ b/libs/prisma/README.md @@ -0,0 +1,9 @@ +# Prisma + +> Prisma 관련 packages + +### 의존성 + +- `@prisma/client` + +### 기능 diff --git a/libs/prisma/package.json b/libs/prisma/package.json new file mode 100644 index 0000000..6cad27a --- /dev/null +++ b/libs/prisma/package.json @@ -0,0 +1,14 @@ +{ + "name": "@libs/prisma", + "version": "v0.0.1", + "description": "monorepo prisma lib", + "scripts": {}, + "engines": { + "node": ">=14 <=16" + }, + "dependencies": { + "@prisma/client": "^5.16.1", + "pg": "^8.11.5" + }, + "license": "MIT" +} diff --git a/libs/prisma/src/index.ts b/libs/prisma/src/index.ts new file mode 100644 index 0000000..1c7679c --- /dev/null +++ b/libs/prisma/src/index.ts @@ -0,0 +1,3 @@ +export * from './prisma.module'; +export * from './prisma.service'; +export * from './prisma.repository'; diff --git a/libs/prisma/src/prisma.entity.ts b/libs/prisma/src/prisma.entity.ts new file mode 100644 index 0000000..2fd23b3 --- /dev/null +++ b/libs/prisma/src/prisma.entity.ts @@ -0,0 +1,5 @@ +export class PrismaEntity { + constructor(data: Partial) { + Object.assign(this, data); + } +} diff --git a/libs/prisma/src/prisma.module.ts b/libs/prisma/src/prisma.module.ts new file mode 100644 index 0000000..b6e19b3 --- /dev/null +++ b/libs/prisma/src/prisma.module.ts @@ -0,0 +1,24 @@ +import { Global, Module, DynamicModule } from '@nestjs/common'; +import { PrismaService } from './prisma.service'; +import { PrismaRepository } from './prisma.repository'; + +@Global() +@Module({ + providers: [PrismaService, PrismaRepository], + exports: [PrismaService, PrismaRepository], +}) +export class PrismaModule { + static forRoot({ service }: { service: new () => PrismaService }): DynamicModule { + return { + module: PrismaModule, + providers: [ + { + provide: PrismaService, + useValue: new service(), + }, + PrismaRepository, + ], + exports: [PrismaService, PrismaRepository], + }; + } +} diff --git a/libs/prisma/src/prisma.repository.ts b/libs/prisma/src/prisma.repository.ts new file mode 100644 index 0000000..f1b04ca --- /dev/null +++ b/libs/prisma/src/prisma.repository.ts @@ -0,0 +1,88 @@ +export interface PrismaDelegate { + aggregate(data: any): any; + count(data: any): any; + create(data: any): any; + delete(data: any): any; + deleteMany(data: any): any; + findFirst(data: any): any; + findMany(data: any): any; + findUnique(data: any): any; + update(data: any): any; + updateMany(data: any): any; + upsert(data: any): any; +} + +export class PrismaRepository implements PrismaDelegate { + constructor(protected delegate: D, protected entity?: new (data: any) => any) { + return new Proxy(this, { + get: function (target, prop) { + const origMethod = target[prop]; + + if (typeof origMethod !== 'function' || prop === 'getDelegate' || !target.entity) { + return origMethod; + } + + return async function (...args) { + const result = await origMethod.apply(target, args); + return target.responseSerializer(result); + }; + }, + }); + } + + public responseSerializer(data: any) { + if (Array.isArray(data)) { + return data.map((item) => new this.entity(item)); + } else { + return new this.entity(data); + } + } + + public getDelegate(): D { + return this.delegate; + } + + aggregate(data: Parameters[0]): ReturnType { + return this.getDelegate().aggregate(data); + } + + count(data: Parameters[0]): ReturnType { + return this.getDelegate().count(data); + } + + create(data: Parameters[0]): ReturnType { + return this.getDelegate().create(data); + } + + delete(data: Parameters[0]): ReturnType { + return this.getDelegate().delete(data); + } + + deleteMany(data: Parameters[0]): ReturnType { + return this.getDelegate().deleteMany(data); + } + + findFirst(data: Parameters[0]): ReturnType { + return this.getDelegate().findFirst(data); + } + + async findMany(data: Parameters[0]): Promise> { + return await this.getDelegate().findMany(data); + } + + findUnique(data: Parameters[0]): ReturnType { + return this.getDelegate().findUnique(data); + } + + update(data: Parameters[0]): ReturnType { + return this.getDelegate().update(data); + } + + updateMany(data: Parameters[0]): ReturnType { + return this.getDelegate().updateMany(data); + } + + upsert(data: Parameters[0]): ReturnType { + return this.getDelegate().upsert(data); + } +} diff --git a/libs/prisma/src/prisma.service.ts b/libs/prisma/src/prisma.service.ts new file mode 100644 index 0000000..623d5e0 --- /dev/null +++ b/libs/prisma/src/prisma.service.ts @@ -0,0 +1,13 @@ +import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common'; +import { PrismaClient } from '@prisma/client'; + +@Injectable() +export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy { + async onModuleInit() { + await this.$connect(); + } + + async onModuleDestroy() { + await this.$disconnect(); + } +} diff --git a/libs/prisma/tsconfig.lib.json b/libs/prisma/tsconfig.lib.json new file mode 100644 index 0000000..e350873 --- /dev/null +++ b/libs/prisma/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "declaration": true, + "outDir": "../../dist/libs/prisma" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "test", "**/*spec.ts"] +} diff --git a/nest-cli.json b/nest-cli.json index eefc074..50841e9 100644 --- a/nest-cli.json +++ b/nest-cli.json @@ -27,6 +27,15 @@ "compilerOptions": { "tsConfigPath": "libs/config/tsconfig.lib.json" } + }, + "prisma": { + "type": "library", + "root": "libs/prisma", + "entryFile": "index", + "sourceRoot": "libs/prisma/src", + "compilerOptions": { + "tsConfigPath": "libs/prisma/tsconfig.lib.json" + } } } } \ No newline at end of file diff --git a/package.json b/package.json index 700f510..f4bfe78 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,11 @@ "@nestjs/common": "^10.0.0", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", + "@nestjs/swagger": "^7.3.1", + "@prisma/client": "^5.16.1", + "class-transformer": "^0.5.1", + "class-validator": "^0.14.1", + "pg": "^8.11.5", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1" }, @@ -71,7 +76,8 @@ ], "moduleNameMapper": { "^@app/test2(|/.*)$": "/libs/test2/src/$1", - "^@modules/config(|/.*)$": "/libs/config/src/$1" + "^@modules/config(|/.*)$": "/libs/config/src/$1", + "^@modules/prisma(|/.*)$": "/libs/prisma/src/$1" } } } diff --git a/tsconfig.json b/tsconfig.json index 62e24ae..3c54df0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,6 +23,12 @@ ], "@modules/config/*": [ "libs/config/src/*" + ], + "@modules/prisma": [ + "libs/prisma/src" + ], + "@modules/prisma/*": [ + "libs/prisma/src/*" ] } }