@andrewlwn77/s3-upload-mcp-server
Version:
Pure Node.js MCP server for uploading images to AWS S3 with high-performance validation using Sharp and file-type
162 lines • 6.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ImageUploadService = void 0;
const s3_client_1 = require("../infrastructure/s3-client");
const image_validator_1 = require("../validation/image-validator");
const config_1 = require("../utils/config");
const file_utils_1 = require("../utils/file-utils");
const logger_1 = require("../utils/logger");
class ImageUploadService {
constructor() {
this.s3Client = new s3_client_1.S3Client();
this.imageValidator = new image_validator_1.ImageValidator();
this.configManager = config_1.ConfigManager.getInstance();
this.logger = logger_1.Logger.getInstance();
}
async uploadImageData(imageData, filename, bucket, contentType) {
try {
// Validate bucket
const bucketName = this.configManager.validateBucket(bucket);
// Validate filename
if (!file_utils_1.FileUtils.validateFilename(filename)) {
return {
success: false,
error: {
code: 'VALIDATION_ERROR',
message: 'Invalid filename format'
}
};
}
if (!file_utils_1.FileUtils.validateImageExtension(filename)) {
return {
success: false,
error: {
code: 'VALIDATION_ERROR',
message: 'Unsupported image file extension'
}
};
}
// Validate base64 image data
const validationResult = await this.imageValidator.validateBase64Image(imageData, filename);
if (!validationResult.success) {
return validationResult;
}
if (!validationResult.is_valid) {
return {
success: false,
error: {
code: 'VALIDATION_ERROR',
message: 'Image validation failed',
details: { validation_errors: validationResult.validation_errors }
}
};
}
// Convert base64 to buffer
const imageBuffer = file_utils_1.FileUtils.base64ToBuffer(imageData);
// Determine content type
const finalContentType = contentType ||
validationResult.content_type ||
file_utils_1.FileUtils.getContentType(filename);
// Generate S3 key
const s3Key = file_utils_1.FileUtils.generateUniqueFilename(filename);
// Upload to S3 using secure presigned URL method
const uploadResult = await this.s3Client.uploadImageDataViaUrl(imageBuffer, s3Key, bucketName, finalContentType);
if (!uploadResult.success) {
return uploadResult;
}
this.logger.info('Image uploaded successfully', {
bucket: bucketName,
key: s3Key,
size: imageBuffer.length
});
return uploadResult;
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown image upload error';
this.logger.error('Image upload service failed', { error: errorMessage, filename });
return {
success: false,
error: {
code: 'UPLOAD_ERROR',
message: errorMessage
}
};
}
}
async uploadImageFile(filePath, bucket, key, preserveFilename = true) {
try {
// Validate bucket
const bucketName = this.configManager.validateBucket(bucket);
// Check if file exists
if (!(await file_utils_1.FileUtils.fileExists(filePath))) {
return {
success: false,
error: {
code: 'FILE_ERROR',
message: 'File does not exist'
}
};
}
// Validate image file
const validationResult = await this.imageValidator.validateImageFile(filePath);
if (!validationResult.success) {
return validationResult;
}
if (!validationResult.is_valid) {
return {
success: false,
error: {
code: 'VALIDATION_ERROR',
message: 'Image validation failed',
details: { validation_errors: validationResult.validation_errors }
}
};
}
// Generate S3 key
let s3Key;
if (key) {
s3Key = key;
}
else {
const filename = filePath.split('/').pop() || 'unknown';
s3Key = preserveFilename ?
file_utils_1.FileUtils.generateUniqueFilename(filename) :
file_utils_1.FileUtils.generateUniqueFilename(filename, undefined, true);
}
// Validate S3 key
if (!file_utils_1.FileUtils.validateFilename(s3Key)) {
return {
success: false,
error: {
code: 'VALIDATION_ERROR',
message: 'Invalid S3 key format'
}
};
}
// Upload file to S3
const uploadResult = await this.s3Client.uploadFile(filePath, s3Key, bucketName);
if (!uploadResult.success) {
return uploadResult;
}
this.logger.info('File uploaded successfully', {
bucket: bucketName,
key: s3Key,
filePath
});
return uploadResult;
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown file upload error';
this.logger.error('File upload service failed', { error: errorMessage, filePath });
return {
success: false,
error: {
code: 'UPLOAD_ERROR',
message: errorMessage
}
};
}
}
}
exports.ImageUploadService = ImageUploadService;
//# sourceMappingURL=image-upload-service.js.map