97 lines
2.3 KiB
TypeScript
97 lines
2.3 KiB
TypeScript
import { FileSystem } from 'react-native-file-access';
|
|
import filetypemime from 'magic-bytes.js';
|
|
import { lookup } from 'react-native-mime-types';
|
|
import { MEME_TYPE } from '../database';
|
|
|
|
const allowedImageMimeTypes = [
|
|
'image/bmp',
|
|
'image/jpg',
|
|
'image/jpeg',
|
|
'image/png',
|
|
'image/webp',
|
|
];
|
|
|
|
const allowedGifMimeTypes = ['image/gif'];
|
|
|
|
const allowedVideoMimeTypes = [
|
|
'video/av01',
|
|
'video/3gpp',
|
|
'video/avc',
|
|
'video/hevc',
|
|
'video/x-matroska',
|
|
'video/mp2t',
|
|
'video/mp4',
|
|
'video/mp42',
|
|
'video/mp43',
|
|
'video/mp4v-es',
|
|
'video/mpeg',
|
|
'video/mpeg2',
|
|
'video/x-vnd.on2.vp8',
|
|
'video/x-vnd.on2.vp9',
|
|
'video/webm',
|
|
];
|
|
|
|
const allowedMimeTypes = [
|
|
...allowedImageMimeTypes,
|
|
...allowedGifMimeTypes,
|
|
...allowedVideoMimeTypes,
|
|
];
|
|
|
|
const getMemeTypeFromMimeType = (mimeType: string): MEME_TYPE | undefined => {
|
|
if (!allowedMimeTypes.includes(mimeType)) return undefined;
|
|
|
|
const mimeStart = mimeType.split('/')[0];
|
|
|
|
switch (mimeStart) {
|
|
case 'image': {
|
|
if (mimeType === 'image/gif') return MEME_TYPE.GIF;
|
|
return MEME_TYPE.IMAGE;
|
|
}
|
|
case 'video': {
|
|
return MEME_TYPE.VIDEO;
|
|
}
|
|
}
|
|
};
|
|
|
|
const guessMimeTypeFromExtension = (filename: string): string | undefined => {
|
|
const extension = filename.split('.').pop()?.toLowerCase();
|
|
if (!extension) return undefined;
|
|
const guessedMimeType = lookup(extension);
|
|
if (!guessedMimeType) return undefined;
|
|
return guessedMimeType;
|
|
};
|
|
|
|
const guessMimeTypeFromMagicBytes = async (
|
|
uri: string,
|
|
): Promise<string | undefined> => {
|
|
const fileContent = await FileSystem.read(uri, 100);
|
|
const possibleMimeTypes = filetypemime(fileContent);
|
|
if (possibleMimeTypes.length === 0) return undefined;
|
|
return possibleMimeTypes[0].mime;
|
|
};
|
|
|
|
const guessMimeType = async (
|
|
uri: string,
|
|
hint?: string | null,
|
|
): Promise<string | undefined> => {
|
|
if (hint && allowedMimeTypes.includes(hint)) return hint;
|
|
|
|
let guessedMimeType = guessMimeTypeFromExtension(uri);
|
|
if (guessedMimeType && allowedMimeTypes.includes(guessedMimeType)) {
|
|
return guessedMimeType;
|
|
}
|
|
|
|
guessedMimeType = await guessMimeTypeFromMagicBytes(uri);
|
|
if (guessedMimeType && allowedMimeTypes.includes(guessedMimeType)) {
|
|
return guessedMimeType;
|
|
}
|
|
};
|
|
|
|
export {
|
|
allowedImageMimeTypes,
|
|
allowedGifMimeTypes,
|
|
allowedMimeTypes,
|
|
getMemeTypeFromMimeType,
|
|
guessMimeType,
|
|
};
|