@gp_jcisneros/aws-utils
Version:
AWS SDK utilities for GreenPay microservices
464 lines (336 loc) • 12.4 kB
Markdown
🚀 **AWS SDK utilities for GreenPay microservices** with standardized error handling and modern AWS SDK v3 support.
This NPM package provides easy-to-use utilities for common AWS operations including **Lambda**, **S3**, **SQS**, and **DynamoDB** with **standardized error handling** using `@gp_jcisneros/errors`.
- 🔧 **AWS SDK v3 Support** - Built with the latest AWS SDK
- 🛡️ **Standardized Error Handling** - Consistent error format across all utilities
- 📦 **Modular Design** - Import only what you need
- 🧪 **Comprehensive Testing** - Full test coverage
- 📚 **TypeScript Ready** - Full JSDoc documentation
- ⚡ **Performance Optimized** - Efficient AWS operations
```bash
npm install @gp_jcisneros/aws-utils
```
```javascript
const { DynamoUtils, S3Utils, LambdaUtils, SQSUtils } = require('@gp_jcisneros/aws-utils');
// DynamoDB - Get an item
const user = await DynamoUtils.getItem('users', { id: '123' });
// S3 - Upload a file
await S3Utils.uploadFile('my-bucket', 'data.json', Buffer.from('{"key": "value"}'));
// Lambda - Invoke a function
const result = await LambdaUtils.invokeLambda('my-function', { data: 'test' });
// SQS - Send a message
await SQSUtils.sendMessage('https://sqs.region.amazonaws.com/queue', 'Hello World!');
```
```javascript
const { LambdaUtils, invokeLambda } = require('@gp_jcisneros/aws-utils');
// Synchronous invocation
const result = await LambdaUtils.invokeLambda('my-function', { data: 'test' });
// Asynchronous invocation
await LambdaUtils.invokeLambdaAsync('my-function', { data: 'test' });
// Get function configuration
const config = await LambdaUtils.getFunctionConfiguration('my-function');
// Using convenience function
const result = await invokeLambda('my-function', { data: 'test' });
```
```javascript
const { S3Utils, uploadToS3 } = require('@gp_jcisneros/aws-utils');
// Upload a file
const result = await S3Utils.uploadFile('my-bucket', 'path/to/file.json', fileData);
// Upload JSON data
const result = await S3Utils.uploadJson('my-bucket', 'data.json', { key: 'value' });
// Download a file
const file = await S3Utils.downloadFile('my-bucket', 'path/to/file.json');
// Download and parse JSON
const data = await S3Utils.downloadJson('my-bucket', 'data.json');
// Delete a file
await S3Utils.deleteFile('my-bucket', 'path/to/file.json');
// Using convenience function
await uploadToS3('my-bucket', 'data.json', { key: 'value' });
```
```javascript
const { SQSUtils, sendToSQS } = require('@gp_jcisneros/aws-utils');
// Send a message
const result = await SQSUtils.sendMessage('https://sqs.region.amazonaws.com/queue-url', { data: 'test' });
// Send JSON message
const result = await SQSUtils.sendJsonMessage('queue-url', { key: 'value' });
// Receive messages
const messages = await SQSUtils.receiveMessages('queue-url');
// Process messages with handler
const results = await SQSUtils.processMessages('queue-url', async (message) => {
console.log('Processing:', message.Body);
return { processed: true };
});
// Delete a message
await SQSUtils.deleteMessage('queue-url', message.ReceiptHandle);
// Using convenience function
await sendToSQS('queue-url', { key: 'value' });
```
```javascript
const { DynamoUtils, getFromDynamo } = require('@gp_jcisneros/aws-utils');
// Get an item
const item = await DynamoUtils.getItem('my-table', { id: '123' });
// Put an item
const result = await DynamoUtils.putItem('my-table', { id: '123', data: 'value' });
// Update an item
const result = await DynamoUtils.updateItem(
'my-table',
{ id: '123' },
'SET #data = :data',
{ ':data': 'new-value' },
{ '#data': 'data' }
);
// Delete an item
await DynamoUtils.deleteItem('my-table', { id: '123' });
// Query items
const items = await DynamoUtils.queryItems(
'my-table',
'id = :id',
{ ':id': '123' }
);
// Scan items
const items = await DynamoUtils.scanItems('my-table');
// Batch get items
const items = await DynamoUtils.batchGetItems('my-table', [
{ id: '123' },
{ id: '456' }
]);
// Using convenience function
const item = await getFromDynamo('my-table', { id: '123' });
```
All utilities use **standardized error handling** with `@gp_jcisneros/errors`. Each error includes:
- **`errorCode`**: Specific error code for the operation
- **`description`**: Detailed error description
- **`integration`**: Service name (aws-utils)
- **`statusCode`**: Appropriate HTTP status code
- **`timestamp`**: Error timestamp
- **`type`**: Error type for categorization
### 🚨 Error Types
```javascript
const { AWSError, DatabaseError, IntegrationError } = require('@gp_jcisneros/aws-utils');
// AWS Errors (statusCode: 500)
const awsError = new AWSError('AWS service error', 'S3', 'UPLOAD_ERROR');
// {
// errorCode: 'AWS_S3',
// description: 'AWS service error',
// integration: 'aws-service',
// statusCode: 500,
// service: 'S3',
// awsErrorCode: 'UPLOAD_ERROR'
// }
// Database Errors (statusCode: 500)
const dbError = new DatabaseError('Database operation failed', 'GET', 'users');
// {
// errorCode: 'DB_GET',
// description: 'Database operation failed',
// integration: 'database-service',
// statusCode: 500,
// operation: 'GET',
// table: 'users'
// }
// Integration Errors (statusCode: 502)
const integrationError = new IntegrationError('External service error', 'SERVICE_ERROR', 'external-service', { context: 'data' });
// {
// errorCode: 'SERVICE_ERROR',
// description: 'External service error',
// integration: 'external-service',
// statusCode: 502,
// integrationCode: 'SERVICE_ERROR',
// integrationName: 'external-service',
// context: { context: 'data' }
// }
```
```javascript
const { DynamoUtils, DatabaseError, AWSError } = require('@gp_jcisneros/aws-utils');
try {
const item = await DynamoUtils.getItem('users', { id: '123' });
return item;
} catch (error) {
if (error instanceof DatabaseError) {
console.log('Database error:', {
errorCode: error.errorCode, // 'DB_GET'
description: error.description, // 'DynamoDB get failed for users: ...'
integration: error.integration, // 'database-service'
operation: error.operation, // 'GET'
table: error.table, // 'users'
statusCode: error.statusCode // 500
});
} else if (error instanceof AWSError) {
console.log('AWS error:', {
service: error.service, // 'DYNAMODB'
awsErrorCode: error.awsErrorCode, // 'ERROR_CODE'
statusCode: error.statusCode // 500
});
}
throw error;
}
```
Invokes a Lambda function synchronously or asynchronously.
**Parameters:**
- `functionName` (string): Name of the Lambda function
- `payload` (object): Data to send to the function
- `invocationType` (string): 'RequestResponse' or 'Event' (default: 'RequestResponse')
**Returns:** Promise with Lambda response
Invokes a Lambda function asynchronously.
Gets the configuration of a Lambda function.
Uploads a file to S3.
**Parameters:**
- `bucketName` (string): Name of the S3 bucket
- `key` (string): Object key (file path)
- `data` (Buffer|string): File data
- `contentType` (string): Content type (default: 'application/json')
**Returns:** Promise with upload result
#### `downloadFile(bucketName, key)`
Downloads a file from S3.
#### `deleteFile(bucketName, key)`
Deletes a file from S3.
#### `uploadJson(bucketName, key, jsonData)`
Uploads JSON data to S3.
#### `downloadJson(bucketName, key)`
Downloads and parses JSON from S3.
### SQSUtils
#### `sendMessage(queueUrl, messageBody, options)`
Sends a message to an SQS queue.
**Parameters:**
- `queueUrl` (string): URL of the SQS queue
- `messageBody` (object|string): Message to send
- `options` (object): Additional options (delaySeconds, messageAttributes, etc.)
**Returns:** Promise with send result
#### `receiveMessages(queueUrl, options)`
Receives messages from an SQS queue.
#### `deleteMessage(queueUrl, receiptHandle)`
Deletes a message from an SQS queue.
#### `sendJsonMessage(queueUrl, jsonData, options)`
Sends JSON data to an SQS queue.
#### `processMessages(queueUrl, messageHandler, options)`
Processes messages from an SQS queue with a handler function.
### DynamoUtils
#### `getItem(tableName, key)`
Gets an item from DynamoDB.
**Parameters:**
- `tableName` (string): Name of the DynamoDB table
- `key` (object): Primary key of the item
**Returns:** Promise with item or null
#### `putItem(tableName, item)`
Puts an item in DynamoDB.
#### `updateItem(tableName, key, updateExpression, expressionAttributeValues, expressionAttributeNames)`
Updates an item in DynamoDB.
#### `deleteItem(tableName, key)`
Deletes an item from DynamoDB.
#### `queryItems(tableName, keyConditionExpression, expressionAttributeValues, expressionAttributeNames, indexName)`
Queries items from DynamoDB.
#### `scanItems(tableName, filterExpression, expressionAttributeValues, expressionAttributeNames)`
Scans items from DynamoDB.
#### `batchGetItems(tableName, keys)`
Batch gets items from DynamoDB.
## 🧪 Testing
```bash
# Run all tests
npm test
# Run tests with coverage
npm run test:coverage
# Run tests in watch mode
npm run test:watch
# Run specific test file
npm test -- tests/DynamoUtils.test.js
```
## 🛠️ Development
```bash
# Install dependencies
npm install
# Run linting
npm run lint
# Fix linting issues
npm run lint:fix
# Format code
npm run format
# Run tests before commit
npm run pre-commit
```
## 🚀 Despliegue Local
### Configuración del Token NPM
Para publicar el paquete localmente, primero configura tu token de npm:
```bash
# Configurar token de npm (reemplaza TU_TOKEN_AQUI con tu token real)
npm config set //registry.npmjs.org/:_authToken=TU_TOKEN_AQUI
# Verificar que estás autenticado
npm whoami
```
### Pasos para Publicar
```bash
# 1. Instalar dependencias
npm install
# 2. Ejecutar tests
npm test
# 3. Ejecutar linting
npm run lint
# 4. Verificar qué se va a publicar
npm pack
# 5. Publicar el paquete
npm publish --access public
```
### Verificar la Publicación
```bash
# Verificar que el paquete se publicó correctamente
npm info @gp_jcisneros/aws-utils
# Instalar el paquete para probar
npm install @gp_jcisneros/aws-utils
```
### Actualizar Versión
```bash
# Incrementar versión patch (1.0.0 -> 1.0.1)
npm version patch
# Incrementar versión minor (1.0.0 -> 1.1.0)
npm version minor
# Incrementar versión major (1.0.0 -> 2.0.0)
npm version major
# Publicar nueva versión
npm publish
```
## 📦 Dependencies
- **@aws-sdk/client-lambda**: ^3.500.0
- **@aws-sdk/client-s3**: ^3.500.0
- **@aws-sdk/client-sqs**: ^3.500.0
- **@aws-sdk/lib-dynamodb**: ^3.500.0
- **@gp_jcisneros/errors**: ^1.0.1-dev
## 🤝 Contributing
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## 📄 License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## 📋 Changelog
### v1.0.1-dev
- ✅ **Updated error handling** to use new `@gp_jcisneros/errors` constructor
- ✅ **Improved error messages** with better context and details
- ✅ **Enhanced integration errors** with service-specific information
- ✅ **Updated all utilities** to use standardized error handling
- ✅ **Better error codes** for different AWS operations
- ✅ **Consistent error format** across all utilities
- ✅ **Removed singleton pattern** for better flexibility
- ✅ **Enhanced test coverage** with comprehensive error testing
- ✅ **Updated documentation** with new error handling examples
### v1.0.0
- 🎉 Initial release
- ✨ AWS SDK v3 support
- 🛡️ Standardized error handling
- 📦 Modular utility classes
- 🧪 Comprehensive test suite