UNPKG

@algochad/prisma-core

Version:

A comprehensive NestJS library that provides EF-Core-like operations using Prisma and GraphQL. Features LINQ-style query builders, advanced data manipulation, GraphQL integration with genql, and a unified API for both Prisma and GraphQL operations. Includ

302 lines (252 loc) 7.94 kB
# Quick Setup Guide ## 🛠️ Quick Setup Guide ### Step 1: Define Your Prisma Schema Create or update your `prisma/schema.prisma` file: ```prisma generator client { provider = "prisma-client-js" output = "../generated/prisma" } datasource db { provider = "sqlite" url = env("DATABASE_URL") } model Test { id Int @id @default(autoincrement()) name String description String? isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model User { id Int @id @default(autoincrement()) email String @unique name String? age Int? isActive Boolean @default(true) posts Post[] } model Post { id Int @id @default(autoincrement()) title String content String? userId Int user User @relation(fields: [userId], references: [id]) } ``` ### Step 2: Configure the Module Set up the `PrismaCoreModule` in your NestJS application: ```typescript import { Module } from '@nestjs/common'; import { PrismaClient } from '../generated/prisma'; import { PrismaCoreModule } from '@algochad/prisma-core'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { AppRepository } from './app.repository'; const PRISMA_CLIENT_PROVIDER = { provide: 'PRISMA_CLIENT', useFactory: () => new PrismaClient(), }; @Module({ imports: [ PrismaCoreModule.forRoot({ prismaClientProvider: PRISMA_CLIENT_PROVIDER, }), ], controllers: [AppController], providers: [AppService, AppRepository], }) export class AppModule {} ``` ### Alternative: GraphQL Setup For GraphQL data sources, configure your GraphQL client and use the GraphQL repository: ```typescript import { Module } from '@nestjs/common'; import { createClient } from '../generated/graphql'; import { PrismaCoreModule } from '@algochad/prisma-core'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { AppRepository } from './app.repository'; const GRAPHQL_CLIENT_PROVIDER = { provide: 'GRAPHQL_CLIENT', useFactory: () => createClient({ url: 'http://localhost:4000/graphql', // Your GraphQL endpoint }), }; @Module({ imports: [ PrismaCoreModule.forRoot({ graphqlClientProvider: GRAPHQL_CLIENT_PROVIDER, }), ], controllers: [AppController], providers: [AppService, AppRepository], }) export class AppModule {} ``` > **Note**: When using GraphQL as a data source, ensure your GraphQL schema matches your Prisma models for seamless type compatibility and LINQ operations. ### Step 3: Create Your Repository Create a typed repository with full type safety: ```typescript import { Injectable } from '@nestjs/common'; import { Prisma, Test, User, Post } from '../generated/prisma'; import { PrismaCoreService, PrismaRepository, PrismaUnifiedBuilder, } from '@algochad/prisma-core'; @Injectable() export class AppRepository extends PrismaRepository { constructor(databaseService: PrismaCoreService) { super(databaseService); } // Typed accessor for Test model get test(): PrismaUnifiedBuilder< Test, Test, Prisma.TestWhereInput, Prisma.TestOrderByWithRelationInput, Prisma.TestInclude, Prisma.TestSelect, Prisma.TestCreateInput, Prisma.TestUpdateInput, Prisma.TestWhereUniqueInput > { return this.model<Test>('test') as any; } // Typed accessor for User model get user(): PrismaUnifiedBuilder< User, User, Prisma.UserWhereInput, Prisma.UserOrderByWithRelationInput, Prisma.UserInclude, Prisma.UserSelect, Prisma.UserCreateInput, Prisma.UserUpdateInput, Prisma.UserWhereUniqueInput > { return this.model<User>('user') as any; } // Typed accessor for Post model get post(): PrismaUnifiedBuilder< Post, Post, Prisma.PostWhereInput, Prisma.PostOrderByWithRelationInput, Prisma.PostInclude, Prisma.PostSelect, Prisma.PostCreateInput, Prisma.PostUpdateInput, Prisma.PostWhereUniqueInput > { return this.model<Post>('post') as any; } } ``` #### Alternative: GraphQL Repository For GraphQL data sources, extend `GraphQLRepository` and use the `.model()` method: ```typescript import { Injectable } from '@nestjs/common'; import { Test, User, Post } from '../generated/graphql/types'; import { PrismaCoreService, GraphQLRepository, GraphQLQueryBuilder, } from '@algochad/prisma-core'; @Injectable() export class AppRepository extends GraphQLRepository { constructor(databaseService: PrismaCoreService) { super(databaseService); } // Typed accessor for Test model via GraphQL get test(): GraphQLQueryBuilder<Test> { return this.model<Test>('test'); } // Typed accessor for User model via GraphQL get user(): GraphQLQueryBuilder<User> { return this.model<User>('user'); } // Typed accessor for Post model via GraphQL get post(): GraphQLQueryBuilder<Post> { return this.model<Post>('post'); } } ``` ### Step 4: Use in Your Service Inject and use the repository in your services: ```typescript import { Injectable } from '@nestjs/common'; import { AppRepository } from './app.repository'; @Injectable() export class AppService { constructor(private readonly repository: AppRepository) {} // Simple query example async getActiveTests() { return await this.repository.test .Where({ isActive: true }) .OrderBy({ createdAt: 'desc' }) .ToArray(); } // Complex query with LINQ operations async getTestsWithTransformation() { const tests = await this.repository.test .Where({ isActive: true }) .ToEnumerable(); return tests .Where((test) => test.description != null) .Select((test) => ({ id: test.id, displayName: test.name.toUpperCase(), summary: `${test.name}: ${test.description}`, hasDescription: true, })) .OrderBy((item) => item.displayName) .ToArray(); } } ``` #### GraphQL Service Examples For GraphQL data sources, the same LINQ patterns work seamlessly: ```typescript import { Injectable } from '@nestjs/common'; import { AppRepository } from './app.repository'; @Injectable() export class AppService { constructor(private readonly repository: AppRepository) {} // GraphQL query with LINQ-style operations async getActiveTestsFromGraphQL() { return await this.repository.test .Where({ isActive: true }) .Select({ id: true, name: true, description: true, }) .OrderBy({ name: 'asc' }) .ToArrayAsync(); } // Complex GraphQL query with transformations async getGraphQLTestsWithTransformation() { const tests = await this.repository.test .Where({ isActive: true }) .ToAsyncEnumerable(); return tests .Where((test) => test.description != null) .Select((test) => ({ id: test.id, displayName: test.name.toUpperCase(), summary: `${test.name}: ${test.description}`, hasDescription: true, })) .OrderBy((item) => item.displayName) .ToArray(); } } ``` ## Next Steps - [Learn about Select & OrderBy patterns](./quick-start-patterns.md) - [Explore LINQ operations](./linq-operations.md) - [Understand the Universal Repository Pattern](./repository-pattern.md)