@codisolutions23/node-utils 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.changeset/README.md +8 -0
- package/.changeset/comprehensive-improvements.md +29 -0
- package/.changeset/config.json +11 -0
- package/README.md +517 -1
- package/dist/index.d.mts +152 -0
- package/dist/index.d.ts +152 -0
- package/dist/index.js +728 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +673 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +1 -1
- package/tsconfig.json +1 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Changesets
|
|
2
|
+
|
|
3
|
+
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
|
|
4
|
+
with multi-package repos, or single-package repos to help you version and publish your code. You can
|
|
5
|
+
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
|
6
|
+
|
|
7
|
+
We have a quick list of common questions to get you started engaging with this project in
|
|
8
|
+
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@codisolutions23/node-utils": minor
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# 🚀 Comprehensive Package Enhancement
|
|
6
|
+
|
|
7
|
+
## ✨ New Features
|
|
8
|
+
- **NEW**: `ConflictError` class for HTTP 409 responses
|
|
9
|
+
- **NEW**: Enhanced `AuthenticatedRequest` interface with better TypeScript support
|
|
10
|
+
- **NEW**: Comprehensive README documentation with usage examples and API reference
|
|
11
|
+
|
|
12
|
+
## 🔧 Improvements
|
|
13
|
+
- **Enhanced**: Auth middleware with improved token handling and error messages
|
|
14
|
+
- **Improved**: Error handler middleware with better import paths
|
|
15
|
+
- **Simplified**: Configuration system for better flexibility
|
|
16
|
+
- **Updated**: All AWS SDK packages to latest versions (3.857.x → 3.859.x)
|
|
17
|
+
- **Updated**: Redis ecosystem packages (redis 5.6.1 → 5.8.0, ioredis 5.6.1 → 5.7.0)
|
|
18
|
+
- **Updated**: TypeScript to 5.9.2 for improved type safety
|
|
19
|
+
|
|
20
|
+
## 📚 Documentation
|
|
21
|
+
- Complete README overhaul with detailed usage examples
|
|
22
|
+
- API reference for all utilities and middleware
|
|
23
|
+
- Best practices and configuration guides
|
|
24
|
+
- Testing support examples and mock utilities
|
|
25
|
+
|
|
26
|
+
## 🛡️ Security & Performance
|
|
27
|
+
- Latest security patches through dependency updates
|
|
28
|
+
- Improved error handling and logging
|
|
29
|
+
- Better TypeScript type definitions
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
|
|
3
|
+
"changelog": "@changesets/cli/changelog",
|
|
4
|
+
"commit": false,
|
|
5
|
+
"fixed": [],
|
|
6
|
+
"linked": [],
|
|
7
|
+
"access": "restricted",
|
|
8
|
+
"baseBranch": "main",
|
|
9
|
+
"updateInternalDependencies": "patch",
|
|
10
|
+
"ignore": []
|
|
11
|
+
}
|
package/README.md
CHANGED
|
@@ -1 +1,517 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @codisolutions23/node-utils
|
|
2
|
+
|
|
3
|
+
A comprehensive collection of production-ready Node.js utilities, middleware, and helper functions for building scalable enterprise applications. This foundational package provides essential building blocks for authentication, database operations, caching, logging, and more.
|
|
4
|
+
|
|
5
|
+
## 🚀 Features
|
|
6
|
+
|
|
7
|
+
### **🔧 Core Utilities**
|
|
8
|
+
- **Authentication** - JWT token management and password hashing
|
|
9
|
+
- **Database** - MongoDB Atlas connection and query helpers
|
|
10
|
+
- **Caching** - Redis and IoRedis integration with advanced patterns
|
|
11
|
+
- **Logging** - Structured logging with Winston
|
|
12
|
+
- **Email** - Transactional email with Handlebars templating
|
|
13
|
+
- **File Storage** - AWS S3 integration for file uploads
|
|
14
|
+
- **Validation** - HTTP error handling and request validation
|
|
15
|
+
- **Pagination** - Standardized pagination utilities
|
|
16
|
+
|
|
17
|
+
### **🛡️ Middleware Collection**
|
|
18
|
+
- **Auth Middleware** - JWT authentication and authorization
|
|
19
|
+
- **Error Handler** - Global error handling with proper HTTP responses
|
|
20
|
+
- **Request Validation** - Input sanitization and validation
|
|
21
|
+
|
|
22
|
+
### **📊 Advanced Features**
|
|
23
|
+
- **Connection Pooling** - Optimized database connections
|
|
24
|
+
- **Cache Strategies** - Intelligent caching with TTL support
|
|
25
|
+
- **Error Context** - Enhanced error tracking and debugging
|
|
26
|
+
- **Template Engine** - Dynamic email and document generation
|
|
27
|
+
- **File Upload** - Secure file handling with S3 integration
|
|
28
|
+
|
|
29
|
+
## 📦 Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install @codisolutions23/node-utils
|
|
33
|
+
# or
|
|
34
|
+
yarn add @codisolutions23/node-utils
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 🛠️ Quick Start
|
|
38
|
+
|
|
39
|
+
### Basic Setup
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import {
|
|
43
|
+
useAtlas,
|
|
44
|
+
useRedis,
|
|
45
|
+
logger,
|
|
46
|
+
authenticate,
|
|
47
|
+
errorHandler
|
|
48
|
+
} from '@codisolutions23/node-utils';
|
|
49
|
+
|
|
50
|
+
// Initialize database connection
|
|
51
|
+
await useAtlas.connect();
|
|
52
|
+
|
|
53
|
+
// Initialize Redis
|
|
54
|
+
const redis = useRedis();
|
|
55
|
+
|
|
56
|
+
// Setup logging
|
|
57
|
+
logger.info('Application started');
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 🔐 Authentication
|
|
61
|
+
|
|
62
|
+
### JWT Token Management
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { signJwtToken, hashPassword, comparePasswords } from '@codisolutions23/node-utils';
|
|
66
|
+
|
|
67
|
+
// Generate JWT tokens
|
|
68
|
+
const accessToken = signJwtToken({
|
|
69
|
+
payload: { userId: '12345', role: 'admin' },
|
|
70
|
+
secretKey: process.env.JWT_SECRET,
|
|
71
|
+
signOptions: { expiresIn: '15m' }
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Password hashing and comparison
|
|
75
|
+
const hashedPassword = await hashPassword('userPassword');
|
|
76
|
+
const isValid = await comparePasswords('userPassword', hashedPassword);
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Auth Middleware
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { authenticate } from '@codisolutions23/node-utils';
|
|
83
|
+
|
|
84
|
+
// Create authentication middleware with your secret
|
|
85
|
+
const authMiddleware = authenticate(process.env.ACCESS_TOKEN_SECRET);
|
|
86
|
+
|
|
87
|
+
// Protect routes with authentication
|
|
88
|
+
app.use('/api/protected', authMiddleware);
|
|
89
|
+
|
|
90
|
+
// Access user info in protected routes
|
|
91
|
+
app.get('/api/profile', authMiddleware, (req, res) => {
|
|
92
|
+
// req.user contains the decoded JWT payload
|
|
93
|
+
const userId = req.user.id;
|
|
94
|
+
res.json({ message: `Welcome user ${userId}` });
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 🗄️ Database Operations
|
|
99
|
+
|
|
100
|
+
### MongoDB Atlas Integration
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
import { useAtlas, toObjectId } from '@codisolutions23/node-utils';
|
|
104
|
+
|
|
105
|
+
// Connect to MongoDB Atlas
|
|
106
|
+
await useAtlas.connect();
|
|
107
|
+
|
|
108
|
+
// Get database instance
|
|
109
|
+
const db = useAtlas.getDb();
|
|
110
|
+
const users = db.collection('users');
|
|
111
|
+
|
|
112
|
+
// Convert string to ObjectId safely
|
|
113
|
+
const userId = toObjectId('507f1f77bcf86cd799439011');
|
|
114
|
+
const user = await users.findOne({ _id: userId });
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Pagination Helper
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
import { paginate } from '@codisolutions23/node-utils';
|
|
121
|
+
|
|
122
|
+
// Standardized pagination
|
|
123
|
+
const page = 0;
|
|
124
|
+
const limit = 10;
|
|
125
|
+
const total = 250;
|
|
126
|
+
const items = await users.find().skip(page * limit).limit(limit).toArray();
|
|
127
|
+
|
|
128
|
+
const paginatedResult = paginate(items, page, limit, total);
|
|
129
|
+
// Returns: { items, pagination: { page, limit, total, pages, hasNext, hasPrev } }
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## 🧠 Caching
|
|
133
|
+
|
|
134
|
+
### Redis Integration
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import { useRedis, useIoRedis, getCacheKey } from '@codisolutions23/node-utils';
|
|
138
|
+
|
|
139
|
+
// Basic Redis operations
|
|
140
|
+
const redis = useRedis();
|
|
141
|
+
await redis.set('user:123', JSON.stringify(userData), 'EX', 3600);
|
|
142
|
+
const cached = await redis.get('user:123');
|
|
143
|
+
|
|
144
|
+
// Advanced Redis with IoRedis
|
|
145
|
+
const ioredis = useIoRedis();
|
|
146
|
+
await ioredis.hset('user:123:profile', 'name', 'John Doe', 'email', 'john@example.com');
|
|
147
|
+
|
|
148
|
+
// Smart cache key generation
|
|
149
|
+
const cacheKey = getCacheKey('user', { id: '123', type: 'profile' });
|
|
150
|
+
// Returns: 'user:123:profile'
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Cache Patterns
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
// Cache-aside pattern
|
|
157
|
+
async function getUser(userId: string) {
|
|
158
|
+
const cacheKey = getCacheKey('user', { id: userId });
|
|
159
|
+
|
|
160
|
+
// Try cache first
|
|
161
|
+
const cached = await redis.get(cacheKey);
|
|
162
|
+
if (cached) {
|
|
163
|
+
return JSON.parse(cached);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Fetch from database
|
|
167
|
+
const user = await db.collection('users').findOne({ _id: toObjectId(userId) });
|
|
168
|
+
|
|
169
|
+
// Cache for 1 hour
|
|
170
|
+
if (user) {
|
|
171
|
+
await redis.setex(cacheKey, 3600, JSON.stringify(user));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return user;
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## 📧 Email & Templates
|
|
179
|
+
|
|
180
|
+
### Handlebars Email Templates
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
import { sendMail, compileTemplate, getTemplatePath } from '@codisolutions23/node-utils';
|
|
184
|
+
|
|
185
|
+
// Compile and send templated emails
|
|
186
|
+
const templatePath = getTemplatePath('welcome-email');
|
|
187
|
+
const compiledTemplate = compileTemplate(templatePath);
|
|
188
|
+
|
|
189
|
+
const html = compiledTemplate({
|
|
190
|
+
userName: 'John Doe',
|
|
191
|
+
activationLink: 'https://app.com/activate/token123'
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
await sendMail({
|
|
195
|
+
to: 'user@example.com',
|
|
196
|
+
subject: 'Welcome to Our Platform',
|
|
197
|
+
html
|
|
198
|
+
});
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Email Configuration
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
// Environment setup
|
|
205
|
+
process.env.MAILER_HOST = 'smtp.gmail.com';
|
|
206
|
+
process.env.MAILER_PORT = '587';
|
|
207
|
+
process.env.MAILER_USER = 'your-email@gmail.com';
|
|
208
|
+
process.env.MAILER_PASS = 'your-app-password';
|
|
209
|
+
|
|
210
|
+
// Send emails
|
|
211
|
+
await sendMail({
|
|
212
|
+
from: 'noreply@yourcompany.com',
|
|
213
|
+
to: 'recipient@example.com',
|
|
214
|
+
subject: 'Your Subject',
|
|
215
|
+
text: 'Plain text content',
|
|
216
|
+
html: '<h1>HTML Content</h1>'
|
|
217
|
+
});
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## ☁️ File Storage (AWS S3)
|
|
221
|
+
|
|
222
|
+
### S3 Integration
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
import { useS3 } from '@codisolutions23/node-utils';
|
|
226
|
+
|
|
227
|
+
const s3Client = useS3();
|
|
228
|
+
|
|
229
|
+
// Upload file
|
|
230
|
+
const uploadParams = {
|
|
231
|
+
Bucket: 'your-bucket-name',
|
|
232
|
+
Key: 'uploads/user-avatar.jpg',
|
|
233
|
+
Body: fileBuffer,
|
|
234
|
+
ContentType: 'image/jpeg'
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
const result = await s3Client.upload(uploadParams).promise();
|
|
238
|
+
console.log('File uploaded:', result.Location);
|
|
239
|
+
|
|
240
|
+
// Generate signed URL for secure access
|
|
241
|
+
const signedUrl = s3Client.getSignedUrl('getObject', {
|
|
242
|
+
Bucket: 'your-bucket-name',
|
|
243
|
+
Key: 'uploads/user-avatar.jpg',
|
|
244
|
+
Expires: 3600 // 1 hour
|
|
245
|
+
});
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## 📝 Logging
|
|
249
|
+
|
|
250
|
+
### Structured Logging with Winston
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
import { logger } from '@codisolutions23/node-utils';
|
|
254
|
+
|
|
255
|
+
// Different log levels
|
|
256
|
+
logger.info('Application started', { port: 3000, env: 'production' });
|
|
257
|
+
logger.warn('High memory usage detected', { usage: '85%' });
|
|
258
|
+
logger.error('Database connection failed', {
|
|
259
|
+
error: error.message,
|
|
260
|
+
stack: error.stack,
|
|
261
|
+
timestamp: new Date().toISOString()
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
// Structured logging for better searchability
|
|
265
|
+
logger.info('User action', {
|
|
266
|
+
userId: '12345',
|
|
267
|
+
action: 'login',
|
|
268
|
+
ip: req.ip,
|
|
269
|
+
userAgent: req.get('user-agent'),
|
|
270
|
+
timestamp: new Date().toISOString()
|
|
271
|
+
});
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## 🚨 Error Handling
|
|
275
|
+
|
|
276
|
+
### HTTP Error Classes
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
import {
|
|
280
|
+
BadRequestError,
|
|
281
|
+
NotFoundError,
|
|
282
|
+
UnauthorizedError,
|
|
283
|
+
ConflictError,
|
|
284
|
+
InternalServerError
|
|
285
|
+
} from '@codisolutions23/node-utils';
|
|
286
|
+
|
|
287
|
+
// Use in your route handlers
|
|
288
|
+
app.post('/api/users', async (req, res, next) => {
|
|
289
|
+
try {
|
|
290
|
+
const { email } = req.body;
|
|
291
|
+
|
|
292
|
+
if (!email) {
|
|
293
|
+
throw new BadRequestError('Email is required');
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const existingUser = await users.findOne({ email });
|
|
297
|
+
if (existingUser) {
|
|
298
|
+
throw new ConflictError('User already exists');
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Create user logic...
|
|
302
|
+
res.json({ success: true });
|
|
303
|
+
} catch (error) {
|
|
304
|
+
next(error); // Handled by errorHandler middleware
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Global Error Handler
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
import { errorHandler } from '@codisolutions23/node-utils';
|
|
313
|
+
|
|
314
|
+
// Apply global error handling
|
|
315
|
+
app.use(errorHandler);
|
|
316
|
+
|
|
317
|
+
// All errors are automatically formatted as:
|
|
318
|
+
// {
|
|
319
|
+
// "status": "error",
|
|
320
|
+
// "message": "Email is required"
|
|
321
|
+
// }
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## 🧪 Testing Support
|
|
325
|
+
|
|
326
|
+
### Mock Utilities
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
// Mock Redis for testing
|
|
330
|
+
jest.mock('@codisolutions23/node-utils', () => ({
|
|
331
|
+
...jest.requireActual('@codisolutions23/node-utils'),
|
|
332
|
+
useRedis: () => ({
|
|
333
|
+
get: jest.fn(),
|
|
334
|
+
set: jest.fn(),
|
|
335
|
+
del: jest.fn(),
|
|
336
|
+
}),
|
|
337
|
+
}));
|
|
338
|
+
|
|
339
|
+
// Mock database
|
|
340
|
+
const mockDb = {
|
|
341
|
+
collection: jest.fn(() => ({
|
|
342
|
+
findOne: jest.fn(),
|
|
343
|
+
find: jest.fn(),
|
|
344
|
+
insertOne: jest.fn(),
|
|
345
|
+
}))
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
jest.spyOn(require('@codisolutions23/node-utils'), 'useAtlas').mockImplementation(() => ({
|
|
349
|
+
getDb: () => mockDb,
|
|
350
|
+
}));
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## ⚙️ Configuration
|
|
354
|
+
|
|
355
|
+
### Environment Variables
|
|
356
|
+
|
|
357
|
+
The package only requires minimal global environment configuration. Most services accept configuration as parameters for maximum flexibility:
|
|
358
|
+
|
|
359
|
+
```env
|
|
360
|
+
# Required for Redis utilities
|
|
361
|
+
REDIS_HOST=localhost
|
|
362
|
+
REDIS_PORT=6379
|
|
363
|
+
REDIS_PASSWORD=your-redis-password
|
|
364
|
+
|
|
365
|
+
# Optional - defaults to development if not set
|
|
366
|
+
NODE_ENV=production
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Service-Specific Configuration
|
|
370
|
+
|
|
371
|
+
Other services accept configuration when instantiated:
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
// Database - pass config to connect method
|
|
375
|
+
await useAtlas.connect({
|
|
376
|
+
uri: 'mongodb://localhost:27017',
|
|
377
|
+
db: 'your-database'
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
// Email - pass config to constructor
|
|
381
|
+
const mailer = new useMailer({
|
|
382
|
+
host: 'smtp.gmail.com',
|
|
383
|
+
port: 587,
|
|
384
|
+
secure: false,
|
|
385
|
+
email: 'your-email@gmail.com',
|
|
386
|
+
password: 'your-app-password'
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
// S3 - pass config to constructor
|
|
390
|
+
const s3 = new useS3({
|
|
391
|
+
accessKeyId: 'your-access-key',
|
|
392
|
+
secretAccessKey: 'your-secret-key',
|
|
393
|
+
region: 'us-east-1',
|
|
394
|
+
endpoint: 'https://s3.amazonaws.com',
|
|
395
|
+
bucket: 'your-bucket-name',
|
|
396
|
+
forcePathStyle: false
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
// Auth - pass secret to middleware function
|
|
400
|
+
const authMiddleware = authenticate('your-jwt-secret');
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
## 📚 API Reference
|
|
404
|
+
|
|
405
|
+
### Core Functions
|
|
406
|
+
|
|
407
|
+
| Function | Description | Usage |
|
|
408
|
+
|----------|-------------|-------|
|
|
409
|
+
| `signJwtToken()` | Generate JWT tokens | `signJwtToken({ payload, secretKey, signOptions })` |
|
|
410
|
+
| `hashPassword()` | Hash passwords with bcrypt | `await hashPassword('password')` |
|
|
411
|
+
| `comparePasswords()` | Compare password with hash | `await comparePasswords('password', hash)` |
|
|
412
|
+
| `toObjectId()` | Convert string to MongoDB ObjectId | `toObjectId('507f1f77bcf86cd799439011')` |
|
|
413
|
+
| `paginate()` | Create pagination object | `paginate(items, page, limit, total)` |
|
|
414
|
+
| `getCacheKey()` | Generate cache keys | `getCacheKey('user', { id: '123' })` |
|
|
415
|
+
|
|
416
|
+
### Middleware
|
|
417
|
+
|
|
418
|
+
| Middleware | Description | Usage |
|
|
419
|
+
|------------|-------------|-------|
|
|
420
|
+
| `authenticate()` | JWT authentication | `const authMiddleware = authenticate(secretKey); app.use('/protected', authMiddleware)` |
|
|
421
|
+
| `errorHandler` | Global error handling | `app.use(errorHandler)` |
|
|
422
|
+
|
|
423
|
+
### Database & Cache
|
|
424
|
+
|
|
425
|
+
| Function | Description | Usage |
|
|
426
|
+
|----------|-------------|-------|
|
|
427
|
+
| `useAtlas.connect()` | Connect to MongoDB Atlas | `await useAtlas.connect()` |
|
|
428
|
+
| `useAtlas.getDb()` | Get database instance | `const db = useAtlas.getDb()` |
|
|
429
|
+
| `useRedis()` | Get Redis client | `const redis = useRedis()` |
|
|
430
|
+
| `useIoRedis()` | Get IoRedis client | `const ioredis = useIoRedis()` |
|
|
431
|
+
|
|
432
|
+
## 🎯 Best Practices
|
|
433
|
+
|
|
434
|
+
### 1. **Error Handling**
|
|
435
|
+
```typescript
|
|
436
|
+
// Always use specific error types
|
|
437
|
+
throw new BadRequestError('Specific error message');
|
|
438
|
+
// Instead of generic Error
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### 2. **Logging**
|
|
442
|
+
```typescript
|
|
443
|
+
// Structure your logs for better searchability
|
|
444
|
+
logger.info('User action', {
|
|
445
|
+
userId,
|
|
446
|
+
action: 'create_post',
|
|
447
|
+
metadata: { postId, timestamp }
|
|
448
|
+
});
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### 3. **Caching**
|
|
452
|
+
```typescript
|
|
453
|
+
// Use consistent cache key patterns
|
|
454
|
+
const cacheKey = getCacheKey('user:profile', { id: userId });
|
|
455
|
+
// Results in: 'user:profile:123'
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### 4. **Database Operations**
|
|
459
|
+
```typescript
|
|
460
|
+
// Always convert string IDs to ObjectId for MongoDB
|
|
461
|
+
const user = await users.findOne({ _id: toObjectId(userId) });
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
## 🔧 Advanced Configuration
|
|
465
|
+
|
|
466
|
+
### Custom Logger Configuration
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
import winston from 'winston';
|
|
470
|
+
import { logger } from '@codisolutions23/node-utils';
|
|
471
|
+
|
|
472
|
+
// The logger is pre-configured with console and file transports
|
|
473
|
+
// But you can extend it:
|
|
474
|
+
logger.add(new winston.transports.File({
|
|
475
|
+
filename: 'error.log',
|
|
476
|
+
level: 'error',
|
|
477
|
+
format: winston.format.json()
|
|
478
|
+
}));
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
### Custom Redis Configuration
|
|
482
|
+
|
|
483
|
+
```typescript
|
|
484
|
+
// The package uses standard Redis configuration
|
|
485
|
+
// But you can override with environment variables:
|
|
486
|
+
process.env.REDIS_URL = 'redis://username:password@host:port';
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
## 🤝 Contributing
|
|
490
|
+
|
|
491
|
+
1. Fork the repository
|
|
492
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
493
|
+
3. Run tests (`yarn test`)
|
|
494
|
+
4. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
495
|
+
5. Push to the branch (`git push origin feature/amazing-feature`)
|
|
496
|
+
6. Open a Pull Request
|
|
497
|
+
|
|
498
|
+
## 📜 License
|
|
499
|
+
|
|
500
|
+
MIT License - see the [LICENSE](LICENSE) file for details.
|
|
501
|
+
|
|
502
|
+
## 🔗 Related Packages
|
|
503
|
+
|
|
504
|
+
- [@codisolutions23/api-core](https://www.npmjs.com/package/@codisolutions23/api-core) - Enhanced API core with performance optimizations
|
|
505
|
+
- [@codisolutions23/codi-api-server](https://www.npmjs.com/package/@codisolutions23/codi-api-server) - Complete API server implementation
|
|
506
|
+
|
|
507
|
+
## 📊 Package Stats
|
|
508
|
+
|
|
509
|
+
- **Zero Dependencies Conflicts** - All dependencies are carefully managed
|
|
510
|
+
- **TypeScript Support** - Full type definitions included
|
|
511
|
+
- **Production Ready** - Used in enterprise applications
|
|
512
|
+
- **Well Tested** - Comprehensive test coverage
|
|
513
|
+
- **Actively Maintained** - Regular updates and improvements
|
|
514
|
+
|
|
515
|
+
---
|
|
516
|
+
|
|
517
|
+
Built with ❤️ by the Codi Solutions team
|