@nixxie-international/s3-service
v1.0.4
Published
A comprehensive AWS S3 service wrapper with TypeScript support
Maintainers
Readme
S3 Service
A comprehensive AWS S3 service wrapper with TypeScript support, designed for easy file management and operations.
Features
- 🚀 Easy to use - Simple API for common S3 operations
- 📁 File Management - Upload, download, delete, and list files
- 🔒 Access Control - Support for public and private files
- 🔗 Signed URLs - Generate secure, time-limited access URLs
- 📝 TypeScript - Full TypeScript support with type definitions
- 🏗️ Flexible - Singleton pattern with support for multiple instances
- 📊 Logging - Configurable logging support
- ✅ Well Tested - Comprehensive test coverage
Installation
npm install @nixxie-international/s3-serviceQuick Start
import { S3Service } from '@nixxie-international/s3-service';
// Create service instance
const s3Service = S3Service.getInstance({
bucket: 'your-bucket-name',
region: 'us-east-1',
accessKeyId: 'your-access-key',
secretAccessKey: 'your-secret-key'
});
// Initialize the service
await s3Service.initialize();
// Upload a file
const fileBuffer = Buffer.from('Hello, World!');
const fileKey = await s3Service.uploadFile(fileBuffer, {
filename: 'hello',
extension: 'txt',
folder: 'documents'
});
console.log('File uploaded:', fileKey);Configuration
Basic Configuration
import { S3Service, S3ServiceConfig } from '@nixxie-international/s3-service';
const config: S3ServiceConfig = {
bucket: 'your-bucket-name',
region: 'us-east-1', // Optional, defaults to us-east-1
accessKeyId: 'your-access-key', // Optional, uses env var AWS_ACCESS_KEY_ID
secretAccessKey: 'your-secret-key', // Optional, uses env var AWS_SECRET_ACCESS_KEY
publicFolder: 'public', // Optional, defaults to 'public'
logger: customLogger // Optional, uses console logger by default
};
const s3Service = S3Service.getInstance(config);Environment Variables
You can also configure using environment variables:
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_REGION=us-east-1API Reference
File Upload
uploadFile(fileBuffer, options)
Upload a file to S3.
const fileKey = await s3Service.uploadFile(fileBuffer, {
contentType: 'image/jpeg',
folder: 'images',
filename: 'profile-pic',
extension: 'jpg',
metadata: { userId: '123' },
isPublic: true
});uploadPublicFile(fileBuffer, options)
Upload a file to the public folder.
const fileKey = await s3Service.uploadPublicFile(fileBuffer, {
filename: 'avatar',
extension: 'png'
});File Retrieval
getFile(key)
Retrieve a file from S3.
const { buffer, contentType } = await s3Service.getFile('documents/hello.txt');fileExists(key)
Check if a file exists.
const exists = await s3Service.fileExists('documents/hello.txt');getFileMetadata(key)
Get file metadata.
const metadata = await s3Service.getFileMetadata('documents/hello.txt');
console.log(metadata.ContentLength, metadata.LastModified);File Management
deleteFile(key)
Delete a single file.
await s3Service.deleteFile('documents/old-file.txt');deleteFiles(keys)
Delete multiple files.
await s3Service.deleteFiles([
'documents/file1.txt',
'documents/file2.txt'
]);copyFile(sourceKey, destinationKey, options)
Copy a file within S3.
await s3Service.copyFile(
'documents/original.txt',
'backup/original-backup.txt',
{ isPublic: true }
);listFiles(prefix, maxKeys)
List files in a folder.
const files = await s3Service.listFiles('documents/', 100);
files.forEach(file => {
console.log(file.Key, file.Size, file.LastModified);
});Access Control
makeFilePublic(key)
Make an existing file public.
await s3Service.makeFilePublic('documents/public-doc.pdf');makeFilePrivate(key)
Make an existing file private.
await s3Service.makeFilePrivate('documents/private-doc.pdf');isPublicFile(key)
Check if a file is in the public folder.
const isPublic = s3Service.isPublicFile('public/images/logo.png'); // trueURL Generation
getPublicUrl(key)
Get the public URL for a file.
const url = s3Service.getPublicUrl('public/images/logo.png');
// Returns: https://your-bucket.s3.us-east-1.amazonaws.com/public/images/logo.pnggetSignedUrl(key, options)
Generate a signed URL for secure access.
// Default: 1 hour expiration for getObject
const url = await s3Service.getSignedUrl('private/document.pdf');
// Custom expiration and operation
const uploadUrl = await s3Service.getSignedUrl('uploads/new-file.jpg', {
expiresIn: 3600, // 1 hour
operation: 'putObject'
});Advanced Usage
Multiple Instances
You can create multiple S3Service instances for different buckets:
const productionS3 = S3Service.getInstance({
bucket: 'production-bucket'
}, 'production');
const stagingS3 = S3Service.getInstance({
bucket: 'staging-bucket'
}, 'staging');Custom Logger
Implement your own logger:
import { Logger } from '@nixxie-international/s3-service';
class CustomLogger implements Logger {
info(message: string, meta?: any): void {
// Your custom logging logic
}
error(message: string, meta?: any): void {
// Your custom error logging
}
warn(message: string, meta?: any): void {
// Your custom warning logging
}
debug(message: string, meta?: any): void {
// Your custom debug logging
}
}
const s3Service = S3Service.getInstance({
bucket: 'your-bucket',
logger: new CustomLogger()
});File Upload with Progress
For large files, you might want to use multipart uploads:
// For large files, consider using AWS SDK directly for multipart uploads
// This service is optimized for smaller files and standard uploadsError Handling
The service throws descriptive errors for various scenarios:
try {
await s3Service.uploadFile(fileBuffer, options);
} catch (error) {
if (error.message === 'Failed to upload file to S3') {
// Handle upload failure
}
}Common error scenarios:
- Initialization failed: Invalid credentials or bucket doesn't exist
- Upload failed: Network issues, insufficient permissions, or invalid file
- File not found: Trying to access a non-existent file
- Access denied: Insufficient permissions for the operation
TypeScript Support
Full TypeScript support with comprehensive type definitions:
import { S3Service, S3ServiceConfig, UploadOptions, FileResult } from '@nixxie-international/s3-service';
const config: S3ServiceConfig = {
bucket: 'my-bucket',
region: 'us-west-2'
};
const options: UploadOptions = {
contentType: 'application/pdf',
isPublic: false,
metadata: {
uploadedBy: 'user123'
}
};
const result: FileResult = await s3Service.getFile('document.pdf');Best Practices
1. Initialize Once
// Good: Initialize once at application startup
const s3Service = S3Service.getInstance(config);
await s3Service.initialize();
// Use throughout your application
export { s3Service };2. Use Appropriate Folders
// Organize files in logical folders
await s3Service.uploadFile(profilePic, {
folder: 'users/avatars',
isPublic: true
});
await s3Service.uploadFile(document, {
folder: 'users/documents',
isPublic: false
});3. Handle Errors Gracefully
try {
const fileKey = await s3Service.uploadFile(buffer, options);
return { success: true, fileKey };
} catch (error) {
logger.error('File upload failed', { error, options });
return { success: false, error: error.message };
}4. Use Signed URLs for Private Files
// Instead of making files public, use signed URLs
const signedUrl = await s3Service.getSignedUrl(privateFileKey, {
expiresIn: 3600 // 1 hour
});Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Changelog
1.0.0
- Initial release
- Basic S3 operations (upload, download, delete)
- Public/private file management
- Signed URL generation
- TypeScript support
- Comprehensive test coverage
