admindb 1.1.0 → 1.2.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 CHANGED
@@ -23,9 +23,11 @@ editor, and multi-database support.
23
23
 
24
24
  > ## ⚠️ Security warning — read first
25
25
  >
26
- > **This tool exposes full, unauthenticated database access.** Every page and
27
- > API route (browse, edit, delete, run arbitrary SQL, change the schema, export
28
- > the whole database) is available to **anyone who can reach the server**.
26
+ > **This tool exposes full, unauthenticated database AND filesystem access.**
27
+ > Every page and API route (browse, edit, delete, run arbitrary SQL, change the
28
+ > schema, export the whole database, and — in manager mode — browse the
29
+ > filesystem to open database files) is available to **anyone who can reach the
30
+ > server**.
29
31
  >
30
32
  > - **No authentication or authorization is built in.** The routes are **not
31
33
  > protected**.
@@ -49,6 +51,26 @@ npm install admindb
49
51
 
50
52
  Requires **Node.js ≥ 20**.
51
53
 
54
+ ### Use as a standalone CLI tool
55
+
56
+ AdminDB ships a command-line server. Install it globally (or just run it with
57
+ `npx` — no install needed):
58
+
59
+ ```bash
60
+ npm install -g admindb
61
+ admindb # starts the server → open http://localhost:3000
62
+ ```
63
+
64
+ Run it without installing anything:
65
+
66
+ ```bash
67
+ npx admindb -p 8080 # run on port 8080
68
+ ```
69
+
70
+ The `admindb` command starts the built-in server and opens the web UI in your
71
+ browser. See [Run the built-in server](#run-the-built-in-server) for all the
72
+ flags — `--port`, `--open <file>`, `--dir <folder>`, `--readonly`, and more.
73
+
52
74
  ## Using as an npm package
53
75
 
54
76
  AdminDB is an Express app you can mount inside your own application, under
@@ -83,6 +105,8 @@ static assets + view engine). Mounting it is just `app.use('/path', router)`.
83
105
  | `basePath` | `string` | URL prefix used by templates/assets (e.g. `/admin`). Pass the same prefix you mount at |
84
106
  | `logger` | `Logger` | Custom logger (see `createLogger`) |
85
107
  | `logLevel` | `'debug'\|'info'\|'warn'\|'error'` | Log verbosity (used when no logger is passed) |
108
+ | `allowBrowse` | `boolean` | Manager mode: show the filesystem file-browser on the databases page. Set `false` to disable it (e.g. when the server was started with specific database files). Default: `true` |
109
+ | `browseRoot` | `string` | Manager mode: restrict the file-browser to this folder (absolute path) — it cannot navigate above it and only databases inside it can be opened |
86
110
  | `readonly` | `boolean` | Open the database(s) **read-only**: every write is rejected (403), write controls are disabled in the UI, and a banner is shown. The DB file is opened with `SQLITE_OPEN_READONLY` + `PRAGMA query_only` as a belt-and-suspenders guard. Default: `false` |
87
111
 
88
112
  Example with a custom logger and prefix:
@@ -167,6 +191,10 @@ In multi-db mode:
167
191
  - **Read-only mode:** open the database(s) without write access — the file is
168
192
  opened `SQLITE_OPEN_READONLY` + `query_only`, every write route returns `403`,
169
193
  and the UI hides/disables all write controls and shows a banner.
194
+ - **Standalone CLI / file browser:** `admindb` runs as a full web app — with no
195
+ arguments it opens a **Databases** landing page where you can browse the
196
+ filesystem and open any SQLite database file, or create new ones. Flags set
197
+ the port, open a file, manage a folder, and more (`admindb --help`).
170
198
  - **Multiple databases:** directory scanning and/or explicit file lists, each
171
199
  with its own workspace under `/{db}/…`.
172
200
 
@@ -210,26 +238,70 @@ npm run build
210
238
  npm start # open http://localhost:3000
211
239
  ```
212
240
 
213
- Configuration via environment variables:
214
-
215
- | Variable | Default | Description |
216
- | ----------- | ------------------ | ------------------------------------ |
217
- | `PORT` | `3000` | Port to listen on |
218
- | `HOST` | `0.0.0.0` | Host / interface to bind |
219
- | `DB_PATH` | `admindb.db` | Single SQLite database file |
220
- | `DB_DIR` | — | Multi-db source 1: a directory of `.db`/`.sqlite` files |
221
- | `DB_FILES` | — | Multi-db source 2: comma-separated explicit database file paths |
222
- | `READONLY` | — | `1` / `true` / `yes` / `on` opens the database(s) read-only |
223
- | `BASE_PATH` | `''` | URL prefix (e.g. `/admin`) |
224
- | `LOG_LEVEL` | `info` | `debug` \| `info` \| `warn` \| `error` |
241
+ The server is a full standalone web app. With no arguments it runs in
242
+ **manager mode**: a **Databases** landing page where you can browse the
243
+ filesystem and open any SQLite database file (`.db` / `.sqlite` / `.sqlite3`),
244
+ or create new ones.
245
+
246
+ ### CLI flags
247
+
248
+ | Flag | Description |
249
+ | -------------------- | -------------------------------------------------------- |
250
+ | `-p, --port <port>` | Port to listen on (default `3000`) |
251
+ | `-H, --host <host>` | Host / interface to bind (default `0.0.0.0`) |
252
+ | `-o, --open <file>` | Open a single database file directly |
253
+ | `-d, --dir <dir>` | Manage a folder of database files |
254
+ | `--files <list>` | Comma-separated database file paths to manage |
255
+ | `-b, --base-path <p>`| URL prefix to serve under (default `/`) |
256
+ | `-r, --readonly` | Open databases read-only (all writes disabled) |
257
+ | `-l, --log-level <l>`| `debug` \| `info` \| `warn` \| `error` (default `info`) |
258
+ | `-h, --help` | Show help |
259
+ | `-v, --version` | Show the version |
260
+
261
+ A positional `path` argument opens a database file directly, or manages a
262
+ folder when it is a directory. Flags override the environment variables below:
263
+
264
+ | Variable | Default | Description |
265
+ | ----------- | ------- | ------------------------------------ |
266
+ | `PORT` | `3000` | Port to listen on |
267
+ | `HOST` | `0.0.0.0` | Host / interface to bind |
268
+ | `DB_PATH` | — | Single SQLite database file |
269
+ | `DB_DIR` | — | Folder of `.db`/`.sqlite` files |
270
+ | `DB_FILES` | — | Comma-separated explicit database file paths |
271
+ | `READONLY` | — | `1` / `true` / `yes` / `on` opens the database(s) read-only |
272
+ | `BASE_PATH` | `''` | URL prefix (e.g. `/admin`) |
273
+ | `LOG_LEVEL` | `info` | `debug` \| `info` \| `warn` \| `error` |
274
+
275
+ Examples:
225
276
 
226
- Multi-db mode activates when `DB_DIR` and/or `DB_FILES` is set:
277
+ ```bash
278
+ admindb # manager UI on http://localhost:3000
279
+ admindb -p 8080 # same, on port 8080
280
+ admindb ./data/app.db # open a single database file
281
+ admindb --open ~/notes.sqlite # open a file directly
282
+ admindb -d ./dbs # manage a folder of databases
283
+ admindb --files a.db,b.db -r # open two files read-only
284
+ ```
227
285
 
228
286
  ```powershell
229
- $env:DB_DIR='./db'; npm start # PowerShell
287
+ $env:DB_DIR='./db'; npm start # PowerShell
230
288
  # bash/zsh: DB_DIR=./db npm start
231
289
  ```
232
290
 
291
+ When the server runs without an explicit single file, the **Databases** landing
292
+ page lists the managed databases and includes an **"Open an existing
293
+ database"** file browser: navigate folders, pick a database file, and open it.
294
+ Opened files are added to the list so you can switch between databases freely.
295
+
296
+ File-browser policy:
297
+ - When a **folder** is given (`--dir`, a directory path, or `DB_DIR`), browsing
298
+ is limited to that folder — it cannot navigate above it and only databases
299
+ inside it can be opened.
300
+ - When specific **files** are given (`--files`, or `DB_FILES`) without a folder,
301
+ file browsing is **disabled** entirely; only the configured databases are
302
+ listed.
303
+ - With no folder or files, browsing is unrestricted.
304
+
233
305
  ## The JSON REST API (under `basePath`)
234
306
 
235
307
  | Method | Path | Purpose |
@@ -270,6 +342,17 @@ In multi-db mode, every route is scoped under the database, e.g.
270
342
  `/api/app.db/tables`. Every API response uses the consistent shape
271
343
  `{ success, data?, error? }`.
272
344
 
345
+ In manager mode (the databases landing page), these extra endpoints manage
346
+ database files and power the filesystem browser:
347
+
348
+ | Method | Path | Purpose |
349
+ | ------ | ----------------------- | ------------------------------------------- |
350
+ | GET | `/api/databases` | List managed databases |
351
+ | POST | `/api/databases` | Create a new database (`{ name }`) |
352
+ | DELETE | `/api/databases/:id` | Delete a database |
353
+ | GET | `/api/fs/list?path=` | List subfolders + SQLite files under a path (file browser) |
354
+ | POST | `/api/databases/open` | Open/register an existing database file by path (`{ path }`) |
355
+
273
356
  ## Behaviour notes
274
357
 
275
358
  - **Empty input = "not set".** Empty form fields are omitted so DB defaults
package/dist/app.d.ts CHANGED
@@ -15,6 +15,18 @@ export interface AppOptions {
15
15
  manager?: DbManager;
16
16
  /** Open the database read-only — all write routes are rejected with 403. */
17
17
  readonly?: boolean;
18
+ /**
19
+ * Manager mode: show the filesystem file-browser on the databases landing
20
+ * page. Defaults to `true`. Set to `false` to disable browsing (e.g. when the
21
+ * server was started with specific database files only).
22
+ */
23
+ allowBrowse?: boolean;
24
+ /**
25
+ * Manager mode: restrict the file-browser to this folder (absolute path).
26
+ * When set, the browser cannot navigate above it and only databases inside it
27
+ * can be opened.
28
+ */
29
+ browseRoot?: string;
18
30
  /** Internal: URL of the databases list (used by per-db apps to link "switch database"). */
19
31
  databasesUrl?: string;
20
32
  /** Internal: current database id (for locals/display). */
package/dist/app.js CHANGED
@@ -12,7 +12,10 @@ const logger_1 = require("./logger");
12
12
  const pages_1 = require("./routes/pages");
13
13
  const api_1 = require("./routes/api");
14
14
  const databases_1 = require("./routes/databases");
15
+ const args_1 = require("./args");
15
16
  const util_1 = require("./util");
17
+ /** Installed package version, exposed to every template as `{{version}}`. */
18
+ const APP_VERSION = (0, args_1.getPackageVersion)();
16
19
  /**
17
20
  * Build a fully configured, mountable Express app (pages + JSON API + static
18
21
  * assets + view engine).
@@ -94,6 +97,7 @@ function createSingleDbApp(options) {
94
97
  res.locals.databasesUrl = databasesUrl ?? null;
95
98
  res.locals.databasesMode = false;
96
99
  res.locals.readonly = db.isReadOnly;
100
+ res.locals.version = APP_VERSION;
97
101
  if (!req.path.startsWith('/api/')) {
98
102
  const all = await db.listTables();
99
103
  const names = (all.data ?? []).map((t) => t.name);
@@ -133,6 +137,7 @@ function createManagerApp(options) {
133
137
  res.locals.databasesUrl = null;
134
138
  res.locals.databasesMode = true;
135
139
  res.locals.readonly = readonly;
140
+ res.locals.version = APP_VERSION;
136
141
  if (!req.path.startsWith('/api/')) {
137
142
  res.locals.tables = [];
138
143
  res.locals.internalTables = [];
@@ -150,6 +155,8 @@ function createManagerApp(options) {
150
155
  logger,
151
156
  basePath,
152
157
  readonly,
158
+ allowBrowse: options.allowBrowse,
159
+ browseRoot: options.browseRoot,
153
160
  invalidate: (id) => subApps.delete(id),
154
161
  });
155
162
  app.use('/:dbId', (req, res, next) => {
package/dist/app.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":";;;;;AA2CA,oCAEC;AA7CD,sDAA8B;AAC9B,0DAA6B;AAC7B,2DAA4C;AAC5C,4CAA+C;AAE/C,qCAAoE;AACpE,0CAA+C;AAC/C,sCAA2C;AAC3C,kDAA6D;AAC7D,iCAAsC;AAqBtC;;;;;;;;;;;;GAYG;AACH,SAAgB,YAAY,CAAC,UAAsB,EAAE;IACnD,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,eAAe,CAAC,GAAoB,EAAE,MAAc;IAC3D,GAAG,CAAC,MAAM,CACR,KAAK,EACL,IAAA,2BAAM,EAAC;QACL,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,MAAM;QACrB,UAAU,EAAE,mBAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC;QACpD,WAAW,EAAE,mBAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,UAAU,CAAC;QACtD,OAAO,EAAE;YACP,EAAE,EAAE,CAAC,CAAU,EAAE,CAAU,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC;YACvC,UAAU,EAAE,CAAC,CAAU,EAAE,CAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACnF,MAAM,EAAE,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS;YACrD,QAAQ,EAAE,CAAC,CAAU,EAAE,CAAS,EAAE,EAAE;gBAClC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBACrC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAChD,CAAC;YACD,IAAI,EAAE,CAAC,CAAU,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;YAChE,GAAG,EAAE,CAAC,CAAU,EAAE,CAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;YACtD,GAAG,EAAE,CAAC,CAAU,EAAE,CAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;YACtD,EAAE,EAAE,CAAC,CAAU,EAAE,CAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;YACrD,EAAE,EAAE,CAAC,CAAU,EAAE,CAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;YACrD,IAAI,EAAE,CAAC,GAAY,EAAE,GAAW,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;SAC7G;KACF,CAAC,CACH,CAAC;IACF,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAC9B,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,mBAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAoB,EAAE,MAAc;IAC5D,eAAe;IACf,GAAG,CAAC,GAAG,CAAC,CAAC,GAAoB,EAAE,GAAqB,EAAE,EAAE;QACtD,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACjC,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;QACvE,CAAC;QACD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,wCAAwC,EAAE,CAAC,CAAC;IAC9H,CAAC,CAAC,CAAC;IAEH,yBAAyB;IACzB,GAAG,CAAC,GAAG,CAAC,CAAC,GAAU,EAAE,GAAoB,EAAE,GAAqB,EAAE,KAA2B,EAAE,EAAE;QAC/F,MAAM,CAAC,KAAK,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;QACrC,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACjC,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAA,mBAAY,EAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAA,mBAAY,EAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACnG,CAAC,CAAC,CAAC;AACL,CAAC;AAED,gFAAgF;AAChF,SAAS,iBAAiB,CAAC,OAAmB;IAC5C,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAA,qBAAY,EAAC,OAAO,CAAC,QAAQ,IAAI,MAAM,EAAE,SAAS,CAAC,CAAC;IACrF,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,IAAI,IAAI,yBAAc,CAAC,OAAO,CAAC,MAAM,IAAI,YAAY,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACpH,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAE1C,MAAM,MAAM,GAAG,IAAA,iBAAO,GAAE,CAAC;IACzB,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAE/B,yEAAyE;IACzE,MAAM,CAAC,GAAG,CAAC,iBAAO,CAAC,MAAM,CAAC,mBAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE3D,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IAE5C,gDAAgD;IAChD,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAClC,IAAI,CAAC;YACH,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;YAC/B,GAAG,CAAC,MAAM,CAAC,WAAW,GAAG,GAAG,CAAC,IAAI,CAAC;YAClC,GAAG,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC;YAC/B,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC,IAAI,CAAC;YAC5B,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC;YACvC,GAAG,CAAC,MAAM,CAAC,YAAY,GAAG,YAAY,IAAI,IAAI,CAAC;YAC/C,GAAG,CAAC,MAAM,CAAC,aAAa,GAAG,KAAK,CAAC;YACjC,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAC,UAAU,CAAC;YACpC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAClC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,UAAU,EAAE,CAAC;gBAClC,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAClD,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC5D,GAAG,CAAC,MAAM,CAAC,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;YACrE,CAAC;YACD,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,CAAC;QACZ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAA,qBAAa,EAAC,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,IAAA,iBAAW,EAAC,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAEpC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,oFAAoF;AACpF,SAAS,gBAAgB,CAAC,OAAmB;IAC3C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAQ,CAAC;IACjC,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAA,qBAAY,EAAC,OAAO,CAAC,QAAQ,IAAI,MAAM,EAAE,SAAS,CAAC,CAAC;IACrF,MAAM,QAAQ,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IAEpC,MAAM,GAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;IACtB,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAE5B,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,MAAM,CAAC,mBAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACxD,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IAEzC,yCAAyC;IACzC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC/B,IAAI,CAAC;YACH,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;YAC/B,GAAG,CAAC,MAAM,CAAC,WAAW,GAAG,GAAG,CAAC,IAAI,CAAC;YAClC,GAAG,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC;YAC/B,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;YACtC,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;YACvB,GAAG,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC;YAC/B,GAAG,CAAC,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC;YAChC,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;YAC/B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAClC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;gBACvB,GAAG,CAAC,MAAM,CAAC,cAAc,GAAG,EAAE,CAAC;YACjC,CAAC;YACD,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,CAAC;QACZ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,iEAAiE;IACjE,MAAM,OAAO,GAAG,IAAI,GAAG,EAA2B,CAAC;IACnD,IAAA,mCAAuB,EAAC,GAAG,EAAE;QAC3B,OAAO;QACP,MAAM;QACN,QAAQ;QACR,QAAQ;QACR,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;KACvC,CAAC,CAAC;IACH,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAoB,EAAE,GAAqB,EAAE,IAA0B,EAAE,EAAE;QAC5F,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBACjC,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,IAAI,mBAAmB,EAAE,CAAC,CAAC;YAC/F,CAAC;YACD,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE;gBAC3C,KAAK,EAAE,WAAW;gBAClB,MAAM,EAAE,GAAG;gBACX,KAAK,EAAE,aAAa,IAAI,mBAAmB;aAC5C,CAAC,CAAC;QACL,CAAC;QACD,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,OAAO,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1E,GAAG,GAAG,iBAAiB,CAAC;gBACtB,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;gBACtB,QAAQ,EAAE,OAAO;gBACjB,MAAM;gBACN,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,IAAI;gBACJ,YAAY,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG;gBAC5C,QAAQ;aACT,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC9B,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
package/dist/args.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ import type { LogLevel } from './logger';
2
+ export interface CliArgs {
3
+ help: boolean;
4
+ version: boolean;
5
+ /** Bind host/interface. */
6
+ host?: string;
7
+ /** Port to listen on. */
8
+ port?: number;
9
+ /** A single database file to open directly (`--open`/`--db`/`--file`). */
10
+ dbPath?: string;
11
+ /** Directory of database files to manage (`--dir`). */
12
+ dbDir?: string;
13
+ /** Explicit database file paths (`--files a.db,b.db`). */
14
+ dbFiles?: string[];
15
+ /** URL prefix to serve under (`--base-path`). */
16
+ basePath?: string;
17
+ logLevel?: LogLevel;
18
+ /** Open databases read-only (`--readonly`). */
19
+ readonly: boolean;
20
+ }
21
+ export declare function helpText(): string;
22
+ /** The installed `admindb` package version (from package.json), or '' when unknown. */
23
+ export declare function getPackageVersion(): string;
24
+ export declare function versionText(): string;
25
+ export declare function parseArgs(argv: string[]): {
26
+ args: CliArgs;
27
+ error?: string;
28
+ };
package/dist/args.js ADDED
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.helpText = helpText;
7
+ exports.getPackageVersion = getPackageVersion;
8
+ exports.versionText = versionText;
9
+ exports.parseArgs = parseArgs;
10
+ /**
11
+ * Command-line argument parsing for the standalone `admindb` server.
12
+ *
13
+ * The CLI supports flags to pick the port/host, open a single database file,
14
+ * manage a folder of databases, and more. Every flag has a matching
15
+ * environment variable; flags always win over the environment.
16
+ */
17
+ const node_fs_1 = require("node:fs");
18
+ const node_path_1 = __importDefault(require("node:path"));
19
+ const LOG_LEVELS = ['debug', 'info', 'warn', 'error'];
20
+ function helpText() {
21
+ return [
22
+ 'AdminDB — browser-based SQLite administration tool.',
23
+ '',
24
+ 'Usage:',
25
+ ' admindb [options] [path]',
26
+ '',
27
+ 'Starts a local server and opens a web UI where you can browse, select and',
28
+ 'manage SQLite databases (.db / .sqlite / .sqlite3).',
29
+ '',
30
+ 'With no path or options it runs in "manager" mode: the landing page lets',
31
+ 'you browse the filesystem and open any database file, or create new ones.',
32
+ '',
33
+ 'Arguments:',
34
+ ' path Path to a database file (opens it directly) or to a',
35
+ ' folder of databases (lists them). Default: the',
36
+ ' current directory.',
37
+ '',
38
+ 'Options:',
39
+ ' -p, --port <port> Port to listen on (default: 3000)',
40
+ ' -H, --host <host> Host/interface to bind (default: 0.0.0.0)',
41
+ ' -o, --open <file> Open a single database file',
42
+ ' -d, --dir <dir> Folder of database files to manage',
43
+ ' --files <list> Comma-separated database file paths',
44
+ ' -b, --base-path <p> URL prefix to serve under (default: /)',
45
+ ' -r, --readonly Open databases read-only (all writes disabled)',
46
+ ' -l, --log-level <l> debug | info | warn | error (default: info)',
47
+ ' -h, --help Show this help',
48
+ ' -v, --version Show the version',
49
+ '',
50
+ 'Environment variables (used when the matching flag is not given):',
51
+ ' PORT, HOST, DB_PATH, DB_DIR, DB_FILES, BASE_PATH, READONLY, LOG_LEVEL',
52
+ '',
53
+ 'Examples:',
54
+ ' admindb # manager UI on http://localhost:3000',
55
+ ' admindb -p 8080 # same, on port 8080',
56
+ ' admindb ./data/app.db # open a single database file',
57
+ ' admindb --open ~/notes.sqlite # open a file (direct)',
58
+ ' admindb -d ./dbs # manage a folder of databases',
59
+ ' admindb --files a.db,b.db -r # open two files read-only',
60
+ ].join('\n');
61
+ }
62
+ function packageVersion() {
63
+ try {
64
+ const raw = (0, node_fs_1.readFileSync)(node_path_1.default.join(__dirname, '..', 'package.json'), 'utf8');
65
+ const pkg = JSON.parse(raw);
66
+ return pkg.version ?? '';
67
+ }
68
+ catch {
69
+ return '';
70
+ }
71
+ }
72
+ /** The installed `admindb` package version (from package.json), or '' when unknown. */
73
+ function getPackageVersion() {
74
+ return packageVersion();
75
+ }
76
+ function versionText() {
77
+ const v = packageVersion();
78
+ return v ? `admindb v${v}` : 'admindb';
79
+ }
80
+ /** True when a token is exactly a flag or `flag=value` (for long flags). */
81
+ function isFlag(tok, ...names) {
82
+ return names.includes(tok) || names.some((n) => n.length > 2 && tok.startsWith(n + '='));
83
+ }
84
+ function parseArgs(argv) {
85
+ const args = { help: false, version: false, readonly: false };
86
+ const positional = [];
87
+ let i = 0;
88
+ const invalid = (error) => ({ args, error });
89
+ // Read the value for the current flag token; supports `--flag=value` and
90
+ // `--flag value`. Leaves `i` pointing at the value token so the loop can
91
+ // advance past it.
92
+ const takeValue = (flag) => {
93
+ const eq = argv[i].indexOf('=');
94
+ if (eq !== -1)
95
+ return argv[i].slice(eq + 1);
96
+ i += 1;
97
+ return argv[i];
98
+ };
99
+ while (i < argv.length) {
100
+ const tok = argv[i];
101
+ if (tok === '-h' || tok === '--help') {
102
+ args.help = true;
103
+ }
104
+ else if (tok === '-v' || tok === '--version') {
105
+ args.version = true;
106
+ }
107
+ else if (isFlag(tok, '-p', '--port')) {
108
+ const v = takeValue('--port');
109
+ if (v === undefined)
110
+ return invalid('Missing value for --port.');
111
+ const n = Number.parseInt(v, 10);
112
+ if (!Number.isFinite(n) || n <= 0)
113
+ return invalid(`Invalid port: "${v}".`);
114
+ args.port = n;
115
+ }
116
+ else if (isFlag(tok, '-H', '--host')) {
117
+ const v = takeValue('--host');
118
+ if (v === undefined)
119
+ return invalid('Missing value for --host.');
120
+ args.host = v;
121
+ }
122
+ else if (isFlag(tok, '-o', '--open', '--db', '-f', '--file')) {
123
+ const v = takeValue('--open');
124
+ if (v === undefined)
125
+ return invalid('Missing value for --open.');
126
+ args.dbPath = v;
127
+ }
128
+ else if (isFlag(tok, '-d', '--dir', '--folder')) {
129
+ const v = takeValue('--dir');
130
+ if (v === undefined)
131
+ return invalid('Missing value for --dir.');
132
+ args.dbDir = v;
133
+ }
134
+ else if (isFlag(tok, '--files')) {
135
+ const v = takeValue('--files');
136
+ if (v === undefined)
137
+ return invalid('Missing value for --files.');
138
+ args.dbFiles = v
139
+ .split(',')
140
+ .map((s) => s.trim())
141
+ .filter(Boolean);
142
+ }
143
+ else if (isFlag(tok, '-b', '--base-path', '--base')) {
144
+ const v = takeValue('--base-path');
145
+ if (v === undefined)
146
+ return invalid('Missing value for --base-path.');
147
+ args.basePath = v;
148
+ }
149
+ else if (isFlag(tok, '-l', '--log-level')) {
150
+ const v = takeValue('--log-level');
151
+ if (v === undefined)
152
+ return invalid('Missing value for --log-level.');
153
+ if (!LOG_LEVELS.includes(v)) {
154
+ return invalid(`Invalid log level: "${v}". Expected one of: ${LOG_LEVELS.join(', ')}.`);
155
+ }
156
+ args.logLevel = v;
157
+ }
158
+ else if (tok === '-r' || tok === '--readonly') {
159
+ args.readonly = true;
160
+ }
161
+ else if (tok.startsWith('-') && tok.length > 1) {
162
+ return invalid(`Unknown option: "${tok}".`);
163
+ }
164
+ else {
165
+ positional.push(tok);
166
+ }
167
+ i += 1;
168
+ }
169
+ if (positional.length > 1) {
170
+ return invalid(`Unexpected extra arguments: ${positional.slice(1).join(' ')}.`);
171
+ }
172
+ const p = positional[0];
173
+ if (p) {
174
+ const abs = node_path_1.default.resolve(p);
175
+ try {
176
+ if ((0, node_fs_1.statSync)(abs).isDirectory())
177
+ args.dbDir = p;
178
+ else
179
+ args.dbPath = p;
180
+ }
181
+ catch {
182
+ args.dbPath = p;
183
+ }
184
+ }
185
+ return { args };
186
+ }
187
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -5,50 +5,120 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  const express_1 = __importDefault(require("express"));
8
+ const node_path_1 = __importDefault(require("node:path"));
8
9
  const app_1 = require("./app");
9
10
  const config_1 = require("./config");
10
11
  const logger_1 = require("./logger");
11
12
  const manager_1 = require("./db/manager");
13
+ const args_1 = require("./args");
12
14
  /**
13
15
  * Standalone CLI / server entry point. Run `npm start` (or `npx admindb`).
14
- * Configure via PORT, HOST, DB_PATH, DB_DIR, DB_FILES, BASE_PATH and LOG_LEVEL
15
- * env vars. Set DB_DIR and/or DB_FILES to enable multi-database mode.
16
16
  *
17
- * SECURITY: this server exposes full, unauthenticated database access. It must
18
- * NOT be exposed to the public internet — protect it yourself (bind to
19
- * localhost, put it behind an authenticated reverse proxy, a VPN, etc.).
17
+ * Everything can be set with CLI flags (see `--help`) or environment variables
18
+ * (PORT, HOST, DB_PATH, DB_DIR, DB_FILES, BASE_PATH, READONLY, LOG_LEVEL); flags
19
+ * win over the environment.
20
+ *
21
+ * By default the server runs in "manager" mode: the landing page lets you
22
+ * browse the filesystem and open any SQLite database file, or create new ones.
23
+ * `--open <file>` (or a file path / DB_PATH) opens a single database directly.
24
+ *
25
+ * SECURITY: this server exposes full, unauthenticated database AND filesystem
26
+ * access. It must NOT be exposed to the public internet — protect it yourself
27
+ * (bind to localhost, put it behind an authenticated reverse proxy, a VPN,
28
+ * etc.).
20
29
  */
21
- const config = (0, config_1.loadConfig)();
30
+ const env = (0, config_1.loadConfig)();
31
+ const parsed = (0, args_1.parseArgs)(process.argv.slice(2));
32
+ if (parsed.error) {
33
+ console.error(parsed.error);
34
+ console.error();
35
+ console.error((0, args_1.helpText)());
36
+ process.exit(1);
37
+ }
38
+ const args = parsed.args;
39
+ if (args.help) {
40
+ console.log((0, args_1.helpText)());
41
+ process.exit(0);
42
+ }
43
+ if (args.version) {
44
+ console.log((0, args_1.versionText)());
45
+ process.exit(0);
46
+ }
47
+ // Merge CLI flags over environment variables.
48
+ const config = {
49
+ host: args.host ?? env.host,
50
+ port: args.port ?? env.port,
51
+ dbPath: args.dbPath ?? env.dbPath,
52
+ dbDir: args.dbDir ?? env.dbDir,
53
+ dbFiles: args.dbFiles ?? env.dbFiles,
54
+ basePath: (args.basePath ?? env.basePath).replace(/\/+$/, ''),
55
+ logLevel: args.logLevel ?? env.logLevel,
56
+ readonly: args.readonly || env.readonly,
57
+ };
22
58
  const logger = (0, logger_1.createLogger)(config.logLevel, 'admindb');
23
59
  const app = (0, express_1.default)();
24
60
  app.disable('x-powered-by');
25
- const multiDb = Boolean(config.dbDir || (config.dbFiles && config.dbFiles.length > 0));
26
- const router = multiDb
61
+ // Mode selection:
62
+ // - A specific single file was requested (`--open`, a file path argument, or
63
+ // DB_PATH) and no folder/files were configured → single-database mode.
64
+ // - Otherwise → manager mode with a landing page where you can browse the
65
+ // filesystem and open database files, or create new ones.
66
+ const hasDir = Boolean(config.dbDir);
67
+ const hasFiles = Boolean(config.dbFiles && config.dbFiles.length > 0);
68
+ const explicitFile = args.dbPath ?? (process.env.DB_PATH ? process.env.DB_PATH : undefined);
69
+ const singleFileOnly = Boolean(explicitFile) && !hasDir && !hasFiles;
70
+ const useManager = !singleFileOnly;
71
+ const managerFiles = [...(config.dbFiles ?? [])];
72
+ if (useManager && explicitFile)
73
+ managerFiles.push(explicitFile);
74
+ // File-browser policy for manager mode:
75
+ // - a folder was requested → browsing is allowed but limited to that folder;
76
+ // - specific files were requested (no folder) → browsing is disabled entirely;
77
+ // - nothing requested → browsing is allowed (free); the folder defaults to the
78
+ // current directory so new/created databases land there.
79
+ const managerDir = hasDir ? config.dbDir : hasFiles || explicitFile ? undefined : process.cwd();
80
+ const allowBrowse = useManager && (hasDir || (!hasFiles && !explicitFile));
81
+ const browseRoot = hasDir ? node_path_1.default.resolve(config.dbDir) : undefined;
82
+ const router = useManager
27
83
  ? (0, app_1.createRouter)({
28
- manager: new manager_1.DbManager({ dir: config.dbDir, files: config.dbFiles, readonly: config.readonly }, logger),
84
+ manager: new manager_1.DbManager({ dir: managerDir, files: managerFiles, readonly: config.readonly }, logger),
29
85
  basePath: config.basePath,
30
86
  logger,
31
87
  readonly: config.readonly,
88
+ allowBrowse,
89
+ browseRoot,
32
90
  })
33
- : (0, app_1.createRouter)({ dbPath: config.dbPath, basePath: config.basePath, logger, readonly: config.readonly });
91
+ : (0, app_1.createRouter)({ dbPath: explicitFile, basePath: config.basePath, logger, readonly: config.readonly });
34
92
  app.use(config.basePath || '/', router);
35
93
  const server = app.listen(config.port, config.host, () => {
36
94
  const url = `http://${config.host}:${config.port}${config.basePath}/`;
37
95
  logger.info(`AdminDB listening on ${url}`);
38
- if (multiDb) {
39
- const sources = [config.dbDir ? `dir:${config.dbDir}` : null, config.dbFiles?.length ? `files:[${config.dbFiles.join(', ')}]` : null]
96
+ if (useManager) {
97
+ const sources = [
98
+ managerDir ? `dir:${managerDir}` : null,
99
+ managerFiles.length ? `files:[${managerFiles.join(', ')}]` : null,
100
+ ]
40
101
  .filter(Boolean)
41
102
  .join(' · ');
42
- logger.info(`Multi-database mode — ${sources}`);
103
+ logger.info(`Manager mode — ${sources}`);
104
+ if (!allowBrowse) {
105
+ logger.info('File browsing disabled — only the configured database files are listed.');
106
+ }
107
+ else if (browseRoot) {
108
+ logger.info(`File browsing is limited to: ${browseRoot}`);
109
+ }
110
+ else {
111
+ logger.info('Open the URL above in your browser to browse and open database files.');
112
+ }
43
113
  }
44
114
  else {
45
- logger.info(`Database file: ${config.dbPath}`);
115
+ logger.info(`Database file: ${explicitFile}`);
46
116
  }
47
117
  if (config.readonly) {
48
118
  logger.info('Read-only mode enabled — all writes are disabled.');
49
119
  }
50
120
  if (config.host === '0.0.0.0') {
51
- logger.warn('Listening on 0.0.0.0 — this admin tool has NO authentication. Do not expose it to untrusted networks.');
121
+ logger.warn('Listening on 0.0.0.0 — this admin tool has NO authentication and exposes filesystem access. Do not expose it to untrusted networks.');
52
122
  }
53
123
  });
54
124
  const shutdown = (signal) => {
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;AACA,sDAA8B;AAC9B,+BAAqC;AACrC,qCAAsC;AACtC,qCAAwC;AACxC,0CAAyC;AAEzC;;;;;;;;GAQG;AACH,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;AAC5B,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AACxD,MAAM,GAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;AACtB,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;AAE5B,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;AACvF,MAAM,MAAM,GAAG,OAAO;IACpB,CAAC,CAAC,IAAA,kBAAY,EAAC;QACX,OAAO,EAAE,IAAI,mBAAS,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC;QACvG,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM;QACN,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAC;IACJ,CAAC,CAAC,IAAA,kBAAY,EAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC1G,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,GAAG,EAAE,MAAM,CAAC,CAAC;AAExC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;IACvD,MAAM,GAAG,GAAG,UAAU,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,QAAQ,GAAG,CAAC;IACtE,MAAM,CAAC,IAAI,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;IAC3C,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;aAClI,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,KAAK,CAAC,CAAC;QACf,MAAM,CAAC,IAAI,CAAC,yBAAyB,OAAO,EAAE,CAAC,CAAC;IAClD,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,MAAM,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,uGAAuG,CAAC,CAAC;IACvH,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAQ,EAAE;IACxC,MAAM,CAAC,IAAI,CAAC,YAAY,MAAM,kBAAkB,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;AAClD,CAAC,CAAC;AAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC/C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;AACA,sDAA8B;AAC9B,0DAA6B;AAC7B,+BAAqC;AACrC,qCAAsC;AACtC,qCAAwC;AACxC,0CAAyC;AACzC,iCAA0D;AAE1D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,GAAG,GAAG,IAAA,mBAAU,GAAE,CAAC;AACzB,MAAM,MAAM,GAAG,IAAA,gBAAS,EAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,OAAO,CAAC,KAAK,EAAE,CAAC;IAChB,OAAO,CAAC,KAAK,CAAC,IAAA,eAAQ,GAAE,CAAC,CAAC;IAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;AACzB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,IAAA,eAAQ,GAAE,CAAC,CAAC;IACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,OAAO,CAAC,GAAG,CAAC,IAAA,kBAAW,GAAE,CAAC,CAAC;IAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,8CAA8C;AAC9C,MAAM,MAAM,GAAG;IACb,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI;IAC3B,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI;IAC3B,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM;IACjC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK;IAC9B,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO;IACpC,QAAQ,EAAE,CAAC,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAC7D,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ;IACvC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ;CACxC,CAAC;AAEF,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AACxD,MAAM,GAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;AACtB,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;AAE5B,kBAAkB;AAClB,8EAA8E;AAC9E,0EAA0E;AAC1E,2EAA2E;AAC3E,6DAA6D;AAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACtE,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAC5F,MAAM,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC;AACrE,MAAM,UAAU,GAAG,CAAC,cAAc,CAAC;AAEnC,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;AACjD,IAAI,UAAU,IAAI,YAAY;IAAE,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AAEhE,wCAAwC;AACxC,8EAA8E;AAC9E,gFAAgF;AAChF,gFAAgF;AAChF,4DAA4D;AAC5D,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,IAAI,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;AAChG,MAAM,WAAW,GAAG,UAAU,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;AAC3E,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,mBAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAEpE,MAAM,MAAM,GAAG,UAAU;IACvB,CAAC,CAAC,IAAA,kBAAY,EAAC;QACX,OAAO,EAAE,IAAI,mBAAS,CACpB,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,EACnE,MAAM,CACP;QACD,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM;QACN,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,WAAW;QACX,UAAU;KACX,CAAC;IACJ,CAAC,CAAC,IAAA,kBAAY,EAAC,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;AACzG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,GAAG,EAAE,MAAM,CAAC,CAAC;AAExC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;IACvD,MAAM,GAAG,GAAG,UAAU,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,QAAQ,GAAG,CAAC;IACtE,MAAM,CAAC,IAAI,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;IAC3C,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,OAAO,GAAG;YACd,UAAU,CAAC,CAAC,CAAC,OAAO,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI;YACvC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;SAClE;aACE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,KAAK,CAAC,CAAC;QACf,MAAM,CAAC,IAAI,CAAC,kBAAkB,OAAO,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;QACzF,CAAC;aAAM,IAAI,UAAU,EAAE,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC,gCAAgC,UAAU,EAAE,CAAC,CAAC;QAC5D,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC,kBAAkB,YAAY,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,MAAM,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,qIAAqI,CAAC,CAAC;IACrJ,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAQ,EAAE;IACxC,MAAM,CAAC,IAAI,CAAC,YAAY,MAAM,kBAAkB,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;AAClD,CAAC,CAAC;AAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC/C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC"}