@dreamtree-org/korm-js
v1.0.34
Published
Knowledge Object-Relational Mapping - A powerful, modular ORM system for Node.js with dynamic database operations, complex queries, relationships, and nested requests
Maintainers
Readme
KORM-JS
Knowledge Object-Relational Mapping - A powerful, modular ORM system for Node.js with dynamic database operations, complex queries, relationships, and nested requests.
Features
- 🚀 Multi-Database Support: MySQL, PostgreSQL, SQLite
- 🔧 Dynamic Operations: Create, Read, Update, Delete with ease
- 🔍 Advanced Querying: Complex queries with relationships
- 🛡️ Data Validation: Built-in request validation with custom rules
- 🔄 Auto-Sync: Automatic table schema synchronization
- 📦 Modular Design: Use only what you need
- 🎯 Express.js Ready: Perfect integration with Express applications
- 🔄 Schema Generation: Auto-generate schemas from existing databases
Installation
npm install korm-jsQuick Start with Express.js and PostgreSQL
1. Basic Setup
require('dotenv').config();
const express = require('express');
const { initializeKORM, validate, helperUtility } = require('korm-js');
const knex = require('knex');
const app = express();
app.use(express.json());
// Database configuration
const db = knex({
client: 'pg',
connection: {
host: process.env.DB_HOST || 'localhost',
user: process.env.DB_USER || 'your_user',
password: process.env.DB_PASS || 'your_pass',
database: process.env.DB_NAME || 'your_db'
}
});
// Initialize KORM
const korm = initializeKORM({
db: db,
dbClient: 'pg'
});
app.listen(3000, () => {
console.log('🚀 Server running on http://localhost:3000');
});2. Schema Generation and Database Sync
async function initApp() {
// Load existing schema if available
let syncSchema = helperUtility.file.readJSON('schema/sync.json');
korm.setSchema(syncSchema);
// Sync database with schema
await korm.syncDatabase().then(() => {
console.log('✅ Database synced');
});
// Generate schema from existing database
await korm.generateSchema().then(schema => {
korm.setSchema(schema); // Set the schema to the korm instance
helperUtility.file.createDirectory('schema');
helperUtility.file.writeJSON('schema/schema.json', schema);
console.log('✅ Schema generated and saved');
});
}
// Initialize the application
initApp();3. Generic CRUD API Endpoint
// Generic CRUD endpoint for any model
app.post('/api/:model/crud', async (req, res) => {
try {
const { model } = req.params;
const result = await korm.processRequest(req.body, model);
res.json(result);
} catch (error) {
res.status(400).json({ error: error.message });
}
});
// Health check endpoint
app.get('/health', (req, res) => {
res.send('OK');
});4. Example API Usage
// Create a new record
POST /api/Users/crud
{
"action": "create",
"data": {
"username": "john_doe",
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe"
}
}
// Get all records
POST /api/Users/crud
{
"action": "list",
"where": { "is_active": true },
"select": ["id", "username", "email", "first_name", "last_name"],
"sort": [["created_at", "desc"]],
"limit": 10
}
// Get single record
POST /api/Users/crud
{
"action": "show",
"where": { "id": 1 }
}
// Update record
POST /api/Users/crud
{
"action": "update",
"where": { "id": 1 },
"data": {
"first_name": "Jane",
"updated_at": "2024-01-01T00:00:00Z"
}
}
// Delete record
POST /api/Users/crud
{
"action": "delete",
"where": { "id": 1 }
}
// Count records
POST /api/Users/crud
{
"action": "count",
"where": { "is_active": true }
}5. Advanced Querying Examples
// Complex search with multiple conditions
POST /api/Users/crud
{
"action": "list",
"where": {
"first_name": { "like": "%John%" },
"email": { "like": "%@example.com" },
"is_active": true
},
"select": ["id", "username", "email", "first_name", "last_name"],
"sort": [["created_at", "desc"]],
"limit": 10
}
// Pagination with offset
POST /api/Users/crud
{
"action": "list",
"select": ["id", "username", "email", "first_name", "last_name"],
"sort": [["created_at", "desc"]],
"limit": 10,
"offset": 20
}
// Count with conditions
POST /api/Users/crud
{
"action": "count",
"where": {
"is_active": true,
"created_at": { ">=": "2024-01-01" }
}
}
// Join queries (if relationships are defined)
POST /api/Users/crud
{
"action": "list",
"select": ["id", "username", "email"],
"join": [
{
"table": "user_profiles",
"on": "users.id = user_profiles.user_id"
}
],
"where": { "users.is_active": true }
}6. Data Validation Example
const { validate } = require('korm-js');
// Define validation rules
const userValidationRules = {
username: 'required|type:string|maxLen:50',
email: 'required|type:string|maxLen:255',
first_name: 'required|type:string|maxLen:100',
last_name: 'required|type:string|maxLen:100',
age: 'type:number|min:0|max:150'
};
// Validate and create user
app.post('/api/users/validate', async (req, res) => {
try {
// Validate request data
const validatedData = await validate(req.body, userValidationRules);
const result = await korm.processRequest({
action: 'create',
data: {
...validatedData,
created_at: new Date(),
updated_at: new Date()
}
}, 'Users');
res.status(201).json({
success: true,
message: 'User created successfully',
data: result.data
});
} catch (error) {
if (error.name === 'ValidationError') {
return res.status(400).json({
success: false,
message: 'Validation failed',
errors: error.message.details
});
}
res.status(500).json({
success: false,
message: 'Error creating user',
error: error.message
});
}
});7. Schema Structure Example
// Example schema structure (auto-generated)
{
"Users": {
"table": "users",
"alias": "Users",
"columns": {
"id": "bigint|size:8|default:nextval('users_id_seq'::regclass)",
"username": "character varying|size:255",
"email": "character varying|size:255",
"first_name": "character varying|size:255|nullable",
"last_name": "character varying|size:255|nullable",
"is_active": "boolean|default:true",
"created_at": "timestamp with time zone|default:now()",
"updated_at": "timestamp with time zone|default:now()"
},
"modelName": "Users",
"seed": [],
"hasRelations": {},
"indexes": []
}
}API Reference
KORM Instance Methods
const korm = initializeKORM({
db: db,
dbClient: 'pg' // or 'mysql', 'sqlite'
});
// Process any CRUD request
const result = await korm.processRequest(requestBody, modelName);
// Set schema manually
korm.setSchema(schemaObject);
// Sync database with schema
await korm.syncDatabase();
// Generate schema from existing database
const schema = await korm.generateSchema();ProcessRequest Actions
// List records
{
"action": "list",
"where": { "is_active": true },
"select": ["id", "name", "email"],
"sort": [["created_at", "desc"]],
"limit": 10,
"offset": 0
}
// Show single record
{
"action": "show",
"where": { "id": 1 }
}
// Create record
{
"action": "create",
"data": { "name": "John", "email": "[email protected]" }
}
// Update record
{
"action": "update",
"where": { "id": 1 },
"data": { "name": "Jane" }
}
// Delete record
{
"action": "delete",
"where": { "id": 1 }
}
// Count records
{
"action": "count",
"where": { "is_active": true }
}Validation Rules
const { validate } = require('korm-js');
// Basic validation rules
const rules = {
username: 'required|type:string|minLen:3|maxLen:30',
email: 'required|type:string|maxLen:255',
age: 'type:number|min:0|max:150',
status: 'in:active,inactive,pending'
};
// Advanced validation with custom patterns
const advancedRules = {
username: 'required|type:string|regex:username',
email: 'required|type:string|regex:email',
phone: 'regex:phone',
user_id: 'exists:users,id'
};
const customRegex = {
username: /^[a-zA-Z0-9_]+$/,
email: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
phone: /^\+?[\d\s-()]{10,15}$/
};
const validatedData = await validate(data, rules, { customRegex });Helper Utilities
const { helperUtility } = require('korm-js');
// File operations
helperUtility.file.readJSON('path/to/file.json');
helperUtility.file.writeJSON('path/to/file.json', data);
helperUtility.file.createDirectory('path/to/directory');
// Other utilities available through helperUtilityDatabase Support
PostgreSQL (Recommended)
const knex = require('knex');
const db = knex({
client: 'pg',
connection: {
host: process.env.DB_HOST || 'localhost',
user: process.env.DB_USER || 'username',
password: process.env.DB_PASS || 'password',
database: process.env.DB_NAME || 'database_name',
port: process.env.DB_PORT || 5432
}
});
const korm = initializeKORM({
db: db,
dbClient: 'pg'
});MySQL
const knex = require('knex');
const db = knex({
client: 'mysql2',
connection: {
host: process.env.DB_HOST || 'localhost',
user: process.env.DB_USER || 'username',
password: process.env.DB_PASS || 'password',
database: process.env.DB_NAME || 'database_name',
port: process.env.DB_PORT || 3306
}
});
const korm = initializeKORM({
db: db,
dbClient: 'mysql'
});SQLite
const knex = require('knex');
const db = knex({
client: 'sqlite3',
connection: {
filename: process.env.DB_FILE || './database.sqlite'
}
});
const korm = initializeKORM({
db: db,
dbClient: 'sqlite'
});Error Handling
app.use((error, req, res, next) => {
console.error('KORM Error:', error);
res.status(500).json({
success: false,
message: 'Internal server error',
error: process.env.NODE_ENV === 'development' ? error.message : 'Something went wrong'
});
});Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
If you have any questions or need help, please open an issue on GitHub or contact us at [email protected].
Made with ❤️ by Partha Preetham Krishna
