SQLite Admin

This is a lightweight SQLite Admin interface to view and debug your SQLite data.

Screenshot 2023-12-08 at 13.35.04.gif

It's currently super limited (no pagination, editing data, data-type specific viewers), and is just a couple dozens lines of code over a couple different vals. Forks encouraged! Just comment on the val if you add any features that you want to share.

To use it on your own Val Town SQLite database, fork it to your account.

It uses basic authentication with your Val Town API Token as the password (leave the username field blank).

1
2
3
4
5
6
7
8
9
10
11
import { basicAuth } from "https://esm.town/v/pomdtr/basicAuth";
import { sqlite } from "https://esm.town/v/std/sqlite?v=4";
import { html } from "https://esm.town/v/stevekrouse/html";
import { sqlite_admin_table } from "https://esm.town/v/stevekrouse/sqlite_admin_table";
import { sqlite_admin_tables } from "https://esm.town/v/stevekrouse/sqlite_admin_tables";
import { Hono } from "npm:hono@3.9.2";
const app = new Hono();
app.get("/", async (c) => c.html(await sqlite_admin_tables()));
app.get("/:table", async (c) => c.html(await sqlite_admin_table(c.req.param("table"))));
export default basicAuth(app.fetch);

Blob Admin

This is a lightweight Blob Admin interface to view and debug your Blob data.

b7321ca2cd80899250589b9aa08bc3cae9c7cea276282561194e7fc537259b46.png

Use this button to install the val:

It uses basic authentication with your Val Town API Token as the password (leave the username field blank).

TODO

  • /new - render a page to write a new blob key and value
  • /edit/:blob - render a page to edit a blob (prefilled with the existing content)
  • /delete/:blob - delete a blob and render success
  • add upload/download buttons
  • Use modals for create/upload/edit/view/delete page (htmx ?)
  • handle non-textual blobs properly
  • use codemirror instead of a textarea for editing text blobs
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
/** @jsxImportSource https://esm.sh/hono@4.0.8/jsx **/
import { modifyFetchHandler } from "https://esm.town/v/andreterron/codeOnValTown?v=50";
import view_route from "https://esm.town/v/pomdtr/blob_admin_blob";
import create_route from "https://esm.town/v/pomdtr/blob_admin_create";
import delete_route from "https://esm.town/v/pomdtr/blob_admin_delete";
import edit_route from "https://esm.town/v/pomdtr/blob_admin_edit";
import upload_route from "https://esm.town/v/pomdtr/blob_admin_upload";
import { passwordAuth } from "https://esm.town/v/pomdtr/password_auth?v=74";
import { blob } from "https://esm.town/v/std/blob?v=11";
import { Hono } from "npm:hono@4.0.8";
import { jsxRenderer } from "npm:hono@4.0.8/jsx-renderer";
const app = new Hono();
app.use(
jsxRenderer(({ children }) => {
return (
<html>
<head>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
/>
<script
type="module"
src="https://cdn.jsdelivr.net/npm/code-mirror-web-component@0.0.8/dist/code-mirror.js"
>
</script>
<title>Blob Admin</title>
</head>
<body>
<main class="container">
{children}
</main>
</body>
</html>
);
}),
);
app.get("/", async (c) => {
let blobs = await blob.list();
return c.render(
<div class="overflow-auto">
<h1>Blob Admin</h1>
<section
style={{
display: "flex",
gap: "0.5em",
}}
>
<a href="/create">New Blob</a>
<a href="/upload">Upload Blob</a>
</section>
<section>
<table>
<thead>
<tr>
<th>Name</th>
<th>Size (kb)</th>
<th>Last Modified</th>
<th
style={{
textAlign: "center",
}}
>
Edit
</th>
<th
style={{
textAlign: "center",
}}
>
Delete
</th>
<th
style={{
textAlign: "center",
}}
>
Download
</th>
</tr>
</thead>
{blobs.map(b => (
<tr>
<td>
<a href={`/view/${encodeURIComponent(b.key)}`}>
{b.key}
</a>
</td>
<td>{b.size / 1000}</td>
<td>{new Date(b.lastModified).toLocaleString()}</td>
<td
style={{
textAlign: "center",
}}
>

SQLite Admin

This is a lightweight SQLite Admin interface to view and debug your SQLite data.

Screenshot 2023-12-08 at 13.35.04.gif

It's currently super limited (no pagination, editing data, data-type specific viewers), and is just a couple dozens lines of code over a couple different vals. Forks encouraged! Just comment on the val if you add any features that you want to share.

To use it on your own Val Town SQLite database, fork it to your account.

It uses basic authentication with your Val Town API Token as the password (leave the username field blank).

1
2
3
4
5
6
7
8
9
10
11
import { basicAuth } from "https://esm.town/v/pomdtr/basicAuth?v=38";
import { sqlite } from "https://esm.town/v/std/sqlite?v=4";
import { html } from "https://esm.town/v/stevekrouse/html";
import { sqlite_admin_table } from "https://esm.town/v/stevekrouse/sqlite_admin_table";
import { sqlite_admin_tables } from "https://esm.town/v/stevekrouse/sqlite_admin_tables";
import { Hono } from "npm:hono@3.9.2";
const app = new Hono();
app.get("/", async (c) => c.html(await sqlite_admin_tables()));
app.get("/:table", async (c) => c.html(await sqlite_admin_table(c.req.param("table"))));
export default basicAuth(app.fetch);

SQLite Admin

This is a lightweight SQLite Admin interface to view and debug your SQLite data.

Screenshot 2023-12-08 at 13.35.04.gif

It's currently super limited (no pagination, editing data, data-type specific viewers), and is just a couple dozens lines of code over a couple different vals. Forks encouraged! Just comment on the val if you add any features that you want to share.

To use it on your own Val Town SQLite database, fork it to your account.

It uses basic authentication with your Val Town API Token as the password (leave the username field blank).

1
2
3
4
5
6
7
8
9
10
11
import { basicAuth } from "https://esm.town/v/pomdtr/basicAuth?v=38";
import { sqlite } from "https://esm.town/v/std/sqlite?v=4";
import { html } from "https://esm.town/v/stevekrouse/html";
import { sqlite_admin_table } from "https://esm.town/v/stevekrouse/sqlite_admin_table";
import { sqlite_admin_tables } from "https://esm.town/v/stevekrouse/sqlite_admin_tables";
import { Hono } from "npm:hono@3.9.2";
const app = new Hono();
app.get("/", async (c) => c.html(await sqlite_admin_tables()));
app.get("/:table", async (c) => c.html(await sqlite_admin_table(c.req.param("table"))));
export default basicAuth(app.fetch);

SQLite Admin

This is a lightweight SQLite Admin interface to view and debug your SQLite data.

It's currently super limited (no pagination, editing data, data-type specific viewers), and is just a couple dozens lines of code over a couple different vals. Forks encouraged! Just comment on the val if you add any features that you want to share.

To use it on your own Val Town SQLite database, fork it to your account.

Warning: Anyone with the URL can read your entire SQLite database. I haven't yet saved any sensitive info to my database, so I don't mind this. I plan to add some notion of password protection to this admin viewer, either via query params (not very safe) or basic auth. You can be reasonably safe with an unlisted val with an unguessable name.

1
2
3
4
5
6
7
8
9
10
import { sqlite } from "https://esm.town/v/std/sqlite?v=4";
import { html } from "https://esm.town/v/stevekrouse/html";
import { sqlite_admin_table } from "https://esm.town/v/stevekrouse/sqlite_admin_table";
import { sqlite_admin_tables } from "https://esm.town/v/stevekrouse/sqlite_admin_tables";
import { Hono } from "npm:hono@3.9.2";
const app = new Hono();
app.get("/", async (c) => c.html(await sqlite_admin_tables()));
app.get("/:table", async (c) => c.html(await sqlite_admin_table(c.req.param("table"))));
export default app.fetch;
1
Next