diff --git a/src/s3/correctContentType.ts b/src/s3/correctContentType.ts index 58ef9d3..e4235b1 100644 --- a/src/s3/correctContentType.ts +++ b/src/s3/correctContentType.ts @@ -249,6 +249,8 @@ for (const objectKey of allObjects) { console.log(`✗ Skipped ${objectKey}`); skippedCount = skippedCount + 1; } + } else { + console.log(`✓ ${objectKey} is already correct: ${currentContentType ?? "undefined"}`); } } diff --git a/src/s3/upload.ts b/src/s3/upload.ts index d5f9cd1..f657f1d 100644 --- a/src/s3/upload.ts +++ b/src/s3/upload.ts @@ -4,7 +4,7 @@ * @author Naomi Carrigan */ import { readFile } from "node:fs/promises"; -import { join } from "node:path"; +import { extname, join } from "node:path"; import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"; import { input } from "@inquirer/prompts"; @@ -43,13 +43,92 @@ const s3 = new S3Client({ region: "hel1", }); +/** + * MIME type mapping for file extensions. + */ +/* eslint-disable @typescript-eslint/naming-convention -- File extensions */ +/* eslint-disable stylistic/key-spacing -- Alignment for readability */ +const mimeTypes: Record = { + ".7z": "application/x-7z-compressed", + ".aac": "audio/aac", + ".avi": "video/x-msvideo", + ".bmp": "image/bmp", + ".css": "text/css", + ".csv": "text/csv", + ".doc": "application/msword", + ".docx": + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + ".eot": "application/vnd.ms-fontobject", + ".flac": "audio/flac", + ".gif": "image/gif", + ".gz": "application/gzip", + ".htm": "text/html", + ".html": "text/html", + ".ico": "image/x-icon", + ".jpeg": "image/jpeg", + ".jpg": "image/jpeg", + ".js": "text/javascript", + ".json": "application/json", + ".md": "text/markdown", + ".mkv": "video/x-matroska", + ".mov": "video/quicktime", + ".mp3": "audio/mpeg", + ".mp4": "video/mp4", + ".ogg": "audio/ogg", + ".otf": "font/otf", + ".pdf": "application/pdf", + ".png": "image/png", + ".ppt": "application/vnd.ms-powerpoint", + ".pptx": + "application/vnd.openxmlformats-officedocument.presentationml.presentation", + ".rar": "application/x-rar-compressed", + ".svg": "image/svg+xml", + ".tar": "application/x-tar", + ".tif": "image/tiff", + ".tiff": "image/tiff", + ".ttf": "font/ttf", + ".txt": "text/plain", + ".wav": "audio/wav", + ".webm": "video/webm", + ".webp": "image/webp", + ".woff": "font/woff", + ".woff2": "font/woff2", + ".xls": "application/vnd.ms-excel", + ".xlsx": + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + ".xml": "application/xml", + ".zip": "application/zip", +}; +/* eslint-enable @typescript-eslint/naming-convention -- File extensions */ +/* eslint-enable stylistic/key-spacing -- Alignment for readability */ + +/** + * Gets the MIME type for a file based on its extension. + * @param filePath - The file name or path. + * @returns The MIME type, or undefined if unknown. + */ +const getMimeType = (filePath: string): string | undefined => { + const extension = extname(filePath).toLowerCase(); + return mimeTypes[extension]; +}; + +const contentType = getMimeType(uploadPath); + +if (contentType === undefined) { + console.warn( + `Warning: Unknown file type for ${uploadPath}. Content type will not be set.`, + ); +} + const command = new PutObjectCommand({ // eslint-disable-next-line @typescript-eslint/naming-convention -- AWS SDK - Body: file, + Body: file, // eslint-disable-next-line @typescript-eslint/naming-convention -- AWS SDK - Bucket: "nhcarrigan", + Bucket: "nhcarrigan", // eslint-disable-next-line @typescript-eslint/naming-convention -- AWS SDK - Key: uploadPath, + ContentType: contentType, + // eslint-disable-next-line @typescript-eslint/naming-convention -- AWS SDK + Key: uploadPath, }); await s3.send(command);