sqlite-hub 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/bin/sqlite-hub.js +555 -122
- package/docs/API.md +30 -0
- package/docs/CLI.md +22 -0
- package/docs/CLI_API_PARITY.md +61 -0
- package/docs/changelog.md +9 -1
- package/docs/guidelines/AGENTS.md +32 -0
- package/docs/{DESIGN_GUIDELINES.md → guidelines/DESIGN.md} +10 -0
- package/docs/todo.md +1 -13
- package/frontend/js/api.js +45 -0
- package/frontend/js/app.js +192 -2
- package/frontend/js/components/connectionCard.js +3 -1
- package/frontend/js/components/modal.js +356 -15
- package/frontend/js/components/sidebar.js +41 -7
- package/frontend/js/components/topNav.js +2 -14
- package/frontend/js/router.js +10 -0
- package/frontend/js/store.js +448 -0
- package/frontend/js/utils/inputClear.js +36 -0
- package/frontend/js/utils/syntheticData.js +240 -0
- package/frontend/js/views/backups.js +52 -0
- package/frontend/js/views/data.js +16 -0
- package/frontend/js/views/logs.js +339 -0
- package/frontend/js/views/settings.js +77 -27
- package/frontend/js/views/structure.js +6 -0
- package/frontend/js/views/tableAdvisor.js +385 -0
- package/frontend/js/views/tableDesigner.js +6 -0
- package/frontend/styles/components.css +149 -0
- package/frontend/styles/tailwind.generated.css +1 -1
- package/frontend/styles/views.css +8 -0
- package/package.json +1 -1
- package/server/routes/data.js +45 -0
- package/server/routes/externalApi.js +285 -2
- package/server/routes/logs.js +127 -0
- package/server/server.js +3 -0
- package/server/services/databaseCommandService.js +45 -0
- package/server/services/sqlite/dataBrowserService.js +36 -0
- package/server/services/sqlite/introspection.js +226 -22
- package/server/services/sqlite/syntheticDataGenerator.js +728 -0
- package/server/services/sqlite/tableAdvisor.js +790 -0
- package/server/services/storage/appStateStore.js +773 -169
package/docs/API.md
CHANGED
|
@@ -36,6 +36,9 @@ GET /api/v1/databases/:databaseId/tables/:tableName
|
|
|
36
36
|
POST /api/v1/databases/:databaseId/tables/:tableName/row
|
|
37
37
|
POST /api/v1/databases/:databaseId/tables/:tableName/types
|
|
38
38
|
|
|
39
|
+
GET /api/v1/databases/:databaseId/backups
|
|
40
|
+
POST /api/v1/databases/:databaseId/backups
|
|
41
|
+
|
|
39
42
|
GET /api/v1/databases/:databaseId/queries
|
|
40
43
|
GET /api/v1/databases/:databaseId/queries/:queryName
|
|
41
44
|
GET /api/v1/databases/:databaseId/queries/:queryName/notes
|
|
@@ -57,6 +60,10 @@ bearer token and include `databaseId` plus `sql` in the JSON body. Add `store`
|
|
|
57
60
|
or `name` to title the history item and mark it as saved. Raw query execution is
|
|
58
61
|
rejected with HTTP `403` when the target database is marked read-only.
|
|
59
62
|
|
|
63
|
+
Every `/api/v1` request is also recorded in the local Access Log with its API
|
|
64
|
+
action, database id when available, target type/name, status, duration, and API
|
|
65
|
+
token name/id. Tokens and request payloads are not stored in the Access Log.
|
|
66
|
+
|
|
60
67
|
```bash
|
|
61
68
|
curl \
|
|
62
69
|
-H "Authorization: Bearer shub_..." \
|
|
@@ -100,6 +107,29 @@ Supported targets are `typescript`, `rust`, `kotlin`, and `swift`. Warnings are
|
|
|
100
107
|
returned in the top-level `warnings` array. Metadata includes column counts and
|
|
101
108
|
CHECK-constraint counts.
|
|
102
109
|
|
|
110
|
+
`GET /api/v1/databases/:databaseId/backups` lists managed backups for the
|
|
111
|
+
token's database.
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
curl \
|
|
115
|
+
-H "Authorization: Bearer shub_..." \
|
|
116
|
+
http://127.0.0.1:4173/api/v1/databases/DATABASE_ID/backups
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`POST /api/v1/databases/:databaseId/backups` creates and verifies a managed
|
|
120
|
+
backup for the token's database. The request body may include `name` and `notes`.
|
|
121
|
+
Backup creation uses SQLite's backup API and is allowed for read-only database
|
|
122
|
+
connections because the source database is only read.
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
curl \
|
|
126
|
+
-X POST \
|
|
127
|
+
-H "Authorization: Bearer shub_..." \
|
|
128
|
+
-H "Content-Type: application/json" \
|
|
129
|
+
-d '{"name":"Before import","notes":"Before loading vendor data"}' \
|
|
130
|
+
http://127.0.0.1:4173/api/v1/databases/DATABASE_ID/backups
|
|
131
|
+
```
|
|
132
|
+
|
|
103
133
|
Successful responses use this envelope:
|
|
104
134
|
|
|
105
135
|
```json
|
package/docs/CLI.md
CHANGED
|
@@ -4,6 +4,10 @@ SQLite Hub ships with a built-in CLI that lets you start the app, inspect
|
|
|
4
4
|
imported databases, execute raw or saved SQL, export query results, and work
|
|
5
5
|
with Markdown documents from the terminal.
|
|
6
6
|
|
|
7
|
+
CLI commands are recorded in the local Access Log with their action, target,
|
|
8
|
+
database id when available, status, and duration. Raw SQL text is still handled
|
|
9
|
+
by Query History for executed queries and is not duplicated in the Access Log.
|
|
10
|
+
|
|
7
11
|
## Start The App
|
|
8
12
|
|
|
9
13
|
```bash
|
|
@@ -66,6 +70,20 @@ Aliases are available for common targets: `ts`, `rs`, and `kt`. Without
|
|
|
66
70
|
redirection works cleanly. Warnings are written to stderr. Use `--force` to
|
|
67
71
|
overwrite an existing output file.
|
|
68
72
|
|
|
73
|
+
Create a verified managed backup for a database:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
sqlite-hub --database:Unit-00 --backups
|
|
77
|
+
sqlite-hub --database:Unit-00 --backup
|
|
78
|
+
sqlite-hub --database:Unit-00 --backup:"Before import" --backup-notes:"Before loading vendor data"
|
|
79
|
+
sqlite-hub --database:Unit-00 --backup:"Nightly checkpoint" --json
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Backup creation uses the same SQLite backup API and verification path as the UI
|
|
83
|
+
Backup Manager. It works for read-only database connections because the source
|
|
84
|
+
database is only read. `--backups` lists the managed backups for the selected
|
|
85
|
+
database; add `--json` for structured output.
|
|
86
|
+
|
|
69
87
|
## SQL Editor
|
|
70
88
|
|
|
71
89
|
Execute raw SQL through the same SQL Editor execution path used by the app:
|
|
@@ -178,6 +196,10 @@ sqlite-hub --database:Unit-00 --table:companies --export:0a754aba373d34972998792
|
|
|
178
196
|
| `--database:name --documents` | List Markdown documents for a database |
|
|
179
197
|
| `--database:name --documents:"document"` | Print a document's Markdown content |
|
|
180
198
|
| `--database:name --documents:"document" --export` | Export a document as Markdown |
|
|
199
|
+
| `--database:name --backups` | List managed backups for a database |
|
|
200
|
+
| `--database:name --backup` | Create and verify a managed backup |
|
|
201
|
+
| `--database:name --backup:"name"` | Create a managed backup with a custom name |
|
|
202
|
+
| `--backup-notes:"text"` | Add notes to a backup created by `--backup` |
|
|
181
203
|
| `--database:name --table:"table"` | Print table metadata |
|
|
182
204
|
| `--database:name --table:"table" --export:"pk"` | Export one row as JSON |
|
|
183
205
|
| `--database:name --table:"table" --types:typescript\|ts\|rust\|rs\|kotlin\|kt\|swift` | Generate application types |
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# CLI / External API Parity
|
|
2
|
+
|
|
3
|
+
This document compares the public CLI (`sqlite-hub ...`) with the versioned external API (`/api/v1`). It does not treat the internal browser routes under `/api/*` as stable automation surfaces.
|
|
4
|
+
|
|
5
|
+
## Capability Matrix
|
|
6
|
+
|
|
7
|
+
| Capability | CLI | `/api/v1` | Parity | Notes |
|
|
8
|
+
| --------------------- | ------------------------------------------------------ | ----------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------- |
|
|
9
|
+
| App info | `sqlite-hub --info` | `GET /api/v1/info` | Full | Both return app/runtime/version status. |
|
|
10
|
+
| Start/open app | `sqlite-hub`, `--port`, `--open` | No | CLI only | API assumes the server is already running. |
|
|
11
|
+
| List known databases | `--database` | No | CLI only | API requires a specific database id and token. |
|
|
12
|
+
| Database detail | `--database:name --path/--size/--lastopened` | `GET /databases/:databaseId` | Partial | API returns structured detail for one authorized database. CLI can discover databases by name/id. |
|
|
13
|
+
| List tables | `--database:name --tables` | `GET /databases/:databaseId/tables` | Full | Output format differs: terminal text vs JSON. |
|
|
14
|
+
| Inspect table | `--database:name --table:name` | `GET /databases/:databaseId/tables/:tableName` | Full | Both expose columns, keys, indexes, counts, and identity metadata. |
|
|
15
|
+
| Raw SQL execution | `--query:"SQL"` | `POST /api/v1/query` | Full | Both use SQL Editor execution and write Query History. |
|
|
16
|
+
| Save raw query | `--query:"SQL" --store:"Name"` | `POST /api/v1/query` with `store` or `name` | Full | Both title the history item and mark it saved. |
|
|
17
|
+
| List saved queries | `--queries` | `GET /databases/:databaseId/queries` | Full | Saved query collection only. |
|
|
18
|
+
| Get saved query SQL | `--saved-query:"Name"` | `GET /databases/:databaseId/queries/:queryName` | Full | API returns structured query metadata. |
|
|
19
|
+
| Get saved query notes | `--notes:"Name"` | `GET /databases/:databaseId/queries/:queryName/notes` | Full | Same saved-query lookup behavior. |
|
|
20
|
+
| Execute saved query | `--execute:"Name"` | `POST /databases/:databaseId/queries/:queryName/execute` | Full | Both return result metadata and rows. |
|
|
21
|
+
| Export saved query | `--export:"Name" --format:csv\|tsv\|md\|json` | `GET /databases/:databaseId/queries/:queryName/export?format=...` | Partial | Same formats. CLI writes a file; API returns content in JSON. |
|
|
22
|
+
| List documents | `--documents` | `GET /databases/:databaseId/documents` | Full | Read-only document listing. |
|
|
23
|
+
| Read document | `--documents:"Name"` | `GET /databases/:databaseId/documents/:documentName` | Full | API returns the document object. |
|
|
24
|
+
| Export document | `--documents:"Name" --export` | `GET /databases/:databaseId/documents/:documentName/export` | Partial | CLI writes Markdown to disk; API returns content and filename. |
|
|
25
|
+
| Row JSON export | `--table:name --export:"pk"` | `POST /databases/:databaseId/tables/:tableName/row` | Full | API body supports scalar or composite key objects. |
|
|
26
|
+
| Generate schema types | `--table:name --types:typescript\|rust\|kotlin\|swift` | `POST /databases/:databaseId/tables/:tableName/types` | Partial | Same generator. CLI supports stdout/file output and aliases; API returns JSON. |
|
|
27
|
+
| List backups | `--backups` | `GET /databases/:databaseId/backups` | Full | Both return managed backups for one database. |
|
|
28
|
+
| Create backup | `--backup`, `--backup:"name"` | `POST /databases/:databaseId/backups` | Full | Both create and verify a managed backup through the same service. |
|
|
29
|
+
|
|
30
|
+
## Stable Surface Gaps
|
|
31
|
+
|
|
32
|
+
These UI features currently have no public CLI or `/api/v1` equivalent:
|
|
33
|
+
|
|
34
|
+
- Backups: verify, compare, restore, download, edit notes, delete, usage summary.
|
|
35
|
+
- Table Advisor: run deterministic table analysis and copy SQL recommendations.
|
|
36
|
+
- Synthetic Data: preview and insert generated rows.
|
|
37
|
+
- Table Designer: create/edit tables, CSV-seed drafts, apply SQL preview.
|
|
38
|
+
- Charts: create, edit, delete, resize, and export PNG.
|
|
39
|
+
- Logs: filtered access/query history inspection.
|
|
40
|
+
- Settings/API tokens: create, delete, inspect token usage.
|
|
41
|
+
- Connections: open/create databases, edit labels/paths/icons/read-only mode, remove registry entries.
|
|
42
|
+
- Documents mutation: create, edit, autosave, import, delete, insert saved-query tables/notes.
|
|
43
|
+
- Row editing and table data mutation through the Data Browser.
|
|
44
|
+
- Media Tagging setup and queue actions.
|
|
45
|
+
- Overview Finder action.
|
|
46
|
+
|
|
47
|
+
## Recommended Parity Order
|
|
48
|
+
|
|
49
|
+
1. **Table Advisor**: read-only, deterministic, low risk, useful for automation.
|
|
50
|
+
2. **Backups**: list and create are exposed; verify, restore, and download should follow.
|
|
51
|
+
3. **Logs**: read-only observability with filters.
|
|
52
|
+
4. **Synthetic Data**: useful for test automation; needs clear write safeguards.
|
|
53
|
+
5. **Table Designer**: powerful but schema-mutating, so it needs dry-run/preview-first API design.
|
|
54
|
+
6. **Charts**: lower priority for CLI, useful as API metadata/export later.
|
|
55
|
+
|
|
56
|
+
## Design Notes
|
|
57
|
+
|
|
58
|
+
- Keep `/api/v1` token-scoped by database.
|
|
59
|
+
- Keep write operations explicit and reject read-only databases consistently.
|
|
60
|
+
- Prefer JSON responses for API and file/stdout behavior for CLI.
|
|
61
|
+
- Reuse existing services where possible so UI, CLI, and API stay behaviorally aligned.
|
package/docs/changelog.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
# v1.5.0
|
|
2
|
+
|
|
3
|
+
- synthetic data generation
|
|
4
|
+
- logs for everything in the log menu
|
|
5
|
+
- in api tokens you can now see last used and amount of api calls
|
|
6
|
+
- removed legacy tables
|
|
7
|
+
- new menu/view order
|
|
8
|
+
|
|
1
9
|
# v1.4.0
|
|
2
10
|
|
|
3
|
-
- Schema Diff / Database Diff
|
|
11
|
+
- Schema Diff / Database Diff in backups
|
|
4
12
|
|
|
5
13
|
# v1.3.0
|
|
6
14
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Repository Guidelines
|
|
2
|
+
|
|
3
|
+
## Project Structure & Module Organization
|
|
4
|
+
|
|
5
|
+
SQLite Hub is a local-first Node/Express app with a browser SPA. Backend code lives in `server/`: routes in `server/routes`, domain services in `server/services`, SQLite helpers in `server/services/sqlite`, and shared utilities in `server/utils`. Frontend code lives in `frontend/`: views in `frontend/js/views`, reusable UI in `frontend/js/components`, state/router logic in `frontend/js/store.js` and `frontend/js/router.js`, and styles in `frontend/styles`. CLI entrypoint code is in `bin/sqlite-hub.js`. Tests are in `tests/*.test.js`. Documentation is in `docs/`, with user-facing overview content in `README.md`.
|
|
6
|
+
|
|
7
|
+
## Build, Test, and Development Commands
|
|
8
|
+
|
|
9
|
+
- `npm run dev` starts the local server with Node watch mode on port `4180`.
|
|
10
|
+
- `npm start` runs the packaged CLI entrypoint.
|
|
11
|
+
- `npm test` runs all Node test files under `tests/`.
|
|
12
|
+
- `npm run build` or `npm run build:css` regenerates `frontend/styles/tailwind.generated.css`.
|
|
13
|
+
- `npm run screenshots` refreshes the standard screenshot set; use `npm run screenshots:backup-drawer` for the backup drawer capture.
|
|
14
|
+
- `npm run audit` checks production dependencies for high-severity issues.
|
|
15
|
+
|
|
16
|
+
## Coding Style & Naming Conventions
|
|
17
|
+
|
|
18
|
+
Use plain JavaScript and existing local patterns. Frontend modules use ES modules; backend modules mostly use CommonJS. Prefer small, focused functions and reuse existing components before adding new UI primitives. Keep UI work aligned with `/docs/guidelines/DESIGN.md`; shared button, input, drawer, modal, and Escape-key behavior should stay consistent. Use descriptive camelCase for functions and variables, PascalCase only for classes/services, and route/view files named by feature, for example `tableAdvisor.js`.
|
|
19
|
+
|
|
20
|
+
## Testing Guidelines
|
|
21
|
+
|
|
22
|
+
Tests use the built-in Node test runner (`node:test`) with `node:assert/strict`. Name files `feature-name.test.js` and keep fixtures local to each test unless reuse is clearly helpful. Add focused tests for backend services, routes, state changes, and rendered view markup when behavior changes. Run the relevant focused test first, then `npm test` before handing off.
|
|
23
|
+
You can use the test database id:conn_c3b310c3373fda5a
|
|
24
|
+
for all tests.
|
|
25
|
+
|
|
26
|
+
## Commit & Pull Request Guidelines
|
|
27
|
+
|
|
28
|
+
Recent history uses short, informal messages, but contributors should keep commits clear and scoped, for example `add table advisor view` or `fix backup usage summary`. Pull requests should include a concise summary, test commands run, linked issue or context when available, and screenshots for visible UI changes. Note any generated files, especially `frontend/styles/tailwind.generated.css`, when CSS utilities change.
|
|
29
|
+
|
|
30
|
+
## Security & Configuration Tips
|
|
31
|
+
|
|
32
|
+
Do not commit local databases, tokens, or `.env` files. Use `.env.example` for documented configuration. Local API changes must preserve loopback-only and API-token protections in `server/middleware`.
|
|
@@ -39,6 +39,16 @@ Follow these rules exactly when creating or modifying UI controls.
|
|
|
39
39
|
- Prefer migration over local override.
|
|
40
40
|
- Prefer shared component updates over per-view fixes.
|
|
41
41
|
|
|
42
|
+
## UX behavior
|
|
43
|
+
|
|
44
|
+
- All drawers must close with `Escape`.
|
|
45
|
+
- All modal windows must close with `Escape`.
|
|
46
|
+
- Open dropdowns and menu popovers must close with `Escape`.
|
|
47
|
+
- Focused text-like input elements must clear their value with `Escape` before any parent drawer, modal, dropdown, or selection state handles the key.
|
|
48
|
+
- Search inputs must clear with `Escape` and dispatch the same input/update behavior as manual clearing.
|
|
49
|
+
- Do not clear multiline textareas with `Escape` unless the textarea is explicitly built as a search field.
|
|
50
|
+
- If an input is already empty, `Escape` may continue to the next applicable close/clear behavior.
|
|
51
|
+
|
|
42
52
|
## History elements
|
|
43
53
|
|
|
44
54
|
- Query history panels, such as SQL Editor and Charts history, are always placed on the right side.
|
package/docs/todo.md
CHANGED
|
@@ -1,16 +1,4 @@
|
|
|
1
1
|
# Maybe
|
|
2
2
|
|
|
3
|
+
- Data Pipeline Light/hook, programmable triggers?
|
|
3
4
|
- MCP
|
|
4
|
-
- query perf, history, api history
|
|
5
|
-
- Data Pipeline Light/hook
|
|
6
|
-
- Query Results as persistent Artifacts
|
|
7
|
-
- SDK?
|
|
8
|
-
- FTS5 Manager
|
|
9
|
-
- Synthetic Data Generator
|
|
10
|
-
- programmable triggers?
|
|
11
|
-
- Query/Scheme Analyzer mit Explain Query Plan
|
|
12
|
-
- MD to pdf
|
|
13
|
-
- Color update / Customization
|
|
14
|
-
- hide media tagging / backups / overview
|
|
15
|
-
- change accent color
|
|
16
|
-
- toast position
|
package/frontend/js/api.js
CHANGED
|
@@ -216,6 +216,33 @@ export function getDbStatus() {
|
|
|
216
216
|
return request("/api/db/status");
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
+
export function getLogs(options = {}) {
|
|
220
|
+
const params = new URLSearchParams();
|
|
221
|
+
|
|
222
|
+
[
|
|
223
|
+
"kind",
|
|
224
|
+
"range",
|
|
225
|
+
"actor",
|
|
226
|
+
"status",
|
|
227
|
+
"queryType",
|
|
228
|
+
"destructive",
|
|
229
|
+
"from",
|
|
230
|
+
"to",
|
|
231
|
+
"search",
|
|
232
|
+
"limit",
|
|
233
|
+
"offset",
|
|
234
|
+
].forEach((key) => {
|
|
235
|
+
const value = options[key];
|
|
236
|
+
|
|
237
|
+
if (value !== undefined && value !== null && value !== "") {
|
|
238
|
+
params.set(key, String(value));
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
const query = params.toString();
|
|
243
|
+
return request(`/api/logs${query ? `?${query}` : ""}`);
|
|
244
|
+
}
|
|
245
|
+
|
|
219
246
|
export function executeSql(sql) {
|
|
220
247
|
return request("/api/sql/execute", {
|
|
221
248
|
method: "POST",
|
|
@@ -470,6 +497,10 @@ export function getDataTable(tableName, options = {}) {
|
|
|
470
497
|
return request(`/api/data/${encodeURIComponent(tableName)}${query ? `?${query}` : ""}`);
|
|
471
498
|
}
|
|
472
499
|
|
|
500
|
+
export function analyzeTableAdvisor(tableName) {
|
|
501
|
+
return request(`/api/data/${encodeURIComponent(tableName)}/advisor`);
|
|
502
|
+
}
|
|
503
|
+
|
|
473
504
|
export function getDataTableRow(tableName, payload) {
|
|
474
505
|
return request(`/api/data/${encodeURIComponent(tableName)}/row`, {
|
|
475
506
|
method: "POST",
|
|
@@ -491,6 +522,20 @@ export function previewDataTableRowUpdate(tableName, payload) {
|
|
|
491
522
|
});
|
|
492
523
|
}
|
|
493
524
|
|
|
525
|
+
export function previewSyntheticDataRows(tableName, payload) {
|
|
526
|
+
return request(`/api/data/${encodeURIComponent(tableName)}/generate/preview`, {
|
|
527
|
+
method: "POST",
|
|
528
|
+
body: payload,
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
export function insertSyntheticDataRows(tableName, payload) {
|
|
533
|
+
return request(`/api/data/${encodeURIComponent(tableName)}/generate/insert`, {
|
|
534
|
+
method: "POST",
|
|
535
|
+
body: payload,
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
|
|
494
539
|
export function deleteDataTableRow(tableName, payload) {
|
|
495
540
|
return request(`/api/data/${encodeURIComponent(tableName)}/rows`, {
|
|
496
541
|
method: "DELETE",
|