From 7c39a4594463442d07d09bba03c4e24639d59d70 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Sat, 14 Mar 2026 22:43:18 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=8D=20refactor:=20Normalize=20Non-Stan?= =?UTF-8?q?dard=20Browser=20MIME=20Type=20Aliases=20in=20`inferMimeType`?= =?UTF-8?q?=20(#12240)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ๐Ÿ› fix: Normalize non-standard browser MIME types in inferMimeType macOS Chrome/Firefox report .py files as text/x-python-script instead of text/x-python, causing client-side validation to reject Python file uploads. inferMimeType now normalizes known MIME type aliases before returning, so non-standard variants match the accepted regex patterns. * ๐Ÿงช test: Add tests for MIME type alias normalization in inferMimeType * ๐Ÿ› fix: Restore JSDoc params and make mimeTypeAliases immutable * ๐Ÿงช test: Add checkType integration tests, remove redundant DragDropModal tests --- .../data-provider/src/file-config.spec.ts | 41 ++++++++++++++++++- packages/data-provider/src/file-config.ts | 16 +++++--- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/packages/data-provider/src/file-config.spec.ts b/packages/data-provider/src/file-config.spec.ts index 018b4dbfcf..0ab9f23a3e 100644 --- a/packages/data-provider/src/file-config.spec.ts +++ b/packages/data-provider/src/file-config.spec.ts @@ -1,15 +1,52 @@ import type { FileConfig } from './types/files'; import { fileConfig as baseFileConfig, + documentParserMimeTypes, getEndpointFileConfig, - mergeFileConfig, applicationMimeTypes, defaultOCRMimeTypes, - documentParserMimeTypes, supportedMimeTypes, + mergeFileConfig, + inferMimeType, + textMimeTypes, } from './file-config'; import { EModelEndpoint } from './schemas'; +describe('inferMimeType', () => { + it('should normalize text/x-python-script to text/x-python', () => { + expect(inferMimeType('test.py', 'text/x-python-script')).toBe('text/x-python'); + }); + + it('should return a type that matches textMimeTypes after normalization', () => { + const normalized = inferMimeType('test.py', 'text/x-python-script'); + expect(textMimeTypes.test(normalized)).toBe(true); + }); + + it('should pass through standard browser types unchanged', () => { + expect(inferMimeType('test.py', 'text/x-python')).toBe('text/x-python'); + expect(inferMimeType('doc.pdf', 'application/pdf')).toBe('application/pdf'); + }); + + it('should infer from extension when browser type is empty', () => { + expect(inferMimeType('test.py', '')).toBe('text/x-python'); + expect(inferMimeType('code.js', '')).toBe('text/javascript'); + expect(inferMimeType('photo.heic', '')).toBe('image/heic'); + }); + + it('should return empty string for unknown extension with no browser type', () => { + expect(inferMimeType('file.xyz', '')).toBe(''); + }); + + it('should produce a type accepted by checkType after normalizing text/x-python-script', () => { + const normalized = inferMimeType('test.py', 'text/x-python-script'); + expect(baseFileConfig.checkType(normalized)).toBe(true); + }); + + it('should reject raw text/x-python-script without normalization', () => { + expect(baseFileConfig.checkType('text/x-python-script')).toBe(false); + }); +}); + describe('applicationMimeTypes', () => { const odfTypes = [ 'application/vnd.oasis.opendocument.text', diff --git a/packages/data-provider/src/file-config.ts b/packages/data-provider/src/file-config.ts index 033c868a80..67b4197958 100644 --- a/packages/data-provider/src/file-config.ts +++ b/packages/data-provider/src/file-config.ts @@ -357,15 +357,21 @@ export const imageTypeMapping: { [key: string]: string } = { heif: 'image/heif', }; +/** Normalizes non-standard MIME types that browsers may report to their canonical forms */ +export const mimeTypeAliases: Readonly> = { + 'text/x-python-script': 'text/x-python', +}; + /** - * Infers the MIME type from a file's extension when the browser doesn't recognize it - * @param fileName - The name of the file including extension - * @param currentType - The current MIME type reported by the browser (may be empty) - * @returns The inferred MIME type if browser didn't provide one, otherwise the original type + * Infers the MIME type from a file's extension when the browser doesn't recognize it, + * and normalizes known non-standard MIME type aliases to their canonical forms. + * @param fileName - The file name including its extension + * @param currentType - The MIME type reported by the browser (may be empty string) + * @returns The normalized or inferred MIME type; empty string if unresolvable */ export function inferMimeType(fileName: string, currentType: string): string { if (currentType) { - return currentType; + return mimeTypeAliases[currentType] ?? currentType; } const extension = fileName.split('.').pop()?.toLowerCase() ?? '';