| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- export const ARCHIVE_EXTENSIONS = [
- 'zip', 'zipx', '7z', 'rar', 'tar', 'gz', 'gzip', 'tgz', 'bz2', 'bzip2', 'tbz', 'tbz2',
- 'xz', 'txz', 'lzma', 'zst', 'tzst', 'cab', 'ar', 'cpio', 'iso', 'xar', 'lha', 'lzh',
- 'jar', 'war', 'ear', 'apk', 'cbz', 'cbr'
- ]
- export const ARCHIVE_PREVIEWABLE_EXTENSIONS = [
- 'doc', 'docx', 'docm', 'dot', 'dotx', 'dotm', 'xls', 'xlsx', 'xlsm', 'xlsb',
- 'xlt', 'xltx', 'xltm', 'csv', 'ods', 'fods', 'numbers', 'pptx', 'pptm',
- 'potx', 'potm', 'ppsx', 'ppsm', 'rtf', 'odt', 'odp', 'pdf', 'ofd', 'typ', 'typst', 'dxf', 'dwg', 'dwf', 'dwfx', 'xps',
- 'gltf', 'glb', 'obj', 'stl', 'ply', 'fbx', 'dae', '3ds',
- '3mf', 'amf', 'usd', 'usda', 'usdc', 'usdz', 'kmz', 'geojson', 'kml', 'gpx', 'shp', 'pcd', 'wrl', 'vrml', 'xyz', 'vtk',
- 'vtp', 'step', 'stp', 'iges', 'igs', 'ifc', '3dm', 'excalidraw', 'drawio', 'dio',
- 'epub', 'umd', 'gif', 'jpg', 'jpeg', 'bmp', 'tiff', 'tif', 'png', 'svg', 'webp', 'avif', 'ico', 'heic', 'heif', 'jxl', 'md',
- 'markdown', 'txt', 'json', 'jsonc', 'json5', 'ipynb', 'toml', 'proto', 'hcl', 'tex', 'gv', 'http', 'js', 'mjs', 'cjs', 'css', 'java', 'py', 'html', 'htm', 'jsx',
- 'ts', 'tsx', 'xml', 'log', 'vue', 'yaml', 'yml', 'ini', 'sh', 'bash', 'sql', 'go', 'rs',
- 'php', 'c', 'cpp', 'cc', 'h', 'hpp', 'cs', 'diff', 'react', 'rb', 'swift', 'kt', 'mp4', 'webm', 'm3u8', 'mp3', 'mpeg', 'wav', 'ogg',
- 'oga', 'opus', 'm4a', 'aac', 'flac', 'weba', 'midi', 'mid', 'eml', 'msg', 'mbox', 'olb', 'dra',
- 'ttf', 'otf', 'woff', 'woff2', 'psd', 'ai', 'eps', 'sqlite', 'wasm', 'parquet', 'avro', 'webarchive',
- ...ARCHIVE_EXTENSIONS
- ]
- export interface ArchiveEntryView {
- id: string;
- path: string;
- name: string;
- extension: string;
- size: number;
- lastModified?: number;
- depth: number;
- previewable: boolean;
- compressedFile: {
- name: string;
- size: number;
- lastModified?: number;
- extract(): Promise<File>;
- };
- }
- export const getExtension = (name: string) => {
- const clean = name.split(/[?#]/)[0] || name
- const dot = clean.lastIndexOf('.')
- return dot === -1 ? '' : clean.slice(dot + 1).toLowerCase()
- }
- export const isArchiveExtension = (extension: string) => ARCHIVE_EXTENSIONS.includes(extension.toLowerCase())
- export const isPreviewableArchiveEntry = (name: string) => {
- const extension = getExtension(name)
- return ARCHIVE_PREVIEWABLE_EXTENSIONS.includes(extension)
- }
- export const formatBytes = (value: number) => {
- if (!Number.isFinite(value) || value < 0) {
- return '-'
- }
- if (value < 1024) {
- return `${value} B`
- }
- const units = ['KB', 'MB', 'GB']
- let next = value / 1024
- for (const unit of units) {
- if (next < 1024 || unit === units[units.length - 1]) {
- return `${next.toFixed(next < 10 ? 1 : 0)} ${unit}`
- }
- next /= 1024
- }
- return `${value} B`
- }
- const isCompressedFile = (value: unknown): value is ArchiveEntryView['compressedFile'] => {
- return typeof value === 'object' &&
- value !== null &&
- 'extract' in value &&
- typeof value.extract === 'function'
- }
- export const flattenArchiveObject = (input: Record<string, unknown>, prefix = ''): ArchiveEntryView[] => {
- const entries: ArchiveEntryView[] = []
- Object.entries(input).forEach(([key, value]) => {
- const path = prefix ? `${prefix}/${key}` : key
- if (isCompressedFile(value)) {
- const name = value.name || key
- const extension = getExtension(name)
- entries.push({
- id: path,
- path,
- name,
- extension,
- size: value.size || 0,
- lastModified: value.lastModified,
- depth: path.split('/').length - 1,
- previewable: isPreviewableArchiveEntry(name),
- compressedFile: value
- })
- return
- }
- if (value && typeof value === 'object') {
- entries.push(...flattenArchiveObject(value as Record<string, unknown>, path))
- }
- })
- return entries
- }
- export const createArchiveCacheKey = (archiveName: string, archiveSize: number, entry: ArchiveEntryView) => {
- return [
- 'archive-entry',
- archiveName || 'archive',
- archiveSize,
- entry.path,
- entry.size,
- entry.lastModified || 0
- ].join(':')
- }
|