Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 1x 1x 1x 1x 1x 2x 2x 2x 1x 1x 1x 1x | import { ImageService } from '../services/imageService';
import { ApiResponse } from '../common/apiResponse';
import { ValidationError } from '../common/errors';
import {
LambdaEvent,
PresignUploadRequest,
PresignUploadResponse,
} from '../dto/image.dto';
import { getLogger } from '../common/logger';
const logger = getLogger('ImageController');
const imageService = new ImageService();
/**
* Generate a presigned S3 upload URL for image upload
* @param event - Lambda event containing filename and contentType in request body
* @returns ApiResponse with imageId and presigned upload URL
* @throws ValidationError if filename or contentType is missing or invalid
*/
export async function presignUpload(event: LambdaEvent): Promise<ApiResponse> {
const body: PresignUploadRequest = event.body
? (JSON.parse(event.body) as PresignUploadRequest)
: {};
logger.info('PresignUpload invoked', event);
const { filename, contentType } = body;
Iif (!filename || !contentType) {
logger.warn('PresignUpload validation failed', event, {
filename,
contentType,
});
throw new ValidationError('filename and contentType are required');
}
const result = await imageService.generatePresignedUpload(
filename,
contentType
);
logger.info('PresignUpload URL generated', event, {
imageId: result.imageId,
uploadUrl: result.uploadUrl,
});
const response: PresignUploadResponse = {
imageId: result.imageId,
url: result.uploadUrl,
};
return ApiResponse.created({ success: true, data: response });
}
/**
* Retrieve image metadata by ID
* @param event - Lambda event with image ID in path parameters
* @returns ApiResponse with image metadata or 404 if not found
* @throws ValidationError if image ID is missing
*/
export async function getImage(event: LambdaEvent): Promise<ApiResponse> {
logger.info('getImage invoked', event);
const id = event.pathParameters?.id;
if (!id) throw new ValidationError('Image ID is required');
const metadata = await imageService.getImageMetaData(id);
if (!metadata) {
logger.warn('getImage not found', event, { id });
return ApiResponse.notFound('Image not found');
}
logger.info('getImage success', event, metadata.imageId);
return ApiResponse.ok(metadata);
}
/**
* Delete an image and its metadata
* @param event - Lambda event with image ID in path parameters
* @returns ApiResponse with 204 No Content on success or 404 if not found
* @throws ValidationError if image ID is missing
*/
export async function deleteImage(event: LambdaEvent): Promise<ApiResponse> {
logger.info('deleteImage invoked', event);
const id = event.pathParameters?.id;
if (!id) throw new ValidationError('Image ID is required');
const deleted = await imageService.deleteImage(id);
if (!deleted) {
logger.warn('deleteImage not found', event, { id });
return ApiResponse.notFound('Image not found');
}
logger.info('deleteImage success', event, { id });
return ApiResponse.no_content({
success: true,
message: 'Image deleted successfully',
});
}
|