@gp_jcisneros/aws-utils
Version:
AWS SDK utilities for GreenPay microservices
595 lines (430 loc) • 17.5 kB
Markdown
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**, **DynamoDB**, and **Cognito** 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, CognitoUtils } = 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!');
// Cognito - User login
const authResult = await CognitoUtils.login('username', 'password', poolData);
```
```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' });
```
```javascript
const { CognitoUtils, login } = require('@gp_jcisneros/aws-utils');
// Pool data configuration
const poolData = {
ClientId: 'your-client-id',
UserPoolId: 'your-user-pool-id',
SecretHash: 'your-secret-hash'
};
// User authentication
const loginResult = await CognitoUtils.login('username', 'password', poolData);
// User registration
const signUpResult = await CognitoUtils.signUp('username', 'password', poolData, [
{ Name: 'email', Value: 'user@example.com' },
{ Name: 'given_name', Value: 'John' }
]);
// Verify user with confirmation code
await CognitoUtils.verify('username', '123456', poolData);
// Forgot password flow
await CognitoUtils.forgotPassword('username', poolData);
// Confirm new password
await CognitoUtils.confirmPassword('username', '123456', 'newPassword', poolData);
// Refresh tokens
const refreshResult = await CognitoUtils.refreshToken('username', 'refreshToken', poolData);
// Revoke tokens
await CognitoUtils.revokeToken('accessToken', poolData);
// Change password (requires access token)
await CognitoUtils.changePassword('accessToken', 'oldPassword', 'newPassword');
// Admin operations - Add user to group
await CognitoUtils.adminAddUserToGroup('username', 'admin', poolData);
// Admin operations - Remove user from group
await CognitoUtils.adminRemoveUserFromGroup('username', 'admin', poolData);
// Group management - Create group
await CognitoUtils.addGroupPool('admin', 'Administrator group', poolData);
// Group management - Delete group
await CognitoUtils.deleteGroupPool('admin', poolData);
// User management - Delete user
await CognitoUtils.deleteUserPool('username', poolData);
// Using convenience functions
const result = await login('username', 'password', poolData);
```
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/errors');
// 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 } = require('@gp_jcisneros/aws-utils');
const { DatabaseError, AWSError } = require('@gp_jcisneros/errors');
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.
### CognitoUtils
#### `login(username, password, poolData)`
Authenticates a user with username and password.
**Parameters:**
- `username` (string): User's username or email
- `password` (string): User's password
- `poolData` (object): Cognito pool configuration with ClientId, UserPoolId, and SecretHash
**Returns:** Promise with authentication result including tokens
#### `signUp(username, password, poolData, userAttributes)`
Registers a new user in Cognito.
**Parameters:**
- `username` (string): Desired username
- `password` (string): User's password
- `poolData` (object): Cognito pool configuration
- `userAttributes` (array): User attributes (email, given_name, etc.)
**Returns:** Promise with registration result
#### `verify(username, code, poolData)`
Verifies a user's email/phone with confirmation code.
#### `forgotPassword(username, poolData)`
Initiates forgot password flow.
#### `confirmPassword(username, code, newPassword, poolData)`
Confirms new password with verification code.
#### `refreshToken(username, refreshToken, poolData)`
Refreshes access tokens using refresh token.
#### `revokeToken(token, poolData)`
Revokes access or refresh tokens.
#### `changePassword(accessToken, oldPassword, newPassword)`
Changes user password (requires valid access token).
#### `adminAddUserToGroup(username, groupName, poolData)`
Adds user to a Cognito group (admin operation).
#### `adminRemoveUserFromGroup(username, groupName, poolData)`
Removes user from a Cognito group (admin operation).
#### `addGroupPool(groupName, description, poolData)`
Creates a new group in the user pool.
#### `deleteGroupPool(groupName, poolData)`
Deletes a group from the user pool.
#### `deleteUserPool(username, poolData)`
Deletes a user from the user pool (admin operation).
## 🧪 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
- **@aws-sdk/client-cognito-identity-provider**: ^3.856.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.13-dev
- ✅ **Added CognitoUtils** - Complete AWS Cognito integration
- ✅ **User authentication** - Login, signup, verification flows
- ✅ **Password management** - Forgot password, change password, confirm password
- ✅ **Token management** - Refresh tokens, revoke tokens
- ✅ **Admin operations** - User group management, user deletion
- ✅ **Group management** - Create and delete user pool groups
- ✅ **Comprehensive error handling** for all Cognito operations
- ✅ **Static methods** for convenient usage
- ✅ **Full test coverage** for CognitoUtils
- ✅ **Updated documentation** with Cognito examples and API reference
### 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
🚀 **AWS SDK utilities