Create utils/media.ts, move some code from note.ts there

This commit is contained in:
Alex Gleason 2024-05-18 11:52:33 -05:00
parent f97064afb4
commit 5997ff0fff
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
3 changed files with 47 additions and 19 deletions

View File

@ -1,10 +1,10 @@
import { typeByExtension } from '@std/media-types';
import 'linkify-plugin-hashtag';
import linkifyStr from 'linkify-string';
import linkify from 'linkifyjs';
import { nip19, nip21 } from 'nostr-tools';
import { Conf } from '@/config.ts';
import { getUrlMediaType, isPermittedMediaType } from '@/utils/media.ts';
import { type DittoAttachment } from '@/views/mastodon/attachments.ts';
linkify.registerCustomProtocol('nostr', true);
@ -60,16 +60,14 @@ function parseNoteContent(content: string): ParsedNoteContent {
function getMediaLinks(links: Link[]): DittoAttachment[] {
return links.reduce<DittoAttachment[]>((acc, link) => {
const mimeType = getUrlMimeType(link.href);
if (!mimeType) return acc;
const mediaType = getUrlMediaType(link.href);
if (!mediaType) return acc;
const [baseType, _subType] = mimeType.split('/');
if (['audio', 'image', 'video'].includes(baseType)) {
if (isPermittedMediaType(mediaType, ['audio', 'image', 'video'])) {
acc.push({
url: link.href,
data: {
mime: mimeType,
mime: mediaType,
},
});
}
@ -79,7 +77,7 @@ function getMediaLinks(links: Link[]): DittoAttachment[] {
}
function isNonMediaLink({ href }: Link): boolean {
return /^https?:\/\//.test(href) && !getUrlMimeType(href);
return /^https?:\/\//.test(href) && !getUrlMediaType(href);
}
/** Ensures the Link is a URL so it can be parsed. */
@ -87,17 +85,6 @@ function isLinkURL(link: Link): boolean {
return link.type === 'url';
}
/** Get the extension from the URL, then get its type. */
function getUrlMimeType(url: string): string | undefined {
try {
const { pathname } = new URL(url);
const ext = pathname.split('.').pop() ?? '';
return typeByExtension(ext);
} catch {
return undefined;
}
}
/** Get pubkey from decoded bech32 entity, or undefined if not applicable. */
function getDecodedPubkey(decoded: nip19.DecodeResult): string | undefined {
switch (decoded.type) {

17
src/utils/media.test.ts Normal file
View File

@ -0,0 +1,17 @@
import { assertEquals } from '@std/assert';
import { getUrlMediaType, isPermittedMediaType } from '@/utils/media.ts';
Deno.test('getUrlMediaType', () => {
assertEquals(getUrlMediaType('https://example.com/image.png'), 'image/png');
assertEquals(getUrlMediaType('https://example.com/index.html'), 'text/html');
assertEquals(getUrlMediaType('https://example.com/yolo'), undefined);
assertEquals(getUrlMediaType('https://example.com/'), undefined);
});
Deno.test('isPermittedMediaType', () => {
assertEquals(isPermittedMediaType('image/png', ['image', 'video']), true);
assertEquals(isPermittedMediaType('video/webm', ['image', 'video']), true);
assertEquals(isPermittedMediaType('audio/ogg', ['image', 'video']), false);
assertEquals(isPermittedMediaType('application/json', ['image', 'video']), false);
});

24
src/utils/media.ts Normal file
View File

@ -0,0 +1,24 @@
import { typeByExtension } from '@std/media-types';
/** Get media type of the filename in the URL by its extension, if any. */
export function getUrlMediaType(url: string): string | undefined {
try {
const { pathname } = new URL(url);
const ext = pathname.split('.').pop() ?? '';
return typeByExtension(ext);
} catch {
return undefined;
}
}
/**
* Check if the base type matches any of the permitted types.
*
* ```ts
* isPermittedMediaType('image/png', ['image', 'video']); // true
* ```
*/
export function isPermittedMediaType(mediaType: string, permitted: string[]): boolean {
const [baseType, _subType] = mediaType.split('/');
return permitted.includes(baseType);
}