diff --git a/src/mime.js b/src/mime.js new file mode 100644 index 0000000..f0c63e7 --- /dev/null +++ b/src/mime.js @@ -0,0 +1,29 @@ +import { fileTypeFromFile } from 'file-type'; + +const OUTPUT_MIME_TYPES = { + jpg: 'image/jpeg', + jpeg: 'image/jpeg', + png: 'image/png', + webp: 'image/webp', + gif: 'image/gif', + tiff: 'image/tiff', + avif: 'image/avif', + bmp: 'image/bmp', + pdf: 'application/pdf', + html: 'text/html', + txt: 'text/plain', + docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', +}; + +export async function detectInputMime(filePath) { + const result = await fileTypeFromFile(filePath); + return result ?? null; +} + +export function outputMimeType(targetFormat) { + const mime = OUTPUT_MIME_TYPES[targetFormat]; + if (!mime) { + throw new Error(`No known MIME type for target format "${targetFormat}"`); + } + return mime; +} diff --git a/test/fixtures/sample.png b/test/fixtures/sample.png new file mode 100644 index 0000000..520b38b Binary files /dev/null and b/test/fixtures/sample.png differ diff --git a/test/mime.test.js b/test/mime.test.js new file mode 100644 index 0000000..bdc5e47 --- /dev/null +++ b/test/mime.test.js @@ -0,0 +1,27 @@ +import { describe, it, expect } from 'vitest'; +import path from 'node:path'; +import { detectInputMime, outputMimeType } from '../src/mime.js'; + +describe('detectInputMime', () => { + it('detects PNG from magic bytes regardless of file extension', async () => { + const fixturePath = path.join(import.meta.dirname, 'fixtures', 'sample.png'); + + const result = await detectInputMime(fixturePath); + + expect(result).toEqual({ ext: 'png', mime: 'image/png' }); + }); +}); + +describe('outputMimeType', () => { + it('returns the MIME type for a known target format', () => { + expect(outputMimeType('pdf')).toBe('application/pdf'); + expect(outputMimeType('png')).toBe('image/png'); + expect(outputMimeType('docx')).toBe( + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' + ); + }); + + it('throws for an unknown target format', () => { + expect(() => outputMimeType('made-up-format')).toThrowError(/made-up-format/); + }); +});