@muhgholy/next-drive 4.23.6 → 4.23.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,6 +17,50 @@ var formatBytes = (bytes, decimals = 2) => {
17
17
  const i = Math.floor(Math.log(bytes) / Math.log(k));
18
18
  return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
19
19
  };
20
+ var FILE_FORMAT_PRESET = {
21
+ "image/jpeg": "JPEG image",
22
+ "image/png": "PNG image",
23
+ "image/gif": "GIF image",
24
+ "image/webp": "WebP image",
25
+ "image/svg+xml": "SVG image",
26
+ "image/avif": "AVIF image",
27
+ "image/heic": "HEIC image",
28
+ "image/bmp": "Bitmap image",
29
+ "image/x-icon": "Icon",
30
+ "video/mp4": "MP4 video",
31
+ "video/quicktime": "QuickTime video",
32
+ "video/webm": "WebM video",
33
+ "video/x-matroska": "MKV video",
34
+ "video/x-msvideo": "AVI video",
35
+ "audio/mpeg": "MP3 audio",
36
+ "audio/wav": "WAV audio",
37
+ "audio/ogg": "OGG audio",
38
+ "audio/flac": "FLAC audio",
39
+ "application/pdf": "PDF document",
40
+ "application/msword": "Word document",
41
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "Word document",
42
+ "application/vnd.ms-excel": "Excel spreadsheet",
43
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "Excel spreadsheet",
44
+ "application/vnd.ms-powerpoint": "PowerPoint presentation",
45
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation": "PowerPoint presentation",
46
+ "application/zip": "ZIP archive",
47
+ "application/x-zip-compressed": "ZIP archive",
48
+ "application/x-rar-compressed": "RAR archive",
49
+ "application/x-7z-compressed": "7z archive",
50
+ "application/json": "JSON file",
51
+ "application/xml": "XML file",
52
+ "text/plain": "Text file",
53
+ "text/csv": "CSV file",
54
+ "text/html": "HTML file",
55
+ "application/x-folder": "Folder"
56
+ };
57
+ var getFileFormat = (mime) => {
58
+ if (!mime) return "File";
59
+ const preset = FILE_FORMAT_PRESET[mime.toLowerCase()];
60
+ if (preset) return preset;
61
+ const subtype = (mime.split("/")[1] || mime).replace(/^vnd\.|^x-/, "").split(/[.+;]/)[0];
62
+ return subtype ? `${subtype.toUpperCase()} file` : "File";
63
+ };
20
64
  var getFileIcon = (mime, isFolder, className = "nd:w-6 nd:h-6") => {
21
65
  if (isFolder) return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Folder, { className: cn("nd:text-blue-500 nd:fill-blue-500/20", className) });
22
66
  if (mime.startsWith("image/")) return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Image, { className: cn("nd:text-purple-500", className) });
@@ -106,7 +150,8 @@ var driveCreateUrl = (driveFile, apiEndpoint) => {
106
150
  exports.cn = cn;
107
151
  exports.driveCreateUrl = driveCreateUrl;
108
152
  exports.formatBytes = formatBytes;
153
+ exports.getFileFormat = getFileFormat;
109
154
  exports.getFileIcon = getFileIcon;
110
155
  exports.matchesMimeFilter = matchesMimeFilter;
111
- //# sourceMappingURL=chunk-TA6L5FYG.cjs.map
112
- //# sourceMappingURL=chunk-TA6L5FYG.cjs.map
156
+ //# sourceMappingURL=chunk-HQTC3554.cjs.map
157
+ //# sourceMappingURL=chunk-HQTC3554.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client/utils.tsx"],"names":["twMerge","clsx","jsx","Folder","Image","Video","Music","FileText","FileArchive","FileCode","File"],"mappings":"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","file":"chunk-HQTC3554.cjs","sourcesContent":["// ** Client Utils\nimport React from 'react';\nimport { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\n// ** Format bytes to human readable string\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const dm = decimals < 0 ? 0 : decimals;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];\n};\n\n// ** Preset of common MIME types mapped to friendly format labels\nconst FILE_FORMAT_PRESET: Record<string, string> = {\n 'image/jpeg': 'JPEG image',\n 'image/png': 'PNG image',\n 'image/gif': 'GIF image',\n 'image/webp': 'WebP image',\n 'image/svg+xml': 'SVG image',\n 'image/avif': 'AVIF image',\n 'image/heic': 'HEIC image',\n 'image/bmp': 'Bitmap image',\n 'image/x-icon': 'Icon',\n 'video/mp4': 'MP4 video',\n 'video/quicktime': 'QuickTime video',\n 'video/webm': 'WebM video',\n 'video/x-matroska': 'MKV video',\n 'video/x-msvideo': 'AVI video',\n 'audio/mpeg': 'MP3 audio',\n 'audio/wav': 'WAV audio',\n 'audio/ogg': 'OGG audio',\n 'audio/flac': 'FLAC audio',\n 'application/pdf': 'PDF document',\n 'application/msword': 'Word document',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'Word document',\n 'application/vnd.ms-excel': 'Excel spreadsheet',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'Excel spreadsheet',\n 'application/vnd.ms-powerpoint': 'PowerPoint presentation',\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'PowerPoint presentation',\n 'application/zip': 'ZIP archive',\n 'application/x-zip-compressed': 'ZIP archive',\n 'application/x-rar-compressed': 'RAR archive',\n 'application/x-7z-compressed': '7z archive',\n 'application/json': 'JSON file',\n 'application/xml': 'XML file',\n 'text/plain': 'Text file',\n 'text/csv': 'CSV file',\n 'text/html': 'HTML file',\n 'application/x-folder': 'Folder',\n};\n\n// ** Get a friendly, human-readable file format label from a MIME type.\n// Falls back to a cleaned-up subtype when the MIME type is not in the preset.\nexport const getFileFormat = (mime?: string): string => {\n if (!mime) return 'File';\n const preset = FILE_FORMAT_PRESET[mime.toLowerCase()];\n if (preset) return preset;\n const subtype = (mime.split('/')[1] || mime).replace(/^vnd\\.|^x-/, '').split(/[.+;]/)[0];\n return subtype ? `${subtype.toUpperCase()} file` : 'File';\n};\n\nimport type { ReactNode } from 'react';\nimport { File, Folder, Image, Video, Music, FileText, Package, FileCode, FileArchive } from 'lucide-react';\n\n// ** Get file icon based on mime type\nexport const getFileIcon = (mime: string, isFolder: boolean, className = \"nd:w-6 nd:h-6\"): ReactNode => {\n if (isFolder) return <Folder className={cn(\"nd:text-blue-500 nd:fill-blue-500/20\", className)} />;\n if (mime.startsWith('image/')) return <Image className={cn(\"nd:text-purple-500\", className)} />;\n if (mime.startsWith('video/')) return <Video className={cn(\"nd:text-red-500\", className)} />;\n if (mime.startsWith('audio/')) return <Music className={cn(\"nd:text-yellow-500\", className)} />;\n if (mime === 'application/pdf') return <FileText className={cn(\"nd:text-orange-500\", className)} />;\n if (mime.includes('text') || mime.includes('document')) return <FileText className={cn(\"nd:text-slate-500\", className)} />;\n if (mime.includes('zip') || mime.includes('compressed')) return <FileArchive className={cn(\"nd:text-amber-500\", className)} />;\n if (mime.includes('javascript') || mime.includes('typescript') || mime.includes('json') || mime.includes('html') || mime.includes('css')) return <FileCode className={cn(\"nd:text-green-500\", className)} />;\n return <File className={cn(\"nd:text-gray-400\", className)} />;\n};\n\n// ** Check if file matches mime filter (supports native accept format)\n// Supports: \"image/*\", \"video/*\", \".pdf\", \".jpg,.png\", \"image/png,image/jpeg\", etc.\nexport const matchesMimeFilter = (mime: string, isFolder: boolean, filter?: string): boolean => {\n if (!filter) return true;\n if (isFolder) return true;\n if (filter === '*/*' || filter === '*') return true;\n\n const types = filter.split(',').map(t => t.trim().toLowerCase());\n const lowerMime = mime.toLowerCase();\n\n return types.some(type => {\n // Exact mime match: \"image/png\"\n if (type === lowerMime) return true;\n\n // Wildcard mime: \"image/*\"\n if (type.endsWith('/*')) {\n const prefix = type.slice(0, -2);\n return lowerMime.startsWith(`${prefix}/`);\n }\n\n // Extension format: \".pdf\", \".jpg\"\n if (type.startsWith('.')) {\n const ext = type.slice(1);\n // Map common extensions to mimes\n const extMimeMap: Record<string, string[]> = {\n 'jpg': ['image/jpeg'],\n 'jpeg': ['image/jpeg'],\n 'png': ['image/png'],\n 'gif': ['image/gif'],\n 'webp': ['image/webp'],\n 'svg': ['image/svg+xml'],\n 'bmp': ['image/bmp'],\n 'ico': ['image/x-icon', 'image/vnd.microsoft.icon'],\n 'tiff': ['image/tiff'],\n 'tif': ['image/tiff'],\n 'heic': ['image/heic'],\n 'heif': ['image/heif'],\n 'avif': ['image/avif'],\n 'mp4': ['video/mp4'],\n 'webm': ['video/webm'],\n 'mov': ['video/quicktime'],\n 'avi': ['video/x-msvideo'],\n 'mkv': ['video/x-matroska'],\n 'wmv': ['video/x-ms-wmv'],\n 'flv': ['video/x-flv'],\n 'mp3': ['audio/mpeg', 'audio/mp3'],\n 'wav': ['audio/wav', 'audio/x-wav'],\n 'ogg': ['audio/ogg'],\n 'flac': ['audio/flac'],\n 'aac': ['audio/aac'],\n 'm4a': ['audio/mp4', 'audio/x-m4a'],\n 'pdf': ['application/pdf'],\n 'doc': ['application/msword'],\n 'docx': ['application/vnd.openxmlformats-officedocument.wordprocessingml.document'],\n 'xls': ['application/vnd.ms-excel'],\n 'xlsx': ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],\n 'ppt': ['application/vnd.ms-powerpoint'],\n 'pptx': ['application/vnd.openxmlformats-officedocument.presentationml.presentation'],\n 'txt': ['text/plain'],\n 'csv': ['text/csv'],\n 'json': ['application/json'],\n 'xml': ['application/xml', 'text/xml'],\n 'zip': ['application/zip', 'application/x-zip-compressed'],\n 'rar': ['application/x-rar-compressed', 'application/vnd.rar'],\n '7z': ['application/x-7z-compressed'],\n 'tar': ['application/x-tar'],\n 'gz': ['application/gzip'],\n };\n const allowedMimes = extMimeMap[ext];\n if (allowedMimes) {\n return allowedMimes.some(m => lowerMime === m);\n }\n // Fallback: check if mime ends with extension\n return lowerMime.includes(ext);\n }\n\n return false;\n });\n};\n\n// ** Get accept string for input element from filter\nexport const getAcceptString = (filter?: string): string | undefined => {\n if (!filter) return undefined;\n // Already in correct format for input accept\n return filter;\n};\n\nimport type { TDriveFile } from '@/types/client';\n\n// ** Create URL for drive file\nexport const driveCreateUrl = (driveFile: TDriveFile, apiEndpoint: string): string => {\n const params = new URLSearchParams({\n action: 'serve',\n id: driveFile.id,\n });\n\n return `${apiEndpoint}?${params.toString()}`;\n};\n"]}