MasterRecord ORM
MasterRecord is a lightweight, code-first Object-Relational Mapper (ORM) for Node.js, currently at version 1.0.4. It emphasizes a fluent, lambda-based query API, a comprehensive CLI-driven migration system, and out-of-the-box support for multiple relational databases including MySQL (5.7+/8.0+), PostgreSQL (9.6+/12+), and SQLite (3.x). The ORM operates on an Active Record pattern, providing entity serialization, lifecycle hooks, and built-in validation. A key differentiator is its "ESM only" nature, requiring Node.js 20+ and a host project configured as a module, with no CommonJS build available. It offers features like query result caching, bulk operations, and robust SQL injection protection through parameterized queries. The project seems to follow a stable release cadence with its initial major v1.0 release.
Common errors
-
ERR_REQUIRE_ESM: require() of ES module .../masterrecord/index.js from ... not supported.
cause Attempting to import MasterRecord using CommonJS `require()` syntax in a non-ESM project, or in an older Node.js environment.fixEnsure your project's `package.json` has `"type": "module"` and use `import { ... } from 'masterrecord';` syntax. Upgrade your Node.js environment to version 20.0.0 or newer. -
Error: The current Node.js version (vX.Y.Z) is not supported. MasterRecord requires Node.js v20.0.0 or higher.
cause Running MasterRecord with an incompatible Node.js version.fixUpgrade your Node.js environment to version 20.0.0 or newer. Consider using a version manager like `nvm` or `volta` to manage Node.js versions. -
TypeError: MasterRecord.create is not a function OR Cannot read properties of undefined (reading 'create')
cause Attempting to create an entity instance directly via `new YourEntityClass()` instead of using the factory method, or incorrectly accessing the `create` method.fixAlways ensure you are correctly importing `MasterRecord` and using the factory method as `const newEntity = MasterRecord.create(YourEntityClass, { data });`. -
Error: connect ECONNREFUSED 127.0.0.1:3306 (for MySQL) / Connection refused (for PostgreSQL) / SQLITE_CANTOPEN: unable to open database file
cause The database server is not running, is inaccessible from the application's host, or the connection credentials (host, port, user, password, database) are incorrect. For SQLite, the path to the database file might be invalid or permissions might be insufficient.fixVerify that your database server is running and accessible. Double-check all connection parameters in your `MasterRecord.configure()` settings. Ensure no firewalls are blocking the connection. For SQLite, check the `filename` path and file system permissions.
Warnings
- breaking MasterRecord v1.0+ is a pure ECMAScript Module (ESM) package. It does not provide a CommonJS build and requires Node.js v20.0.0 or higher. Your project's `package.json` must include `"type": "module"`.
- gotcha When creating new entity instances, it is critical to use the `MasterRecord.create(Entity, data)` factory method instead of directly instantiating with `new Entity(data)`. Direct instantiation bypasses internal lifecycle hooks, validation, and proper field initialization.
- gotcha While MasterRecord offers 'Raw SQL Queries' as an advanced feature, developers should exercise extreme caution. Although the ORM's primary query API provides automatic SQL injection protection, direct raw SQL requires manual parameterization and sanitization to prevent security vulnerabilities.
- gotcha The `MasterRecord.syncSchema()` method is convenient for rapid development and testing but should not be used in production environments, as it can lead to data loss or unintended schema changes. Production environments should rely exclusively on the CLI-driven migration system.
Install
-
npm install masterrecord -
yarn add masterrecord -
pnpm add masterrecord
Imports
- MasterRecord
const { MasterRecord } = require('masterrecord');import { MasterRecord } from 'masterrecord'; - defineEntity
const { defineEntity } = require('masterrecord');import { defineEntity } from 'masterrecord'; - Entity
const { Entity } = require('masterrecord');import { Entity } from 'masterrecord';
Quickstart
import { MasterRecord } from 'masterrecord';
// 1. Define an entity extending MasterRecord.Entity
class User extends MasterRecord.Entity {
id!: number;
name!: string;
email!: string;
age?: number;
static tableName = 'users'; // Explicitly define the table name
static fields = {
id: { type: 'number', primaryKey: true, autoIncrement: true },
name: { type: 'string', required: true, length: { min: 3, max: 255 } },
email: { type: 'string', required: true, pattern: /^\S+@\S+\.\S+$/, unique: true },
age: { type: 'number', required: false, min: 18 }
};
}
async function runMasterRecord() {
// 2. Configure MasterRecord for SQLite database
await MasterRecord.configure({
connection: {
client: 'sqlite',
filename: './quickstart.sqlite'
},
entities: [User],
debug: process.env.NODE_ENV !== 'production' // Enable logging in development
});
// 3. Sync schema (for development; use migrations in production)
await MasterRecord.syncSchema();
console.log('Database schema synced successfully for User entity.');
// 4. Create a new user instance using the factory method
const newUser = MasterRecord.create(User, {
name: 'Alice Wonderland',
email: 'alice@example.com',
age: 28
});
await newUser.save();
console.log('Created new user:', newUser.toObject());
// 5. Find a user by email
const foundUser = await MasterRecord.query(User).where(u => u.email === 'alice@example.com').first();
if (foundUser) {
console.log('Found user:', foundUser.toObject());
// 6. Update the user
foundUser.age = 29;
await foundUser.save();
console.log('Updated user age:', foundUser.toObject());
}
// 7. Disconnect from the database
await MasterRecord.disconnect();
console.log('MasterRecord disconnected.');
}
runMasterRecord().catch(console.error);