@tensorix/metahub 0.1.2 → 0.1.3
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 +30 -5
- package/dist/cli.js +2445 -171
- package/dist/cli.js.map +28 -16
- package/dist/core/config.d.ts +14 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/db.d.ts +6 -0
- package/dist/core/db.d.ts.map +1 -1
- package/dist/core/documents.d.ts +1 -0
- package/dist/core/documents.d.ts.map +1 -1
- package/dist/core/schema.d.ts +1 -1
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/sync/auth.d.ts +6 -0
- package/dist/core/sync/auth.d.ts.map +1 -1
- package/dist/core/sync/client.d.ts +7 -2
- package/dist/core/sync/client.d.ts.map +1 -1
- package/dist/core/sync/pairing.d.ts +50 -0
- package/dist/core/sync/pairing.d.ts.map +1 -0
- package/dist/core/sync/peers-routes.d.ts +3 -0
- package/dist/core/sync/peers-routes.d.ts.map +1 -0
- package/dist/core/sync/peers.d.ts +45 -0
- package/dist/core/sync/peers.d.ts.map +1 -0
- package/dist/core/sync/protocol.d.ts +13 -0
- package/dist/core/sync/protocol.d.ts.map +1 -1
- package/dist/core/sync/routes.d.ts.map +1 -1
- package/dist/core/sync/server.d.ts +6 -0
- package/dist/core/sync/server.d.ts.map +1 -1
- package/dist/core/sync/webui-routes.d.ts.map +1 -1
- package/dist/core/sync/webui.d.ts.map +1 -1
- package/dist/index.js +526 -93
- package/dist/index.js.map +18 -14
- package/dist/webui.js +31 -30
- package/package.json +2 -1
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
3
5
|
var __defProp = Object.defineProperty;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
9
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
10
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
11
|
+
for (let key of __getOwnPropNames(mod))
|
|
12
|
+
if (!__hasOwnProp.call(to, key))
|
|
13
|
+
__defProp(to, key, {
|
|
14
|
+
get: () => mod[key],
|
|
15
|
+
enumerable: true
|
|
16
|
+
});
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
4
20
|
var __export = (target, all) => {
|
|
5
21
|
for (var name in all)
|
|
6
22
|
__defProp(target, name, {
|
|
@@ -1272,6 +1288,64 @@ var init_sites = __esm(() => {
|
|
|
1272
1288
|
};
|
|
1273
1289
|
});
|
|
1274
1290
|
|
|
1291
|
+
// node_modules/sisteransi/src/index.js
|
|
1292
|
+
var require_src = __commonJS((exports, module) => {
|
|
1293
|
+
var ESC2 = "\x1B";
|
|
1294
|
+
var CSI2 = `${ESC2}[`;
|
|
1295
|
+
var beep = "\x07";
|
|
1296
|
+
var cursor = {
|
|
1297
|
+
to(x2, y3) {
|
|
1298
|
+
if (!y3)
|
|
1299
|
+
return `${CSI2}${x2 + 1}G`;
|
|
1300
|
+
return `${CSI2}${y3 + 1};${x2 + 1}H`;
|
|
1301
|
+
},
|
|
1302
|
+
move(x2, y3) {
|
|
1303
|
+
let ret = "";
|
|
1304
|
+
if (x2 < 0)
|
|
1305
|
+
ret += `${CSI2}${-x2}D`;
|
|
1306
|
+
else if (x2 > 0)
|
|
1307
|
+
ret += `${CSI2}${x2}C`;
|
|
1308
|
+
if (y3 < 0)
|
|
1309
|
+
ret += `${CSI2}${-y3}A`;
|
|
1310
|
+
else if (y3 > 0)
|
|
1311
|
+
ret += `${CSI2}${y3}B`;
|
|
1312
|
+
return ret;
|
|
1313
|
+
},
|
|
1314
|
+
up: (count = 1) => `${CSI2}${count}A`,
|
|
1315
|
+
down: (count = 1) => `${CSI2}${count}B`,
|
|
1316
|
+
forward: (count = 1) => `${CSI2}${count}C`,
|
|
1317
|
+
backward: (count = 1) => `${CSI2}${count}D`,
|
|
1318
|
+
nextLine: (count = 1) => `${CSI2}E`.repeat(count),
|
|
1319
|
+
prevLine: (count = 1) => `${CSI2}F`.repeat(count),
|
|
1320
|
+
left: `${CSI2}G`,
|
|
1321
|
+
hide: `${CSI2}?25l`,
|
|
1322
|
+
show: `${CSI2}?25h`,
|
|
1323
|
+
save: `${ESC2}7`,
|
|
1324
|
+
restore: `${ESC2}8`
|
|
1325
|
+
};
|
|
1326
|
+
var scroll = {
|
|
1327
|
+
up: (count = 1) => `${CSI2}S`.repeat(count),
|
|
1328
|
+
down: (count = 1) => `${CSI2}T`.repeat(count)
|
|
1329
|
+
};
|
|
1330
|
+
var erase = {
|
|
1331
|
+
screen: `${CSI2}2J`,
|
|
1332
|
+
up: (count = 1) => `${CSI2}1J`.repeat(count),
|
|
1333
|
+
down: (count = 1) => `${CSI2}J`.repeat(count),
|
|
1334
|
+
line: `${CSI2}2K`,
|
|
1335
|
+
lineEnd: `${CSI2}K`,
|
|
1336
|
+
lineStart: `${CSI2}1K`,
|
|
1337
|
+
lines(count) {
|
|
1338
|
+
let clear = "";
|
|
1339
|
+
for (let i2 = 0;i2 < count; i2++)
|
|
1340
|
+
clear += this.line + (i2 < count - 1 ? cursor.up() : "");
|
|
1341
|
+
if (count)
|
|
1342
|
+
clear += cursor.left;
|
|
1343
|
+
return clear;
|
|
1344
|
+
}
|
|
1345
|
+
};
|
|
1346
|
+
module.exports = { cursor, scroll, erase, beep };
|
|
1347
|
+
});
|
|
1348
|
+
|
|
1275
1349
|
// src/core/sync/webui.ts
|
|
1276
1350
|
var exports_webui = {};
|
|
1277
1351
|
__export(exports_webui, {
|
|
@@ -1305,8 +1379,8 @@ async function serveWebui(req) {
|
|
|
1305
1379
|
return new Response(await getJs(), {
|
|
1306
1380
|
headers: { "content-type": "text/javascript; charset=utf-8" }
|
|
1307
1381
|
});
|
|
1308
|
-
} catch (
|
|
1309
|
-
return new Response(`webui build failed: ${
|
|
1382
|
+
} catch (e3) {
|
|
1383
|
+
return new Response(`webui build failed: ${e3}`, { status: 500 });
|
|
1310
1384
|
}
|
|
1311
1385
|
}
|
|
1312
1386
|
return null;
|
|
@@ -1448,6 +1522,21 @@ var HTML = `<!doctype html>
|
|
|
1448
1522
|
.theme-card.sel .tc-check { opacity:1; transform:scale(1); }
|
|
1449
1523
|
@media (max-width:560px) { .theme-grid { grid-template-columns:1fr; } }
|
|
1450
1524
|
|
|
1525
|
+
/* sync devices */
|
|
1526
|
+
.peer-actions { display:flex; gap:10px; margin-bottom:16px; flex-wrap:wrap; }
|
|
1527
|
+
.peer-actions .btn { display:inline-flex; align-items:center; gap:6px; }
|
|
1528
|
+
.peer-list { display:flex; flex-direction:column; gap:8px; }
|
|
1529
|
+
.peer-row { display:flex; align-items:center; gap:12px; padding:12px 14px; border:1px solid var(--line);
|
|
1530
|
+
border-radius:10px; background:var(--surface); }
|
|
1531
|
+
.peer-dot { width:9px; height:9px; border-radius:50%; flex:none; background:var(--muted); }
|
|
1532
|
+
.peer-dot.on { background:#3fb950; } .peer-dot.err { background:#f85149; } .peer-dot.off { background:var(--muted); }
|
|
1533
|
+
.peer-main { flex:1; min-width:0; }
|
|
1534
|
+
.peer-url { font-weight:600; font-size:14px; color:var(--fg); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
1535
|
+
.peer-sub { font-size:12px; color:var(--muted); margin-top:2px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
1536
|
+
.peer-menu { flex:none; padding:6px; }
|
|
1537
|
+
.pair-code { font-family:var(--mono); font-size:26px; font-weight:700; letter-spacing:.12em;
|
|
1538
|
+
text-align:center; padding:16px; border:1px dashed var(--line); border-radius:10px; background:var(--surface); color:var(--fg); }
|
|
1539
|
+
|
|
1451
1540
|
/* main */
|
|
1452
1541
|
.main { flex:1; display:flex; flex-direction:column; overflow:hidden; min-width:0; }
|
|
1453
1542
|
.topbar { display:flex; align-items:center; gap:6px; padding:10px 18px; border-bottom:1px solid var(--line); min-height:49px; }
|
|
@@ -1884,6 +1973,49 @@ var HTML = `<!doctype html>
|
|
|
1884
1973
|
.db { padding:16px 14px 90px; }
|
|
1885
1974
|
.peek { width:100%; }
|
|
1886
1975
|
}
|
|
1976
|
+
|
|
1977
|
+
/* Quick Notes window (desktop, loaded at #quick). A transparent body lets the
|
|
1978
|
+
macOS vibrancy blur show through; a translucent panel keeps text readable.
|
|
1979
|
+
The top bar is the window drag region; its buttons opt back out. */
|
|
1980
|
+
body.quicknote { background:transparent; }
|
|
1981
|
+
/* The main app lays #app out as a flex row (sidebar + main); the quick-note
|
|
1982
|
+
route has a single child, so override to a full-bleed block or the panel
|
|
1983
|
+
shrinks to its content width and the window's vibrancy shows through. */
|
|
1984
|
+
body.quicknote #app { display:block; width:100vw; height:100vh; }
|
|
1985
|
+
.qn { display:flex; flex-direction:column; width:100%; height:100vh; overflow:hidden;
|
|
1986
|
+
background:color-mix(in srgb, var(--bg) 20%, transparent); }
|
|
1987
|
+
.qn-bar { display:flex; align-items:center; gap:6px; padding:4px 10px 4px 76px;
|
|
1988
|
+
user-select:none; -webkit-app-region:drag;
|
|
1989
|
+
background:color-mix(in srgb, var(--surface) 30%, transparent); }
|
|
1990
|
+
.qn-brand { flex:1; min-width:0; font-size:12px; font-weight:600; color:var(--fg-soft);
|
|
1991
|
+
white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
|
|
1992
|
+
.qn-actions { display:flex; gap:2px; -webkit-app-region:no-drag; }
|
|
1993
|
+
.qn-actions .iconbtn { width:26px; height:26px; }
|
|
1994
|
+
.qn-actions .iconbtn.active { color:var(--accent); background:var(--hover-2); }
|
|
1995
|
+
.qn-body { flex:1; overflow:auto; -webkit-app-region:no-drag; }
|
|
1996
|
+
.qn-body .doc { max-width:none; margin:0; padding:14px 22px 30vh; }
|
|
1997
|
+
.qn-body .doc-title { font-size:24px; margin-bottom:2px; }
|
|
1998
|
+
.qn-body .doc-meta { display:none; }
|
|
1999
|
+
/* Compact menus inside the quick-note window only (dropdown + slash command
|
|
2000
|
+
share .pop/.item/.lico with the main app; scope under body.quicknote so the
|
|
2001
|
+
main app keeps its roomier density). */
|
|
2002
|
+
body.quicknote .pop { padding:5px; border-radius:9px; }
|
|
2003
|
+
body.quicknote .pop .lbl { padding:4px 8px 2px; font-size:10px; }
|
|
2004
|
+
body.quicknote .pop .item { padding:5px 9px; gap:8px; font-size:12.5px; }
|
|
2005
|
+
body.quicknote .pop .item .t { font-size:12.5px; }
|
|
2006
|
+
body.quicknote .pop .item .d { font-size:10.5px; }
|
|
2007
|
+
body.quicknote .pop .item .lico { width:22px; height:22px; }
|
|
2008
|
+
body.quicknote .pop .item .lico.plain { width:20px; height:20px; }
|
|
2009
|
+
body.quicknote .pop .sep { margin:4px 4px; }
|
|
2010
|
+
|
|
2011
|
+
/* Quick Notes settings rows (desktop only). */
|
|
2012
|
+
.qn-set-row { display:flex; align-items:center; gap:14px; padding:12px 0; border-top:1px solid var(--line); }
|
|
2013
|
+
.qn-set-row:first-of-type { border-top:0; }
|
|
2014
|
+
.qn-set-main { flex:1; min-width:0; }
|
|
2015
|
+
.qn-set-name { font-weight:600; }
|
|
2016
|
+
.qn-set-desc { color:var(--muted); font-size:13px; margin-top:2px; }
|
|
2017
|
+
.qn-shortcut { min-width:140px; justify-content:center; font-family:var(--mono); }
|
|
2018
|
+
.qn-shortcut.capturing { outline:2px solid var(--accent); color:var(--accent); }
|
|
1887
2019
|
</style>
|
|
1888
2020
|
</head>
|
|
1889
2021
|
<body>
|
|
@@ -3324,7 +3456,7 @@ async function runMain(cmd, opts = {}) {
|
|
|
3324
3456
|
// package.json
|
|
3325
3457
|
var package_default = {
|
|
3326
3458
|
name: "@tensorix/metahub",
|
|
3327
|
-
version: "0.1.
|
|
3459
|
+
version: "0.1.3",
|
|
3328
3460
|
description: "Metahub core library and CLI",
|
|
3329
3461
|
type: "module",
|
|
3330
3462
|
main: "./dist/index.js",
|
|
@@ -3353,6 +3485,7 @@ var package_default = {
|
|
|
3353
3485
|
test: "bun test"
|
|
3354
3486
|
},
|
|
3355
3487
|
dependencies: {
|
|
3488
|
+
"@clack/prompts": "^1.5.0",
|
|
3356
3489
|
citty: "^0.1.6",
|
|
3357
3490
|
"highlight.js": "^11.11.1",
|
|
3358
3491
|
preact: "^10.29.2",
|
|
@@ -3389,11 +3522,41 @@ CREATE TABLE IF NOT EXISTS crdt_changes (
|
|
|
3389
3522
|
CREATE INDEX IF NOT EXISTS idx_changes_hlc ON crdt_changes(hlc);
|
|
3390
3523
|
|
|
3391
3524
|
-- Per-peer replication cursors (SQLite rowids: monotonic in insertion order,
|
|
3392
|
-
-- so no change is ever skipped regardless of HLC/clock skew).
|
|
3525
|
+
-- so no change is ever skipped regardless of HLC/clock skew). Outbound side of
|
|
3526
|
+
-- a pairing: "token" is the credential the *remote* issued to us (sent as a
|
|
3527
|
+
-- Bearer header when we sync to them). See migratePeers in db.ts for the columns
|
|
3528
|
+
-- added to legacy databases.
|
|
3393
3529
|
CREATE TABLE IF NOT EXISTS peers (
|
|
3394
|
-
url
|
|
3395
|
-
pull_cursor
|
|
3396
|
-
push_cursor
|
|
3530
|
+
url TEXT PRIMARY KEY,
|
|
3531
|
+
pull_cursor INTEGER NOT NULL DEFAULT 0,
|
|
3532
|
+
push_cursor INTEGER NOT NULL DEFAULT 0,
|
|
3533
|
+
token TEXT,
|
|
3534
|
+
label TEXT,
|
|
3535
|
+
node_id TEXT,
|
|
3536
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
3537
|
+
last_sync_at INTEGER,
|
|
3538
|
+
last_status TEXT,
|
|
3539
|
+
last_error TEXT
|
|
3540
|
+
);
|
|
3541
|
+
|
|
3542
|
+
-- Inbound side of a pairing: credentials *we* issued to remote devices. A peer
|
|
3543
|
+
-- presents one of these on /sync; acceptsSyncToken() checks it alongside the
|
|
3544
|
+
-- managed master token. Revoke by deleting the row.
|
|
3545
|
+
CREATE TABLE IF NOT EXISTS peer_grants (
|
|
3546
|
+
token TEXT PRIMARY KEY,
|
|
3547
|
+
peer_url TEXT,
|
|
3548
|
+
node_id TEXT,
|
|
3549
|
+
created_at INTEGER
|
|
3550
|
+
);
|
|
3551
|
+
|
|
3552
|
+
-- One-time pairing codes minted by "mh config peer code" / POST /api/pair/new.
|
|
3553
|
+
-- Short-lived and single-use: redeemed during the pairing handshake, then the
|
|
3554
|
+
-- two devices exchange durable peer_grants. used/exp gate redemption.
|
|
3555
|
+
CREATE TABLE IF NOT EXISTS pairing_codes (
|
|
3556
|
+
code TEXT PRIMARY KEY,
|
|
3557
|
+
exp INTEGER NOT NULL,
|
|
3558
|
+
used INTEGER NOT NULL DEFAULT 0,
|
|
3559
|
+
created_at INTEGER
|
|
3397
3560
|
);
|
|
3398
3561
|
|
|
3399
3562
|
CREATE TABLE IF NOT EXISTS databases (
|
|
@@ -4106,12 +4269,28 @@ function migrateRecords(db) {
|
|
|
4106
4269
|
tx();
|
|
4107
4270
|
backfillRecordOrderKeys(db);
|
|
4108
4271
|
}
|
|
4272
|
+
function migratePeers(db) {
|
|
4273
|
+
const add = [
|
|
4274
|
+
["token", "TEXT"],
|
|
4275
|
+
["label", "TEXT"],
|
|
4276
|
+
["node_id", "TEXT"],
|
|
4277
|
+
["enabled", "INTEGER NOT NULL DEFAULT 1"],
|
|
4278
|
+
["last_sync_at", "INTEGER"],
|
|
4279
|
+
["last_status", "TEXT"],
|
|
4280
|
+
["last_error", "TEXT"]
|
|
4281
|
+
];
|
|
4282
|
+
for (const [col, decl] of add) {
|
|
4283
|
+
if (!hasColumn(db, "peers", col))
|
|
4284
|
+
db.exec(`ALTER TABLE peers ADD COLUMN ${col} ${decl}`);
|
|
4285
|
+
}
|
|
4286
|
+
}
|
|
4109
4287
|
function openMetahub() {
|
|
4110
4288
|
ensureDirs();
|
|
4111
4289
|
const db = new Database(dbPath(), { create: true });
|
|
4112
4290
|
db.exec("PRAGMA journal_mode = WAL;");
|
|
4113
4291
|
runSchema(db);
|
|
4114
4292
|
migrateRecords(db);
|
|
4293
|
+
migratePeers(db);
|
|
4115
4294
|
return db;
|
|
4116
4295
|
}
|
|
4117
4296
|
|
|
@@ -4354,9 +4533,12 @@ function getDocument(db, id) {
|
|
|
4354
4533
|
return db.query("SELECT id, title, body, database_id, parent_id, created_hlc FROM documents WHERE id = ? AND __deleted = 0").get(id);
|
|
4355
4534
|
}
|
|
4356
4535
|
function listDocuments(db, opts = {}) {
|
|
4536
|
+
const cols = "SELECT id, title, database_id, parent_id, created_hlc FROM documents WHERE __deleted = 0";
|
|
4537
|
+
if (opts.parent_id !== undefined)
|
|
4538
|
+
return db.query(`${cols} AND parent_id = ? ORDER BY created_hlc`).all(opts.parent_id);
|
|
4357
4539
|
if (opts.database_id)
|
|
4358
|
-
return db.query(
|
|
4359
|
-
return db.query(
|
|
4540
|
+
return db.query(`${cols} AND database_id = ? ORDER BY created_hlc`).all(opts.database_id);
|
|
4541
|
+
return db.query(`${cols} ORDER BY created_hlc`).all();
|
|
4360
4542
|
}
|
|
4361
4543
|
function updateDocument(db, id, fields) {
|
|
4362
4544
|
if (!getDocument(db, id))
|
|
@@ -4675,6 +4857,7 @@ function docTree(rows) {
|
|
|
4675
4857
|
if (rows.length === 0)
|
|
4676
4858
|
return "(empty)";
|
|
4677
4859
|
const ids = new Set(rows.map((r3) => r3.id));
|
|
4860
|
+
const idWidth = Math.max(...rows.map((r3) => r3.id.length));
|
|
4678
4861
|
const children = new Map;
|
|
4679
4862
|
const roots = [];
|
|
4680
4863
|
for (const r3 of rows) {
|
|
@@ -4685,13 +4868,15 @@ function docTree(rows) {
|
|
|
4685
4868
|
(children.get(key) ?? children.set(key, []).get(key)).push(r3);
|
|
4686
4869
|
}
|
|
4687
4870
|
const lines = [];
|
|
4688
|
-
const walk = (node,
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
walk(
|
|
4871
|
+
const walk = (node, prefix, isRoot, isLast) => {
|
|
4872
|
+
const branch = isRoot ? "" : isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
4873
|
+
const title = node.title || "(untitled)";
|
|
4874
|
+
lines.push(`${node.id.padEnd(idWidth)} ${prefix}${branch}${title}`);
|
|
4875
|
+
const kids = children.get(node.id) ?? [];
|
|
4876
|
+
const childPrefix = isRoot ? "" : prefix + (isLast ? " " : "\u2502 ");
|
|
4877
|
+
kids.forEach((child, i2) => walk(child, childPrefix, false, i2 === kids.length - 1));
|
|
4878
|
+
};
|
|
4879
|
+
roots.forEach((root) => walk(root, "", true, true));
|
|
4695
4880
|
return lines.join(`
|
|
4696
4881
|
`);
|
|
4697
4882
|
}
|
|
@@ -19674,25 +19859,40 @@ var HealthResponseSchema = exports_external.object({
|
|
|
19674
19859
|
ok: exports_external.boolean(),
|
|
19675
19860
|
node: exports_external.string().describe("Server's node id")
|
|
19676
19861
|
});
|
|
19862
|
+
var PairRequestSchema = exports_external.object({
|
|
19863
|
+
code: exports_external.string().describe("One-time pairing code minted by this server"),
|
|
19864
|
+
node_id: exports_external.string().describe("Calling device's node id"),
|
|
19865
|
+
grant: exports_external.string().describe("Durable credential the caller issues to us"),
|
|
19866
|
+
self_url: exports_external.string().optional().describe("Caller's reachable server URL (for mutual sync)")
|
|
19867
|
+
});
|
|
19868
|
+
var PairResponseSchema = exports_external.object({
|
|
19869
|
+
node_id: exports_external.string().describe("This server's node id"),
|
|
19870
|
+
grant: exports_external.string().describe("Durable credential we issue to the caller")
|
|
19871
|
+
});
|
|
19677
19872
|
var SYNC_PATH = "/sync";
|
|
19678
19873
|
var HEALTH_PATH = "/health";
|
|
19679
19874
|
var RENEW_PATH = "/auth/token";
|
|
19875
|
+
var PAIR_PATH = "/api/pair";
|
|
19680
19876
|
|
|
19681
19877
|
// src/core/sync/client.ts
|
|
19682
19878
|
function getPeer(db, url2) {
|
|
19683
|
-
const row = db.query("SELECT pull_cursor, push_cursor FROM peers WHERE url = ?").get(url2);
|
|
19684
|
-
return row ?? { pull_cursor: 0, push_cursor: 0 };
|
|
19879
|
+
const row = db.query("SELECT pull_cursor, push_cursor, token FROM peers WHERE url = ?").get(url2);
|
|
19880
|
+
return row ?? { pull_cursor: 0, push_cursor: 0, token: null };
|
|
19685
19881
|
}
|
|
19686
19882
|
function setPeer(db, url2, c3) {
|
|
19687
19883
|
db.query("INSERT INTO peers (url, pull_cursor, push_cursor) VALUES (?, ?, ?) ON CONFLICT(url) DO UPDATE SET pull_cursor = excluded.pull_cursor, push_cursor = excluded.push_cursor").run(url2, c3.pull_cursor, c3.push_cursor);
|
|
19688
19884
|
}
|
|
19689
|
-
async function syncWithPeer(db, url2) {
|
|
19885
|
+
async function syncWithPeer(db, url2, token) {
|
|
19690
19886
|
const node = getNodeId(db);
|
|
19691
19887
|
const peer = getPeer(db, url2);
|
|
19888
|
+
const bearer = token ?? peer.token ?? undefined;
|
|
19692
19889
|
const toPush = changesAfterSeq(db, peer.push_cursor);
|
|
19890
|
+
const headers = { "content-type": "application/json" };
|
|
19891
|
+
if (bearer)
|
|
19892
|
+
headers.authorization = `Bearer ${bearer}`;
|
|
19693
19893
|
const res = await fetch(new URL(SYNC_PATH, url2), {
|
|
19694
19894
|
method: "POST",
|
|
19695
|
-
headers
|
|
19895
|
+
headers,
|
|
19696
19896
|
body: JSON.stringify({ node_id: node, since: peer.pull_cursor, changes: toPush.changes })
|
|
19697
19897
|
});
|
|
19698
19898
|
if (!res.ok)
|
|
@@ -19704,6 +19904,55 @@ async function syncWithPeer(db, url2) {
|
|
|
19704
19904
|
return { pushed: toPush.changes.length, pulled };
|
|
19705
19905
|
}
|
|
19706
19906
|
|
|
19907
|
+
// src/core/sync/peers.ts
|
|
19908
|
+
function listPeers(db) {
|
|
19909
|
+
return db.query("SELECT url, pull_cursor, push_cursor, token, label, node_id, enabled, last_sync_at, last_status, last_error FROM peers ORDER BY url").all();
|
|
19910
|
+
}
|
|
19911
|
+
function addPeer(db, input) {
|
|
19912
|
+
db.query(`INSERT INTO peers (url, token, label, node_id, enabled, pull_cursor, push_cursor)
|
|
19913
|
+
VALUES (?, ?, ?, ?, 1, 0, 0)
|
|
19914
|
+
ON CONFLICT(url) DO UPDATE SET
|
|
19915
|
+
token = coalesce(excluded.token, peers.token),
|
|
19916
|
+
label = coalesce(excluded.label, peers.label),
|
|
19917
|
+
node_id = coalesce(excluded.node_id, peers.node_id),
|
|
19918
|
+
enabled = 1`).run(input.url, input.token ?? null, input.label ?? null, input.node_id ?? null);
|
|
19919
|
+
}
|
|
19920
|
+
function removePeer(db, url2) {
|
|
19921
|
+
const tx = db.transaction(() => {
|
|
19922
|
+
const changed = db.query("DELETE FROM peers WHERE url = ?").run(url2).changes > 0;
|
|
19923
|
+
db.query("DELETE FROM peer_grants WHERE peer_url = ?").run(url2);
|
|
19924
|
+
return changed;
|
|
19925
|
+
});
|
|
19926
|
+
return tx();
|
|
19927
|
+
}
|
|
19928
|
+
function setPeerEnabled(db, url2, enabled) {
|
|
19929
|
+
return db.query("UPDATE peers SET enabled = ? WHERE url = ?").run(enabled ? 1 : 0, url2).changes > 0;
|
|
19930
|
+
}
|
|
19931
|
+
function setPeerLabel(db, url2, label) {
|
|
19932
|
+
return db.query("UPDATE peers SET label = ? WHERE url = ?").run(label, url2).changes > 0;
|
|
19933
|
+
}
|
|
19934
|
+
function updatePeerStatus(db, url2, status, error51) {
|
|
19935
|
+
db.query("UPDATE peers SET last_sync_at = ?, last_status = ?, last_error = ? WHERE url = ?").run(Date.now(), status, error51 ?? null, url2);
|
|
19936
|
+
}
|
|
19937
|
+
async function syncPeer(db, url2) {
|
|
19938
|
+
try {
|
|
19939
|
+
const result = await syncWithPeer(db, url2);
|
|
19940
|
+
updatePeerStatus(db, url2, "ok", null);
|
|
19941
|
+
return { url: url2, ok: true, pushed: result.pushed, pulled: result.pulled };
|
|
19942
|
+
} catch (e2) {
|
|
19943
|
+
const error51 = e2.message;
|
|
19944
|
+
updatePeerStatus(db, url2, "error", error51);
|
|
19945
|
+
return { url: url2, ok: false, error: error51 };
|
|
19946
|
+
}
|
|
19947
|
+
}
|
|
19948
|
+
async function syncAllPeers(db) {
|
|
19949
|
+
const peers = listPeers(db).filter((p) => p.enabled);
|
|
19950
|
+
const out = [];
|
|
19951
|
+
for (const p of peers)
|
|
19952
|
+
out.push(await syncPeer(db, p.url));
|
|
19953
|
+
return out;
|
|
19954
|
+
}
|
|
19955
|
+
|
|
19707
19956
|
// src/core/csv.ts
|
|
19708
19957
|
var NEEDS_QUOTE = /[",\r\n]/;
|
|
19709
19958
|
function encodeCell(value) {
|
|
@@ -19856,6 +20105,31 @@ async function syncFiles(db, src2, dst) {
|
|
|
19856
20105
|
}
|
|
19857
20106
|
|
|
19858
20107
|
// src/cli/commands/sync.ts
|
|
20108
|
+
function isAuthError(e2) {
|
|
20109
|
+
return e2 instanceof Error && /\b401\b|unauthorized/i.test(e2.message);
|
|
20110
|
+
}
|
|
20111
|
+
var isTTY = () => Boolean(process.stdout.isTTY && process.stdin.isTTY);
|
|
20112
|
+
async function peerSync(db, url2, token) {
|
|
20113
|
+
try {
|
|
20114
|
+
const result = await syncWithPeer(db, url2, token);
|
|
20115
|
+
if (token)
|
|
20116
|
+
addPeer(db, { url: url2, token });
|
|
20117
|
+
return result;
|
|
20118
|
+
} catch (e2) {
|
|
20119
|
+
if (token || !isAuthError(e2))
|
|
20120
|
+
throw e2;
|
|
20121
|
+
if (!isTTY()) {
|
|
20122
|
+
throw new Error(`${e2.message}
|
|
20123
|
+
this server requires a token \u2014 pass --token <token> or run in an interactive terminal`);
|
|
20124
|
+
}
|
|
20125
|
+
const entered = (globalThis.prompt("\u8BE5\u670D\u52A1\u5668\u9700\u8981\u4EE4\u724C\uFF0C\u8BF7\u8F93\u5165 token:") ?? "").trim();
|
|
20126
|
+
if (!entered)
|
|
20127
|
+
throw new Error("no token provided");
|
|
20128
|
+
const result = await syncWithPeer(db, url2, entered);
|
|
20129
|
+
addPeer(db, { url: url2, token: entered });
|
|
20130
|
+
return result;
|
|
20131
|
+
}
|
|
20132
|
+
}
|
|
19859
20133
|
var sync_default = defineCommand({
|
|
19860
20134
|
meta: {
|
|
19861
20135
|
name: "sync",
|
|
@@ -19871,12 +20145,16 @@ var sync_default = defineCommand({
|
|
|
19871
20145
|
type: "positional",
|
|
19872
20146
|
required: false,
|
|
19873
20147
|
description: "File path or entity ref; when given, export/import instead of peer sync"
|
|
20148
|
+
},
|
|
20149
|
+
token: {
|
|
20150
|
+
type: "string",
|
|
20151
|
+
description: "Auth token for a protected sync server (saved for next time)"
|
|
19874
20152
|
}
|
|
19875
20153
|
},
|
|
19876
20154
|
run: guard(async (args) => {
|
|
19877
20155
|
const db = openMetahub();
|
|
19878
20156
|
if (args.dst == null) {
|
|
19879
|
-
const result = await
|
|
20157
|
+
const result = await peerSync(db, args.src, args.token);
|
|
19880
20158
|
return print(result, () => `pushed ${result.pushed}, pulled ${result.pulled}`);
|
|
19881
20159
|
}
|
|
19882
20160
|
const r3 = await syncFiles(db, args.src, args.dst);
|
|
@@ -20058,135 +20336,1954 @@ var restore_default = defineCommand({
|
|
|
20058
20336
|
})
|
|
20059
20337
|
});
|
|
20060
20338
|
|
|
20061
|
-
// src/
|
|
20339
|
+
// src/cli/commands/config.ts
|
|
20062
20340
|
init_node();
|
|
20063
20341
|
|
|
20064
|
-
// src/core/
|
|
20065
|
-
|
|
20342
|
+
// src/core/config.ts
|
|
20343
|
+
var K_HOST = "cfg_host";
|
|
20344
|
+
var K_PORT = "cfg_port";
|
|
20345
|
+
var K_SYNC_INTERVAL = "cfg_sync_interval";
|
|
20346
|
+
var K_AUTO_SYNC = "cfg_auto_sync";
|
|
20347
|
+
var DEFAULT_CONFIG = {
|
|
20348
|
+
host: "127.0.0.1",
|
|
20349
|
+
port: 7777,
|
|
20350
|
+
syncIntervalMs: parseDuration(process.env.METAHUB_SYNC_INTERVAL, 30000),
|
|
20351
|
+
autoSync: true
|
|
20352
|
+
};
|
|
20353
|
+
function getMeta2(db, key) {
|
|
20354
|
+
const row = db.query("SELECT value FROM meta WHERE key = ?").get(key);
|
|
20355
|
+
return row ? row.value : null;
|
|
20356
|
+
}
|
|
20357
|
+
function setMeta2(db, key, value) {
|
|
20358
|
+
db.query("INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value").run(key, value);
|
|
20359
|
+
}
|
|
20360
|
+
function getServerConfig(db) {
|
|
20361
|
+
const host = getMeta2(db, K_HOST);
|
|
20362
|
+
const port = getMeta2(db, K_PORT);
|
|
20363
|
+
const interval = getMeta2(db, K_SYNC_INTERVAL);
|
|
20364
|
+
const auto = getMeta2(db, K_AUTO_SYNC);
|
|
20365
|
+
return {
|
|
20366
|
+
host: host ?? DEFAULT_CONFIG.host,
|
|
20367
|
+
port: port != null ? Number(port) : DEFAULT_CONFIG.port,
|
|
20368
|
+
syncIntervalMs: interval != null ? Number(interval) : DEFAULT_CONFIG.syncIntervalMs,
|
|
20369
|
+
autoSync: auto != null ? auto === "1" : DEFAULT_CONFIG.autoSync
|
|
20370
|
+
};
|
|
20371
|
+
}
|
|
20372
|
+
function setServerConfig(db, partial2) {
|
|
20373
|
+
if (partial2.host != null)
|
|
20374
|
+
setMeta2(db, K_HOST, partial2.host);
|
|
20375
|
+
if (partial2.port != null)
|
|
20376
|
+
setMeta2(db, K_PORT, String(partial2.port));
|
|
20377
|
+
if (partial2.syncIntervalMs != null)
|
|
20378
|
+
setMeta2(db, K_SYNC_INTERVAL, String(partial2.syncIntervalMs));
|
|
20379
|
+
if (partial2.autoSync != null)
|
|
20380
|
+
setMeta2(db, K_AUTO_SYNC, partial2.autoSync ? "1" : "0");
|
|
20381
|
+
return getServerConfig(db);
|
|
20382
|
+
}
|
|
20066
20383
|
|
|
20067
|
-
// src/core/sync/
|
|
20068
|
-
|
|
20069
|
-
|
|
20070
|
-
|
|
20071
|
-
|
|
20072
|
-
|
|
20073
|
-
|
|
20074
|
-
|
|
20075
|
-
|
|
20076
|
-
|
|
20077
|
-
name: exports_external.string(),
|
|
20078
|
-
type: exports_external.string(),
|
|
20079
|
-
config: exports_external.any().nullable(),
|
|
20080
|
-
position: exports_external.number()
|
|
20081
|
-
});
|
|
20082
|
-
var RecordSchema = exports_external.object({
|
|
20083
|
-
id: exports_external.string(),
|
|
20084
|
-
database_id: exports_external.string(),
|
|
20085
|
-
values: exports_external.record(exports_external.string(), exports_external.any())
|
|
20086
|
-
});
|
|
20087
|
-
var MoveRecordReq = exports_external.object({
|
|
20088
|
-
target: exports_external.string(),
|
|
20089
|
-
where: exports_external.enum(["before", "after"])
|
|
20090
|
-
});
|
|
20091
|
-
var DocumentSummarySchema = exports_external.object({
|
|
20092
|
-
id: exports_external.string(),
|
|
20093
|
-
title: exports_external.string(),
|
|
20094
|
-
database_id: exports_external.string().nullable(),
|
|
20095
|
-
parent_id: exports_external.string().nullable(),
|
|
20096
|
-
created_hlc: exports_external.string()
|
|
20097
|
-
});
|
|
20098
|
-
var DocumentSchema = DocumentSummarySchema.extend({ body: exports_external.string().nullable() });
|
|
20099
|
-
var SearchHitSchema = exports_external.object({
|
|
20100
|
-
type: exports_external.string(),
|
|
20101
|
-
id: exports_external.string(),
|
|
20102
|
-
database_id: exports_external.string().nullable(),
|
|
20103
|
-
title: exports_external.string().optional(),
|
|
20104
|
-
snippet: exports_external.string()
|
|
20105
|
-
});
|
|
20106
|
-
var OkSchema = exports_external.object({ ok: exports_external.boolean() });
|
|
20107
|
-
var CreateDatabaseReq = exports_external.object({ name: exports_external.string(), icon: exports_external.string().optional() });
|
|
20108
|
-
var UpdateDatabaseReq = exports_external.object({
|
|
20109
|
-
name: exports_external.string().optional(),
|
|
20110
|
-
icon: exports_external.string().nullable().optional()
|
|
20111
|
-
});
|
|
20112
|
-
var CreatePropertyReq = exports_external.object({
|
|
20113
|
-
db: exports_external.string(),
|
|
20114
|
-
name: exports_external.string(),
|
|
20115
|
-
type: exports_external.string(),
|
|
20116
|
-
config: exports_external.any().optional()
|
|
20117
|
-
});
|
|
20118
|
-
var UpdatePropertyReq = exports_external.object({
|
|
20119
|
-
name: exports_external.string().optional(),
|
|
20120
|
-
type: exports_external.string().optional(),
|
|
20121
|
-
config: exports_external.any().optional(),
|
|
20122
|
-
position: exports_external.number().optional()
|
|
20123
|
-
});
|
|
20124
|
-
var SetWidthReq = exports_external.object({ width: exports_external.number() });
|
|
20125
|
-
var RecordValuesReq = exports_external.record(exports_external.string(), exports_external.any());
|
|
20126
|
-
var CreateDocumentReq = exports_external.object({
|
|
20127
|
-
title: exports_external.string(),
|
|
20128
|
-
body: exports_external.string().optional(),
|
|
20129
|
-
database_id: exports_external.string().optional()
|
|
20130
|
-
});
|
|
20131
|
-
var UpdateDocumentReq = exports_external.object({
|
|
20132
|
-
title: exports_external.string().optional(),
|
|
20133
|
-
body: exports_external.string().optional(),
|
|
20134
|
-
parent_id: exports_external.string().nullable().optional()
|
|
20135
|
-
});
|
|
20136
|
-
function need(req, key) {
|
|
20137
|
-
const v2 = new URL(req.url).searchParams.get(key);
|
|
20138
|
-
if (!v2)
|
|
20139
|
-
throw new Error(`missing query param: ${key}`);
|
|
20140
|
-
return v2;
|
|
20384
|
+
// src/core/sync/pairing.ts
|
|
20385
|
+
init_ids();
|
|
20386
|
+
var DEFAULT_PAIR_TTL_MS = parseDuration(process.env.METAHUB_PAIR_TTL, 10 * 60000);
|
|
20387
|
+
function generatePairingCode(db, ttlMs = DEFAULT_PAIR_TTL_MS) {
|
|
20388
|
+
const now = Date.now();
|
|
20389
|
+
db.query("DELETE FROM pairing_codes WHERE used = 1 OR exp < ?").run(now);
|
|
20390
|
+
const code = randomSuffix(12);
|
|
20391
|
+
const exp = now + ttlMs;
|
|
20392
|
+
db.query("INSERT INTO pairing_codes (code, exp, used, created_at) VALUES (?, ?, 0, ?)").run(code, exp, now);
|
|
20393
|
+
return { code, exp };
|
|
20141
20394
|
}
|
|
20142
|
-
function
|
|
20143
|
-
return
|
|
20395
|
+
function redeemPairingCode(db, code) {
|
|
20396
|
+
return db.query("UPDATE pairing_codes SET used = 1 WHERE code = ? AND used = 0 AND exp >= ?").run(code, Date.now()).changes > 0;
|
|
20144
20397
|
}
|
|
20145
|
-
function
|
|
20146
|
-
|
|
20147
|
-
|
|
20148
|
-
|
|
20149
|
-
|
|
20150
|
-
|
|
20151
|
-
|
|
20152
|
-
|
|
20153
|
-
|
|
20398
|
+
function mintGrant(db, peerUrl, nodeId) {
|
|
20399
|
+
const token = randomSuffix(32);
|
|
20400
|
+
db.query("INSERT INTO peer_grants (token, peer_url, node_id, created_at) VALUES (?, ?, ?, ?)").run(token, peerUrl, nodeId, Date.now());
|
|
20401
|
+
return token;
|
|
20402
|
+
}
|
|
20403
|
+
function isAcceptedGrant(db, token) {
|
|
20404
|
+
return db.query("SELECT 1 FROM peer_grants WHERE token = ?").get(token) != null;
|
|
20405
|
+
}
|
|
20406
|
+
function listGrants(db) {
|
|
20407
|
+
return db.query("SELECT token, peer_url, node_id, created_at FROM peer_grants ORDER BY created_at DESC").all();
|
|
20408
|
+
}
|
|
20409
|
+
function revokeGrant(db, tokenOrPrefix) {
|
|
20410
|
+
return db.query("DELETE FROM peer_grants WHERE token = ? OR token LIKE ? || '%'").run(tokenOrPrefix, tokenOrPrefix).changes;
|
|
20411
|
+
}
|
|
20412
|
+
function handlePairRequest(db, node, body) {
|
|
20413
|
+
if (!redeemPairingCode(db, body.code)) {
|
|
20414
|
+
throw new Error("invalid or expired pairing code");
|
|
20415
|
+
}
|
|
20416
|
+
if (body.self_url) {
|
|
20417
|
+
addPeer(db, { url: body.self_url, token: body.grant, node_id: body.node_id });
|
|
20418
|
+
}
|
|
20419
|
+
const grant = mintGrant(db, body.self_url ?? null, body.node_id);
|
|
20420
|
+
return { node_id: node, grant };
|
|
20421
|
+
}
|
|
20422
|
+
async function performPairing(db, node, remoteUrl, code, selfUrl) {
|
|
20423
|
+
const ourGrant = mintGrant(db, remoteUrl, null);
|
|
20424
|
+
const reqBody = { code, node_id: node, grant: ourGrant, self_url: selfUrl };
|
|
20425
|
+
const res = await fetch(new URL(PAIR_PATH, remoteUrl), {
|
|
20426
|
+
method: "POST",
|
|
20427
|
+
headers: { "content-type": "application/json" },
|
|
20428
|
+
body: JSON.stringify(reqBody)
|
|
20429
|
+
});
|
|
20430
|
+
if (!res.ok)
|
|
20431
|
+
throw new Error(`pairing failed: ${res.status} ${await res.text()}`);
|
|
20432
|
+
const data = await res.json();
|
|
20433
|
+
addPeer(db, { url: remoteUrl, token: data.grant, node_id: data.node_id });
|
|
20434
|
+
return { node_id: data.node_id, url: remoteUrl };
|
|
20435
|
+
}
|
|
20436
|
+
|
|
20437
|
+
// node_modules/@clack/core/dist/index.mjs
|
|
20438
|
+
import { styleText as v2 } from "util";
|
|
20439
|
+
import { stdout as x2, stdin as D2 } from "process";
|
|
20440
|
+
import * as b2 from "readline";
|
|
20441
|
+
import G3 from "readline";
|
|
20442
|
+
|
|
20443
|
+
// node_modules/fast-string-truncated-width/dist/utils.js
|
|
20444
|
+
var getCodePointsLength = (() => {
|
|
20445
|
+
const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
|
20446
|
+
return (input) => {
|
|
20447
|
+
let surrogatePairsNr = 0;
|
|
20448
|
+
SURROGATE_PAIR_RE.lastIndex = 0;
|
|
20449
|
+
while (SURROGATE_PAIR_RE.test(input)) {
|
|
20450
|
+
surrogatePairsNr += 1;
|
|
20451
|
+
}
|
|
20452
|
+
return input.length - surrogatePairsNr;
|
|
20453
|
+
};
|
|
20454
|
+
})();
|
|
20455
|
+
var isFullWidth2 = (x2) => {
|
|
20456
|
+
return x2 === 12288 || x2 >= 65281 && x2 <= 65376 || x2 >= 65504 && x2 <= 65510;
|
|
20457
|
+
};
|
|
20458
|
+
var isWideNotCJKTNotEmoji = (x2) => {
|
|
20459
|
+
return x2 === 8987 || x2 === 9001 || x2 >= 12272 && x2 <= 12287 || x2 >= 12289 && x2 <= 12350 || x2 >= 12441 && x2 <= 12543 || x2 >= 12549 && x2 <= 12591 || x2 >= 12593 && x2 <= 12686 || x2 >= 12688 && x2 <= 12771 || x2 >= 12783 && x2 <= 12830 || x2 >= 12832 && x2 <= 12871 || x2 >= 12880 && x2 <= 19903 || x2 >= 65040 && x2 <= 65049 || x2 >= 65072 && x2 <= 65106 || x2 >= 65108 && x2 <= 65126 || x2 >= 65128 && x2 <= 65131 || x2 >= 127488 && x2 <= 127490 || x2 >= 127504 && x2 <= 127547 || x2 >= 127552 && x2 <= 127560 || x2 >= 131072 && x2 <= 196605 || x2 >= 196608 && x2 <= 262141;
|
|
20460
|
+
};
|
|
20461
|
+
|
|
20462
|
+
// node_modules/fast-string-truncated-width/dist/index.js
|
|
20463
|
+
var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
|
|
20464
|
+
var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
|
|
20465
|
+
var CJKT_WIDE_RE = /(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu;
|
|
20466
|
+
var TAB_RE = /\t{1,1000}/y;
|
|
20467
|
+
var EMOJI_RE = /[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[\u{E0061}-\u{E007A}]{2}[\u{E0030}-\u{E0039}\u{E0061}-\u{E007A}]{1,3}\u{E007F}|(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})(?:\u200D(?:\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F\u20E3?))*/yu;
|
|
20468
|
+
var LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
|
|
20469
|
+
var MODIFIER_RE = /\p{M}+/gu;
|
|
20470
|
+
var NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
|
|
20471
|
+
var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
|
|
20472
|
+
const LIMIT = truncationOptions.limit ?? Infinity;
|
|
20473
|
+
const ELLIPSIS = truncationOptions.ellipsis ?? "";
|
|
20474
|
+
const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
|
|
20475
|
+
const ANSI_WIDTH = 0;
|
|
20476
|
+
const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
|
|
20477
|
+
const TAB_WIDTH = widthOptions.tabWidth ?? 8;
|
|
20478
|
+
const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
|
|
20479
|
+
const FULL_WIDTH_WIDTH = 2;
|
|
20480
|
+
const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
|
|
20481
|
+
const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;
|
|
20482
|
+
const PARSE_BLOCKS = [
|
|
20483
|
+
[LATIN_RE, REGULAR_WIDTH],
|
|
20484
|
+
[ANSI_RE, ANSI_WIDTH],
|
|
20485
|
+
[CONTROL_RE, CONTROL_WIDTH],
|
|
20486
|
+
[TAB_RE, TAB_WIDTH],
|
|
20487
|
+
[EMOJI_RE, EMOJI_WIDTH],
|
|
20488
|
+
[CJKT_WIDE_RE, WIDE_WIDTH]
|
|
20489
|
+
];
|
|
20490
|
+
let indexPrev = 0;
|
|
20491
|
+
let index = 0;
|
|
20492
|
+
let length = input.length;
|
|
20493
|
+
let lengthExtra = 0;
|
|
20494
|
+
let truncationEnabled = false;
|
|
20495
|
+
let truncationIndex = length;
|
|
20496
|
+
let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
|
|
20497
|
+
let unmatchedStart = 0;
|
|
20498
|
+
let unmatchedEnd = 0;
|
|
20499
|
+
let width = 0;
|
|
20500
|
+
let widthExtra = 0;
|
|
20501
|
+
outer:
|
|
20502
|
+
while (true) {
|
|
20503
|
+
if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
|
|
20504
|
+
const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
|
|
20505
|
+
lengthExtra = 0;
|
|
20506
|
+
for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
|
|
20507
|
+
const codePoint = char.codePointAt(0) || 0;
|
|
20508
|
+
if (isFullWidth2(codePoint)) {
|
|
20509
|
+
widthExtra = FULL_WIDTH_WIDTH;
|
|
20510
|
+
} else if (isWideNotCJKTNotEmoji(codePoint)) {
|
|
20511
|
+
widthExtra = WIDE_WIDTH;
|
|
20512
|
+
} else {
|
|
20513
|
+
widthExtra = REGULAR_WIDTH;
|
|
20514
|
+
}
|
|
20515
|
+
if (width + widthExtra > truncationLimit) {
|
|
20516
|
+
truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
|
|
20517
|
+
}
|
|
20518
|
+
if (width + widthExtra > LIMIT) {
|
|
20519
|
+
truncationEnabled = true;
|
|
20520
|
+
break outer;
|
|
20521
|
+
}
|
|
20522
|
+
lengthExtra += char.length;
|
|
20523
|
+
width += widthExtra;
|
|
20524
|
+
}
|
|
20525
|
+
unmatchedStart = unmatchedEnd = 0;
|
|
20526
|
+
}
|
|
20527
|
+
if (index >= length) {
|
|
20528
|
+
break outer;
|
|
20529
|
+
}
|
|
20530
|
+
for (let i2 = 0, l2 = PARSE_BLOCKS.length;i2 < l2; i2++) {
|
|
20531
|
+
const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i2];
|
|
20532
|
+
BLOCK_RE.lastIndex = index;
|
|
20533
|
+
if (BLOCK_RE.test(input)) {
|
|
20534
|
+
lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
|
|
20535
|
+
widthExtra = lengthExtra * BLOCK_WIDTH;
|
|
20536
|
+
if (width + widthExtra > truncationLimit) {
|
|
20537
|
+
truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
|
|
20538
|
+
}
|
|
20539
|
+
if (width + widthExtra > LIMIT) {
|
|
20540
|
+
truncationEnabled = true;
|
|
20541
|
+
break outer;
|
|
20542
|
+
}
|
|
20543
|
+
width += widthExtra;
|
|
20544
|
+
unmatchedStart = indexPrev;
|
|
20545
|
+
unmatchedEnd = index;
|
|
20546
|
+
index = indexPrev = BLOCK_RE.lastIndex;
|
|
20547
|
+
continue outer;
|
|
20548
|
+
}
|
|
20549
|
+
}
|
|
20550
|
+
index += 1;
|
|
20154
20551
|
}
|
|
20552
|
+
return {
|
|
20553
|
+
width: truncationEnabled ? truncationLimit : width,
|
|
20554
|
+
index: truncationEnabled ? truncationIndex : length,
|
|
20555
|
+
truncated: truncationEnabled,
|
|
20556
|
+
ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
|
|
20155
20557
|
};
|
|
20558
|
+
};
|
|
20559
|
+
var dist_default = getStringTruncatedWidth;
|
|
20560
|
+
|
|
20561
|
+
// node_modules/fast-string-width/dist/index.js
|
|
20562
|
+
var NO_TRUNCATION2 = {
|
|
20563
|
+
limit: Infinity,
|
|
20564
|
+
ellipsis: "",
|
|
20565
|
+
ellipsisWidth: 0
|
|
20566
|
+
};
|
|
20567
|
+
var fastStringWidth = (input, options = {}) => {
|
|
20568
|
+
return dist_default(input, NO_TRUNCATION2, options).width;
|
|
20569
|
+
};
|
|
20570
|
+
var dist_default2 = fastStringWidth;
|
|
20571
|
+
|
|
20572
|
+
// node_modules/fast-wrap-ansi/lib/main.js
|
|
20573
|
+
var ESC = "\x1B";
|
|
20574
|
+
var CSI = "\x9B";
|
|
20575
|
+
var END_CODE = 39;
|
|
20576
|
+
var ANSI_ESCAPE_BELL = "\x07";
|
|
20577
|
+
var ANSI_CSI = "[";
|
|
20578
|
+
var ANSI_OSC = "]";
|
|
20579
|
+
var ANSI_SGR_TERMINATOR = "m";
|
|
20580
|
+
var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
|
|
20581
|
+
var GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
|
|
20582
|
+
var getClosingCode = (openingCode) => {
|
|
20583
|
+
if (openingCode >= 30 && openingCode <= 37)
|
|
20584
|
+
return 39;
|
|
20585
|
+
if (openingCode >= 90 && openingCode <= 97)
|
|
20586
|
+
return 39;
|
|
20587
|
+
if (openingCode >= 40 && openingCode <= 47)
|
|
20588
|
+
return 49;
|
|
20589
|
+
if (openingCode >= 100 && openingCode <= 107)
|
|
20590
|
+
return 49;
|
|
20591
|
+
if (openingCode === 1 || openingCode === 2)
|
|
20592
|
+
return 22;
|
|
20593
|
+
if (openingCode === 3)
|
|
20594
|
+
return 23;
|
|
20595
|
+
if (openingCode === 4)
|
|
20596
|
+
return 24;
|
|
20597
|
+
if (openingCode === 7)
|
|
20598
|
+
return 27;
|
|
20599
|
+
if (openingCode === 8)
|
|
20600
|
+
return 28;
|
|
20601
|
+
if (openingCode === 9)
|
|
20602
|
+
return 29;
|
|
20603
|
+
if (openingCode === 0)
|
|
20604
|
+
return 0;
|
|
20605
|
+
return;
|
|
20606
|
+
};
|
|
20607
|
+
var wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
|
|
20608
|
+
var wrapAnsiHyperlink = (url2) => `${ESC}${ANSI_ESCAPE_LINK}${url2}${ANSI_ESCAPE_BELL}`;
|
|
20609
|
+
var wrapWord = (rows, word, columns) => {
|
|
20610
|
+
const characters = word[Symbol.iterator]();
|
|
20611
|
+
let isInsideEscape = false;
|
|
20612
|
+
let isInsideLinkEscape = false;
|
|
20613
|
+
let lastRow = rows.at(-1);
|
|
20614
|
+
let visible = lastRow === undefined ? 0 : dist_default2(lastRow);
|
|
20615
|
+
let currentCharacter = characters.next();
|
|
20616
|
+
let nextCharacter = characters.next();
|
|
20617
|
+
let rawCharacterIndex = 0;
|
|
20618
|
+
while (!currentCharacter.done) {
|
|
20619
|
+
const character = currentCharacter.value;
|
|
20620
|
+
const characterLength = dist_default2(character);
|
|
20621
|
+
if (visible + characterLength <= columns) {
|
|
20622
|
+
rows[rows.length - 1] += character;
|
|
20623
|
+
} else {
|
|
20624
|
+
rows.push(character);
|
|
20625
|
+
visible = 0;
|
|
20626
|
+
}
|
|
20627
|
+
if (character === ESC || character === CSI) {
|
|
20628
|
+
isInsideEscape = true;
|
|
20629
|
+
isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
|
|
20630
|
+
}
|
|
20631
|
+
if (isInsideEscape) {
|
|
20632
|
+
if (isInsideLinkEscape) {
|
|
20633
|
+
if (character === ANSI_ESCAPE_BELL) {
|
|
20634
|
+
isInsideEscape = false;
|
|
20635
|
+
isInsideLinkEscape = false;
|
|
20636
|
+
}
|
|
20637
|
+
} else if (character === ANSI_SGR_TERMINATOR) {
|
|
20638
|
+
isInsideEscape = false;
|
|
20639
|
+
}
|
|
20640
|
+
} else {
|
|
20641
|
+
visible += characterLength;
|
|
20642
|
+
if (visible === columns && !nextCharacter.done) {
|
|
20643
|
+
rows.push("");
|
|
20644
|
+
visible = 0;
|
|
20645
|
+
}
|
|
20646
|
+
}
|
|
20647
|
+
currentCharacter = nextCharacter;
|
|
20648
|
+
nextCharacter = characters.next();
|
|
20649
|
+
rawCharacterIndex += character.length;
|
|
20650
|
+
}
|
|
20651
|
+
lastRow = rows.at(-1);
|
|
20652
|
+
if (!visible && lastRow !== undefined && lastRow.length && rows.length > 1) {
|
|
20653
|
+
rows[rows.length - 2] += rows.pop();
|
|
20654
|
+
}
|
|
20655
|
+
};
|
|
20656
|
+
var stringVisibleTrimSpacesRight = (string4) => {
|
|
20657
|
+
const words = string4.split(" ");
|
|
20658
|
+
let last = words.length;
|
|
20659
|
+
while (last) {
|
|
20660
|
+
if (dist_default2(words[last - 1])) {
|
|
20661
|
+
break;
|
|
20662
|
+
}
|
|
20663
|
+
last--;
|
|
20664
|
+
}
|
|
20665
|
+
if (last === words.length) {
|
|
20666
|
+
return string4;
|
|
20667
|
+
}
|
|
20668
|
+
return words.slice(0, last).join(" ") + words.slice(last).join("");
|
|
20669
|
+
};
|
|
20670
|
+
var exec = (string4, columns, options = {}) => {
|
|
20671
|
+
if (options.trim !== false && string4.trim() === "") {
|
|
20672
|
+
return "";
|
|
20673
|
+
}
|
|
20674
|
+
let returnValue = "";
|
|
20675
|
+
let escapeCode;
|
|
20676
|
+
let escapeUrl;
|
|
20677
|
+
const words = string4.split(" ");
|
|
20678
|
+
let rows = [""];
|
|
20679
|
+
let rowLength = 0;
|
|
20680
|
+
for (let index = 0;index < words.length; index++) {
|
|
20681
|
+
const word = words[index];
|
|
20682
|
+
if (options.trim !== false) {
|
|
20683
|
+
const row = rows.at(-1) ?? "";
|
|
20684
|
+
const trimmed = row.trimStart();
|
|
20685
|
+
if (row.length !== trimmed.length) {
|
|
20686
|
+
rows[rows.length - 1] = trimmed;
|
|
20687
|
+
rowLength = dist_default2(trimmed);
|
|
20688
|
+
}
|
|
20689
|
+
}
|
|
20690
|
+
if (index !== 0) {
|
|
20691
|
+
if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
|
|
20692
|
+
rows.push("");
|
|
20693
|
+
rowLength = 0;
|
|
20694
|
+
}
|
|
20695
|
+
if (rowLength || options.trim === false) {
|
|
20696
|
+
rows[rows.length - 1] += " ";
|
|
20697
|
+
rowLength++;
|
|
20698
|
+
}
|
|
20699
|
+
}
|
|
20700
|
+
const wordLength = dist_default2(word);
|
|
20701
|
+
if (options.hard && wordLength > columns) {
|
|
20702
|
+
const remainingColumns = columns - rowLength;
|
|
20703
|
+
const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
|
|
20704
|
+
const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
|
|
20705
|
+
if (breaksStartingNextLine < breaksStartingThisLine) {
|
|
20706
|
+
rows.push("");
|
|
20707
|
+
}
|
|
20708
|
+
wrapWord(rows, word, columns);
|
|
20709
|
+
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
20710
|
+
continue;
|
|
20711
|
+
}
|
|
20712
|
+
if (rowLength + wordLength > columns && rowLength && wordLength) {
|
|
20713
|
+
if (options.wordWrap === false && rowLength < columns) {
|
|
20714
|
+
wrapWord(rows, word, columns);
|
|
20715
|
+
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
20716
|
+
continue;
|
|
20717
|
+
}
|
|
20718
|
+
rows.push("");
|
|
20719
|
+
rowLength = 0;
|
|
20720
|
+
}
|
|
20721
|
+
if (rowLength + wordLength > columns && options.wordWrap === false) {
|
|
20722
|
+
wrapWord(rows, word, columns);
|
|
20723
|
+
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
20724
|
+
continue;
|
|
20725
|
+
}
|
|
20726
|
+
rows[rows.length - 1] += word;
|
|
20727
|
+
rowLength += wordLength;
|
|
20728
|
+
}
|
|
20729
|
+
if (options.trim !== false) {
|
|
20730
|
+
rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
|
|
20731
|
+
}
|
|
20732
|
+
const preString = rows.join(`
|
|
20733
|
+
`);
|
|
20734
|
+
let inSurrogate = false;
|
|
20735
|
+
for (let i2 = 0;i2 < preString.length; i2++) {
|
|
20736
|
+
const character = preString[i2];
|
|
20737
|
+
returnValue += character;
|
|
20738
|
+
if (!inSurrogate) {
|
|
20739
|
+
inSurrogate = character >= "\uD800" && character <= "\uDBFF";
|
|
20740
|
+
if (inSurrogate) {
|
|
20741
|
+
continue;
|
|
20742
|
+
}
|
|
20743
|
+
} else {
|
|
20744
|
+
inSurrogate = false;
|
|
20745
|
+
}
|
|
20746
|
+
if (character === ESC || character === CSI) {
|
|
20747
|
+
GROUP_REGEX.lastIndex = i2 + 1;
|
|
20748
|
+
const groupsResult = GROUP_REGEX.exec(preString);
|
|
20749
|
+
const groups = groupsResult?.groups;
|
|
20750
|
+
if (groups?.code !== undefined) {
|
|
20751
|
+
const code = Number.parseFloat(groups.code);
|
|
20752
|
+
escapeCode = code === END_CODE ? undefined : code;
|
|
20753
|
+
} else if (groups?.uri !== undefined) {
|
|
20754
|
+
escapeUrl = groups.uri.length === 0 ? undefined : groups.uri;
|
|
20755
|
+
}
|
|
20756
|
+
}
|
|
20757
|
+
if (preString[i2 + 1] === `
|
|
20758
|
+
`) {
|
|
20759
|
+
if (escapeUrl) {
|
|
20760
|
+
returnValue += wrapAnsiHyperlink("");
|
|
20761
|
+
}
|
|
20762
|
+
const closingCode = escapeCode ? getClosingCode(escapeCode) : undefined;
|
|
20763
|
+
if (escapeCode && closingCode) {
|
|
20764
|
+
returnValue += wrapAnsiCode(closingCode);
|
|
20765
|
+
}
|
|
20766
|
+
} else if (character === `
|
|
20767
|
+
`) {
|
|
20768
|
+
if (escapeCode && getClosingCode(escapeCode)) {
|
|
20769
|
+
returnValue += wrapAnsiCode(escapeCode);
|
|
20770
|
+
}
|
|
20771
|
+
if (escapeUrl) {
|
|
20772
|
+
returnValue += wrapAnsiHyperlink(escapeUrl);
|
|
20773
|
+
}
|
|
20774
|
+
}
|
|
20775
|
+
}
|
|
20776
|
+
return returnValue;
|
|
20777
|
+
};
|
|
20778
|
+
var CRLF_OR_LF = /\r?\n/;
|
|
20779
|
+
function wrapAnsi(string4, columns, options) {
|
|
20780
|
+
return String(string4).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join(`
|
|
20781
|
+
`);
|
|
20156
20782
|
}
|
|
20157
|
-
|
|
20158
|
-
|
|
20159
|
-
|
|
20160
|
-
|
|
20161
|
-
|
|
20162
|
-
|
|
20163
|
-
|
|
20164
|
-
|
|
20165
|
-
|
|
20166
|
-
|
|
20167
|
-
|
|
20168
|
-
|
|
20169
|
-
|
|
20170
|
-
|
|
20171
|
-
|
|
20172
|
-
|
|
20173
|
-
|
|
20174
|
-
|
|
20175
|
-
}
|
|
20176
|
-
|
|
20177
|
-
|
|
20178
|
-
|
|
20179
|
-
|
|
20180
|
-
|
|
20181
|
-
|
|
20182
|
-
|
|
20183
|
-
|
|
20184
|
-
|
|
20185
|
-
|
|
20186
|
-
|
|
20187
|
-
|
|
20188
|
-
|
|
20189
|
-
|
|
20783
|
+
|
|
20784
|
+
// node_modules/@clack/core/dist/index.mjs
|
|
20785
|
+
var import_sisteransi = __toESM(require_src(), 1);
|
|
20786
|
+
import { ReadStream as O3 } from "tty";
|
|
20787
|
+
function f3(r3, t2, s2) {
|
|
20788
|
+
if (!s2.some((o3) => !o3.disabled))
|
|
20789
|
+
return r3;
|
|
20790
|
+
const e2 = r3 + t2, i2 = Math.max(s2.length - 1, 0), n2 = e2 < 0 ? i2 : e2 > i2 ? 0 : e2;
|
|
20791
|
+
return s2[n2].disabled ? f3(n2, t2 < 0 ? -1 : 1, s2) : n2;
|
|
20792
|
+
}
|
|
20793
|
+
function I3(r3, t2, s2, e2) {
|
|
20794
|
+
const i2 = e2.split(`
|
|
20795
|
+
`);
|
|
20796
|
+
let n2 = 0, o3 = r3;
|
|
20797
|
+
for (const a2 of i2) {
|
|
20798
|
+
if (o3 <= a2.length)
|
|
20799
|
+
break;
|
|
20800
|
+
o3 -= a2.length + 1, n2++;
|
|
20801
|
+
}
|
|
20802
|
+
for (n2 = Math.max(0, Math.min(i2.length - 1, n2 + s2)), o3 = Math.min(o3, i2[n2].length) + t2;o3 < 0 && n2 > 0; )
|
|
20803
|
+
n2--, o3 += i2[n2].length + 1;
|
|
20804
|
+
for (;o3 > i2[n2].length && n2 < i2.length - 1; )
|
|
20805
|
+
o3 -= i2[n2].length + 1, n2++;
|
|
20806
|
+
o3 = Math.max(0, Math.min(i2[n2].length, o3));
|
|
20807
|
+
let u3 = 0;
|
|
20808
|
+
for (let a2 = 0;a2 < n2; a2++)
|
|
20809
|
+
u3 += i2[a2].length + 1;
|
|
20810
|
+
return u3 + o3;
|
|
20811
|
+
}
|
|
20812
|
+
var K = ["up", "down", "left", "right", "space", "enter", "cancel"];
|
|
20813
|
+
var j = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
20814
|
+
var h2 = { actions: new Set(K), aliases: new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["\x03", "cancel"], ["escape", "cancel"]]), messages: { cancel: "Canceled", error: "Something went wrong" }, withGuide: true, date: { monthNames: [...j], messages: { required: "Please enter a valid date", invalidMonth: "There are only 12 months in a year", invalidDay: (r3, t2) => `There are only ${r3} days in ${t2}`, afterMin: (r3) => `Date must be on or after ${r3.toISOString().slice(0, 10)}`, beforeMax: (r3) => `Date must be on or before ${r3.toISOString().slice(0, 10)}` } } };
|
|
20815
|
+
function C3(r3, t2) {
|
|
20816
|
+
if (typeof r3 == "string")
|
|
20817
|
+
return h2.aliases.get(r3) === t2;
|
|
20818
|
+
for (const s2 of r3)
|
|
20819
|
+
if (s2 !== undefined && C3(s2, t2))
|
|
20820
|
+
return true;
|
|
20821
|
+
return false;
|
|
20822
|
+
}
|
|
20823
|
+
function Y2(r3, t2) {
|
|
20824
|
+
if (r3 === t2)
|
|
20825
|
+
return;
|
|
20826
|
+
const s2 = r3.split(`
|
|
20827
|
+
`), e2 = t2.split(`
|
|
20828
|
+
`), i2 = Math.max(s2.length, e2.length), n2 = [];
|
|
20829
|
+
for (let o3 = 0;o3 < i2; o3++)
|
|
20830
|
+
s2[o3] !== e2[o3] && n2.push(o3);
|
|
20831
|
+
return { lines: n2, numLinesBefore: s2.length, numLinesAfter: e2.length, numLines: i2 };
|
|
20832
|
+
}
|
|
20833
|
+
var q2 = globalThis.process.platform.startsWith("win");
|
|
20834
|
+
var k2 = Symbol("clack:cancel");
|
|
20835
|
+
function R3(r3) {
|
|
20836
|
+
return r3 === k2;
|
|
20837
|
+
}
|
|
20838
|
+
function w2(r3, t2) {
|
|
20839
|
+
const s2 = r3;
|
|
20840
|
+
s2.isTTY && s2.setRawMode(t2);
|
|
20841
|
+
}
|
|
20842
|
+
function W2({ input: r3 = D2, output: t2 = x2, overwrite: s2 = true, hideCursor: e2 = true } = {}) {
|
|
20843
|
+
const i2 = b2.createInterface({ input: r3, output: t2, prompt: "", tabSize: 1 });
|
|
20844
|
+
b2.emitKeypressEvents(r3, i2), r3 instanceof O3 && r3.isTTY && r3.setRawMode(true);
|
|
20845
|
+
const n2 = (o3, { name: u3, sequence: a2 }) => {
|
|
20846
|
+
const l2 = String(o3);
|
|
20847
|
+
if (C3([l2, u3, a2], "cancel")) {
|
|
20848
|
+
e2 && t2.write(import_sisteransi.cursor.show), process.exit(0);
|
|
20849
|
+
return;
|
|
20850
|
+
}
|
|
20851
|
+
if (!s2)
|
|
20852
|
+
return;
|
|
20853
|
+
const c3 = u3 === "return" ? 0 : -1, y3 = u3 === "return" ? -1 : 0;
|
|
20854
|
+
b2.moveCursor(t2, c3, y3, () => {
|
|
20855
|
+
b2.clearLine(t2, 1, () => {
|
|
20856
|
+
r3.once("keypress", n2);
|
|
20857
|
+
});
|
|
20858
|
+
});
|
|
20859
|
+
};
|
|
20860
|
+
return e2 && t2.write(import_sisteransi.cursor.hide), r3.once("keypress", n2), () => {
|
|
20861
|
+
r3.off("keypress", n2), e2 && t2.write(import_sisteransi.cursor.show), r3 instanceof O3 && r3.isTTY && !q2 && r3.setRawMode(false), i2.terminal = false, i2.close();
|
|
20862
|
+
};
|
|
20863
|
+
}
|
|
20864
|
+
var A3 = (r3) => ("columns" in r3) && typeof r3.columns == "number" ? r3.columns : 80;
|
|
20865
|
+
var L3 = (r3) => ("rows" in r3) && typeof r3.rows == "number" ? r3.rows : 20;
|
|
20866
|
+
function B2(r3, t2, s2, e2 = s2, i2 = s2, n2) {
|
|
20867
|
+
const o3 = A3(r3 ?? x2);
|
|
20868
|
+
return wrapAnsi(t2, o3 - s2.length, { hard: true, trim: false }).split(`
|
|
20869
|
+
`).map((u3, a2, l2) => {
|
|
20870
|
+
const c3 = n2 ? n2(u3, a2) : u3;
|
|
20871
|
+
return a2 === 0 ? `${e2}${c3}` : a2 === l2.length - 1 ? `${i2}${c3}` : `${s2}${c3}`;
|
|
20872
|
+
}).join(`
|
|
20873
|
+
`);
|
|
20874
|
+
}
|
|
20875
|
+
function P3(r3, t2) {
|
|
20876
|
+
if ("~standard" in r3) {
|
|
20877
|
+
const s2 = r3["~standard"].validate(t2);
|
|
20878
|
+
if (s2 instanceof Promise)
|
|
20879
|
+
throw new TypeError("Schema validation must be synchronous. Update `validate()` and remove any asynchronous logic.");
|
|
20880
|
+
return s2.issues?.at(0)?.message;
|
|
20881
|
+
}
|
|
20882
|
+
return r3(t2);
|
|
20883
|
+
}
|
|
20884
|
+
|
|
20885
|
+
class m2 {
|
|
20886
|
+
input;
|
|
20887
|
+
output;
|
|
20888
|
+
_abortSignal;
|
|
20889
|
+
rl;
|
|
20890
|
+
opts;
|
|
20891
|
+
_render;
|
|
20892
|
+
_track = false;
|
|
20893
|
+
_prevFrame = "";
|
|
20894
|
+
_subscribers = new Map;
|
|
20895
|
+
_cursor = 0;
|
|
20896
|
+
state = "initial";
|
|
20897
|
+
error = "";
|
|
20898
|
+
value;
|
|
20899
|
+
userInput = "";
|
|
20900
|
+
constructor(t2, s2 = true) {
|
|
20901
|
+
const { input: e2 = D2, output: i2 = x2, render: n2, signal: o3, ...u3 } = t2;
|
|
20902
|
+
this.opts = u3, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = n2.bind(this), this._track = s2, this._abortSignal = o3, this.input = e2, this.output = i2;
|
|
20903
|
+
}
|
|
20904
|
+
unsubscribe() {
|
|
20905
|
+
this._subscribers.clear();
|
|
20906
|
+
}
|
|
20907
|
+
setSubscriber(t2, s2) {
|
|
20908
|
+
const e2 = this._subscribers.get(t2) ?? [];
|
|
20909
|
+
e2.push(s2), this._subscribers.set(t2, e2);
|
|
20910
|
+
}
|
|
20911
|
+
on(t2, s2) {
|
|
20912
|
+
this.setSubscriber(t2, { cb: s2 });
|
|
20913
|
+
}
|
|
20914
|
+
once(t2, s2) {
|
|
20915
|
+
this.setSubscriber(t2, { cb: s2, once: true });
|
|
20916
|
+
}
|
|
20917
|
+
emit(t2, ...s2) {
|
|
20918
|
+
const e2 = this._subscribers.get(t2) ?? [], i2 = [];
|
|
20919
|
+
for (const n2 of e2)
|
|
20920
|
+
n2.cb(...s2), n2.once && i2.push(() => e2.splice(e2.indexOf(n2), 1));
|
|
20921
|
+
for (const n2 of i2)
|
|
20922
|
+
n2();
|
|
20923
|
+
}
|
|
20924
|
+
prompt() {
|
|
20925
|
+
return new Promise((t2) => {
|
|
20926
|
+
if (this._abortSignal) {
|
|
20927
|
+
if (this._abortSignal.aborted)
|
|
20928
|
+
return this.state = "cancel", this.close(), t2(k2);
|
|
20929
|
+
this._abortSignal.addEventListener("abort", () => {
|
|
20930
|
+
this.state = "cancel", this.close();
|
|
20931
|
+
}, { once: true });
|
|
20932
|
+
}
|
|
20933
|
+
this.rl = G3.createInterface({ input: this.input, tabSize: 2, prompt: "", escapeCodeTimeout: 50, terminal: true }), this.rl.prompt(), this.opts.initialUserInput !== undefined && this._setUserInput(this.opts.initialUserInput, true), this.input.on("keypress", this.onKeypress), w2(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
|
|
20934
|
+
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), w2(this.input, false), t2(this.value);
|
|
20935
|
+
}), this.once("cancel", () => {
|
|
20936
|
+
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), w2(this.input, false), t2(k2);
|
|
20937
|
+
});
|
|
20938
|
+
});
|
|
20939
|
+
}
|
|
20940
|
+
_isActionKey(t2, s2) {
|
|
20941
|
+
return t2 === "\t";
|
|
20942
|
+
}
|
|
20943
|
+
_shouldSubmit(t2, s2) {
|
|
20944
|
+
return true;
|
|
20945
|
+
}
|
|
20946
|
+
_setValue(t2) {
|
|
20947
|
+
this.value = t2, this.emit("value", this.value);
|
|
20948
|
+
}
|
|
20949
|
+
_setUserInput(t2, s2) {
|
|
20950
|
+
this.userInput = t2 ?? "", this.emit("userInput", this.userInput), s2 && this._track && this.rl && (this.rl.write(this.userInput), this._cursor = this.rl.cursor);
|
|
20951
|
+
}
|
|
20952
|
+
_clearUserInput() {
|
|
20953
|
+
this.rl?.write(null, { ctrl: true, name: "u" }), this._setUserInput("");
|
|
20954
|
+
}
|
|
20955
|
+
onKeypress(t2, s2) {
|
|
20956
|
+
if (this._track && s2.name !== "return" && (s2.name && this._isActionKey(t2, s2) && this.rl?.write(null, { ctrl: true, name: "h" }), this._cursor = this.rl?.cursor ?? 0, this._setUserInput(this.rl?.line)), this.state === "error" && (this.state = "active"), s2?.name && (!this._track && h2.aliases.has(s2.name) && this.emit("cursor", h2.aliases.get(s2.name)), h2.actions.has(s2.name) && this.emit("cursor", s2.name)), t2 && (t2.toLowerCase() === "y" || t2.toLowerCase() === "n") && this.emit("confirm", t2.toLowerCase() === "y"), this.emit("key", t2, s2), s2?.name === "return" && this._shouldSubmit(t2, s2)) {
|
|
20957
|
+
if (this.opts.validate) {
|
|
20958
|
+
const e2 = P3(this.opts.validate, this.value);
|
|
20959
|
+
e2 && (this.error = e2 instanceof Error ? e2.message : e2, this.state = "error", this.rl?.write(this.userInput));
|
|
20960
|
+
}
|
|
20961
|
+
this.state !== "error" && (this.state = "submit");
|
|
20962
|
+
}
|
|
20963
|
+
C3([t2, s2?.name, s2?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
|
|
20964
|
+
}
|
|
20965
|
+
close() {
|
|
20966
|
+
this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
|
|
20967
|
+
`), w2(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
|
|
20968
|
+
}
|
|
20969
|
+
restoreCursor() {
|
|
20970
|
+
const t2 = wrapAnsi(this._prevFrame, process.stdout.columns, { hard: true, trim: false }).split(`
|
|
20971
|
+
`).length - 1;
|
|
20972
|
+
this.output.write(import_sisteransi.cursor.move(-999, t2 * -1));
|
|
20973
|
+
}
|
|
20974
|
+
render() {
|
|
20975
|
+
const t2 = wrapAnsi(this._render(this) ?? "", process.stdout.columns, { hard: true, trim: false });
|
|
20976
|
+
if (t2 !== this._prevFrame) {
|
|
20977
|
+
if (this.state === "initial")
|
|
20978
|
+
this.output.write(import_sisteransi.cursor.hide);
|
|
20979
|
+
else {
|
|
20980
|
+
const s2 = Y2(this._prevFrame, t2), e2 = L3(this.output);
|
|
20981
|
+
if (this.restoreCursor(), s2) {
|
|
20982
|
+
const i2 = Math.max(0, s2.numLinesAfter - e2), n2 = Math.max(0, s2.numLinesBefore - e2);
|
|
20983
|
+
let o3 = s2.lines.find((u3) => u3 >= i2);
|
|
20984
|
+
if (o3 === undefined) {
|
|
20985
|
+
this._prevFrame = t2;
|
|
20986
|
+
return;
|
|
20987
|
+
}
|
|
20988
|
+
if (s2.lines.length === 1) {
|
|
20989
|
+
this.output.write(import_sisteransi.cursor.move(0, o3 - n2)), this.output.write(import_sisteransi.erase.lines(1));
|
|
20990
|
+
const u3 = t2.split(`
|
|
20991
|
+
`);
|
|
20992
|
+
this.output.write(u3[o3]), this._prevFrame = t2, this.output.write(import_sisteransi.cursor.move(0, u3.length - o3 - 1));
|
|
20993
|
+
return;
|
|
20994
|
+
} else if (s2.lines.length > 1) {
|
|
20995
|
+
if (i2 < n2)
|
|
20996
|
+
o3 = i2;
|
|
20997
|
+
else {
|
|
20998
|
+
const a2 = o3 - n2;
|
|
20999
|
+
a2 > 0 && this.output.write(import_sisteransi.cursor.move(0, a2));
|
|
21000
|
+
}
|
|
21001
|
+
this.output.write(import_sisteransi.erase.down());
|
|
21002
|
+
const u3 = t2.split(`
|
|
21003
|
+
`).slice(o3);
|
|
21004
|
+
this.output.write(u3.join(`
|
|
21005
|
+
`)), this._prevFrame = t2;
|
|
21006
|
+
return;
|
|
21007
|
+
}
|
|
21008
|
+
}
|
|
21009
|
+
this.output.write(import_sisteransi.erase.down());
|
|
21010
|
+
}
|
|
21011
|
+
this.output.write(t2), this.state === "initial" && (this.state = "active"), this._prevFrame = t2;
|
|
21012
|
+
}
|
|
21013
|
+
}
|
|
21014
|
+
}
|
|
21015
|
+
function J2(r3, t2) {
|
|
21016
|
+
if (r3 === undefined || t2.length === 0)
|
|
21017
|
+
return 0;
|
|
21018
|
+
const s2 = t2.findIndex((e2) => e2.value === r3);
|
|
21019
|
+
return s2 !== -1 ? s2 : 0;
|
|
21020
|
+
}
|
|
21021
|
+
function H(r3, t2) {
|
|
21022
|
+
return (t2.label ?? String(t2.value)).toLowerCase().includes(r3.toLowerCase());
|
|
21023
|
+
}
|
|
21024
|
+
function Q2(r3, t2) {
|
|
21025
|
+
if (t2)
|
|
21026
|
+
return r3 ? t2 : t2[0];
|
|
21027
|
+
}
|
|
21028
|
+
var X2 = class extends m2 {
|
|
21029
|
+
filteredOptions;
|
|
21030
|
+
multiple;
|
|
21031
|
+
isNavigating = false;
|
|
21032
|
+
selectedValues = [];
|
|
21033
|
+
focusedValue;
|
|
21034
|
+
#s = 0;
|
|
21035
|
+
#r = "";
|
|
21036
|
+
#t;
|
|
21037
|
+
#n;
|
|
21038
|
+
#u;
|
|
21039
|
+
get cursor() {
|
|
21040
|
+
return this.#s;
|
|
21041
|
+
}
|
|
21042
|
+
get userInputWithCursor() {
|
|
21043
|
+
if (!this.userInput)
|
|
21044
|
+
return v2(["inverse", "hidden"], "_");
|
|
21045
|
+
if (this._cursor >= this.userInput.length)
|
|
21046
|
+
return `${this.userInput}\u2588`;
|
|
21047
|
+
const t2 = this.userInput.slice(0, this._cursor), [s2, ...e2] = this.userInput.slice(this._cursor);
|
|
21048
|
+
return `${t2}${v2("inverse", s2)}${e2.join("")}`;
|
|
21049
|
+
}
|
|
21050
|
+
get options() {
|
|
21051
|
+
return typeof this.#n == "function" ? this.#n() : this.#n;
|
|
21052
|
+
}
|
|
21053
|
+
constructor(t2) {
|
|
21054
|
+
super(t2), this.#n = t2.options, this.#u = t2.placeholder;
|
|
21055
|
+
const s2 = this.options;
|
|
21056
|
+
this.filteredOptions = [...s2], this.multiple = t2.multiple === true, this.#t = typeof t2.options == "function" ? t2.filter : t2.filter ?? H;
|
|
21057
|
+
let e2;
|
|
21058
|
+
if (t2.initialValue && Array.isArray(t2.initialValue) ? this.multiple ? e2 = t2.initialValue : e2 = t2.initialValue.slice(0, 1) : !this.multiple && this.options.length > 0 && (e2 = [this.options[0].value]), e2)
|
|
21059
|
+
for (const i2 of e2) {
|
|
21060
|
+
const n2 = s2.findIndex((o3) => o3.value === i2);
|
|
21061
|
+
n2 !== -1 && (this.toggleSelected(i2), this.#s = n2);
|
|
21062
|
+
}
|
|
21063
|
+
this.focusedValue = this.options[this.#s]?.value, this.on("key", (i2, n2) => this.#e(i2, n2)), this.on("userInput", (i2) => this.#i(i2));
|
|
21064
|
+
}
|
|
21065
|
+
_isActionKey(t2, s2) {
|
|
21066
|
+
return t2 === "\t" || this.multiple && this.isNavigating && s2.name === "space" && t2 !== undefined && t2 !== "";
|
|
21067
|
+
}
|
|
21068
|
+
#e(t2, s2) {
|
|
21069
|
+
const e2 = s2.name === "up", i2 = s2.name === "down", n2 = s2.name === "return", o3 = this.userInput === "" || this.userInput === "\t", u3 = this.#u, a2 = this.options, l2 = u3 !== undefined && u3 !== "" && a2.some((c3) => !c3.disabled && (this.#t ? this.#t(u3, c3) : true));
|
|
21070
|
+
if (s2.name === "tab" && o3 && l2) {
|
|
21071
|
+
this.userInput === "\t" && this._clearUserInput(), this._setUserInput(u3, true), this.isNavigating = false;
|
|
21072
|
+
return;
|
|
21073
|
+
}
|
|
21074
|
+
e2 || i2 ? (this.#s = f3(this.#s, e2 ? -1 : 1, this.filteredOptions), this.focusedValue = this.filteredOptions[this.#s]?.value, this.multiple || (this.selectedValues = [this.focusedValue]), this.isNavigating = true) : n2 ? this.value = Q2(this.multiple, this.selectedValues) : this.multiple ? this.focusedValue !== undefined && (s2.name === "tab" || this.isNavigating && s2.name === "space") ? this.toggleSelected(this.focusedValue) : this.isNavigating = false : (this.focusedValue && (this.selectedValues = [this.focusedValue]), this.isNavigating = false);
|
|
21075
|
+
}
|
|
21076
|
+
deselectAll() {
|
|
21077
|
+
this.selectedValues = [];
|
|
21078
|
+
}
|
|
21079
|
+
toggleSelected(t2) {
|
|
21080
|
+
this.filteredOptions.length !== 0 && (this.multiple ? this.selectedValues.includes(t2) ? this.selectedValues = this.selectedValues.filter((s2) => s2 !== t2) : this.selectedValues = [...this.selectedValues, t2] : this.selectedValues = [t2]);
|
|
21081
|
+
}
|
|
21082
|
+
#i(t2) {
|
|
21083
|
+
if (t2 !== this.#r) {
|
|
21084
|
+
this.#r = t2;
|
|
21085
|
+
const s2 = this.options;
|
|
21086
|
+
t2 && this.#t ? this.filteredOptions = s2.filter((n2) => this.#t?.(t2, n2)) : this.filteredOptions = [...s2];
|
|
21087
|
+
const e2 = J2(this.focusedValue, this.filteredOptions);
|
|
21088
|
+
this.#s = f3(e2, 0, this.filteredOptions);
|
|
21089
|
+
const i2 = this.filteredOptions[this.#s];
|
|
21090
|
+
i2 && !i2.disabled ? this.focusedValue = i2.value : this.focusedValue = undefined, this.multiple || (this.focusedValue !== undefined ? this.toggleSelected(this.focusedValue) : this.deselectAll());
|
|
21091
|
+
}
|
|
21092
|
+
}
|
|
21093
|
+
};
|
|
21094
|
+
|
|
21095
|
+
class Z extends m2 {
|
|
21096
|
+
get cursor() {
|
|
21097
|
+
return this.value ? 0 : 1;
|
|
21098
|
+
}
|
|
21099
|
+
get _value() {
|
|
21100
|
+
return this.cursor === 0;
|
|
21101
|
+
}
|
|
21102
|
+
constructor(t2) {
|
|
21103
|
+
super(t2, false), this.value = !!t2.initialValue, this.on("userInput", () => {
|
|
21104
|
+
this.value = this._value;
|
|
21105
|
+
}), this.on("confirm", (s2) => {
|
|
21106
|
+
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = s2, this.state = "submit", this.close();
|
|
21107
|
+
}), this.on("cursor", () => {
|
|
21108
|
+
this.value = !this.value;
|
|
21109
|
+
});
|
|
21110
|
+
}
|
|
21111
|
+
}
|
|
21112
|
+
var tt = { Y: { type: "year", len: 4 }, M: { type: "month", len: 2 }, D: { type: "day", len: 2 } };
|
|
21113
|
+
function F3(r3) {
|
|
21114
|
+
return [...r3].map((t2) => tt[t2]);
|
|
21115
|
+
}
|
|
21116
|
+
function st(r3) {
|
|
21117
|
+
const t2 = new Intl.DateTimeFormat(r3, { year: "numeric", month: "2-digit", day: "2-digit" }).formatToParts(new Date(2000, 0, 15)), s2 = [];
|
|
21118
|
+
let e2 = "/";
|
|
21119
|
+
for (const i2 of t2)
|
|
21120
|
+
i2.type === "literal" ? e2 = i2.value.trim() || i2.value : (i2.type === "year" || i2.type === "month" || i2.type === "day") && s2.push({ type: i2.type, len: i2.type === "year" ? 4 : 2 });
|
|
21121
|
+
return { segments: s2, separator: e2 };
|
|
21122
|
+
}
|
|
21123
|
+
function $(r3) {
|
|
21124
|
+
return Number.parseInt((r3 || "0").replace(/_/g, "0"), 10) || 0;
|
|
21125
|
+
}
|
|
21126
|
+
function S3(r3) {
|
|
21127
|
+
return { year: $(r3.year), month: $(r3.month), day: $(r3.day) };
|
|
21128
|
+
}
|
|
21129
|
+
function U(r3, t2) {
|
|
21130
|
+
return new Date(r3 || 2001, t2 || 1, 0).getDate();
|
|
21131
|
+
}
|
|
21132
|
+
function N3(r3) {
|
|
21133
|
+
const { year: t2, month: s2, day: e2 } = S3(r3);
|
|
21134
|
+
if (!t2 || t2 < 0 || t2 > 9999 || !s2 || s2 < 1 || s2 > 12 || !e2 || e2 < 1)
|
|
21135
|
+
return;
|
|
21136
|
+
const i2 = new Date(Date.UTC(t2, s2 - 1, e2));
|
|
21137
|
+
if (!(i2.getUTCFullYear() !== t2 || i2.getUTCMonth() !== s2 - 1 || i2.getUTCDate() !== e2))
|
|
21138
|
+
return { year: t2, month: s2, day: e2 };
|
|
21139
|
+
}
|
|
21140
|
+
function E(r3) {
|
|
21141
|
+
const t2 = N3(r3);
|
|
21142
|
+
return t2 ? new Date(Date.UTC(t2.year, t2.month - 1, t2.day)) : undefined;
|
|
21143
|
+
}
|
|
21144
|
+
function et(r3, t2, s2, e2) {
|
|
21145
|
+
const i2 = s2 ? { year: s2.getUTCFullYear(), month: s2.getUTCMonth() + 1, day: s2.getUTCDate() } : null, n2 = e2 ? { year: e2.getUTCFullYear(), month: e2.getUTCMonth() + 1, day: e2.getUTCDate() } : null;
|
|
21146
|
+
return r3 === "year" ? { min: i2?.year ?? 1, max: n2?.year ?? 9999 } : r3 === "month" ? { min: i2 && t2.year === i2.year ? i2.month : 1, max: n2 && t2.year === n2.year ? n2.month : 12 } : { min: i2 && t2.year === i2.year && t2.month === i2.month ? i2.day : 1, max: n2 && t2.year === n2.year && t2.month === n2.month ? n2.day : U(t2.year, t2.month) };
|
|
21147
|
+
}
|
|
21148
|
+
|
|
21149
|
+
class it extends m2 {
|
|
21150
|
+
#s;
|
|
21151
|
+
#r;
|
|
21152
|
+
#t;
|
|
21153
|
+
#n;
|
|
21154
|
+
#u;
|
|
21155
|
+
#e = { segmentIndex: 0, positionInSegment: 0 };
|
|
21156
|
+
#i = true;
|
|
21157
|
+
#o = null;
|
|
21158
|
+
inlineError = "";
|
|
21159
|
+
get segmentCursor() {
|
|
21160
|
+
return { ...this.#e };
|
|
21161
|
+
}
|
|
21162
|
+
get segmentValues() {
|
|
21163
|
+
return { ...this.#t };
|
|
21164
|
+
}
|
|
21165
|
+
get segments() {
|
|
21166
|
+
return this.#s;
|
|
21167
|
+
}
|
|
21168
|
+
get separator() {
|
|
21169
|
+
return this.#r;
|
|
21170
|
+
}
|
|
21171
|
+
get formattedValue() {
|
|
21172
|
+
return this.#c(this.#t);
|
|
21173
|
+
}
|
|
21174
|
+
#c(t2) {
|
|
21175
|
+
return this.#s.map((s2) => t2[s2.type]).join(this.#r);
|
|
21176
|
+
}
|
|
21177
|
+
#a() {
|
|
21178
|
+
this._setUserInput(this.#c(this.#t)), this._setValue(E(this.#t) ?? undefined);
|
|
21179
|
+
}
|
|
21180
|
+
constructor(t2) {
|
|
21181
|
+
const s2 = t2.format ? { segments: F3(t2.format), separator: t2.separator ?? "/" } : st(t2.locale), e2 = t2.separator ?? s2.separator, i2 = t2.format ? F3(t2.format) : s2.segments, n2 = t2.initialValue ?? t2.defaultValue, o3 = n2 ? { year: String(n2.getUTCFullYear()).padStart(4, "0"), month: String(n2.getUTCMonth() + 1).padStart(2, "0"), day: String(n2.getUTCDate()).padStart(2, "0") } : { year: "____", month: "__", day: "__" }, u3 = i2.map((a2) => o3[a2.type]).join(e2);
|
|
21182
|
+
super({ ...t2, initialUserInput: u3 }, false), this.#s = i2, this.#r = e2, this.#t = o3, this.#n = t2.minDate, this.#u = t2.maxDate, this.#a(), this.on("cursor", (a2) => this.#d(a2)), this.on("key", (a2, l2) => this.#f(a2, l2)), this.on("finalize", () => this.#g(t2));
|
|
21183
|
+
}
|
|
21184
|
+
#h() {
|
|
21185
|
+
const t2 = Math.max(0, Math.min(this.#e.segmentIndex, this.#s.length - 1)), s2 = this.#s[t2];
|
|
21186
|
+
if (s2)
|
|
21187
|
+
return this.#e.positionInSegment = Math.max(0, Math.min(this.#e.positionInSegment, s2.len - 1)), { segment: s2, index: t2 };
|
|
21188
|
+
}
|
|
21189
|
+
#l(t2) {
|
|
21190
|
+
this.inlineError = "", this.#o = null;
|
|
21191
|
+
const s2 = this.#h();
|
|
21192
|
+
s2 && (this.#e.segmentIndex = Math.max(0, Math.min(this.#s.length - 1, s2.index + t2)), this.#e.positionInSegment = 0, this.#i = true);
|
|
21193
|
+
}
|
|
21194
|
+
#p(t2) {
|
|
21195
|
+
const s2 = this.#h();
|
|
21196
|
+
if (!s2)
|
|
21197
|
+
return;
|
|
21198
|
+
const { segment: e2 } = s2, i2 = this.#t[e2.type], n2 = !i2 || i2.replace(/_/g, "") === "", o3 = Number.parseInt((i2 || "0").replace(/_/g, "0"), 10) || 0, u3 = et(e2.type, S3(this.#t), this.#n, this.#u);
|
|
21199
|
+
let a2;
|
|
21200
|
+
n2 ? a2 = t2 === 1 ? u3.min : u3.max : a2 = Math.max(Math.min(u3.max, o3 + t2), u3.min), this.#t = { ...this.#t, [e2.type]: a2.toString().padStart(e2.len, "0") }, this.#i = true, this.#o = null, this.#a();
|
|
21201
|
+
}
|
|
21202
|
+
#d(t2) {
|
|
21203
|
+
if (t2)
|
|
21204
|
+
switch (t2) {
|
|
21205
|
+
case "right":
|
|
21206
|
+
return this.#l(1);
|
|
21207
|
+
case "left":
|
|
21208
|
+
return this.#l(-1);
|
|
21209
|
+
case "up":
|
|
21210
|
+
return this.#p(1);
|
|
21211
|
+
case "down":
|
|
21212
|
+
return this.#p(-1);
|
|
21213
|
+
}
|
|
21214
|
+
}
|
|
21215
|
+
#f(t2, s2) {
|
|
21216
|
+
if (s2?.name === "backspace" || s2?.sequence === "\x7F" || s2?.sequence === "\b" || t2 === "\x7F" || t2 === "\b") {
|
|
21217
|
+
this.inlineError = "";
|
|
21218
|
+
const e2 = this.#h();
|
|
21219
|
+
if (!e2)
|
|
21220
|
+
return;
|
|
21221
|
+
if (!this.#t[e2.segment.type].replace(/_/g, "")) {
|
|
21222
|
+
this.#l(-1);
|
|
21223
|
+
return;
|
|
21224
|
+
}
|
|
21225
|
+
this.#t[e2.segment.type] = "_".repeat(e2.segment.len), this.#i = true, this.#e.positionInSegment = 0, this.#a();
|
|
21226
|
+
return;
|
|
21227
|
+
}
|
|
21228
|
+
if (s2?.name === "tab") {
|
|
21229
|
+
this.inlineError = "";
|
|
21230
|
+
const e2 = this.#h();
|
|
21231
|
+
if (!e2)
|
|
21232
|
+
return;
|
|
21233
|
+
const i2 = s2.shift ? -1 : 1, n2 = e2.index + i2;
|
|
21234
|
+
n2 >= 0 && n2 < this.#s.length && (this.#e.segmentIndex = n2, this.#e.positionInSegment = 0, this.#i = true);
|
|
21235
|
+
return;
|
|
21236
|
+
}
|
|
21237
|
+
if (t2 && /^[0-9]$/.test(t2)) {
|
|
21238
|
+
const e2 = this.#h();
|
|
21239
|
+
if (!e2)
|
|
21240
|
+
return;
|
|
21241
|
+
const { segment: i2 } = e2, n2 = !this.#t[i2.type].replace(/_/g, "");
|
|
21242
|
+
if (this.#i && this.#o !== null && !n2) {
|
|
21243
|
+
const d2 = this.#o + t2, g3 = { ...this.#t, [i2.type]: d2 }, _3 = this.#m(g3, i2);
|
|
21244
|
+
if (_3) {
|
|
21245
|
+
this.inlineError = _3, this.#o = null, this.#i = false;
|
|
21246
|
+
return;
|
|
21247
|
+
}
|
|
21248
|
+
this.inlineError = "", this.#t[i2.type] = d2, this.#o = null, this.#i = false, this.#a(), e2.index < this.#s.length - 1 && (this.#e.segmentIndex = e2.index + 1, this.#e.positionInSegment = 0, this.#i = true);
|
|
21249
|
+
return;
|
|
21250
|
+
}
|
|
21251
|
+
this.#i && !n2 && (this.#t[i2.type] = "_".repeat(i2.len), this.#e.positionInSegment = 0), this.#i = false, this.#o = null;
|
|
21252
|
+
const o3 = this.#t[i2.type], u3 = o3.indexOf("_"), a2 = u3 >= 0 ? u3 : Math.min(this.#e.positionInSegment, i2.len - 1);
|
|
21253
|
+
if (a2 < 0 || a2 >= i2.len)
|
|
21254
|
+
return;
|
|
21255
|
+
let l2 = o3.slice(0, a2) + t2 + o3.slice(a2 + 1), c3 = false;
|
|
21256
|
+
if (a2 === 0 && o3 === "__" && (i2.type === "month" || i2.type === "day")) {
|
|
21257
|
+
const d2 = Number.parseInt(t2, 10);
|
|
21258
|
+
l2 = `0${t2}`, c3 = d2 <= (i2.type === "month" ? 1 : 2);
|
|
21259
|
+
}
|
|
21260
|
+
if (i2.type === "year" && (l2 = (o3.replace(/_/g, "") + t2).padStart(i2.len, "_")), !l2.includes("_")) {
|
|
21261
|
+
const d2 = { ...this.#t, [i2.type]: l2 }, g3 = this.#m(d2, i2);
|
|
21262
|
+
if (g3) {
|
|
21263
|
+
this.inlineError = g3;
|
|
21264
|
+
return;
|
|
21265
|
+
}
|
|
21266
|
+
}
|
|
21267
|
+
this.inlineError = "", this.#t[i2.type] = l2;
|
|
21268
|
+
const y3 = l2.includes("_") ? undefined : N3(this.#t);
|
|
21269
|
+
if (y3) {
|
|
21270
|
+
const { year: d2, month: g3 } = y3, _3 = U(d2, g3);
|
|
21271
|
+
this.#t = { year: String(Math.max(0, Math.min(9999, d2))).padStart(4, "0"), month: String(Math.max(1, Math.min(12, g3))).padStart(2, "0"), day: String(Math.max(1, Math.min(_3, y3.day))).padStart(2, "0") };
|
|
21272
|
+
}
|
|
21273
|
+
this.#a();
|
|
21274
|
+
const T3 = l2.indexOf("_");
|
|
21275
|
+
c3 ? (this.#i = true, this.#o = t2) : T3 >= 0 ? this.#e.positionInSegment = T3 : u3 >= 0 && e2.index < this.#s.length - 1 ? (this.#e.segmentIndex = e2.index + 1, this.#e.positionInSegment = 0, this.#i = true) : this.#e.positionInSegment = Math.min(a2 + 1, i2.len - 1);
|
|
21276
|
+
}
|
|
21277
|
+
}
|
|
21278
|
+
#m(t2, s2) {
|
|
21279
|
+
const { month: e2, day: i2 } = S3(t2);
|
|
21280
|
+
if (s2.type === "month" && (e2 < 0 || e2 > 12))
|
|
21281
|
+
return h2.date.messages.invalidMonth;
|
|
21282
|
+
if (s2.type === "day" && (i2 < 0 || i2 > 31))
|
|
21283
|
+
return h2.date.messages.invalidDay(31, "any month");
|
|
21284
|
+
}
|
|
21285
|
+
#g(t2) {
|
|
21286
|
+
const { year: s2, month: e2, day: i2 } = S3(this.#t);
|
|
21287
|
+
if (s2 && e2 && i2) {
|
|
21288
|
+
const n2 = U(s2, e2);
|
|
21289
|
+
this.#t = { ...this.#t, day: String(Math.min(i2, n2)).padStart(2, "0") };
|
|
21290
|
+
}
|
|
21291
|
+
this.value = E(this.#t) ?? t2.defaultValue ?? undefined;
|
|
21292
|
+
}
|
|
21293
|
+
}
|
|
21294
|
+
var rt = class extends m2 {
|
|
21295
|
+
options;
|
|
21296
|
+
cursor = 0;
|
|
21297
|
+
#s;
|
|
21298
|
+
getGroupItems(t2) {
|
|
21299
|
+
return this.options.filter((s2) => s2.group === t2);
|
|
21300
|
+
}
|
|
21301
|
+
isGroupSelected(t2) {
|
|
21302
|
+
const s2 = this.getGroupItems(t2), e2 = this.value;
|
|
21303
|
+
return e2 === undefined ? false : s2.every((i2) => e2.includes(i2.value));
|
|
21304
|
+
}
|
|
21305
|
+
toggleValue() {
|
|
21306
|
+
const t2 = this.options[this.cursor];
|
|
21307
|
+
if (this.value === undefined && (this.value = []), t2.group === true) {
|
|
21308
|
+
const s2 = t2.value, e2 = this.getGroupItems(s2);
|
|
21309
|
+
this.isGroupSelected(s2) ? this.value = this.value.filter((i2) => e2.findIndex((n2) => n2.value === i2) === -1) : this.value = [...this.value, ...e2.map((i2) => i2.value)], this.value = Array.from(new Set(this.value));
|
|
21310
|
+
} else {
|
|
21311
|
+
const s2 = this.value.includes(t2.value);
|
|
21312
|
+
this.value = s2 ? this.value.filter((e2) => e2 !== t2.value) : [...this.value, t2.value];
|
|
21313
|
+
}
|
|
21314
|
+
}
|
|
21315
|
+
constructor(t2) {
|
|
21316
|
+
super(t2, false);
|
|
21317
|
+
const { options: s2 } = t2;
|
|
21318
|
+
this.#s = t2.selectableGroups !== false, this.options = Object.entries(s2).flatMap(([e2, i2]) => [{ value: e2, group: true, label: e2 }, ...i2.map((n2) => ({ ...n2, group: e2 }))]), this.value = [...t2.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: e2 }) => e2 === t2.cursorAt), this.#s ? 0 : 1), this.on("cursor", (e2) => {
|
|
21319
|
+
switch (e2) {
|
|
21320
|
+
case "left":
|
|
21321
|
+
case "up": {
|
|
21322
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
21323
|
+
const i2 = this.options[this.cursor]?.group === true;
|
|
21324
|
+
!this.#s && i2 && (this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1);
|
|
21325
|
+
break;
|
|
21326
|
+
}
|
|
21327
|
+
case "down":
|
|
21328
|
+
case "right": {
|
|
21329
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
21330
|
+
const i2 = this.options[this.cursor]?.group === true;
|
|
21331
|
+
!this.#s && i2 && (this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1);
|
|
21332
|
+
break;
|
|
21333
|
+
}
|
|
21334
|
+
case "space":
|
|
21335
|
+
this.toggleValue();
|
|
21336
|
+
break;
|
|
21337
|
+
}
|
|
21338
|
+
});
|
|
21339
|
+
}
|
|
21340
|
+
};
|
|
21341
|
+
var nt = new Set(["up", "down", "left", "right"]);
|
|
21342
|
+
|
|
21343
|
+
class ot extends m2 {
|
|
21344
|
+
#s = false;
|
|
21345
|
+
#r;
|
|
21346
|
+
focused = "editor";
|
|
21347
|
+
get userInputWithCursor() {
|
|
21348
|
+
if (this.state === "submit")
|
|
21349
|
+
return this.userInput;
|
|
21350
|
+
const t2 = this.userInput;
|
|
21351
|
+
if (this.cursor >= t2.length)
|
|
21352
|
+
return `${t2}\u2588`;
|
|
21353
|
+
const s2 = t2.slice(0, this.cursor), e2 = t2[this.cursor], i2 = t2.slice(this.cursor + 1);
|
|
21354
|
+
return e2 === `
|
|
21355
|
+
` ? `${s2}\u2588
|
|
21356
|
+
${i2}` : `${s2}${v2("inverse", e2)}${i2}`;
|
|
21357
|
+
}
|
|
21358
|
+
get cursor() {
|
|
21359
|
+
return this._cursor;
|
|
21360
|
+
}
|
|
21361
|
+
#t(t2) {
|
|
21362
|
+
if (this.userInput.length === 0) {
|
|
21363
|
+
this._setUserInput(t2);
|
|
21364
|
+
return;
|
|
21365
|
+
}
|
|
21366
|
+
this._setUserInput(this.userInput.slice(0, this.cursor) + t2 + this.userInput.slice(this.cursor));
|
|
21367
|
+
}
|
|
21368
|
+
#n(t2) {
|
|
21369
|
+
const s2 = this.value ?? "";
|
|
21370
|
+
switch (t2) {
|
|
21371
|
+
case "up":
|
|
21372
|
+
this._cursor = I3(this._cursor, 0, -1, s2);
|
|
21373
|
+
return;
|
|
21374
|
+
case "down":
|
|
21375
|
+
this._cursor = I3(this._cursor, 0, 1, s2);
|
|
21376
|
+
return;
|
|
21377
|
+
case "left":
|
|
21378
|
+
this._cursor = I3(this._cursor, -1, 0, s2);
|
|
21379
|
+
return;
|
|
21380
|
+
case "right":
|
|
21381
|
+
this._cursor = I3(this._cursor, 1, 0, s2);
|
|
21382
|
+
return;
|
|
21383
|
+
}
|
|
21384
|
+
}
|
|
21385
|
+
_shouldSubmit(t2, s2) {
|
|
21386
|
+
if (this.#r)
|
|
21387
|
+
return this.focused === "submit" ? true : (this.#t(`
|
|
21388
|
+
`), this._cursor++, false);
|
|
21389
|
+
const e2 = this.#s;
|
|
21390
|
+
return this.#s = true, e2 ? (this.userInput[this.cursor - 1] === `
|
|
21391
|
+
` && (this._setUserInput(this.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)), this._cursor--), true) : (this.#t(`
|
|
21392
|
+
`), this._cursor++, false);
|
|
21393
|
+
}
|
|
21394
|
+
constructor(t2) {
|
|
21395
|
+
super(t2, false), this.#r = t2.showSubmit ?? false, this.on("key", (s2, e2) => {
|
|
21396
|
+
if (e2?.name && nt.has(e2.name)) {
|
|
21397
|
+
this.#n(e2.name);
|
|
21398
|
+
return;
|
|
21399
|
+
}
|
|
21400
|
+
if (s2 === "\t" && this.#r) {
|
|
21401
|
+
this.focused = this.focused === "editor" ? "submit" : "editor";
|
|
21402
|
+
return;
|
|
21403
|
+
}
|
|
21404
|
+
if (e2?.name !== "return") {
|
|
21405
|
+
if (this.#s = false, e2?.name === "backspace" && this.cursor > 0) {
|
|
21406
|
+
this._setUserInput(this.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)), this._cursor--;
|
|
21407
|
+
return;
|
|
21408
|
+
}
|
|
21409
|
+
if (e2?.name === "delete" && this.cursor < this.userInput.length) {
|
|
21410
|
+
this._setUserInput(this.userInput.slice(0, this.cursor) + this.userInput.slice(this.cursor + 1));
|
|
21411
|
+
return;
|
|
21412
|
+
}
|
|
21413
|
+
s2 && (this.#r && this.focused === "submit" && (this.focused = "editor"), this.#t(s2 ?? ""), this._cursor++);
|
|
21414
|
+
}
|
|
21415
|
+
}), this.on("userInput", (s2) => {
|
|
21416
|
+
this._setValue(s2);
|
|
21417
|
+
}), this.on("finalize", () => {
|
|
21418
|
+
this.value || (this.value = t2.defaultValue), this.value === undefined && (this.value = "");
|
|
21419
|
+
});
|
|
21420
|
+
}
|
|
21421
|
+
}
|
|
21422
|
+
class ht extends m2 {
|
|
21423
|
+
options;
|
|
21424
|
+
cursor = 0;
|
|
21425
|
+
get _selectedValue() {
|
|
21426
|
+
return this.options[this.cursor];
|
|
21427
|
+
}
|
|
21428
|
+
changeValue() {
|
|
21429
|
+
this.value = this._selectedValue.value;
|
|
21430
|
+
}
|
|
21431
|
+
constructor(t2) {
|
|
21432
|
+
super(t2, false), this.options = t2.options;
|
|
21433
|
+
const s2 = this.options.findIndex(({ value: i2 }) => i2 === t2.initialValue), e2 = s2 === -1 ? 0 : s2;
|
|
21434
|
+
this.cursor = this.options[e2].disabled ? f3(e2, 1, this.options) : e2, this.changeValue(), this.on("cursor", (i2) => {
|
|
21435
|
+
switch (i2) {
|
|
21436
|
+
case "left":
|
|
21437
|
+
case "up":
|
|
21438
|
+
this.cursor = f3(this.cursor, -1, this.options);
|
|
21439
|
+
break;
|
|
21440
|
+
case "down":
|
|
21441
|
+
case "right":
|
|
21442
|
+
this.cursor = f3(this.cursor, 1, this.options);
|
|
21443
|
+
break;
|
|
21444
|
+
}
|
|
21445
|
+
this.changeValue();
|
|
21446
|
+
});
|
|
21447
|
+
}
|
|
21448
|
+
}
|
|
21449
|
+
class ct extends m2 {
|
|
21450
|
+
get userInputWithCursor() {
|
|
21451
|
+
if (this.state === "submit")
|
|
21452
|
+
return this.userInput;
|
|
21453
|
+
const t2 = this.userInput;
|
|
21454
|
+
if (this.cursor >= t2.length)
|
|
21455
|
+
return `${this.userInput}\u2588`;
|
|
21456
|
+
const s2 = t2.slice(0, this.cursor), [e2, ...i2] = t2.slice(this.cursor);
|
|
21457
|
+
return `${s2}${v2("inverse", e2)}${i2.join("")}`;
|
|
21458
|
+
}
|
|
21459
|
+
get cursor() {
|
|
21460
|
+
return this._cursor;
|
|
21461
|
+
}
|
|
21462
|
+
constructor(t2) {
|
|
21463
|
+
super({ ...t2, initialUserInput: t2.initialUserInput ?? t2.initialValue }), this.on("userInput", (s2) => {
|
|
21464
|
+
this._setValue(s2);
|
|
21465
|
+
}), this.on("finalize", () => {
|
|
21466
|
+
this.value || (this.value = t2.defaultValue), this.value === undefined && (this.value = "");
|
|
21467
|
+
});
|
|
21468
|
+
}
|
|
21469
|
+
}
|
|
21470
|
+
|
|
21471
|
+
// node_modules/@clack/prompts/dist/index.mjs
|
|
21472
|
+
import { styleText as e2, stripVTControlCharacters as ot2 } from "util";
|
|
21473
|
+
import V3 from "process";
|
|
21474
|
+
var import_sisteransi2 = __toESM(require_src(), 1);
|
|
21475
|
+
function se() {
|
|
21476
|
+
return V3.platform !== "win32" ? V3.env.TERM !== "linux" : !!V3.env.CI || !!V3.env.WT_SESSION || !!V3.env.TERMINUS_SUBLIME || V3.env.ConEmuTask === "{cmd::Cmder}" || V3.env.TERM_PROGRAM === "Terminus-Sublime" || V3.env.TERM_PROGRAM === "vscode" || V3.env.TERM === "xterm-256color" || V3.env.TERM === "alacritty" || V3.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
21477
|
+
}
|
|
21478
|
+
var tt2 = se();
|
|
21479
|
+
var at2 = () => process.env.CI === "true";
|
|
21480
|
+
var w3 = (t2, i2) => tt2 ? t2 : i2;
|
|
21481
|
+
var _t = w3("\u25C6", "*");
|
|
21482
|
+
var ut2 = w3("\u25A0", "x");
|
|
21483
|
+
var lt2 = w3("\u25B2", "x");
|
|
21484
|
+
var H2 = w3("\u25C7", "o");
|
|
21485
|
+
var ct2 = w3("\u250C", "T");
|
|
21486
|
+
var $2 = w3("\u2502", "|");
|
|
21487
|
+
var x3 = w3("\u2514", "\u2014");
|
|
21488
|
+
var xt = w3("\u2510", "T");
|
|
21489
|
+
var Et = w3("\u2518", "\u2014");
|
|
21490
|
+
var z4 = w3("\u25CF", ">");
|
|
21491
|
+
var U2 = w3("\u25CB", " ");
|
|
21492
|
+
var et2 = w3("\u25FB", "[\u2022]");
|
|
21493
|
+
var K2 = w3("\u25FC", "[+]");
|
|
21494
|
+
var Y3 = w3("\u25FB", "[ ]");
|
|
21495
|
+
var Gt = w3("\u25AA", "\u2022");
|
|
21496
|
+
var st2 = w3("\u2500", "-");
|
|
21497
|
+
var $t = w3("\u256E", "+");
|
|
21498
|
+
var Mt = w3("\u251C", "+");
|
|
21499
|
+
var dt = w3("\u256F", "+");
|
|
21500
|
+
var ht2 = w3("\u2570", "+");
|
|
21501
|
+
var Ot = w3("\u256D", "+");
|
|
21502
|
+
var pt = w3("\u25CF", "\u2022");
|
|
21503
|
+
var mt = w3("\u25C6", "*");
|
|
21504
|
+
var gt = w3("\u25B2", "!");
|
|
21505
|
+
var yt = w3("\u25A0", "x");
|
|
21506
|
+
var P4 = (t2) => {
|
|
21507
|
+
switch (t2) {
|
|
21508
|
+
case "initial":
|
|
21509
|
+
case "active":
|
|
21510
|
+
return e2("cyan", _t);
|
|
21511
|
+
case "cancel":
|
|
21512
|
+
return e2("red", ut2);
|
|
21513
|
+
case "error":
|
|
21514
|
+
return e2("yellow", lt2);
|
|
21515
|
+
case "submit":
|
|
21516
|
+
return e2("green", H2);
|
|
21517
|
+
}
|
|
21518
|
+
};
|
|
21519
|
+
var ft = (t2) => {
|
|
21520
|
+
switch (t2) {
|
|
21521
|
+
case "initial":
|
|
21522
|
+
case "active":
|
|
21523
|
+
return e2("cyan", $2);
|
|
21524
|
+
case "cancel":
|
|
21525
|
+
return e2("red", $2);
|
|
21526
|
+
case "error":
|
|
21527
|
+
return e2("yellow", $2);
|
|
21528
|
+
case "submit":
|
|
21529
|
+
return e2("green", $2);
|
|
21530
|
+
}
|
|
21531
|
+
};
|
|
21532
|
+
var Pt = (t2, i2, s2, r3, u3, n2 = false) => {
|
|
21533
|
+
let a2 = i2, c3 = 0;
|
|
21534
|
+
if (n2)
|
|
21535
|
+
for (let o3 = r3 - 1;o3 >= s2 && (a2 -= t2[o3].length, c3++, !(a2 <= u3)); o3--)
|
|
21536
|
+
;
|
|
21537
|
+
else
|
|
21538
|
+
for (let o3 = s2;o3 < r3 && (a2 -= t2[o3].length, c3++, !(a2 <= u3)); o3++)
|
|
21539
|
+
;
|
|
21540
|
+
return { lineCount: a2, removals: c3 };
|
|
21541
|
+
};
|
|
21542
|
+
var F4 = ({ cursor: t2, options: i2, style: s2, output: r3 = process.stdout, maxItems: u3 = Number.POSITIVE_INFINITY, columnPadding: n2 = 0, rowPadding: a2 = 4 }) => {
|
|
21543
|
+
const c3 = A3(r3) - n2, o3 = L3(r3), l2 = e2("dim", "..."), d2 = Math.max(o3 - a2, 0), g3 = Math.max(Math.min(u3, d2), 5);
|
|
21544
|
+
let p2 = 0;
|
|
21545
|
+
t2 >= g3 - 3 && (p2 = Math.max(Math.min(t2 - g3 + 3, i2.length - g3), 0));
|
|
21546
|
+
let f4 = g3 < i2.length && p2 > 0, h3 = g3 < i2.length && p2 + g3 < i2.length;
|
|
21547
|
+
const I4 = Math.min(p2 + g3, i2.length), m3 = [];
|
|
21548
|
+
let y3 = 0;
|
|
21549
|
+
f4 && y3++, h3 && y3++;
|
|
21550
|
+
const v3 = p2 + (f4 ? 1 : 0), C4 = I4 - (h3 ? 1 : 0);
|
|
21551
|
+
for (let b3 = v3;b3 < C4; b3++) {
|
|
21552
|
+
const G4 = wrapAnsi(s2(i2[b3], b3 === t2), c3, { hard: true, trim: false }).split(`
|
|
21553
|
+
`);
|
|
21554
|
+
m3.push(G4), y3 += G4.length;
|
|
21555
|
+
}
|
|
21556
|
+
if (y3 > d2) {
|
|
21557
|
+
let b3 = 0, G4 = 0, M = y3;
|
|
21558
|
+
const N4 = t2 - v3;
|
|
21559
|
+
let O4 = d2;
|
|
21560
|
+
const j2 = () => Pt(m3, M, 0, N4, O4), k3 = () => Pt(m3, M, N4 + 1, m3.length, O4, true);
|
|
21561
|
+
f4 ? ({ lineCount: M, removals: b3 } = j2(), M > O4 && (h3 || (O4 -= 1), { lineCount: M, removals: G4 } = k3())) : (h3 || (O4 -= 1), { lineCount: M, removals: G4 } = k3(), M > O4 && (O4 -= 1, { lineCount: M, removals: b3 } = j2())), b3 > 0 && (f4 = true, m3.splice(0, b3)), G4 > 0 && (h3 = true, m3.splice(m3.length - G4, G4));
|
|
21562
|
+
}
|
|
21563
|
+
const S4 = [];
|
|
21564
|
+
f4 && S4.push(l2);
|
|
21565
|
+
for (const b3 of m3)
|
|
21566
|
+
for (const G4 of b3)
|
|
21567
|
+
S4.push(G4);
|
|
21568
|
+
return h3 && S4.push(l2), S4;
|
|
21569
|
+
};
|
|
21570
|
+
var le2 = (t2) => {
|
|
21571
|
+
const i2 = t2.active ?? "Yes", s2 = t2.inactive ?? "No";
|
|
21572
|
+
return new Z({ active: i2, inactive: s2, signal: t2.signal, input: t2.input, output: t2.output, initialValue: t2.initialValue ?? true, render() {
|
|
21573
|
+
const r3 = t2.withGuide ?? h2.withGuide, u3 = `${P4(this.state)} `, n2 = r3 ? `${e2("gray", $2)} ` : "", a2 = B2(t2.output, t2.message, n2, u3), c3 = `${r3 ? `${e2("gray", $2)}
|
|
21574
|
+
` : ""}${a2}
|
|
21575
|
+
`, o3 = this.value ? i2 : s2;
|
|
21576
|
+
switch (this.state) {
|
|
21577
|
+
case "submit": {
|
|
21578
|
+
const l2 = r3 ? `${e2("gray", $2)} ` : "";
|
|
21579
|
+
return `${c3}${l2}${e2("dim", o3)}`;
|
|
21580
|
+
}
|
|
21581
|
+
case "cancel": {
|
|
21582
|
+
const l2 = r3 ? `${e2("gray", $2)} ` : "";
|
|
21583
|
+
return `${c3}${l2}${e2(["strikethrough", "dim"], o3)}${r3 ? `
|
|
21584
|
+
${e2("gray", $2)}` : ""}`;
|
|
21585
|
+
}
|
|
21586
|
+
default: {
|
|
21587
|
+
const l2 = r3 ? `${e2("cyan", $2)} ` : "", d2 = r3 ? e2("cyan", x3) : "";
|
|
21588
|
+
return `${c3}${l2}${this.value ? `${e2("green", z4)} ${i2}` : `${e2("dim", U2)} ${e2("dim", i2)}`}${t2.vertical ? r3 ? `
|
|
21589
|
+
${e2("cyan", $2)} ` : `
|
|
21590
|
+
` : ` ${e2("dim", "/")} `}${this.value ? `${e2("dim", U2)} ${e2("dim", s2)}` : `${e2("green", z4)} ${s2}`}
|
|
21591
|
+
${d2}
|
|
21592
|
+
`;
|
|
21593
|
+
}
|
|
21594
|
+
}
|
|
21595
|
+
} }).prompt();
|
|
21596
|
+
};
|
|
21597
|
+
var ge = (t2 = "", i2) => {
|
|
21598
|
+
const s2 = i2?.output ?? process.stdout, r3 = i2?.withGuide ?? h2.withGuide ? `${e2("gray", x3)} ` : "";
|
|
21599
|
+
s2.write(`${r3}${e2("red", t2)}
|
|
21600
|
+
|
|
21601
|
+
`);
|
|
21602
|
+
};
|
|
21603
|
+
var ye2 = (t2 = "", i2) => {
|
|
21604
|
+
const s2 = i2?.output ?? process.stdout, r3 = i2?.withGuide ?? h2.withGuide ? `${e2("gray", ct2)} ` : "";
|
|
21605
|
+
s2.write(`${r3}${t2}
|
|
21606
|
+
`);
|
|
21607
|
+
};
|
|
21608
|
+
var fe2 = (t2 = "", i2) => {
|
|
21609
|
+
const s2 = i2?.output ?? process.stdout, r3 = i2?.withGuide ?? h2.withGuide ? `${e2("gray", $2)}
|
|
21610
|
+
${e2("gray", x3)} ` : "";
|
|
21611
|
+
s2.write(`${r3}${t2}
|
|
21612
|
+
|
|
21613
|
+
`);
|
|
21614
|
+
};
|
|
21615
|
+
var be = (t2) => e2("dim", t2);
|
|
21616
|
+
var Se = (t2, i2, s2) => {
|
|
21617
|
+
const r3 = { hard: true, trim: false }, u3 = wrapAnsi(t2, i2, r3).split(`
|
|
21618
|
+
`), n2 = u3.reduce((o3, l2) => Math.max(dist_default2(l2), o3), 0), a2 = u3.map(s2).reduce((o3, l2) => Math.max(dist_default2(l2), o3), 0), c3 = i2 - (a2 - n2);
|
|
21619
|
+
return wrapAnsi(t2, c3, r3);
|
|
21620
|
+
};
|
|
21621
|
+
var Ce = (t2 = "", i2 = "", s2) => {
|
|
21622
|
+
const r3 = s2?.output ?? V3.stdout, u3 = s2?.withGuide ?? h2.withGuide, n2 = s2?.format ?? be, a2 = ["", ...Se(t2, A3(r3) - 6, n2).split(`
|
|
21623
|
+
`).map(n2), ""], c3 = dist_default2(i2), o3 = Math.max(a2.reduce((p2, f4) => {
|
|
21624
|
+
const h3 = dist_default2(f4);
|
|
21625
|
+
return h3 > p2 ? h3 : p2;
|
|
21626
|
+
}, 0), c3) + 2, l2 = a2.map((p2) => `${e2("gray", $2)} ${p2}${" ".repeat(o3 - dist_default2(p2))}${e2("gray", $2)}`).join(`
|
|
21627
|
+
`), d2 = u3 ? `${e2("gray", $2)}
|
|
21628
|
+
` : "", g3 = u3 ? Mt : ht2;
|
|
21629
|
+
r3.write(`${d2}${e2("green", H2)} ${e2("reset", i2)} ${e2("gray", st2.repeat(Math.max(o3 - c3 - 1, 1)) + $t)}
|
|
21630
|
+
${l2}
|
|
21631
|
+
${e2("gray", g3 + st2.repeat(o3 + 2) + dt)}
|
|
21632
|
+
`);
|
|
21633
|
+
};
|
|
21634
|
+
var _e = (t2) => e2("magenta", t2);
|
|
21635
|
+
var vt = ({ indicator: t2 = "dots", onCancel: i2, output: s2 = process.stdout, cancelMessage: r3, errorMessage: u3, frames: n2 = tt2 ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"], delay: a2 = tt2 ? 80 : 120, signal: c3, ...o3 } = {}) => {
|
|
21636
|
+
const l2 = at2();
|
|
21637
|
+
let d2, g3, p2 = false, f4 = false, h3 = "", I4, m3 = performance.now();
|
|
21638
|
+
const y3 = A3(s2), v3 = o3?.styleFrame ?? _e, C4 = (_3) => {
|
|
21639
|
+
const A4 = _3 > 1 ? u3 ?? h2.messages.error : r3 ?? h2.messages.cancel;
|
|
21640
|
+
f4 = _3 === 1, p2 && (W3(A4, _3), f4 && typeof i2 == "function" && i2());
|
|
21641
|
+
}, S4 = () => C4(2), b3 = () => C4(1), G4 = () => {
|
|
21642
|
+
process.on("uncaughtExceptionMonitor", S4), process.on("unhandledRejection", S4), process.on("SIGINT", b3), process.on("SIGTERM", b3), process.on("exit", C4), c3 && c3.addEventListener("abort", b3);
|
|
21643
|
+
}, M = () => {
|
|
21644
|
+
process.removeListener("uncaughtExceptionMonitor", S4), process.removeListener("unhandledRejection", S4), process.removeListener("SIGINT", b3), process.removeListener("SIGTERM", b3), process.removeListener("exit", C4), c3 && c3.removeEventListener("abort", b3);
|
|
21645
|
+
}, N4 = () => {
|
|
21646
|
+
if (I4 === undefined)
|
|
21647
|
+
return;
|
|
21648
|
+
l2 && s2.write(`
|
|
21649
|
+
`);
|
|
21650
|
+
const _3 = wrapAnsi(I4, y3, { hard: true, trim: false }).split(`
|
|
21651
|
+
`);
|
|
21652
|
+
_3.length > 1 && s2.write(import_sisteransi2.cursor.up(_3.length - 1)), s2.write(import_sisteransi2.cursor.to(0)), s2.write(import_sisteransi2.erase.down());
|
|
21653
|
+
}, O4 = (_3) => _3.replace(/\.+$/, ""), j2 = (_3) => {
|
|
21654
|
+
const A4 = (performance.now() - _3) / 1000, L4 = Math.floor(A4 / 60), D3 = Math.floor(A4 % 60);
|
|
21655
|
+
return L4 > 0 ? `[${L4}m ${D3}s]` : `[${D3}s]`;
|
|
21656
|
+
}, k3 = o3.withGuide ?? h2.withGuide, rt2 = (_3 = "") => {
|
|
21657
|
+
p2 = true, d2 = W2({ output: s2 }), h3 = O4(_3), m3 = performance.now(), k3 && s2.write(`${e2("gray", $2)}
|
|
21658
|
+
`);
|
|
21659
|
+
let A4 = 0, L4 = 0;
|
|
21660
|
+
G4(), g3 = setInterval(() => {
|
|
21661
|
+
if (l2 && h3 === I4)
|
|
21662
|
+
return;
|
|
21663
|
+
N4(), I4 = h3;
|
|
21664
|
+
const D3 = v3(n2[A4]);
|
|
21665
|
+
let Z2;
|
|
21666
|
+
if (l2)
|
|
21667
|
+
Z2 = `${D3} ${h3}...`;
|
|
21668
|
+
else if (t2 === "timer")
|
|
21669
|
+
Z2 = `${D3} ${h3} ${j2(m3)}`;
|
|
21670
|
+
else {
|
|
21671
|
+
const Lt = ".".repeat(Math.floor(L4)).slice(0, 3);
|
|
21672
|
+
Z2 = `${D3} ${h3}${Lt}`;
|
|
21673
|
+
}
|
|
21674
|
+
const kt = wrapAnsi(Z2, y3, { hard: true, trim: false });
|
|
21675
|
+
s2.write(kt), A4 = A4 + 1 < n2.length ? A4 + 1 : 0, L4 = L4 < 4 ? L4 + 0.125 : 0;
|
|
21676
|
+
}, a2);
|
|
21677
|
+
}, W3 = (_3 = "", A4 = 0, L4 = false) => {
|
|
21678
|
+
if (!p2)
|
|
21679
|
+
return;
|
|
21680
|
+
p2 = false, clearInterval(g3), N4();
|
|
21681
|
+
const D3 = A4 === 0 ? e2("green", H2) : A4 === 1 ? e2("red", ut2) : e2("red", lt2);
|
|
21682
|
+
h3 = _3 ?? h3, L4 || (t2 === "timer" ? s2.write(`${D3} ${h3} ${j2(m3)}
|
|
21683
|
+
`) : s2.write(`${D3} ${h3}
|
|
21684
|
+
`)), M(), d2();
|
|
21685
|
+
};
|
|
21686
|
+
return { start: rt2, stop: (_3 = "") => W3(_3, 0), message: (_3 = "") => {
|
|
21687
|
+
h3 = O4(_3 ?? h3);
|
|
21688
|
+
}, cancel: (_3 = "") => W3(_3, 1), error: (_3 = "") => W3(_3, 2), clear: () => W3("", 0, true), get isCancelled() {
|
|
21689
|
+
return f4;
|
|
21690
|
+
} };
|
|
21691
|
+
};
|
|
21692
|
+
var Nt = { light: w3("\u2500", "-"), heavy: w3("\u2501", "="), block: w3("\u2588", "#") };
|
|
21693
|
+
var it2 = (t2, i2) => t2.includes(`
|
|
21694
|
+
`) ? t2.split(`
|
|
21695
|
+
`).map((s2) => i2(s2)).join(`
|
|
21696
|
+
`) : i2(t2);
|
|
21697
|
+
var Ee = (t2) => {
|
|
21698
|
+
const i2 = (s2, r3) => {
|
|
21699
|
+
const u3 = s2.label ?? String(s2.value);
|
|
21700
|
+
switch (r3) {
|
|
21701
|
+
case "disabled":
|
|
21702
|
+
return `${e2("gray", U2)} ${it2(u3, (n2) => e2("gray", n2))}${s2.hint ? ` ${e2("dim", `(${s2.hint ?? "disabled"})`)}` : ""}`;
|
|
21703
|
+
case "selected":
|
|
21704
|
+
return `${it2(u3, (n2) => e2("dim", n2))}`;
|
|
21705
|
+
case "active":
|
|
21706
|
+
return `${e2("green", z4)} ${u3}${s2.hint ? ` ${e2("dim", `(${s2.hint})`)}` : ""}`;
|
|
21707
|
+
case "cancelled":
|
|
21708
|
+
return `${it2(u3, (n2) => e2(["strikethrough", "dim"], n2))}`;
|
|
21709
|
+
default:
|
|
21710
|
+
return `${e2("dim", U2)} ${it2(u3, (n2) => e2("dim", n2))}`;
|
|
21711
|
+
}
|
|
21712
|
+
};
|
|
21713
|
+
return new ht({ options: t2.options, signal: t2.signal, input: t2.input, output: t2.output, initialValue: t2.initialValue, render() {
|
|
21714
|
+
const s2 = t2.withGuide ?? h2.withGuide, r3 = `${P4(this.state)} `, u3 = `${ft(this.state)} `, n2 = B2(t2.output, t2.message, u3, r3), a2 = `${s2 ? `${e2("gray", $2)}
|
|
21715
|
+
` : ""}${n2}
|
|
21716
|
+
`;
|
|
21717
|
+
switch (this.state) {
|
|
21718
|
+
case "submit": {
|
|
21719
|
+
const c3 = s2 ? `${e2("gray", $2)} ` : "", o3 = B2(t2.output, i2(this.options[this.cursor], "selected"), c3);
|
|
21720
|
+
return `${a2}${o3}`;
|
|
21721
|
+
}
|
|
21722
|
+
case "cancel": {
|
|
21723
|
+
const c3 = s2 ? `${e2("gray", $2)} ` : "", o3 = B2(t2.output, i2(this.options[this.cursor], "cancelled"), c3);
|
|
21724
|
+
return `${a2}${o3}${s2 ? `
|
|
21725
|
+
${e2("gray", $2)}` : ""}`;
|
|
21726
|
+
}
|
|
21727
|
+
default: {
|
|
21728
|
+
const c3 = s2 ? `${e2("cyan", $2)} ` : "", o3 = s2 ? e2("cyan", x3) : "", l2 = a2.split(`
|
|
21729
|
+
`).length, d2 = s2 ? 2 : 1;
|
|
21730
|
+
return `${a2}${c3}${F4({ output: t2.output, cursor: this.cursor, options: this.options, maxItems: t2.maxItems, columnPadding: c3.length, rowPadding: l2 + d2, style: (g3, p2) => i2(g3, g3.disabled ? "disabled" : p2 ? "active" : "inactive") }).join(`
|
|
21731
|
+
${c3}`)}
|
|
21732
|
+
${o3}
|
|
21733
|
+
`;
|
|
21734
|
+
}
|
|
21735
|
+
}
|
|
21736
|
+
} }).prompt();
|
|
21737
|
+
};
|
|
21738
|
+
var Bt = `${e2("gray", $2)} `;
|
|
21739
|
+
var Re = (t2) => new ct({ validate: t2.validate, placeholder: t2.placeholder, defaultValue: t2.defaultValue, initialValue: t2.initialValue, output: t2.output, signal: t2.signal, input: t2.input, render() {
|
|
21740
|
+
const i2 = t2?.withGuide ?? h2.withGuide, s2 = `${`${i2 ? `${e2("gray", $2)}
|
|
21741
|
+
` : ""}${P4(this.state)} `}${t2.message}
|
|
21742
|
+
`, r3 = t2.placeholder ? e2("inverse", t2.placeholder[0]) + e2("dim", t2.placeholder.slice(1)) : e2(["inverse", "hidden"], "_"), u3 = this.userInput ? this.userInputWithCursor : r3, n2 = this.value ?? "";
|
|
21743
|
+
switch (this.state) {
|
|
21744
|
+
case "error": {
|
|
21745
|
+
const a2 = this.error ? ` ${e2("yellow", this.error)}` : "", c3 = i2 ? `${e2("yellow", $2)} ` : "", o3 = i2 ? e2("yellow", x3) : "";
|
|
21746
|
+
return `${s2.trim()}
|
|
21747
|
+
${c3}${u3}
|
|
21748
|
+
${o3}${a2}
|
|
21749
|
+
`;
|
|
21750
|
+
}
|
|
21751
|
+
case "submit": {
|
|
21752
|
+
const a2 = n2 ? ` ${e2("dim", n2)}` : "", c3 = i2 ? e2("gray", $2) : "";
|
|
21753
|
+
return `${s2}${c3}${a2}`;
|
|
21754
|
+
}
|
|
21755
|
+
case "cancel": {
|
|
21756
|
+
const a2 = n2 ? ` ${e2(["strikethrough", "dim"], n2)}` : "", c3 = i2 ? e2("gray", $2) : "";
|
|
21757
|
+
return `${s2}${c3}${a2}${n2.trim() ? `
|
|
21758
|
+
${c3}` : ""}`;
|
|
21759
|
+
}
|
|
21760
|
+
default: {
|
|
21761
|
+
const a2 = i2 ? `${e2("cyan", $2)} ` : "", c3 = i2 ? e2("cyan", x3) : "";
|
|
21762
|
+
return `${s2}${a2}${u3}
|
|
21763
|
+
${c3}
|
|
21764
|
+
`;
|
|
21765
|
+
}
|
|
21766
|
+
}
|
|
21767
|
+
} }).prompt();
|
|
21768
|
+
|
|
21769
|
+
// src/cli/commands/config.ts
|
|
21770
|
+
var iso2 = (ms) => ms ? new Date(ms).toISOString() : "";
|
|
21771
|
+
var isTTY2 = () => process.stdout.isTTY && process.stdin.isTTY;
|
|
21772
|
+
function ask(label, def) {
|
|
21773
|
+
const suffix = def != null && def !== "" ? ` [${def}]` : "";
|
|
21774
|
+
const raw = globalThis.prompt(`${label}${suffix}:`);
|
|
21775
|
+
const val = (raw ?? "").trim();
|
|
21776
|
+
return val === "" && def != null ? def : val;
|
|
21777
|
+
}
|
|
21778
|
+
function flagOrAsk(flag, label) {
|
|
21779
|
+
if (typeof flag === "string" && flag !== "")
|
|
21780
|
+
return flag;
|
|
21781
|
+
if (isTTY2()) {
|
|
21782
|
+
const v3 = ask(label);
|
|
21783
|
+
if (v3)
|
|
21784
|
+
return v3;
|
|
21785
|
+
}
|
|
21786
|
+
throw new Error(`missing --${label}`);
|
|
21787
|
+
}
|
|
21788
|
+
function showConfig(db) {
|
|
21789
|
+
const cfg = getServerConfig(db);
|
|
21790
|
+
const peers = listPeers(db).map(peerView);
|
|
21791
|
+
print({ config: cfg, peers }, () => {
|
|
21792
|
+
const lines = [
|
|
21793
|
+
"server config:",
|
|
21794
|
+
` host: ${cfg.host}`,
|
|
21795
|
+
` port: ${cfg.port}`,
|
|
21796
|
+
` sync-interval: ${Math.round(cfg.syncIntervalMs / 1000)}s`,
|
|
21797
|
+
` auto-sync: ${cfg.autoSync}`,
|
|
21798
|
+
"",
|
|
21799
|
+
"peers:",
|
|
21800
|
+
peers.length ? table(peers) : " (none)"
|
|
21801
|
+
];
|
|
21802
|
+
return lines.join(`
|
|
21803
|
+
`);
|
|
21804
|
+
});
|
|
21805
|
+
}
|
|
21806
|
+
function peerView(p2) {
|
|
21807
|
+
return {
|
|
21808
|
+
url: p2.url,
|
|
21809
|
+
label: p2.label ?? "",
|
|
21810
|
+
enabled: p2.enabled ? "yes" : "no",
|
|
21811
|
+
status: p2.last_status ?? "",
|
|
21812
|
+
last_sync: iso2(p2.last_sync_at)
|
|
21813
|
+
};
|
|
21814
|
+
}
|
|
21815
|
+
function applySet(db, args) {
|
|
21816
|
+
const partial2 = {};
|
|
21817
|
+
if (typeof args.host === "string" && args.host !== "")
|
|
21818
|
+
partial2.host = args.host;
|
|
21819
|
+
if (args.port != null && args.port !== "")
|
|
21820
|
+
partial2.port = Number(args.port);
|
|
21821
|
+
if (args["sync-interval"] != null && args["sync-interval"] !== "")
|
|
21822
|
+
partial2.syncIntervalMs = parseDuration(String(args["sync-interval"]), 30000);
|
|
21823
|
+
if (args["auto-sync"] != null)
|
|
21824
|
+
partial2.autoSync = parseBool(args["auto-sync"]);
|
|
21825
|
+
const next = setServerConfig(db, partial2);
|
|
21826
|
+
print(next, () => `updated. (restart --server to apply host/port/interval changes)`);
|
|
21827
|
+
}
|
|
21828
|
+
function parseBool(v3) {
|
|
21829
|
+
if (typeof v3 === "boolean")
|
|
21830
|
+
return v3;
|
|
21831
|
+
const s2 = String(v3).trim().toLowerCase();
|
|
21832
|
+
return s2 === "1" || s2 === "true" || s2 === "yes" || s2 === "on";
|
|
21833
|
+
}
|
|
21834
|
+
async function peerDispatch(db, action, args) {
|
|
21835
|
+
const node = getNodeId(db);
|
|
21836
|
+
switch (action) {
|
|
21837
|
+
case "add": {
|
|
21838
|
+
const url2 = flagOrAsk(args.url, "url");
|
|
21839
|
+
const code = flagOrAsk(args.code, "code");
|
|
21840
|
+
const selfUrl = typeof args["self-url"] === "string" ? args["self-url"] : undefined;
|
|
21841
|
+
const r3 = await performPairing(db, node, url2, code, selfUrl);
|
|
21842
|
+
const sync = await syncPeer(db, url2);
|
|
21843
|
+
print({ paired: r3, sync }, () => `paired with ${r3.url} (node ${r3.node_id}); ${syncLine(sync)}`);
|
|
21844
|
+
return;
|
|
21845
|
+
}
|
|
21846
|
+
case "code": {
|
|
21847
|
+
const c3 = generatePairingCode(db);
|
|
21848
|
+
print(c3, () => `pairing code: ${c3.code}
|
|
21849
|
+
expires: ${iso2(c3.exp)}
|
|
21850
|
+
(redeem with: mh config peer add --url <this-server-url> --code ${c3.code})`);
|
|
21851
|
+
return;
|
|
21852
|
+
}
|
|
21853
|
+
case "list":
|
|
21854
|
+
print(listPeers(db).map(peerView), () => {
|
|
21855
|
+
const rows = listPeers(db).map(peerView);
|
|
21856
|
+
return rows.length ? table(rows) : "(no peers)";
|
|
21857
|
+
});
|
|
21858
|
+
return;
|
|
21859
|
+
case "rm": {
|
|
21860
|
+
const url2 = flagOrAsk(args.url, "url");
|
|
21861
|
+
print({ ok: removePeer(db, url2) }, () => `removed ${url2}`);
|
|
21862
|
+
return;
|
|
21863
|
+
}
|
|
21864
|
+
case "enable":
|
|
21865
|
+
case "disable": {
|
|
21866
|
+
const url2 = flagOrAsk(args.url, "url");
|
|
21867
|
+
setPeerEnabled(db, url2, action === "enable");
|
|
21868
|
+
print({ ok: true }, () => `${action}d ${url2}`);
|
|
21869
|
+
return;
|
|
21870
|
+
}
|
|
21871
|
+
case "sync": {
|
|
21872
|
+
if (typeof args.url === "string" && args.url !== "") {
|
|
21873
|
+
const r3 = await syncPeer(db, args.url);
|
|
21874
|
+
print(r3, () => syncLine(r3));
|
|
21875
|
+
} else {
|
|
21876
|
+
const r3 = await syncAllPeers(db);
|
|
21877
|
+
print(r3, () => r3.length ? r3.map(syncLine).join(`
|
|
21878
|
+
`) : "(no enabled peers)");
|
|
21879
|
+
}
|
|
21880
|
+
return;
|
|
21881
|
+
}
|
|
21882
|
+
default:
|
|
21883
|
+
throw new Error(`unknown peer action '${action}' (add|code|list|rm|enable|disable|sync)`);
|
|
21884
|
+
}
|
|
21885
|
+
}
|
|
21886
|
+
function syncLine(o3) {
|
|
21887
|
+
return o3.ok ? `${o3.url}: pushed ${o3.pushed}, pulled ${o3.pulled}` : `${o3.url}: error \u2014 ${o3.error}`;
|
|
21888
|
+
}
|
|
21889
|
+
var maskToken = (t2) => t2.length > 10 ? `${t2.slice(0, 8)}\u2026` : t2;
|
|
21890
|
+
function grantView(g3) {
|
|
21891
|
+
return {
|
|
21892
|
+
token: maskToken(g3.token),
|
|
21893
|
+
peer_url: g3.peer_url ?? "(unknown)",
|
|
21894
|
+
node_id: g3.node_id ?? "",
|
|
21895
|
+
issued: iso2(g3.created_at)
|
|
21896
|
+
};
|
|
21897
|
+
}
|
|
21898
|
+
function grantDispatch(db, action, args) {
|
|
21899
|
+
switch (action) {
|
|
21900
|
+
case "list": {
|
|
21901
|
+
const rows = listGrants(db).map(grantView);
|
|
21902
|
+
print(rows, () => rows.length ? table(rows) : "(no issued credentials)");
|
|
21903
|
+
return;
|
|
21904
|
+
}
|
|
21905
|
+
case "revoke": {
|
|
21906
|
+
const token = flagOrAsk(args.token, "token");
|
|
21907
|
+
const n2 = revokeGrant(db, token);
|
|
21908
|
+
print({ revoked: n2 }, () => n2 > 0 ? `revoked ${n2} credential(s)` : "no matching credential");
|
|
21909
|
+
return;
|
|
21910
|
+
}
|
|
21911
|
+
default:
|
|
21912
|
+
throw new Error(`unknown grant action '${action}' (list|revoke)`);
|
|
21913
|
+
}
|
|
21914
|
+
}
|
|
21915
|
+
var secs = (ms) => `${Math.round(ms / 1000)}s`;
|
|
21916
|
+
function cancelled(v3) {
|
|
21917
|
+
if (R3(v3)) {
|
|
21918
|
+
ge("\u5DF2\u53D6\u6D88");
|
|
21919
|
+
return true;
|
|
21920
|
+
}
|
|
21921
|
+
return false;
|
|
21922
|
+
}
|
|
21923
|
+
function peerChoices(peers) {
|
|
21924
|
+
return peers.map((pr) => ({
|
|
21925
|
+
value: pr.url,
|
|
21926
|
+
label: pr.label ? `${pr.label} (${pr.url})` : pr.url,
|
|
21927
|
+
hint: pr.enabled ? "enabled" : "disabled"
|
|
21928
|
+
}));
|
|
21929
|
+
}
|
|
21930
|
+
function grantChoices(grants) {
|
|
21931
|
+
return grants.map((g3) => ({
|
|
21932
|
+
value: g3.token,
|
|
21933
|
+
label: maskToken(g3.token),
|
|
21934
|
+
hint: g3.peer_url ?? "(unknown)"
|
|
21935
|
+
}));
|
|
21936
|
+
}
|
|
21937
|
+
function validatePort(s2) {
|
|
21938
|
+
const n2 = Number(s2);
|
|
21939
|
+
if (!Number.isInteger(n2) || n2 <= 0 || n2 > 65535)
|
|
21940
|
+
return "\u7AEF\u53E3\u5FC5\u987B\u662F 1-65535 \u7684\u6574\u6570";
|
|
21941
|
+
return;
|
|
21942
|
+
}
|
|
21943
|
+
function validateInterval(s2) {
|
|
21944
|
+
return parseDuration(s2, -1) > 0 ? undefined : "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u65F6\u957F (\u5982 30s, 5m)";
|
|
21945
|
+
}
|
|
21946
|
+
var required2 = (v3) => v3 && v3.trim() ? undefined : "\u5FC5\u586B";
|
|
21947
|
+
async function serverWizard(db) {
|
|
21948
|
+
const working = { ...getServerConfig(db) };
|
|
21949
|
+
for (;; ) {
|
|
21950
|
+
const field = await Ee({
|
|
21951
|
+
message: "\u670D\u52A1\u5668\u8BBE\u7F6E",
|
|
21952
|
+
options: [
|
|
21953
|
+
{ value: "host", label: "Host", hint: working.host },
|
|
21954
|
+
{ value: "port", label: "Port", hint: String(working.port) },
|
|
21955
|
+
{ value: "interval", label: "\u540C\u6B65\u95F4\u9694", hint: secs(working.syncIntervalMs) },
|
|
21956
|
+
{ value: "auto", label: "Auto-sync", hint: working.autoSync ? "on" : "off" },
|
|
21957
|
+
{ value: "save", label: "\u4FDD\u5B58\u5E76\u8FD4\u56DE" },
|
|
21958
|
+
{ value: "back", label: "\u8FD4\u56DE (\u653E\u5F03\u4FEE\u6539)" }
|
|
21959
|
+
]
|
|
21960
|
+
});
|
|
21961
|
+
if (cancelled(field) || field === "back")
|
|
21962
|
+
return;
|
|
21963
|
+
if (field === "save") {
|
|
21964
|
+
setServerConfig(db, working);
|
|
21965
|
+
Ce("restart --server to apply host/port/interval changes", "\u2713 \u5DF2\u4FDD\u5B58");
|
|
21966
|
+
return;
|
|
21967
|
+
}
|
|
21968
|
+
if (field === "host") {
|
|
21969
|
+
const v3 = await Re({ message: "Host", initialValue: working.host });
|
|
21970
|
+
if (cancelled(v3))
|
|
21971
|
+
return;
|
|
21972
|
+
working.host = v3;
|
|
21973
|
+
} else if (field === "port") {
|
|
21974
|
+
const v3 = await Re({ message: "Port", initialValue: String(working.port), validate: validatePort });
|
|
21975
|
+
if (cancelled(v3))
|
|
21976
|
+
return;
|
|
21977
|
+
working.port = Number(v3);
|
|
21978
|
+
} else if (field === "interval") {
|
|
21979
|
+
const v3 = await Re({ message: "\u540C\u6B65\u95F4\u9694 (\u5982 30s, 5m)", initialValue: secs(working.syncIntervalMs), validate: validateInterval });
|
|
21980
|
+
if (cancelled(v3))
|
|
21981
|
+
return;
|
|
21982
|
+
working.syncIntervalMs = parseDuration(v3, working.syncIntervalMs);
|
|
21983
|
+
} else if (field === "auto") {
|
|
21984
|
+
const v3 = await le2({ message: "\u542F\u7528 auto-sync?", initialValue: working.autoSync });
|
|
21985
|
+
if (cancelled(v3))
|
|
21986
|
+
return;
|
|
21987
|
+
working.autoSync = v3;
|
|
21988
|
+
}
|
|
21989
|
+
}
|
|
21990
|
+
}
|
|
21991
|
+
async function peerWizard(db) {
|
|
21992
|
+
const node = getNodeId(db);
|
|
21993
|
+
for (;; ) {
|
|
21994
|
+
const action = await Ee({
|
|
21995
|
+
message: "\u540C\u6B65\u8BBE\u5907",
|
|
21996
|
+
options: [
|
|
21997
|
+
{ value: "add", label: "\u6DFB\u52A0\u8BBE\u5907", hint: "\u5BF9\u65B9\u5730\u5740 + \u914D\u5BF9\u7801" },
|
|
21998
|
+
{ value: "code", label: "\u751F\u6210\u672C\u673A\u914D\u5BF9\u7801" },
|
|
21999
|
+
{ value: "list", label: "\u5217\u51FA\u8BBE\u5907" },
|
|
22000
|
+
{ value: "rm", label: "\u79FB\u9664\u8BBE\u5907" },
|
|
22001
|
+
{ value: "toggle", label: "\u542F\u7528 / \u7981\u7528\u8BBE\u5907" },
|
|
22002
|
+
{ value: "sync", label: "\u7ACB\u5373\u540C\u6B65\u5168\u90E8" },
|
|
22003
|
+
{ value: "back", label: "\u8FD4\u56DE" }
|
|
22004
|
+
]
|
|
22005
|
+
});
|
|
22006
|
+
if (cancelled(action) || action === "back")
|
|
22007
|
+
return;
|
|
22008
|
+
try {
|
|
22009
|
+
if (action === "add") {
|
|
22010
|
+
const url2 = await Re({ message: "\u5BF9\u65B9\u670D\u52A1\u5668\u5730\u5740", placeholder: "http://192.168.1.10:7777", validate: required2 });
|
|
22011
|
+
if (cancelled(url2))
|
|
22012
|
+
continue;
|
|
22013
|
+
const code = await Re({ message: "\u914D\u5BF9\u7801", validate: required2 });
|
|
22014
|
+
if (cancelled(code))
|
|
22015
|
+
continue;
|
|
22016
|
+
const selfUrl = await Re({ message: "\u672C\u673A\u53EF\u8FBE\u5730\u5740 (\u53EF\u9009, \u7559\u7A7A\u5219\u5355\u5411)" });
|
|
22017
|
+
if (cancelled(selfUrl))
|
|
22018
|
+
continue;
|
|
22019
|
+
const s2 = vt();
|
|
22020
|
+
s2.start("\u914D\u5BF9\u4E2D\u2026");
|
|
22021
|
+
try {
|
|
22022
|
+
const r3 = await performPairing(db, node, url2, code, selfUrl || undefined);
|
|
22023
|
+
const sync = await syncPeer(db, r3.url);
|
|
22024
|
+
s2.stop(`\u2713 \u5DF2\u914D\u5BF9 ${r3.url} (node ${r3.node_id})`);
|
|
22025
|
+
Ce(syncLine(sync), "\u540C\u6B65\u7ED3\u679C");
|
|
22026
|
+
} catch (e3) {
|
|
22027
|
+
s2.stop(`\u2717 ${e3.message}`);
|
|
22028
|
+
}
|
|
22029
|
+
} else if (action === "code") {
|
|
22030
|
+
const code = generatePairingCode(db);
|
|
22031
|
+
Ce(`\u914D\u5BF9\u7801: ${code.code}
|
|
22032
|
+
\u6709\u6548\u81F3: ${iso2(code.exp)}`, "\u672C\u673A\u914D\u5BF9\u7801");
|
|
22033
|
+
} else if (action === "list") {
|
|
22034
|
+
const rows = listPeers(db).map(peerView);
|
|
22035
|
+
Ce(rows.length ? table(rows) : "(\u65E0\u8BBE\u5907)", "\u8BBE\u5907\u5217\u8868");
|
|
22036
|
+
} else if (action === "rm") {
|
|
22037
|
+
const peers = listPeers(db);
|
|
22038
|
+
if (!peers.length) {
|
|
22039
|
+
Ce("(\u65E0\u8BBE\u5907)");
|
|
22040
|
+
continue;
|
|
22041
|
+
}
|
|
22042
|
+
const url2 = await Ee({ message: "\u9009\u62E9\u8981\u79FB\u9664\u7684\u8BBE\u5907", options: peerChoices(peers) });
|
|
22043
|
+
if (cancelled(url2))
|
|
22044
|
+
continue;
|
|
22045
|
+
Ce(removePeer(db, url2) ? `\u2713 \u5DF2\u79FB\u9664 ${url2}` : "\u672A\u627E\u5230\u8BE5\u8BBE\u5907");
|
|
22046
|
+
} else if (action === "toggle") {
|
|
22047
|
+
const peers = listPeers(db);
|
|
22048
|
+
if (!peers.length) {
|
|
22049
|
+
Ce("(\u65E0\u8BBE\u5907)");
|
|
22050
|
+
continue;
|
|
22051
|
+
}
|
|
22052
|
+
const url2 = await Ee({ message: "\u9009\u62E9\u8BBE\u5907", options: peerChoices(peers) });
|
|
22053
|
+
if (cancelled(url2))
|
|
22054
|
+
continue;
|
|
22055
|
+
const cur = peers.find((x4) => x4.url === url2);
|
|
22056
|
+
const en = await le2({ message: "\u542F\u7528\u8BE5\u8BBE\u5907?", initialValue: cur ? !!cur.enabled : true });
|
|
22057
|
+
if (cancelled(en))
|
|
22058
|
+
continue;
|
|
22059
|
+
setPeerEnabled(db, url2, en);
|
|
22060
|
+
Ce(`\u2713 ${en ? "\u5DF2\u542F\u7528" : "\u5DF2\u7981\u7528"} ${url2}`);
|
|
22061
|
+
} else if (action === "sync") {
|
|
22062
|
+
const s2 = vt();
|
|
22063
|
+
s2.start("\u540C\u6B65\u4E2D\u2026");
|
|
22064
|
+
const r3 = await syncAllPeers(db);
|
|
22065
|
+
s2.stop("\u540C\u6B65\u5B8C\u6210");
|
|
22066
|
+
Ce(r3.length ? r3.map(syncLine).join(`
|
|
22067
|
+
`) : "(\u65E0\u542F\u7528\u7684\u8BBE\u5907)", "\u540C\u6B65\u7ED3\u679C");
|
|
22068
|
+
}
|
|
22069
|
+
} catch (e3) {
|
|
22070
|
+
Ce(`\u2717 ${e3.message}`, "\u9519\u8BEF");
|
|
22071
|
+
}
|
|
22072
|
+
}
|
|
22073
|
+
}
|
|
22074
|
+
async function grantWizard(db) {
|
|
22075
|
+
for (;; ) {
|
|
22076
|
+
const grants = listGrants(db);
|
|
22077
|
+
Ce(grants.length ? table(grants.map(grantView)) : "(\u65E0\u5DF2\u7B7E\u53D1\u51ED\u636E)", "\u5DF2\u7B7E\u53D1\u51ED\u636E");
|
|
22078
|
+
if (!grants.length)
|
|
22079
|
+
return;
|
|
22080
|
+
const token = await Ee({
|
|
22081
|
+
message: "\u9009\u62E9\u8981\u540A\u9500\u7684\u51ED\u636E",
|
|
22082
|
+
options: [...grantChoices(grants), { value: "__back__", label: "\u8FD4\u56DE" }]
|
|
22083
|
+
});
|
|
22084
|
+
if (cancelled(token) || token === "__back__")
|
|
22085
|
+
return;
|
|
22086
|
+
const ok = await le2({ message: `\u786E\u8BA4\u540A\u9500 ${maskToken(token)}?`, initialValue: false });
|
|
22087
|
+
if (cancelled(ok) || !ok)
|
|
22088
|
+
continue;
|
|
22089
|
+
const n2 = revokeGrant(db, token);
|
|
22090
|
+
Ce(n2 > 0 ? `\u2713 \u5DF2\u540A\u9500 ${n2} \u6761` : "\u65E0\u5339\u914D\u51ED\u636E");
|
|
22091
|
+
}
|
|
22092
|
+
}
|
|
22093
|
+
async function wizard(db) {
|
|
22094
|
+
ye2("Metahub \u914D\u7F6E");
|
|
22095
|
+
for (;; ) {
|
|
22096
|
+
const choice = await Ee({
|
|
22097
|
+
message: "\u9009\u62E9\u64CD\u4F5C",
|
|
22098
|
+
options: [
|
|
22099
|
+
{ value: "server", label: "\u670D\u52A1\u5668\u8BBE\u7F6E", hint: "host / port / \u540C\u6B65\u95F4\u9694 / auto-sync" },
|
|
22100
|
+
{ value: "peers", label: "\u540C\u6B65\u8BBE\u5907", hint: "\u914D\u5BF9 / \u5217\u51FA / \u79FB\u9664 / \u540C\u6B65" },
|
|
22101
|
+
{ value: "grants", label: "\u5DF2\u7B7E\u53D1\u51ED\u636E", hint: "\u5217\u51FA / \u540A\u9500" },
|
|
22102
|
+
{ value: "exit", label: "\u9000\u51FA" }
|
|
22103
|
+
]
|
|
22104
|
+
});
|
|
22105
|
+
if (cancelled(choice) || choice === "exit") {
|
|
22106
|
+
fe2("\u518D\u89C1");
|
|
22107
|
+
return;
|
|
22108
|
+
}
|
|
22109
|
+
if (choice === "server")
|
|
22110
|
+
await serverWizard(db);
|
|
22111
|
+
else if (choice === "peers")
|
|
22112
|
+
await peerWizard(db);
|
|
22113
|
+
else if (choice === "grants")
|
|
22114
|
+
await grantWizard(db);
|
|
22115
|
+
}
|
|
22116
|
+
}
|
|
22117
|
+
var config_default = defineCommand({
|
|
22118
|
+
meta: {
|
|
22119
|
+
name: "config",
|
|
22120
|
+
description: "Configure server + sync devices. Run with no args for an interactive wizard, or use flags directly (e.g. `config --port 7777`, `config peer add --url <url> --code <code>`)."
|
|
22121
|
+
},
|
|
22122
|
+
args: {
|
|
22123
|
+
section: { type: "positional", required: false, description: "show | set | peer | grant (omit for wizard)" },
|
|
22124
|
+
action: { type: "positional", required: false, description: "peer: add|code|list|rm|enable|disable|sync \xB7 grant: list|revoke" },
|
|
22125
|
+
host: { type: "string", description: "Bind address" },
|
|
22126
|
+
port: { type: "string", description: "Server port" },
|
|
22127
|
+
"sync-interval": { type: "string", description: "Auto-sync interval (e.g. 30s, 5m)" },
|
|
22128
|
+
"auto-sync": { type: "string", description: "Enable auto-sync timer (true/false)" },
|
|
22129
|
+
url: { type: "string", description: "Peer URL (peer add/rm/enable/disable/sync)" },
|
|
22130
|
+
code: { type: "string", description: "One-time pairing code (peer add)" },
|
|
22131
|
+
"self-url": { type: "string", description: "This device's reachable URL (peer add, optional)" },
|
|
22132
|
+
token: { type: "string", description: "Issued credential token or prefix (grant revoke)" }
|
|
22133
|
+
},
|
|
22134
|
+
run: guard(async (args) => {
|
|
22135
|
+
const db = openMetahub();
|
|
22136
|
+
const section = typeof args.section === "string" ? args.section : undefined;
|
|
22137
|
+
const hasSettingFlag = args.host != null || args.port != null || args["sync-interval"] != null || args["auto-sync"] != null;
|
|
22138
|
+
if (!section) {
|
|
22139
|
+
if (hasSettingFlag)
|
|
22140
|
+
return applySet(db, args);
|
|
22141
|
+
if (isTTY2())
|
|
22142
|
+
return wizard(db);
|
|
22143
|
+
return showConfig(db);
|
|
22144
|
+
}
|
|
22145
|
+
if (section === "show")
|
|
22146
|
+
return showConfig(db);
|
|
22147
|
+
if (section === "set")
|
|
22148
|
+
return applySet(db, args);
|
|
22149
|
+
if (section === "peer")
|
|
22150
|
+
return peerDispatch(db, args.action ?? "list", args);
|
|
22151
|
+
if (section === "grant")
|
|
22152
|
+
return grantDispatch(db, args.action ?? "list", args);
|
|
22153
|
+
throw new Error(`unknown config section '${section}' (show | set | peer | grant)`);
|
|
22154
|
+
})
|
|
22155
|
+
});
|
|
22156
|
+
|
|
22157
|
+
// src/core/sync/server.ts
|
|
22158
|
+
init_node();
|
|
22159
|
+
|
|
22160
|
+
// src/core/sync/routes.ts
|
|
22161
|
+
init_crdt();
|
|
22162
|
+
|
|
22163
|
+
// src/core/sync/webui-routes.ts
|
|
22164
|
+
var DatabaseSchema = exports_external.object({
|
|
22165
|
+
id: exports_external.string(),
|
|
22166
|
+
name: exports_external.string(),
|
|
22167
|
+
icon: exports_external.string().nullable(),
|
|
22168
|
+
created_hlc: exports_external.string()
|
|
22169
|
+
});
|
|
22170
|
+
var PropertySchema = exports_external.object({
|
|
22171
|
+
id: exports_external.string(),
|
|
22172
|
+
database_id: exports_external.string(),
|
|
22173
|
+
name: exports_external.string(),
|
|
22174
|
+
type: exports_external.string(),
|
|
22175
|
+
config: exports_external.any().nullable(),
|
|
22176
|
+
position: exports_external.number()
|
|
22177
|
+
});
|
|
22178
|
+
var RecordSchema = exports_external.object({
|
|
22179
|
+
id: exports_external.string(),
|
|
22180
|
+
database_id: exports_external.string(),
|
|
22181
|
+
values: exports_external.record(exports_external.string(), exports_external.any())
|
|
22182
|
+
});
|
|
22183
|
+
var MoveRecordReq = exports_external.object({
|
|
22184
|
+
target: exports_external.string(),
|
|
22185
|
+
where: exports_external.enum(["before", "after"])
|
|
22186
|
+
});
|
|
22187
|
+
var DocumentSummarySchema = exports_external.object({
|
|
22188
|
+
id: exports_external.string(),
|
|
22189
|
+
title: exports_external.string(),
|
|
22190
|
+
database_id: exports_external.string().nullable(),
|
|
22191
|
+
parent_id: exports_external.string().nullable(),
|
|
22192
|
+
created_hlc: exports_external.string()
|
|
22193
|
+
});
|
|
22194
|
+
var DocumentSchema = DocumentSummarySchema.extend({ body: exports_external.string().nullable() });
|
|
22195
|
+
var SearchHitSchema = exports_external.object({
|
|
22196
|
+
type: exports_external.string(),
|
|
22197
|
+
id: exports_external.string(),
|
|
22198
|
+
database_id: exports_external.string().nullable(),
|
|
22199
|
+
title: exports_external.string().optional(),
|
|
22200
|
+
snippet: exports_external.string()
|
|
22201
|
+
});
|
|
22202
|
+
var OkSchema = exports_external.object({ ok: exports_external.boolean() });
|
|
22203
|
+
var CreateDatabaseReq = exports_external.object({ name: exports_external.string(), icon: exports_external.string().optional() });
|
|
22204
|
+
var UpdateDatabaseReq = exports_external.object({
|
|
22205
|
+
name: exports_external.string().optional(),
|
|
22206
|
+
icon: exports_external.string().nullable().optional()
|
|
22207
|
+
});
|
|
22208
|
+
var CreatePropertyReq = exports_external.object({
|
|
22209
|
+
db: exports_external.string(),
|
|
22210
|
+
name: exports_external.string(),
|
|
22211
|
+
type: exports_external.string(),
|
|
22212
|
+
config: exports_external.any().optional()
|
|
22213
|
+
});
|
|
22214
|
+
var UpdatePropertyReq = exports_external.object({
|
|
22215
|
+
name: exports_external.string().optional(),
|
|
22216
|
+
type: exports_external.string().optional(),
|
|
22217
|
+
config: exports_external.any().optional(),
|
|
22218
|
+
position: exports_external.number().optional()
|
|
22219
|
+
});
|
|
22220
|
+
var SetWidthReq = exports_external.object({ width: exports_external.number() });
|
|
22221
|
+
var RecordValuesReq = exports_external.record(exports_external.string(), exports_external.any());
|
|
22222
|
+
var CreateDocumentReq = exports_external.object({
|
|
22223
|
+
title: exports_external.string(),
|
|
22224
|
+
body: exports_external.string().optional(),
|
|
22225
|
+
database_id: exports_external.string().optional(),
|
|
22226
|
+
parent_id: exports_external.string().optional()
|
|
22227
|
+
});
|
|
22228
|
+
var UpdateDocumentReq = exports_external.object({
|
|
22229
|
+
title: exports_external.string().optional(),
|
|
22230
|
+
body: exports_external.string().optional(),
|
|
22231
|
+
parent_id: exports_external.string().nullable().optional()
|
|
22232
|
+
});
|
|
22233
|
+
function need(req, key) {
|
|
22234
|
+
const v3 = new URL(req.url).searchParams.get(key);
|
|
22235
|
+
if (!v3)
|
|
22236
|
+
throw new Error(`missing query param: ${key}`);
|
|
22237
|
+
return v3;
|
|
22238
|
+
}
|
|
22239
|
+
function opt(req, key) {
|
|
22240
|
+
return new URL(req.url).searchParams.get(key) ?? undefined;
|
|
22241
|
+
}
|
|
22242
|
+
function handle(fn) {
|
|
22243
|
+
return async (req, ctx) => {
|
|
22244
|
+
try {
|
|
22245
|
+
const out = await fn(req, ctx);
|
|
22246
|
+
if (out instanceof Response)
|
|
22247
|
+
return out;
|
|
22248
|
+
return Response.json(out ?? null);
|
|
22249
|
+
} catch (e3) {
|
|
22250
|
+
return Response.json({ error: e3.message }, { status: 400 });
|
|
22251
|
+
}
|
|
22252
|
+
};
|
|
22253
|
+
}
|
|
22254
|
+
var webuiRoutes = [
|
|
22255
|
+
{
|
|
22256
|
+
method: "GET",
|
|
22257
|
+
path: "/api/databases",
|
|
22258
|
+
summary: "List all databases",
|
|
22259
|
+
response: exports_external.array(DatabaseSchema),
|
|
22260
|
+
handler: handle((_req, { db }) => listDatabases(db))
|
|
22261
|
+
},
|
|
22262
|
+
{
|
|
22263
|
+
method: "POST",
|
|
22264
|
+
path: "/api/databases",
|
|
22265
|
+
summary: "Create a database",
|
|
22266
|
+
request: CreateDatabaseReq,
|
|
22267
|
+
response: DatabaseSchema,
|
|
22268
|
+
handler: handle(async (req, { db }) => {
|
|
22269
|
+
const body = await req.json();
|
|
22270
|
+
return createDatabase(db, body);
|
|
22271
|
+
})
|
|
22272
|
+
},
|
|
22273
|
+
{
|
|
22274
|
+
method: "PATCH",
|
|
22275
|
+
path: "/api/database",
|
|
22276
|
+
summary: "Rename a database or change its icon. Query: ?id=<id>",
|
|
22277
|
+
request: UpdateDatabaseReq,
|
|
22278
|
+
response: DatabaseSchema,
|
|
22279
|
+
handler: handle(async (req, { db }) => {
|
|
22280
|
+
const body = await req.json();
|
|
22281
|
+
return updateDatabase(db, need(req, "id"), body);
|
|
22282
|
+
})
|
|
22283
|
+
},
|
|
22284
|
+
{
|
|
22285
|
+
method: "DELETE",
|
|
22286
|
+
path: "/api/database",
|
|
20190
22287
|
summary: "Delete a database (and stop it being the current one). Query: ?id=<id>",
|
|
20191
22288
|
response: OkSchema,
|
|
20192
22289
|
handler: handle((req, { db }) => ({ ok: deleteDatabase(db, need(req, "id")) }))
|
|
@@ -20304,9 +22401,9 @@ var webuiRoutes = [
|
|
|
20304
22401
|
{
|
|
20305
22402
|
method: "GET",
|
|
20306
22403
|
path: "/api/documents",
|
|
20307
|
-
summary: "List documents. Optional query: ?db=<id>",
|
|
22404
|
+
summary: "List documents. Optional query: ?db=<id> or ?parent=<id>",
|
|
20308
22405
|
response: exports_external.array(DocumentSummarySchema),
|
|
20309
|
-
handler: handle((req, { db }) => listDocuments(db, { database_id: opt(req, "db") }))
|
|
22406
|
+
handler: handle((req, { db }) => listDocuments(db, { database_id: opt(req, "db"), parent_id: opt(req, "parent") }))
|
|
20310
22407
|
},
|
|
20311
22408
|
{
|
|
20312
22409
|
method: "POST",
|
|
@@ -20375,17 +22472,17 @@ var SiteFileSchema = exports_external.object({
|
|
|
20375
22472
|
encoding: exports_external.string()
|
|
20376
22473
|
});
|
|
20377
22474
|
function need2(req, key) {
|
|
20378
|
-
const
|
|
20379
|
-
if (!
|
|
22475
|
+
const v3 = new URL(req.url).searchParams.get(key);
|
|
22476
|
+
if (!v3)
|
|
20380
22477
|
throw new Error(`missing query param: ${key}`);
|
|
20381
|
-
return
|
|
22478
|
+
return v3;
|
|
20382
22479
|
}
|
|
20383
22480
|
function handle2(fn) {
|
|
20384
22481
|
return async (req, ctx) => {
|
|
20385
22482
|
try {
|
|
20386
22483
|
return Response.json(await fn(req, ctx) ?? null);
|
|
20387
|
-
} catch (
|
|
20388
|
-
return Response.json({ error:
|
|
22484
|
+
} catch (e3) {
|
|
22485
|
+
return Response.json({ error: e3.message }, { status: 400 });
|
|
20389
22486
|
}
|
|
20390
22487
|
};
|
|
20391
22488
|
}
|
|
@@ -20406,6 +22503,146 @@ var sitesRoutes = [
|
|
|
20406
22503
|
}
|
|
20407
22504
|
];
|
|
20408
22505
|
|
|
22506
|
+
// src/core/sync/peers-routes.ts
|
|
22507
|
+
var PeerSchema = exports_external.object({
|
|
22508
|
+
url: exports_external.string(),
|
|
22509
|
+
pull_cursor: exports_external.number(),
|
|
22510
|
+
push_cursor: exports_external.number(),
|
|
22511
|
+
token: exports_external.string().nullable(),
|
|
22512
|
+
label: exports_external.string().nullable(),
|
|
22513
|
+
node_id: exports_external.string().nullable(),
|
|
22514
|
+
enabled: exports_external.number(),
|
|
22515
|
+
last_sync_at: exports_external.number().nullable(),
|
|
22516
|
+
last_status: exports_external.string().nullable(),
|
|
22517
|
+
last_error: exports_external.string().nullable()
|
|
22518
|
+
});
|
|
22519
|
+
var PairingCodeSchema = exports_external.object({ code: exports_external.string(), exp: exports_external.number() });
|
|
22520
|
+
var AddPeerReq = exports_external.object({
|
|
22521
|
+
url: exports_external.string(),
|
|
22522
|
+
code: exports_external.string(),
|
|
22523
|
+
self_url: exports_external.string().optional()
|
|
22524
|
+
});
|
|
22525
|
+
var AddPeerRes = exports_external.object({ node_id: exports_external.string(), url: exports_external.string() });
|
|
22526
|
+
var UpdatePeerReq = exports_external.object({
|
|
22527
|
+
enabled: exports_external.boolean().optional(),
|
|
22528
|
+
label: exports_external.string().optional()
|
|
22529
|
+
});
|
|
22530
|
+
var PeerSyncRes = exports_external.object({
|
|
22531
|
+
url: exports_external.string(),
|
|
22532
|
+
ok: exports_external.boolean(),
|
|
22533
|
+
pushed: exports_external.number().optional(),
|
|
22534
|
+
pulled: exports_external.number().optional(),
|
|
22535
|
+
error: exports_external.string().optional()
|
|
22536
|
+
});
|
|
22537
|
+
var GrantSchema = exports_external.object({
|
|
22538
|
+
token: exports_external.string(),
|
|
22539
|
+
peer_url: exports_external.string().nullable(),
|
|
22540
|
+
node_id: exports_external.string().nullable(),
|
|
22541
|
+
created_at: exports_external.number().nullable()
|
|
22542
|
+
});
|
|
22543
|
+
var RevokeRes = exports_external.object({ revoked: exports_external.number() });
|
|
22544
|
+
var OkSchema2 = exports_external.object({ ok: exports_external.boolean() });
|
|
22545
|
+
function need3(req, key) {
|
|
22546
|
+
const v3 = new URL(req.url).searchParams.get(key);
|
|
22547
|
+
if (!v3)
|
|
22548
|
+
throw new Error(`missing query param: ${key}`);
|
|
22549
|
+
return v3;
|
|
22550
|
+
}
|
|
22551
|
+
function handle3(fn) {
|
|
22552
|
+
return async (req, ctx) => {
|
|
22553
|
+
try {
|
|
22554
|
+
const out = await fn(req, ctx);
|
|
22555
|
+
if (out instanceof Response)
|
|
22556
|
+
return out;
|
|
22557
|
+
return Response.json(out ?? null);
|
|
22558
|
+
} catch (e3) {
|
|
22559
|
+
return Response.json({ error: e3.message }, { status: 400 });
|
|
22560
|
+
}
|
|
22561
|
+
};
|
|
22562
|
+
}
|
|
22563
|
+
var peersRoutes = [
|
|
22564
|
+
{
|
|
22565
|
+
method: "POST",
|
|
22566
|
+
path: PAIR_PATH,
|
|
22567
|
+
summary: "Pairing handshake: redeem a one-time code and exchange credentials",
|
|
22568
|
+
request: PairRequestSchema,
|
|
22569
|
+
response: PairResponseSchema,
|
|
22570
|
+
handler: handle3(async (req, { db, node }) => {
|
|
22571
|
+
const body = await req.json();
|
|
22572
|
+
return handlePairRequest(db, node, body);
|
|
22573
|
+
})
|
|
22574
|
+
},
|
|
22575
|
+
{
|
|
22576
|
+
method: "POST",
|
|
22577
|
+
path: "/api/pair/new",
|
|
22578
|
+
summary: "Mint a one-time pairing code for another device to redeem",
|
|
22579
|
+
response: PairingCodeSchema,
|
|
22580
|
+
handler: handle3((_req, { db }) => generatePairingCode(db))
|
|
22581
|
+
},
|
|
22582
|
+
{
|
|
22583
|
+
method: "POST",
|
|
22584
|
+
path: "/api/peers/pair",
|
|
22585
|
+
summary: "Pair this server with a remote one using its one-time code",
|
|
22586
|
+
request: AddPeerReq,
|
|
22587
|
+
response: AddPeerRes,
|
|
22588
|
+
handler: handle3(async (req, { db, node }) => {
|
|
22589
|
+
const body = await req.json();
|
|
22590
|
+
return performPairing(db, node, body.url, body.code, body.self_url);
|
|
22591
|
+
})
|
|
22592
|
+
},
|
|
22593
|
+
{
|
|
22594
|
+
method: "GET",
|
|
22595
|
+
path: "/api/peers",
|
|
22596
|
+
summary: "List configured sync peers with status",
|
|
22597
|
+
response: exports_external.array(PeerSchema),
|
|
22598
|
+
handler: handle3((_req, { db }) => listPeers(db))
|
|
22599
|
+
},
|
|
22600
|
+
{
|
|
22601
|
+
method: "PATCH",
|
|
22602
|
+
path: "/api/peer",
|
|
22603
|
+
summary: "Update a peer (enable/disable or label). Query: ?url=<url>",
|
|
22604
|
+
request: UpdatePeerReq,
|
|
22605
|
+
response: OkSchema2,
|
|
22606
|
+
handler: handle3(async (req, { db }) => {
|
|
22607
|
+
const url2 = need3(req, "url");
|
|
22608
|
+
const body = await req.json();
|
|
22609
|
+
if (body.enabled != null)
|
|
22610
|
+
setPeerEnabled(db, url2, body.enabled);
|
|
22611
|
+
if (body.label != null)
|
|
22612
|
+
setPeerLabel(db, url2, body.label);
|
|
22613
|
+
return { ok: true };
|
|
22614
|
+
})
|
|
22615
|
+
},
|
|
22616
|
+
{
|
|
22617
|
+
method: "DELETE",
|
|
22618
|
+
path: "/api/peer",
|
|
22619
|
+
summary: "Remove a sync peer. Query: ?url=<url>",
|
|
22620
|
+
response: OkSchema2,
|
|
22621
|
+
handler: handle3((req, { db }) => ({ ok: removePeer(db, need3(req, "url")) }))
|
|
22622
|
+
},
|
|
22623
|
+
{
|
|
22624
|
+
method: "POST",
|
|
22625
|
+
path: "/api/peer/sync",
|
|
22626
|
+
summary: "Manually sync once with a peer. Query: ?url=<url>",
|
|
22627
|
+
response: PeerSyncRes,
|
|
22628
|
+
handler: handle3((req, { db }) => syncPeer(db, need3(req, "url")))
|
|
22629
|
+
},
|
|
22630
|
+
{
|
|
22631
|
+
method: "GET",
|
|
22632
|
+
path: "/api/grants",
|
|
22633
|
+
summary: "List credentials this server issued and accepts on /sync (inbound)",
|
|
22634
|
+
response: exports_external.array(GrantSchema),
|
|
22635
|
+
handler: handle3((_req, { db }) => listGrants(db))
|
|
22636
|
+
},
|
|
22637
|
+
{
|
|
22638
|
+
method: "DELETE",
|
|
22639
|
+
path: "/api/grant",
|
|
22640
|
+
summary: "Revoke an issued credential by token or prefix. Query: ?token=<token>",
|
|
22641
|
+
response: RevokeRes,
|
|
22642
|
+
handler: handle3((req, { db }) => ({ revoked: revokeGrant(db, need3(req, "token")) }))
|
|
22643
|
+
}
|
|
22644
|
+
];
|
|
22645
|
+
|
|
20409
22646
|
// src/core/sync/routes.ts
|
|
20410
22647
|
var syncRoutes = [
|
|
20411
22648
|
{
|
|
@@ -20431,7 +22668,7 @@ var syncRoutes = [
|
|
|
20431
22668
|
}
|
|
20432
22669
|
}
|
|
20433
22670
|
];
|
|
20434
|
-
var routes = [...syncRoutes, ...webuiRoutes, ...sitesRoutes];
|
|
22671
|
+
var routes = [...syncRoutes, ...webuiRoutes, ...sitesRoutes, ...peersRoutes];
|
|
20435
22672
|
|
|
20436
22673
|
// src/core/sync/openapi.ts
|
|
20437
22674
|
function buildOpenApi(version2) {
|
|
@@ -20468,9 +22705,9 @@ function cookieToken(req) {
|
|
|
20468
22705
|
if (!header)
|
|
20469
22706
|
return null;
|
|
20470
22707
|
for (const part of header.split(";")) {
|
|
20471
|
-
const [
|
|
20472
|
-
if (
|
|
20473
|
-
return decodeURIComponent(
|
|
22708
|
+
const [k3, ...v3] = part.trim().split("=");
|
|
22709
|
+
if (k3 === COOKIE)
|
|
22710
|
+
return decodeURIComponent(v3.join("="));
|
|
20474
22711
|
}
|
|
20475
22712
|
return null;
|
|
20476
22713
|
}
|
|
@@ -20500,6 +22737,17 @@ function hasValidToken(req, url2, cfg) {
|
|
|
20500
22737
|
return true;
|
|
20501
22738
|
return extractToken(req, url2) === cur.token;
|
|
20502
22739
|
}
|
|
22740
|
+
function acceptsSyncToken(req, url2, cfg, db) {
|
|
22741
|
+
if (!authActive(cfg))
|
|
22742
|
+
return true;
|
|
22743
|
+
const presented = extractToken(req, url2);
|
|
22744
|
+
if (!presented)
|
|
22745
|
+
return false;
|
|
22746
|
+
const cur = activeToken(cfg);
|
|
22747
|
+
if (cur && presented === cur.token)
|
|
22748
|
+
return true;
|
|
22749
|
+
return isAcceptedGrant(db, presented);
|
|
22750
|
+
}
|
|
20503
22751
|
function renewToken(req, url2, cfg) {
|
|
20504
22752
|
if (cfg.debug || cfg.staticToken != null || !cfg.db)
|
|
20505
22753
|
return null;
|
|
@@ -20615,8 +22863,8 @@ function injectShim(html) {
|
|
|
20615
22863
|
async function withShim(res, cfg) {
|
|
20616
22864
|
if (!authActive(cfg))
|
|
20617
22865
|
return res;
|
|
20618
|
-
const
|
|
20619
|
-
if (!
|
|
22866
|
+
const ct3 = res.headers.get("content-type") ?? "";
|
|
22867
|
+
if (!ct3.includes("text/html"))
|
|
20620
22868
|
return res;
|
|
20621
22869
|
const html = injectShim(await res.text());
|
|
20622
22870
|
const headers = new Headers(res.headers);
|
|
@@ -20639,6 +22887,11 @@ function startServer(opts = {}) {
|
|
|
20639
22887
|
const db = openMetahub();
|
|
20640
22888
|
const node = getNodeId(db);
|
|
20641
22889
|
const ctx = { db, node };
|
|
22890
|
+
const cfg = getServerConfig(db);
|
|
22891
|
+
const port = opts.port ?? cfg.port;
|
|
22892
|
+
const host = opts.host ?? cfg.host;
|
|
22893
|
+
const syncIntervalMs = opts.syncIntervalMs ?? cfg.syncIntervalMs;
|
|
22894
|
+
const autoSync = opts.autoSync ?? cfg.autoSync;
|
|
20642
22895
|
const auth = opts.debug ? { debug: true, staticToken: null, db: null, ttlMs: 0, graceMs: 0 } : opts.token ? { debug: false, staticToken: opts.token, db: null, ttlMs: 0, graceMs: 0 } : {
|
|
20643
22896
|
debug: false,
|
|
20644
22897
|
staticToken: null,
|
|
@@ -20647,13 +22900,18 @@ function startServer(opts = {}) {
|
|
|
20647
22900
|
graceMs: DEFAULT_GRACE_MS
|
|
20648
22901
|
};
|
|
20649
22902
|
const server = Bun.serve({
|
|
20650
|
-
port
|
|
20651
|
-
hostname:
|
|
22903
|
+
port,
|
|
22904
|
+
hostname: host,
|
|
20652
22905
|
async fetch(req) {
|
|
20653
22906
|
const url2 = new URL(req.url);
|
|
20654
|
-
|
|
20655
|
-
|
|
20656
|
-
|
|
22907
|
+
if (url2.pathname === SYNC_PATH) {
|
|
22908
|
+
if (!acceptsSyncToken(req, url2, auth, db))
|
|
22909
|
+
return unauthorized();
|
|
22910
|
+
} else {
|
|
22911
|
+
const exempt = url2.pathname === HEALTH_PATH || url2.pathname === RENEW_PATH || url2.pathname === PAIR_PATH;
|
|
22912
|
+
if (!exempt && !hasValidToken(req, url2, auth)) {
|
|
22913
|
+
return wantsHtml(req) ? new Response(unlockPage(), { headers: HTML_HEADERS }) : unauthorized();
|
|
22914
|
+
}
|
|
20657
22915
|
}
|
|
20658
22916
|
if (url2.pathname === RENEW_PATH) {
|
|
20659
22917
|
const r3 = renewToken(req, url2, auth);
|
|
@@ -20683,13 +22941,25 @@ function startServer(opts = {}) {
|
|
|
20683
22941
|
return new Response("not found", { status: 404 });
|
|
20684
22942
|
}
|
|
20685
22943
|
});
|
|
22944
|
+
let timer = null;
|
|
22945
|
+
if (autoSync && syncIntervalMs > 0) {
|
|
22946
|
+
timer = setInterval(() => {
|
|
22947
|
+
syncAllPeers(db).catch(() => {});
|
|
22948
|
+
}, syncIntervalMs);
|
|
22949
|
+
timer.unref?.();
|
|
22950
|
+
}
|
|
20686
22951
|
const active = activeToken(auth);
|
|
20687
22952
|
return {
|
|
20688
22953
|
server,
|
|
20689
22954
|
node,
|
|
20690
|
-
port: server.port ??
|
|
22955
|
+
port: server.port ?? port,
|
|
20691
22956
|
token: active?.token ?? null,
|
|
20692
|
-
exp: active?.exp ?? null
|
|
22957
|
+
exp: active?.exp ?? null,
|
|
22958
|
+
stop() {
|
|
22959
|
+
if (timer)
|
|
22960
|
+
clearInterval(timer);
|
|
22961
|
+
server.stop();
|
|
22962
|
+
}
|
|
20693
22963
|
};
|
|
20694
22964
|
}
|
|
20695
22965
|
|
|
@@ -20886,7 +23156,7 @@ async function showUsage2(cmd, parent) {
|
|
|
20886
23156
|
|
|
20887
23157
|
EXAMPLES
|
|
20888
23158
|
|
|
20889
|
-
` + examples.map((
|
|
23159
|
+
` + examples.map((e3) => " " + e3).join(`
|
|
20890
23160
|
`);
|
|
20891
23161
|
}
|
|
20892
23162
|
console.log(usage + `
|
|
@@ -20905,7 +23175,9 @@ var main = defineCommand({
|
|
|
20905
23175
|
port: { type: "string", description: "Server port (with --server)", default: "7777" },
|
|
20906
23176
|
host: { type: "string", description: "Bind address (with --server)", default: "127.0.0.1" },
|
|
20907
23177
|
debug: { type: "boolean", description: "Disable auth on the server (with --server)" },
|
|
20908
|
-
token: { type: "string", description: "Server auth token; generated if omitted (with --server)" }
|
|
23178
|
+
token: { type: "string", description: "Server auth token; generated if omitted (with --server)" },
|
|
23179
|
+
"sync-interval": { type: "string", description: "Auto-sync interval, e.g. 30s/5m (with --server)" },
|
|
23180
|
+
"no-auto-sync": { type: "boolean", description: "Disable the auto-sync timer (with --server)" }
|
|
20909
23181
|
},
|
|
20910
23182
|
subCommands: {
|
|
20911
23183
|
init: init_default,
|
|
@@ -20923,7 +23195,8 @@ var main = defineCommand({
|
|
|
20923
23195
|
__complete: complete,
|
|
20924
23196
|
sync: sync_default,
|
|
20925
23197
|
snapshot: snapshot_default,
|
|
20926
|
-
restore: restore_default
|
|
23198
|
+
restore: restore_default,
|
|
23199
|
+
config: config_default
|
|
20927
23200
|
}
|
|
20928
23201
|
});
|
|
20929
23202
|
function flagValue(argv2, name) {
|
|
@@ -20933,16 +23206,17 @@ function flagValue(argv2, name) {
|
|
|
20933
23206
|
const a2 = argv2[i2];
|
|
20934
23207
|
return a2.includes("=") ? a2.slice(a2.indexOf("=") + 1) : argv2[i2 + 1];
|
|
20935
23208
|
}
|
|
20936
|
-
function parsePort(argv2) {
|
|
20937
|
-
return Number(flagValue(argv2, "port")) || 7777;
|
|
20938
|
-
}
|
|
20939
23209
|
var argv2 = process.argv.slice(2);
|
|
20940
23210
|
if (argv2.includes("--server")) {
|
|
23211
|
+
const portFlag = flagValue(argv2, "port");
|
|
23212
|
+
const intervalFlag = flagValue(argv2, "sync-interval");
|
|
20941
23213
|
const s2 = startServer({
|
|
20942
|
-
port:
|
|
23214
|
+
port: portFlag != null ? Number(portFlag) : undefined,
|
|
20943
23215
|
host: flagValue(argv2, "host"),
|
|
20944
23216
|
debug: argv2.includes("--debug"),
|
|
20945
|
-
token: flagValue(argv2, "token") ?? process.env.METAHUB_TOKEN
|
|
23217
|
+
token: flagValue(argv2, "token") ?? process.env.METAHUB_TOKEN,
|
|
23218
|
+
syncIntervalMs: intervalFlag != null ? parseDuration(intervalFlag, 30000) : undefined,
|
|
23219
|
+
autoSync: argv2.includes("--no-auto-sync") ? false : undefined
|
|
20946
23220
|
});
|
|
20947
23221
|
const expNote = s2.token && s2.exp != null && Number.isFinite(s2.exp) ? ` (expires ${new Date(s2.exp).toISOString()})` : "";
|
|
20948
23222
|
print({
|
|
@@ -20958,4 +23232,4 @@ if (argv2.includes("--server")) {
|
|
|
20958
23232
|
runMain(main, { showUsage: showUsage2 });
|
|
20959
23233
|
}
|
|
20960
23234
|
|
|
20961
|
-
//# debugId=
|
|
23235
|
+
//# debugId=10C9A2ACC0C4883B64756E2164756E21
|