A powerful, enterprise-grade Object-Relational Mapping (ORM) library for TypeScript applications using Express.js. FoundryORM provides seamless integration with multiple databases including PostgreSQL, MySQL, SQLite, and MongoDB, offering a unified API for database operations.
Note: This package is currently in alpha stage. APIs may change in future releases.
- π Multi-Database Support: PostgreSQL, MySQL, SQLite, MongoDB
- π Connection Pooling: Efficient connection management with configurable pools
- π Transaction Support: ACID transactions across all supported databases
- π‘οΈ Type Safety: Full TypeScript support with compile-time type checking
- π― Decorator-Based: Clean, decorator-driven model definitions
- π Query Builder: Fluent API with cross-database dialect support
- π Relationship Decorators:
@HasMany,@HasOne,@BelongsTo,@ManyToMany - π Repository Pattern: Clean data access layer with multiple connection support
- π SQL Injection Prevention: Built-in identifier sanitization
- π Health Checks: Built-in database health monitoring
- π Comprehensive Logging: Pluggable logging interface
- β‘ High Performance: Optimized for production workloads
- π§ͺ Well Tested: Comprehensive test coverage
- π Rich Documentation: Complete API documentation and guides
npm install foundry-orm@alphanpm install foundry-ormnpm install reflect-metadataInstall the driver for your database:
# PostgreSQL
npm install pg
# MySQL
npm install mysql2
# SQLite
npm install sqlite3
# MongoDB
npm install mongodbimport { Connection, Entity, Column, BaseModel, ConsoleLogger } from 'foundry-orm';
import 'reflect-metadata';
// Define a model using decorators
@Entity('users')
class User extends BaseModel {
@Column({ primary: true, autoIncrement: true })
id: number;
@Column({ type: 'varchar', length: 255 })
name: string;
@Column({ type: 'varchar', length: 255, unique: true })
email: string;
@Column({ type: 'timestamp', default: 'CURRENT_TIMESTAMP' })
createdAt: Date;
}
// Create connection with connection pooling
const logger = new ConsoleLogger();
const connection = new Connection('postgres', {
host: 'localhost',
port: 5432,
database: 'myapp',
user: 'myuser',
password: 'mypassword',
maxConnections: 20,
minConnections: 5
}, logger);
// Connect and use
await connection.connect();
BaseModel.setConnection(connection);
// Perform operations
const user = await User.create({
name: 'John Doe',
email: '[email protected]'
});
await user.save();
const users = await User.findAll();
console.log(`Found ${users.length} users`);- Node.js: >= 18.0.0
- TypeScript: >= 5.0.0
- Databases:
- PostgreSQL >= 12
- MySQL >= 8.0
- SQLite >= 3.0
- MongoDB >= 4.0
const connection = new Connection('postgres', {
host: 'localhost',
port: 5432,
database: 'mydb',
user: 'user',
password: 'pass',
maxConnections: 20,
ssl: true
}, logger);const connection = new Connection('mysql', {
host: 'localhost',
port: 3306,
database: 'mydb',
user: 'user',
password: 'pass',
connectionLimit: 15,
acquireTimeout: 60000
}, logger);const connection = new Connection('sqlite', {
filename: './database.db',
mode: 0o666
}, logger);const connection = new Connection('mongodb', {
url: 'mongodb://localhost:27017',
database: 'mydb',
maxPoolSize: 10,
serverSelectionTimeoutMS: 5000
}, logger);import { Entity, Column, BaseModel } from 'foundry-orm';
@Entity('products')
export class Product extends BaseModel {
@Column({ primary: true, autoIncrement: true })
id: number;
@Column({ type: 'varchar', length: 255, nullable: false })
name: string;
@Column({ type: 'decimal', precision: 10, scale: 2 })
price: number;
@Column({ type: 'text' })
description: string;
@Column({ type: 'boolean', default: true })
isActive: boolean;
}import { Entity, Column, BaseModel, HasMany, BelongsTo } from 'foundry-orm';
@Entity('users')
export class User extends BaseModel {
@Column({ primary: true, autoIncrement: true })
id: number;
@Column()
name: string;
@HasMany(() => Order, 'userId')
orders: Order[];
}
@Entity('orders')
export class Order extends BaseModel {
@Column({ primary: true, autoIncrement: true })
id: number;
@Column()
userId: number;
@Column({ type: 'decimal', precision: 10, scale: 2 })
total: number;
@BelongsTo(() => User, 'userId')
user: User;
}Use the Repository pattern for clean data access with multiple database support:
import { Repository, Connection } from 'foundry-orm';
// Create repositories with different connections
const userRepo = new Repository(User, primaryConnection, 'postgres');
const analyticsRepo = new Repository(Event, analyticsConnection, 'mysql');
// CRUD operations
const user = await userRepo.find(1);
const users = await userRepo.findAll({ where: { active: true }, limit: 10 });
const newUser = await userRepo.create({ name: 'Jane', email: '[email protected]' });
await userRepo.update(1, { name: 'Updated Name' });
await userRepo.delete(1);
// Utility methods
const count = await userRepo.count({ active: true });
const exists = await userRepo.exists(1);const user = await User.create({
name: 'Jane Smith',
email: '[email protected]'
});
await user.save();// Find by ID
const user = await User.find(1);
// Find all
const users = await User.findAll();
// Find with conditions
const activeUsers = await User.findAll({
where: { isActive: true },
limit: 10,
offset: 0
});const user = await User.find(1);
user.name = 'Updated Name';
await user.save();const user = await User.find(1);
await user.delete();
// Or delete by ID
await User.destroy(1);await connection.getAdapter().transaction(async (adapter) => {
const user = await User.create({ name: 'Test', email: '[email protected]' });
await user.save();
const order = await Order.create({ userId: user.id, total: 100.00 });
await order.save();
// If anything fails, transaction rolls back automatically
});import { QueryBuilder } from 'foundry-orm';
const query = new QueryBuilder('users')
.select('id', 'name', 'email')
.where('isActive', '=', true)
.where('createdAt', '>', '2023-01-01')
.orderBy('createdAt', 'DESC')
.limit(10)
.offset(0);
const users = await connection.query(query.build());FoundryORM provides comprehensive error handling with custom error types:
import { ORMErrors } from 'foundry-orm';
try {
await connection.connect();
const user = await User.find(999);
} catch (error) {
if (error instanceof ORMErrors.ConnectionError) {
console.error('Database connection failed:', error.message);
} else if (error instanceof ORMErrors.QueryError) {
console.error('Query execution failed:', error.message);
console.error('SQL:', error.sql);
} else if (error instanceof ORMErrors.ValidationError) {
console.error('Validation failed:', error.message);
} else if (error instanceof ORMErrors.NotFoundError) {
console.error('Record not found');
}
}Implement custom logging by extending the ILogger interface:
import { ILogger } from 'foundry-orm';
class CustomLogger implements ILogger {
info(message: string, meta?: any): void {
console.log(`[INFO] ${message}`, meta);
}
warn(message: string, meta?: any): void {
console.warn(`[WARN] ${message}`, meta);
}
error(message: string, meta?: any): void {
console.error(`[ERROR] ${message}`, meta);
}
debug(message: string, meta?: any): void {
console.debug(`[DEBUG] ${message}`, meta);
}
}
const connection = new Connection('postgres', config, new CustomLogger());Monitor database connectivity:
const isHealthy = await connection.healthCheck();
if (isHealthy) {
console.log('Database is healthy');
} else {
console.error('Database health check failed');
}- π Getting Started Guide - Complete setup and basic usage
- ποΈ Models & Decorators - Learn about model definitions
- π Database Connections - Connection configuration
- π Query Builder - Advanced querying
- π Transactions - Transaction management
- π‘ Examples - Real-world examples
- π API Reference - Complete API documentation
# Run tests
npm test
# Run tests with coverage
npm run test:coverage
# Run specific test file
npm test -- tests/models.test.tsWe welcome contributions!
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Make your changes and add tests
- Run the test suite:
npm test - Commit your changes:
git commit -am 'Add my feature' - Push to the branch:
git push origin feature/my-feature - Submit a pull request
# Clone the repository
git clone https://github.com/sitharaj88/foundry-orm.git
cd foundry-orm
# Install dependencies
npm install
# Run in development mode
npm run dev
# Build for production
npm run build
# Run tests
npm testThis project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- π Repository Pattern - Clean data access layer with multiple connection support
- π Relationship Decorators -
@HasMany,@HasOne,@BelongsTo,@ManyToMany - π§ Cross-Database Query Builder - Dialect-aware placeholder generation
- π SQL Injection Prevention - Built-in identifier sanitization
- π‘οΈ Enhanced Type Safety - Generic types for BaseModel methods
- π Standardized Query Results - Unified
QueryResultinterface
- π Initial alpha release
- β Multi-database support (PostgreSQL, MySQL, SQLite, MongoDB)
- β Connection pooling
- β Transaction support
- β Decorator-based models (@Entity, @Column)
- β Query builder
- β Health checks
- β Comprehensive logging
- β TypeScript support
- Built with β€οΈ for the TypeScript and Node.js community
- Inspired by popular ORMs like TypeORM and Sequelize
- Thanks to all our contributors!
- π Issues: GitHub Issues
- π Documentation: Official Docs
- π¬ Discussions: GitHub Discussions
FoundryORM v0.2.0-alpha.1 - Building the future of TypeScript ORMs