@easyweb/rabbitmq-utils 1.0.19 → 1.1.1

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/README.md CHANGED
@@ -1,426 +1,426 @@
1
- # @myfoto/easyweb-common
2
-
3
- A shared utility library for Easyweb microservices built with TypeScript. This package provides common functionality including a type-safe RabbitMQ event system (publishers, subscribers, exchanges, and routing keys).
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install @myfoto/easyweb-common
9
- ```
10
-
11
- ## Features
12
-
13
- - 🚨 **Error Handling** - Custom error classes with consistent serialization
14
- - ✅ **Validation** - Zod-based request/response validation with common patterns
15
- - 🗃️ **Database Utilities** - Prisma helpers, transactions, and health checks
16
- - 🔐 **Password Management** - Hashing, validation, and secure token generation
17
- - 📄 **Response Formatting** - Standardized API responses with pagination
18
- - 📊 **Pagination** - Cursor and offset-based pagination utilities
19
- - 📝 **Logging** - Structured logging with performance monitoring
20
- - 🛡️ **Middleware** - Rate limiting, error handling, and more
21
- - 🐰 **RabbitMQ Event System** - Type-safe event-driven architecture with publishers and subscribers
22
-
23
- ## Quick Start
24
-
25
- ```typescript
26
- import {
27
- // Error classes
28
- BadRequestError,
29
- NotFoundError,
30
- ValidationPatterns,
31
-
32
- // Utilities
33
- PasswordService,
34
- ResponseFormatter,
35
- PaginationService,
36
- Logger,
37
- DatabaseService,
38
-
39
- // Middleware
40
- errorHandler,
41
- validateRequest,
42
- responseFormatter,
43
- } from '@glow-up/common-shared';
44
-
45
- // Use in your Express app
46
- import express from 'express';
47
-
48
- const app = express();
49
-
50
- // Add response formatter middleware
51
- app.use(responseFormatter);
52
-
53
- // Add error handler (should be last)
54
- app.use(errorHandler);
55
- ```
56
-
57
- ## Error Handling
58
-
59
- ### Custom Error Classes
60
-
61
- ```typescript
62
- import {
63
- BadRequestError,
64
- NotFoundError,
65
- ValidationError,
66
- } from '@glow-up/common-shared';
67
-
68
- // Throw errors that will be automatically handled
69
- throw new BadRequestError('Invalid input data');
70
- throw new NotFoundError('User not found');
71
- throw new ValidationError([
72
- { field: 'email', message: 'Invalid email format' },
73
- ]);
74
- ```
75
-
76
- ### Error Handler Middleware
77
-
78
- ```typescript
79
- import { errorHandler } from '@glow-up/common-shared';
80
-
81
- // Add as the last middleware
82
- app.use(errorHandler);
83
- ```
84
-
85
- ## Validation
86
-
87
- ### Request Validation with Zod
88
-
89
- ```typescript
90
- import { validateRequest, ValidationPatterns } from '@glow-up/common-shared';
91
- import { z } from 'zod';
92
-
93
- // Use predefined patterns
94
- const loginSchema = {
95
- body: z.object({
96
- email: ValidationPatterns.email(),
97
- password: z.string().min(1),
98
- }),
99
- };
100
-
101
- app.post('/login', validateRequest(loginSchema), (req, res) => {
102
- // req.body is now validated and typed
103
- const { email, password } = req.body;
104
- res.success({ message: 'Login successful' });
105
- });
106
-
107
- // Common validation middleware
108
- import { ValidationMiddleware } from '@glow-up/common-shared';
109
-
110
- app.post(
111
- '/register',
112
- ValidationMiddleware.validateRegistration(),
113
- (req, res) => {
114
- // Handles email, password, name validation
115
- },
116
- );
117
- ```
118
-
119
- ## Response Formatting
120
-
121
- ### Standardized API Responses
122
-
123
- ```typescript
124
- import { ResponseFormatter } from '@glow-up/common-shared';
125
-
126
- // Success response
127
- ResponseFormatter.success(res, { user: userData }, 'User created');
128
- // { success: true, message: 'User created', data: { user: userData }, metadata: { timestamp: ... } }
129
-
130
- // Error response
131
- ResponseFormatter.error(res, 'Invalid credentials', 'Login failed', 401);
132
-
133
- // Paginated response
134
- ResponseFormatter.paginated(res, users, { page: 1, limit: 10, total: 100 });
135
-
136
- // Using middleware (adds methods to res object)
137
- app.use(responseFormatter);
138
-
139
- app.get('/users', (req, res) => {
140
- res.success(users, 'Users retrieved');
141
- res.paginated(users, paginationInfo);
142
- res.notFound('User not found');
143
- });
144
- ```
145
-
146
- ## Pagination
147
-
148
- ```typescript
149
- import { PaginationService, parseSort } from '@glow-up/common-shared';
150
-
151
- // Parse pagination params
152
- const pagination = PaginationService.parsePagination({
153
- page: req.query.page,
154
- limit: req.query.limit,
155
- });
156
-
157
- // For Prisma
158
- const prismaOptions = PaginationService.toPrisma(pagination, sort);
159
- const users = await prisma.user.findMany(prismaOptions);
160
-
161
- // Generate metadata
162
- const metadata = PaginationService.generateMetadata(
163
- pagination.page,
164
- pagination.limit,
165
- totalUsers,
166
- );
167
-
168
- res.paginated(users, metadata);
169
- ```
170
-
171
- ## Database Utilities
172
-
173
- ```typescript
174
- import { DatabaseService } from '@glow-up/common-shared';
175
- import { PrismaClient } from '@prisma/client';
176
-
177
- const prisma = new PrismaClient();
178
- const dbService = new DatabaseService(prisma);
179
-
180
- // Health check
181
- const health = await dbService.healthCheck();
182
-
183
- // Transactions
184
- const result = await dbService.withTransaction(async tx => {
185
- const user = await tx.user.create({ data: userData });
186
- const profile = await tx.profile.create({
187
- data: { userId: user.id, ...profileData },
188
- });
189
- return { user, profile };
190
- });
191
-
192
- // Batch operations
193
- await dbService.batchCreate('user', userDataArray, 50);
194
-
195
- // Soft delete
196
- await dbService.softDelete('user', { id: userId });
197
- ```
198
-
199
- ## Password Management
200
-
201
- ```typescript
202
- import { PasswordService } from '@glow-up/common-shared';
203
-
204
- // Hash password
205
- const hashedPassword = await PasswordService.hashPassword('mypassword');
206
-
207
- // Compare password
208
- const isValid = await PasswordService.comparePassword(
209
- 'mypassword',
210
- hashedPassword,
211
- );
212
-
213
- // Generate secure tokens
214
- const token = PasswordService.generateSecureToken(32);
215
- const resetToken = PasswordService.generatePasswordResetToken();
216
-
217
- // Check password strength
218
- const strength = PasswordService.checkPasswordStrength('mypassword');
219
- console.log(strength.isStrong); // boolean
220
- console.log(strength.feedback); // array of suggestions
221
- ```
222
-
223
- ## RabbitMQ Event System
224
-
225
- ### Quick Start
226
-
227
- ```typescript
228
- import {
229
- Publisher,
230
- Subscriber,
231
- Exchanges,
232
- RoutingKeys,
233
- UserProfileCreatedEvent,
234
- } from '@myfoto/common-shared';
235
- import { Channel } from 'amqplib';
236
-
237
- // Create a publisher
238
- export class UserProfileCreatedPublisher extends Publisher<UserProfileCreatedEvent> {
239
- exchange = Exchanges.UserProfile;
240
- routingKey = RoutingKeys.UserProfileCreated;
241
- }
242
-
243
- // Publish an event
244
- const publisher = new UserProfileCreatedPublisher(channel);
245
- await publisher.publish({
246
- userId: '123',
247
- name: 'John Doe',
248
- email: 'john@example.com',
249
- });
250
-
251
- // Create a subscriber
252
- export class UserProfileCreatedSubscriber extends Subscriber<UserProfileCreatedEvent> {
253
- exchange = Exchanges.UserProfile;
254
- routingKey = RoutingKeys.UserProfileCreated;
255
-
256
- async onMessage(
257
- data: UserProfileCreatedEvent['data'],
258
- msg: ConsumeMessage,
259
- ): Promise<void> {
260
- console.log('User created:', data);
261
- // Your business logic here
262
- }
263
- }
264
-
265
- // Subscribe to events
266
- const subscriber = new UserProfileCreatedSubscriber(channel);
267
- await subscriber.subscribe();
268
- ```
269
-
270
- ### Features
271
-
272
- - ✅ **Type-safe events** - Full TypeScript support with autocomplete
273
- - ✅ **Centralized definitions** - All events defined in one package
274
- - ✅ **Consistent naming** - Clear routing key conventions
275
- - ✅ **Durable queues** - Messages persist across restarts
276
- - ✅ **Error handling** - Automatic message requeuing on failures
277
- - ✅ **Documentation** - Comprehensive guides and examples
278
-
279
- ### Available Events
280
-
281
- **User Profile**: `UserProfileCreatedEvent`, `UserProfileUpdatedEvent`, `UserProfileDeletedEvent`
282
-
283
- **Product**: `ProductCreatedEvent`, `ProductUpdatedEvent`, `ProductDeletedEvent`, `ProductStockChangedEvent`
284
-
285
- **Order**: `OrderCreatedEvent`, `OrderUpdatedEvent`, `OrderCompletedEvent`, `OrderCancelledEvent`
286
-
287
- ### Routing Key Convention
288
-
289
- Format: `<service>.<entity>.<action>`
290
-
291
- Examples:
292
-
293
- - `user_profile.profile.created`
294
- - `product.product.updated`
295
- - `order.order.completed`
296
-
297
- ### Documentation
298
-
299
- - 📚 [Full Event System Documentation](src/events/README.md)
300
- - 📋 [Event Guidelines](EVENT_GUIDELINES.md)
301
- - 🚀 [Quick Reference](QUICK_REFERENCE.md)
302
- - 🔄 [Migration Guide](MIGRATION.md)
303
-
304
- ## Logging
305
-
306
- ```typescript
307
- import { Logger, createLogger, requestLogger } from '@myfoto/common-shared';
308
-
309
- // Use default logger
310
- import { log } from '@glow-up/common-shared';
311
-
312
- log.info('Application started');
313
- log.error('Something went wrong', error, { userId: '123' });
314
-
315
- // Create custom logger
316
- const logger = createLogger({
317
- level: 'debug',
318
- enableFile: true,
319
- filePath: './logs/app.log',
320
- });
321
-
322
- // Add request logging middleware
323
- app.use(requestLogger(logger));
324
-
325
- // Performance logging
326
- import { timeOperation } from '@glow-up/common-shared';
327
-
328
- const result = await timeOperation(
329
- 'database-query',
330
- () => prisma.user.findMany(),
331
- logger,
332
- );
333
- ```
334
-
335
- ## Validation Patterns
336
-
337
- ```typescript
338
- import { ValidationPatterns } from '@glow-up/common-shared';
339
-
340
- // Email with normalization
341
- ValidationPatterns.email();
342
-
343
- // Strong password requirements
344
- ValidationPatterns.password();
345
-
346
- // UUID validation
347
- ValidationPatterns.uuid();
348
-
349
- // Pagination parameters
350
- ValidationPatterns.pagination();
351
-
352
- // Phone number
353
- ValidationPatterns.phoneNumber();
354
-
355
- // Custom enum with case insensitive matching
356
- ValidationPatterns.enumCaseInsensitive(['ACTIVE', 'INACTIVE']);
357
- ```
358
-
359
- ## TypeScript Support
360
-
361
- This package is built with TypeScript and provides full type definitions. All utilities are properly typed for the best development experience.
362
-
363
- ```typescript
364
- // Types are automatically inferred
365
- import {
366
- ApiResponse,
367
- PaginatedResponse,
368
- LogLevel,
369
- } from '@glow-up/common-shared';
370
-
371
- // Extend Express types (automatically included)
372
- declare global {
373
- namespace Express {
374
- interface Request {
375
- user?: {
376
- id: string;
377
- email: string;
378
- roles?: string[];
379
- };
380
- }
381
- interface Response {
382
- success: (data?: any, message?: string) => void;
383
- error: (errors: any, message?: string, statusCode?: number) => void;
384
- // ... other response methods
385
- }
386
- }
387
- }
388
- ```
389
-
390
- ## Peer Dependencies
391
-
392
- Make sure to install peer dependencies if you're using related features:
393
-
394
- ```bash
395
- # For database utilities
396
- npm install @prisma/client
397
-
398
- # For logging to files (if using file logging)
399
- npm install winston
400
- ```
401
-
402
- ## Contributing
403
-
404
- This package is part of the Glow Up microservices ecosystem. When adding new utilities:
405
-
406
- 1. Follow the existing patterns and TypeScript conventions
407
- 2. Add proper JSDoc documentation
408
- 3. Include unit tests
409
- 4. Update this README with usage examples
410
-
411
- ## License
412
-
413
- MIT License - see LICENSE file for details.
414
-
415
- ## Changelog
416
-
417
- ### 1.0.0
418
-
419
- - Initial release with core utilities
420
- - Error handling system
421
- - Validation middleware
422
- - Database utilities
423
- - Response formatting
424
- - Pagination helpers
425
- - Logging system
426
- - Password management
1
+ # @myfoto/easyweb-common
2
+
3
+ A shared utility library for Easyweb microservices built with TypeScript. This package provides common functionality including a type-safe RabbitMQ event system (publishers, subscribers, exchanges, and routing keys).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @myfoto/easyweb-common
9
+ ```
10
+
11
+ ## Features
12
+
13
+ - 🚨 **Error Handling** - Custom error classes with consistent serialization
14
+ - ✅ **Validation** - Zod-based request/response validation with common patterns
15
+ - 🗃️ **Database Utilities** - Prisma helpers, transactions, and health checks
16
+ - 🔐 **Password Management** - Hashing, validation, and secure token generation
17
+ - 📄 **Response Formatting** - Standardized API responses with pagination
18
+ - 📊 **Pagination** - Cursor and offset-based pagination utilities
19
+ - 📝 **Logging** - Structured logging with performance monitoring
20
+ - 🛡️ **Middleware** - Rate limiting, error handling, and more
21
+ - 🐰 **RabbitMQ Event System** - Type-safe event-driven architecture with publishers and subscribers
22
+
23
+ ## Quick Start
24
+
25
+ ```typescript
26
+ import {
27
+ // Error classes
28
+ BadRequestError,
29
+ NotFoundError,
30
+ ValidationPatterns,
31
+
32
+ // Utilities
33
+ PasswordService,
34
+ ResponseFormatter,
35
+ PaginationService,
36
+ Logger,
37
+ DatabaseService,
38
+
39
+ // Middleware
40
+ errorHandler,
41
+ validateRequest,
42
+ responseFormatter,
43
+ } from '@glow-up/common-shared';
44
+
45
+ // Use in your Express app
46
+ import express from 'express';
47
+
48
+ const app = express();
49
+
50
+ // Add response formatter middleware
51
+ app.use(responseFormatter);
52
+
53
+ // Add error handler (should be last)
54
+ app.use(errorHandler);
55
+ ```
56
+
57
+ ## Error Handling
58
+
59
+ ### Custom Error Classes
60
+
61
+ ```typescript
62
+ import {
63
+ BadRequestError,
64
+ NotFoundError,
65
+ ValidationError,
66
+ } from '@glow-up/common-shared';
67
+
68
+ // Throw errors that will be automatically handled
69
+ throw new BadRequestError('Invalid input data');
70
+ throw new NotFoundError('User not found');
71
+ throw new ValidationError([
72
+ { field: 'email', message: 'Invalid email format' },
73
+ ]);
74
+ ```
75
+
76
+ ### Error Handler Middleware
77
+
78
+ ```typescript
79
+ import { errorHandler } from '@glow-up/common-shared';
80
+
81
+ // Add as the last middleware
82
+ app.use(errorHandler);
83
+ ```
84
+
85
+ ## Validation
86
+
87
+ ### Request Validation with Zod
88
+
89
+ ```typescript
90
+ import { validateRequest, ValidationPatterns } from '@glow-up/common-shared';
91
+ import { z } from 'zod';
92
+
93
+ // Use predefined patterns
94
+ const loginSchema = {
95
+ body: z.object({
96
+ email: ValidationPatterns.email(),
97
+ password: z.string().min(1),
98
+ }),
99
+ };
100
+
101
+ app.post('/login', validateRequest(loginSchema), (req, res) => {
102
+ // req.body is now validated and typed
103
+ const { email, password } = req.body;
104
+ res.success({ message: 'Login successful' });
105
+ });
106
+
107
+ // Common validation middleware
108
+ import { ValidationMiddleware } from '@glow-up/common-shared';
109
+
110
+ app.post(
111
+ '/register',
112
+ ValidationMiddleware.validateRegistration(),
113
+ (req, res) => {
114
+ // Handles email, password, name validation
115
+ },
116
+ );
117
+ ```
118
+
119
+ ## Response Formatting
120
+
121
+ ### Standardized API Responses
122
+
123
+ ```typescript
124
+ import { ResponseFormatter } from '@glow-up/common-shared';
125
+
126
+ // Success response
127
+ ResponseFormatter.success(res, { user: userData }, 'User created');
128
+ // { success: true, message: 'User created', data: { user: userData }, metadata: { timestamp: ... } }
129
+
130
+ // Error response
131
+ ResponseFormatter.error(res, 'Invalid credentials', 'Login failed', 401);
132
+
133
+ // Paginated response
134
+ ResponseFormatter.paginated(res, users, { page: 1, limit: 10, total: 100 });
135
+
136
+ // Using middleware (adds methods to res object)
137
+ app.use(responseFormatter);
138
+
139
+ app.get('/users', (req, res) => {
140
+ res.success(users, 'Users retrieved');
141
+ res.paginated(users, paginationInfo);
142
+ res.notFound('User not found');
143
+ });
144
+ ```
145
+
146
+ ## Pagination
147
+
148
+ ```typescript
149
+ import { PaginationService, parseSort } from '@glow-up/common-shared';
150
+
151
+ // Parse pagination params
152
+ const pagination = PaginationService.parsePagination({
153
+ page: req.query.page,
154
+ limit: req.query.limit,
155
+ });
156
+
157
+ // For Prisma
158
+ const prismaOptions = PaginationService.toPrisma(pagination, sort);
159
+ const users = await prisma.user.findMany(prismaOptions);
160
+
161
+ // Generate metadata
162
+ const metadata = PaginationService.generateMetadata(
163
+ pagination.page,
164
+ pagination.limit,
165
+ totalUsers,
166
+ );
167
+
168
+ res.paginated(users, metadata);
169
+ ```
170
+
171
+ ## Database Utilities
172
+
173
+ ```typescript
174
+ import { DatabaseService } from '@glow-up/common-shared';
175
+ import { PrismaClient } from '@prisma/client';
176
+
177
+ const prisma = new PrismaClient();
178
+ const dbService = new DatabaseService(prisma);
179
+
180
+ // Health check
181
+ const health = await dbService.healthCheck();
182
+
183
+ // Transactions
184
+ const result = await dbService.withTransaction(async tx => {
185
+ const user = await tx.user.create({ data: userData });
186
+ const profile = await tx.profile.create({
187
+ data: { userId: user.id, ...profileData },
188
+ });
189
+ return { user, profile };
190
+ });
191
+
192
+ // Batch operations
193
+ await dbService.batchCreate('user', userDataArray, 50);
194
+
195
+ // Soft delete
196
+ await dbService.softDelete('user', { id: userId });
197
+ ```
198
+
199
+ ## Password Management
200
+
201
+ ```typescript
202
+ import { PasswordService } from '@glow-up/common-shared';
203
+
204
+ // Hash password
205
+ const hashedPassword = await PasswordService.hashPassword('mypassword');
206
+
207
+ // Compare password
208
+ const isValid = await PasswordService.comparePassword(
209
+ 'mypassword',
210
+ hashedPassword,
211
+ );
212
+
213
+ // Generate secure tokens
214
+ const token = PasswordService.generateSecureToken(32);
215
+ const resetToken = PasswordService.generatePasswordResetToken();
216
+
217
+ // Check password strength
218
+ const strength = PasswordService.checkPasswordStrength('mypassword');
219
+ console.log(strength.isStrong); // boolean
220
+ console.log(strength.feedback); // array of suggestions
221
+ ```
222
+
223
+ ## RabbitMQ Event System
224
+
225
+ ### Quick Start
226
+
227
+ ```typescript
228
+ import {
229
+ Publisher,
230
+ Subscriber,
231
+ Exchanges,
232
+ RoutingKeys,
233
+ UserProfileCreatedEvent,
234
+ } from '@myfoto/common-shared';
235
+ import { Channel } from 'amqplib';
236
+
237
+ // Create a publisher
238
+ export class UserProfileCreatedPublisher extends Publisher<UserProfileCreatedEvent> {
239
+ exchange = Exchanges.UserProfile;
240
+ routingKey = RoutingKeys.UserProfileCreated;
241
+ }
242
+
243
+ // Publish an event
244
+ const publisher = new UserProfileCreatedPublisher(channel);
245
+ await publisher.publish({
246
+ userId: '123',
247
+ name: 'John Doe',
248
+ email: 'john@example.com',
249
+ });
250
+
251
+ // Create a subscriber
252
+ export class UserProfileCreatedSubscriber extends Subscriber<UserProfileCreatedEvent> {
253
+ exchange = Exchanges.UserProfile;
254
+ routingKey = RoutingKeys.UserProfileCreated;
255
+
256
+ async onMessage(
257
+ data: UserProfileCreatedEvent['data'],
258
+ msg: ConsumeMessage,
259
+ ): Promise<void> {
260
+ console.log('User created:', data);
261
+ // Your business logic here
262
+ }
263
+ }
264
+
265
+ // Subscribe to events
266
+ const subscriber = new UserProfileCreatedSubscriber(channel);
267
+ await subscriber.subscribe();
268
+ ```
269
+
270
+ ### Features
271
+
272
+ - ✅ **Type-safe events** - Full TypeScript support with autocomplete
273
+ - ✅ **Centralized definitions** - All events defined in one package
274
+ - ✅ **Consistent naming** - Clear routing key conventions
275
+ - ✅ **Durable queues** - Messages persist across restarts
276
+ - ✅ **Error handling** - Automatic message requeuing on failures
277
+ - ✅ **Documentation** - Comprehensive guides and examples
278
+
279
+ ### Available Events
280
+
281
+ **User Profile**: `UserProfileCreatedEvent`, `UserProfileUpdatedEvent`, `UserProfileDeletedEvent`
282
+
283
+ **Product**: `ProductCreatedEvent`, `ProductUpdatedEvent`, `ProductDeletedEvent`, `ProductStockChangedEvent`
284
+
285
+ **Order**: `OrderCreatedEvent`, `OrderUpdatedEvent`, `OrderCompletedEvent`, `OrderCancelledEvent`
286
+
287
+ ### Routing Key Convention
288
+
289
+ Format: `<service>.<entity>.<action>`
290
+
291
+ Examples:
292
+
293
+ - `user_profile.profile.created`
294
+ - `product.product.updated`
295
+ - `order.order.completed`
296
+
297
+ ### Documentation
298
+
299
+ - 📚 [Full Event System Documentation](src/events/README.md)
300
+ - 📋 [Event Guidelines](EVENT_GUIDELINES.md)
301
+ - 🚀 [Quick Reference](QUICK_REFERENCE.md)
302
+ - 🔄 [Migration Guide](MIGRATION.md)
303
+
304
+ ## Logging
305
+
306
+ ```typescript
307
+ import { Logger, createLogger, requestLogger } from '@myfoto/common-shared';
308
+
309
+ // Use default logger
310
+ import { log } from '@glow-up/common-shared';
311
+
312
+ log.info('Application started');
313
+ log.error('Something went wrong', error, { userId: '123' });
314
+
315
+ // Create custom logger
316
+ const logger = createLogger({
317
+ level: 'debug',
318
+ enableFile: true,
319
+ filePath: './logs/app.log',
320
+ });
321
+
322
+ // Add request logging middleware
323
+ app.use(requestLogger(logger));
324
+
325
+ // Performance logging
326
+ import { timeOperation } from '@glow-up/common-shared';
327
+
328
+ const result = await timeOperation(
329
+ 'database-query',
330
+ () => prisma.user.findMany(),
331
+ logger,
332
+ );
333
+ ```
334
+
335
+ ## Validation Patterns
336
+
337
+ ```typescript
338
+ import { ValidationPatterns } from '@glow-up/common-shared';
339
+
340
+ // Email with normalization
341
+ ValidationPatterns.email();
342
+
343
+ // Strong password requirements
344
+ ValidationPatterns.password();
345
+
346
+ // UUID validation
347
+ ValidationPatterns.uuid();
348
+
349
+ // Pagination parameters
350
+ ValidationPatterns.pagination();
351
+
352
+ // Phone number
353
+ ValidationPatterns.phoneNumber();
354
+
355
+ // Custom enum with case insensitive matching
356
+ ValidationPatterns.enumCaseInsensitive(['ACTIVE', 'INACTIVE']);
357
+ ```
358
+
359
+ ## TypeScript Support
360
+
361
+ This package is built with TypeScript and provides full type definitions. All utilities are properly typed for the best development experience.
362
+
363
+ ```typescript
364
+ // Types are automatically inferred
365
+ import {
366
+ ApiResponse,
367
+ PaginatedResponse,
368
+ LogLevel,
369
+ } from '@glow-up/common-shared';
370
+
371
+ // Extend Express types (automatically included)
372
+ declare global {
373
+ namespace Express {
374
+ interface Request {
375
+ user?: {
376
+ id: string;
377
+ email: string;
378
+ roles?: string[];
379
+ };
380
+ }
381
+ interface Response {
382
+ success: (data?: any, message?: string) => void;
383
+ error: (errors: any, message?: string, statusCode?: number) => void;
384
+ // ... other response methods
385
+ }
386
+ }
387
+ }
388
+ ```
389
+
390
+ ## Peer Dependencies
391
+
392
+ Make sure to install peer dependencies if you're using related features:
393
+
394
+ ```bash
395
+ # For database utilities
396
+ npm install @prisma/client
397
+
398
+ # For logging to files (if using file logging)
399
+ npm install winston
400
+ ```
401
+
402
+ ## Contributing
403
+
404
+ This package is part of the Glow Up microservices ecosystem. When adding new utilities:
405
+
406
+ 1. Follow the existing patterns and TypeScript conventions
407
+ 2. Add proper JSDoc documentation
408
+ 3. Include unit tests
409
+ 4. Update this README with usage examples
410
+
411
+ ## License
412
+
413
+ MIT License - see LICENSE file for details.
414
+
415
+ ## Changelog
416
+
417
+ ### 1.0.0
418
+
419
+ - Initial release with core utilities
420
+ - Error handling system
421
+ - Validation middleware
422
+ - Database utilities
423
+ - Response formatting
424
+ - Pagination helpers
425
+ - Logging system
426
+ - Password management
@@ -0,0 +1,13 @@
1
+ export interface LibraryCdn {
2
+ headLinks: string[];
3
+ bodyScripts: string[];
4
+ initScript?: string;
5
+ }
6
+ export declare const LIBRARY_CDN: Record<string, LibraryCdn>;
7
+ export declare const ALL_LIBRARY_SLUGS: string[];
8
+ export declare function buildLibraryHtml(slugs: string[]): {
9
+ head: string;
10
+ body: string;
11
+ };
12
+ export declare function detectLibrariesFromHtml(html: string | null | undefined): string[];
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/website-libraries/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAwElD,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAA6B,CAAC;AAEpE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAkBA;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC9B,MAAM,EAAE,CAcV"}
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ALL_LIBRARY_SLUGS = exports.LIBRARY_CDN = void 0;
4
+ exports.buildLibraryHtml = buildLibraryHtml;
5
+ exports.detectLibrariesFromHtml = detectLibrariesFromHtml;
6
+ exports.LIBRARY_CDN = {
7
+ gsap: {
8
+ headLinks: [],
9
+ bodyScripts: [
10
+ '<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>',
11
+ ],
12
+ },
13
+ "gsap-scrolltrigger": {
14
+ headLinks: [],
15
+ bodyScripts: [
16
+ '<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>',
17
+ '<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/ScrollTrigger.min.js"></script>',
18
+ ],
19
+ initScript: "(function(){if(window.__gsapStInit)return;window.__gsapStInit=true;gsap.registerPlugin(ScrollTrigger);})();",
20
+ },
21
+ swiper: {
22
+ headLinks: [
23
+ '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css"/>',
24
+ ],
25
+ bodyScripts: [
26
+ '<script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>',
27
+ ],
28
+ },
29
+ glightbox: {
30
+ headLinks: [
31
+ '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/glightbox@3.3.0/dist/css/glightbox.min.css"/>',
32
+ ],
33
+ bodyScripts: [
34
+ '<script src="https://cdn.jsdelivr.net/npm/glightbox@3.3.0/dist/js/glightbox.min.js"></script>',
35
+ ],
36
+ initScript: "(function(){if(window.__glightboxInit)return;window.__glightboxInit=true;GLightbox({touchNavigation:true,loop:true});})();",
37
+ },
38
+ typed: {
39
+ headLinks: [],
40
+ bodyScripts: [
41
+ '<script src="https://cdn.jsdelivr.net/npm/typed.js@2.1.0/dist/typed.umd.js"></script>',
42
+ ],
43
+ },
44
+ splitting: {
45
+ headLinks: [
46
+ '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/splitting@1.0.6/dist/splitting.css"/>',
47
+ '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/splitting@1.0.6/dist/splitting-cells.css"/>',
48
+ ],
49
+ bodyScripts: [
50
+ '<script src="https://cdn.jsdelivr.net/npm/splitting@1.0.6/dist/splitting.min.js"></script>',
51
+ ],
52
+ initScript: "(function(){if(window.__splittingInit)return;window.__splittingInit=true;Splitting();})();",
53
+ },
54
+ lenis: {
55
+ headLinks: [],
56
+ bodyScripts: [
57
+ '<script src="https://cdn.jsdelivr.net/npm/lenis@1.1.13/dist/lenis.min.js"></script>',
58
+ ],
59
+ initScript: "(function(){if(window.__lenisInit)return;window.__lenisInit=true;var l=new Lenis();function raf(t){l.raf(t);requestAnimationFrame(raf);}requestAnimationFrame(raf);window.lenis=l;})();",
60
+ },
61
+ countup: {
62
+ headLinks: [],
63
+ bodyScripts: [
64
+ '<script src="https://cdn.jsdelivr.net/npm/countup.js@2.8.0/dist/countUp.umd.js"></script>',
65
+ ],
66
+ },
67
+ particles: {
68
+ headLinks: [],
69
+ bodyScripts: [
70
+ '<script src="https://cdn.jsdelivr.net/npm/@tsparticles/engine@3.7.1/tsparticles.engine.min.js"></script>',
71
+ '<script src="https://cdn.jsdelivr.net/npm/@tsparticles/slim@3.7.1/tsparticles.slim.bundle.min.js"></script>',
72
+ ],
73
+ },
74
+ };
75
+ exports.ALL_LIBRARY_SLUGS = Object.keys(exports.LIBRARY_CDN);
76
+ function buildLibraryHtml(slugs) {
77
+ const headParts = [];
78
+ const bodyParts = [];
79
+ for (const slug of slugs) {
80
+ const lib = exports.LIBRARY_CDN[slug];
81
+ if (!lib)
82
+ continue;
83
+ headParts.push(...lib.headLinks);
84
+ bodyParts.push(...lib.bodyScripts);
85
+ if (lib.initScript) {
86
+ bodyParts.push("<script>" + lib.initScript + "</script>");
87
+ }
88
+ }
89
+ return {
90
+ head: headParts.join("\n"),
91
+ body: bodyParts.join("\n"),
92
+ };
93
+ }
94
+ function detectLibrariesFromHtml(html) {
95
+ const detected = [];
96
+ if (!html)
97
+ return detected;
98
+ if (/GLightbox|glightbox/i.test(html))
99
+ detected.push("glightbox");
100
+ if (/swiper/i.test(html))
101
+ detected.push("swiper");
102
+ if (/\bgsap\b/i.test(html) && /ScrollTrigger/i.test(html))
103
+ detected.push("gsap-scrolltrigger");
104
+ else if (/\bgsap\b/i.test(html))
105
+ detected.push("gsap");
106
+ if (/new Typed\(/i.test(html))
107
+ detected.push("typed");
108
+ if (/Splitting\(\)/i.test(html))
109
+ detected.push("splitting");
110
+ if (/new Lenis\(/i.test(html))
111
+ detected.push("lenis");
112
+ if (/CountUp\b|countUp/i.test(html))
113
+ detected.push("countup");
114
+ if (/tsParticles|particlesJS/i.test(html))
115
+ detected.push("particles");
116
+ return detected;
117
+ }
118
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/website-libraries/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,68 +1,73 @@
1
- {
2
- "name": "@easyweb/rabbitmq-utils",
3
- "version": "1.0.19",
4
- "description": "Common utilities and middleware for Easyweb microservices architecture",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "exports": {
8
- ".": {
9
- "require": "./dist/index.js",
10
- "import": "./dist/index.js",
11
- "types": "./dist/index.d.ts"
12
- }
13
- },
14
- "files": [
15
- "dist",
16
- "README.md"
17
- ],
18
- "scripts": {
19
- "build": "tsc",
20
- "build:watch": "tsc --watch",
21
- "prepublishOnly": "npm run build",
22
- "clean": "rimraf dist",
23
- "test": "jest",
24
- "test:watch": "jest --watch",
25
- "test:coverage": "jest --coverage",
26
- "lint": "eslint src/**/*.ts",
27
- "lint:fix": "eslint src/**/*.ts --fix"
28
- },
29
- "keywords": [
30
- "microservices",
31
- "express",
32
- "middleware",
33
- "validation",
34
- "authentication",
35
- "error-handling",
36
- "utilities"
37
- ],
38
- "author": "Easy Web Team",
39
- "license": "MIT",
40
- "repository": {
41
- "type": "git",
42
- "url": "https://github.com/Alpine-Solusi/website-builder.git",
43
- "directory": "server/common-shared"
44
- },
45
- "dependencies": {
46
- "amqplib": "^0.10.9",
47
- "pino": "^10.3.1"
48
- },
49
- "devDependencies": {
50
- "@types/amqplib": "^0.10.8",
51
- "@types/express": "^5.0.6",
52
- "@types/jest": "^29.5.14",
53
- "@types/node": "^25.2.3",
54
- "@typescript-eslint/eslint-plugin": "^8.56.1",
55
- "@typescript-eslint/parser": "^8.56.1",
56
- "eslint": "^8.50.0",
57
- "jest": "^29.7.0",
58
- "rimraf": "^5.0.5",
59
- "ts-jest": "^29.1.1",
60
- "typescript": "^5.9.3"
61
- },
62
- "engines": {
63
- "node": ">=18.0.0"
64
- },
65
- "publishConfig": {
66
- "access": "public"
67
- }
68
- }
1
+ {
2
+ "name": "@easyweb/rabbitmq-utils",
3
+ "version": "1.1.1",
4
+ "description": "Common utilities and middleware for Easyweb microservices architecture",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "require": "./dist/index.js",
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./website-libraries": {
14
+ "require": "./dist/website-libraries/index.js",
15
+ "import": "./dist/website-libraries/index.js",
16
+ "types": "./dist/website-libraries/index.d.ts"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "README.md"
22
+ ],
23
+ "scripts": {
24
+ "build": "tsc",
25
+ "build:watch": "tsc --watch",
26
+ "prepublishOnly": "npm run build",
27
+ "clean": "rimraf dist",
28
+ "test": "jest",
29
+ "test:watch": "jest --watch",
30
+ "test:coverage": "jest --coverage",
31
+ "lint": "eslint src/**/*.ts",
32
+ "lint:fix": "eslint src/**/*.ts --fix"
33
+ },
34
+ "keywords": [
35
+ "microservices",
36
+ "express",
37
+ "middleware",
38
+ "validation",
39
+ "authentication",
40
+ "error-handling",
41
+ "utilities"
42
+ ],
43
+ "author": "Easy Web Team",
44
+ "license": "MIT",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "https://github.com/Alpine-Solusi/website-builder.git",
48
+ "directory": "server/common-shared"
49
+ },
50
+ "dependencies": {
51
+ "amqplib": "^0.10.9",
52
+ "pino": "^10.3.1"
53
+ },
54
+ "devDependencies": {
55
+ "@types/amqplib": "^0.10.8",
56
+ "@types/express": "^5.0.6",
57
+ "@types/jest": "^29.5.14",
58
+ "@types/node": "^25.2.3",
59
+ "@typescript-eslint/eslint-plugin": "^8.56.1",
60
+ "@typescript-eslint/parser": "^8.56.1",
61
+ "eslint": "^8.50.0",
62
+ "jest": "^29.7.0",
63
+ "rimraf": "^5.0.5",
64
+ "ts-jest": "^29.1.1",
65
+ "typescript": "^5.9.3"
66
+ },
67
+ "engines": {
68
+ "node": ">=18.0.0"
69
+ },
70
+ "publishConfig": {
71
+ "access": "public"
72
+ }
73
+ }