Static site hosting via tangled
1export function joinurl(...segments) {
2 let url = segments[0];
3 for (const segment of segments.slice(1)) {
4 if (url.endsWith("/") && segment.startsWith("/")) {
5 url = url.slice(0, -1) + segment;
6 } else if (!url.endsWith("/") && !segment.startsWith("/")) {
7 url = url + "/" + segment;
8 } else {
9 url = url + segment;
10 }
11 }
12 return url;
13}
14
15export function extname(filename) {
16 if (!filename.includes(".")) {
17 return "";
18 }
19 return "." + filename.split(".").pop();
20}
21
22export function getContentTypeForFilename(filename) {
23 const extension = extname(filename).toLowerCase();
24 return getContentTypeForExtension(extension);
25}
26
27export function getContentTypeForExtension(extension, fallback = "text/plain") {
28 switch (extension) {
29 case ".html":
30 return "text/html";
31 case ".css":
32 return "text/css";
33 case ".js":
34 return "application/javascript";
35 case ".json":
36 return "application/json";
37 case ".svg":
38 return "image/svg+xml";
39 case ".png":
40 return "image/png";
41 case ".jpg":
42 return "image/jpeg";
43 case ".gif":
44 return "image/gif";
45 case ".webp":
46 return "image/webp";
47 case ".ico":
48 return "image/x-icon";
49 case ".txt":
50 return "text/plain";
51 case ".md":
52 return "text/markdown";
53 case ".xml":
54 return "application/xml";
55 case ".pdf":
56 return "application/pdf";
57 case ".zip":
58 return "application/zip";
59 case ".7z":
60 return "application/x-7z-compressed";
61 case ".tar":
62 return "application/x-tar";
63 case ".gz":
64 return "application/gzip";
65 case ".bz2":
66 return "application/x-bzip2";
67 case ".mp3":
68 return "audio/mpeg";
69 case ".mp4":
70 return "video/mp4";
71 case ".webm":
72 return "video/webm";
73 case ".ogg":
74 return "audio/ogg";
75 case ".wav":
76 return "audio/wav";
77 case ".flac":
78 return "audio/flac";
79 case ".aac":
80 return "audio/aac";
81 case ".m4a":
82 return "audio/mp4";
83 case ".m4v":
84 return "video/mp4";
85 }
86 return fallback;
87}
88
89export function trimLeadingSlash(path) {
90 if (path.startsWith("/")) {
91 return path.slice(1);
92 }
93 return path;
94}