downcity 1.1.89 → 1.1.90
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/city/admin/commands/config.d.ts +1 -1
- package/city/admin/commands/config.js +1 -1
- package/city/admin/loop.d.ts +8 -2
- package/city/admin/loop.d.ts.map +1 -1
- package/city/admin/loop.js +17 -6
- package/city/admin/loop.js.map +1 -1
- package/city/app.d.ts +6 -5
- package/city/app.d.ts.map +1 -1
- package/city/app.js +51 -56
- package/city/app.js.map +1 -1
- package/city/auth/admin.js +1 -1
- package/city/auth/admin.js.map +1 -1
- package/city/auth/server-switch.d.ts +10 -11
- package/city/auth/server-switch.d.ts.map +1 -1
- package/city/auth/server-switch.js +77 -100
- package/city/auth/server-switch.js.map +1 -1
- package/city/core/ui.d.ts.map +1 -1
- package/city/core/ui.js +5 -4
- package/city/core/ui.js.map +1 -1
- package/city/deploy/runtime/CloudflareWorkersDeployer.js +1 -1
- package/city/deploy/runtime/CloudflareWorkersDeployer.js.map +1 -1
- package/city/home/HomeMenu.d.ts +17 -0
- package/city/home/HomeMenu.d.ts.map +1 -0
- package/city/home/HomeMenu.js +72 -0
- package/city/home/HomeMenu.js.map +1 -0
- package/city/types/Interactive.d.ts +25 -0
- package/city/types/Interactive.d.ts.map +1 -0
- package/city/types/Interactive.js +10 -0
- package/city/types/Interactive.js.map +1 -0
- package/city/user/loop.d.ts +3 -2
- package/city/user/loop.d.ts.map +1 -1
- package/city/user/loop.js +15 -8
- package/city/user/loop.js.map +1 -1
- package/city/workspace/ServerManagement.d.ts +13 -0
- package/city/workspace/ServerManagement.d.ts.map +1 -0
- package/city/workspace/ServerManagement.js +98 -0
- package/city/workspace/ServerManagement.js.map +1 -0
- package/city/workspace/ServerWorkspace.d.ts +12 -0
- package/city/workspace/ServerWorkspace.d.ts.map +1 -0
- package/city/workspace/ServerWorkspace.js +98 -0
- package/city/workspace/ServerWorkspace.js.map +1 -0
- package/package.json +1 -1
- package/town/agent/http/sdk/Router.d.ts +1 -1
- package/town/agent/http/sdk/Router.js +1 -1
- package/town/control-plane/ControlPlaneCommand.d.ts +1 -1
- package/town/control-plane/ControlPlaneCommand.js +1 -1
- package/city/auth/mode-select.d.ts +0 -11
- package/city/auth/mode-select.d.ts.map +0 -1
- package/city/auth/mode-select.js +0 -33
- package/city/auth/mode-select.js.map +0 -1
package/city/admin/loop.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Admin
|
|
2
|
+
* Admin 命令循环。
|
|
3
|
+
*
|
|
4
|
+
* 关键说明(中文)
|
|
5
|
+
* - embedded 模式用于 user 工作区下的 server management
|
|
6
|
+
* - 此时 admin 只作为低频管理工具,不再承担顶层导航职责
|
|
3
7
|
*/
|
|
4
8
|
import { type AdminSession } from "../core/session.js";
|
|
5
|
-
export declare function adminLoop(session: AdminSession
|
|
9
|
+
export declare function adminLoop(session: AdminSession, options?: {
|
|
10
|
+
embedded?: boolean;
|
|
11
|
+
}): Promise<"logout" | "quit" | "switch_identity" | "back">;
|
|
6
12
|
//# sourceMappingURL=loop.d.ts.map
|
package/city/admin/loop.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/admin/loop.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/admin/loop.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAyBvD,wBAAsB,SAAS,CAC7B,OAAO,EAAE,YAAY,EACrB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/B,OAAO,CAAC,QAAQ,GAAG,MAAM,GAAG,iBAAiB,GAAG,MAAM,CAAC,CA+CzD"}
|
package/city/admin/loop.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Admin
|
|
2
|
+
* Admin 命令循环。
|
|
3
|
+
*
|
|
4
|
+
* 关键说明(中文)
|
|
5
|
+
* - embedded 模式用于 user 工作区下的 server management
|
|
6
|
+
* - 此时 admin 只作为低频管理工具,不再承担顶层导航职责
|
|
3
7
|
*/
|
|
4
8
|
import { City } from "@downcity/city";
|
|
5
9
|
import { select, isCancel } from "@clack/prompts";
|
|
@@ -25,15 +29,16 @@ const commands = {
|
|
|
25
29
|
payment: managePayment,
|
|
26
30
|
custom: manageCustom,
|
|
27
31
|
};
|
|
28
|
-
export async function adminLoop(session) {
|
|
32
|
+
export async function adminLoop(session, options) {
|
|
29
33
|
const admin = new City({
|
|
30
34
|
role: "admin",
|
|
31
35
|
city_url: session.base_url,
|
|
32
36
|
admin_secret_key: session.admin_secret_key,
|
|
33
37
|
});
|
|
38
|
+
const embedded = options?.embedded === true;
|
|
34
39
|
while (true) {
|
|
35
40
|
const svc = await select({
|
|
36
|
-
message: "Manage Service",
|
|
41
|
+
message: embedded ? "Server management" : "Manage Service",
|
|
37
42
|
options: [
|
|
38
43
|
{ label: "Env", value: "env", hint: "View & configure environment variables" },
|
|
39
44
|
{ label: "City Instruction", value: "instruction", hint: "Read aggregated city/service guidance" },
|
|
@@ -44,15 +49,21 @@ export async function adminLoop(session) {
|
|
|
44
49
|
{ label: "Usage", value: "usage" },
|
|
45
50
|
{ label: "Payment (Stripe)", value: "payment" },
|
|
46
51
|
{ label: "Custom service...", value: "custom" },
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
...(embedded
|
|
53
|
+
? [{ label: "Back", value: "back" }]
|
|
54
|
+
: [
|
|
55
|
+
{ label: "Switch to User", value: "switch" },
|
|
56
|
+
{ label: "Logout", value: "logout" },
|
|
57
|
+
]),
|
|
49
58
|
{ label: "Quit", value: "quit" },
|
|
50
59
|
],
|
|
51
60
|
});
|
|
52
61
|
if (!svc || isCancel(svc))
|
|
53
|
-
return "quit";
|
|
62
|
+
return embedded ? "back" : "quit";
|
|
54
63
|
if (svc === "quit")
|
|
55
64
|
return "quit";
|
|
65
|
+
if (svc === "back")
|
|
66
|
+
return "back";
|
|
56
67
|
if (svc === "logout") {
|
|
57
68
|
showSuccess("left admin mode");
|
|
58
69
|
return "logout";
|
package/city/admin/loop.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/admin/loop.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/admin/loop.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,MAAM,QAAQ,GAAgE;IAC5E,GAAG,EAAE,SAAS;IACd,WAAW,EAAE,iBAAiB;IAC9B,MAAM,EAAE,YAAY;IACpB,KAAK,EAAE,WAAW;IAClB,QAAQ,EAAE,cAAc;IACxB,OAAO,EAAE,aAAa;IACtB,KAAK,EAAE,WAAW;IAClB,OAAO,EAAE,aAAa;IACtB,MAAM,EAAE,YAAY;CACrB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,OAAqB,EACrB,OAAgC;IAEhC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC;QACrB,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;KAC3C,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,KAAK,IAAI,CAAC;IAE5C,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC;YACvB,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,gBAAgB;YAC1D,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,wCAAwC,EAAE;gBAC9E,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,uCAAuC,EAAE;gBAClG,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,sCAAsC,EAAE;gBAClF,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;gBAClC,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;gBACxC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;gBACtC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;gBAClC,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,SAAS,EAAE;gBAC/C,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,QAAQ,EAAE;gBAC/C,GAAG,CAAC,QAAQ;oBACV,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;oBACpC,CAAC,CAAC;wBACA,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,QAAQ,EAAE;wBAC5C,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;qBACrC,CAAC;gBACJ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;aACjC;SACF,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QAE7D,IAAI,GAAG,KAAK,MAAM;YAAE,OAAO,MAAM,CAAC;QAClC,IAAI,GAAG,KAAK,MAAM;YAAE,OAAO,MAAM,CAAC;QAClC,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;YAAC,OAAO,QAAQ,CAAC;QAAC,CAAC;QAC1E,IAAI,GAAG,KAAK,QAAQ;YAAE,OAAO,iBAAiB,CAAC;QAE/C,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxB,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChC,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;AACH,CAAC"}
|
package/city/app.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Downcity City
|
|
3
|
+
* Downcity City 交互入口与工作区调度。
|
|
4
4
|
*
|
|
5
5
|
* 状态流转:
|
|
6
|
-
*
|
|
7
|
-
* selectIdentity → User → userLoop → selectIdentity (switch identity)
|
|
8
|
-
* selectIdentity → Manage Servers → selectIdentity
|
|
6
|
+
* welcome/home → connect/switch City → server workspace → server management/admin tools
|
|
9
7
|
*
|
|
10
|
-
*
|
|
8
|
+
* 关键说明(中文)
|
|
9
|
+
* - 顶层不再要求先选择 admin / user 身份
|
|
10
|
+
* - connect City 后默认进入 user sign in / user 工作区
|
|
11
|
+
* - admin 能力只作为低频的 server management 入口出现
|
|
11
12
|
*/
|
|
12
13
|
export declare function runCityApp(argv?: string[]): Promise<void>;
|
|
13
14
|
//# sourceMappingURL=app.d.ts.map
|
package/city/app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":";AAEA
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;GAUG;AAYH,wBAAsB,UAAU,CAAC,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAsEnE"}
|
package/city/app.js
CHANGED
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Downcity City
|
|
3
|
+
* Downcity City 交互入口与工作区调度。
|
|
4
4
|
*
|
|
5
5
|
* 状态流转:
|
|
6
|
-
*
|
|
7
|
-
* selectIdentity → User → userLoop → selectIdentity (switch identity)
|
|
8
|
-
* selectIdentity → Manage Servers → selectIdentity
|
|
6
|
+
* welcome/home → connect/switch City → server workspace → server management/admin tools
|
|
9
7
|
*
|
|
10
|
-
*
|
|
8
|
+
* 关键说明(中文)
|
|
9
|
+
* - 顶层不再要求先选择 admin / user 身份
|
|
10
|
+
* - connect City 后默认进入 user sign in / user 工作区
|
|
11
|
+
* - admin 能力只作为低频的 server management 入口出现
|
|
11
12
|
*/
|
|
12
13
|
import { readFileSync } from "node:fs";
|
|
13
14
|
import { intro } from "./core/ui.js";
|
|
14
|
-
import { readActiveServer
|
|
15
|
+
import { readActiveServer } from "./core/session.js";
|
|
15
16
|
import { parseArgs } from "./core/env.js";
|
|
16
|
-
import {
|
|
17
|
-
import { adminAuth } from "./auth/admin.js";
|
|
18
|
-
import { userAuth } from "./auth/user.js";
|
|
19
|
-
import { ensureServerConfigured, manageServersMenu } from "./auth/server-switch.js";
|
|
20
|
-
import { userLoop } from "./user/loop.js";
|
|
21
|
-
import { adminLoop } from "./admin/loop.js";
|
|
17
|
+
import { promptAddServer, promptSelectActiveServer } from "./auth/server-switch.js";
|
|
22
18
|
import { show, showError, showSuccess } from "./core/ui.js";
|
|
23
19
|
import { updateCli } from "./core/update.js";
|
|
20
|
+
import { selectHomeAction, selectWelcomeAction } from "./home/HomeMenu.js";
|
|
21
|
+
import { openServerWorkspace } from "./workspace/ServerWorkspace.js";
|
|
24
22
|
export async function runCityApp(argv = []) {
|
|
25
23
|
const cli = parseArgs(argv);
|
|
26
24
|
if (cli.command === "update") {
|
|
@@ -28,64 +26,61 @@ export async function runCityApp(argv = []) {
|
|
|
28
26
|
return;
|
|
29
27
|
}
|
|
30
28
|
intro(`Downcity City v${readCliVersion()} (Esc to go back, Ctrl+C to exit)`);
|
|
31
|
-
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
let identity = await selectIdentity();
|
|
35
|
-
while (identity !== "quit") {
|
|
36
|
-
if (identity === "update") {
|
|
37
|
-
await runSelfUpdate();
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
if (identity === "servers") {
|
|
41
|
-
await manageServersMenu();
|
|
42
|
-
if (!(await ensureServerConfigured())) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
identity = await selectIdentity();
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
// 每次从磁盘读取最新 config,不持快照
|
|
49
|
-
const cfg = readConfig();
|
|
29
|
+
while (true) {
|
|
50
30
|
const activeServer = readActiveServer();
|
|
51
31
|
if (!activeServer) {
|
|
52
|
-
|
|
32
|
+
const welcomeAction = await selectWelcomeAction();
|
|
33
|
+
if (welcomeAction === "quit") {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (welcomeAction === "update") {
|
|
37
|
+
await runSelfUpdate();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const connectedServer = await promptAddServer();
|
|
41
|
+
if (!connectedServer) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const result = await openServerWorkspace(connectedServer.base_url);
|
|
45
|
+
if (result === "quit") {
|
|
53
46
|
return;
|
|
54
47
|
}
|
|
55
|
-
identity = await selectIdentity();
|
|
56
48
|
continue;
|
|
57
49
|
}
|
|
58
|
-
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
50
|
+
const homeAction = await selectHomeAction();
|
|
51
|
+
if (homeAction === "quit") {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (homeAction === "update") {
|
|
55
|
+
await runSelfUpdate();
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (homeAction === "connect_city") {
|
|
59
|
+
const connectedServer = await promptAddServer();
|
|
60
|
+
if (!connectedServer) {
|
|
63
61
|
continue;
|
|
64
62
|
}
|
|
65
|
-
const result = await
|
|
66
|
-
if (result === "quit")
|
|
67
|
-
|
|
68
|
-
if (result === "switch_identity") {
|
|
69
|
-
identity = await selectIdentity();
|
|
70
|
-
continue;
|
|
63
|
+
const result = await openServerWorkspace(connectedServer.base_url);
|
|
64
|
+
if (result === "quit") {
|
|
65
|
+
return;
|
|
71
66
|
}
|
|
72
|
-
identity = await selectIdentity();
|
|
73
67
|
continue;
|
|
74
68
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
69
|
+
if (homeAction === "switch_city") {
|
|
70
|
+
const selectedServer = await promptSelectActiveServer();
|
|
71
|
+
if (!selectedServer) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const result = await openServerWorkspace(selectedServer.base_url);
|
|
75
|
+
if (result === "quit") {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
79
78
|
continue;
|
|
80
79
|
}
|
|
81
|
-
const result = await
|
|
82
|
-
if (result === "quit")
|
|
83
|
-
|
|
84
|
-
if (result === "switch_identity") {
|
|
85
|
-
identity = await selectIdentity();
|
|
86
|
-
continue;
|
|
80
|
+
const result = await openServerWorkspace(activeServer.base_url);
|
|
81
|
+
if (result === "quit") {
|
|
82
|
+
return;
|
|
87
83
|
}
|
|
88
|
-
identity = await selectIdentity();
|
|
89
84
|
}
|
|
90
85
|
}
|
|
91
86
|
/**
|
package/city/app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":";AAEA
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
|
package/city/auth/admin.js
CHANGED
|
@@ -7,7 +7,7 @@ import { showError } from "../core/ui.js";
|
|
|
7
7
|
export async function adminAuth(server) {
|
|
8
8
|
const adminSecretKey = String(server.admin_secret_key ?? "").trim();
|
|
9
9
|
if (!adminSecretKey) {
|
|
10
|
-
showError("Current
|
|
10
|
+
showError("Current City is missing admin_secret_key. Open Server management -> Configure admin access.");
|
|
11
11
|
return undefined;
|
|
12
12
|
}
|
|
13
13
|
return {
|
package/city/auth/admin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/auth/admin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAqB;IACnD,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACpE,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/auth/admin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAqB;IACnD,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACpE,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,SAAS,CAAC,6FAA6F,CAAC,CAAC;QACzG,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,gBAAgB,EAAE,cAAc;KACjC,CAAC;AACJ,CAAC"}
|
|
@@ -2,21 +2,20 @@
|
|
|
2
2
|
* Server 管理模块。
|
|
3
3
|
*
|
|
4
4
|
* 关键说明(中文)
|
|
5
|
-
* -
|
|
6
|
-
* -
|
|
7
|
-
* -
|
|
5
|
+
* - connect City 不再强制要求 admin_secret_key
|
|
6
|
+
* - admin access 只在低频管理场景中单独配置
|
|
7
|
+
* - server 仍然作为本地连接记录持久化保存
|
|
8
8
|
*/
|
|
9
9
|
import { type ServerProfile } from "../core/session.js";
|
|
10
|
-
/**
|
|
11
|
-
* 确保至少存在一个 server。
|
|
12
|
-
*/
|
|
13
|
-
export declare function ensureServerConfigured(): Promise<boolean>;
|
|
14
|
-
/**
|
|
15
|
-
* 顶层 server 管理菜单。
|
|
16
|
-
*/
|
|
17
|
-
export declare function manageServersMenu(): Promise<void>;
|
|
18
10
|
/**
|
|
19
11
|
* 添加 server。
|
|
20
12
|
*/
|
|
21
13
|
export declare function promptAddServer(): Promise<ServerProfile | undefined>;
|
|
14
|
+
export declare function promptSelectActiveServer(): Promise<ServerProfile | undefined>;
|
|
15
|
+
export declare function promptEditServer(baseUrl?: string): Promise<ServerProfile | undefined>;
|
|
16
|
+
/**
|
|
17
|
+
* 为当前 server 单独配置 admin access。
|
|
18
|
+
*/
|
|
19
|
+
export declare function promptConfigureAdminAccess(baseUrl: string): Promise<ServerProfile | undefined>;
|
|
20
|
+
export declare function promptRemoveServer(baseUrl?: string): Promise<boolean>;
|
|
22
21
|
//# sourceMappingURL=server-switch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-switch.d.ts","sourceRoot":"","sources":["../../src/auth/server-switch.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAOL,KAAK,aAAa,EAEnB,MAAM,oBAAoB,CAAC;AAG5B;;GAEG;AACH,wBAAsB,
|
|
1
|
+
{"version":3,"file":"server-switch.d.ts","sourceRoot":"","sources":["../../src/auth/server-switch.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAOL,KAAK,aAAa,EAEnB,MAAM,oBAAoB,CAAC;AAG5B;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAqB1E;AAED,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAwBnF;AAED,wBAAsB,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAwE3F;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAyBpC;AAED,wBAAsB,kBAAkB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA8B3E"}
|
|
@@ -2,73 +2,14 @@
|
|
|
2
2
|
* Server 管理模块。
|
|
3
3
|
*
|
|
4
4
|
* 关键说明(中文)
|
|
5
|
-
* -
|
|
6
|
-
* -
|
|
7
|
-
* -
|
|
5
|
+
* - connect City 不再强制要求 admin_secret_key
|
|
6
|
+
* - admin access 只在低频管理场景中单独配置
|
|
7
|
+
* - server 仍然作为本地连接记录持久化保存
|
|
8
8
|
*/
|
|
9
9
|
import { City } from "@downcity/city";
|
|
10
10
|
import { isCancel, password, select, text } from "@clack/prompts";
|
|
11
11
|
import { addServer, readActiveServer, readConfig, readServer, removeServer, setActiveServer, updateServer, } from "../core/session.js";
|
|
12
|
-
import {
|
|
13
|
-
/**
|
|
14
|
-
* 确保至少存在一个 server。
|
|
15
|
-
*/
|
|
16
|
-
export async function ensureServerConfigured() {
|
|
17
|
-
if (readConfig().servers.length > 0) {
|
|
18
|
-
return true;
|
|
19
|
-
}
|
|
20
|
-
show("No servers configured. Add a server before continuing.");
|
|
21
|
-
const created = await promptAddServer();
|
|
22
|
-
if (!created) {
|
|
23
|
-
showError("No server configured. Exiting.");
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* 顶层 server 管理菜单。
|
|
30
|
-
*/
|
|
31
|
-
export async function manageServersMenu() {
|
|
32
|
-
while (true) {
|
|
33
|
-
const config = readConfig();
|
|
34
|
-
const active = readActiveServer();
|
|
35
|
-
const selected = await select({
|
|
36
|
-
message: active
|
|
37
|
-
? `Manage Servers [current: ${active.name}]`
|
|
38
|
-
: "Manage Servers [no active server]",
|
|
39
|
-
options: [
|
|
40
|
-
{ label: "List Servers", value: "list", hint: `${config.servers.length} configured` },
|
|
41
|
-
{ label: "Add Server", value: "add", hint: "Create a new Infra server profile" },
|
|
42
|
-
{ label: "Select Active Server", value: "select", hint: active ? active.base_url : "Choose current server" },
|
|
43
|
-
{ label: "Edit Server", value: "edit", hint: "Update name, server URL, or admin key" },
|
|
44
|
-
{ label: "Remove Server", value: "remove", hint: "Delete a server profile" },
|
|
45
|
-
{ label: "Back", value: "back", hint: "Return to main menu" },
|
|
46
|
-
],
|
|
47
|
-
});
|
|
48
|
-
if (!selected || isCancel(selected) || selected === "back") {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
if (selected === "list") {
|
|
52
|
-
printServers(config.servers, active?.base_url);
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
if (selected === "add") {
|
|
56
|
-
await promptAddServer();
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
if (selected === "select") {
|
|
60
|
-
await promptSelectActiveServer();
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
if (selected === "edit") {
|
|
64
|
-
await promptEditServer();
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
if (selected === "remove") {
|
|
68
|
-
await promptRemoveServer();
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
12
|
+
import { showError, showSuccess } from "../core/ui.js";
|
|
72
13
|
/**
|
|
73
14
|
* 添加 server。
|
|
74
15
|
*/
|
|
@@ -80,28 +21,23 @@ export async function promptAddServer() {
|
|
|
80
21
|
if (!baseUrl || isCancel(baseUrl) || !String(baseUrl).trim()) {
|
|
81
22
|
return undefined;
|
|
82
23
|
}
|
|
83
|
-
const adminSecretKey = await password({ message: "admin_secret_key" });
|
|
84
|
-
if (!adminSecretKey || isCancel(adminSecretKey) || !String(adminSecretKey).trim()) {
|
|
85
|
-
return undefined;
|
|
86
|
-
}
|
|
87
24
|
const server = addServer({
|
|
88
25
|
base_url: String(baseUrl).trim(),
|
|
89
|
-
admin_secret_key: String(adminSecretKey).trim(),
|
|
90
26
|
});
|
|
91
|
-
const verified = await
|
|
27
|
+
const verified = await verifyServerPublicAccess(server);
|
|
92
28
|
if (verified) {
|
|
93
|
-
showSuccess(`
|
|
29
|
+
showSuccess(`City connected: ${server.name}`);
|
|
94
30
|
}
|
|
95
31
|
else {
|
|
96
|
-
showError(`
|
|
32
|
+
showError(`City saved, but the public reachability check failed: ${server.name}`);
|
|
97
33
|
}
|
|
98
34
|
return server;
|
|
99
35
|
}
|
|
100
|
-
async function promptSelectActiveServer() {
|
|
36
|
+
export async function promptSelectActiveServer() {
|
|
101
37
|
const config = readConfig();
|
|
102
38
|
if (config.servers.length === 0) {
|
|
103
39
|
showError("No servers configured.");
|
|
104
|
-
return;
|
|
40
|
+
return undefined;
|
|
105
41
|
}
|
|
106
42
|
const selected = await select({
|
|
107
43
|
message: "Select active server",
|
|
@@ -112,18 +48,20 @@ async function promptSelectActiveServer() {
|
|
|
112
48
|
})),
|
|
113
49
|
});
|
|
114
50
|
if (!selected || isCancel(selected)) {
|
|
115
|
-
return;
|
|
51
|
+
return undefined;
|
|
116
52
|
}
|
|
117
|
-
|
|
118
|
-
|
|
53
|
+
const selected_base_url = String(selected);
|
|
54
|
+
setActiveServer(selected_base_url);
|
|
55
|
+
showSuccess(`Current City: ${selected_base_url}`);
|
|
56
|
+
return readServer(selected_base_url);
|
|
119
57
|
}
|
|
120
|
-
async function promptEditServer() {
|
|
58
|
+
export async function promptEditServer(baseUrl) {
|
|
121
59
|
const config = readConfig();
|
|
122
60
|
if (config.servers.length === 0) {
|
|
123
61
|
showError("No servers configured.");
|
|
124
|
-
return;
|
|
62
|
+
return undefined;
|
|
125
63
|
}
|
|
126
|
-
const targetBaseUrl = await select({
|
|
64
|
+
const targetBaseUrl = baseUrl ?? await select({
|
|
127
65
|
message: "Edit server",
|
|
128
66
|
options: config.servers.map((server) => ({
|
|
129
67
|
label: server.base_url === config.active_server_url ? `★ ${server.name}` : ` ${server.name}`,
|
|
@@ -132,12 +70,12 @@ async function promptEditServer() {
|
|
|
132
70
|
})),
|
|
133
71
|
});
|
|
134
72
|
if (!targetBaseUrl || isCancel(targetBaseUrl)) {
|
|
135
|
-
return;
|
|
73
|
+
return undefined;
|
|
136
74
|
}
|
|
137
75
|
const current = readServer(String(targetBaseUrl));
|
|
138
76
|
if (!current) {
|
|
139
77
|
showError("Selected server no longer exists.");
|
|
140
|
-
return;
|
|
78
|
+
return undefined;
|
|
141
79
|
}
|
|
142
80
|
const field = await select({
|
|
143
81
|
message: `Edit ${current.name}`,
|
|
@@ -149,43 +87,80 @@ async function promptEditServer() {
|
|
|
149
87
|
],
|
|
150
88
|
});
|
|
151
89
|
if (!field || isCancel(field) || field === "cancel") {
|
|
152
|
-
return;
|
|
90
|
+
return undefined;
|
|
153
91
|
}
|
|
154
92
|
const next = { ...current };
|
|
155
93
|
if (field === "name") {
|
|
156
94
|
const name = await text({ message: "Display name", initialValue: current.name });
|
|
157
95
|
if (!name || isCancel(name))
|
|
158
|
-
return;
|
|
96
|
+
return undefined;
|
|
159
97
|
next.name = String(name).trim() || current.name;
|
|
160
98
|
}
|
|
161
99
|
else if (field === "base_url") {
|
|
162
100
|
const baseUrl = await text({ message: "Server URL", initialValue: current.base_url });
|
|
163
101
|
if (!baseUrl || isCancel(baseUrl))
|
|
164
|
-
return;
|
|
102
|
+
return undefined;
|
|
165
103
|
next.base_url = String(baseUrl).trim() || current.base_url;
|
|
166
104
|
}
|
|
167
105
|
else if (field === "admin_secret_key") {
|
|
168
106
|
const adminSecretKey = await password({ message: "admin_secret_key" });
|
|
169
107
|
if (!adminSecretKey || isCancel(adminSecretKey))
|
|
170
|
-
return;
|
|
108
|
+
return undefined;
|
|
171
109
|
next.admin_secret_key = String(adminSecretKey).trim();
|
|
172
110
|
}
|
|
173
111
|
const updated = updateServer(current.base_url, next);
|
|
112
|
+
if (field === "admin_secret_key") {
|
|
113
|
+
const verified = await verifyServerAdminAccess(updated);
|
|
114
|
+
if (verified) {
|
|
115
|
+
showSuccess(`Admin access updated: ${updated.name}`);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
showError(`City saved, but admin verification failed: ${updated.name}`);
|
|
119
|
+
}
|
|
120
|
+
return updated;
|
|
121
|
+
}
|
|
122
|
+
const verified = await verifyServerPublicAccess(updated);
|
|
123
|
+
if (verified) {
|
|
124
|
+
showSuccess(`City updated: ${updated.name}`);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
showError(`City saved, but the public reachability check failed: ${updated.name}`);
|
|
128
|
+
}
|
|
129
|
+
return updated;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* 为当前 server 单独配置 admin access。
|
|
133
|
+
*/
|
|
134
|
+
export async function promptConfigureAdminAccess(baseUrl) {
|
|
135
|
+
const current = readServer(baseUrl);
|
|
136
|
+
if (!current) {
|
|
137
|
+
showError("Selected server no longer exists.");
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
const adminSecretKey = await password({ message: "admin_secret_key" });
|
|
141
|
+
if (!adminSecretKey || isCancel(adminSecretKey) || !String(adminSecretKey).trim()) {
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
const updated = updateServer(current.base_url, {
|
|
145
|
+
...current,
|
|
146
|
+
admin_secret_key: String(adminSecretKey).trim(),
|
|
147
|
+
});
|
|
174
148
|
const verified = await verifyServerAdminAccess(updated);
|
|
175
149
|
if (verified) {
|
|
176
|
-
showSuccess(`
|
|
150
|
+
showSuccess(`Admin access configured: ${updated.name}`);
|
|
177
151
|
}
|
|
178
152
|
else {
|
|
179
|
-
showError(`
|
|
153
|
+
showError(`City saved, but admin verification failed: ${updated.name}`);
|
|
180
154
|
}
|
|
155
|
+
return updated;
|
|
181
156
|
}
|
|
182
|
-
async function promptRemoveServer() {
|
|
157
|
+
export async function promptRemoveServer(baseUrl) {
|
|
183
158
|
const config = readConfig();
|
|
184
159
|
if (config.servers.length === 0) {
|
|
185
160
|
showError("No servers configured.");
|
|
186
|
-
return;
|
|
161
|
+
return false;
|
|
187
162
|
}
|
|
188
|
-
const selected = await select({
|
|
163
|
+
const selected = baseUrl ?? await select({
|
|
189
164
|
message: "Remove server",
|
|
190
165
|
options: [
|
|
191
166
|
...config.servers.map((server) => ({
|
|
@@ -197,13 +172,14 @@ async function promptRemoveServer() {
|
|
|
197
172
|
],
|
|
198
173
|
});
|
|
199
174
|
if (!selected || isCancel(selected) || selected === "cancel") {
|
|
200
|
-
return;
|
|
175
|
+
return false;
|
|
201
176
|
}
|
|
202
177
|
removeServer(String(selected));
|
|
203
178
|
const nextActive = readActiveServer();
|
|
204
179
|
showSuccess(nextActive
|
|
205
180
|
? `Server removed. Current server: ${nextActive.name}`
|
|
206
181
|
: "Server removed. No servers configured.");
|
|
182
|
+
return true;
|
|
207
183
|
}
|
|
208
184
|
async function verifyServerAdminAccess(server) {
|
|
209
185
|
try {
|
|
@@ -219,17 +195,18 @@ async function verifyServerAdminAccess(server) {
|
|
|
219
195
|
return false;
|
|
220
196
|
}
|
|
221
197
|
}
|
|
222
|
-
function
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
198
|
+
async function verifyServerPublicAccess(server) {
|
|
199
|
+
try {
|
|
200
|
+
const user = new City({
|
|
201
|
+
role: "user",
|
|
202
|
+
city_url: server.base_url,
|
|
203
|
+
});
|
|
204
|
+
await user.service("accounts").get("providers");
|
|
205
|
+
return true;
|
|
226
206
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
const marker = server.base_url === activeBaseUrl ? "★" : " ";
|
|
230
|
-
console.log(` ${marker} ${server.name.padEnd(24)} ${server.base_url} admin=${maskSecret(server.admin_secret_key)}`);
|
|
207
|
+
catch {
|
|
208
|
+
return false;
|
|
231
209
|
}
|
|
232
|
-
console.log("");
|
|
233
210
|
}
|
|
234
211
|
function maskSecret(value) {
|
|
235
212
|
const normalized = String(value ?? "").trim();
|