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
import { upgradeExpress } from "https://esm.town/v/easrng/upgradeExpress";
async function inlineUrls(cssString) {
const urlRegex = /url\(['"]?(.*?)['"]?\)/g;
let result = cssString;
for (const urlMatch of cssString.matchAll(urlRegex)) {
const originalUrl = urlMatch[1];
const response = await fetch(originalUrl);
const data = new Uint8Array(await response.arrayBuffer());
result = result.replace(
urlMatch[0],
`url("data:${response.headers.get("content-type")};base64,${
btoa(data.reduce((a, b) => a + String.fromCharCode(b), ""))
}")`,
);
}
return result;
}
import IBMPlexSansMetrics from "https://easrng.github.io/IBMPlexSansMetrics.js";
import esc from "npm:escape-html@1.0.3";
import { init } from "npm:server-text-width@1.0.2";
export const button = upgradeExpress(async function button(req) {
const { getTextWidth } = init(
IBMPlexSansMetrics,
);
const text = decodeURIComponent(new URL(req.url).pathname.slice(1) || "Button");
let fontCss = "";
try {
const r = await fetch(
"https://fonts.googleapis.com/css2?family="
+ encodeURIComponent("IBM Plex Sans:wght@600")
+ "&text="
+ encodeURIComponent(text),
{ headers: { "user-agent": req.headers.get("user-agent") } },
);
if (!r.ok)
throw new Error();
fontCss = await inlineUrls(await r.text());
}
catch (e) {}
const width = Math.ceil(getTextWidth(text) + 16);
return new Response(
`<svg viewBox="0 0 ${width} 28" width="${width}" height="28" xmlns="http://www.w3.org/2000/svg"><defs><style>${fontCss}</style></defs><foreignObject width="100%" height="100%"><span xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'IBM Plex San
esc(text)
}</span></foreignObject></svg>`,
{
headers: {
"content-type": "image/svg+xml",
},
},
);
});