@surv-co/prisma-typeorm-db-utils
v4.0.4
Published
Transform Prisma schemas to TypeORM entities with NestJS integration and fast pg-mem testing
Downloads
71
Maintainers
Readme
@surv-co/prisma-typeorm-db-utils
Transform Prisma schemas to TypeORM datasources with NestJS integration and testing support.
Why use this library?
- 🔄 Prisma Schema → TypeORM Datasource - Complete transformation in one step
- 🧪 Fast pg-mem testing - In-memory PostgreSQL for lightning-fast tests
- 🏗️ Ready-to-use NestJS modules - Drop-in TypeORM and repository integration for both testing (pg-mem) and production (PostgreSQL)
- 🎯 Type-safe throughout - Full TypeScript support with proper error handling
- 📦 Simple API - Just a few imports to get everything working
Core Features
1. Complete Testing Setup (pg-mem) - Schema to TypeORM Datasource
Transform your Prisma schema directly into a working TypeORM datasource with pg-mem database:
import { createPrismaToPgMemTypeormDatasourceGenerator } from '@surv-co/prisma-typeorm-db-utils';
// Your Prisma schema
const schema = `
model User {
id String @id @default(uuid())
email String @unique
name String?
posts Post[]
}
model Post {
id String @id @default(uuid())
title String
content String?
authorId String
author User @relation(fields: [authorId], references: [id])
}
`;
// Generate complete TypeORM datasource
const generator = createPrismaToPgMemTypeormDatasourceGenerator();
const result = await generator.generateDatasource({
schema,
entities: [User, Post] // Your TypeORM entity classes
});
if (result._tag === 'Right') {
const { datasource } = result.right;
// Use datasource for testing - fully configured with pg-mem database
const userRepository = datasource.getRepository(User);
const newUser = await userRepository.save({ email: '[email protected]' });
}2. NestJS DataSource Integration (pg-mem) - Injectable TYPEORM_DATASOURCE
Automatically provides a TypeORM datasource with pg-mem for fast testing:
import { Module } from '@nestjs/common';
import { TypeORMPgMemModule } from '@surv-co/prisma-typeorm-db-utils';
import { User, Post } from './entities';
@Module({
imports: [
TypeORMPgMemModule.forRoot({
entities: [User, Post],
prismaSchema: `
model User {
id String @id @default(uuid())
email String @unique
name String?
posts Post[]
}
model Post {
id String @id @default(uuid())
title String
content String?
authorId String
author User @relation(fields: [authorId], references: [id])
}
`
}),
// Other modules can now inject TYPEORM_DATASOURCE
],
})
export class AppModule {}Note: The
synchronizeoption is not supported for pg-mem. The schema is always created from the providedprismaSchema.
3. Production/PostgreSQL Integration - Real PostgreSQL Datasource
Use the TypeORMPostgresModule to connect to a real PostgreSQL database in production or staging environments:
import { Module } from '@nestjs/common';
import { TypeORMPostgresModule } from '@surv-co/prisma-typeorm-db-utils';
import { User, Post } from './entities';
@Module({
imports: [
TypeORMPostgresModule.forRoot({
entities: [User, Post],
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'password',
database: 'mydb',
// synchronize: false, // Not supported! See note below
logging: false,
ssl: false // or provide SSL config for production
}),
// Other modules can now inject TYPEORM_DATASOURCE
],
})
export class AppModule {}- Entities: Register your TypeORM entity classes
- Connection: Provide all PostgreSQL connection details
- SSL/Logging: Configure as needed for your environment
Important: The
synchronizeoption is not supported for the real PostgreSQL datasource. You must run your database migrations before using the datasource. This module does not auto-sync or create the schema in PostgreSQL.
4. Repository Factory Function - createTypeORMRepositoryFactory
Create repository operations from any TypeORM datasource:
import {
createPrismaToPgMemTypeormDatasourceGenerator,
createTypeORMRepositoryFactory
} from '@surv-co/prisma-typeorm-db-utils';
import { Entity, PrimaryColumn, Column } from 'typeorm';
@Entity()
class User {
@PrimaryColumn('uuid')
id: string;
@Column('varchar')
email: string;
@Column('varchar', { nullable: true })
name: string;
}
const schema = `
model User {
id String @id @default(uuid())
email String @unique
name String?
}
`;
// Complete setup in one step
const generator = createPrismaToPgMemTypeormDatasourceGenerator();
const result = await generator.generateDatasource({ schema, entities: [User] });
if (result._tag === 'Right') {
const { datasource } = result.right;
// Create repository factory from the datasource
const repositoryFactory = createTypeORMRepositoryFactory(datasource);
const userRepository = repositoryFactory(User);
// Use functional repository operations
const createResult = await userRepository.create({
email: '[email protected]',
name: 'Test User'
})();
if (createResult._tag === 'Right') {
console.log('User created:', createResult.right);
}
}5. NestJS Repository Integration - Injectable REPOSITORY_OPERATIONS
Provides a repository factory that works with any datasource:
import { Injectable, Inject } from '@nestjs/common';
import { REPOSITORY_OPERATIONS } from '@surv-co/prisma-typeorm-db-utils';
import { User } from './entities/User';
@Injectable()
export class UserService {
private userRepository;
constructor(
@Inject(REPOSITORY_OPERATIONS) repositoryFactory: any
) {
this.userRepository = repositoryFactory(User);
}
async createUser(userData: Partial<User>) {
const result = await this.userRepository.create(userData)();
if (result._tag === 'Right') {
return result.right;
}
throw new Error(result.left.message);
}
}6. Entity Generator - TypeORM Entities from Prisma Schema
Generate TypeORM entity classes from your Prisma schema:
import { createPrismaToEntitiesGenerator } from '@surv-co/prisma-typeorm-db-utils';
const generator = createPrismaToEntitiesGenerator();
const result = await generator.generateEntities(schema)();
if (result._tag === 'Right') {
console.log('Generated TypeORM entities:');
result.right.forEach(entityCode => {
console.log(entityCode);
});
}Quick Start
1. Install
npm install @surv-co/prisma-typeorm-db-utils2. Basic Usage
import {
createPrismaToPgMemTypeormDatasourceGenerator,
TypeORMPgMemModule,
TypeORMPostgresModule, // <-- NEW: for real PostgreSQL
RepositoryModule,
REPOSITORY_OPERATIONS
} from '@surv-co/prisma-typeorm-db-utils';3. Complete NestJS Setup (pg-mem and postgres)
// app.module.ts
import { Module } from '@nestjs/common';
import { TypeORMPgMemModule, TypeORMPostgresModule, RepositoryModule } from '@surv-co/prisma-typeorm-db-utils';
import { User, Post } from './entities';
@Module({
imports: [
// For fast in-memory testing
TypeORMPgMemModule.forRoot({
entities: [User, Post],
prismaSchema: `...`
}),
// For production with real PostgreSQL
// TypeORMPostgresModule.forRoot({
// entities: [User, Post],
// host: 'localhost',
// port: 5432,
// username: 'postgres',
// password: 'password',
// database: 'mydb',
// // synchronize: false, // Not supported!
// logging: false,
// ssl: false
// }),
RepositoryModule,
],
})
export class AppModule {}Note: For pg-mem, schema is always created from the provided
prismaSchema. For PostgreSQL, you must run your migrations before using the datasource. The module does not auto-sync or create the schema.
4. Testing Setup
// user.service.spec.ts
import { Test } from '@nestjs/testing';
import { createPrismaToPgMemTypeormDatasourceGenerator } from '@surv-co/prisma-typeorm-db-utils';
import { UserService } from './user.service';
describe('UserService', () => {
let service: UserService;
let cleanup: () => Promise<void>;
beforeEach(async () => {
// Create complete testing environment from schema
const generator = createPrismaToPgMemTypeormDatasourceGenerator();
const result = await generator.generateDatasource({
schema: prismaSchemaString,
entities: [User, Post]
});
if (result._tag === 'Right') {
const { datasource, database } = result.right;
cleanup = database.cleanup;
const module = await Test.createTestingModule({
imports: [RepositoryModule],
providers: [UserService],
})
.overrideProvider('TYPEORM_DATASOURCE')
.useValue(datasource)
.compile();
service = module.get<UserService>(UserService);
}
});
afterEach(async () => {
await cleanup();
});
it('should create a user', async () => {
const user = await service.createUser({
email: '[email protected]',
name: 'Test User'
});
expect(user.email).toBe('[email protected]');
});
});Core API
Primary Functions
// Complete schema to datasource transformation
createPrismaToPgMemTypeormDatasourceGenerator()
// NestJS modules
TypeORMPgMemModule.forRoot({ entities: [...], prismaSchema: '...' }) // Provides TYPEORM_DATASOURCE (pg-mem)
TypeORMPostgresModule.forRoot({ entities: [...], host, port, username, password, database, ... }) // Provides TYPEORM_DATASOURCE (PostgreSQL)
RepositoryModule // Provides REPOSITORY_OPERATIONS
// Repository factory function
createTypeORMRepositoryFactory(dataSource)
// Entity generation
createPrismaToEntitiesGenerator()Core Exports
import {
// Main integration - Prisma schema to complete TypeORM datasource
createPrismaToPgMemTypeormDatasourceGenerator,
// NestJS modules
TypeORMPgMemModule, // Provides TYPEORM_DATASOURCE (pg-mem)
TypeORMPostgresModule, // Provides TYPEORM_DATASOURCE (PostgreSQL)
RepositoryModule, // Provides REPOSITORY_OPERATIONS
REPOSITORY_OPERATIONS, // Repository factory injection token
// Individual functions
createTypeORMRepositoryFactory, // Repository factory function
createPrismaToEntitiesGenerator, // Entity generator
// Testing utilities
createTestTypeORMClient, // Low-level pg-mem client
createPostgresTypeORMClient, // Low-level Postgres client
// Types
type RepositoryOperations,
type TableConfig,
type ColumnConfig
} from '@surv-co/prisma-typeorm-db-utils';Environment Configuration
All Environments
- pg-mem: Uses in-memory database for fast testing and development. No external dependencies. The schema is always created from the provided
prismaSchema. - PostgreSQL: Uses real PostgreSQL connection for production/staging. You must run your migrations before using the datasource. The module does not auto-sync or create the schema.
TypeORM Features Supported
- ✅ Complete datasource creation from Prisma schema
- ✅ Entity generation with proper decorators
- ✅ Relationships (@ManyToOne, @OneToMany, @JoinColumn)
- ✅ UUID primary keys with auto-generation
- ✅ Composite primary keys with defaults
- ✅ Snake case naming (camelCase → snake_case)
- ✅ Unique constraints and indexes
- ✅ Nullable fields and default values
Error Handling
All operations use functional error handling:
const result = await someOperation();
if (result._tag === 'Right') {
const data = result.right; // Success case
} else {
const error = result.left; // Error case
console.error('Operation failed:', error.message);
}Requirements
- Node.js 18+
- TypeScript 4.9+
- NestJS 10+ (for NestJS features)
- TypeORM 0.3+
License
MIT
Need help? Open an issue on GitHub for support.
