admindb 2.1.1 → 2.3.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 +368 -335
- package/dist/app.js +227 -1
- package/dist/auth/config.d.ts +1 -1
- package/dist/auth/config.js +109 -1
- package/dist/auth/crypto.js +98 -1
- package/dist/auth/index.js +21 -1
- package/dist/auth/middleware.js +78 -1
- package/dist/auth/routes.js +64 -1
- package/dist/auth/types.js +7 -1
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.js +309 -1
- package/dist/cli/config.js +118 -1
- package/dist/cli/index.js +20 -1
- package/dist/cli/runner.js +208 -1
- package/dist/cli.js +4 -1
- package/dist/data/chain.d.ts +1 -0
- package/dist/data/chain.js +130 -0
- package/dist/data/datasets.d.ts +1 -1
- package/dist/data/datasets.js +171 -1
- package/dist/data/detector.d.ts +1 -1
- package/dist/data/detector.js +535 -1
- package/dist/data/engine.d.ts +1 -1
- package/dist/data/engine.js +586 -1
- package/dist/data/index.d.ts +1 -1
- package/dist/data/index.js +30 -1
- package/dist/data/prng.d.ts +1 -0
- package/dist/data/prng.js +73 -0
- package/dist/data/registry.d.ts +1 -0
- package/dist/data/registry.js +805 -0
- package/dist/data/schema-graph.d.ts +1 -0
- package/dist/data/schema-graph.js +210 -0
- package/dist/data/strategies.d.ts +1 -1
- package/dist/data/strategies.js +100 -1
- package/dist/data/templates.d.ts +1 -0
- package/dist/data/templates.js +134 -0
- package/dist/data/types.d.ts +1 -1
- package/dist/data/types.js +5 -1
- package/dist/data/validator.d.ts +1 -0
- package/dist/data/validator.js +160 -0
- package/dist/db/database.d.ts +1 -1
- package/dist/db/database.js +472 -1
- package/dist/db/export.d.ts +1 -1
- package/dist/db/export.js +67 -1
- package/dist/db/filters.d.ts +1 -1
- package/dist/db/filters.js +119 -1
- package/dist/db/index.js +24 -1
- package/dist/db/introspection.js +164 -1
- package/dist/db/manager.js +327 -1
- package/dist/db/migrations.js +100 -1
- package/dist/db/postgres.d.ts +1 -1
- package/dist/db/postgres.js +687 -1
- package/dist/db/types.d.ts +1 -1
- package/dist/db/types.js +6 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +52 -1
- package/dist/public/css/app.css +1 -1
- package/dist/public/js/api.js +1 -1
- package/dist/public/js/browse.js +1 -1
- package/dist/public/js/common.js +1 -0
- package/dist/public/js/databases.js +1 -1
- package/dist/public/js/designer.js +1 -1
- package/dist/public/js/forms.js +1 -1
- package/dist/public/js/home.js +1 -0
- package/dist/public/js/inspector.js +1 -1
- package/dist/public/js/query.js +1 -1
- package/dist/public/js/schema.js +1 -1
- package/dist/public/js/seed.js +1 -1
- package/dist/routes/api/erd.d.ts +1 -0
- package/dist/routes/api/erd.js +45 -0
- package/dist/routes/api/helpers.d.ts +1 -1
- package/dist/routes/api/helpers.js +213 -1
- package/dist/routes/api/import-export.js +82 -1
- package/dist/routes/api/index.js +48 -1
- package/dist/routes/api/query.js +74 -1
- package/dist/routes/api/rows.js +358 -1
- package/dist/routes/api/seed.js +167 -1
- package/dist/routes/api/tables.js +216 -1
- package/dist/routes/databases.js +210 -1
- package/dist/routes/index.js +19 -1
- package/dist/routes/pages.js +446 -1
- package/dist/serverless.js +149 -1
- package/dist/sql/classifier.js +24 -1
- package/dist/sql/error-analyzer.d.ts +1 -0
- package/dist/sql/error-analyzer.js +550 -0
- package/dist/sql/generator.d.ts +1 -1
- package/dist/sql/generator.js +245 -1
- package/dist/sql/index.js +18 -1
- package/dist/types/api.d.ts +1 -1
- package/dist/types/api.js +2 -1
- package/dist/utils/colors.js +54 -1
- package/dist/utils/common.d.ts +1 -1
- package/dist/utils/common.js +185 -1
- package/dist/utils/csv.d.ts +1 -1
- package/dist/utils/csv.js +61 -1
- package/dist/utils/datatype.js +167 -1
- package/dist/utils/icons.js +81 -1
- package/dist/utils/index.js +20 -1
- package/dist/utils/logger.js +36 -1
- package/dist/views/layouts/main.hbs +1 -74
- package/dist/views/pages/databases.hbs +1 -233
- package/dist/views/pages/designer.hbs +1 -89
- package/dist/views/pages/erd.hbs +1 -0
- package/dist/views/pages/error.hbs +1 -10
- package/dist/views/pages/form.hbs +1 -59
- package/dist/views/pages/home.hbs +1 -124
- package/dist/views/pages/info.hbs +1 -0
- package/dist/views/pages/login.hbs +1 -98
- package/dist/views/pages/query.hbs +1 -87
- package/dist/views/pages/schema.hbs +1 -298
- package/dist/views/pages/seed-select.hbs +251 -0
- package/dist/views/pages/seed.hbs +273 -167
- package/dist/views/pages/table.hbs +1 -327
- package/dist/views/partials/navbar.hbs +1 -83
- package/dist/views/partials/sidebar.hbs +1 -117
- package/docs/API.md +149 -144
- package/docs/EXAMPLES.md +579 -576
- package/docs/SECURITY.md +265 -265
- package/package.json +79 -78
- package/dist/public/js/icons.js +0 -1
package/docs/API.md
CHANGED
|
@@ -1,144 +1,149 @@
|
|
|
1
|
-
# AdminDB REST API
|
|
2
|
-
|
|
3
|
-
Every route is under `basePath` and returns the consistent shape
|
|
4
|
-
`{ success, data?, error? }`. In multi-db mode, every route is scoped under the
|
|
5
|
-
database identifier, e.g. `/api/app.db/tables` or `/api/prod_pg/tables`.
|
|
6
|
-
|
|
7
|
-
AdminDB supports both **SQLite** and **PostgreSQL** database backends seamlessly.
|
|
8
|
-
|
|
9
|
-
## Tables & rows
|
|
10
|
-
|
|
11
|
-
| Method | Path | Purpose |
|
|
12
|
-
| ------ | ---------------------------------------- | -------------------------------- |
|
|
13
|
-
| GET | `/api/tables` | List tables |
|
|
14
|
-
| GET | `/api/tables/:table/info` | Column + FK metadata, PK columns |
|
|
15
|
-
| GET | `/api/tables/:table/fk-options` | Values for FK dropdowns |
|
|
16
|
-
| GET | `/api/tables/:table/rows?page&limit&f` | Paginated rows (`f` = URL-encoded JSON filters — legacy strings like `{"age":">35"}` or structured conditions like `{"balance":{"op":"gte","value":"100"}}`) |
|
|
17
|
-
| GET | `/api/tables/:table/rows/count?f=` | Filtered row count |
|
|
18
|
-
| GET | `/api/tables/:table/row/:id` | Single row by (encoded) PK |
|
|
19
|
-
| GET | `/api/tables/:table/rows/:id/references` | Rows in other tables whose foreign keys reference this row |
|
|
20
|
-
| GET | `/api/tables/:table/row/:id/blob/:column` | Stream binary BLOB / BYTEA with MIME detection (add `?download=1` to force download) |
|
|
21
|
-
| GET | `/api/tables/:table/row/:id/blob/:column/meta` | Inspect BLOB / BYTEA metadata, MIME sniffing & 3-column hex dump |
|
|
22
|
-
| PUT | `/api/tables/:table/row/:id/blob/:column` | Update binary value (`{ data: base64/hex, format?: 'base64'|'hex'|'text' }`) |
|
|
23
|
-
| POST | `/api/tables/:table/rows` | Insert row (or batch of rows with `{ rows: [...] }`) |
|
|
24
|
-
| POST | `/api/tables/:table/rows/generate` | Generate INSERT SQL (no execute) |
|
|
25
|
-
| POST | `/api/tables/:table/rows/import` | Import CSV (`{ csv }`, header row must match columns) |
|
|
26
|
-
| GET | `/api/tables/:table/export?format=` | Download all rows as `csv` or `json` |
|
|
27
|
-
| PUT | `/api/tables/:table/row/:id` | Update row (`{ values, nulls? }` — `nulls` explicitly sets columns to NULL) |
|
|
28
|
-
| PUT | `/api/tables/:table/row/:id/generate` | Generate UPDATE SQL (no execute) |
|
|
29
|
-
| DELETE | `/api/tables/:table/row/:id` | Delete row |
|
|
30
|
-
| POST | `/api/tables/:table/rows/bulk-impact` | FK-impact preview: how many rows in other tables reference the selected rows |
|
|
31
|
-
| POST | `/api/tables/:table/rows/bulk-delete` | Delete selected rows (`{ ids, confirmImpact }`; transactional) |
|
|
32
|
-
| POST | `/api/tables/:table/rows/bulk-export` | Export only the selected rows as `csv`/`json` (`{ ids, format }`) |
|
|
33
|
-
| POST | `/api/tables/:table/rows/bulk-update` | Apply staged inline edits (`{ updates: [{ id, values?, nulls? }] }`; transactional) |
|
|
34
|
-
| GET | `/api/tables/:table/seed/config` | Per-column generator strategies + detected defaults |
|
|
35
|
-
| GET | `/api/tables/:table/seed/plan` | Detect intelligent seed plan heuristics |
|
|
36
|
-
| POST | `/api/tables/:table/seed/preview` | Generate preview sample rows for grid without executing |
|
|
37
|
-
| POST | `/api/tables/:table/seed/generate` | Generate seed INSERT SQL without executing (`{ count, plan }`) |
|
|
38
|
-
| POST | `/api/tables/:table/seed` | Generate and insert seed rows transactionally (`{ count, plan, truncate? }`) |
|
|
39
|
-
|
|
40
|
-
## Schema & indexes
|
|
41
|
-
|
|
42
|
-
| Method | Path | Purpose |
|
|
43
|
-
| ------ | ------------------------------------ | -------------------------------- |
|
|
44
|
-
| POST | `/api/tables` | Create table |
|
|
45
|
-
| POST | `/api/tables/generate` | Generate CREATE SQL (no execute) |
|
|
46
|
-
| GET | `/api/tables/:table/schema` | Full schema (constraints, indexes, FK refs) |
|
|
47
|
-
| GET | `/api/tables/:table/ddl` | Get formatted `CREATE TABLE` and `INDEX` DDL |
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
| POST | `/api/tables/:table/
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
| DELETE | `/api/tables/:table`
|
|
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
|
-
| POST | `/api/databases/
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
|
88
|
-
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
1
|
+
# AdminDB REST API
|
|
2
|
+
|
|
3
|
+
Every route is under `basePath` and returns the consistent shape
|
|
4
|
+
`{ success, data?, error? }`. In multi-db mode, every route is scoped under the
|
|
5
|
+
database identifier, e.g. `/api/app.db/tables` or `/api/prod_pg/tables`.
|
|
6
|
+
|
|
7
|
+
AdminDB supports both **SQLite** and **PostgreSQL** database backends seamlessly.
|
|
8
|
+
|
|
9
|
+
## Tables & rows
|
|
10
|
+
|
|
11
|
+
| Method | Path | Purpose |
|
|
12
|
+
| ------ | ---------------------------------------- | -------------------------------- |
|
|
13
|
+
| GET | `/api/tables` | List tables |
|
|
14
|
+
| GET | `/api/tables/:table/info` | Column + FK metadata, PK columns |
|
|
15
|
+
| GET | `/api/tables/:table/fk-options` | Values for FK dropdowns |
|
|
16
|
+
| GET | `/api/tables/:table/rows?page&limit&f` | Paginated rows (`f` = URL-encoded JSON filters — legacy strings like `{"age":">35"}` or structured conditions like `{"balance":{"op":"gte","value":"100"}}`) |
|
|
17
|
+
| GET | `/api/tables/:table/rows/count?f=` | Filtered row count |
|
|
18
|
+
| GET | `/api/tables/:table/row/:id` | Single row by (encoded) PK |
|
|
19
|
+
| GET | `/api/tables/:table/rows/:id/references` | Rows in other tables whose foreign keys reference this row |
|
|
20
|
+
| GET | `/api/tables/:table/row/:id/blob/:column` | Stream binary BLOB / BYTEA with MIME detection (add `?download=1` to force download) |
|
|
21
|
+
| GET | `/api/tables/:table/row/:id/blob/:column/meta` | Inspect BLOB / BYTEA metadata, MIME sniffing & 3-column hex dump |
|
|
22
|
+
| PUT | `/api/tables/:table/row/:id/blob/:column` | Update binary value (`{ data: base64/hex, format?: 'base64'|'hex'|'text' }`) |
|
|
23
|
+
| POST | `/api/tables/:table/rows` | Insert row (or batch of rows with `{ rows: [...] }`) |
|
|
24
|
+
| POST | `/api/tables/:table/rows/generate` | Generate INSERT SQL (no execute) |
|
|
25
|
+
| POST | `/api/tables/:table/rows/import` | Import CSV (`{ csv }`, header row must match columns) |
|
|
26
|
+
| GET | `/api/tables/:table/export?format=` | Download all rows as `csv` or `json` |
|
|
27
|
+
| PUT | `/api/tables/:table/row/:id` | Update row (`{ values, nulls? }` — `nulls` explicitly sets columns to NULL) |
|
|
28
|
+
| PUT | `/api/tables/:table/row/:id/generate` | Generate UPDATE SQL (no execute) |
|
|
29
|
+
| DELETE | `/api/tables/:table/row/:id` | Delete row |
|
|
30
|
+
| POST | `/api/tables/:table/rows/bulk-impact` | FK-impact preview: how many rows in other tables reference the selected rows |
|
|
31
|
+
| POST | `/api/tables/:table/rows/bulk-delete` | Delete selected rows (`{ ids, confirmImpact }`; transactional) |
|
|
32
|
+
| POST | `/api/tables/:table/rows/bulk-export` | Export only the selected rows as `csv`/`json` (`{ ids, format }`) |
|
|
33
|
+
| POST | `/api/tables/:table/rows/bulk-update` | Apply staged inline edits (`{ updates: [{ id, values?, nulls? }] }`; transactional) |
|
|
34
|
+
| GET | `/api/tables/:table/seed/config` | Per-column generator strategies + detected defaults |
|
|
35
|
+
| GET | `/api/tables/:table/seed/plan` | Detect intelligent seed plan heuristics |
|
|
36
|
+
| POST | `/api/tables/:table/seed/preview` | Generate preview sample rows for grid without executing |
|
|
37
|
+
| POST | `/api/tables/:table/seed/generate` | Generate seed INSERT SQL without executing (`{ count, plan }`) |
|
|
38
|
+
| POST | `/api/tables/:table/seed` | Generate and insert seed rows transactionally (`{ count, plan, truncate? }`) |
|
|
39
|
+
|
|
40
|
+
## Schema & indexes
|
|
41
|
+
|
|
42
|
+
| Method | Path | Purpose |
|
|
43
|
+
| ------ | ------------------------------------ | -------------------------------- |
|
|
44
|
+
| POST | `/api/tables` | Create table |
|
|
45
|
+
| POST | `/api/tables/generate` | Generate CREATE SQL (no execute) |
|
|
46
|
+
| GET | `/api/tables/:table/schema` | Full schema (constraints, indexes, FK refs) |
|
|
47
|
+
| GET | `/api/tables/:table/ddl` | Get formatted `CREATE TABLE` and `INDEX` DDL for a single table |
|
|
48
|
+
| GET | `/api/info/ddl` | Get formatted DDL for the entire database schema |
|
|
49
|
+
|
|
50
|
+
| POST | `/api/tables/:table/rename` | Rename the table |
|
|
51
|
+
| POST | `/api/tables/:table/columns` | Add a column |
|
|
52
|
+
| PUT | `/api/tables/:table/columns/:column` | Modify/rename a column |
|
|
53
|
+
| DELETE | `/api/tables/:table/columns/:column` | Drop a column (safety-checked) |
|
|
54
|
+
| DELETE | `/api/tables/:table` | Drop the table (safety-checked) |
|
|
55
|
+
| POST | `/api/tables/bulk-drop` | Drop multiple tables at once (`{ tables, force }`) |
|
|
56
|
+
| POST | `/api/tables/bulk-truncate` | Truncate/empty multiple tables at once (`{ tables, force }`) |
|
|
57
|
+
| POST | `/api/tables/:table/indexes` | Create an index (`{ name?, columns[], unique? }`) |
|
|
58
|
+
| DELETE | `/api/tables/:table/indexes/:index` | Drop an index (auto indexes refused) |
|
|
59
|
+
| GET | `/api/erd` | Full schema graph with columns & FK edges for ER Diagram |
|
|
60
|
+
|
|
61
|
+
## Queries
|
|
62
|
+
|
|
63
|
+
| Method | Path | Purpose |
|
|
64
|
+
| ------ | ----------------- | -------------------------- |
|
|
65
|
+
| POST | `/api/query` | Run arbitrary SQL |
|
|
66
|
+
| POST | `/api/query/export` | Run a SELECT and download as `csv`/`json` |
|
|
67
|
+
| GET | `/api/queries` | List saved queries |
|
|
68
|
+
| POST | `/api/queries` | Save a named query |
|
|
69
|
+
| DELETE | `/api/queries/:id`| Delete a saved query |
|
|
70
|
+
|
|
71
|
+
## Manager mode (databases landing page)
|
|
72
|
+
|
|
73
|
+
These endpoints manage database files and power the filesystem browser:
|
|
74
|
+
|
|
75
|
+
| Method | Path | Purpose |
|
|
76
|
+
| ------ | ------------------------------- | ------------------------------------------- |
|
|
77
|
+
| GET | `/api/databases` | List managed databases |
|
|
78
|
+
| POST | `/api/databases` | Create a new SQLite database (`{ name }`) |
|
|
79
|
+
| POST | `/api/databases/connect-postgres` | Connect a PostgreSQL database (`{ name?, connectionString, readonly? }`) |
|
|
80
|
+
| POST | `/api/databases/:id/mode` | Toggle/set database mode (`{ readonly: boolean }`) |
|
|
81
|
+
| DELETE | `/api/databases/:id` | Delete SQLite database file or disconnect PostgreSQL connection |
|
|
82
|
+
| GET | `/api/fs/list?path=` | List subfolders + SQLite files under a path (sandboxed file browser) |
|
|
83
|
+
| POST | `/api/databases/open` | Open/register an existing database file by path (`{ path, readonly? }`) |
|
|
84
|
+
|
|
85
|
+
## Authentication & Sessions
|
|
86
|
+
|
|
87
|
+
| Method | Path | Purpose |
|
|
88
|
+
| ------ | --------------------- | ------------------------------------------- |
|
|
89
|
+
| GET | `/login` | Web UI login page |
|
|
90
|
+
| POST | `/login` | Authenticate with `{ username, password }` and get session token |
|
|
91
|
+
| POST | `/logout` | Terminate session and clear cookie |
|
|
92
|
+
| GET | `/logout` | Terminate session and redirect to `/login` |
|
|
93
|
+
|
|
94
|
+
All API endpoints accept:
|
|
95
|
+
- **HTTP Basic Auth**: `Authorization: Basic <base64(username:password)>`
|
|
96
|
+
- **Bearer Token**: `Authorization: Bearer <sessionToken>`
|
|
97
|
+
- **Session Cookie**: `admindb_session=<sessionToken>`
|
|
98
|
+
|
|
99
|
+
### Generating Password Hashes
|
|
100
|
+
Generate salted `scrypt` password hashes for custom credentials:
|
|
101
|
+
```bash
|
|
102
|
+
npm run generatehash
|
|
103
|
+
# Enter password -> outputs scrypt:<salt>:<hash>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Paste the generated hash into `ADMINDB_PASSWORD`, CLI `-P`, or `auth.password` option.
|
|
107
|
+
|
|
108
|
+
### Disabling Native Authentication & Custom Application Auth
|
|
109
|
+
Pass `auth: false`, CLI `--no-auth`, or `ADMINDB_AUTH=false` to turn off built-in authentication when integrating your own security layer.
|
|
110
|
+
|
|
111
|
+
> [!WARNING]
|
|
112
|
+
> **Security & Responsibility Notice**:
|
|
113
|
+
> AdminDB's built-in authentication is designed for basic access control during local development. For production environments and internet-facing networks, **it is entirely the user's responsibility to protect AdminDB** by placing it behind your own application authentication (e.g. NextAuth, Passport, JWT, SSO/OAuth middleware), a VPN, an IP-allowlist reverse proxy (Nginx, Cloudflare Access), or HTTPS with rate limiting.
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
## TypeScript API Types & Helpers
|
|
117
|
+
|
|
118
|
+
All request and response types, data inspection helpers, and serverless handlers are exported by the package entry point:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import {
|
|
122
|
+
createRouter,
|
|
123
|
+
createServerlessHandler,
|
|
124
|
+
createLambdaHandler,
|
|
125
|
+
sniffMimeType,
|
|
126
|
+
generateHexDump,
|
|
127
|
+
analyzeBlob,
|
|
128
|
+
isJsonString,
|
|
129
|
+
formatJsonSafely,
|
|
130
|
+
type ApiResponse,
|
|
131
|
+
type GetRowsResponseData,
|
|
132
|
+
type BlobMetaResponseData,
|
|
133
|
+
type TableDdlResponseData,
|
|
134
|
+
} from 'admindb';
|
|
135
|
+
import { analyzeSqlError } from 'admindb/dist/sql/error-analyzer.js';
|
|
136
|
+
|
|
137
|
+
// 1. Sniff MIME type from binary magic bytes
|
|
138
|
+
const analysis = sniffMimeType(imageBuffer);
|
|
139
|
+
console.log(analysis.mime, analysis.ext, analysis.isImage);
|
|
140
|
+
|
|
141
|
+
// 2. Generate a 3-column hex dump
|
|
142
|
+
const dump = generateHexDump(binaryBuffer, 1024);
|
|
143
|
+
dump.lines.forEach((l) => console.log(`${l.offset} ${l.hex} |${l.ascii}|`));
|
|
144
|
+
|
|
145
|
+
// 3. Serverless request handler (Vercel, AWS Lambda, Cloudflare, etc.)
|
|
146
|
+
export default createServerlessHandler({ dbPath: './app.db' });
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
|