Augmented run api

This val is a wrapper on top of the val.town run api, improving it with additional features:

  • basic auth
  • content-type header in response based on url file extension

Usage

Custom Content-Type

The content-type will be inferred from the filename using the mime-types library.

If you use a .html extension, the response will be interpreted as text/html

~ $ curl -v 'https://pomdtr-run.web.val.run/pomdtr/helloWorld.html'
HTTP/1.1 200 OK
...
Content-Type: text/html; charset=utf-8
...

Hello, World!

If you switch the extension to .txt, the content-type header switch to text/raw.

~ $ curl -v 'https://pomdtr-run.web.val.run/pomdtr/helloWorld.txt'
HTTP/1.1 200 OK
...
Content-Type: text/plain; charset=utf-8
...

Hello, World!

Passing arguments

The request is proxyed to the run api, so you can pass args to your vals via query params or body. See the run api docs for more details.

~ $ curl -X POST -d '{"args": ["pomdtr"]}' 'https://pomdtr-run.web.val.run/pomdtr/helloWorld.html'
...
< content-type: text/html; charset=utf-8
...

Hello, pomdtr!

Basic Authentication

Just add your val town token as the username:

curl  'https://<val-token>@pomdtr-run.web.val.run/pomdtr/privateVal.txt'
Readme
Fork
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
import { fetch } from "https://esm.town/v/std/fetch";
import { parseAuthorizationHeader } from "https://esm.town/v/pomdtr/parseAuthorizationHeader";
export async function run(req: Request) {
const url = new URL(req.url);
const [owner, filename] = url.pathname.slice(1).split("/");
const [name] = filename.split(".");
const mime = await import("npm:mime-types");
let contentType = await mime.lookup(filename);
if (!contentType) {
contentType = "application/json";
}
url.host = "api.val.town";
url.pathname = `v1/run/${owner}.${name}`;
const body = await req.text();
const headers = {};
const authorization = req.headers.get("Authorization");
if (authorization) {
const auth = parseAuthorizationHeader(
req.headers.get("Authorization"),
);
if (auth.type == "basic") {
headers["Authorization"] = `Bearer ${auth.username}`;
}
else {
headers["Authorization"] = req.headers.get("Authorization");
}
}
const resp = await fetch(url.toString(), {
method: req.method,
body: body || undefined,
headers,
});
if (resp.status != 200) {
return resp;
}
if (contentType == "application/json") {
return resp;
}
const res = await resp.json();
return new Response(typeof res == "string" ? res : JSON.stringify(res), {
headers: { "Content-Type": contentType },
});
}
👆 This is a val. Vals are TypeScript snippets of code, written in the browser and run on our servers. Create scheduled functions, email yourself, and persist small pieces of data — all from the browser.
Comments
neverstew avatar

Really cool! Would be great to have an example in the README about how changing the extension changes the type. E.g. you could curl the same URL but ending in txt for a plaintext page.

pomdtr avatar

Good idea!