Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
import type { MessageFile } from "$lib/types/Message"; | |
import { z } from "zod"; | |
export interface FileProcessorOptions<TMimeType extends string = string> { | |
supportedMimeTypes: TMimeType[]; | |
maxSizeInMB: number; | |
} | |
export type ImageProcessor<TMimeType extends string = string> = (file: MessageFile) => Promise<{ | |
file: Buffer; | |
mime: TMimeType; | |
}>; | |
export const createDocumentProcessorOptionsValidator = <TMimeType extends string = string>( | |
defaults: FileProcessorOptions<TMimeType> | |
) => { | |
return z | |
.object({ | |
supportedMimeTypes: z | |
.array( | |
z.enum<string, [TMimeType, ...TMimeType[]]>([ | |
defaults.supportedMimeTypes[0], | |
...defaults.supportedMimeTypes.slice(1), | |
]) | |
) | |
.default(defaults.supportedMimeTypes), | |
maxSizeInMB: z.number().positive().default(defaults.maxSizeInMB), | |
}) | |
.default(defaults); | |
}; | |
export type DocumentProcessor<TMimeType extends string = string> = (file: MessageFile) => { | |
file: Buffer; | |
mime: TMimeType; | |
}; | |
export type AsyncDocumentProcessor<TMimeType extends string = string> = ( | |
file: MessageFile | |
) => Promise<{ | |
file: Buffer; | |
mime: TMimeType; | |
}>; | |
export function makeDocumentProcessor<TMimeType extends string = string>( | |
options: FileProcessorOptions<TMimeType> | |
): AsyncDocumentProcessor<TMimeType> { | |
return async (file) => { | |
const { supportedMimeTypes, maxSizeInMB } = options; | |
const { mime, value } = file; | |
const buffer = Buffer.from(value, "base64"); | |
const tooLargeInBytes = buffer.byteLength > maxSizeInMB * 1000 * 1000; | |
if (tooLargeInBytes) { | |
throw Error("Document is too large"); | |
} | |
const outputMime = validateMimeType(supportedMimeTypes, mime); | |
return { file: buffer, mime: outputMime }; | |
}; | |
} | |
const validateMimeType = <T extends readonly string[]>( | |
supportedMimes: T, | |
mime: string | |
): T[number] => { | |
if (!supportedMimes.includes(mime)) { | |
const supportedMimesStr = supportedMimes.join(", "); | |
throw Error(`Mimetype "${mime}" not found in supported mimes: ${supportedMimesStr}`); | |
} | |
return mime; | |
}; | |