Readme

Sync vals to a git repo

CleanShot 2024-01-04 at 14.47.41@2x.png

This will not run on val town! You need to run it locally with deno.

There is currently no incremental syncing or recovering. You can only use this script against a fresh git repo. If you want to sync to an existing repo, you should create a new repo, run the script and then force push to your existing repo.

This will sync all your vals, including private ones so be careful where you push your git repo if you want those to remain private.

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
95
96
97
98
99
100
#!/usr/bin/env -S deno run --allow-read --allow-write --allow-env --allow-net --allow-run
// Sync all your vals to a local git repo.
// Note: this will not run on val town. You need to run it locally with deno.
// * Install Deno: https://docs.deno.com/runtime/manual/getting_started/installation
// * Set your val.town api key environment variable. https://www.val.town/settings/api
// * `export valtown="abcdefgh-ijkl-mnop-qrst-uvwxyz123456"`
// * Create a git repo to sync to.
// * `mkdir ./valtown && pushd ./valtown && git init && popd`
// * Copy down this script and run it, passing the path to your git directory.
// * `deno run -A ./git_sync.ts ./valtown`
// Note: There is currently no incremental syncing or recovering. You can only use
// this script against a fresh git repo. If you want to sync to an existing repo, you
// should create a new repo, run the script and then force push to your existing repo.
// Note: This will sync all your vals, including private ones so be careful where you
// push your git repo if you want those to remain private.
import ProgressBar from "https://deno.land/x/progress@v1.4.3/mod.ts";
type User = {
id: string;
username: string;
};
type Val = {
id: string;
name: string;
version: number;
createdAt: string;
code: string;
};
type Vals = {
data: Val[];
links: {
next?: string;
};
};
async function valtown(path: string): Promise<[number, object | null]> {
const req = await fetch(path, {
headers: {
Authorization: "Bearer " + Deno.env.get("valtown"),
Accept: "application/json",
},
});
if (req.status != 200) {
return [req.status, null];
}
const resp = await req.json();
return [req.status, resp];
}
async function git(
args: string[],
env: { [key: string]: string } = {},
): Promise<[number, string]> {
const cmd = new Deno.Command("git", {
args,
env,
});
const { code, stdout } = await cmd.output();
return [code, new TextDecoder().decode(stdout)];
}
// Get all the vals for the user.
async function getVals(me: User): Promise<Val[]> {
const vals = [];
let next_page:
| string
| undefined = `https://api.val.town/v1/users/${me.id}/vals`;
while (next_page) {
const [_, result] = await valtown(next_page);
const resp = result as Vals;
for (const val of resp.data) {
vals.push(val);
}
next_page = resp.links.next;
}
return vals;
}
// Write every version of the val to a file and commit it (unless there's no changes).
async function syncVals(vals: Val[]) {
for (let i = 0; i < vals.length; i++) {
const val = vals[i];
const progress = new ProgressBar({
title: `${i + 1}/${vals.length} ${val.name}:`,
total: Math.max(val.version - 1, 1),
});
let last_version_code = "";
progress.render(0);
for (let v = 1; v <= val.version; v++) {
const [_, result] = await valtown(
`https://api.val.town/v1/vals/${val.id}/versions/${v}`,
);
👆 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.