webcake-data
v1.0.15
Published
A modern JavaScript/TypeScript client library for WebCake database operations with MongoDB-like query interface
Downloads
566
Maintainers
Readme
WebCake Data
A modern JavaScript/TypeScript client library for WebCake database operations with MongoDB-like query interface.
Features
- 🚀 Modern ES6+ Module Support - Works with both Node.js and browsers
- 🔍 MongoDB-like Query Interface - Familiar query syntax for easy adoption
- 🎯 TypeScript Support - Full TypeScript definitions included
- 🌐 Browser & Node.js Compatible - Works everywhere JavaScript runs
- 📦 Zero Dependencies - Lightweight with no external dependencies
- 🔗 Fluent API - Chainable query builder for complex operations
- ⚡ Minified Builds - Optimized and compressed for production use
Installation
npm install webcake-dataQuick Start
ES6 Modules
import { DBConnection } from 'webcake-data';
// Initialize connection
const db = new DBConnection({
// baseURL/siteId/token are preconfigured on WebCake-hosted sites;
// override only if you use a custom backend. Headers still need to be set.
baseURL: 'https://api.webcake.com/api/v1',
siteId: 'your-site-id',
token: 'your-auth-token',
headers: {
'x-cms-api-key': 'your-api-key' // For API permission checking
}
});
// Create a model
const User = db.model('users');
// Create a user
const user = await User.create({
name: 'John Doe',
email: '[email protected]',
age: 30,
active: true
});
// Find users
const users = await User.find({ active: true }).exec();CommonJS (Node.js)
const { DBConnection } = require('webcake-data');Browser (Global)
Using CDN (Unpkg or JSDelivr):
<!-- Minified version (recommended for production) -->
<script src="https://unpkg.com/webcake-data@latest/dist/webcake-data.umd.min.js"></script>
<script>
const db = new WebCakeData.DBConnection({
baseURL: '/api/v1',
siteId: 'your-site-id',
headers: {
'x-cms-api-key': 'your-api-key' // For API permission checking
}
});
</script>Using JSDelivr:
<script src="https://cdn.jsdelivr.net/npm/webcake-data@latest/dist/webcake-data.umd.min.js"></script>API Reference
DBConnection
Main connection class for database operations.
Constructor
new DBConnection(config)Parameters:
config.baseURL(string, optional): API base URLconfig.domain(string, optional): Domain base URL (overrides default relative path if provided)config.siteId(string, optional): Site ID (auto-detected from DOM if not provided)config.token(string, optional): Authentication tokenconfig.headers(object, optional): Additional headersconfig.headers['x-cms-api-key'](string, optional): API key for permission checking
Automatic Header Injection:
The library automatically monitors window.store_post and window.store_product. If present, it injects x-article-id and x-product-id headers respectively.
Example:
const db = new DBConnection({
baseURL: 'https://api.webcake.com/api/v1', // Optional: defaults to /api/v1
domain: 'https://api.webcake.com', // Optional: Base domain to prepend to baseURL
siteId: 'your-site-id',
token: 'your-auth-token',
headers: {
'x-cms-api-key': 'your-api-key' // For API permission checking
}
});
// Automatic Header Injection:
// If window.store_post or window.store_product are present,
// the library will automatically inject 'x-article-id' and 'x-product-id' headers.Methods
model(collectionName)- Create a model for a collectioninsertOne(tableName, fields)- Insert a single recordinsertMany(tableName, records)- Insert multiple recordsquery(tableName, queryParams)- Query recordsupdateById(tableName, id, fields)- Update record by IDupdateOne(tableName, filters, fields)- Update one recordupdateMany(tableName, filters, fields)- Update multiple recordsdeleteById(tableName, id)- Delete record by IDdeleteOne(tableName, filters)- Delete one recorddeleteMany(tableName, filters)- Delete multiple recordscount(tableName, filters)- Count recordsexists(tableName, filters)- Check if records exist
DBModel
Model class for collection operations.
Methods
create(data)- Create a new documentinsertMany(dataArray)- Create multiple documentsfind(filters)- Find documents (returns QueryBuilder)findOne(filters, options)- Find one document with optional select/sort/populatefindById(id, options)- Find document by ID with optional select/sort/populateupdateOne(filters, updateData)- Update one documentfindByIdAndUpdate(id, updateData, options)- Update document by IDfindOneAndUpdate(filters, updateData)- Find and update one documentupdateMany(filters, updateData)- Update multiple documentsdeleteOne(filters)- Delete one documentfindByIdAndDelete(id)- Delete document by IDfindOneAndDelete(filters)- Find and delete one documentdeleteMany(filters)- Delete multiple documentscountDocuments(filters)- Count documentsexists(filters)- Check if documents exist
findOne/findById options:
select(string | string[]): Fields to returnsort(object): Sort order applied before taking the first recordpopulate(object | object[]): Populate configuration(s) identical toQueryBuilder.populate()
QueryBuilder
Fluent query builder for complex database queries.
Methods
where(field, operator, value)- Add filter condition (supports: where(obj), where(field, value), or where(field, operator, value))eq(field, value)- Equality filtergt(field, value)- Greater than filtergte(field, value)- Greater than or equal filterlt(field, value)- Less than filterlte(field, value)- Less than or equal filterin(field, values)- In array filternin(field, values)- Not in array filterne(field, value)- Not equal filterbetween(field, value1, value2)- Between values filterlike(field, pattern)- Pattern matching filtersort(sortObj)- Sort resultslimit(n)- Limit number of resultsskip(n)- Skip number of resultsselect(fields)- Select specific fieldspopulate(config)- Populate related dataexec()- Execute query
Usage Examples
Basic CRUD Operations
import { DBConnection } from 'webcake-data';
const db = new DBConnection({
baseURL: 'https://api.webcake.com/api/v1',
siteId: 'your-site-id',
token: 'your-auth-token',
headers: {
'x-cms-api-key': 'your-api-key' // For API permission checking
}
});
const User = db.model('users');
// Create
const user = await User.create({
name: 'John Doe',
email: '[email protected]',
age: 30,
active: true
});
// Read
const users = await User.find({ active: true }).exec();
const user = await User.findOne(
{ email: '[email protected]' },
{
select: ['id', 'name', 'email'],
populate: {
field: 'profile',
table: 'profiles',
referenceField: 'user_id',
select: 'avatar bio'
}
}
);
const userById = await User.findById('user-id', {
select: 'id name email',
sort: { inserted_at: -1 }
});
// Update
await User.updateOne(
{ email: '[email protected]' },
{ age: 31, active: false }
);
await User.findByIdAndUpdate('user-id', { age: 32 }, { new: true });
// Delete
await User.deleteOne({ email: '[email protected]' });
await User.findByIdAndDelete('user-id');Advanced Queries
// Using where with object
const results1 = await User.find()
.where({ active: true, age: { $gte: 25 } })
.exec();
// Complex query with multiple conditions
const results = await User.find()
.where('age').gte(25).lte(40)
.where('active', true)
.in('name', ['John', 'Jane', 'Bob'])
.like('email', '%@example.com')
.sort({ age: -1, name: 1 })
.limit(20)
.skip(10)
.select('name email age')
.exec();
// Population (joins) with object-based where and sort
const usersWithPosts = await User.find()
.populate({
field: 'posts',
table: 'posts',
referenceField: 'user_id',
select: 'title content',
where: { published: true },
sort: { inserted_at: -1 },
limit: 5
})
.exec();
// Count and exists
const activeUserCount = await User.countDocuments({ active: true });
const userExists = await User.exists({ email: '[email protected]' });Batch Operations
// Insert multiple records
await User.insertMany([
{ name: 'Jane', email: '[email protected]', age: 25, active: true },
{ name: 'Bob', email: '[email protected]', age: 35, active: false }
]);
// Update multiple records
await User.updateMany({ active: false }, { active: true });
// Delete multiple records
await User.deleteMany({ active: false });Error Handling
try {
const user = await User.create({
name: 'John Doe',
email: '[email protected]'
});
} catch (error) {
console.error('Failed to create user:', error.message);
}TypeScript Support
The library includes full TypeScript definitions:
import { DBConnection, DBModel, QueryBuilder } from 'webcake-data';
interface User {
id: string;
name: string;
email: string;
age: number;
active: boolean;
}
const db = new DBConnection({
baseURL: 'https://api.webcake.com/api/v1',
siteId: 'your-site-id',
headers: {
'x-cms-api-key': 'your-api-key' // For API permission checking
}
});
const UserModel: DBModel = db.model<User>('users');Browser Integration
The library automatically detects the site ID from DOM attributes:
<html x:id="your-site-id" x:env="production">
<!-- Your content -->
</html>Or you can provide it explicitly:
const db = new DBConnection({
siteId: 'your-site-id'
});Development
Building the Library
The library uses Rollup for bundling and minification. Build scripts are available:
# Build minified and unminified versions for all formats
npm run build
# Production build with optimizations
npm run build:prodBuild outputs are generated in the dist/ directory:
webcake-data.esm.min.js- ES Module (minified, ~7.4KB)webcake-data.umd.min.js- UMD format (minified, ~7.6KB) - for browserswebcake-data.esm.js- ES Module (unminified)webcake-data.umd.js- UMD format (unminified)
File Sizes
The minified builds are optimized for production use:
- ESM Minified: ~7.4KB
- UMD Minified: ~7.6KB (includes browser global export)
Minification Details
The library is minified using Terser with the following optimizations:
- Variable name mangling
- Dead code elimination
- Whitespace and comment removal
- Property access optimization
- 2-pass compression for maximum size reduction
Contributing
To contribute to the library:
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Make your changes and add tests
- Run the build:
npm run build - 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
MIT License - see LICENSE file for details.
Support
For support, please open an issue on GitHub.
AI Helper Prompt
Users can copy this prompt into ChatGPT, Gemini, Claude, or any AI assistant to get high-quality help with WebCake Data. For best results, share it together with the raw code bundle (https://raw.githubusercontent.com/vuluu2k/webcake-data/main/repomix-output.txt) so the AI can read the entire library context:
You are a senior full-stack engineer specializing in the WebCake Data JavaScript/TypeScript library - a modern MongoDB-like query interface for WebCake database operations.
## Context & Documentation
- Read the full repository context from: https://raw.githubusercontent.com/vuluu2k/webcake-data/main/repomix-output.txt
- Official documentation: https://github.com/vuluu2k/webcake-data
- The library provides three main classes: DBConnection, DBModel, and QueryBuilder
- Supports both browser (UMD) and Node.js (ESM/CommonJS) environments
## Core Principles
1. **Database Field Convention**: Use `inserted_at` for timestamp fields, NOT `created_at`
2. **Query Builder Pattern**: Leverage fluent API for complex queries with method chaining
3. **Population (Joins)**: Use populate() for relational data with proper referenceField configuration
4. **Error Handling**: Always wrap database operations in try-catch blocks
5. **Performance**: Use select() to limit fields, limit/skip for pagination, and indexes for sorting
## Your Task Workflow
When helping users with WebCake Data:
### 1. Clarify Requirements
Ask about:
- Collection/table names and their relationships
- Filter conditions and query complexity
- Fields to select/return (use select() for performance)
- Pagination needs (limit/skip values)
- Population requirements (which related data to join)
- Sorting preferences (use inserted_at for chronological sorting)
- Environment (browser vs Node.js, TypeScript vs JavaScript)
- Authentication setup (baseURL, siteId, token, headers)
### 2. Design the Solution
- Identify which API methods to use (find, findOne, findById, create, update, delete)
- Plan query builder chain for complex conditions
- Design population strategy for relational data
- Consider performance optimizations (field selection, pagination)
### 3. Write Production-Ready Code
Follow these patterns:
**Connection Setup:**
```javascript
import { DBConnection } from 'webcake-data';
const db = new DBConnection({
baseURL: 'https://api.webcake.com/api/v1',
siteId: 'your-site-id',
token: 'your-auth-token',
headers: {
'x-cms-api-key': 'your-api-key'
}
});CRUD Operations:
const User = db.model('users');
// Create with inserted_at
const user = await User.create({
name: 'John Doe',
email: '[email protected]',
inserted_at: new Date()
});
// Query with filters
const users = await User.find({ active: true })
.where('age').gte(18).lte(65)
.select('name email age')
.sort({ inserted_at: -1 })
.limit(20)
.skip(0)
.exec();
// Update
await User.findByIdAndUpdate(userId, { age: 31 }, { new: true });
// Delete
await User.findByIdAndDelete(userId);Population (Joins):
const usersWithPosts = await User.find()
.populate({
field: 'posts',
table: 'posts',
referenceField: 'user_id',
select: 'title content',
where: { published: true },
sort: { inserted_at: -1 },
limit: 5
})
.exec();Error Handling:
try {
const result = await User.create(userData);
return { success: true, data: result };
} catch (error) {
console.error('Database operation failed:', error.message);
return { success: false, error: error.message };
}4. Explain Your Solution
- Describe why each method/operator was chosen
- Explain how populate() creates the join relationship
- Clarify pagination behavior (skip/limit)
- Note performance implications (indexes, field selection)
- Highlight error handling strategy
5. Provide Context & Alternatives
- Call out any assumptions made
- Suggest alternative approaches when applicable
- Mention testing strategies
- Note any environment-specific considerations
Critical Rules
✅ DO:
- Use
inserted_atfor all timestamp fields - Use async/await for all database operations
- Wrap operations in try-catch blocks
- Use select() to limit returned fields
- Use populate() for relational data
- Follow the fluent API pattern for queries
- Use object-based where() for complex filters:
.where({ field: value, age: { $gte: 25 } }) - Provide self-contained, runnable code examples
❌ DON'T:
- Use
created_at(useinserted_atinstead) - Use undocumented or private APIs
- Forget error handling
- Return all fields when only some are needed
- Use synchronous patterns
- Make assumptions about schema without asking
- Provide incomplete code snippets
Example Response Format
- Requirements Summary: Briefly restate what the user needs
- Solution Plan: List the APIs and approach
- Code Implementation: Provide complete, runnable code
- Explanation: Explain key decisions and patterns
- Next Steps: Suggest testing approach or improvements
Additional Resources
- MongoDB-like operators: $gte, $lte, $gt, $lt, $in, $nin, $ne, $like
- Query methods: where(), eq(), gt(), gte(), lt(), lte(), in(), nin(), ne(), between(), like()
- Options: select, sort, limit, skip, populate
- findOne/findById support options: { select, sort, populate }
Remember: Clarity, correctness, and production-readiness are paramount. Always provide code that follows best practices and can be used immediately.
