feat: turn mimetype into proper util to dedupe this all
Node.js CI / CI (push) Successful in 25s
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 59s

This commit is contained in:
2026-01-08 23:29:50 -08:00
parent 6acef3b770
commit 6fe566b3f6
5 changed files with 93 additions and 149 deletions
+5 -5
View File
@@ -1,13 +1,13 @@
# Crowdin # Crowdin
CROWDIN_PROJECT_ID="op://Environment Variables - Development/Scripts/Crowdin Project ID" CROWDIN_PROJECT_ID="op://Environment Variables - Development/Ephemere/Crowdin Project ID"
CROWDIN_API_URL="op://Environment Variables - Development/Scripts/Crowdin API Url" CROWDIN_API_URL="op://Environment Variables - Development/Ephemere/Crowdin API Url"
CROWDIN_TOKEN="op://Environment Variables - Development/Scripts/Crowdin Token" CROWDIN_TOKEN="op://Environment Variables - Development/Ephemere/Crowdin Token"
# Github # Github
GITHUB_TOKEN="op://Environment Variables - Development/Scripts/GitHub Token" GITHUB_TOKEN="op://Environment Variables - Development/Ephemere/GitHub Token"
# Discord # Discord
DISCORD_TOKEN="op://Environment Variables - Development/Scripts/Discord Token" DISCORD_TOKEN="op://Environment Variables - Development/Ephemere/Discord Token"
DISCORD_CLIENT_ID="op://Private/Guild Counter/client id" DISCORD_CLIENT_ID="op://Private/Guild Counter/client id"
DISCORD_CLIENT_SECRET="op://Private/Guild Counter/client secret" DISCORD_CLIENT_SECRET="op://Private/Guild Counter/client secret"
+4
View File
@@ -8,6 +8,7 @@ import { join, relative } from "node:path";
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"; import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { confirm } from "@inquirer/prompts"; import { confirm } from "@inquirer/prompts";
import { SingleBar, Presets } from "cli-progress"; import { SingleBar, Presets } from "cli-progress";
import { getMimeType } from "../utils/mimeType.js";
const accessKeyId = process.env.AWS_ACCESS_KEY_ID; const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY; const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
@@ -185,6 +186,7 @@ for (const file of files) {
try { try {
const filePath = join(dataDirectory, file); const filePath = join(dataDirectory, file);
const fileContent = await readFile(filePath); const fileContent = await readFile(filePath);
const contentType = getMimeType(file);
const command = new PutObjectCommand({ const command = new PutObjectCommand({
// eslint-disable-next-line @typescript-eslint/naming-convention -- AWS SDK // eslint-disable-next-line @typescript-eslint/naming-convention -- AWS SDK
@@ -192,6 +194,8 @@ for (const file of files) {
// eslint-disable-next-line @typescript-eslint/naming-convention -- AWS SDK // eslint-disable-next-line @typescript-eslint/naming-convention -- AWS SDK
Bucket: "nhcarrigan", Bucket: "nhcarrigan",
// eslint-disable-next-line @typescript-eslint/naming-convention -- AWS SDK // eslint-disable-next-line @typescript-eslint/naming-convention -- AWS SDK
ContentType: contentType,
// eslint-disable-next-line @typescript-eslint/naming-convention -- AWS SDK
Key: file, Key: file,
}); });
+1 -70
View File
@@ -3,7 +3,6 @@
* @license Naomi's Public License * @license Naomi's Public License
* @author Naomi Carrigan * @author Naomi Carrigan
*/ */
import { extname } from "node:path";
import { import {
CopyObjectCommand, CopyObjectCommand,
HeadObjectCommand, HeadObjectCommand,
@@ -12,6 +11,7 @@ import {
S3Client, S3Client,
} from "@aws-sdk/client-s3"; } from "@aws-sdk/client-s3";
import { confirm } from "@inquirer/prompts"; import { confirm } from "@inquirer/prompts";
import { getMimeType } from "../utils/mimeType.js";
const accessKeyId = process.env.AWS_ACCESS_KEY_ID; const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY; const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
@@ -30,75 +30,6 @@ const s3 = new S3Client({
const bucket = "nhcarrigan"; const bucket = "nhcarrigan";
/**
* 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<string, string> = {
".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 fileName - The file name or path.
* @returns The MIME type, or undefined if unknown.
*/
const getMimeType = (fileName: string): string | undefined => {
const extension = extname(fileName).toLowerCase();
return mimeTypes[extension];
};
/** /**
* Lists all objects in the S3 bucket recursively. * Lists all objects in the S3 bucket recursively.
* @returns An array of object keys. * @returns An array of object keys.
+2 -70
View File
@@ -4,9 +4,10 @@
* @author Naomi Carrigan * @author Naomi Carrigan
*/ */
import { readFile } from "node:fs/promises"; import { readFile } from "node:fs/promises";
import { extname, join } from "node:path"; import { join } from "node:path";
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"; import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { input } from "@inquirer/prompts"; import { input } from "@inquirer/prompts";
import { getMimeType } from "../utils/mimeType.js";
const accessKeyId = process.env.AWS_ACCESS_KEY_ID; const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY; const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
@@ -43,75 +44,6 @@ const s3 = new S3Client({
region: "hel1", 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<string, string> = {
".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); const contentType = getMimeType(uploadPath);
if (contentType === undefined) { if (contentType === undefined) {
+77
View File
@@ -0,0 +1,77 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { extname } from "node:path";
/**
* 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<string, string> = {
".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":
// eslint-disable-next-line stylistic/max-len -- Big boi string.
"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.
*/
export const getMimeType = (filePath: string): string | undefined => {
const extension = extname(filePath).toLowerCase();
return mimeTypes[extension];
};