@nathapp/nestjs-prisma
v3.3.0
Published
NestJS Prisma integration with multi-database support
Readme
@nathapp/nestjs-prisma
Prisma 6 wrapper for NestJS with multi-database support, transactions, an
IRepository-compatible abstract repository, pagination, and error mapping.
Installation
npm install @nathapp/nestjs-prisma@prisma/client is a peer dependency — install it in your consuming app; you
will also want the prisma CLI installed there for migrations. This package is
part of the @nathapp/nestjs-* peer-layer stack and builds on
@nathapp/nestjs-common and @nathapp/nestjs-data.
What it provides
PrismaModule—forRoot({ client, name?, transaction?, isGlobal? })/forRootAsync({ useFactory | useClass | useExisting }). Repeat the call with differentnamevalues to register multiple databases.PrismaService— wraps aPrismaClientinstance (composition, not inheritance) for multi-DB flexibility; exposes.clientand.isConnected.AbstractPrismaRepository<TDomain, TModel, TId>— implementsIRepository<TDomain, TId>from@nathapp/nestjs-data. Subclasses implementmodelDelegate,toDomain,toPersistenceCreate,toPersistenceUpdate.InjectPrisma(name?)— parameter decorator to inject a namedPrismaService.PrismaHealthIndicator—isHealthy()returns{ status: 'up' | 'down' }.Paginate(model, pageOption, args?)— paginate a raw Prisma model query, returning aPage<T>from@nathapp/nestjs-common.PrismaExceptionFilter—@Catchfilter mappingPrismaClientKnownRequestError/PrismaClientValidationErrorto a standardized error response.PrismaErrorMapper,PRISMA_ERROR_CODES— map known Prisma error codes (P2000, P2002, P2003, P2025, ...) to anAppExceptionwith a string code.getPrismaToken(name?),getPrismaTransactionManagerToken(name?)— derive the DI tokens for a named connection'sPrismaService/ITransactionManager.- Prisma testing utilities under the
testingexport.
Usage
Single-DB setup and a repository implementation:
import { Module, Inject, Injectable } from '@nestjs/common';
import { PrismaModule, AbstractPrismaRepository } from '@nathapp/nestjs-prisma';
import { TRANSACTION_MANAGER, ITransactionManager, IRepository } from '@nathapp/nestjs-data';
import { PrismaClient } from '@prisma/client';
interface User { id: string; email: string; name: string }
@Injectable()
export class PrismaUserRepository extends AbstractPrismaRepository<User, any, string> {
constructor(@Inject(TRANSACTION_MANAGER) tx: ITransactionManager) { super(tx); }
protected modelDelegate(client: any) { return client.user; }
protected toDomain(m: any): User { return { id: m.id, email: m.emailAddress, name: m.fullName }; }
protected toPersistenceCreate(d: User) { return { id: d.id, emailAddress: d.email, fullName: d.name }; }
protected toPersistenceUpdate(p: Partial<User>) {
const out: any = {};
if (p.email !== undefined) out.emailAddress = p.email;
if (p.name !== undefined) out.fullName = p.name;
return out;
}
}
export const USER_REPOSITORY = Symbol('USER_REPOSITORY');
@Module({
imports: [PrismaModule.forRoot({ client: PrismaClient, transaction: true })],
providers: [
PrismaUserRepository,
{ provide: USER_REPOSITORY, useExisting: PrismaUserRepository },
],
})
export class AppModule {}Multi-DB and transactions
For multiple databases in one process, call PrismaModule.forRoot once per
connection with a distinct name, and inject the connection-scoped tokens
returned by getPrismaToken(name) / getPrismaTransactionManagerToken(name)
instead of the default PrismaService / TRANSACTION_MANAGER. Only the
default connection aliases the global TRANSACTION_MANAGER symbol from
@nathapp/nestjs-data. A tx.run() on a named transaction manager covers
only that connection's writes — there is no cross-DB atomicity; use sagas or
an outbox pattern for cross-DB consistency.
