93 lines
3.1 KiB
TypeScript
93 lines
3.1 KiB
TypeScript
/** Image extensions rendered inline. */
|
|
export const IMAGE_EXTS = 'jpg|jpeg|png|gif|webp|svg|avif';
|
|
|
|
/** Video extensions rendered as players. */
|
|
export const VIDEO_EXTS = 'mp4|webm|mov|qt|avi|mkv|flv';
|
|
|
|
/** Audio extensions rendered as players. */
|
|
export const AUDIO_EXTS = 'mp3|wav|ogg|flac|m4a|aac|opus';
|
|
|
|
/** All media extensions (image + video + audio + webxdc). */
|
|
export const ALL_MEDIA_EXTS = `${IMAGE_EXTS}|${VIDEO_EXTS}|${AUDIO_EXTS}|xdc`;
|
|
|
|
/** Matches image URLs. */
|
|
export const IMAGE_URL_REGEX = new RegExp(
|
|
`https?:\\/\\/[^\\s]+\\.(${IMAGE_EXTS})(\\?[^\\s]*)?`,
|
|
'i',
|
|
);
|
|
|
|
/** Matches video URLs. */
|
|
export const VIDEO_URL_REGEX = new RegExp(
|
|
`https?:\\/\\/[^\\s]+\\.(${VIDEO_EXTS})(\\?[^\\s]*)?`,
|
|
'gi',
|
|
);
|
|
|
|
/** Matches audio URLs. */
|
|
export const AUDIO_URL_REGEX = new RegExp(
|
|
`https?:\\/\\/[^\\s]+\\.(${AUDIO_EXTS})(\\?[^\\s]*)?`,
|
|
'gi',
|
|
);
|
|
|
|
/** Matches any media URL (video, audio, webxdc) that is rendered as an embed — not a link preview. */
|
|
export const EMBED_MEDIA_URL_REGEX = new RegExp(
|
|
`https?:\\/\\/[^\\s]+\\.(${VIDEO_EXTS}|${AUDIO_EXTS}|xdc)(\\?[^\\s]*)?`,
|
|
'i',
|
|
);
|
|
|
|
/** Matches all NIP-92 media URLs for imeta tag generation (images + video + audio + webxdc). */
|
|
export const IMETA_MEDIA_URL_REGEX = new RegExp(
|
|
`https?:\\/\\/[^\\s]+\\.(${ALL_MEDIA_EXTS})(\\?[^\\s]*)?`,
|
|
'gi',
|
|
);
|
|
|
|
/**
|
|
* Non-global variant of IMETA_MEDIA_URL_REGEX, safe for `.test()` calls.
|
|
*
|
|
* IMPORTANT: Never use the global (`g`) IMETA_MEDIA_URL_REGEX with `.test()` —
|
|
* the global flag makes `lastIndex` stateful, so repeated `.test()` calls
|
|
* (e.g. inside `.find()` or `.filter()`) will alternate between matching and
|
|
* not matching, causing every other URL to be misclassified.
|
|
*/
|
|
export const IMETA_MEDIA_URL_TEST_REGEX = new RegExp(
|
|
IMETA_MEDIA_URL_REGEX.source,
|
|
'i',
|
|
);
|
|
|
|
/** Infers a MIME type from a file extension string (lowercase). */
|
|
export function mimeFromExt(ext: string): string {
|
|
switch (ext) {
|
|
case 'jpg': case 'jpeg': return 'image/jpeg';
|
|
case 'png': return 'image/png';
|
|
case 'gif': return 'image/gif';
|
|
case 'webp': return 'image/webp';
|
|
case 'svg': return 'image/svg+xml';
|
|
case 'avif': return 'image/avif';
|
|
case 'mp4': return 'video/mp4';
|
|
case 'webm': return 'video/webm';
|
|
case 'mov': return 'video/quicktime';
|
|
case 'qt': return 'video/quicktime';
|
|
case 'avi': return 'video/x-msvideo';
|
|
case 'mkv': return 'video/x-matroska';
|
|
case 'flv': return 'video/x-flv';
|
|
case 'mp3': return 'audio/mpeg';
|
|
case 'wav': return 'audio/wav';
|
|
case 'ogg': return 'audio/ogg';
|
|
case 'flac': return 'audio/flac';
|
|
case 'm4a': return 'audio/mp4';
|
|
case 'aac': return 'audio/aac';
|
|
case 'opus': return 'audio/opus';
|
|
case 'xdc': return 'application/x-webxdc';
|
|
default: return 'application/octet-stream';
|
|
}
|
|
}
|
|
|
|
|
|
/** Extracts all video URLs from a string. */
|
|
export function extractVideoUrls(content: string): string[] {
|
|
return content.match(new RegExp(VIDEO_URL_REGEX.source, 'gi')) ?? [];
|
|
}
|
|
|
|
/** Extracts all audio URLs from a string. */
|
|
export function extractAudioUrls(content: string): string[] {
|
|
return content.match(new RegExp(AUDIO_URL_REGEX.source, 'gi')) ?? [];
|
|
}
|