mn-ws 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/assets/groups.json +10 -0
  2. package/assets/mn-ws/SKILL.md +55 -0
  3. package/assets/mn-ws/hooks.json +14 -0
  4. package/assets/mn-ws/install/inject-root.mjs +26 -0
  5. package/bin/ws.mjs +13 -0
  6. package/dist/core/auth.d.ts +194 -0
  7. package/dist/core/auth.d.ts.map +1 -0
  8. package/dist/core/auth.js +331 -0
  9. package/dist/core/auth.js.map +1 -0
  10. package/dist/core/brand.d.ts +11 -0
  11. package/dist/core/brand.d.ts.map +1 -0
  12. package/dist/core/brand.js +7 -0
  13. package/dist/core/brand.js.map +1 -0
  14. package/dist/core/bridge.d.ts +106 -0
  15. package/dist/core/bridge.d.ts.map +1 -0
  16. package/dist/core/bridge.js +308 -0
  17. package/dist/core/bridge.js.map +1 -0
  18. package/dist/core/config.d.ts +174 -0
  19. package/dist/core/config.d.ts.map +1 -0
  20. package/dist/core/config.js +417 -0
  21. package/dist/core/config.js.map +1 -0
  22. package/dist/core/controller.d.ts +64 -0
  23. package/dist/core/controller.d.ts.map +1 -0
  24. package/dist/core/controller.js +100 -0
  25. package/dist/core/controller.js.map +1 -0
  26. package/dist/core/errors/index.d.ts +30 -0
  27. package/dist/core/errors/index.d.ts.map +1 -0
  28. package/dist/core/errors/index.js +88 -0
  29. package/dist/core/errors/index.js.map +1 -0
  30. package/dist/core/open.d.ts +3 -0
  31. package/dist/core/open.d.ts.map +1 -0
  32. package/dist/core/open.js +27 -0
  33. package/dist/core/open.js.map +1 -0
  34. package/dist/core/paths.d.ts +15 -0
  35. package/dist/core/paths.d.ts.map +1 -0
  36. package/dist/core/paths.js +50 -0
  37. package/dist/core/paths.js.map +1 -0
  38. package/dist/core/serve-port.d.ts +73 -0
  39. package/dist/core/serve-port.d.ts.map +1 -0
  40. package/dist/core/serve-port.js +134 -0
  41. package/dist/core/serve-port.js.map +1 -0
  42. package/dist/core/session.d.ts +78 -0
  43. package/dist/core/session.d.ts.map +1 -0
  44. package/dist/core/session.js +124 -0
  45. package/dist/core/session.js.map +1 -0
  46. package/dist/core/skills/bus.d.ts +29 -0
  47. package/dist/core/skills/bus.d.ts.map +1 -0
  48. package/dist/core/skills/bus.js +114 -0
  49. package/dist/core/skills/bus.js.map +1 -0
  50. package/dist/core/skills/get.d.ts +17 -0
  51. package/dist/core/skills/get.d.ts.map +1 -0
  52. package/dist/core/skills/get.js +87 -0
  53. package/dist/core/skills/get.js.map +1 -0
  54. package/dist/core/skills/handlers.d.ts +22 -0
  55. package/dist/core/skills/handlers.d.ts.map +1 -0
  56. package/dist/core/skills/handlers.js +86 -0
  57. package/dist/core/skills/handlers.js.map +1 -0
  58. package/dist/core/skills/index.d.ts +47 -0
  59. package/dist/core/skills/index.d.ts.map +1 -0
  60. package/dist/core/skills/index.js +268 -0
  61. package/dist/core/skills/index.js.map +1 -0
  62. package/dist/core/skills/install.d.ts +18 -0
  63. package/dist/core/skills/install.d.ts.map +1 -0
  64. package/dist/core/skills/install.js +123 -0
  65. package/dist/core/skills/install.js.map +1 -0
  66. package/dist/core/skills/text-util.d.ts +2 -0
  67. package/dist/core/skills/text-util.d.ts.map +1 -0
  68. package/dist/core/skills/text-util.js +14 -0
  69. package/dist/core/skills/text-util.js.map +1 -0
  70. package/dist/core/store.d.ts +29 -0
  71. package/dist/core/store.d.ts.map +1 -0
  72. package/dist/core/store.js +100 -0
  73. package/dist/core/store.js.map +1 -0
  74. package/dist/core/views.d.ts +11 -0
  75. package/dist/core/views.d.ts.map +1 -0
  76. package/dist/core/views.js +20 -0
  77. package/dist/core/views.js.map +1 -0
  78. package/dist/index.d.ts +6 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +8 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/modules/auth/index.d.ts +73 -0
  83. package/dist/modules/auth/index.d.ts.map +1 -0
  84. package/dist/modules/auth/index.js +64 -0
  85. package/dist/modules/auth/index.js.map +1 -0
  86. package/dist/modules/auth/service.d.ts +98 -0
  87. package/dist/modules/auth/service.d.ts.map +1 -0
  88. package/dist/modules/auth/service.js +200 -0
  89. package/dist/modules/auth/service.js.map +1 -0
  90. package/dist/modules/bridge/index.d.ts +73 -0
  91. package/dist/modules/bridge/index.d.ts.map +1 -0
  92. package/dist/modules/bridge/index.js +89 -0
  93. package/dist/modules/bridge/index.js.map +1 -0
  94. package/dist/modules/bridge/service.d.ts +75 -0
  95. package/dist/modules/bridge/service.d.ts.map +1 -0
  96. package/dist/modules/bridge/service.js +134 -0
  97. package/dist/modules/bridge/service.js.map +1 -0
  98. package/dist/modules/home/index.d.ts +95 -0
  99. package/dist/modules/home/index.d.ts.map +1 -0
  100. package/dist/modules/home/index.js +123 -0
  101. package/dist/modules/home/index.js.map +1 -0
  102. package/dist/modules/home/service.d.ts +48 -0
  103. package/dist/modules/home/service.d.ts.map +1 -0
  104. package/dist/modules/home/service.js +195 -0
  105. package/dist/modules/home/service.js.map +1 -0
  106. package/dist/modules/skill/index.d.ts +78 -0
  107. package/dist/modules/skill/index.d.ts.map +1 -0
  108. package/dist/modules/skill/index.js +132 -0
  109. package/dist/modules/skill/index.js.map +1 -0
  110. package/dist/runtime/api.d.ts +24 -0
  111. package/dist/runtime/api.d.ts.map +1 -0
  112. package/dist/runtime/api.js +140 -0
  113. package/dist/runtime/api.js.map +1 -0
  114. package/dist/runtime/cli.d.ts +23 -0
  115. package/dist/runtime/cli.d.ts.map +1 -0
  116. package/dist/runtime/cli.js +410 -0
  117. package/dist/runtime/cli.js.map +1 -0
  118. package/dist/runtime/help.d.ts +29 -0
  119. package/dist/runtime/help.d.ts.map +1 -0
  120. package/dist/runtime/help.js +89 -0
  121. package/dist/runtime/help.js.map +1 -0
  122. package/dist/runtime/registry.d.ts +318 -0
  123. package/dist/runtime/registry.d.ts.map +1 -0
  124. package/dist/runtime/registry.js +75 -0
  125. package/dist/runtime/registry.js.map +1 -0
  126. package/dist/runtime/server.d.ts +10 -0
  127. package/dist/runtime/server.d.ts.map +1 -0
  128. package/dist/runtime/server.js +127 -0
  129. package/dist/runtime/server.js.map +1 -0
  130. package/dist/runtime/spec.d.ts +32 -0
  131. package/dist/runtime/spec.d.ts.map +1 -0
  132. package/dist/runtime/spec.js +180 -0
  133. package/dist/runtime/spec.js.map +1 -0
  134. package/dist/runtime/types/action.d.ts +101 -0
  135. package/dist/runtime/types/action.d.ts.map +1 -0
  136. package/dist/runtime/types/action.js +19 -0
  137. package/dist/runtime/types/action.js.map +1 -0
  138. package/dist/runtime/types/client.d.ts +39 -0
  139. package/dist/runtime/types/client.d.ts.map +1 -0
  140. package/dist/runtime/types/client.js +2 -0
  141. package/dist/runtime/types/client.js.map +1 -0
  142. package/dist/runtime/types/http.d.ts +22 -0
  143. package/dist/runtime/types/http.d.ts.map +1 -0
  144. package/dist/runtime/types/http.js +6 -0
  145. package/dist/runtime/types/http.js.map +1 -0
  146. package/dist/runtime/types/module.d.ts +72 -0
  147. package/dist/runtime/types/module.d.ts.map +1 -0
  148. package/dist/runtime/types/module.js +15 -0
  149. package/dist/runtime/types/module.js.map +1 -0
  150. package/dist/web/public/assets/CliHints-BOxU-Duc.js +1 -0
  151. package/dist/web/public/assets/index-BTRKdMIW.js +50 -0
  152. package/dist/web/public/assets/index-BjGe8ggI.css +1 -0
  153. package/dist/web/public/assets/view-CE4tnCuy.js +1 -0
  154. package/dist/web/public/assets/view-CEQ2uPxE.js +1 -0
  155. package/dist/web/public/favicon-16.png +0 -0
  156. package/dist/web/public/favicon-32.png +0 -0
  157. package/dist/web/public/favicon-48.png +0 -0
  158. package/dist/web/public/favicon.ico +0 -0
  159. package/dist/web/public/index.html +19 -0
  160. package/dist/web/public/logo-rounded.png +0 -0
  161. package/dist/web/public/logo-rounded.svg +6 -0
  162. package/dist/web/public/logo.png +0 -0
  163. package/dist/web/public/logo.svg +6 -0
  164. package/package.json +52 -31
  165. package/README.md +0 -251
  166. package/bin/index.js +0 -714
  167. package/client/bridge-client.js +0 -160
  168. package/client/web.js +0 -234
  169. package/client/ws-client.js +0 -191
  170. package/lib/apps.js +0 -237
  171. package/lib/auth.js +0 -319
  172. package/lib/config.js +0 -534
  173. package/lib/index.js +0 -15
  174. package/lib/logger.js +0 -63
  175. package/lib/protocol.js +0 -208
  176. package/lib/store.js +0 -66
  177. package/server/auth.js +0 -274
  178. package/server/server.js +0 -752
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,417 @@
1
+ import fs from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ export function configDir() {
5
+ return process.env.MN_WS_HOME || path.join(os.homedir(), '.mn-ws');
6
+ }
7
+ export function configFile() {
8
+ return path.join(configDir(), 'config.json');
9
+ }
10
+ export function readConfigFile() {
11
+ try {
12
+ const f = configFile();
13
+ if (!fs.existsSync(f))
14
+ return {};
15
+ return JSON.parse(fs.readFileSync(f, 'utf8'));
16
+ }
17
+ catch {
18
+ return {};
19
+ }
20
+ }
21
+ /**
22
+ * 原子写整份配置文件:同目录 tmp(0600)→ fsync → rename。
23
+ *
24
+ * 必须整份替换而不是就地改:写入方不止一个(serve 会在注册成功后回写配置,
25
+ * 用户随时可能在另一个终端跑 auth login),半截文件被下一次读当成空配置,
26
+ * 等于把凭据静默清空。
27
+ */
28
+ export function writeConfigFile(nextRaw) {
29
+ const f = configFile();
30
+ fs.mkdirSync(path.dirname(f), { recursive: true });
31
+ const tmp = `${f}.${process.pid}.tmp`;
32
+ let fd = null;
33
+ try {
34
+ fd = fs.openSync(tmp, 'w', 0o600);
35
+ fs.writeFileSync(fd, `${JSON.stringify(nextRaw, null, 2)}\n`, 'utf8');
36
+ fs.fsyncSync(fd);
37
+ fs.closeSync(fd);
38
+ fd = null;
39
+ renameWithRetry(tmp, f);
40
+ }
41
+ catch (e) {
42
+ if (fd !== null) {
43
+ try {
44
+ fs.closeSync(fd);
45
+ }
46
+ catch { /* ignore */ }
47
+ }
48
+ try {
49
+ fs.unlinkSync(tmp);
50
+ }
51
+ catch { /* ignore */ }
52
+ throw e;
53
+ }
54
+ if (process.platform !== 'win32') {
55
+ try {
56
+ fs.chmodSync(f, 0o600);
57
+ }
58
+ catch { /* ignore */ }
59
+ }
60
+ return { file: f };
61
+ }
62
+ /** rename 在 Windows 上可能被扫描器占住(EPERM/EBUSY),带几次短重试。 */
63
+ function renameWithRetry(from, to) {
64
+ let lastErr = null;
65
+ for (let i = 0; i < 4; i += 1) {
66
+ try {
67
+ fs.renameSync(from, to);
68
+ return;
69
+ }
70
+ catch (e) {
71
+ lastErr = e;
72
+ const code = e.code;
73
+ if (code !== 'EPERM' && code !== 'EBUSY' && code !== 'EACCES')
74
+ throw e;
75
+ const until = Date.now() + 20;
76
+ while (Date.now() < until) { /* spin */ }
77
+ }
78
+ }
79
+ throw lastErr;
80
+ }
81
+ /** 第一个非空值。 */
82
+ export function pick(...vals) {
83
+ for (const v of vals) {
84
+ if (v !== undefined && v !== null && v !== '')
85
+ return v;
86
+ }
87
+ return undefined;
88
+ }
89
+ /**
90
+ * 取字符串值,缺省是**空串**。
91
+ *
92
+ * 为什么不能直接 String(pick(...)):pick 全空时返回 undefined,
93
+ * 而 `String(undefined)` 是字符串 **"undefined"** —— 不是空串!
94
+ * 于是 `if (!cfg.serverHttp)` 这类判空全部失效("undefined" 是真值),
95
+ * 表现为「配置里写着 undefined」这种没法一眼看出来的坏值。
96
+ * 这个坑真踩过:serverHttp 推不出地址,clientId 永远是 "undefined",
97
+ * 配置文件也从来不落盘。
98
+ */
99
+ export function str(v) {
100
+ return v === undefined || v === null ? '' : String(v);
101
+ }
102
+ /** 真值判定:1 / true / yes / on(大小写不敏感)。 */
103
+ export function isEnvTruthy(value) {
104
+ if (value === undefined || value === null)
105
+ return false;
106
+ const s = String(value).trim().toLowerCase();
107
+ return s === '1' || s === 'true' || s === 'yes' || s === 'on';
108
+ }
109
+ /** 布尔开关的严格解析;空 = 没表态(undefined),非法值直接抛错。 */
110
+ export function parseBoolFlag(v) {
111
+ if (v === undefined || v === null || v === '')
112
+ return undefined;
113
+ if (v === true || v === false)
114
+ return v;
115
+ const s = String(v).trim().toLowerCase();
116
+ if (['1', 'true', 'yes', 'on'].includes(s))
117
+ return true;
118
+ if (['0', 'false', 'no', 'off'].includes(s))
119
+ return false;
120
+ throw new Error(`布尔开关取值无法识别:${JSON.stringify(v)}(认 1/true/yes/on 与 0/false/no/off)`);
121
+ }
122
+ /** 从 ws://h:p/ws 推导 http://h:p。 */
123
+ export function httpBaseFromWs(wsUrl) {
124
+ try {
125
+ const u = new URL(String(wsUrl));
126
+ const proto = u.protocol === 'wss:' ? 'https:' : 'http:';
127
+ const port = u.port ? `:${u.port}` : '';
128
+ return `${proto}//${u.hostname}${port}`;
129
+ }
130
+ catch {
131
+ return '';
132
+ }
133
+ }
134
+ /** --apps "nx-kv,nx-rh" → ['nx-kv','nx-rh'];空 → [](= 不限,但实际仍需显式配置才开桥)。 */
135
+ export function parseApps(v) {
136
+ if (Array.isArray(v))
137
+ return v.map((x) => String(x).trim()).filter(Boolean);
138
+ if (!v)
139
+ return [];
140
+ return String(v).split(',').map((x) => x.trim()).filter(Boolean);
141
+ }
142
+ /**
143
+ * --ports "7877,7800" → [7877, 7800]
144
+ *
145
+ * 「本地 client 端选择可以开放的端口」——按端口选比按应用名选更贴近
146
+ * 用户的心智:他看到的是「nx-kv 跑在 7877」,不是「nx-kv 这个名字」。
147
+ */
148
+ export function parsePorts(v) {
149
+ if (Array.isArray(v))
150
+ return v.map((x) => Number(x)).filter((n) => Number.isFinite(n));
151
+ if (!v)
152
+ return [];
153
+ return String(v).split(',')
154
+ .map((x) => Number(x.trim()))
155
+ .filter((n) => Number.isFinite(n) && n > 0);
156
+ }
157
+ /**
158
+ * --app-map "nx-kv=http://127.0.0.1:7877" → { 'nx-kv': { base: '...' } }
159
+ *
160
+ * 为什么需要它:已知端口表只是**兜底默认值**,真实部署常改端口
161
+ * (换机、端口冲突、容器映射)。让用户能显式覆盖,比让程序去猜端口靠谱。
162
+ */
163
+ export function parseAppMap(v) {
164
+ const out = {};
165
+ if (!v)
166
+ return out;
167
+ for (const pair of String(v).split(',')) {
168
+ const s = pair.trim();
169
+ if (!s)
170
+ continue;
171
+ const eq = s.indexOf('=');
172
+ if (eq <= 0)
173
+ continue;
174
+ const app = s.slice(0, eq).trim();
175
+ const base = s.slice(eq + 1).trim();
176
+ if (app && base)
177
+ out[app] = { base };
178
+ }
179
+ return out;
180
+ }
181
+ /** 合并出最终配置。 */
182
+ export function loadClientConfig(flags = {}) {
183
+ const file = readConfigFile();
184
+ const env = process.env;
185
+ const cfg = {
186
+ url: str(pick(flags.url, env.MN_WS_URL, file.url, 'ws://1.94.101.189:7777/ws')),
187
+ serverHttp: str(pick(flags.serverHttp, env.MN_WS_SERVER_HTTP, file.serverHttp, '')),
188
+ token: str(pick(flags.token, env.MN_WS_TOKEN, file.token, '')),
189
+ clientId: str(pick(flags.clientId, env.MN_WS_CLIENT_ID, file.clientId, '')),
190
+ deviceName: str(pick(flags.deviceName, env.MN_WS_DEVICE_NAME, file.deviceName, os.hostname())),
191
+ account: str(pick(flags.account, env.MN_WS_ACCOUNT, file.account, '')),
192
+ apps: parseApps(pick(flags.apps, env.MN_WS_APPS, file.apps, '')),
193
+ ports: parsePorts(pick(flags.ports, env.MN_WS_PORTS, file.ports, '')),
194
+ appOverrides: parseAppMap(pick(flags.appMap, env.MN_WS_APP_MAP, '', '')),
195
+ webPort: Number(pick(flags.webPort, env.MN_WS_WEB_PORT, file.webPort, 7777)),
196
+ webHost: str(pick(flags.webHost, env.MN_WS_WEB_HOST, file.webHost, '127.0.0.1')),
197
+ noOpen: flags.noOpen === true || env.MN_WS_NO_OPEN === '1',
198
+ logLevel: str(pick(flags.logLevel, env.MN_WS_LOG_LEVEL, file.logLevel, 'info')),
199
+ requestTimeoutMs: Number(pick(flags.requestTimeout, env.MN_WS_REQUEST_TIMEOUT, file.requestTimeoutMs, 30_000)),
200
+ };
201
+ // serverHttp 缺省从 url 推导(ws://h:p/ws → http://h:p)
202
+ if (!cfg.serverHttp)
203
+ cfg.serverHttp = httpBaseFromWs(cfg.url);
204
+ // clientId 缺省自动生成并持久化
205
+ if (!cfg.clientId) {
206
+ cfg.clientId = ensureClientId();
207
+ file.clientId = cfg.clientId;
208
+ try {
209
+ writeConfigFile(file);
210
+ }
211
+ catch { /* ignore */ }
212
+ }
213
+ return cfg;
214
+ }
215
+ // ───────────────────────── 账号表 ─────────────────────────
216
+ /** 账号条目的稳定 key:优先 userId,其次邮箱/用户名/昵称。 */
217
+ export function entryKeyOf(entry) {
218
+ const e = entry || {};
219
+ return String(e.userId || e.email || e.username || e.nickname || e.clientId || '');
220
+ }
221
+ export function labelOf(entry) {
222
+ const e = entry || {};
223
+ return String(e.nickname || e.username || e.email || e.userId || e.clientId || '(未知账号)');
224
+ }
225
+ /**
226
+ * 视图:老配置的 flat 凭据被合成成首个条目。
227
+ *
228
+ * 这样「第二个人登录」不会把第一个人的登录态挤掉 —— 两个账号并存。
229
+ */
230
+ export function withAccounts(raw, { defaultClientId = '' } = {}) {
231
+ const base = raw || {};
232
+ const accounts = {
233
+ ...(base.accounts && typeof base.accounts === 'object' ? base.accounts : {}),
234
+ };
235
+ let activeAccountKey = String(base.activeAccount || '');
236
+ const flat = {
237
+ userId: base.userId,
238
+ email: base.email,
239
+ username: base.username,
240
+ nickname: base.nickname,
241
+ deviceToken: base.deviceToken,
242
+ expiresAt: base.expiresAt,
243
+ deviceName: base.deviceName,
244
+ clientId: base.clientId,
245
+ };
246
+ const hasFlat = Object.values(flat).some((v) => v !== undefined && v !== '');
247
+ if (hasFlat) {
248
+ const flatEntry = { ...flat };
249
+ let flatKey = entryKeyOf(flatEntry);
250
+ if (!flatKey) {
251
+ flatKey = 'local';
252
+ flatEntry.clientId = flatEntry.clientId || defaultClientId;
253
+ }
254
+ // flat 里没有的账号才补进去(flat 优先:它是「当前激活账号」的镜像)
255
+ if (!accounts[flatKey])
256
+ accounts[flatKey] = flatEntry;
257
+ if (!activeAccountKey)
258
+ activeAccountKey = flatKey;
259
+ }
260
+ return { accounts, activeAccountKey };
261
+ }
262
+ export function listAccounts(view) {
263
+ return Object.entries(view.accounts || {}).map(([key, entry]) => ({ key, entry }));
264
+ }
265
+ /** 把账号条目的运行期字段并进 flat(不动身份字段)。 */
266
+ function buildFlatSyncPatch(entry) {
267
+ const patch = {};
268
+ for (const k of ['url', 'deviceToken', 'expiresAt', 'userId', 'email', 'username', 'nickname', 'deviceName', 'clientId', 'serverHttp']) {
269
+ if (entry[k] !== undefined)
270
+ patch[k] = entry[k];
271
+ }
272
+ return patch;
273
+ }
274
+ /**
275
+ * 保存一次成功登录的账号,并激活它。
276
+ * @returns {{changed: boolean, key: string, file: string}}
277
+ */
278
+ export function saveAuthAccount({ entry, setActive = true }) {
279
+ const file = configFile();
280
+ const existing = readConfigFile();
281
+ const view = withAccounts(existing, { defaultClientId: ensureClientId() });
282
+ const key = entryKeyOf(entry);
283
+ const entryWithId = { ...entry, clientId: entry.clientId || ensureClientId() };
284
+ const accounts = { ...view.accounts, [key]: entryWithId };
285
+ const next = { ...existing, accounts };
286
+ if (setActive) {
287
+ next.activeAccount = key;
288
+ Object.assign(next, buildFlatSyncPatch(entryWithId));
289
+ }
290
+ const changed = JSON.stringify(existing) !== JSON.stringify(next);
291
+ if (changed)
292
+ writeConfigFile(next);
293
+ return { changed, key, file };
294
+ }
295
+ /** 设备令牌是否已过期。 */
296
+ export function isExpired(entry) {
297
+ if (!entry)
298
+ return true;
299
+ if (!entry.expiresAt)
300
+ return false;
301
+ return Date.now() >= entry.expiresAt;
302
+ }
303
+ /**
304
+ * 切换激活账号:设指针 + 把该账号条目打平成 flat。
305
+ * 跨部署切换时 url/serverHttp 必须一起走,否则会拿 A 服务器的令牌去连 B。
306
+ */
307
+ export function switchActiveAccount(target, { defaultClientId = '' } = {}) {
308
+ const file = configFile();
309
+ const existing = readConfigFile();
310
+ const view = withAccounts(existing, { defaultClientId });
311
+ const list = listAccounts(view);
312
+ if (!list.length)
313
+ throw new Error('本机还没有已存账号:先执行 npx mn-ws auth login');
314
+ let picked = null;
315
+ const t = String(target || '').trim();
316
+ if (t) {
317
+ const byKey = list.find((a) => a.key === t);
318
+ const byIdx = /^\d+$/.test(t) ? list[Number(t) - 1] : undefined;
319
+ const byField = list.find((a) => [a.entry.email, a.entry.username, a.entry.nickname].some((v) => v && String(v) === t));
320
+ picked = byKey || byIdx || byField || null;
321
+ if (!picked) {
322
+ throw new Error(`找不到账号「${t}」。本机已存:${list.map((a) => a.key).join(', ')}`);
323
+ }
324
+ }
325
+ else {
326
+ // 不带参数且只有一个账号:没有「切换」可言,直接说清楚
327
+ if (list.length === 1) {
328
+ const only = list[0];
329
+ const err = new Error(`本机只有 1 个账号:${labelOf(only.entry)}(clientId ${only.entry.clientId || '(无)'})`);
330
+ err.onlyOne = true;
331
+ err.entry = only.entry;
332
+ throw err;
333
+ }
334
+ return { changed: false, key: '', entry: {}, file };
335
+ }
336
+ const entry = { ...picked.entry, clientId: picked.entry.clientId || defaultClientId };
337
+ const next = {
338
+ ...existing,
339
+ accounts: { ...view.accounts, [picked.key]: entry },
340
+ activeAccount: picked.key,
341
+ ...buildFlatSyncPatch(entry),
342
+ };
343
+ const changed = JSON.stringify(existing) !== JSON.stringify(next);
344
+ if (changed)
345
+ writeConfigFile(next);
346
+ return { changed, key: picked.key, entry, file };
347
+ }
348
+ /** 清除登录凭据。 */
349
+ export function clearAuthCredentials({ all = false } = {}) {
350
+ const file = configFile();
351
+ const existing = readConfigFile();
352
+ const view = withAccounts(existing, { defaultClientId: ensureClientId() });
353
+ const next = { ...existing };
354
+ if (all) {
355
+ delete next.accounts;
356
+ delete next.activeAccount;
357
+ }
358
+ else if (view.activeAccountKey && view.accounts[view.activeAccountKey]) {
359
+ const accounts = { ...view.accounts };
360
+ delete accounts[view.activeAccountKey];
361
+ if (Object.keys(accounts).length)
362
+ next.accounts = accounts;
363
+ else
364
+ delete next.accounts;
365
+ if (next.activeAccount === view.activeAccountKey)
366
+ delete next.activeAccount;
367
+ }
368
+ for (const k of ['userId', 'email', 'username', 'nickname', 'deviceToken', 'expiresAt', 'clientId']) {
369
+ delete next[k];
370
+ }
371
+ const changed = JSON.stringify(existing) !== JSON.stringify(next);
372
+ if (changed)
373
+ writeConfigFile(next);
374
+ const remaining = next.accounts ? Object.keys(next.accounts).length : 0;
375
+ return { changed, file, remaining };
376
+ }
377
+ /** 本机标识:没有就生成一个并落盘。 */
378
+ export function ensureClientId() {
379
+ const file = readConfigFile();
380
+ if (file.clientId)
381
+ return String(file.clientId);
382
+ const id = generateClientId();
383
+ file.clientId = id;
384
+ try {
385
+ writeConfigFile(file);
386
+ }
387
+ catch { /* ignore */ }
388
+ return id;
389
+ }
390
+ /** 「主机名-6 位随机」生成 clientId。 */
391
+ export function generateClientId(exclude) {
392
+ const host = (os.hostname() || 'pc').toLowerCase().replace(/[^a-z0-9-]/g, '-').slice(0, 20);
393
+ const skip = exclude instanceof Set ? exclude : new Set();
394
+ for (let i = 0; i < 20; i += 1) {
395
+ const id = `${host}-${Math.random().toString(36).slice(2, 8)}`;
396
+ if (!skip.has(id))
397
+ return id;
398
+ }
399
+ return `${host}-${Math.random().toString(36).slice(2, 8)}`;
400
+ }
401
+ /** 保存本次连接用的参数(url / token 等)到配置文件。 */
402
+ export function saveConnectionConfig(cfg) {
403
+ const file = configFile();
404
+ const existing = readConfigFile();
405
+ const relevant = {};
406
+ for (const k of ['url', 'serverHttp', 'token', 'deviceName', 'clientId']) {
407
+ const v = cfg[k];
408
+ if (v)
409
+ relevant[k] = v;
410
+ }
411
+ const next = { ...existing, ...relevant };
412
+ const changed = JSON.stringify(existing) !== JSON.stringify(next);
413
+ if (changed)
414
+ writeConfigFile(next);
415
+ return { changed, file };
416
+ }
417
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import { WsBridgeClient, type BridgeStatus } from './bridge.js';
2
+ import { SessionManager } from './session.js';
3
+ import { type ClientConfig } from './config.js';
4
+ /**
5
+ * client 半的**运行时**:桥连接 + 登录态的**唯一归属**。
6
+ *
7
+ * 为什么要有这么一个中心:桥是**长驻**的东西,而模板的 action 模型是
8
+ * 「每个命令是一次调用」。面板上的「启停桥」「改白名单」要操作的是
9
+ * **同一个正在跑的连接**,所以必须有一个进程内的单例来持有它 ——
10
+ * 否则每个 action 各建各的连接,面板上点「断开」断的也不是那条真的在跑的。
11
+ *
12
+ * CLI 与面板共用这一个实例:命令行起的桥,面板里看得到状态、改得了白名单。
13
+ */
14
+ /** 白名单解析的结果。 */
15
+ export interface ResolvedApps {
16
+ /** app -> base */
17
+ apps: Record<string, string>;
18
+ /** 端口反查不到应用名时的提示 */
19
+ unknownPorts: number[];
20
+ }
21
+ export declare class MnWsController {
22
+ cfg: ClientConfig;
23
+ session: SessionManager;
24
+ client: WsBridgeClient | null;
25
+ lastStatus: BridgeStatus;
26
+ /** 面板实际监听的端口(运行时才知道,回调地址要用它) */
27
+ panelPort: number;
28
+ constructor(cfg: ClientConfig);
29
+ /**
30
+ * 解析白名单 → { app -> base }。
31
+ *
32
+ * **白名单说了算**:只有 --apps / --ports / --app-map 列出的应用才会被桥。
33
+ * 端口探测只用来显示状态,**绝不因为「扫到端口在监听」就自动开桥** ——
34
+ * 扫到就开桥等于把整台机器暴露出去。
35
+ */
36
+ resolveApps(): ResolvedApps;
37
+ /** 起桥。已连着就不重复起。 */
38
+ start(): {
39
+ started: boolean;
40
+ apps: string[];
41
+ reason?: string;
42
+ };
43
+ /** 停桥。 */
44
+ stop(): {
45
+ stopped: boolean;
46
+ reason?: string;
47
+ };
48
+ /** 当前状态快照(面板与 CLI 共用同一份)。 */
49
+ status(): BridgeStatus & {
50
+ url: string;
51
+ apps: string[];
52
+ clientId: string;
53
+ };
54
+ }
55
+ /**
56
+ * 取进程内的控制器单例。
57
+ *
58
+ * 第一次调用时按当前配置创建;之后一直复用 ——
59
+ * 面板上的操作要作用在**正在跑的那条桥**上,不能各建各的。
60
+ */
61
+ export declare function getController(overrides?: Record<string, unknown>): MnWsController;
62
+ /** 重新读配置并替换单例(改了配置之后用)。 */
63
+ export declare function resetController(overrides?: Record<string, unknown>): MnWsController;
64
+ //# sourceMappingURL=controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/core/controller.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAElE;;;;;;;;;GASG;AAEH,gBAAgB;AAChB,MAAM,WAAW,YAAY;IAC3B,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,oBAAoB;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,qBAAa,cAAc;IACzB,GAAG,EAAE,YAAY,CAAC;IAClB,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,cAAc,GAAG,IAAI,CAAQ;IACrC,UAAU,EAAE,YAAY,CAAqB;IAC7C,gCAAgC;IAChC,SAAS,SAAK;gBAEF,GAAG,EAAE,YAAY;IAK7B;;;;;;OAMG;IACH,WAAW,IAAI,YAAY;IAqB3B,mBAAmB;IACnB,KAAK,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAoB9D,UAAU;IACV,IAAI,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAQ7C,6BAA6B;IAC7B,MAAM,IAAI,YAAY,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;CAQ3E;AAID;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,cAAc,CAKrF;AAED,2BAA2B;AAC3B,wBAAgB,eAAe,CAAC,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,cAAc,CAGvF"}
@@ -0,0 +1,100 @@
1
+ import { KNOWN_APPS } from 'mn-ws-server/apps';
2
+ import { WsBridgeClient } from './bridge.js';
3
+ import { SessionManager } from './session.js';
4
+ import { loadClientConfig } from './config.js';
5
+ export class MnWsController {
6
+ cfg;
7
+ session;
8
+ client = null;
9
+ lastStatus = { state: 'idle' };
10
+ /** 面板实际监听的端口(运行时才知道,回调地址要用它) */
11
+ panelPort = 0;
12
+ constructor(cfg) {
13
+ this.cfg = cfg;
14
+ this.session = new SessionManager(cfg);
15
+ }
16
+ /**
17
+ * 解析白名单 → { app -> base }。
18
+ *
19
+ * **白名单说了算**:只有 --apps / --ports / --app-map 列出的应用才会被桥。
20
+ * 端口探测只用来显示状态,**绝不因为「扫到端口在监听」就自动开桥** ——
21
+ * 扫到就开桥等于把整台机器暴露出去。
22
+ */
23
+ resolveApps() {
24
+ const wanted = new Set(this.cfg.apps || []);
25
+ const unknownPorts = [];
26
+ // 按端口反查应用名
27
+ for (const port of this.cfg.ports || []) {
28
+ const hit = Object.entries(KNOWN_APPS).find(([, info]) => info.port === port);
29
+ if (hit)
30
+ wanted.add(hit[0]);
31
+ else
32
+ unknownPorts.push(port);
33
+ }
34
+ const apps = {};
35
+ for (const app of wanted) {
36
+ const base = (this.cfg.appOverrides[app] && this.cfg.appOverrides[app].base) ||
37
+ (KNOWN_APPS[app] ? `http://127.0.0.1:${KNOWN_APPS[app].port}` : '');
38
+ if (base)
39
+ apps[app] = base;
40
+ }
41
+ return { apps, unknownPorts };
42
+ }
43
+ /** 起桥。已连着就不重复起。 */
44
+ start() {
45
+ const { apps, unknownPorts } = this.resolveApps();
46
+ const names = Object.keys(apps);
47
+ if (!names.length) {
48
+ return { started: false, apps: [], reason: '白名单为空 —— 一个都不桥(用 --apps 指定)' };
49
+ }
50
+ if (this.client) {
51
+ return { started: false, apps: names, reason: '桥已在运行' };
52
+ }
53
+ this.client = new WsBridgeClient({
54
+ url: this.cfg.url,
55
+ token: this.session.credential() || this.cfg.token,
56
+ bridgeId: this.cfg.clientId,
57
+ apps,
58
+ onStatus: (s) => { this.lastStatus = s; },
59
+ });
60
+ this.client.start();
61
+ return { started: true, apps: names, reason: unknownPorts.length ? `端口未在已知服务表:${unknownPorts.join(', ')}` : undefined };
62
+ }
63
+ /** 停桥。 */
64
+ stop() {
65
+ if (!this.client)
66
+ return { stopped: false, reason: '桥没在跑' };
67
+ this.client.stop();
68
+ this.client = null;
69
+ this.lastStatus = { state: 'stopped' };
70
+ return { stopped: true };
71
+ }
72
+ /** 当前状态快照(面板与 CLI 共用同一份)。 */
73
+ status() {
74
+ return {
75
+ ...this.lastStatus,
76
+ url: this.cfg.url,
77
+ apps: Object.keys(this.resolveApps().apps),
78
+ clientId: this.cfg.clientId,
79
+ };
80
+ }
81
+ }
82
+ let singleton = null;
83
+ /**
84
+ * 取进程内的控制器单例。
85
+ *
86
+ * 第一次调用时按当前配置创建;之后一直复用 ——
87
+ * 面板上的操作要作用在**正在跑的那条桥**上,不能各建各的。
88
+ */
89
+ export function getController(overrides = {}) {
90
+ if (!singleton) {
91
+ singleton = new MnWsController(loadClientConfig(overrides));
92
+ }
93
+ return singleton;
94
+ }
95
+ /** 重新读配置并替换单例(改了配置之后用)。 */
96
+ export function resetController(overrides = {}) {
97
+ singleton = new MnWsController(loadClientConfig(overrides));
98
+ return singleton;
99
+ }
100
+ //# sourceMappingURL=controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller.js","sourceRoot":"","sources":["../../src/core/controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export declare const CODES: {
2
+ readonly INVALID_INPUT: "INVALID_INPUT";
3
+ readonly NOT_FOUND: "NOT_FOUND";
4
+ readonly CONFLICT: "CONFLICT";
5
+ readonly BLOCKED: "BLOCKED";
6
+ readonly EXTERNAL: "EXTERNAL";
7
+ readonly SPEC_ERROR: "SPEC_ERROR";
8
+ readonly INTERNAL: "INTERNAL";
9
+ };
10
+ export type ErrorCode = (typeof CODES)[keyof typeof CODES];
11
+ export declare class NxError extends Error {
12
+ code: ErrorCode;
13
+ details?: unknown;
14
+ constructor(code: ErrorCode, message: string, details?: unknown);
15
+ }
16
+ export interface ErrorPayload {
17
+ code: ErrorCode;
18
+ message: string;
19
+ details?: unknown;
20
+ }
21
+ export declare function httpStatusOf(code: ErrorCode): number;
22
+ export declare function exitCodeOf(code: ErrorCode): number;
23
+ export declare function toErrorPayload(err: unknown): ErrorPayload;
24
+ export declare const badInput: (message: string, details?: unknown) => NxError;
25
+ export declare const notFound: (message: string, details?: unknown) => NxError;
26
+ export declare const conflict: (message: string, details?: unknown) => NxError;
27
+ export declare const blocked: (message: string, details?: unknown) => NxError;
28
+ export declare const external: (message: string, details?: unknown) => NxError;
29
+ export declare const specError: (message: string, details?: unknown) => NxError;
30
+ //# sourceMappingURL=index.d.ts.map