TypeORM Extension Library
typeorm-extension is a robust library that augments TypeORM with essential database management functionalities, including streamlined database creation and dropping, and a powerful, flexible data seeding mechanism. It integrates seamlessly with the TypeORM ecosystem, offering CLI commands for many of its operations. Currently at version 3.9.0, the library maintains an active release cadence, frequently introducing minor features and critical bug fixes. Its key differentiators lie in simplifying complex database setup and teardown, as well as providing sophisticated factory-based data seeding capabilities, which are especially useful for development, testing, and populating initial datasets. It acts as a significant convenience layer over raw TypeORM operations for these specific use cases.
Common errors
-
Error: Cannot find module '@faker-js/faker'
cause You are using SeederFactory features (e.g., `setSeederFactory().make()`) but `@faker-js/faker` is not installed as a direct dependency in your project.fixInstall faker as a project dependency: `npm install @faker-js/faker` or `yarn add @faker-js/faker`. -
DataSource is not initialized.
cause A TypeORM DataSource object was not properly initialized or connected before an operation (e.g., `runSeeder`, `createDatabase`) was attempted. This often happens if `createDataSource` fails or `dataSource.initialize()` is not awaited.fixEnsure `await createDataSource(config)` successfully completes and returns an initialized DataSource instance before proceeding with any database operations or seeding. -
Error: connect ECONNREFUSED ::1:5432
cause The database server configured in your TypeORM DataSource options (e.g., PostgreSQL on port 5432) is not running or is not accessible from where your application is executing.fixVerify that your database server is running, listening on the correct port, and that your connection credentials and hostname in the DataSource configuration are accurate. Check firewall rules if applicable.
Warnings
- gotcha The `@faker-js/faker` library is a peer dependency and became optional/on-demand loaded since v3.8.0. If you are using `setSeederFactory` or other faker-dependent features, you must explicitly install `@faker-js/faker` in your project.
- breaking Prior to v3.9.0, the `generateMigration` operation could inadvertently destroy the data-source connection after execution, leading to unexpected errors or requiring manual re-initialization for subsequent operations.
- gotcha In versions prior to v3.7.3, certain database operations might not have consistently preserved all DataSource options, potentially leading to incorrect behavior or configurations not being applied as expected.
- breaking Behavior related to pagination (`options.maxLimit`) was adjusted in versions 3.7.4 and 3.8.0. If you rely on specific default pagination limits or their application, review your code after upgrading, as the exact application and defaulting logic may have changed.
Install
-
npm install typeorm-extension -
yarn add typeorm-extension -
pnpm add typeorm-extension
Imports
- DataSource
import { DataSource } from 'typeorm-extension';import { DataSource } from 'typeorm'; - createDataSource
const createDataSource = require('typeorm-extension').createDataSource;import { createDataSource } from 'typeorm-extension'; - runSeeder
import runSeeder from 'typeorm-extension';
import { runSeeder } from 'typeorm-extension'; - Seeder
import Seeder from 'typeorm-extension';
import { Seeder } from 'typeorm-extension'; - setSeederFactory
import { seederFactory } from 'typeorm-extension';import { setSeederFactory } from 'typeorm-extension';
Quickstart
import { DataSource, Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
import { createDataSource, runSeeder, Seeder, SeederFactory, setSeederFactory } from 'typeorm-extension';
import { faker } from '@faker-js/faker';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id!: number;
@Column()
firstName!: string;
@Column()
lastName!: string;
@Column({ unique: true })
email!: string;
}
// 1. Define a SeederFactory
setSeederFactory(User, (faker) => {
const user = new User();
user.firstName = faker.person.firstName();
user.lastName = faker.person.lastName();
user.email = faker.internet.email().toLowerCase();
return user;
});
// 2. Create a Seeder class
class UserSeeder implements Seeder {
async run(dataSource: DataSource): Promise<any> {
const repository = dataSource.getRepository(User);
const users = await Promise.all(
Array(10)
.fill(null)
.map(() => setSeederFactory(User)(faker).make())
);
await repository.save(users);
console.log(`Seeded ${users.length} users.`);
}
}
// 3. Main execution function
async function bootstrap() {
// Create a new DataSource connection
const dataSource = await createDataSource({
type: 'sqlite',
database: './temp_db.sqlite',
entities: [User],
synchronize: true, // Automatically create schema for demo
logging: false,
dropSchema: true // Drop schema to ensure a clean state for demo
});
if (!dataSource) {
throw new Error('DataSource not initialized');
}
console.log('DataSource created and connected.');
try {
// Run the seeder
await runSeeder(dataSource, UserSeeder);
console.log('Seeding complete.');
} catch (error) {
console.error('Seeding failed:', error);
} finally {
// Ensure the data source is closed
if (dataSource.isInitialized) {
await dataSource.destroy();
console.log('DataSource destroyed.');
}
}
}
bootstrap().catch(console.error);