@a_jackie_z/typeorm
v1.0.8
Published
A TypeORM wrapper with handy utilities for easier database management.
Readme
@a_jackie_z/typeorm
A TypeORM wrapper with handy utilities for easier database management.
Installation
npm install @a_jackie_z/typeorm reflect-metadataQuick Start (30 seconds)
1. Set environment variables:
export DB_TYPE=postgres
export DB_POSTGRES_HOST=localhost
export DB_POSTGRES_PORT=5432
export DB_POSTGRES_USERNAME=postgres
export DB_POSTGRES_PASSWORD=yourpassword
export DB_POSTGRES_DATABASE=mydb2. Connect to database:
import 'reflect-metadata'
import { createOrm } from '@a_jackie_z/typeorm'
const dataSource = createOrm()
await dataSource.initialize()
// ✓ Connected!That's it! You're connected and ready to use TypeORM.
Basic Usage
Define an Entity
import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn } from '@a_jackie_z/typeorm'
@Entity('user')
export class User {
@PrimaryGeneratedColumn()
id!: number
@Column()
email!: string
@Column()
name!: string
@CreateDateColumn()
createdAt!: Date
}CRUD Operations
import { createOrm } from '@a_jackie_z/typeorm'
import { User } from './entities/User.js'
const dataSource = createOrm({
entities: [User],
synchronize: true, // Only for development!
})
await dataSource.initialize()
const userRepo = dataSource.getRepository(User)
// Create
const user = userRepo.create({ email: '[email protected]', name: 'John' })
await userRepo.save(user)
// Read
const users = await userRepo.find()
const john = await userRepo.findOneBy({ email: '[email protected]' })
// Update
john.name = 'John Doe'
await userRepo.save(john)
// Delete
await userRepo.remove(john)Environment Variables
PostgreSQL (Recommended)
DB_TYPE=postgres
DB_POSTGRES_HOST=localhost
DB_POSTGRES_PORT=5432
DB_POSTGRES_USERNAME=postgres
DB_POSTGRES_PASSWORD=yourpassword
DB_POSTGRES_DATABASE=mydb
DB_POSTGRES_LOGGING=false # optionalMySQL / MariaDB
DB_TYPE=mysql # or mariadb
DB_MYSQL_HOST=localhost
DB_MYSQL_PORT=3306
DB_MYSQL_USERNAME=root
DB_MYSQL_PASSWORD=yourpassword
DB_MYSQL_DATABASE=mydb
DB_MYSQL_LOGGING=false # optionalSQLite (Default)
DB_TYPE=sqlite
DB_SQLITE_DATABASE=./data.db # or :memory:
DB_SQLITE_LOGGING=false # optionalIf no DB_TYPE is set, SQLite with in-memory database is used by default.
Real-World Example
Production-ready setup with migrations and error handling:
import 'reflect-metadata'
import { logger } from '@a_jackie_z/logger'
import { createOrm, DataSource } from '@a_jackie_z/typeorm'
import { User } from './entities/User.js'
import { CreateUserTable1234567890 } from './migrations/1234567890-CreateUserTable.js'
export let dataSource: DataSource
try {
dataSource = createOrm({
entities: [User],
migrations: [CreateUserTable1234567890],
// migrations run automatically on startup
})
await dataSource.initialize()
logger.info('Database connection established')
} catch (error) {
logger.error(error, 'Database connection error')
process.exit(1)
}Features
Automatic Snake Case
Property names are automatically converted to snake_case in the database:
@Entity('user')
export class User {
@Column()
firstName!: string // → first_name in database
@CreateDateColumn()
createdAt!: Date // → created_at in database
}Automatic Migrations
Migrations run automatically on startup (controlled by migrationsRun: true default):
const dataSource = createOrm({
entities: [User],
migrations: [CreateUserTable1234567890],
// migrationsRun: true by default
})
await dataSource.initialize()
// All pending migrations executed ✓Query Builder
const users = await dataSource
.getRepository(User)
.createQueryBuilder('user')
.where('user.email LIKE :pattern', { pattern: '%@example.com' })
.orderBy('user.createdAt', 'DESC')
.take(10)
.getMany()Transactions
await dataSource.transaction(async (manager) => {
const user = manager.create(User, {
email: '[email protected]',
name: 'Jane',
})
await manager.save(user)
// More operations in same transaction...
})API Reference
createOrm(options?)
Creates a TypeORM DataSource with environment-based configuration.
function createOrm(options?: Partial<DataSourceOptions>): DataSourceDefault Configuration:
logging:['migration', 'schema', 'error']migrationsRun:true(runs migrations on startup)namingStrategy:SnakeNamingStrategy(camelCase → snake_case)synchronize:false(use migrations instead)
Override any option:
const dataSource = createOrm({
entities: ['./entities/**/*.entity.ts'],
migrations: ['./migrations/**/*.ts'],
logging: true,
synchronize: false, // NEVER true in production
})Configuration Schemas
Type-safe configuration schemas for custom setup:
import { createConfig } from '@a_jackie_z/config'
import { postgresSchema, mysqlSchema, sqliteSchema } from '@a_jackie_z/typeorm'
// Use with custom environment
const config = createConfig(
postgresSchema,
{
type: 'DB_TYPE',
host: 'DB_POSTGRES_HOST',
port: 'DB_POSTGRES_PORT',
username: 'DB_POSTGRES_USERNAME',
password: 'DB_POSTGRES_PASSWORD',
database: 'DB_POSTGRES_DATABASE',
},
process.env
)Testing
Use in-memory SQLite for fast tests:
import { createOrm } from '@a_jackie_z/typeorm'
const testDataSource = createOrm({
type: 'sqlite',
database: ':memory:',
entities: [User],
synchronize: true, // OK for tests
dropSchema: true,
})
await testDataSource.initialize()
// Run tests...
await testDataSource.destroy()TypeScript Setup
Required in tsconfig.json:
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}Import reflect-metadata once at your app entry point:
import 'reflect-metadata'Best Practices
- ✅ Use migrations for schema changes (never
synchronize: truein production) - ✅ Enable
migrationsRun: truefor automatic migration execution - ✅ Use repositories for cleaner code
- ✅ Handle initialization errors gracefully
- ✅ Use environment variables for different environments
- ❌ Never commit database credentials to git
Re-exported TypeORM
All TypeORM exports are available:
import {
Entity,
Column,
PrimaryGeneratedColumn,
ManyToOne,
OneToMany,
// ... everything from 'typeorm'
} from '@a_jackie_z/typeorm'License
MIT
Author
Sang Lu [email protected]
