UNPKG

jdb-lite

Version:

A lightweight schema-based JSON database library with validation

497 lines (388 loc) • 11 kB
# jdb-lite A lightweight, zero-dependency JSON database for Node.js with a familiar API. Perfect for small projects, prototyping, or when you need a simple file-based database without the complexity of traditional databases. ## ✨ Features - šŸ”„ **Familiar API** - Mongoose-like interface that feels natural - šŸ“ **JSON File Storage** - Data stored in simple JSON files - šŸ”§ **Schema Validation** - Define and validate your data structure - šŸ“¦ **Multi-format Support** - Works with CommonJS, ES Modules, TypeScript, and JavaScript - šŸ” **Full CRUD Operations** - Create, Read, Update, Delete with filtering and sorting - šŸŽÆ **TypeScript Support** - Full type safety and IntelliSense - ⚔ **Zero Dependencies** - Lightweight with no external dependencies - šŸš€ **Easy Setup** - Get started in minutes ## šŸ“¦ Installation ```bash npm install jdb-lite ``` ## šŸš€ Quick Start ### JavaScript (CommonJS) ```javascript const JsonDB = require('jdb-lite'); const { Schema } = require('jdb-lite'); // Define a schema const userSchema = new Schema({ name: { type: 'String', required: true }, email: { type: 'String', required: true }, age: { type: 'Number', required: true }, isActive: { type: 'Boolean', default: true } }); // Connect and create model async function main() { await JsonDB.connect('./my-database'); const User = JsonDB.model('User', userSchema); // Create a user const user = new User({ name: 'John Doe', email: 'john@example.com', age: 30 }); await user.save(); console.log('User saved!', user); } main(); ``` ### JavaScript (ES Modules) ```javascript import JsonDB, { Schema } from 'jdb-lite'; const userSchema = new Schema({ name: { type: 'String', required: true }, email: { type: 'String', required: true }, age: { type: 'Number', required: true } }); await JsonDB.connect('./my-database'); const User = JsonDB.model('User', userSchema); const user = await User.create({ name: 'Jane Doe', email: 'jane@example.com', age: 25 }); console.log('User created!', user); ``` ### TypeScript ```typescript import JsonDB, { Schema, Document } from 'jdb-lite'; // Define interface interface IUser extends Document { name: string; email: string; age: number; isActive?: boolean; } // Create schema with type safety const userSchema = new Schema<IUser>({ name: { type: 'String', required: true }, email: { type: 'String', required: true }, age: { type: 'Number', required: true }, isActive: { type: 'Boolean', default: true } }); await JsonDB.connect('./my-database'); const User = JsonDB.model<IUser>('User', userSchema); // Type-safe operations const user: IUser = await User.create({ name: 'Alice Smith', email: 'alice@example.com', age: 28 }); ``` ## šŸ“– Complete Usage Guide ### 1. Connection ```javascript // Connect to database (creates folder if doesn't exist) await JsonDB.connect('./my-database'); // Or specify a different path await JsonDB.connect('/path/to/database'); // Disconnect when done await JsonDB.disconnect(); ``` ### 2. Schema Definition ```javascript const userSchema = new Schema({ // String field name: { type: 'String', required: true, default: 'Anonymous' }, // Number field age: { type: 'Number', required: true, validate: (value) => value >= 0 // Custom validation }, // Boolean field isActive: { type: 'Boolean', default: true }, // Date field createdAt: { type: 'Date', default: Date.now }, // Array field tags: { type: 'Array', default: [] }, // Object field settings: { type: 'Object', default: {} } }, { timestamps: true, // Adds createdAt and updatedAt automatically collection: 'users' // Custom collection name (optional) }); ``` ### 3. Creating Documents ```javascript // Method 1: Constructor + save const user = new User({ name: 'John Doe', email: 'john@example.com', age: 30 }); await user.save(); // Method 2: Direct creation const user = await User.create({ name: 'Jane Doe', email: 'jane@example.com', age: 25 }); // Method 3: Create multiple const users = await User.insertMany([ { name: 'User 1', email: 'user1@example.com', age: 20 }, { name: 'User 2', email: 'user2@example.com', age: 30 } ]); ``` ### 4. Reading Documents ```javascript // Find all documents const allUsers = await User.find(); // Find with conditions const adults = await User.find({ age: { $gte: 18 } }); const activeUsers = await User.find({ isActive: true }); // Find one document const user = await User.findOne({ email: 'john@example.com' }); // Find by ID const user = await User.findById('507f1f77bcf86cd799439011'); // Advanced querying const users = await User.find({ age: { $gte: 25 } }) .sort({ age: -1 }) // Sort by age descending .limit(10) // Limit to 10 results .skip(5); // Skip first 5 results // Count documents const count = await User.countDocuments({ isActive: true }); ``` ### 5. Updating Documents ```javascript // Update one document await User.updateOne( { email: 'john@example.com' }, // Filter { age: 31 } // Update ); // Update multiple documents await User.updateMany( { isActive: false }, // Filter { isActive: true } // Update ); // Find and update (returns updated document) const updatedUser = await User.findOneAndUpdate( { email: 'john@example.com' }, { age: 32 }, { new: true } // Return updated document ); // Find by ID and update const user = await User.findByIdAndUpdate( '507f1f77bcf86cd799439011', { name: 'John Smith' }, { new: true } ); ``` ### 6. Deleting Documents ```javascript // Delete one document await User.deleteOne({ email: 'john@example.com' }); // Delete multiple documents await User.deleteMany({ isActive: false }); // Find and delete (returns deleted document) const deletedUser = await User.findOneAndDelete({ email: 'john@example.com' }); // Find by ID and delete const user = await User.findByIdAndDelete('507f1f77bcf86cd799439011'); ``` ### 7. Instance Methods ```javascript const user = await User.findOne({ email: 'john@example.com' }); // Check if document is new (not saved yet) console.log(user.isNew); // false // Check if field was modified user.age = 32; console.log(user.isModified('age')); // true // Convert to plain object const plainObject = user.toObject(); // Convert to JSON const jsonString = JSON.stringify(user.toJSON()); // Validate document await user.validate(); // Save changes await user.save(); // Remove document await user.remove(); ``` ## šŸ—ļø Data Storage Your data is stored in JSON files within the specified database folder: ``` my-database/ ā”œā”€ā”€ users.json # User collection ā”œā”€ā”€ posts.json # Post collection └── comments.json # Comment collection ``` Each collection is a JSON array of documents: ```json [ { "_id": "507f1f77bcf86cd799439011", "name": "John Doe", "email": "john@example.com", "age": 30, "isActive": true, "createdAt": "2023-01-01T00:00:00.000Z", "updatedAt": "2023-01-01T00:00:00.000Z" } ] ``` ## šŸ”§ Advanced Features ### Custom Methods and Statics ```javascript // Add instance methods userSchema.methods.getDisplayName = function() { return this.name.toUpperCase(); }; // Add static methods userSchema.statics.findByEmail = function(email) { return this.findOne({ email }); }; // Usage const user = await User.findOne({ name: 'John' }); console.log(user.getDisplayName()); // "JOHN" const user = await User.findByEmail('john@example.com'); ``` ### Schema Validation ```javascript const userSchema = new Schema({ email: { type: 'String', required: true, validate: (email) => { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(email)) { throw new Error('Invalid email format'); } return true; } }, age: { type: 'Number', required: true, validate: (age) => { if (age < 0 || age > 150) { throw new Error('Age must be between 0 and 150'); } return true; } } }); ``` ## šŸ“± Module System Examples ### Node.js (CommonJS) ```javascript // index.js const JsonDB = require('jdb-lite'); async function main() { await JsonDB.connect('./database'); // Your code here } ``` ### Node.js (ES Modules) ```javascript // index.mjs or with "type": "module" in package.json import JsonDB from 'jdb-lite'; await JsonDB.connect('./database'); // Your code here ``` ### TypeScript ```typescript // index.ts import JsonDB, { Schema, Document } from 'jdb-lite'; interface User extends Document { name: string; email: string; } const userSchema = new Schema<User>({ name: { type: 'String', required: true }, email: { type: 'String', required: true } }); await JsonDB.connect('./database'); const UserModel = JsonDB.model<User>('User', userSchema); ``` ## šŸ” Query Examples ```javascript // Basic queries const users = await User.find({ age: 25 }); const user = await User.findOne({ email: 'john@example.com' }); // Comparison operators const adults = await User.find({ age: { $gte: 18 } }); const seniors = await User.find({ age: { $gt: 65 } }); const young = await User.find({ age: { $lt: 30 } }); // Sorting and limiting const newest = await User.find().sort({ createdAt: -1 }).limit(5); const oldest = await User.find().sort({ createdAt: 1 }).limit(5); // Pagination const page2 = await User.find().skip(10).limit(10); // Counting const totalUsers = await User.countDocuments(); const activeUsers = await User.countDocuments({ isActive: true }); ``` ## šŸ› ļø Error Handling ```javascript try { const user = new User({ name: 'John', // Missing required email field age: 30 }); await user.save(); } catch (error) { console.error('Validation error:', error.message); // "Field 'email' is required" } ``` ## šŸš€ Performance Tips 1. **Use indexes for frequently queried fields** (planned feature) 2. **Limit results with `.limit()`** to avoid loading large datasets 3. **Use `.countDocuments()`** instead of `.find().length` for counting 4. **Close connections** with `JsonDB.disconnect()` when done ## šŸ“š Migration from Other Libraries ### From Mongoose ```javascript // Mongoose const mongoose = require('mongoose'); const User = mongoose.model('User', userSchema); // jdb-lite const JsonDB = require('jdb-lite'); const User = JsonDB.model('User', userSchema); ``` ### From Lowdb ```javascript // Lowdb const low = require('lowdb'); const db = low('db.json'); // jdb-lite const JsonDB = require('jdb-lite'); await JsonDB.connect('./database'); ``` ## šŸ¤ Contributing Contributions are welcome! Please feel free to submit a Pull Request. ## šŸ“„ License MIT License - see [LICENSE](LICENSE) file for details. --- **Made with ā¤ļø for developers who need a simple, reliable JSON database solution.**