zero-knowledge file sharing
1export const IMAGE_EXTS = new Set([
2 "png",
3 "jpg",
4 "jpeg",
5 "gif",
6 "webp",
7 "ico",
8 "bmp",
9 "avif",
10]);
11
12export const TEXT_EXTS = new Set([
13 "txt",
14 "md",
15 "js",
16 "ts",
17 "jsx",
18 "tsx",
19 "json",
20 "yaml",
21 "yml",
22 "toml",
23 "xml",
24 "html",
25 "css",
26 "sh",
27 "py",
28 "rb",
29 "go",
30 "rs",
31 "java",
32 "c",
33 "cpp",
34 "h",
35 "php",
36 "sql",
37 "csv",
38 "log",
39 "ini",
40 "env",
41]);
42
43export const VIDEO_EXTS = new Set(["mp4", "webm", "ogv", "mov"]);
44
45export const AUDIO_EXTS = new Set(["mp3", "wav", "ogg", "flac", "aac", "m4a"]);
46
47export const VIDEO_MIME: Record<string, string> = {
48 mp4: "video/mp4",
49 webm: "video/webm",
50 ogv: "video/ogg",
51 mov: "video/mp4",
52};
53
54export const AUDIO_MIME: Record<string, string> = {
55 mp3: "audio/mpeg",
56 wav: "audio/wav",
57 ogg: "audio/ogg",
58 flac: "audio/flac",
59 aac: "audio/aac",
60 m4a: "audio/mp4",
61};
62
63export const IMAGE_MIME: Record<string, string> = {
64 png: "image/png",
65 jpg: "image/jpeg",
66 jpeg: "image/jpeg",
67 gif: "image/gif",
68 webp: "image/webp",
69 ico: "image/x-icon",
70 bmp: "image/bmp",
71 avif: "image/avif",
72};
73
74export function getExt(name: string): string {
75 const parts = name.split(".");
76 return parts.length > 1 ? parts[parts.length - 1].toLowerCase() : "";
77}
78
79export function formatBytes(n: number): string {
80 if (n < 1000) return `${n} B`;
81 if (n < 1e6) return `${parseFloat((n / 1e3).toFixed(1))} KB`;
82 if (n < 1e9) return `${parseFloat((n / 1e6).toFixed(1))} MB`;
83 return `${parseFloat((n / 1e9).toFixed(2))} GB`;
84}
85
86export function formatExpiry(unixSec: number): string {
87 const secs = unixSec - Math.floor(Date.now() / 1000);
88 if (secs < 60) return "expires in less than a minute";
89 const mins = Math.floor(secs / 60);
90 if (secs < 3600)
91 return `expires in ${mins} ${mins === 1 ? "minute" : "minutes"}`;
92 const hours = Math.floor(secs / 3600);
93 if (secs < 86400)
94 return `expires in ${hours} ${hours === 1 ? "hour" : "hours"}`;
95 const days = Math.floor(secs / 86400);
96 return `expires in ${days} ${days === 1 ? "day" : "days"}`;
97}
98
99export function triggerDownload(blob: Blob, fileName: string) {
100 const url = URL.createObjectURL(blob);
101 const a = document.createElement("a");
102 a.href = url;
103 a.download = fileName;
104 a.click();
105 setTimeout(() => URL.revokeObjectURL(url), 60000);
106}