1.0.4 • Published 5 months ago
@vitkuz/aws-dynamodb v1.0.4
AWS DynamoDB Helper
A lightweight TypeScript library for seamless DynamoDB operations with strong typing, pagination handling, and batch operations.
Features
- 🚀 Simple API: Intuitive methods for common DynamoDB operations
- 📦 TypeScript Support: Full type definitions for better developer experience
- 🔄 Automatic Pagination: Handles DynamoDB pagination internally
- 🧩 Batch Operations: Efficient batch operations with automatic chunking
- 🔍 Flexible Querying: Query by index or scan with any property condition
- 🔄 Deep Merging: Support for merging deeply nested properties on patch operations
- 🧠 Smart Logging: Comprehensive, emoji-rich logging for easy debugging
- 🛡️ Error Handling: Robust error handling with descriptive messages
Installation
npm install @vitkuz/aws-dynamodb
Configuration
import { createContext } from '@vitkuz/aws-dynamodb';
const context = createContext({
region: 'your-aws-region',
// Optional: provide AWS credentials if not using AWS SDK default config
credentials: {
accessKeyId: 'your-access-key',
secretAccessKey: 'your-secret-key'
}
});
Usage Examples
Single Item Operations
import {
createContext,
createOne,
updateById,
patchOneById,
deleteOneById,
getOneById,
getAll
} from '@vitkuz/aws-dynamodb';
// Create a new item (generates UUID automatically)
const user = await createOne(context, 'users', {
name: 'John Doe',
email: 'john@example.com',
status: 'active'
});
// Get item by ID
const foundUser = await getOneById(context, 'users', user.id);
// Update item (full replace)
const updatedUser = await updateById(context, 'users', user.id, {
name: 'John Updated',
email: 'john.updated@example.com',
status: 'inactive'
});
// Partial update (patch) - supports deep merge of nested properties
const patchedUser = await patchOneById(context, 'users', user.id, {
status: 'active',
profile: {
preferences: {
notifications: {
email: true
}
}
}
});
// Delete item
const deleted = await deleteOneById(context, 'users', user.id);
// Get all items (handles pagination automatically)
const allUsers = await getAll(context, 'users');
Query Operations
import { query, scanByProperty } from '@vitkuz/aws-dynamodb';
// Query using a Global Secondary Index (requires an existing GSI)
const activeUsers = await query(
context,
'users',
'status-index', // GSI name
{ status: 'active' },
'age > :minAge', // Optional filter expression
{ ':minAge': 18 } // Optional expression values
);
// Query by any property (uses scan with filters)
const premiumUsers = await scanByProperty(
context,
'users',
{
status: 'active',
accountType: 'premium'
}
);
Batch Operations
import { getMany, createMany, deleteMany } from '@vitkuz/aws-dynamodb';
// Batch get items
const users = await getMany(context, 'users', ['id1', 'id2', 'id3']);
// Batch create items (IDs are generated automatically)
const newUsers = await createMany(context, 'users', [
{ name: 'User 1', status: 'active' },
{ name: 'User 2', status: 'pending' }
]);
// Batch delete items
await deleteMany(context, 'users', ['id1', 'id2']);
Types
The library exports the following types to help with type safety:
import { DynamoDBConfig, AwsDynamodbHelperContext, DynamoDBItem } from '@vitkuz/aws-dynamodb';
// Define your item type
interface User {
name: string;
email: string;
status: 'active' | 'inactive' | 'pending';
age?: number;
profile?: {
address?: {
street?: string;
city?: string;
zipCode?: string;
};
preferences?: {
theme?: string;
notifications?: {
email?: boolean;
sms?: boolean;
push?: boolean;
};
};
};
}
// Use with generic methods
const user = await createOne<User>(context, 'users', {
name: 'John',
email: 'john@example.com',
status: 'active'
});
// The returned type will be User & { id: string } (DynamoDBItem<User>)
console.log(user.id, user.name, user.status);
// Deep nested patching maintains full type safety
await patchOneById<User>(context, 'users', user.id, {
profile: {
preferences: {
notifications: {
email: true
}
}
}
});
Error Handling
All methods include proper error handling:
try {
const user = await getOneById(context, 'users', 'non-existent-id');
if (!user) {
console.log('User not found');
}
} catch (error) {
console.error('Error accessing DynamoDB:', error.message);
}
// Comprehensive logging included
// Example log output:
// 🔍 FIND: Retrieving record by ID { tableName: 'users', id: '123' }
// ⚠️ FIND: Record not found { tableName: 'users', id: '123' }
Contributing
- Fork the repository
- Install dependencies:
npm install
- Make your changes
- Run tests:
npm test
- Submit a pull request
License
MIT