|
- import {getTextMetadata, TextMetadata} from '@modal-sh/text-utils';
- import {getMetadataFromUrl as getImageMetadataFromUrl, ImageMetadata} from '@modal-sh/image-utils';
- import {getMetadataFromUrl as getAudioMetadataFromUrl, AudioMetadata} from '@modal-sh/audio-utils';
- import {getMetadataFromUrl as getVideoMetadataFromUrl, VideoMetadata} from '@modal-sh/video-utils';
-
- export const readAsDataURL = (blob: Partial<Blob>) => new Promise<string>((resolve, reject) => {
- // TODO when to revoke these URLs
- // return URL.createObjectURL(blob as Blob);
-
- const reader = new FileReader();
- reader.addEventListener('error', () => {
- reject(new Error('Could not read file as data URL'));
- });
-
- reader.addEventListener('load', (e) => {
- if (!e.target) {
- reject();
- return;
- }
- resolve(e.target.result as string);
- });
-
- reader.readAsDataURL(blob as Blob);
- });
-
- export interface FileWithDataUrl extends File {
- url?: string;
- }
-
- export const addDataUrl = async (f: Partial<File>): Promise<Partial<FileWithDataUrl>> => {
- (f as unknown as Record<string, unknown>).url = await readAsDataURL(f);
- return f;
- }
-
- export interface FileWithResolvedContentType extends Partial<FileWithDataUrl> {
- resolvedType: ContentType;
- }
-
- export interface TextFile extends FileWithResolvedContentType {
- resolvedType: ContentType.TEXT;
- metadata?: TextMetadata;
- }
-
- export const augmentTextFile = async <T extends Partial<FileWithDataUrl>>(file: T): Promise<TextFile> => {
- const contents = typeof file?.text === 'function' ? await file.text() : '';
- const fileMutable = file as unknown as Record<string, TextMetadata>;
- fileMutable.metadata = await getTextMetadata(contents ?? '', file.name);
- return fileMutable as unknown as TextFile;
- };
-
- export interface ImageFile extends FileWithResolvedContentType {
- resolvedType: ContentType.IMAGE;
- metadata?: ImageMetadata;
- }
-
- export const augmentImageFile = async <T extends Partial<FileWithDataUrl>>(file: T): Promise<ImageFile> => {
- const fileMutable = file as unknown as Record<string, ImageMetadata>;
- fileMutable.metadata = await getImageMetadataFromUrl(file.url);
- return fileMutable as unknown as ImageFile;
- };
-
- export interface AudioFile extends FileWithResolvedContentType {
- resolvedType: ContentType.AUDIO;
- metadata?: AudioMetadata;
- }
-
- export const augmentAudioFile = async <T extends Partial<FileWithDataUrl>>(file: T): Promise<AudioFile> => {
- const fileMutable = file as unknown as Record<string, AudioMetadata>;
- if (file.type === 'audio/mid') {
- fileMutable.metadata = {};
- } else {
- fileMutable.metadata = await getAudioMetadataFromUrl(file.url);
- }
- return fileMutable as unknown as AudioFile;
- };
-
- export interface BinaryFileMetadata {
- contents: ArrayBuffer;
- }
-
- export interface BinaryFile extends FileWithResolvedContentType {
- resolvedType: ContentType.BINARY;
- metadata?: BinaryFileMetadata;
- }
-
- export const augmentBinaryFile = async <T extends Partial<FileWithDataUrl>>(file: T): Promise<BinaryFile> => {
- const metadata = {} as BinaryFileMetadata;
- if (typeof file?.arrayBuffer === 'function') {
- metadata.contents = await file.arrayBuffer();
- }
- const fileMutable = file as unknown as Record<string, BinaryFileMetadata>;
- fileMutable.metadata = metadata;
- return fileMutable as unknown as BinaryFile;
- };
-
- export interface VideoFile extends FileWithResolvedContentType {
- resolvedType: ContentType.VIDEO;
- metadata?: VideoMetadata;
- }
-
- export const augmentVideoFile = async <T extends Partial<FileWithDataUrl>>(file: T): Promise<VideoFile> => {
- const fileMutable = file as unknown as Record<string, AudioMetadata>;
- fileMutable.metadata = await getVideoMetadataFromUrl(file.url);
- return fileMutable as unknown as VideoFile;
- };
|