/** * Extensions supported by ONLYOFFICE Document Server (view/edit). * @see https://github.com/ONLYOFFICE/document-formats * PDF is omitted here — opened via in-app preview instead. */ const ONLYOFFICE_WORD = [ "doc", "docm", "docx", "dot", "dotm", "dotx", "epub", "fb2", "fodt", "htm", "html", "hwp", "hwpx", "md", "mht", "mhtml", "odt", "ott", "rtf", "stw", "sxw", "txt", "wps", "wpt", "xml", ] as const const ONLYOFFICE_CELL = [ "csv", "et", "ett", "fods", "ods", "ots", "sxc", "tsv", "xls", "xlsb", "xlsm", "xlsx", "xlt", "xltm", "xltx", ] as const const ONLYOFFICE_SLIDE = [ "dps", "dpt", "fodp", "odg", "odp", "otp", "pot", "potm", "potx", "pps", "ppsm", "ppsx", "ppt", "pptm", "pptx", "sxi", ] as const const ONLYOFFICE_DIAGRAM = [ "vsdm", "vsdx", "vssm", "vssx", "vstm", "vstx", ] as const export const ONLYOFFICE_EXTENSIONS = new Set([ ...ONLYOFFICE_WORD, ...ONLYOFFICE_CELL, ...ONLYOFFICE_SLIDE, ...ONLYOFFICE_DIAGRAM, ]) const OFFICE_MIME_HINTS = [ "wordprocessingml", "spreadsheetml", "presentationml", "msword", "ms-excel", "ms-powerpoint", "opendocument", "visio", ] as const export function fileExtension(name: string): string { const base = name.split("/").pop() ?? name const i = base.lastIndexOf(".") if (i <= 0) return "" return base.slice(i + 1).toLowerCase() } export function isOnlyOfficeExtension(ext: string): boolean { return ONLYOFFICE_EXTENSIONS.has(ext.toLowerCase()) } export function isOnlyOfficeMime(mime: string): boolean { const m = mime.toLowerCase() if (m === "application/pdf") return false return OFFICE_MIME_HINTS.some((hint) => m.includes(hint)) } export function isOnlyOfficeFile(file: { name: string mime_type?: string }): boolean { const mime = (file.mime_type ?? "").toLowerCase() if (mime && isOnlyOfficeMime(mime)) return true return isOnlyOfficeExtension(fileExtension(file.name)) }