Public
HTTP (deprecated)
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Readme

Static Vals

Serve static content from val.town

Usage

First, fork this val to get your own http endpoint.

Then create a val that uses a string as it's default export, or a single string export. The val must be either public or unlisted.

export default `<static content>`

You can then fetch the exported string from outside val.town using:

curl 'https://<owner>-static.web.val.run/<val>.<extension>'

The Content-Type will be dynamically set depending on the provided extension.

Example

https://pomdtr-static.web.val.run/val_town_readme_style.css

Val Link

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
import { extractValInfo } from "https://esm.town/v/pomdtr/extractValInfo";
import { gfm } from "https://esm.town/v/pomdtr/gfm";
import { readme } from "https://esm.town/v/pomdtr/readme";
import { Hono } from "npm:hono";
import { HTTPException } from "npm:hono/http-exception";
import mime from "npm:mime";
const app = new Hono();
const { author, name } = extractValInfo(import.meta.url);
async function extractStaticContent(code: string) {
const blob = new Blob([code], { type: "text/javascript" });
const url = URL.createObjectURL(blob);
const exports = await import(url);
if (exports.default) {
return exports.default;
}
const values = Object.values(exports);
if (values.length == 1) {
return values[0];
}
return "";
}
app.get("/", async c => {
const html = await gfm(await readme(author, name));
return c.html(html);
});
app.get("/:filename", async c => {
const { filename } = c.req.param();
const [name, ext] = filename.split(".");
// we check that we are not exposing private vals
const resp = await fetch(`https://api.val.town/v1/alias/${author}/${name}`, {
headers: {
authorization: `Bearer ${Deno.env.get("valtown")}`,
},
});
if (!resp.ok) {
return resp;
}
const { code, privacy } = await resp.json();
if (privacy == "private") {
throw new HTTPException(404);
}
const content = await extractStaticContent(code);
if (typeof content !== "string") {
throw new HTTPException(500, { message: `val @${author}/${name} is not a static val: ${content}` });
}
return new Response(content, {
headers: {
"Content-Type": mime.getType(ext),
},
});
});
export default app.fetch;
pomdtr-static.web.val.run
December 31, 2023