mime-bytes 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export { FileTypeDetector, FileTypeDetectorOptions, defaultDetector, detectFromStream, detectFromBuffer, detectFromExtension } from './file-type-detector';
2
+ export { FileTypeDefinition, DetectionResult, ContentTypeMapping, FILE_TYPES, CONTENT_TYPE_MAPPINGS, getFileTypeByMagicBytes, getFileTypeByExtension, getFileTypesByCategory, getContentTypeByExtension, detectCharset } from './file-types-registry';
3
+ export { peek, BufferPeekStream, PeekStreamOptions, PeekCallback, PeekPromise } from './peak';
4
+ export * from './utils/magic-bytes';
5
+ export * from './utils/mime-types';
6
+ export * from './utils/extensions';
package/index.js ADDED
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ // Main export file for mime-bytes package
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.BufferPeekStream = exports.peek = exports.detectCharset = exports.getContentTypeByExtension = exports.getFileTypesByCategory = exports.getFileTypeByExtension = exports.getFileTypeByMagicBytes = exports.CONTENT_TYPE_MAPPINGS = exports.FILE_TYPES = exports.detectFromExtension = exports.detectFromBuffer = exports.detectFromStream = exports.defaultDetector = exports.FileTypeDetector = void 0;
19
+ // Export the main detector class and convenience functions
20
+ var file_type_detector_1 = require("./file-type-detector");
21
+ Object.defineProperty(exports, "FileTypeDetector", { enumerable: true, get: function () { return file_type_detector_1.FileTypeDetector; } });
22
+ Object.defineProperty(exports, "defaultDetector", { enumerable: true, get: function () { return file_type_detector_1.defaultDetector; } });
23
+ Object.defineProperty(exports, "detectFromStream", { enumerable: true, get: function () { return file_type_detector_1.detectFromStream; } });
24
+ Object.defineProperty(exports, "detectFromBuffer", { enumerable: true, get: function () { return file_type_detector_1.detectFromBuffer; } });
25
+ Object.defineProperty(exports, "detectFromExtension", { enumerable: true, get: function () { return file_type_detector_1.detectFromExtension; } });
26
+ // Export registry types and functions
27
+ var file_types_registry_1 = require("./file-types-registry");
28
+ Object.defineProperty(exports, "FILE_TYPES", { enumerable: true, get: function () { return file_types_registry_1.FILE_TYPES; } });
29
+ Object.defineProperty(exports, "CONTENT_TYPE_MAPPINGS", { enumerable: true, get: function () { return file_types_registry_1.CONTENT_TYPE_MAPPINGS; } });
30
+ Object.defineProperty(exports, "getFileTypeByMagicBytes", { enumerable: true, get: function () { return file_types_registry_1.getFileTypeByMagicBytes; } });
31
+ Object.defineProperty(exports, "getFileTypeByExtension", { enumerable: true, get: function () { return file_types_registry_1.getFileTypeByExtension; } });
32
+ Object.defineProperty(exports, "getFileTypesByCategory", { enumerable: true, get: function () { return file_types_registry_1.getFileTypesByCategory; } });
33
+ Object.defineProperty(exports, "getContentTypeByExtension", { enumerable: true, get: function () { return file_types_registry_1.getContentTypeByExtension; } });
34
+ Object.defineProperty(exports, "detectCharset", { enumerable: true, get: function () { return file_types_registry_1.detectCharset; } });
35
+ // Export peek stream functionality
36
+ var peak_1 = require("./peak");
37
+ Object.defineProperty(exports, "peek", { enumerable: true, get: function () { return peak_1.peek; } });
38
+ Object.defineProperty(exports, "BufferPeekStream", { enumerable: true, get: function () { return peak_1.BufferPeekStream; } });
39
+ // Export utility functions
40
+ __exportStar(require("./utils/magic-bytes"), exports);
41
+ __exportStar(require("./utils/mime-types"), exports);
42
+ __exportStar(require("./utils/extensions"), exports);
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "mime-bytes",
3
+ "version": "0.0.2",
4
+ "author": "Dan Lynch <pyramation@gmail.com>",
5
+ "description": "mime-bytes",
6
+ "main": "index.js",
7
+ "module": "esm/index.js",
8
+ "types": "index.d.ts",
9
+ "homepage": "https://github.com/launchql/launchql",
10
+ "license": "SEE LICENSE IN LICENSE",
11
+ "publishConfig": {
12
+ "access": "public",
13
+ "directory": "dist"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/launchql/launchql"
18
+ },
19
+ "bugs": {
20
+ "url": "https://github.com/launchql/launchql/issues"
21
+ },
22
+ "scripts": {
23
+ "copy": "copyfiles -f ../../LICENSE README.md package.json dist",
24
+ "clean": "rimraf dist/**",
25
+ "prepare": "npm run build",
26
+ "build": "npm run clean; tsc; tsc -p tsconfig.esm.json; npm run copy",
27
+ "build:dev": "npm run clean; tsc --declarationMap; tsc -p tsconfig.esm.json; npm run copy",
28
+ "lint": "eslint . --fix",
29
+ "test": "jest",
30
+ "test:watch": "jest --watch"
31
+ },
32
+ "keywords": [],
33
+ "devDependencies": {
34
+ "@types/glob": "^8.1.0",
35
+ "glob": "^11.0.2"
36
+ },
37
+ "gitHead": "52bbc49baf1ed0e4a1b1f349bf1817b3f71f72b0"
38
+ }
package/peak.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { Transform, TransformOptions, Readable } from 'stream';
2
+ export interface PeekStreamOptions extends TransformOptions {
3
+ peekBytes: number;
4
+ }
5
+ export declare class BufferPeekStream extends Transform {
6
+ private peekBytes;
7
+ private buffer;
8
+ private bufferLength;
9
+ private peeked;
10
+ constructor(options: PeekStreamOptions);
11
+ _transform(chunk: any, encoding: BufferEncoding, callback: Function): void;
12
+ _flush(callback: Function): void;
13
+ }
14
+ export declare function peek(source: Readable, bytes: number, callback?: (err: Error | null, buffer: Buffer, dest: BufferPeekStream) => void): BufferPeekStream;
15
+ export declare function peek(source: Readable, callback: (err: Error | null, buffer: Buffer, dest: BufferPeekStream) => void): BufferPeekStream;
16
+ export declare namespace peek {
17
+ var promise: (source: Readable, bytes?: number) => Promise<[Buffer, BufferPeekStream]>;
18
+ }
19
+ export type PeekCallback = (err: Error | null, buffer: Buffer, dest: BufferPeekStream) => void;
20
+ export type PeekPromise = (source: Readable, bytes?: number) => Promise<[Buffer, BufferPeekStream]>;
package/peak.js ADDED
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ // TypeScript implementation of peek stream for efficient file type detection
3
+ // Based on reference-packages/buffer-peak/peak.js
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.BufferPeekStream = void 0;
6
+ exports.peek = peek;
7
+ const stream_1 = require("stream");
8
+ class BufferPeekStream extends stream_1.Transform {
9
+ peekBytes;
10
+ buffer;
11
+ bufferLength;
12
+ peeked;
13
+ constructor(options) {
14
+ super(options);
15
+ this.peekBytes = options.peekBytes || 16;
16
+ this.buffer = Buffer.alloc(0);
17
+ this.bufferLength = 0;
18
+ this.peeked = false;
19
+ }
20
+ _transform(chunk, encoding, callback) {
21
+ if (this.peeked) {
22
+ // After peeking, just pass through
23
+ this.push(chunk);
24
+ callback();
25
+ return;
26
+ }
27
+ // Accumulate data until we have enough to peek
28
+ const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding);
29
+ this.buffer = Buffer.concat([this.buffer, chunkBuffer]);
30
+ this.bufferLength += chunkBuffer.length;
31
+ if (this.bufferLength >= this.peekBytes) {
32
+ // We have enough data to peek
33
+ this.peeked = true;
34
+ // Emit the peek event with the requested bytes
35
+ const peekBuffer = this.buffer.slice(0, this.peekBytes);
36
+ this.emit('peek', peekBuffer);
37
+ // Push all accumulated data
38
+ this.push(this.buffer);
39
+ this.buffer = Buffer.alloc(0);
40
+ this.bufferLength = 0;
41
+ callback();
42
+ }
43
+ else {
44
+ // Need more data
45
+ callback();
46
+ }
47
+ }
48
+ _flush(callback) {
49
+ if (!this.peeked && this.bufferLength > 0) {
50
+ // Not enough data was received, emit what we have
51
+ this.peeked = true;
52
+ this.emit('peek', this.buffer);
53
+ this.push(this.buffer);
54
+ }
55
+ callback();
56
+ }
57
+ }
58
+ exports.BufferPeekStream = BufferPeekStream;
59
+ function peek(source, bytesOrCallback, callback) {
60
+ let bytes;
61
+ let cb;
62
+ if (typeof bytesOrCallback === 'function') {
63
+ bytes = 16; // Default peek bytes
64
+ cb = bytesOrCallback;
65
+ }
66
+ else {
67
+ bytes = bytesOrCallback;
68
+ cb = callback;
69
+ }
70
+ const dest = new BufferPeekStream({ peekBytes: bytes });
71
+ if (cb) {
72
+ dest.once('peek', (buffer) => {
73
+ cb(null, buffer, dest);
74
+ });
75
+ dest.once('error', (err) => {
76
+ cb(err, Buffer.alloc(0), dest);
77
+ });
78
+ }
79
+ return source.pipe(dest);
80
+ }
81
+ // Promise-based version
82
+ peek.promise = function (source, bytes = 16) {
83
+ return new Promise((resolve, reject) => {
84
+ const dest = peek(source, bytes, (err, buffer, stream) => {
85
+ if (err) {
86
+ reject(err);
87
+ }
88
+ else {
89
+ resolve([buffer, stream]);
90
+ }
91
+ });
92
+ // Handle source errors
93
+ source.once('error', reject);
94
+ });
95
+ };
@@ -0,0 +1,9 @@
1
+ export declare function normalizeExtension(extension: string): string;
2
+ export declare function getExtension(filename: string): string;
3
+ export declare function isCompressedExtension(extension: string): boolean;
4
+ export declare function isDocumentExtension(extension: string): boolean;
5
+ export declare function isMediaExtension(extension: string): boolean;
6
+ export declare function isImageExtension(extension: string): boolean;
7
+ export declare function isExecutableExtension(extension: string): boolean;
8
+ export declare function getCategoryFromExtension(extension: string): string;
9
+ export declare function getDoubleExtension(filename: string): string | null;
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ // Extension utility functions
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.normalizeExtension = normalizeExtension;
5
+ exports.getExtension = getExtension;
6
+ exports.isCompressedExtension = isCompressedExtension;
7
+ exports.isDocumentExtension = isDocumentExtension;
8
+ exports.isMediaExtension = isMediaExtension;
9
+ exports.isImageExtension = isImageExtension;
10
+ exports.isExecutableExtension = isExecutableExtension;
11
+ exports.getCategoryFromExtension = getCategoryFromExtension;
12
+ exports.getDoubleExtension = getDoubleExtension;
13
+ // Normalize file extension
14
+ function normalizeExtension(extension) {
15
+ return extension.toLowerCase().replace(/^\./, '');
16
+ }
17
+ // Extract extension from filename
18
+ function getExtension(filename) {
19
+ const lastDot = filename.lastIndexOf('.');
20
+ if (lastDot === -1 || lastDot === filename.length - 1) {
21
+ return '';
22
+ }
23
+ return normalizeExtension(filename.substring(lastDot + 1));
24
+ }
25
+ // Check if extension is commonly associated with compressed files
26
+ function isCompressedExtension(extension) {
27
+ const compressed = [
28
+ 'zip', 'rar', '7z', 'tar', 'gz', 'bz2', 'xz', 'lz', 'lzma', 'z',
29
+ 'tgz', 'tbz', 'tbz2', 'txz', 'tlz', 'arc', 'arj', 'cab', 'dmg',
30
+ 'iso', 'lha', 'lzh', 'pkg', 'deb', 'rpm', 'msi', 'jar', 'war',
31
+ 'ear', 'sar', 'aar', 'apk', 'ipa', 'xpi', 'egg', 'whl', 'gem'
32
+ ];
33
+ return compressed.includes(normalizeExtension(extension));
34
+ }
35
+ // Check if extension is commonly associated with document files
36
+ function isDocumentExtension(extension) {
37
+ const documents = [
38
+ 'pdf', 'doc', 'docx', 'odt', 'rtf', 'tex', 'wpd', 'txt', 'md',
39
+ 'xls', 'xlsx', 'ods', 'csv', 'ppt', 'pptx', 'odp', 'epub', 'mobi',
40
+ 'azw', 'azw3', 'fb2', 'lit', 'pdb', 'ps', 'eps', 'indd', 'xps'
41
+ ];
42
+ return documents.includes(normalizeExtension(extension));
43
+ }
44
+ // Check if extension is commonly associated with media files
45
+ function isMediaExtension(extension) {
46
+ const media = [
47
+ // Video
48
+ 'mp4', 'avi', 'mkv', 'mov', 'wmv', 'flv', 'webm', 'vob', 'ogv',
49
+ 'ogg', 'm4v', '3gp', '3g2', 'mpg', 'mpeg', 'mp2', 'mpe', 'mpv',
50
+ 'm2v', 'svi', 'mxf', 'roq', 'nsv', 'f4v', 'f4p', 'f4a', 'f4b',
51
+ // Audio
52
+ 'mp3', 'wav', 'flac', 'aac', 'ogg', 'oga', 'wma', 'm4a', 'opus',
53
+ 'ape', 'wv', 'amr', 'ac3', 'dts', 'spx', 'mid', 'midi', 'kar',
54
+ 'aiff', 'aif', 'aifc', 'au', 'snd', 'voc', 'ra', 'rm', 'ram'
55
+ ];
56
+ return media.includes(normalizeExtension(extension));
57
+ }
58
+ // Check if extension is commonly associated with image files
59
+ function isImageExtension(extension) {
60
+ const images = [
61
+ 'jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp', 'ico', 'tif',
62
+ 'tiff', 'psd', 'raw', 'heif', 'heic', 'indd', 'ai', 'eps', 'ps',
63
+ 'xcf', 'cdr', 'cmx', 'dib', 'jxr', 'hdp', 'wdp', 'cur', 'icns',
64
+ 'pbm', 'pgm', 'ppm', 'pnm', 'pcx', 'dcx', 'dds', 'dng', 'cr2',
65
+ 'cr3', 'crw', 'nef', 'nrw', 'orf', 'raf', 'rw2', 'rwl', 'srw',
66
+ 'arw', 'srf', 'sr2', 'bay', 'cap', 'iiq', 'eip', 'dcs', 'dcr',
67
+ 'drf', 'k25', 'kdc', 'mdc', 'mef', 'mos', 'mrw', 'pef', 'ptx',
68
+ 'pxn', 'r3d', 'x3f', 'qoi'
69
+ ];
70
+ return images.includes(normalizeExtension(extension));
71
+ }
72
+ // Check if extension is commonly associated with executable files
73
+ function isExecutableExtension(extension) {
74
+ const executables = [
75
+ 'exe', 'dll', 'so', 'dylib', 'app', 'deb', 'rpm', 'dmg', 'pkg',
76
+ 'msi', 'bat', 'cmd', 'sh', 'ps1', 'vbs', 'js', 'jar', 'class',
77
+ 'pyc', 'pyo', 'elf', 'o', 'out', 'bin', 'run', 'com', 'scr',
78
+ 'cpl', 'ocx', 'sys', 'drv', 'efi', 'mui', 'ax', 'ime', 'rs',
79
+ 'tsp', 'fon', 'wasm', 'ko', 'mod', 'prx', 'puff', 'axf', 'dex'
80
+ ];
81
+ return executables.includes(normalizeExtension(extension));
82
+ }
83
+ // Get category from extension
84
+ function getCategoryFromExtension(extension) {
85
+ const ext = normalizeExtension(extension);
86
+ if (isImageExtension(ext))
87
+ return 'image';
88
+ if (isMediaExtension(ext))
89
+ return 'media';
90
+ if (isDocumentExtension(ext))
91
+ return 'document';
92
+ if (isCompressedExtension(ext))
93
+ return 'archive';
94
+ if (isExecutableExtension(ext))
95
+ return 'executable';
96
+ // Check for specific categories
97
+ const categories = {
98
+ font: ['ttf', 'otf', 'woff', 'woff2', 'eot', 'fon', 'fnt'],
99
+ database: ['db', 'db3', 'sqlite', 'sqlite3', 'mdb', 'accdb', 'dbf'],
100
+ code: ['js', 'ts', 'jsx', 'tsx', 'py', 'java', 'c', 'cpp', 'h', 'hpp', 'cs', 'php', 'rb', 'go', 'rs', 'swift', 'kt', 'scala', 'r', 'lua', 'pl', 'sh', 'bash', 'zsh', 'fish', 'ps1', 'psm1', 'psd1', 'bat', 'cmd'],
101
+ config: ['json', 'xml', 'yaml', 'yml', 'toml', 'ini', 'cfg', 'conf', 'properties', 'env'],
102
+ text: ['txt', 'md', 'markdown', 'rst', 'asciidoc', 'adoc', 'org', 'tex', 'log']
103
+ };
104
+ for (const [category, extensions] of Object.entries(categories)) {
105
+ if (extensions.includes(ext)) {
106
+ return category;
107
+ }
108
+ }
109
+ return 'other';
110
+ }
111
+ // Common double extensions (e.g., .tar.gz)
112
+ const DOUBLE_EXTENSIONS = [
113
+ 'tar.gz', 'tar.bz2', 'tar.xz', 'tar.lz', 'tar.lzma', 'tar.Z',
114
+ 'tar.br', 'tar.zst', 'user.js', 'min.js', 'min.css', 'd.ts'
115
+ ];
116
+ // Get double extension if applicable
117
+ function getDoubleExtension(filename) {
118
+ const lower = filename.toLowerCase();
119
+ for (const doubleExt of DOUBLE_EXTENSIONS) {
120
+ if (lower.endsWith('.' + doubleExt)) {
121
+ return doubleExt;
122
+ }
123
+ }
124
+ return null;
125
+ }
@@ -0,0 +1,9 @@
1
+ export declare function hexToBuffer(hexArray: string[]): Buffer;
2
+ export declare function bufferToHex(buffer: Buffer): string;
3
+ export declare function compareBytes(buffer: Buffer, pattern: string[], offset?: number): boolean;
4
+ export declare function findMagicBytes(buffer: Buffer, patterns: Array<{
5
+ pattern: string[];
6
+ offset?: number;
7
+ }>): number;
8
+ export declare function extractBytes(buffer: Buffer, offset: number, length: number): Buffer;
9
+ export declare function isTextLike(buffer: Buffer): boolean;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ // Magic bytes utility functions
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.hexToBuffer = hexToBuffer;
5
+ exports.bufferToHex = bufferToHex;
6
+ exports.compareBytes = compareBytes;
7
+ exports.findMagicBytes = findMagicBytes;
8
+ exports.extractBytes = extractBytes;
9
+ exports.isTextLike = isTextLike;
10
+ function hexToBuffer(hexArray) {
11
+ const bytes = hexArray.map(hex => {
12
+ if (hex === '?')
13
+ return 0; // Wildcard placeholder
14
+ return parseInt(hex.replace(/0x/i, ''), 16);
15
+ });
16
+ return Buffer.from(bytes);
17
+ }
18
+ function bufferToHex(buffer) {
19
+ return buffer.toString('hex');
20
+ }
21
+ function compareBytes(buffer, pattern, offset = 0) {
22
+ // Empty patterns should not match
23
+ if (!pattern || pattern.length === 0) {
24
+ return false;
25
+ }
26
+ if (offset + pattern.length > buffer.length) {
27
+ return false;
28
+ }
29
+ for (let i = 0; i < pattern.length; i++) {
30
+ if (pattern[i] === '?')
31
+ continue; // Skip wildcards
32
+ const expectedByte = parseInt(pattern[i].replace(/0x/i, ''), 16);
33
+ const actualByte = buffer[offset + i];
34
+ if (expectedByte !== actualByte) {
35
+ return false;
36
+ }
37
+ }
38
+ return true;
39
+ }
40
+ function findMagicBytes(buffer, patterns) {
41
+ for (let i = 0; i < patterns.length; i++) {
42
+ const { pattern, offset = 0 } = patterns[i];
43
+ if (compareBytes(buffer, pattern, offset)) {
44
+ return i;
45
+ }
46
+ }
47
+ return -1;
48
+ }
49
+ // Extract a specific number of bytes from buffer at offset
50
+ function extractBytes(buffer, offset, length) {
51
+ if (offset + length > buffer.length) {
52
+ return buffer.slice(offset);
53
+ }
54
+ return buffer.slice(offset, offset + length);
55
+ }
56
+ // Check if buffer contains text-like content
57
+ function isTextLike(buffer) {
58
+ const sampleSize = Math.min(buffer.length, 512);
59
+ let printableCount = 0;
60
+ for (let i = 0; i < sampleSize; i++) {
61
+ const byte = buffer[i];
62
+ // Check for printable ASCII characters, tabs, newlines, carriage returns
63
+ if ((byte >= 32 && byte <= 126) || byte === 9 || byte === 10 || byte === 13) {
64
+ printableCount++;
65
+ }
66
+ }
67
+ // If more than 85% are printable characters, likely text
68
+ return (printableCount / sampleSize) > 0.85;
69
+ }
@@ -0,0 +1,14 @@
1
+ export declare const MIME_CATEGORIES: {
2
+ readonly IMAGE: "image";
3
+ readonly VIDEO: "video";
4
+ readonly AUDIO: "audio";
5
+ readonly APPLICATION: "application";
6
+ readonly TEXT: "text";
7
+ readonly FONT: "font";
8
+ };
9
+ export type MimeCategory = typeof MIME_CATEGORIES[keyof typeof MIME_CATEGORIES];
10
+ export declare function getMimeCategory(mimeType: string): MimeCategory | null;
11
+ export declare function isBinaryMimeType(mimeType: string): boolean;
12
+ export declare function normalizeMimeType(mimeType: string): string;
13
+ export declare function getFileCategoryFromMime(mimeType: string): string;
14
+ export declare function resolveMimeAlias(mimeType: string): string;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ // MIME type utility functions
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.MIME_CATEGORIES = void 0;
5
+ exports.getMimeCategory = getMimeCategory;
6
+ exports.isBinaryMimeType = isBinaryMimeType;
7
+ exports.normalizeMimeType = normalizeMimeType;
8
+ exports.getFileCategoryFromMime = getFileCategoryFromMime;
9
+ exports.resolveMimeAlias = resolveMimeAlias;
10
+ // Common MIME type categories
11
+ exports.MIME_CATEGORIES = {
12
+ IMAGE: 'image',
13
+ VIDEO: 'video',
14
+ AUDIO: 'audio',
15
+ APPLICATION: 'application',
16
+ TEXT: 'text',
17
+ FONT: 'font'
18
+ };
19
+ // Extract category from MIME type
20
+ function getMimeCategory(mimeType) {
21
+ const category = mimeType.split('/')[0];
22
+ if (Object.values(exports.MIME_CATEGORIES).includes(category)) {
23
+ return category;
24
+ }
25
+ return null;
26
+ }
27
+ // Check if MIME type is binary
28
+ function isBinaryMimeType(mimeType) {
29
+ const textTypes = [
30
+ 'text/',
31
+ 'application/json',
32
+ 'application/xml',
33
+ 'application/javascript',
34
+ 'application/typescript',
35
+ 'application/x-sh',
36
+ 'application/x-csh',
37
+ 'application/x-python',
38
+ 'application/x-ruby',
39
+ 'application/x-perl'
40
+ ];
41
+ return !textTypes.some(type => mimeType.startsWith(type));
42
+ }
43
+ // Normalize MIME type (remove parameters)
44
+ function normalizeMimeType(mimeType) {
45
+ return mimeType.split(';')[0].trim().toLowerCase();
46
+ }
47
+ // Get file category from MIME type
48
+ function getFileCategoryFromMime(mimeType) {
49
+ const normalized = normalizeMimeType(mimeType);
50
+ if (normalized.startsWith('image/'))
51
+ return 'image';
52
+ if (normalized.startsWith('video/'))
53
+ return 'video';
54
+ if (normalized.startsWith('audio/'))
55
+ return 'audio';
56
+ if (normalized.startsWith('font/'))
57
+ return 'font';
58
+ if (normalized.startsWith('text/'))
59
+ return 'text';
60
+ // Special cases for application types
61
+ if (normalized.includes('zip') || normalized.includes('compressed') || normalized.includes('archive')) {
62
+ return 'archive';
63
+ }
64
+ if (normalized.includes('pdf') || normalized.includes('document') || normalized.includes('msword') || normalized.includes('officedocument')) {
65
+ return 'document';
66
+ }
67
+ if (normalized.includes('executable') || normalized.includes('x-msdownload') || normalized.includes('x-elf') || normalized.includes('x-mach')) {
68
+ return 'executable';
69
+ }
70
+ if (normalized.includes('sqlite') || normalized.includes('database')) {
71
+ return 'database';
72
+ }
73
+ return 'other';
74
+ }
75
+ // Common MIME type aliases
76
+ const MIME_ALIASES = {
77
+ 'application/x-javascript': 'application/javascript',
78
+ 'text/javascript': 'application/javascript',
79
+ 'application/x-mpegURL': 'application/vnd.apple.mpegurl',
80
+ 'audio/mp3': 'audio/mpeg',
81
+ 'audio/x-mp3': 'audio/mpeg',
82
+ 'audio/x-mpeg': 'audio/mpeg',
83
+ 'video/x-m4v': 'video/mp4',
84
+ 'audio/x-m4a': 'audio/mp4',
85
+ 'image/jpg': 'image/jpeg',
86
+ 'image/x-png': 'image/png',
87
+ 'image/x-icon': 'image/vnd.microsoft.icon',
88
+ 'text/xml': 'application/xml',
89
+ 'application/x-compressed': 'application/x-compress',
90
+ 'application/x-gzip': 'application/gzip',
91
+ 'application/x-bzip': 'application/x-bzip2',
92
+ 'application/x-tar': 'application/tar'
93
+ };
94
+ // Resolve MIME type aliases
95
+ function resolveMimeAlias(mimeType) {
96
+ const normalized = normalizeMimeType(mimeType);
97
+ return MIME_ALIASES[normalized] || normalized;
98
+ }