generated from kawarimidoll/deno-dev-template
-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
utils.ts
94 lines (83 loc) · 3.26 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import { Marked, tag as h } from "./deps.ts";
const readme = await Deno.readTextFile("./README.md");
const corner = await Deno.readTextFile("./corner.html");
const description = "Access the modules on GitHub via Deno Deploy🦕";
const icon =
"https://cdn.jsdelivr.net/gh/twitter/[email protected]/assets/72x72/1f4e6.png";
const css = "https://cdn.jsdelivr.net/npm/water.css@2/out/water.min.css";
const viewport = "width=device-width,initial-scale=1.0,minimum-scale=1.0";
const index = "<!DOCTYPE html>" +
h(
"html",
h(
"head",
h("meta", { charset: "UTF-8" }),
h("title", "pax.deno.dev"),
h("meta", { name: "viewport", content: viewport }),
h("link", { rel: "icon", type: "image/png", href: icon }),
h("link", { rel: "stylesheet", href: css }),
h("meta", { name: "description", content: description }),
h("meta", { property: "og:url", content: "https://pax.deno.dev/" }),
h("meta", { property: "og:type", content: "website" }),
h("meta", { property: "og:title", content: "pax.deno.dev" }),
h("meta", { property: "og:description", content: description }),
h("meta", { property: "og:site_name", content: "pax.deno.dev" }),
h("meta", { property: "og:image", content: icon }),
h("meta", { name: "twitter:card", content: "summary" }),
h("meta", { name: "twitter:site", content: "@kawarimidoll" }),
),
h("body", Marked.parse(readme).content, corner),
);
export function extract(path: string) {
const match = path.match(/^\/([^\/]+)\/([^\/@]+)(@[^\/]+)?(\/.*)?/);
if (!match) return [];
const [, owner, repo, atTag, file] = match;
return [
owner,
repo,
atTag ? atTag.slice(1) : "master",
file?.replace(/^\/|\/$/g, "") || "mod.ts",
];
}
export async function handleURL(
url: string,
): Promise<[string | ReadableStream<Uint8Array>, ResponseInit]> {
const { pathname, searchParams } = new URL(url);
if (pathname === "/") {
return [index, { headers: { "content-type": "text/html" } }];
}
const [owner, repo, tag, file] = extract(pathname);
if (!owner || !repo) {
const [status, statusText] = [400, "Invalid URL"];
const init = { status, statusText };
return [`${status}: ${statusText}`, init];
}
let host = "https://raw.githubusercontent.com";
if (searchParams.has("d")) {
host = "https://doc.deno.land/" + host.replace(":/", "");
}
const location = [host, owner, repo, tag, file].join("/");
const body = (searchParams.has("b") && file.endsWith(".pdf"))
? await fetch(location).then((res) => res.body)
: null;
const headers: HeadersInit = body
? { "content-type": "application/pdf" }
: { location };
const [status, statusText] = body ? [200, "OK"] : [301, "Moved Permanently"];
const init = { status, statusText, headers };
return [body ?? `${status}: ${statusText}`, init];
}
export function parse(path: string) {
// match example: [
// "https://github.com/owner/repo/blob/tag/path/to/file",
// "owner/repo",
// "/blob/tag",
// "blob",
// "tag",
// "/path/to/file"
// ]
const [, ownerRepo = "", , , tag, file = ""] = path.match(
/^https:\/\/github\.com\/([^\/]+\/[^\/]+)(\/(tree|blob)\/([^\/]+))?(\/.*)?/,
) || [];
return `https://pax.deno.dev/${ownerRepo}${tag ? "@" + tag : ""}${file}`;
}