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
import { bulk, raw, sql } from "https://esm.town/v/pomdtr/sql";
import type { SqliteInterface } from "https://esm.town/v/postpostscript/sqliteTypes";
import { sqlite } from "https://esm.town/v/std/sqlite?v=4";
type Val = {
author: {
id: string;
username: string;
};
code: string;
createdAt: string;
id: string;
name: string;
privacy: string;
public: boolean;
runStartAt: string;
runEndAt: string;
version: number;
};
const createQuery = `CREATE TABLE IF NOT EXISTS vals (
id TEXT PRIMARY KEY,
name TEXT,
code TEXT,
version NUMBER,
privacy TEXT,
public INTEGER,
run_start_at TEXT,
run_end_at TEXT,
created_at TEXT,
author_id TEXT,
author_username TEXT
);`;
function valToRow(val: Val) {
return [
val.id,
val.name,
val.code,
val.version,
val.privacy,
val.public,
val.createdAt,
val.runEndAt,
val.runStartAt,
val.author.id,
val.author.username,
];
}
async function insertRows(rows, options: { sqlite: SqliteInterface } = { sqlite }) {
const query =
sql`INSERT OR REPLACE INTO vals (id, name, code, version, privacy, public, run_start_at, run_end_at, created_at, author_id, author_username) VALUES ${
bulk(rows)
}`;
await options.sqlite.execute(query);
}
export async function valtownToSQLite(options: { sqlite: SqliteInterface } = { sqlite }) {
await options.sqlite.execute(createQuery);
let url = "https://api.val.town/v1/search/vals?query=%20&limit=100";
while (true) {
const resp = await fetch(url);
if (!resp.ok) {
throw new Error(await resp.text());
}
const res = await resp.json();
const rows = res.data.map(valToRow);
await insertRows(rows, options);
if (!res.links.next) {
break;
}
url = res.links.next;
}
}