@sfmc-bds/cli 0.4.5 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/management/server.js +1 -1
- package/dist/management/server.js.map +2 -2
- package/dist/module-commands.d.ts.map +1 -1
- package/dist/module-commands.js +9 -3
- package/dist/module-commands.js.map +2 -2
- package/dist/services.js +1 -1
- package/dist/services.js.map +2 -2
- package/dist/wizard.js +1 -1
- package/dist/wizard.js.map +2 -2
- package/package.json +5 -5
- package/scripts/module-install/fetch-module.mjs +6 -2
|
@@ -241,7 +241,7 @@ async function dispatchManagement(request) {
|
|
|
241
241
|
context.phase("preflight", "\u68C0\u67E5\u76EE\u5F55\u3001\u78C1\u76D8\u7A7A\u95F4\u548C TCP\uFF0FUDP \u7AEF\u53E3");
|
|
242
242
|
await deploymentPreflight(ports);
|
|
243
243
|
context.phase("prepare");
|
|
244
|
-
ensureCoreConfigs(ROOT, ["db_config", "qq_config", "bds_updater", "permissions"]);
|
|
244
|
+
ensureCoreConfigs(ROOT, ["db_config", "qq_config", "bds_updater", "permissions", "qq_link"]);
|
|
245
245
|
const updater = path.join(ROOT, "configs", "bds_updater.json");
|
|
246
246
|
atomicJson(updater, { ...readJson(updater, {}), bds_path: "BDS", backup_dir: "backups" });
|
|
247
247
|
const dbFile = path.join(ROOT, "configs", "db_config.json");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/management/server.ts"],
|
|
4
|
-
"sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport { EventEmitter } from \"node:events\";\nimport { MANAGEMENT_PROTOCOL_VERSION, type ManagementRequest, type ManagementEvent } from \"@sfmc-bds/management\";\nimport { ROOT, isRuntimeInitialized, spawnService } from \"../runtime.js\";\nimport { queryServicesRuntimeLocal, services, START_ORDER, SERVICE_NAMES, refreshServices, onServiceStateChange, type ServiceName } from \"../services.js\";\nimport { readDiskLogs, onLog } from \"../logs.js\";\nimport { cmdModuleEnable, cmdModuleDisable } from \"../module-commands.js\";\nimport { ensureCoreConfigs } from \"@sfmc-bds/sdk/node/config\";\nimport { TaskStore, atomicJson, type TaskContext } from \"./tasks.js\";\nimport { configFiles, readDocument, saveDocument, validateDocument } from \"./config.js\";\nimport { listModules, searchModules, identifier, runFetch, readJson, listPacks, togglePack, importPack, playerFiles, savePlayerPermissions, modulePlan, applyModulePlan } from \"./domain.js\";\nimport { attachmentPlan, platformVersion, withStoppedServices, launchPlatformUpdate, restoreSnapshot, verifyRunning } from \"./maintenance.js\";\nimport { startupPlan } from \"./startup.js\";\nimport { cmdPackBuild, cmdPackDeploy } from \"../pack-lifecycle.js\";\nimport { withMaintenanceLock } from \"@sfmc-bds/management/node\";\nimport { deploymentPreflight, deploymentPort } from \"./deployment.js\";\nimport { resolveBdsContext } from \"../pack-lifecycle.js\";\n\nconst events = new EventEmitter();\n/** \u7A7A\u76EE\u5F55\u4E5F\u8981\u80FD\u5B8C\u6210\u63E1\u624B\uFF0C\u4F9B\u684C\u9762\u521D\u59CB\u5316\u5411\u5BFC\u7EE7\u7EED\uFF1B\u65E7\u90E8\u7F72\u4ECD\u8BC6\u522B\u5DF2\u6709 BDS\u3002 */\nfunction deploymentInitialized(): boolean {\n if (isRuntimeInitialized()) return true;\n const config = readJson<{ bds_path?: string }>(path.join(ROOT, \"configs\", \"bds_updater.json\"), {});\n if (!config.bds_path) return false;\n return fs.existsSync(path.join(resolveBdsContext().bdsRoot, process.platform === \"win32\" ? \"bedrock_server.exe\" : \"bedrock_server\"));\n}\nlet tasks: TaskStore | undefined;\nexport function managementTasks() {\n if (!tasks) {\n tasks = new TaskStore(ROOT);\n tasks.on(\"operation\", payload => events.emit(\"event\", { type: \"event\", event: \"operation\", instanceId: ROOT, payload }));\n onLog(log => events.emit(\"event\", { type: \"event\", event: \"log\", instanceId: ROOT, payload: { ...log, time: log.time.toISOString() } }));\n onServiceStateChange(payload => events.emit(\"event\", { type: \"event\", event: \"serviceState\", instanceId: ROOT, payload }));\n }\n return tasks;\n}\nexport function onManagementEvent(callback: (event: ManagementEvent) => void) { events.on(\"event\", callback); return () => events.off(\"event\", callback); }\nfunction params(request: ManagementRequest): Record<string, unknown> {\n if (request.params === undefined) return {};\n if (!request.params || typeof request.params !== \"object\" || Array.isArray(request.params)) throw new Error(\"\u53C2\u6570\u5FC5\u987B\u4E3A\u5BF9\u8C61\");\n return request.params as Record<string, unknown>;\n}\nfunction string(value: unknown, label: string) { if (typeof value !== \"string\" || value.length > 2 * 1024 * 1024) throw new Error(`\u975E\u6CD5 ${label}`); return value; }\nfunction service(value: unknown): ServiceName { if (!SERVICE_NAMES.includes(value as ServiceName)) throw new Error(\"\u672A\u77E5\u670D\u52A1\"); return value as ServiceName; }\nasync function rebuildModules() {\n const build = await cmdPackBuild([]); if (!build.ok) throw new Error(build.message);\n const deploy = await cmdPackDeploy([]); if (!deploy.ok) throw new Error(deploy.message);\n return { changed: true };\n}\nasync function players() {\n const files = playerFiles(); const allowlist = readJson<unknown[]>(files.allowlist, []);\n const cfg = readJson<{ db_port?: number; http_auth?: string }>(path.join(ROOT, \"configs\", \"db_config.json\"), {});\n let data: { online?: { name: string }[]; updatedAt?: number } = {};\n try {\n const response = await fetch(`http://127.0.0.1:${cfg.db_port ?? 3001}/api/sfmc/status`, { headers: cfg.http_auth ? { authorization: `Bearer ${cfg.http_auth}` } : {}, signal: AbortSignal.timeout(5000) });\n if (response.ok) data = await response.json() as typeof data;\n } catch { /* \u672A\u8FDE\u63A5\u65F6\u4F7F\u7528\u672A\u77E5\u72B6\u6001 */ }\n const fresh = typeof data.updatedAt === \"number\" && Date.now() - data.updatedAt < 60_000;\n return { players: (data.online ?? []).map(row => ({ name: row.name, xuid: \"\", online: fresh ? true : null })), updatedAt: data.updatedAt ? new Date(data.updatedAt).toISOString() : \"\", fresh, allowlist, permissions: readJson<unknown[]>(files.permissions, []), sfmcPermissions: readJson<unknown[]>(files.sfmcPermissions, []) };\n}\nasync function bdsUpdate(context: TaskContext, checkOnly = false) {\n context.phase(\"download\", checkOnly ? \"\u68C0\u67E5 BDS \u66F4\u65B0\" : \"\u66F4\u65B0 BDS\");\n const args = checkOnly ? [\"--check-only\", \"--no-notify\"] : [\"--no-start\", \"--no-notify\"];\n let output = \"\";\n await new Promise<void>((resolve, reject) => {\n const child = spawnService(\"update\", args, { stdio: \"pipe\", cwd: ROOT });\n for (const stream of [child.stdout, child.stderr]) stream?.on(\"data\", chunk => { output = (output + String(chunk)).slice(-64_000); });\n child.on(\"error\", reject); child.on(\"close\", code => code === 0 ? resolve() : reject(new Error(`BDS \u66F4\u65B0\u5931\u8D25 (${code})`)));\n });\n return { checked: checkOnly, updated: /SFMC_UPDATE_RESULT=deployed/.test(output), currentVersion: /CURRENT=([^\\r\\n]+)/.exec(output)?.[1] ?? \"unknown\", latestVersion: /LATEST=([^\\r\\n]+)/.exec(output)?.[1] ?? \"unknown\", result: /SFMC_UPDATE_RESULT=([^\\r\\n]+)/.exec(output)?.[1] ?? \"unknown\" };\n}\nexport async function dispatchManagement(request: ManagementRequest): Promise<unknown> {\n const p = params(request); const store = managementTasks();\n switch (request.method) {\n case \"handshake\": return { protocolVersion: MANAGEMENT_PROTOCOL_VERSION, platformVersion: platformVersion(), host: { os: process.platform === \"win32\" ? \"windows\" : process.platform, arch: process.arch, release: os.release() }, root: ROOT, capabilities: [\"services\", \"logs\", \"modules\", \"config\", \"packs\", \"players\", \"updates\", \"operations\", \"metrics\"], daemonPid: process.pid, daemonStartedAt: new Date(Date.now() - process.uptime() * 1000).toISOString(), initialized: deploymentInitialized() };\n case \"events.subscribe\": return { subscribed: true };\n case \"services.list\": return { rows: await queryServicesRuntimeLocal() };\n case \"services.start\": case \"services.stop\": case \"services.restart\": {\n const names = p.name === \"all\" ? [...START_ORDER] : [service(p.name)];\n return store.submit(request.method, async context => {\n context.phase(\"execute\");\n const rows = await queryServicesRuntimeLocal();\n if (rows.some(row => names.includes(row.name) && row.running && row.ownership === \"external\") && request.method !== \"services.start\") throw new Error(\"\u5916\u90E8\u8FDB\u7A0B\u65E0\u6CD5\u5B89\u5168\u505C\u6B62\uFF0C\u8BF7\u901A\u8FC7\u539F\u7BA1\u7406\u5668\u64CD\u4F5C\");\n if (request.method !== \"services.start\") for (const name of [...names].reverse()) await services[name].stop(false, false);\n if (request.method !== \"services.stop\") {\n const outcomes = [];\n for (const name of names) outcomes.push({ name, ...(await services[name].start()) });\n await verifyRunning(outcomes.filter(row => row.status !== \"skipped\").map(row => row.name));\n return { outcomes };\n }\n return { stopped: names };\n });\n }\n case \"services.send\": {\n const name = service(p.name); const message = string(p.message, \"\u547D\u4EE4\");\n if (/[\\r\\n]/.test(message) || !message.trim()) throw new Error(\"\u4E00\u6B21\u53EA\u80FD\u53D1\u9001\u4E00\u884C\u547D\u4EE4\");\n const target = services[name]; if (!target.proc?.stdin || !target.running) throw new Error(\"\u670D\u52A1\u672A\u6258\u7BA1\u6216\u6CA1\u6709\u547D\u4EE4\u8F93\u5165\u901A\u9053\");\n return withMaintenanceLock(ROOT, async () => { target.proc!.stdin!.write(message + \"\\n\"); return { delivered: true }; });\n }\n case \"logs.tail\": return { entries: readDiskLogs({ limit: Math.min(5000, Math.max(1, Number(p.limit) || 1000)), ...(Array.isArray(p.sources) ? { sources: p.sources.map(value => string(value, \"\u65E5\u5FD7\u6765\u6E90\")) } : {}), ...(Array.isArray(p.levels) ? { levels: p.levels as (\"info\" | \"warn\" | \"error\")[] } : {}) }).map(log => ({ ...log, time: log.time.toISOString() })) };\n case \"operations.list\": return { operations: store.list().filter(row => !Array.isArray(p.statuses) || p.statuses.includes(row.status)).slice(0, Math.min(Number(p.limit) || 100, 200)) };\n case \"operations.get\": return { operation: store.get(string(p.operationId, \"\u4EFB\u52A1\u7F16\u53F7\")) };\n case \"modules.list\": return listModules();\n case \"modules.search\": return searchModules(typeof p.query === \"string\" ? p.query : \"\");\n case \"modules.install\": case \"modules.uninstall\": case \"modules.toggle\": {\n const id = identifier(p.id);\n if (request.method !== \"modules.toggle\") {\n const linked = (await listModules()).modules.find(row => row.id === id || row.folder === id)?.linked;\n if (linked) throw new Error(\"\u4FDD\u7559\u672C\u5730\u94FE\u63A5\u6A21\u5757\uFF0C\u4E0D\u901A\u8FC7\u5305\u5B89\u88C5\u6216\u5378\u8F7D\u8986\u76D6\u5F00\u53D1\u76EE\u5F55\");\n }\n return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], async () => {\n if (request.method === \"modules.toggle\") {\n const result = await (p.enabled === true ? cmdModuleEnable([id]) : cmdModuleDisable([id])); if (!result.ok) throw new Error(result.message);\n } else {\n const args = [request.method === \"modules.install\" ? \"install\" : \"uninstall\", id];\n if (request.method === \"modules.install\" && typeof p.source === \"string\" && p.source) args.push(\"--from\", p.source);\n await runFetch(args);\n }\n return rebuildModules();\n }, true, \"modules\"));\n }\n case \"config.list\": return { keys: [...configFiles().keys()] };\n case \"config.read\": return readDocument(string(p.key, \"\u914D\u7F6E\u540D\u79F0\"));\n case \"config.apply\": {\n const key = string(p.key, \"\u914D\u7F6E\u540D\u79F0\"); const text = string(p.text, \"\u914D\u7F6E\u5185\u5BB9\"); const expected = string(p.revision, \"\u914D\u7F6E\u7248\u672C\");\n const document = readDocument(key); validateDocument(document, text);\n if (document.revision !== expected) throw Object.assign(new Error(\"\u914D\u7F6E\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\"), { code: \"conflict\" });\n return store.submit(request.method, async context => {\n let saved = false;\n try { return await withStoppedServices(context, [...START_ORDER], async () => {\n saveDocument(key, expected, text); context.phase(\"apply\", \"\u6587\u4EF6\u5DF2\u4FDD\u5B58\uFF0C\u6B63\u5728\u5E94\u7528\u8FD0\u884C\u914D\u7F6E\");\n saved = true;\n refreshServices(); return { saved: true, revision: readDocument(key).revision, applied: true };\n }); } catch (error) { throw Object.assign(new Error(`${saved ? \"\u6587\u4EF6\u5DF2\u4FDD\u5B58\uFF0C\u8FD0\u884C\u65F6\u5E94\u7528\u5931\u8D25\" : \"\u914D\u7F6E\u672A\u4FDD\u5B58\"}: ${error instanceof Error ? error.message : String(error)}`), { code: \"io\", details: { saved, applied: false, backupId: context.id } }); }\n });\n }\n case \"packs.list\": return listPacks();\n case \"packs.import\": return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], () => importPack(identifier(p.filename))));\n case \"packs.toggle\": return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], () => togglePack(identifier(p.id), p.enabled === true)));\n case \"players.list\": return players();\n case \"metrics.read\": {\n const cfg = readJson<{ db_port?: number; http_auth?: string }>(path.join(ROOT, \"configs\", \"db_config.json\"), {});\n try {\n const response = await fetch(`http://127.0.0.1:${cfg.db_port ?? 3001}/api/sfmc/metrics`, { headers: cfg.http_auth ? { authorization: `Bearer ${cfg.http_auth}` } : {}, signal: AbortSignal.timeout(10_000) });\n if (!response.ok) throw new Error(`\u8FD0\u884C\u6307\u6807\u8BFB\u53D6\u5931\u8D25 (${response.status})`);\n return response.json();\n } catch (error) {\n const detail = error instanceof Error ? `${error.message} ${String(error.cause ?? \"\")}` : String(error);\n // \u6570\u636E\u670D\u52A1\u6CA1\u5F00\u65F6 fetch \u4F1A\u629B\u7F51\u7EDC\u9519\u8BEF\uFF1B\u754C\u9762\u7528 note \u5C55\u793A\uFF0C\u800C\u4E0D\u662F\u6574\u9875\u5931\u8D25\u3002\n if (/fetch failed|ECONNREFUSED|ENOTFOUND|AbortError|TimeoutError|timed out/i.test(detail)) {\n return { fresh: false, updatedAt: null, current: null, history: [], host: null, processes: null, resourcesUpdatedAt: null, note: \"\u6570\u636E\u670D\u52A1\u672A\u8FD0\u884C\uFF0C\u6682\u65F6\u6CA1\u6709\u8FD0\u884C\u6307\u6807\" };\n }\n throw error;\n }\n }\n case \"players.apply\": return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], async () => savePlayerPermissions(string(p.kind, \"\u6743\u9650\u7C7B\u578B\"), p.entries)));\n case \"attachment.plan\": return attachmentPlan();\n case \"attachment.apply\": return store.submit(request.method, async context => {\n const plan = await attachmentPlan(false);\n if (p.targetVersion !== undefined && p.targetVersion !== plan.targetVersion) throw Object.assign(new Error(\"\u76EE\u6807\u7248\u672C\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u66F4\u65B0\u65E5\u5FD7\u540E\u786E\u8BA4\"), { code: \"conflict\" });\n if (plan.externalServices.length) throw new Error(\"\u65E0\u6CD5\u53EF\u9760\u8FC1\u79FB\u5916\u90E8\u8FDB\u7A0B\uFF1B\u8BF7\u5148\u901A\u8FC7\u539F\u7BA1\u7406\u5668\u4F18\u96C5\u505C\u670D\");\n if (plan.upgradeRequired) return launchPlatformUpdate(store, context, plan.targetVersion);\n return { attached: true, version: plan.currentVersion, development: plan.development };\n });\n case \"updates.check\": {\n const results = await Promise.allSettled([attachmentPlan(), modulePlan(), bdsUpdate({ id: \"check\", phase: () => {} }, true)]);\n return Object.fromEntries(results.map((result, index) => [[\"platform\", \"modules\", \"bds\"][index], result.status === \"fulfilled\" ? result.value : { error: String(result.reason) }]));\n }\n case \"updates.run\": {\n if (p.kind === \"platform\") return store.submit(request.method, async context => { const plan = await attachmentPlan(false); if (p.targetVersion !== undefined && p.targetVersion !== plan.targetVersion) throw Object.assign(new Error(\"\u76EE\u6807\u7248\u672C\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u66F4\u65B0\u65E5\u5FD7\u540E\u786E\u8BA4\"), { code: \"conflict\" }); return plan.upgradeRequired ? launchPlatformUpdate(store, context, plan.targetVersion) : { upToDate: true, version: plan.currentVersion }; });\n if (p.kind === \"modules\") return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], async () => { const result = await applyModulePlan(Array.isArray(p.ids) ? p.ids.map(identifier) : []); await rebuildModules(); return result; }, true, \"modules\"));\n if (p.kind === \"bds\") return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], () => bdsUpdate(context), true, \"bds\"));\n throw new Error(\"\u672A\u77E5\u66F4\u65B0\u7C7B\u578B\");\n }\n case \"deployment.create\": {\n if (p.acceptEula !== true) throw new Error(\"\u521B\u5EFA\u90E8\u7F72\u524D\u5FC5\u987B\u786E\u8BA4 BDS \u4F7F\u7528\u6761\u6B3E\");\n return store.submit(request.method, async context => {\n if (isRuntimeInitialized()) throw new Error(\"\u76EE\u5F55\u5DF2\u7ECF\u521D\u59CB\u5316\uFF0C\u4E0D\u8986\u76D6\u5DF2\u6709\u90E8\u7F72\");\n const ports = { db: deploymentPort(p.dbPort, 3001), bds: deploymentPort(p.bdsPort, 19132), bds6: deploymentPort(p.bdsPort6, 19133) };\n context.phase(\"preflight\", \"\u68C0\u67E5\u76EE\u5F55\u3001\u78C1\u76D8\u7A7A\u95F4\u548C TCP\uFF0FUDP \u7AEF\u53E3\"); await deploymentPreflight(ports);\n context.phase(\"prepare\"); ensureCoreConfigs(ROOT, [\"db_config\", \"qq_config\", \"bds_updater\", \"permissions\"]);\n const updater = path.join(ROOT, \"configs\", \"bds_updater.json\");\n atomicJson(updater, { ...readJson(updater, {}), bds_path: \"BDS\", backup_dir: \"backups\" });\n const dbFile = path.join(ROOT, \"configs\", \"db_config.json\"); atomicJson(dbFile, { ...readJson(dbFile, {}), db_port: ports.db });\n fs.mkdirSync(path.join(ROOT, \"modules\", \"packages\"), { recursive: true });\n await bdsUpdate(context);\n const properties = path.join(ROOT, \"BDS\", \"server.properties\");\n let text = fs.readFileSync(properties, \"utf8\");\n for (const [key, port] of [[\"server-port\", ports.bds], [\"server-portv6\", ports.bds6]] as const) text = text.replace(new RegExp(`^${key}=.*$`, \"m\"), `${key}=${port}`);\n fs.writeFileSync(properties, text);\n await rebuildModules();\n refreshServices(); context.phase(\"start\");\n const started: ServiceName[] = [];\n try { for (const name of START_ORDER) { const result = await services[name].start(); if (result.status !== \"skipped\") started.push(name); } await verifyRunning(started); }\n catch (error) { for (const name of [...START_ORDER].reverse()) await services[name].stop(false, false).catch(() => {}); throw error; }\n atomicJson(path.join(ROOT, \"configs\", \"runtime.json\"), { ...readJson(path.join(ROOT, \"configs\", \"runtime.json\"), {}), initialized_at: new Date().toISOString() });\n return { created: true, rows: await queryServicesRuntimeLocal() };\n });\n }\n case \"backups.list\": { const directory = path.join(ROOT, \".sfmc\", \"backups\"); return { backups: fs.existsSync(directory) ? fs.readdirSync(directory).filter(id => fs.existsSync(path.join(directory, id, \"manifest.json\"))) : [] }; }\n case \"backups.restore\": {\n if (p.confirmDataLoss !== true) throw new Error(\"\u6062\u590D\u6570\u636E\u9700\u8981\u660E\u786E\u786E\u8BA4\u4E22\u5F03\u5907\u4EFD\u4E4B\u540E\u7684\u53D8\u66F4\");\n return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], () => restoreSnapshot(identifier(p.id), context.phase)));\n }\n case \"startup.plan\": return startupPlan();\n default: throw Object.assign(new Error(`\u4E0D\u652F\u6301\u7684\u7BA1\u7406\u65B9\u6CD5: ${request.method}`), { code: \"unsupported\" });\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport { EventEmitter } from \"node:events\";\nimport { MANAGEMENT_PROTOCOL_VERSION, type ManagementRequest, type ManagementEvent } from \"@sfmc-bds/management\";\nimport { ROOT, isRuntimeInitialized, spawnService } from \"../runtime.js\";\nimport { queryServicesRuntimeLocal, services, START_ORDER, SERVICE_NAMES, refreshServices, onServiceStateChange, type ServiceName } from \"../services.js\";\nimport { readDiskLogs, onLog } from \"../logs.js\";\nimport { cmdModuleEnable, cmdModuleDisable } from \"../module-commands.js\";\nimport { ensureCoreConfigs } from \"@sfmc-bds/sdk/node/config\";\nimport { TaskStore, atomicJson, type TaskContext } from \"./tasks.js\";\nimport { configFiles, readDocument, saveDocument, validateDocument } from \"./config.js\";\nimport { listModules, searchModules, identifier, runFetch, readJson, listPacks, togglePack, importPack, playerFiles, savePlayerPermissions, modulePlan, applyModulePlan } from \"./domain.js\";\nimport { attachmentPlan, platformVersion, withStoppedServices, launchPlatformUpdate, restoreSnapshot, verifyRunning } from \"./maintenance.js\";\nimport { startupPlan } from \"./startup.js\";\nimport { cmdPackBuild, cmdPackDeploy } from \"../pack-lifecycle.js\";\nimport { withMaintenanceLock } from \"@sfmc-bds/management/node\";\nimport { deploymentPreflight, deploymentPort } from \"./deployment.js\";\nimport { resolveBdsContext } from \"../pack-lifecycle.js\";\n\nconst events = new EventEmitter();\n/** \u7A7A\u76EE\u5F55\u4E5F\u8981\u80FD\u5B8C\u6210\u63E1\u624B\uFF0C\u4F9B\u684C\u9762\u521D\u59CB\u5316\u5411\u5BFC\u7EE7\u7EED\uFF1B\u65E7\u90E8\u7F72\u4ECD\u8BC6\u522B\u5DF2\u6709 BDS\u3002 */\nfunction deploymentInitialized(): boolean {\n if (isRuntimeInitialized()) return true;\n const config = readJson<{ bds_path?: string }>(path.join(ROOT, \"configs\", \"bds_updater.json\"), {});\n if (!config.bds_path) return false;\n return fs.existsSync(path.join(resolveBdsContext().bdsRoot, process.platform === \"win32\" ? \"bedrock_server.exe\" : \"bedrock_server\"));\n}\nlet tasks: TaskStore | undefined;\nexport function managementTasks() {\n if (!tasks) {\n tasks = new TaskStore(ROOT);\n tasks.on(\"operation\", payload => events.emit(\"event\", { type: \"event\", event: \"operation\", instanceId: ROOT, payload }));\n onLog(log => events.emit(\"event\", { type: \"event\", event: \"log\", instanceId: ROOT, payload: { ...log, time: log.time.toISOString() } }));\n onServiceStateChange(payload => events.emit(\"event\", { type: \"event\", event: \"serviceState\", instanceId: ROOT, payload }));\n }\n return tasks;\n}\nexport function onManagementEvent(callback: (event: ManagementEvent) => void) { events.on(\"event\", callback); return () => events.off(\"event\", callback); }\nfunction params(request: ManagementRequest): Record<string, unknown> {\n if (request.params === undefined) return {};\n if (!request.params || typeof request.params !== \"object\" || Array.isArray(request.params)) throw new Error(\"\u53C2\u6570\u5FC5\u987B\u4E3A\u5BF9\u8C61\");\n return request.params as Record<string, unknown>;\n}\nfunction string(value: unknown, label: string) { if (typeof value !== \"string\" || value.length > 2 * 1024 * 1024) throw new Error(`\u975E\u6CD5 ${label}`); return value; }\nfunction service(value: unknown): ServiceName { if (!SERVICE_NAMES.includes(value as ServiceName)) throw new Error(\"\u672A\u77E5\u670D\u52A1\"); return value as ServiceName; }\nasync function rebuildModules() {\n const build = await cmdPackBuild([]); if (!build.ok) throw new Error(build.message);\n const deploy = await cmdPackDeploy([]); if (!deploy.ok) throw new Error(deploy.message);\n return { changed: true };\n}\nasync function players() {\n const files = playerFiles(); const allowlist = readJson<unknown[]>(files.allowlist, []);\n const cfg = readJson<{ db_port?: number; http_auth?: string }>(path.join(ROOT, \"configs\", \"db_config.json\"), {});\n let data: { online?: { name: string }[]; updatedAt?: number } = {};\n try {\n const response = await fetch(`http://127.0.0.1:${cfg.db_port ?? 3001}/api/sfmc/status`, { headers: cfg.http_auth ? { authorization: `Bearer ${cfg.http_auth}` } : {}, signal: AbortSignal.timeout(5000) });\n if (response.ok) data = await response.json() as typeof data;\n } catch { /* \u672A\u8FDE\u63A5\u65F6\u4F7F\u7528\u672A\u77E5\u72B6\u6001 */ }\n const fresh = typeof data.updatedAt === \"number\" && Date.now() - data.updatedAt < 60_000;\n return { players: (data.online ?? []).map(row => ({ name: row.name, xuid: \"\", online: fresh ? true : null })), updatedAt: data.updatedAt ? new Date(data.updatedAt).toISOString() : \"\", fresh, allowlist, permissions: readJson<unknown[]>(files.permissions, []), sfmcPermissions: readJson<unknown[]>(files.sfmcPermissions, []) };\n}\nasync function bdsUpdate(context: TaskContext, checkOnly = false) {\n context.phase(\"download\", checkOnly ? \"\u68C0\u67E5 BDS \u66F4\u65B0\" : \"\u66F4\u65B0 BDS\");\n const args = checkOnly ? [\"--check-only\", \"--no-notify\"] : [\"--no-start\", \"--no-notify\"];\n let output = \"\";\n await new Promise<void>((resolve, reject) => {\n const child = spawnService(\"update\", args, { stdio: \"pipe\", cwd: ROOT });\n for (const stream of [child.stdout, child.stderr]) stream?.on(\"data\", chunk => { output = (output + String(chunk)).slice(-64_000); });\n child.on(\"error\", reject); child.on(\"close\", code => code === 0 ? resolve() : reject(new Error(`BDS \u66F4\u65B0\u5931\u8D25 (${code})`)));\n });\n return { checked: checkOnly, updated: /SFMC_UPDATE_RESULT=deployed/.test(output), currentVersion: /CURRENT=([^\\r\\n]+)/.exec(output)?.[1] ?? \"unknown\", latestVersion: /LATEST=([^\\r\\n]+)/.exec(output)?.[1] ?? \"unknown\", result: /SFMC_UPDATE_RESULT=([^\\r\\n]+)/.exec(output)?.[1] ?? \"unknown\" };\n}\nexport async function dispatchManagement(request: ManagementRequest): Promise<unknown> {\n const p = params(request); const store = managementTasks();\n switch (request.method) {\n case \"handshake\": return { protocolVersion: MANAGEMENT_PROTOCOL_VERSION, platformVersion: platformVersion(), host: { os: process.platform === \"win32\" ? \"windows\" : process.platform, arch: process.arch, release: os.release() }, root: ROOT, capabilities: [\"services\", \"logs\", \"modules\", \"config\", \"packs\", \"players\", \"updates\", \"operations\", \"metrics\"], daemonPid: process.pid, daemonStartedAt: new Date(Date.now() - process.uptime() * 1000).toISOString(), initialized: deploymentInitialized() };\n case \"events.subscribe\": return { subscribed: true };\n case \"services.list\": return { rows: await queryServicesRuntimeLocal() };\n case \"services.start\": case \"services.stop\": case \"services.restart\": {\n const names = p.name === \"all\" ? [...START_ORDER] : [service(p.name)];\n return store.submit(request.method, async context => {\n context.phase(\"execute\");\n const rows = await queryServicesRuntimeLocal();\n if (rows.some(row => names.includes(row.name) && row.running && row.ownership === \"external\") && request.method !== \"services.start\") throw new Error(\"\u5916\u90E8\u8FDB\u7A0B\u65E0\u6CD5\u5B89\u5168\u505C\u6B62\uFF0C\u8BF7\u901A\u8FC7\u539F\u7BA1\u7406\u5668\u64CD\u4F5C\");\n if (request.method !== \"services.start\") for (const name of [...names].reverse()) await services[name].stop(false, false);\n if (request.method !== \"services.stop\") {\n const outcomes = [];\n for (const name of names) outcomes.push({ name, ...(await services[name].start()) });\n await verifyRunning(outcomes.filter(row => row.status !== \"skipped\").map(row => row.name));\n return { outcomes };\n }\n return { stopped: names };\n });\n }\n case \"services.send\": {\n const name = service(p.name); const message = string(p.message, \"\u547D\u4EE4\");\n if (/[\\r\\n]/.test(message) || !message.trim()) throw new Error(\"\u4E00\u6B21\u53EA\u80FD\u53D1\u9001\u4E00\u884C\u547D\u4EE4\");\n const target = services[name]; if (!target.proc?.stdin || !target.running) throw new Error(\"\u670D\u52A1\u672A\u6258\u7BA1\u6216\u6CA1\u6709\u547D\u4EE4\u8F93\u5165\u901A\u9053\");\n return withMaintenanceLock(ROOT, async () => { target.proc!.stdin!.write(message + \"\\n\"); return { delivered: true }; });\n }\n case \"logs.tail\": return { entries: readDiskLogs({ limit: Math.min(5000, Math.max(1, Number(p.limit) || 1000)), ...(Array.isArray(p.sources) ? { sources: p.sources.map(value => string(value, \"\u65E5\u5FD7\u6765\u6E90\")) } : {}), ...(Array.isArray(p.levels) ? { levels: p.levels as (\"info\" | \"warn\" | \"error\")[] } : {}) }).map(log => ({ ...log, time: log.time.toISOString() })) };\n case \"operations.list\": return { operations: store.list().filter(row => !Array.isArray(p.statuses) || p.statuses.includes(row.status)).slice(0, Math.min(Number(p.limit) || 100, 200)) };\n case \"operations.get\": return { operation: store.get(string(p.operationId, \"\u4EFB\u52A1\u7F16\u53F7\")) };\n case \"modules.list\": return listModules();\n case \"modules.search\": return searchModules(typeof p.query === \"string\" ? p.query : \"\");\n case \"modules.install\": case \"modules.uninstall\": case \"modules.toggle\": {\n const id = identifier(p.id);\n if (request.method !== \"modules.toggle\") {\n const linked = (await listModules()).modules.find(row => row.id === id || row.folder === id)?.linked;\n if (linked) throw new Error(\"\u4FDD\u7559\u672C\u5730\u94FE\u63A5\u6A21\u5757\uFF0C\u4E0D\u901A\u8FC7\u5305\u5B89\u88C5\u6216\u5378\u8F7D\u8986\u76D6\u5F00\u53D1\u76EE\u5F55\");\n }\n return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], async () => {\n if (request.method === \"modules.toggle\") {\n const result = await (p.enabled === true ? cmdModuleEnable([id]) : cmdModuleDisable([id])); if (!result.ok) throw new Error(result.message);\n } else {\n const args = [request.method === \"modules.install\" ? \"install\" : \"uninstall\", id];\n if (request.method === \"modules.install\" && typeof p.source === \"string\" && p.source) args.push(\"--from\", p.source);\n await runFetch(args);\n }\n return rebuildModules();\n }, true, \"modules\"));\n }\n case \"config.list\": return { keys: [...configFiles().keys()] };\n case \"config.read\": return readDocument(string(p.key, \"\u914D\u7F6E\u540D\u79F0\"));\n case \"config.apply\": {\n const key = string(p.key, \"\u914D\u7F6E\u540D\u79F0\"); const text = string(p.text, \"\u914D\u7F6E\u5185\u5BB9\"); const expected = string(p.revision, \"\u914D\u7F6E\u7248\u672C\");\n const document = readDocument(key); validateDocument(document, text);\n if (document.revision !== expected) throw Object.assign(new Error(\"\u914D\u7F6E\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\"), { code: \"conflict\" });\n return store.submit(request.method, async context => {\n let saved = false;\n try { return await withStoppedServices(context, [...START_ORDER], async () => {\n saveDocument(key, expected, text); context.phase(\"apply\", \"\u6587\u4EF6\u5DF2\u4FDD\u5B58\uFF0C\u6B63\u5728\u5E94\u7528\u8FD0\u884C\u914D\u7F6E\");\n saved = true;\n refreshServices(); return { saved: true, revision: readDocument(key).revision, applied: true };\n }); } catch (error) { throw Object.assign(new Error(`${saved ? \"\u6587\u4EF6\u5DF2\u4FDD\u5B58\uFF0C\u8FD0\u884C\u65F6\u5E94\u7528\u5931\u8D25\" : \"\u914D\u7F6E\u672A\u4FDD\u5B58\"}: ${error instanceof Error ? error.message : String(error)}`), { code: \"io\", details: { saved, applied: false, backupId: context.id } }); }\n });\n }\n case \"packs.list\": return listPacks();\n case \"packs.import\": return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], () => importPack(identifier(p.filename))));\n case \"packs.toggle\": return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], () => togglePack(identifier(p.id), p.enabled === true)));\n case \"players.list\": return players();\n case \"metrics.read\": {\n const cfg = readJson<{ db_port?: number; http_auth?: string }>(path.join(ROOT, \"configs\", \"db_config.json\"), {});\n try {\n const response = await fetch(`http://127.0.0.1:${cfg.db_port ?? 3001}/api/sfmc/metrics`, { headers: cfg.http_auth ? { authorization: `Bearer ${cfg.http_auth}` } : {}, signal: AbortSignal.timeout(10_000) });\n if (!response.ok) throw new Error(`\u8FD0\u884C\u6307\u6807\u8BFB\u53D6\u5931\u8D25 (${response.status})`);\n return response.json();\n } catch (error) {\n const detail = error instanceof Error ? `${error.message} ${String(error.cause ?? \"\")}` : String(error);\n // \u6570\u636E\u670D\u52A1\u6CA1\u5F00\u65F6 fetch \u4F1A\u629B\u7F51\u7EDC\u9519\u8BEF\uFF1B\u754C\u9762\u7528 note \u5C55\u793A\uFF0C\u800C\u4E0D\u662F\u6574\u9875\u5931\u8D25\u3002\n if (/fetch failed|ECONNREFUSED|ENOTFOUND|AbortError|TimeoutError|timed out/i.test(detail)) {\n return { fresh: false, updatedAt: null, current: null, history: [], host: null, processes: null, resourcesUpdatedAt: null, note: \"\u6570\u636E\u670D\u52A1\u672A\u8FD0\u884C\uFF0C\u6682\u65F6\u6CA1\u6709\u8FD0\u884C\u6307\u6807\" };\n }\n throw error;\n }\n }\n case \"players.apply\": return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], async () => savePlayerPermissions(string(p.kind, \"\u6743\u9650\u7C7B\u578B\"), p.entries)));\n case \"attachment.plan\": return attachmentPlan();\n case \"attachment.apply\": return store.submit(request.method, async context => {\n const plan = await attachmentPlan(false);\n if (p.targetVersion !== undefined && p.targetVersion !== plan.targetVersion) throw Object.assign(new Error(\"\u76EE\u6807\u7248\u672C\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u66F4\u65B0\u65E5\u5FD7\u540E\u786E\u8BA4\"), { code: \"conflict\" });\n if (plan.externalServices.length) throw new Error(\"\u65E0\u6CD5\u53EF\u9760\u8FC1\u79FB\u5916\u90E8\u8FDB\u7A0B\uFF1B\u8BF7\u5148\u901A\u8FC7\u539F\u7BA1\u7406\u5668\u4F18\u96C5\u505C\u670D\");\n if (plan.upgradeRequired) return launchPlatformUpdate(store, context, plan.targetVersion);\n return { attached: true, version: plan.currentVersion, development: plan.development };\n });\n case \"updates.check\": {\n const results = await Promise.allSettled([attachmentPlan(), modulePlan(), bdsUpdate({ id: \"check\", phase: () => {} }, true)]);\n return Object.fromEntries(results.map((result, index) => [[\"platform\", \"modules\", \"bds\"][index], result.status === \"fulfilled\" ? result.value : { error: String(result.reason) }]));\n }\n case \"updates.run\": {\n if (p.kind === \"platform\") return store.submit(request.method, async context => { const plan = await attachmentPlan(false); if (p.targetVersion !== undefined && p.targetVersion !== plan.targetVersion) throw Object.assign(new Error(\"\u76EE\u6807\u7248\u672C\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u66F4\u65B0\u65E5\u5FD7\u540E\u786E\u8BA4\"), { code: \"conflict\" }); return plan.upgradeRequired ? launchPlatformUpdate(store, context, plan.targetVersion) : { upToDate: true, version: plan.currentVersion }; });\n if (p.kind === \"modules\") return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], async () => { const result = await applyModulePlan(Array.isArray(p.ids) ? p.ids.map(identifier) : []); await rebuildModules(); return result; }, true, \"modules\"));\n if (p.kind === \"bds\") return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], () => bdsUpdate(context), true, \"bds\"));\n throw new Error(\"\u672A\u77E5\u66F4\u65B0\u7C7B\u578B\");\n }\n case \"deployment.create\": {\n if (p.acceptEula !== true) throw new Error(\"\u521B\u5EFA\u90E8\u7F72\u524D\u5FC5\u987B\u786E\u8BA4 BDS \u4F7F\u7528\u6761\u6B3E\");\n return store.submit(request.method, async context => {\n if (isRuntimeInitialized()) throw new Error(\"\u76EE\u5F55\u5DF2\u7ECF\u521D\u59CB\u5316\uFF0C\u4E0D\u8986\u76D6\u5DF2\u6709\u90E8\u7F72\");\n const ports = { db: deploymentPort(p.dbPort, 3001), bds: deploymentPort(p.bdsPort, 19132), bds6: deploymentPort(p.bdsPort6, 19133) };\n context.phase(\"preflight\", \"\u68C0\u67E5\u76EE\u5F55\u3001\u78C1\u76D8\u7A7A\u95F4\u548C TCP\uFF0FUDP \u7AEF\u53E3\"); await deploymentPreflight(ports);\n context.phase(\"prepare\"); ensureCoreConfigs(ROOT, [\"db_config\", \"qq_config\", \"bds_updater\", \"permissions\", \"qq_link\"]);\n const updater = path.join(ROOT, \"configs\", \"bds_updater.json\");\n atomicJson(updater, { ...readJson(updater, {}), bds_path: \"BDS\", backup_dir: \"backups\" });\n const dbFile = path.join(ROOT, \"configs\", \"db_config.json\"); atomicJson(dbFile, { ...readJson(dbFile, {}), db_port: ports.db });\n fs.mkdirSync(path.join(ROOT, \"modules\", \"packages\"), { recursive: true });\n await bdsUpdate(context);\n const properties = path.join(ROOT, \"BDS\", \"server.properties\");\n let text = fs.readFileSync(properties, \"utf8\");\n for (const [key, port] of [[\"server-port\", ports.bds], [\"server-portv6\", ports.bds6]] as const) text = text.replace(new RegExp(`^${key}=.*$`, \"m\"), `${key}=${port}`);\n fs.writeFileSync(properties, text);\n await rebuildModules();\n refreshServices(); context.phase(\"start\");\n const started: ServiceName[] = [];\n try { for (const name of START_ORDER) { const result = await services[name].start(); if (result.status !== \"skipped\") started.push(name); } await verifyRunning(started); }\n catch (error) { for (const name of [...START_ORDER].reverse()) await services[name].stop(false, false).catch(() => {}); throw error; }\n atomicJson(path.join(ROOT, \"configs\", \"runtime.json\"), { ...readJson(path.join(ROOT, \"configs\", \"runtime.json\"), {}), initialized_at: new Date().toISOString() });\n return { created: true, rows: await queryServicesRuntimeLocal() };\n });\n }\n case \"backups.list\": { const directory = path.join(ROOT, \".sfmc\", \"backups\"); return { backups: fs.existsSync(directory) ? fs.readdirSync(directory).filter(id => fs.existsSync(path.join(directory, id, \"manifest.json\"))) : [] }; }\n case \"backups.restore\": {\n if (p.confirmDataLoss !== true) throw new Error(\"\u6062\u590D\u6570\u636E\u9700\u8981\u660E\u786E\u786E\u8BA4\u4E22\u5F03\u5907\u4EFD\u4E4B\u540E\u7684\u53D8\u66F4\");\n return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], () => restoreSnapshot(identifier(p.id), context.phase)));\n }\n case \"startup.plan\": return startupPlan();\n default: throw Object.assign(new Error(`\u4E0D\u652F\u6301\u7684\u7BA1\u7406\u65B9\u6CD5: ${request.method}`), { code: \"unsupported\" });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-commands.d.ts","sourceRoot":"","sources":["../src/module-commands.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAeH,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAA+C,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAerG,uCAAuC;AACvC,eAAO,MAAM,gBAAgB,YAAI,QAAQ,EAAE,KAAK,CAAU,CAAC;AAE3D,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,GAAG,IAAI,aAAa,CAE7E;AAED,wBAAwB;AACxB,eAAO,MAAM,6BAA6B,YAAI,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAEpF,yCAAyC;AACzC,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,MAAM,EAAE,CAEhF;AAED,6BAA6B;AAC7B,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEtE;AAED,qDAAqD;AACrD,wBAAgB,WAAW,CAAC,IAAI,GAAE,WAAoB,GAAG,MAAM,CAK9D;AA6FD,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAiCpE;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAO1D;AAKD;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoErE;AAKD,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BnE;AAKD,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAerE;
|
|
1
|
+
{"version":3,"file":"module-commands.d.ts","sourceRoot":"","sources":["../src/module-commands.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAeH,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAA+C,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAerG,uCAAuC;AACvC,eAAO,MAAM,gBAAgB,YAAI,QAAQ,EAAE,KAAK,CAAU,CAAC;AAE3D,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,GAAG,IAAI,aAAa,CAE7E;AAED,wBAAwB;AACxB,eAAO,MAAM,6BAA6B,YAAI,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAEpF,yCAAyC;AACzC,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,MAAM,EAAE,CAEhF;AAED,6BAA6B;AAC7B,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEtE;AAED,qDAAqD;AACrD,wBAAgB,WAAW,CAAC,IAAI,GAAE,WAAoB,GAAG,MAAM,CAK9D;AA6FD,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAiCpE;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAO1D;AAKD;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoErE;AAKD,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BnE;AAKD,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAerE;AAwHD,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAKxE;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAIzE;AAqCD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAqDtE;AAKD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BxE;AAuBD;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAMpG;AAmDD,uDAAuD;AACvD,wBAAgB,0BAA0B,IAAI,MAAM,EAAE,CAiBrD"}
|
package/dist/module-commands.js
CHANGED
|
@@ -334,8 +334,9 @@ async function notifyDbToggle(logicalId, action) {
|
|
|
334
334
|
async function cmdModuleToggle(query, action) {
|
|
335
335
|
const installed = await scanInstalled();
|
|
336
336
|
const target = resolveToggleTarget(query, buildToggleCandidates(installed));
|
|
337
|
-
if (action === "enable" && target && isRetiredPlatformModule(target.logicalId))
|
|
338
|
-
|
|
337
|
+
if (action === "enable" && target && isRetiredPlatformModule(target.logicalId)) {
|
|
338
|
+
return failResult(`${target.logicalId} \u5DF2\u6536\u7F16\u81F3\u5E73\u53F0\uFF0C\u65E0\u9700\u542F\u7528\uFF1B\u8BF7\u66F4\u65B0\u5E73\u53F0\u884C\u4E3A\u5305\u3002`);
|
|
339
|
+
}
|
|
339
340
|
if (!target) {
|
|
340
341
|
return failResult(c.red(t("mod.notInstalled", { id: query })));
|
|
341
342
|
}
|
|
@@ -362,7 +363,7 @@ ${warn}`);
|
|
|
362
363
|
}
|
|
363
364
|
async function cmdModuleEnable(args) {
|
|
364
365
|
const id = args[0];
|
|
365
|
-
if (id && isRetiredPlatformModule(id)) return failResult(
|
|
366
|
+
if (id && isRetiredPlatformModule(id)) return failResult(`${id} \u5DF2\u6536\u7F16\u81F3\u5E73\u53F0\uFF0C\u65E0\u9700\u5B89\u88C5\u6216\u542F\u7528\uFF1B\u8BF7\u66F4\u65B0\u5E73\u53F0\u884C\u4E3A\u5305\u3002`);
|
|
366
367
|
if (!id) return failResult(c.yellow(t("mod.enable.usage")));
|
|
367
368
|
return cmdModuleToggle(id, "enable");
|
|
368
369
|
}
|
|
@@ -397,6 +398,11 @@ async function cmdModuleInstall(args) {
|
|
|
397
398
|
if (positional.length === 0) {
|
|
398
399
|
return c.yellow(t("mod.install.usage"));
|
|
399
400
|
}
|
|
401
|
+
for (const id of positional) {
|
|
402
|
+
if (isRetiredPlatformModule(id)) {
|
|
403
|
+
return c.red(`${id} \u5DF2\u6536\u7F16\u81F3\u5E73\u53F0\uFF0C\u65E0\u9700\u5B89\u88C5\uFF1B\u8BF7\u66F4\u65B0\u5E73\u53F0\u884C\u4E3A\u5305\u3002`);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
400
406
|
if (flags.from) {
|
|
401
407
|
const err = validateFromScheme(flags.from);
|
|
402
408
|
if (err) return c.red(err);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/module-commands.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * sfmc module-commands \u2014 runtime CLI for inspecting and managing modules\n * already on disk under `modules/packages/<id>/`.\n *\n * \u9876\u5C42\u547D\u4EE4\u522B\u540D:`module` / `mod`(\u7531 main.ts / repl.ts \u5171\u540C\u8BC6\u522B)\u3002\n * \u5B50\u547D\u4EE4\u901A\u9053\u95E8\u7981\u89C1 command-surface.ts\uFF08dispatch \u524D\u7531 main/repl \u5224\u5B9A\uFF09\u3002\n */\n\nimport {\n configPath,\n modulePath,\n readJson,\n writeJson,\n type Catalog,\n type DBConfig,\n type ModuleLock,\n} from \"@sfmc-bds/sdk/node/config\";\nimport { spawn } from \"node:child_process\";\nimport { existsSync, lstatSync, readdirSync, statSync } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { failResult, okResult, type CliResult } from \"./cli-result.js\";\nimport { isDevAccentModuleSub, listVisibleModuleSubs, type CommandMode } from \"./command-surface.js\";\nimport { t } from \"./i18n/index.js\";\nimport { dirFingerprint, shouldSkipModuleEntry } from \"./module-fingerprint.js\";\nimport {\n applyLockEnabled,\n finalizeToggle,\n resolveToggleTarget,\n type ToggleCandidate,\n type ToggleNotify,\n} from \"./module-toggle.js\";\nimport { DEFAULT_REGISTRY_REPO, DEFAULT_REGISTRY_TAG, findUnknownModules, resolveRegistryIndex } from \"./registry.js\";\nimport { ROOT, resolveFetchModule } from \"./runtime.js\";\nimport { c } from \"./theme.js\";\nimport { isRetiredPlatformModule } from \"@sfmc-bds/sdk/contracts\";\n\n/** \u9876\u5C42\u547D\u4EE4\u540D(\u4E3B\u540D + \u77ED\u522B\u540D),\u4F9B\u5E2E\u52A9 / \u8865\u5168 / \u5206\u53D1\u5171\u7528\u3002 */\nexport const MODULE_CMD_NAMES = [\"module\", \"mod\"] as const;\n\nexport type ModuleCmdName = (typeof MODULE_CMD_NAMES)[number];\n\n/** \u5224\u65AD\u662F\u5426\u4E3A module \u9876\u5C42\u547D\u4EE4(\u542B\u522B\u540D);\u907F\u514D main/repl \u518D\u786C\u7F16\u7801 case\u3002 */\nexport function isModuleCommand(cmd: string | undefined): cmd is ModuleCmdName {\n return !!cmd && (MODULE_CMD_NAMES as readonly string[]).includes(cmd);\n}\n\n/** \u5F00\u53D1\u8005\u6837\u5F0F\u5B50\u547D\u4EE4\uFF08\u84DD\u6807\uFF0C\u975E\u95E8\u7981\uFF09\u3002 */\nexport const DEV_ACCENT_MODULE_SUBCOMMANDS = [\"build\", \"reload\", \"submit\"] as const;\n\n/** \u5F53\u524D\u901A\u9053\u4E0B\u53EF\u89C1\u7684 module \u5B50\u547D\u4EE4\uFF08\u81EA\u52A8\u8865\u5168 / usage\uFF09\u3002 */\nexport function getVisibleModuleSubcommands(mode: CommandMode): readonly string[] {\n return listVisibleModuleSubs(mode);\n}\n\n/** sub \u662F\u5426\u4E3A\u5F00\u53D1\u8005\u84DD\u6807\uFF08help \u7740\u8272\uFF09\u3002 */\nexport function isDeveloperSubcommand(sub: string | undefined): boolean {\n return isDevAccentModuleSub(sub);\n}\n\n/** Usage \u884C\u4E3B\u540D|\u522B\u540D(\u4E0E MODULE_CMD_NAMES \u540C\u6E90,\u907F\u514D\u4E0E\u5E2E\u52A9\u6587\u6848\u6F02\u79FB)\u3002 */\nexport function moduleUsage(mode: CommandMode = \"argv\"): string {\n return t(\"mod.usage\", {\n cmds: MODULE_CMD_NAMES.join(\"|\"),\n subs: getVisibleModuleSubcommands(mode).join(\"|\"),\n });\n}\n\n/** Where modules live on disk. */\nfunction modulesDir(): string {\n return path.join(ROOT, \"modules\", \"packages\");\n}\n\nfunction fmtBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / 1024 / 1024).toFixed(2)} MB`;\n}\n\nfunction shortHash(h: string): string {\n return h.slice(0, 8) + \"\u2026\" + h.slice(-8);\n}\n\ninterface ModuleManifest {\n schemaVersion?: number;\n id?: string;\n handlers?: string[];\n routes?: Array<{ method: string; path: string; handler: string }>;\n migrations?: Array<{ name: string; version: number }>;\n notes?: string;\n}\n\ninterface InstalledModule {\n id: string;\n path: string;\n manifest: ModuleManifest | null;\n totalBytes: number;\n fileCount: number;\n fingerprint: string;\n}\n\n/** Enumerate every installed module by scanning `modules/packages/<id>/`. */\nasync function scanInstalled(): Promise<InstalledModule[]> {\n const dir = modulesDir();\n if (!existsSync(dir)) return [];\n const entries = await fs.readdir(dir, { withFileTypes: true });\n const out: InstalledModule[] = [];\n for (const e of entries) {\n const id = e.name;\n const modPath = path.join(dir, id);\n try {\n if (!statSync(modPath).isDirectory()) continue;\n } catch {\n continue;\n }\n const manifestPath = path.join(modPath, \"sapi\", \"manifest.json\");\n let manifest: ModuleManifest | null = null;\n if (existsSync(manifestPath)) {\n try {\n manifest = JSON.parse(await fs.readFile(manifestPath, \"utf8\")) as ModuleManifest;\n } catch {\n /* corrupt manifest is not fatal \u2014 just skip its fields */\n }\n }\n try {\n const { totalBytes, fileCount } = await dirSize(modPath);\n const fingerprint = await dirFingerprint(modPath);\n out.push({ id, path: modPath, manifest, totalBytes, fileCount, fingerprint });\n } catch {\n // \u574F\u94FE\u63A5\u6216\u76EE\u5F55\u5DF2\u6D88\u5931\u65F6\u8DF3\u8FC7\uFF0C\u4E0D\u8BA9 CLI \u8D77\u4E0D\u6765\n continue;\n }\n }\n out.sort((a, b) => a.id.localeCompare(b.id));\n return out;\n}\n\nasync function dirSize(dir: string): Promise<{ totalBytes: number; fileCount: number }> {\n let totalBytes = 0;\n let fileCount = 0;\n async function walk(p: string): Promise<void> {\n for (const e of await fs.readdir(p, { withFileTypes: true })) {\n if (shouldSkipModuleEntry(path.basename(p), e.name)) continue;\n const child = path.join(p, e.name);\n if (e.isDirectory()) await walk(child);\n else if (e.isFile()) {\n const s = await fs.stat(child);\n totalBytes += s.size;\n fileCount++;\n }\n }\n }\n await walk(dir);\n return { totalBytes, fileCount };\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * list\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleList(_args: string[]): Promise<string> {\n const installed = await scanInstalled();\n if (installed.length === 0) {\n return c.dim(t(\"mod.noneInstalled\", { dir: modulesDir() }));\n }\n const lock = (readJson<ModuleLock>(modulePath(path.join(ROOT, \"modules\"), \"module-lock.json\")) ?? {\n version: 1,\n modules: {},\n }) as ModuleLock;\n const ids = installed.map((m) => m.id);\n const unknown = new Set(await findUnknownModules(ids));\n const lines: string[] = [c.bold(`\\n${t(\"mod.list.title\")}`), c.dim(` ${modulesDir()}`)];\n const header = ` ${\"id\".padEnd(28)}${\"state\".padEnd(8)}${\"files\".padEnd(8)}${\"size\".padEnd(10)}${\"fingerprint\"}`;\n lines.push(c.dim(header));\n for (const m of installed) {\n const logicalId = typeof m.manifest?.id === \"string\" && m.manifest.id ? m.manifest.id : m.id;\n const enabled = lock.modules?.[logicalId]?.enabled === true;\n const stateCol = (enabled ? c.green(\"on\") : c.dim(\"off\")).padEnd(8);\n let mark: string;\n if (!m.manifest) {\n mark = c.yellow(\"\u25CB\");\n } else if (unknown.has(m.id)) {\n mark = c.yellow(\"?\");\n } else {\n mark = enabled ? c.green(\"\u25CF\") : c.dim(\"\u25CB\");\n }\n const idLabel = logicalId !== m.id ? `${m.id}(${logicalId})` : m.id;\n lines.push(\n ` ${mark} ${idLabel.padEnd(26)} ${stateCol}${String(m.fileCount).padEnd(8)}${fmtBytes(m.totalBytes).padEnd(10)}${shortHash(m.fingerprint)}`\n );\n }\n lines.push(c.dim(`\\n tip: ${MODULE_CMD_NAMES[1] ?? \"mod\"} enable|disable <logicalId>`));\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/**\n * Walk `modules/packages/<id>/` and print a one-line yellow warning for each\n * id that isn't in the first-party registry. Intended for the REPL startup\n * hook so users immediately see modules they installed from somewhere else.\n *\n * Best-effort: registry unreachable \u2192 no warning (no false positives).\n */\nexport async function scanAndWarnUnknown(): Promise<string> {\n const installed = await scanInstalled();\n if (installed.length === 0) return \"\";\n const unknown = await findUnknownModules(installed.map((m) => m.id));\n if (unknown.length === 0) return \"\";\n const list = unknown.map((id) => ` ${c.yellow(\"?\")} ${id}`).join(\"\\n\");\n return `${c.yellow(\"[sfmc] modules installed from unknown publisher \u2014 verify before use:\")}\\n${list}\\n`;\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * search \u2014 \u62C9\u53D6 first-party registry;\u5E26 id \u67E5\u5355\u6761 registry info\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/**\n * \u62C9\u53D6 first-party registry \u6A21\u5757\u5217\u8868;\u5E26 id \u65F6\u5C55\u793A\u8BE5\u6761\u76EE\u7684 registry info\u3002\n * \u4E0E\u672C\u5730 `info`(\u5DF2\u5B89\u88C5\u78C1\u76D8\u8BE6\u60C5)\u533A\u5206:`search` \u770B registry,`info` \u770B\u672C\u673A packages\u3002\n */\nexport async function cmdModuleSearch(args: string[]): Promise<string> {\n const query = args[0];\n const { index, stale } = await resolveRegistryIndex({ force: true });\n const ids = Object.keys(index).sort((a, b) => a.localeCompare(b));\n\n if (ids.length === 0) {\n return c.red(\n `\\nRegistry empty or unreachable (${DEFAULT_REGISTRY_REPO}@${DEFAULT_REGISTRY_TAG}).\\n` +\n `Check network, or: mod install <id> --from github:owner/repo@tag\\n`\n );\n }\n\n const staleNote = stale ? c.yellow(\" (offline \u2014 showing cached index)\\n\") : \"\";\n\n /* \u65E0\u53C2\u6570:\u5217\u51FA\u5168\u90E8 */\n if (!query) {\n const installed = new Set(listInstalledModuleIdsSync());\n const lines: string[] = [\n c.bold(`\\nFirst-party registry (${DEFAULT_REGISTRY_REPO}@${DEFAULT_REGISTRY_TAG}) \u2014 ${ids.length} modules`),\n ];\n if (staleNote) lines.push(staleNote.trimEnd());\n lines.push(c.dim(` ${\"id\".padEnd(28)}${\"source\".padEnd(40)}local`));\n for (const id of ids) {\n const e = index[id]!;\n const src = e.npm ? `npm:${e.npm}${e.version ? `@${e.version}` : \"\"}` : `github:${e.repo}@${e.tag}`;\n const local = installed.has(id) ? c.green(\"\u25CF\") : c.dim(\"\u25CB\");\n lines.push(` ${local} ${id.padEnd(26)}${src.padEnd(40)}${installed.has(id) ? \"installed\" : \"\"}`);\n }\n lines.push(c.dim(`\\n tip: sfmc mod search <id> \u2192 registry info`));\n lines.push(c.dim(` sfmc mod install <id> \u2192 download + catalog sync`));\n return lines.join(\"\\n\") + \"\\n\";\n }\n\n /* \u5E26 id:\u67E5\u5355\u6761 registry info */\n const entry = index[query];\n if (!entry) {\n const hints = ids.filter((id) => id.includes(query) || query.includes(id)).slice(0, 8);\n const hintBlock =\n hints.length > 0\n ? c.dim(`\\n Did you mean:\\n`) + hints.map((h) => ` ${h}`).join(\"\\n\")\n : c.dim(`\\n Known ids: ${ids.slice(0, 12).join(\", \")}${ids.length > 12 ? \", \u2026\" : \"\"}`);\n return c.red(t(\"mod.notInRegistry\", { query })) + hintBlock + \"\\n\";\n }\n\n const installedPath = path.join(modulesDir(), query);\n const isInstalled = existsSync(installedPath);\n const lines: string[] = [c.bold(`\\n${query}`)];\n if (staleNote) lines.push(staleNote.trimEnd());\n lines.push(` registry : ${DEFAULT_REGISTRY_REPO}@${DEFAULT_REGISTRY_TAG}`);\n if (entry.npm) {\n lines.push(` npm : ${entry.npm}`);\n if (entry.version) lines.push(` version : ${entry.version}`);\n lines.push(` source : npm:${entry.npm}${entry.version ? `@${entry.version}` : \"\"}`);\n if (entry.sdk) lines.push(` sdk : ${entry.sdk}`);\n } else {\n lines.push(` repo : ${entry.repo}`);\n lines.push(` tag : ${entry.tag}`);\n lines.push(` source : github:${entry.repo}@${entry.tag}`);\n lines.push(` github : https://github.com/${entry.repo}/tree/${entry.tag}`);\n }\n lines.push(` local : ${isInstalled ? c.green(`installed @ ${installedPath}`) : c.dim(\"not installed\")}`);\n\n if (!isInstalled) {\n lines.push(c.dim(`\\n install: sfmc mod install ${query}`));\n } else {\n lines.push(c.dim(`\\n details: sfmc mod info ${query}`));\n }\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * info\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleInfo(args: string[]): Promise<string> {\n const id = args[0];\n if (!id) return c.yellow(t(\"mod.info.usage\"));\n const all = await scanInstalled();\n const m = all.find((x) => x.id === id);\n if (!m) return c.red(t(\"mod.notInstalledAt\", { id, path: path.join(modulesDir(), id) }));\n const lines: string[] = [c.bold(`\\n${id}`)];\n lines.push(` path : ${m.path}`);\n lines.push(` files : ${m.fileCount}`);\n lines.push(` size : ${fmtBytes(m.totalBytes)}`);\n lines.push(` fingerprint : ${m.fingerprint}`);\n if (m.manifest) {\n lines.push(` schemaVer : ${m.manifest.schemaVersion ?? \"(none)\"}`);\n lines.push(` routes : ${m.manifest.routes?.length ?? 0}`);\n if (m.manifest.routes?.length) {\n for (const r of m.manifest.routes)\n lines.push(c.dim(` ${r.method.padEnd(7)} ${r.path.padEnd(36)} ${r.handler}`));\n }\n lines.push(` migrations : ${m.manifest.migrations?.length ?? 0}`);\n if (m.manifest.migrations?.length) {\n for (const mg of m.manifest.migrations) lines.push(c.dim(` v${mg.version} ${mg.name}`));\n }\n if (m.manifest.notes) lines.push(` notes : ${c.dim(m.manifest.notes)}`);\n } else {\n lines.push(c.yellow(` manifest : (missing or unreadable)`));\n }\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * verify\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleVerify(args: string[]): Promise<string> {\n const id = args[0];\n if (id) {\n const all = await scanInstalled();\n const m = all.find((x) => x.id === id);\n if (!m) return c.red(t(\"mod.notInstalled\", { id }));\n return c.green(t(\"mod.verifyOk\", { id, fp: m.fingerprint }));\n }\n const all = await scanInstalled();\n const lines = [c.bold(\"\\nVerifying installed modules\")];\n for (const m of all) {\n lines.push(` ${m.id.padEnd(28)} ${shortHash(m.fingerprint)}`);\n }\n if (all.length === 0) lines.push(c.dim(\" (none)\"));\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * install \u2014 shells out to scripts/module-install/fetch-module.mjs\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * enable / disable \u2014 \u672C\u5730\u5199 module-lock.json\uFF1Bdb \u5728\u7EBF\u65F6 best-effort \u70ED\u540C\u6B65\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nfunction readDbConfig(): DBConfig {\n return (readJson<DBConfig>(configPath(ROOT, \"db_config.json\")) ?? {}) as DBConfig;\n}\n\nfunction moduleLockPath(): string {\n return modulePath(path.join(ROOT, \"modules\"), \"module-lock.json\");\n}\n\nfunction catalogPathOnDisk(): string {\n return modulePath(path.join(ROOT, \"modules\"), \"catalog.json\");\n}\n\n/** \u5DF2\u88C5\u5305 + catalog \u6295\u5F71 \u2192 \u542F\u505C\u5019\u9009\uFF08canDisable \u4E0E db \u540C\u6E90\uFF1A\u7701\u7565\u89C6\u4E3A\u53EF\u7981\u7528\uFF09\u3002 */\nfunction buildToggleCandidates(installed: InstalledModule[]): ToggleCandidate[] {\n const catalog = (readJson<Catalog>(catalogPathOnDisk()) ?? {\n version: 1,\n modules: [],\n }) as Catalog;\n const rows = Array.isArray(catalog.modules) ? catalog.modules : [];\n const byLogical = new Map<string, (typeof rows)[number]>();\n for (const raw of rows) {\n if (!raw || typeof raw !== \"object\") continue;\n const id = String(raw.id || \"\").trim();\n if (id) byLogical.set(id, raw);\n }\n return installed.map((m) => {\n const logicalId = typeof m.manifest?.id === \"string\" && m.manifest.id ? m.manifest.id : m.id;\n const raw = byLogical.get(logicalId);\n const configKeyRaw = raw ? String(raw.configKey || \"\").trim() : \"\";\n const canDisable = raw ? raw.canDisable !== false : true;\n const out: ToggleCandidate = { logicalId, folderId: m.id, canDisable };\n if (configKeyRaw) out.configKey = configKeyRaw;\n return out;\n });\n}\n\nfunction writeLocalModuleEnabled(logicalId: string, enabled: boolean): void {\n const lockPath = moduleLockPath();\n const lock = (readJson<ModuleLock>(lockPath) ?? {\n version: 1,\n modules: {},\n }) as ModuleLock;\n applyLockEnabled(lock, logicalId, enabled);\n writeJson(lockPath, lock);\n}\n\nasync function notifyDbToggle(logicalId: string, action: \"enable\" | \"disable\"): Promise<ToggleNotify> {\n const cfg = readDbConfig();\n const port = cfg.db_port ?? 3001;\n const token = cfg.http_auth || \"\";\n const url = `http://127.0.0.1:${port}/api/sfmc/modules/${encodeURIComponent(logicalId)}/${action}`;\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n },\n });\n } catch (err) {\n return { ok: false, reason: \"unreachable\", detail: (err as Error).message };\n }\n const text = await res.text();\n let body: unknown;\n try {\n body = JSON.parse(text);\n } catch {\n body = text;\n }\n if (!res.ok) {\n const err = (body as { error?: string })?.error ?? `HTTP ${res.status}`;\n return { ok: false, reason: \"http\", detail: err };\n }\n if ((body as { success?: boolean })?.success === false) {\n return { ok: false, reason: \"http\", detail: text };\n }\n return { ok: true };\n}\n\nasync function cmdModuleToggle(query: string, action: \"enable\" | \"disable\"): Promise<CliResult> {\n const installed = await scanInstalled();\n const target = resolveToggleTarget(query, buildToggleCandidates(installed));\n if (action === \"enable\" && target && isRetiredPlatformModule(target.logicalId)) return failResult(\"monitor \u5DF2\u6536\u7F16\u81F3\u5E73\u53F0\uFF0C\u65E0\u9700\u542F\u7528\uFF1B\u8BF7\u66F4\u65B0\u5E73\u53F0\u884C\u4E3A\u5305\u3002\");\n if (action === \"enable\" && target && isRetiredPlatformModule(target.logicalId)) return failResult(\"monitor \u5DF2\u6536\u7F16\u81F3\u5E73\u53F0\uFF0C\u65E0\u9700\u542F\u7528\uFF1B\u8BF7\u66F4\u65B0\u5E73\u53F0\u884C\u4E3A\u5305\u3002\");\n if (!target) {\n return failResult(c.red(t(\"mod.notInstalled\", { id: query })));\n }\n if (action === \"disable\" && !target.canDisable) {\n return failResult(c.red(t(\"mod.cannotDisable\", { id: target.logicalId })));\n }\n\n const enabled = action === \"enable\";\n try {\n writeLocalModuleEnabled(target.logicalId, enabled);\n } catch (err) {\n return failResult(c.red(t(\"mod.toggleLockFailed\", { id: target.logicalId, message: (err as Error).message })));\n }\n\n const notify = await notifyDbToggle(target.logicalId, action);\n const fin = finalizeToggle(true, notify);\n const label = action === \"enable\" ? t(\"mod.action.enabled\") : t(\"mod.action.disabled\");\n const head = c.green(t(\"mod.toggleOk\", { label, id: target.logicalId }));\n if (!fin.warnNotify) {\n return okResult(head);\n }\n const detail = notify.ok === false ? (notify.detail ?? notify.reason) : \"\";\n const warn = c.yellow(t(\"mod.toggleDbSkipped\", { detail }));\n return okResult(`${head}\\n${warn}`);\n}\n\nexport async function cmdModuleEnable(args: string[]): Promise<CliResult> {\n const id = args[0];\n if (id && isRetiredPlatformModule(id)) return failResult(\"monitor \u5DF2\u6536\u7F16\u81F3\u5E73\u53F0\uFF0C\u65E0\u9700\u5B89\u88C5\u6216\u542F\u7528\uFF1B\u8BF7\u66F4\u65B0\u5E73\u53F0\u884C\u4E3A\u5305\u3002\");\n if (!id) return failResult(c.yellow(t(\"mod.enable.usage\")));\n return cmdModuleToggle(id, \"enable\");\n}\n\nexport async function cmdModuleDisable(args: string[]): Promise<CliResult> {\n const id = args[0];\n if (!id) return failResult(c.yellow(t(\"mod.disable.usage\")));\n return cmdModuleToggle(id, \"disable\");\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * install \u2014 shells out to scripts/module-install/fetch-module.mjs\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/**\n * \u9884\u68C0 --from \u53D6\u503C\u662F\u5426\u662F\u5408\u6CD5 scheme\uFF1A\n * - npm:@scope/name / npm:<name>\n * - local[:<path>] / local\n * - tgz:<path>\n * - zip:<path>\n * - dir:<abs path>\n * - github:<owner>/<repo>[@tag]\n * - \u88F8\u8DEF\u5F84\uFF1A\u5FC5\u987B\u5B58\u5728\u4E14\u4E3A\u76EE\u5F55\uFF08\u88F8\u6587\u4EF6\u5E94\u8F6C tgz:/zip:\uFF09\n * \u8FD4\u56DE null \u8868\u793A\u5408\u6CD5\uFF1B\u5426\u5219\u8FD4\u56DE\u7528\u6237\u53EF\u8BFB\u7684\u9519\u8BEF\u6587\u6848\u3002\n */\nfunction validateFromScheme(from: string): string | null {\n if (\n from === \"local\" ||\n from.startsWith(\"local:\") ||\n from.startsWith(\"dir:\") ||\n from.startsWith(\"npm:\") ||\n from.startsWith(\"tgz:\") ||\n from.startsWith(\"zip:\") ||\n from.startsWith(\"github:\")\n ) {\n return null;\n }\n if (existsSync(from)) {\n const st = lstatSync(from);\n if (st.isDirectory()) return null;\n return `--from \u88F8\u8DEF\u5F84\u987B\u4E3A\u76EE\u5F55\uFF08\u6587\u4EF6\u8BF7\u7528 --from local:<tgz|zip>\uFF09: ${from}`;\n }\n return t(\"mod.fromUnknown\", { value: from });\n}\n\nexport async function cmdModuleInstall(args: string[]): Promise<string> {\n // \u652F\u6301: install <id> [id2 ...] [--from ...] [--link] [--sha256 ...]\n const flags = parseFlags(args);\n const positional: string[] = [];\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--from\" || args[i] === \"--sha256\") {\n i++;\n continue;\n }\n if (args[i]?.startsWith(\"--from=\") || args[i]?.startsWith(\"--sha256=\")) continue;\n if (args[i]?.startsWith(\"--\")) continue;\n positional.push(args[i]!);\n }\n if (positional.length === 0) {\n return c.yellow(t(\"mod.install.usage\"));\n }\n\n /* scheme \u9884\u68C0\uFF1A\u907F\u514D\u62FC\u5199\u9519\u8BEF\u5EF6\u8FDF\u5230\u5B50\u8FDB\u7A0B\u62A5\u9519 */\n if (flags.from) {\n const err = validateFromScheme(flags.from);\n if (err) return c.red(err);\n }\n\n const fetchScript = resolveFetchModule();\n if (!fetchScript) {\n return c.red(t(\"mod.fetchMissing\"));\n }\n const sub = [\"install\", ...positional];\n if (flags.from) sub.push(\"--from\", flags.from);\n if (flags.sha256) sub.push(\"--sha256\", flags.sha256);\n if (flags.link) sub.push(\"--link\");\n return new Promise<string>((resolve) => {\n const proc = spawn(process.execPath, [fetchScript, ...sub], {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, SFMC_ROOT: ROOT },\n });\n let out = \"\";\n proc.stdout?.on(\"data\", (d: Buffer) => {\n out += d.toString();\n });\n proc.stderr?.on(\"data\", (d: Buffer) => {\n out += d.toString();\n });\n proc.on(\"exit\", (code) => {\n resolve(out + (code === 0 ? \"\" : `\\n[exit ${code}]`));\n });\n proc.on(\"error\", (e) => resolve(c.red(`spawn failed: ${e.message}`)));\n });\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * uninstall\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleUninstall(args: string[]): Promise<string> {\n const id = args[0];\n if (!id) return c.yellow(t(\"mod.uninstall.usage\"));\n const fetchScript = resolveFetchModule();\n if (!fetchScript) {\n // \u56DE\u9000:\u4EC5\u5220\u76EE\u5F55(\u65E7\u884C\u4E3A)\n const target = path.join(modulesDir(), id);\n if (!existsSync(target)) return c.yellow(t(\"mod.notInstalledFolder\", { id, path: target }));\n await fs.rm(target, { recursive: true, force: true });\n return c.green(t(\"mod.removed\", { id, path: target }));\n }\n return new Promise<string>((resolve) => {\n const proc = spawn(process.execPath, [fetchScript, \"uninstall\", id], {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, SFMC_ROOT: ROOT },\n });\n let out = \"\";\n proc.stdout?.on(\"data\", (d: Buffer) => {\n out += d.toString();\n });\n proc.stderr?.on(\"data\", (d: Buffer) => {\n out += d.toString();\n });\n proc.on(\"exit\", (code) => {\n resolve(out + (code === 0 ? \"\" : `\\n[exit ${code}]`));\n });\n proc.on(\"error\", (e) => resolve(c.red(`spawn failed: ${e.message}`)));\n });\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * CLI flag parsing\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\ninterface InstallFlags {\n from: string | null;\n sha256: string | null;\n link: boolean;\n}\n\nfunction parseFlags(args: string[]): InstallFlags {\n const flags: InstallFlags = { from: null, sha256: null, link: false };\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--from\") flags.from = args[++i] ?? null;\n else if (args[i]?.startsWith(\"--from=\")) flags.from = args[i]!.slice(\"--from=\".length);\n else if (args[i] === \"--sha256\") flags.sha256 = args[++i] ?? null;\n else if (args[i]?.startsWith(\"--sha256=\")) flags.sha256 = args[i]!.slice(\"--sha256=\".length);\n else if (args[i] === \"--link\") flags.link = true;\n }\n return flags;\n}\n\n/**\n * \u7EDF\u4E00\u5206\u53D1 module/mod \u5B50\u547D\u4EE4 \u2014\u2014 CLI(`main.ts`)\u4E0E REPL(`repl.ts`)\u5171\u7528,\n * \u907F\u514D\u4E24\u5904 switch \u6F02\u79FB\u3002\n *\n * \u901A\u9053\u95E8\u7981\uFF08argv/repl\uFF09\u7531\u8C03\u7528\u65B9\u5728 dispatch \u524D\u7ECF command-surface \u5224\u5B9A\uFF1B\n * \u672C\u51FD\u6570\u53EA\u8D1F\u8D23\u5B50\u547D\u4EE4\u8DEF\u7531\u3002`remove` \u4F5C\u4E3A uninstall \u7684\u540C\u4E49\u522B\u540D\u4FDD\u7559\u3002\n *\n * \u4F5C\u8005\u5411 test/watch/publish \u5DF2\u8FC1\u81F3 VS Code \u6269\u5C55\u4E0E @sfmc-bds/devkit\u3002\n */\nexport async function dispatchModuleCommand(sub: string | undefined, args: string[]): Promise<string> {\n if (sub && [\"install\", \"uninstall\", \"remove\", \"enable\", \"disable\", \"update\", \"pin\", \"build\", \"reload\"].includes(sub) && !args.includes(\"--check\")) {\n const { withMaintenanceLock } = await import(\"@sfmc-bds/management/node\");\n return withMaintenanceLock(ROOT, () => dispatchModuleCommandUnlocked(sub, args));\n }\n return dispatchModuleCommandUnlocked(sub, args);\n}\nasync function dispatchModuleCommandUnlocked(sub: string | undefined, args: string[]): Promise<string> {\n switch (sub) {\n case \"list\":\n return cmdModuleList(args);\n case \"search\":\n return cmdModuleSearch(args);\n case \"submit\": {\n const { runRegistrySubmitCommand } = await import(\"@sfmc-bds/devkit\");\n return runRegistrySubmitCommand(args);\n }\n case \"install\":\n return cmdModuleInstall(args);\n case \"uninstall\":\n case \"remove\":\n return cmdModuleUninstall(args);\n case \"verify\":\n return cmdModuleVerify(args);\n case \"info\":\n return cmdModuleInfo(args);\n case \"enable\":\n return (await cmdModuleEnable(args)).message;\n case \"disable\":\n return (await cmdModuleDisable(args)).message;\n case \"build\": {\n const { cmdModuleBuild } = await import(\"./module-pack-build.js\");\n return cmdModuleBuild(args);\n }\n case \"reload\": {\n const { cmdModuleReload } = await import(\"./module-pack-build.js\");\n return cmdModuleReload(args);\n }\n case \"update\": {\n const { cmdModuleUpdate } = await import(\"./module-update/index.js\");\n return cmdModuleUpdate(args);\n }\n case \"pin\": {\n const { cmdModulePin } = await import(\"./module-update/index.js\");\n return cmdModulePin(args);\n }\n case \"test\":\n case \"watch\":\n case \"publish\":\n return c.yellow(\n `[mod ${sub}] \u5DF2\u79FB\u81F3\u6269\u5C55\u300CSFMC Module\u300D\u5168\u5468\u671F\uFF08Create/Test/Link/Watch/Publish\uFF09\uFF1B\u5EFA\u4ED3\u8BF7\u7528 pnpm dlx @sfmc-bds/create-module@latest\uFF1B\u8FD0\u7EF4\u8BF7\u7528 mod build|reload|install\u3002`\n );\n default:\n return c.yellow(moduleUsage());\n }\n}\n\n/** \u540C\u6B65\u679A\u4E3E\u5DF2\u5B89\u88C5\u6A21\u5757 id,\u4F9B REPL Tab \u8865\u5168(\u4E0D\u8BFB fingerprint,\u5C3D\u91CF\u8F7B\u91CF)\u3002 */\nexport function listInstalledModuleIdsSync(): string[] {\n const dir = modulesDir();\n if (!existsSync(dir)) return [];\n try {\n return readdirSync(dir, { withFileTypes: true })\n .filter((e) => {\n try {\n return statSync(path.join(dir, e.name)).isDirectory();\n } catch {\n return false;\n }\n })\n .map((e) => e.name)\n .sort((a, b) => a.localeCompare(b));\n } catch {\n return [];\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * sfmc module-commands \u2014 runtime CLI for inspecting and managing modules\n * already on disk under `modules/packages/<id>/`.\n *\n * \u9876\u5C42\u547D\u4EE4\u522B\u540D:`module` / `mod`(\u7531 main.ts / repl.ts \u5171\u540C\u8BC6\u522B)\u3002\n * \u5B50\u547D\u4EE4\u901A\u9053\u95E8\u7981\u89C1 command-surface.ts\uFF08dispatch \u524D\u7531 main/repl \u5224\u5B9A\uFF09\u3002\n */\n\nimport {\n configPath,\n modulePath,\n readJson,\n writeJson,\n type Catalog,\n type DBConfig,\n type ModuleLock,\n} from \"@sfmc-bds/sdk/node/config\";\nimport { spawn } from \"node:child_process\";\nimport { existsSync, lstatSync, readdirSync, statSync } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { failResult, okResult, type CliResult } from \"./cli-result.js\";\nimport { isDevAccentModuleSub, listVisibleModuleSubs, type CommandMode } from \"./command-surface.js\";\nimport { t } from \"./i18n/index.js\";\nimport { dirFingerprint, shouldSkipModuleEntry } from \"./module-fingerprint.js\";\nimport {\n applyLockEnabled,\n finalizeToggle,\n resolveToggleTarget,\n type ToggleCandidate,\n type ToggleNotify,\n} from \"./module-toggle.js\";\nimport { DEFAULT_REGISTRY_REPO, DEFAULT_REGISTRY_TAG, findUnknownModules, resolveRegistryIndex } from \"./registry.js\";\nimport { ROOT, resolveFetchModule } from \"./runtime.js\";\nimport { c } from \"./theme.js\";\nimport { isRetiredPlatformModule } from \"@sfmc-bds/sdk/contracts\";\n\n/** \u9876\u5C42\u547D\u4EE4\u540D(\u4E3B\u540D + \u77ED\u522B\u540D),\u4F9B\u5E2E\u52A9 / \u8865\u5168 / \u5206\u53D1\u5171\u7528\u3002 */\nexport const MODULE_CMD_NAMES = [\"module\", \"mod\"] as const;\n\nexport type ModuleCmdName = (typeof MODULE_CMD_NAMES)[number];\n\n/** \u5224\u65AD\u662F\u5426\u4E3A module \u9876\u5C42\u547D\u4EE4(\u542B\u522B\u540D);\u907F\u514D main/repl \u518D\u786C\u7F16\u7801 case\u3002 */\nexport function isModuleCommand(cmd: string | undefined): cmd is ModuleCmdName {\n return !!cmd && (MODULE_CMD_NAMES as readonly string[]).includes(cmd);\n}\n\n/** \u5F00\u53D1\u8005\u6837\u5F0F\u5B50\u547D\u4EE4\uFF08\u84DD\u6807\uFF0C\u975E\u95E8\u7981\uFF09\u3002 */\nexport const DEV_ACCENT_MODULE_SUBCOMMANDS = [\"build\", \"reload\", \"submit\"] as const;\n\n/** \u5F53\u524D\u901A\u9053\u4E0B\u53EF\u89C1\u7684 module \u5B50\u547D\u4EE4\uFF08\u81EA\u52A8\u8865\u5168 / usage\uFF09\u3002 */\nexport function getVisibleModuleSubcommands(mode: CommandMode): readonly string[] {\n return listVisibleModuleSubs(mode);\n}\n\n/** sub \u662F\u5426\u4E3A\u5F00\u53D1\u8005\u84DD\u6807\uFF08help \u7740\u8272\uFF09\u3002 */\nexport function isDeveloperSubcommand(sub: string | undefined): boolean {\n return isDevAccentModuleSub(sub);\n}\n\n/** Usage \u884C\u4E3B\u540D|\u522B\u540D(\u4E0E MODULE_CMD_NAMES \u540C\u6E90,\u907F\u514D\u4E0E\u5E2E\u52A9\u6587\u6848\u6F02\u79FB)\u3002 */\nexport function moduleUsage(mode: CommandMode = \"argv\"): string {\n return t(\"mod.usage\", {\n cmds: MODULE_CMD_NAMES.join(\"|\"),\n subs: getVisibleModuleSubcommands(mode).join(\"|\"),\n });\n}\n\n/** Where modules live on disk. */\nfunction modulesDir(): string {\n return path.join(ROOT, \"modules\", \"packages\");\n}\n\nfunction fmtBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / 1024 / 1024).toFixed(2)} MB`;\n}\n\nfunction shortHash(h: string): string {\n return h.slice(0, 8) + \"\u2026\" + h.slice(-8);\n}\n\ninterface ModuleManifest {\n schemaVersion?: number;\n id?: string;\n handlers?: string[];\n routes?: Array<{ method: string; path: string; handler: string }>;\n migrations?: Array<{ name: string; version: number }>;\n notes?: string;\n}\n\ninterface InstalledModule {\n id: string;\n path: string;\n manifest: ModuleManifest | null;\n totalBytes: number;\n fileCount: number;\n fingerprint: string;\n}\n\n/** Enumerate every installed module by scanning `modules/packages/<id>/`. */\nasync function scanInstalled(): Promise<InstalledModule[]> {\n const dir = modulesDir();\n if (!existsSync(dir)) return [];\n const entries = await fs.readdir(dir, { withFileTypes: true });\n const out: InstalledModule[] = [];\n for (const e of entries) {\n const id = e.name;\n const modPath = path.join(dir, id);\n try {\n if (!statSync(modPath).isDirectory()) continue;\n } catch {\n continue;\n }\n const manifestPath = path.join(modPath, \"sapi\", \"manifest.json\");\n let manifest: ModuleManifest | null = null;\n if (existsSync(manifestPath)) {\n try {\n manifest = JSON.parse(await fs.readFile(manifestPath, \"utf8\")) as ModuleManifest;\n } catch {\n /* corrupt manifest is not fatal \u2014 just skip its fields */\n }\n }\n try {\n const { totalBytes, fileCount } = await dirSize(modPath);\n const fingerprint = await dirFingerprint(modPath);\n out.push({ id, path: modPath, manifest, totalBytes, fileCount, fingerprint });\n } catch {\n // \u574F\u94FE\u63A5\u6216\u76EE\u5F55\u5DF2\u6D88\u5931\u65F6\u8DF3\u8FC7\uFF0C\u4E0D\u8BA9 CLI \u8D77\u4E0D\u6765\n continue;\n }\n }\n out.sort((a, b) => a.id.localeCompare(b.id));\n return out;\n}\n\nasync function dirSize(dir: string): Promise<{ totalBytes: number; fileCount: number }> {\n let totalBytes = 0;\n let fileCount = 0;\n async function walk(p: string): Promise<void> {\n for (const e of await fs.readdir(p, { withFileTypes: true })) {\n if (shouldSkipModuleEntry(path.basename(p), e.name)) continue;\n const child = path.join(p, e.name);\n if (e.isDirectory()) await walk(child);\n else if (e.isFile()) {\n const s = await fs.stat(child);\n totalBytes += s.size;\n fileCount++;\n }\n }\n }\n await walk(dir);\n return { totalBytes, fileCount };\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * list\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleList(_args: string[]): Promise<string> {\n const installed = await scanInstalled();\n if (installed.length === 0) {\n return c.dim(t(\"mod.noneInstalled\", { dir: modulesDir() }));\n }\n const lock = (readJson<ModuleLock>(modulePath(path.join(ROOT, \"modules\"), \"module-lock.json\")) ?? {\n version: 1,\n modules: {},\n }) as ModuleLock;\n const ids = installed.map((m) => m.id);\n const unknown = new Set(await findUnknownModules(ids));\n const lines: string[] = [c.bold(`\\n${t(\"mod.list.title\")}`), c.dim(` ${modulesDir()}`)];\n const header = ` ${\"id\".padEnd(28)}${\"state\".padEnd(8)}${\"files\".padEnd(8)}${\"size\".padEnd(10)}${\"fingerprint\"}`;\n lines.push(c.dim(header));\n for (const m of installed) {\n const logicalId = typeof m.manifest?.id === \"string\" && m.manifest.id ? m.manifest.id : m.id;\n const enabled = lock.modules?.[logicalId]?.enabled === true;\n const stateCol = (enabled ? c.green(\"on\") : c.dim(\"off\")).padEnd(8);\n let mark: string;\n if (!m.manifest) {\n mark = c.yellow(\"\u25CB\");\n } else if (unknown.has(m.id)) {\n mark = c.yellow(\"?\");\n } else {\n mark = enabled ? c.green(\"\u25CF\") : c.dim(\"\u25CB\");\n }\n const idLabel = logicalId !== m.id ? `${m.id}(${logicalId})` : m.id;\n lines.push(\n ` ${mark} ${idLabel.padEnd(26)} ${stateCol}${String(m.fileCount).padEnd(8)}${fmtBytes(m.totalBytes).padEnd(10)}${shortHash(m.fingerprint)}`\n );\n }\n lines.push(c.dim(`\\n tip: ${MODULE_CMD_NAMES[1] ?? \"mod\"} enable|disable <logicalId>`));\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/**\n * Walk `modules/packages/<id>/` and print a one-line yellow warning for each\n * id that isn't in the first-party registry. Intended for the REPL startup\n * hook so users immediately see modules they installed from somewhere else.\n *\n * Best-effort: registry unreachable \u2192 no warning (no false positives).\n */\nexport async function scanAndWarnUnknown(): Promise<string> {\n const installed = await scanInstalled();\n if (installed.length === 0) return \"\";\n const unknown = await findUnknownModules(installed.map((m) => m.id));\n if (unknown.length === 0) return \"\";\n const list = unknown.map((id) => ` ${c.yellow(\"?\")} ${id}`).join(\"\\n\");\n return `${c.yellow(\"[sfmc] modules installed from unknown publisher \u2014 verify before use:\")}\\n${list}\\n`;\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * search \u2014 \u62C9\u53D6 first-party registry;\u5E26 id \u67E5\u5355\u6761 registry info\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/**\n * \u62C9\u53D6 first-party registry \u6A21\u5757\u5217\u8868;\u5E26 id \u65F6\u5C55\u793A\u8BE5\u6761\u76EE\u7684 registry info\u3002\n * \u4E0E\u672C\u5730 `info`(\u5DF2\u5B89\u88C5\u78C1\u76D8\u8BE6\u60C5)\u533A\u5206:`search` \u770B registry,`info` \u770B\u672C\u673A packages\u3002\n */\nexport async function cmdModuleSearch(args: string[]): Promise<string> {\n const query = args[0];\n const { index, stale } = await resolveRegistryIndex({ force: true });\n const ids = Object.keys(index).sort((a, b) => a.localeCompare(b));\n\n if (ids.length === 0) {\n return c.red(\n `\\nRegistry empty or unreachable (${DEFAULT_REGISTRY_REPO}@${DEFAULT_REGISTRY_TAG}).\\n` +\n `Check network, or: mod install <id> --from github:owner/repo@tag\\n`\n );\n }\n\n const staleNote = stale ? c.yellow(\" (offline \u2014 showing cached index)\\n\") : \"\";\n\n /* \u65E0\u53C2\u6570:\u5217\u51FA\u5168\u90E8 */\n if (!query) {\n const installed = new Set(listInstalledModuleIdsSync());\n const lines: string[] = [\n c.bold(`\\nFirst-party registry (${DEFAULT_REGISTRY_REPO}@${DEFAULT_REGISTRY_TAG}) \u2014 ${ids.length} modules`),\n ];\n if (staleNote) lines.push(staleNote.trimEnd());\n lines.push(c.dim(` ${\"id\".padEnd(28)}${\"source\".padEnd(40)}local`));\n for (const id of ids) {\n const e = index[id]!;\n const src = e.npm ? `npm:${e.npm}${e.version ? `@${e.version}` : \"\"}` : `github:${e.repo}@${e.tag}`;\n const local = installed.has(id) ? c.green(\"\u25CF\") : c.dim(\"\u25CB\");\n lines.push(` ${local} ${id.padEnd(26)}${src.padEnd(40)}${installed.has(id) ? \"installed\" : \"\"}`);\n }\n lines.push(c.dim(`\\n tip: sfmc mod search <id> \u2192 registry info`));\n lines.push(c.dim(` sfmc mod install <id> \u2192 download + catalog sync`));\n return lines.join(\"\\n\") + \"\\n\";\n }\n\n /* \u5E26 id:\u67E5\u5355\u6761 registry info */\n const entry = index[query];\n if (!entry) {\n const hints = ids.filter((id) => id.includes(query) || query.includes(id)).slice(0, 8);\n const hintBlock =\n hints.length > 0\n ? c.dim(`\\n Did you mean:\\n`) + hints.map((h) => ` ${h}`).join(\"\\n\")\n : c.dim(`\\n Known ids: ${ids.slice(0, 12).join(\", \")}${ids.length > 12 ? \", \u2026\" : \"\"}`);\n return c.red(t(\"mod.notInRegistry\", { query })) + hintBlock + \"\\n\";\n }\n\n const installedPath = path.join(modulesDir(), query);\n const isInstalled = existsSync(installedPath);\n const lines: string[] = [c.bold(`\\n${query}`)];\n if (staleNote) lines.push(staleNote.trimEnd());\n lines.push(` registry : ${DEFAULT_REGISTRY_REPO}@${DEFAULT_REGISTRY_TAG}`);\n if (entry.npm) {\n lines.push(` npm : ${entry.npm}`);\n if (entry.version) lines.push(` version : ${entry.version}`);\n lines.push(` source : npm:${entry.npm}${entry.version ? `@${entry.version}` : \"\"}`);\n if (entry.sdk) lines.push(` sdk : ${entry.sdk}`);\n } else {\n lines.push(` repo : ${entry.repo}`);\n lines.push(` tag : ${entry.tag}`);\n lines.push(` source : github:${entry.repo}@${entry.tag}`);\n lines.push(` github : https://github.com/${entry.repo}/tree/${entry.tag}`);\n }\n lines.push(` local : ${isInstalled ? c.green(`installed @ ${installedPath}`) : c.dim(\"not installed\")}`);\n\n if (!isInstalled) {\n lines.push(c.dim(`\\n install: sfmc mod install ${query}`));\n } else {\n lines.push(c.dim(`\\n details: sfmc mod info ${query}`));\n }\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * info\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleInfo(args: string[]): Promise<string> {\n const id = args[0];\n if (!id) return c.yellow(t(\"mod.info.usage\"));\n const all = await scanInstalled();\n const m = all.find((x) => x.id === id);\n if (!m) return c.red(t(\"mod.notInstalledAt\", { id, path: path.join(modulesDir(), id) }));\n const lines: string[] = [c.bold(`\\n${id}`)];\n lines.push(` path : ${m.path}`);\n lines.push(` files : ${m.fileCount}`);\n lines.push(` size : ${fmtBytes(m.totalBytes)}`);\n lines.push(` fingerprint : ${m.fingerprint}`);\n if (m.manifest) {\n lines.push(` schemaVer : ${m.manifest.schemaVersion ?? \"(none)\"}`);\n lines.push(` routes : ${m.manifest.routes?.length ?? 0}`);\n if (m.manifest.routes?.length) {\n for (const r of m.manifest.routes)\n lines.push(c.dim(` ${r.method.padEnd(7)} ${r.path.padEnd(36)} ${r.handler}`));\n }\n lines.push(` migrations : ${m.manifest.migrations?.length ?? 0}`);\n if (m.manifest.migrations?.length) {\n for (const mg of m.manifest.migrations) lines.push(c.dim(` v${mg.version} ${mg.name}`));\n }\n if (m.manifest.notes) lines.push(` notes : ${c.dim(m.manifest.notes)}`);\n } else {\n lines.push(c.yellow(` manifest : (missing or unreadable)`));\n }\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * verify\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleVerify(args: string[]): Promise<string> {\n const id = args[0];\n if (id) {\n const all = await scanInstalled();\n const m = all.find((x) => x.id === id);\n if (!m) return c.red(t(\"mod.notInstalled\", { id }));\n return c.green(t(\"mod.verifyOk\", { id, fp: m.fingerprint }));\n }\n const all = await scanInstalled();\n const lines = [c.bold(\"\\nVerifying installed modules\")];\n for (const m of all) {\n lines.push(` ${m.id.padEnd(28)} ${shortHash(m.fingerprint)}`);\n }\n if (all.length === 0) lines.push(c.dim(\" (none)\"));\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * install \u2014 shells out to scripts/module-install/fetch-module.mjs\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * enable / disable \u2014 \u672C\u5730\u5199 module-lock.json\uFF1Bdb \u5728\u7EBF\u65F6 best-effort \u70ED\u540C\u6B65\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nfunction readDbConfig(): DBConfig {\n return (readJson<DBConfig>(configPath(ROOT, \"db_config.json\")) ?? {}) as DBConfig;\n}\n\nfunction moduleLockPath(): string {\n return modulePath(path.join(ROOT, \"modules\"), \"module-lock.json\");\n}\n\nfunction catalogPathOnDisk(): string {\n return modulePath(path.join(ROOT, \"modules\"), \"catalog.json\");\n}\n\n/** \u5DF2\u88C5\u5305 + catalog \u6295\u5F71 \u2192 \u542F\u505C\u5019\u9009\uFF08canDisable \u4E0E db \u540C\u6E90\uFF1A\u7701\u7565\u89C6\u4E3A\u53EF\u7981\u7528\uFF09\u3002 */\nfunction buildToggleCandidates(installed: InstalledModule[]): ToggleCandidate[] {\n const catalog = (readJson<Catalog>(catalogPathOnDisk()) ?? {\n version: 1,\n modules: [],\n }) as Catalog;\n const rows = Array.isArray(catalog.modules) ? catalog.modules : [];\n const byLogical = new Map<string, (typeof rows)[number]>();\n for (const raw of rows) {\n if (!raw || typeof raw !== \"object\") continue;\n const id = String(raw.id || \"\").trim();\n if (id) byLogical.set(id, raw);\n }\n return installed.map((m) => {\n const logicalId = typeof m.manifest?.id === \"string\" && m.manifest.id ? m.manifest.id : m.id;\n const raw = byLogical.get(logicalId);\n const configKeyRaw = raw ? String(raw.configKey || \"\").trim() : \"\";\n const canDisable = raw ? raw.canDisable !== false : true;\n const out: ToggleCandidate = { logicalId, folderId: m.id, canDisable };\n if (configKeyRaw) out.configKey = configKeyRaw;\n return out;\n });\n}\n\nfunction writeLocalModuleEnabled(logicalId: string, enabled: boolean): void {\n const lockPath = moduleLockPath();\n const lock = (readJson<ModuleLock>(lockPath) ?? {\n version: 1,\n modules: {},\n }) as ModuleLock;\n applyLockEnabled(lock, logicalId, enabled);\n writeJson(lockPath, lock);\n}\n\nasync function notifyDbToggle(logicalId: string, action: \"enable\" | \"disable\"): Promise<ToggleNotify> {\n const cfg = readDbConfig();\n const port = cfg.db_port ?? 3001;\n const token = cfg.http_auth || \"\";\n const url = `http://127.0.0.1:${port}/api/sfmc/modules/${encodeURIComponent(logicalId)}/${action}`;\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n },\n });\n } catch (err) {\n return { ok: false, reason: \"unreachable\", detail: (err as Error).message };\n }\n const text = await res.text();\n let body: unknown;\n try {\n body = JSON.parse(text);\n } catch {\n body = text;\n }\n if (!res.ok) {\n const err = (body as { error?: string })?.error ?? `HTTP ${res.status}`;\n return { ok: false, reason: \"http\", detail: err };\n }\n if ((body as { success?: boolean })?.success === false) {\n return { ok: false, reason: \"http\", detail: text };\n }\n return { ok: true };\n}\n\nasync function cmdModuleToggle(query: string, action: \"enable\" | \"disable\"): Promise<CliResult> {\n const installed = await scanInstalled();\n const target = resolveToggleTarget(query, buildToggleCandidates(installed));\n if (action === \"enable\" && target && isRetiredPlatformModule(target.logicalId)) {\n return failResult(`${target.logicalId} \u5DF2\u6536\u7F16\u81F3\u5E73\u53F0\uFF0C\u65E0\u9700\u542F\u7528\uFF1B\u8BF7\u66F4\u65B0\u5E73\u53F0\u884C\u4E3A\u5305\u3002`);\n }\n if (!target) {\n return failResult(c.red(t(\"mod.notInstalled\", { id: query })));\n }\n if (action === \"disable\" && !target.canDisable) {\n return failResult(c.red(t(\"mod.cannotDisable\", { id: target.logicalId })));\n }\n\n const enabled = action === \"enable\";\n try {\n writeLocalModuleEnabled(target.logicalId, enabled);\n } catch (err) {\n return failResult(c.red(t(\"mod.toggleLockFailed\", { id: target.logicalId, message: (err as Error).message })));\n }\n\n const notify = await notifyDbToggle(target.logicalId, action);\n const fin = finalizeToggle(true, notify);\n const label = action === \"enable\" ? t(\"mod.action.enabled\") : t(\"mod.action.disabled\");\n const head = c.green(t(\"mod.toggleOk\", { label, id: target.logicalId }));\n if (!fin.warnNotify) {\n return okResult(head);\n }\n const detail = notify.ok === false ? (notify.detail ?? notify.reason) : \"\";\n const warn = c.yellow(t(\"mod.toggleDbSkipped\", { detail }));\n return okResult(`${head}\\n${warn}`);\n}\n\nexport async function cmdModuleEnable(args: string[]): Promise<CliResult> {\n const id = args[0];\n if (id && isRetiredPlatformModule(id)) return failResult(`${id} \u5DF2\u6536\u7F16\u81F3\u5E73\u53F0\uFF0C\u65E0\u9700\u5B89\u88C5\u6216\u542F\u7528\uFF1B\u8BF7\u66F4\u65B0\u5E73\u53F0\u884C\u4E3A\u5305\u3002`);\n if (!id) return failResult(c.yellow(t(\"mod.enable.usage\")));\n return cmdModuleToggle(id, \"enable\");\n}\n\nexport async function cmdModuleDisable(args: string[]): Promise<CliResult> {\n const id = args[0];\n if (!id) return failResult(c.yellow(t(\"mod.disable.usage\")));\n return cmdModuleToggle(id, \"disable\");\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * install \u2014 shells out to scripts/module-install/fetch-module.mjs\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/**\n * \u9884\u68C0 --from \u53D6\u503C\u662F\u5426\u662F\u5408\u6CD5 scheme\uFF1A\n * - npm:@scope/name / npm:<name>\n * - local[:<path>] / local\n * - tgz:<path>\n * - zip:<path>\n * - dir:<abs path>\n * - github:<owner>/<repo>[@tag]\n * - \u88F8\u8DEF\u5F84\uFF1A\u5FC5\u987B\u5B58\u5728\u4E14\u4E3A\u76EE\u5F55\uFF08\u88F8\u6587\u4EF6\u5E94\u8F6C tgz:/zip:\uFF09\n * \u8FD4\u56DE null \u8868\u793A\u5408\u6CD5\uFF1B\u5426\u5219\u8FD4\u56DE\u7528\u6237\u53EF\u8BFB\u7684\u9519\u8BEF\u6587\u6848\u3002\n */\nfunction validateFromScheme(from: string): string | null {\n if (\n from === \"local\" ||\n from.startsWith(\"local:\") ||\n from.startsWith(\"dir:\") ||\n from.startsWith(\"npm:\") ||\n from.startsWith(\"tgz:\") ||\n from.startsWith(\"zip:\") ||\n from.startsWith(\"github:\")\n ) {\n return null;\n }\n if (existsSync(from)) {\n const st = lstatSync(from);\n if (st.isDirectory()) return null;\n return `--from \u88F8\u8DEF\u5F84\u987B\u4E3A\u76EE\u5F55\uFF08\u6587\u4EF6\u8BF7\u7528 --from local:<tgz|zip>\uFF09: ${from}`;\n }\n return t(\"mod.fromUnknown\", { value: from });\n}\n\nexport async function cmdModuleInstall(args: string[]): Promise<string> {\n // \u652F\u6301: install <id> [id2 ...] [--from ...] [--link] [--sha256 ...]\n const flags = parseFlags(args);\n const positional: string[] = [];\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--from\" || args[i] === \"--sha256\") {\n i++;\n continue;\n }\n if (args[i]?.startsWith(\"--from=\") || args[i]?.startsWith(\"--sha256=\")) continue;\n if (args[i]?.startsWith(\"--\")) continue;\n positional.push(args[i]!);\n }\n if (positional.length === 0) {\n return c.yellow(t(\"mod.install.usage\"));\n }\n for (const id of positional) {\n if (isRetiredPlatformModule(id)) {\n return c.red(`${id} \u5DF2\u6536\u7F16\u81F3\u5E73\u53F0\uFF0C\u65E0\u9700\u5B89\u88C5\uFF1B\u8BF7\u66F4\u65B0\u5E73\u53F0\u884C\u4E3A\u5305\u3002`);\n }\n }\n\n /* scheme \u9884\u68C0\uFF1A\u907F\u514D\u62FC\u5199\u9519\u8BEF\u5EF6\u8FDF\u5230\u5B50\u8FDB\u7A0B\u62A5\u9519 */\n if (flags.from) {\n const err = validateFromScheme(flags.from);\n if (err) return c.red(err);\n }\n\n const fetchScript = resolveFetchModule();\n if (!fetchScript) {\n return c.red(t(\"mod.fetchMissing\"));\n }\n const sub = [\"install\", ...positional];\n if (flags.from) sub.push(\"--from\", flags.from);\n if (flags.sha256) sub.push(\"--sha256\", flags.sha256);\n if (flags.link) sub.push(\"--link\");\n return new Promise<string>((resolve) => {\n const proc = spawn(process.execPath, [fetchScript, ...sub], {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, SFMC_ROOT: ROOT },\n });\n let out = \"\";\n proc.stdout?.on(\"data\", (d: Buffer) => {\n out += d.toString();\n });\n proc.stderr?.on(\"data\", (d: Buffer) => {\n out += d.toString();\n });\n proc.on(\"exit\", (code) => {\n resolve(out + (code === 0 ? \"\" : `\\n[exit ${code}]`));\n });\n proc.on(\"error\", (e) => resolve(c.red(`spawn failed: ${e.message}`)));\n });\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * uninstall\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleUninstall(args: string[]): Promise<string> {\n const id = args[0];\n if (!id) return c.yellow(t(\"mod.uninstall.usage\"));\n const fetchScript = resolveFetchModule();\n if (!fetchScript) {\n // \u56DE\u9000:\u4EC5\u5220\u76EE\u5F55(\u65E7\u884C\u4E3A)\n const target = path.join(modulesDir(), id);\n if (!existsSync(target)) return c.yellow(t(\"mod.notInstalledFolder\", { id, path: target }));\n await fs.rm(target, { recursive: true, force: true });\n return c.green(t(\"mod.removed\", { id, path: target }));\n }\n return new Promise<string>((resolve) => {\n const proc = spawn(process.execPath, [fetchScript, \"uninstall\", id], {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, SFMC_ROOT: ROOT },\n });\n let out = \"\";\n proc.stdout?.on(\"data\", (d: Buffer) => {\n out += d.toString();\n });\n proc.stderr?.on(\"data\", (d: Buffer) => {\n out += d.toString();\n });\n proc.on(\"exit\", (code) => {\n resolve(out + (code === 0 ? \"\" : `\\n[exit ${code}]`));\n });\n proc.on(\"error\", (e) => resolve(c.red(`spawn failed: ${e.message}`)));\n });\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * CLI flag parsing\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\ninterface InstallFlags {\n from: string | null;\n sha256: string | null;\n link: boolean;\n}\n\nfunction parseFlags(args: string[]): InstallFlags {\n const flags: InstallFlags = { from: null, sha256: null, link: false };\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--from\") flags.from = args[++i] ?? null;\n else if (args[i]?.startsWith(\"--from=\")) flags.from = args[i]!.slice(\"--from=\".length);\n else if (args[i] === \"--sha256\") flags.sha256 = args[++i] ?? null;\n else if (args[i]?.startsWith(\"--sha256=\")) flags.sha256 = args[i]!.slice(\"--sha256=\".length);\n else if (args[i] === \"--link\") flags.link = true;\n }\n return flags;\n}\n\n/**\n * \u7EDF\u4E00\u5206\u53D1 module/mod \u5B50\u547D\u4EE4 \u2014\u2014 CLI(`main.ts`)\u4E0E REPL(`repl.ts`)\u5171\u7528,\n * \u907F\u514D\u4E24\u5904 switch \u6F02\u79FB\u3002\n *\n * \u901A\u9053\u95E8\u7981\uFF08argv/repl\uFF09\u7531\u8C03\u7528\u65B9\u5728 dispatch \u524D\u7ECF command-surface \u5224\u5B9A\uFF1B\n * \u672C\u51FD\u6570\u53EA\u8D1F\u8D23\u5B50\u547D\u4EE4\u8DEF\u7531\u3002`remove` \u4F5C\u4E3A uninstall \u7684\u540C\u4E49\u522B\u540D\u4FDD\u7559\u3002\n *\n * \u4F5C\u8005\u5411 test/watch/publish \u5DF2\u8FC1\u81F3 VS Code \u6269\u5C55\u4E0E @sfmc-bds/devkit\u3002\n */\nexport async function dispatchModuleCommand(sub: string | undefined, args: string[]): Promise<string> {\n if (sub && [\"install\", \"uninstall\", \"remove\", \"enable\", \"disable\", \"update\", \"pin\", \"build\", \"reload\"].includes(sub) && !args.includes(\"--check\")) {\n const { withMaintenanceLock } = await import(\"@sfmc-bds/management/node\");\n return withMaintenanceLock(ROOT, () => dispatchModuleCommandUnlocked(sub, args));\n }\n return dispatchModuleCommandUnlocked(sub, args);\n}\nasync function dispatchModuleCommandUnlocked(sub: string | undefined, args: string[]): Promise<string> {\n switch (sub) {\n case \"list\":\n return cmdModuleList(args);\n case \"search\":\n return cmdModuleSearch(args);\n case \"submit\": {\n const { runRegistrySubmitCommand } = await import(\"@sfmc-bds/devkit\");\n return runRegistrySubmitCommand(args);\n }\n case \"install\":\n return cmdModuleInstall(args);\n case \"uninstall\":\n case \"remove\":\n return cmdModuleUninstall(args);\n case \"verify\":\n return cmdModuleVerify(args);\n case \"info\":\n return cmdModuleInfo(args);\n case \"enable\":\n return (await cmdModuleEnable(args)).message;\n case \"disable\":\n return (await cmdModuleDisable(args)).message;\n case \"build\": {\n const { cmdModuleBuild } = await import(\"./module-pack-build.js\");\n return cmdModuleBuild(args);\n }\n case \"reload\": {\n const { cmdModuleReload } = await import(\"./module-pack-build.js\");\n return cmdModuleReload(args);\n }\n case \"update\": {\n const { cmdModuleUpdate } = await import(\"./module-update/index.js\");\n return cmdModuleUpdate(args);\n }\n case \"pin\": {\n const { cmdModulePin } = await import(\"./module-update/index.js\");\n return cmdModulePin(args);\n }\n case \"test\":\n case \"watch\":\n case \"publish\":\n return c.yellow(\n `[mod ${sub}] \u5DF2\u79FB\u81F3\u6269\u5C55\u300CSFMC Module\u300D\u5168\u5468\u671F\uFF08Create/Test/Link/Watch/Publish\uFF09\uFF1B\u5EFA\u4ED3\u8BF7\u7528 pnpm dlx @sfmc-bds/create-module@latest\uFF1B\u8FD0\u7EF4\u8BF7\u7528 mod build|reload|install\u3002`\n );\n default:\n return c.yellow(moduleUsage());\n }\n}\n\n/** \u540C\u6B65\u679A\u4E3E\u5DF2\u5B89\u88C5\u6A21\u5757 id,\u4F9B REPL Tab \u8865\u5168(\u4E0D\u8BFB fingerprint,\u5C3D\u91CF\u8F7B\u91CF)\u3002 */\nexport function listInstalledModuleIdsSync(): string[] {\n const dir = modulesDir();\n if (!existsSync(dir)) return [];\n try {\n return readdirSync(dir, { withFileTypes: true })\n .filter((e) => {\n try {\n return statSync(path.join(dir, e.name)).isDirectory();\n } catch {\n return false;\n }\n })\n .map((e) => e.name)\n .sort((a, b) => a.localeCompare(b));\n } catch {\n return [];\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["lines", "all"]
|
|
7
7
|
}
|
package/dist/services.js
CHANGED
|
@@ -399,7 +399,7 @@ class Service {
|
|
|
399
399
|
}
|
|
400
400
|
}
|
|
401
401
|
function createServices() {
|
|
402
|
-
ensureCoreConfigs(ROOT, ["bds_updater", "qq_config", "db_config"]);
|
|
402
|
+
ensureCoreConfigs(ROOT, ["bds_updater", "qq_config", "db_config", "qq_link"]);
|
|
403
403
|
ensurePackUpdateConfigFile();
|
|
404
404
|
void import("./module-update/index.js").then((mod) => mod.ensureModuleUpdateConfigFile()).catch((error) => {
|
|
405
405
|
const message = error instanceof Error ? error.message : String(error);
|
package/dist/services.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/services.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * services.ts \u2014 CLI \u8FDB\u7A0B\u7F16\u6392\u4E0E\u670D\u52A1\u751F\u547D\u5468\u671F\u7BA1\u7406\n *\n * \u6838\u5FC3\u7BA1\u7406\u5BF9\u8C61\uFF08ServiceName\uFF09\uFF1A\n * - `bds`\uFF1AMinecraft \u57FA\u5CA9\u7248\u670D\u52A1\u7AEF\uFF08\u652F\u6301 stdin \u7BA1\u9053\u6307\u4EE4\u4EA4\u4E92\u4E0E\u4F18\u96C5\u505C\u670D\uFF09\n * - `db`\uFF1Adb-server SQLite HTTP \u670D\u52A1\uFF08\u7AEF\u53E3\u5065\u5EB7\u68C0\u67E5\u4E0E loopback \u63A2\u6D3B\uFF09\n * - `tunnel`\uFF1A\u4E91\u7AEF QQ Webhook \u5230\u672C\u673A db-server \u7684 SSH \u53CD\u5411\u96A7\u9053\n * - `qq`\uFF1Aqq-bridge \u6D88\u606F\u7F51\u6865\u670D\u52A1\uFF08\u652F\u6301\u5B98\u65B9 Bot \u4E0E LLBot \u53CC\u540E\u7AEF\uFF09\n * - `llbot`\uFF1ALLBot \u72EC\u7ACB\u673A\u5668\u4EBA\u8FDB\u7A0B\uFF08\u6761\u4EF6\u542F\u52A8\uFF09\n *\n * \u6838\u5FC3\u80FD\u529B\uFF1A\n * - \u8FDB\u7A0B\u751F\u547D\u5468\u671F\uFF1A\u6309\u4F9D\u8D56\u6B21\u5E8F\u7F16\u6392\u670D\u52A1\u542F\u52A8\uFF08db \u2192 qq \u2192 bds\uFF09\u3001\u4F18\u96C5\u505C\u6B62\u4E0E\u5F02\u5E38\u81EA\u52A8\u62C9\u8D77\n * - \u591A\u6E90\u63A2\u6D3B\u611F\u77E5\uFF1A\u81EA\u52A8\u63A2\u6D4B\u6258\u7BA1\u8FDB\u7A0B\u4E0E\u5916\u90E8\u72EC\u7ACB\u8FDB\u7A0B\u72B6\u6001\n * - \u65E5\u5FD7\u6D41\u7EDF\u4E00\u805A\u5408\uFF1A\u6355\u83B7\u5E76\u5F52\u4E00\u5316\u5404\u670D\u52A1\u7684 stdout / stderr \u6570\u636E\u6D41\n */\n\nimport type { BdsUpdaterConfig, DBConfig, QQBackend, QQBridgeConfig } from \"@sfmc-bds/sdk/node/config\";\nimport {\n DEFAULT_BDS_UPDATER_CONFIG,\n DEFAULT_DB_CONFIG,\n DEFAULT_QQ_CONFIG,\n ensureCoreConfigs,\n loadEnsuredConfig,\n qqRuntimeStatusPath,\n readJson,\n type QqRuntimeStatus,\n} from \"@sfmc-bds/sdk/node/config\";\n\nimport { bdsExePath, bdsSpawnEnvExtra, ensureBdsExecutable } from \"@sfmc-bds/bds-tools/host-platform\";\nimport {\n clearBdsPidFile,\n findBedrockServerPids,\n isProcessAlive,\n killBedrockServerByImage,\n probeBdsStatus,\n readBdsPidFile,\n writeBdsPidFile,\n} from \"@sfmc-bds/bds-tools/process-probe\";\nimport { postBdsLifecycleEvent } from \"@sfmc-bds/bds-tools/qq-events-notify\";\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { EventEmitter } from \"node:events\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { isDaemonServer } from \"./daemon/role.js\";\nimport { onRemoteServiceStateChange } from \"./daemon/client.js\";\nimport { t } from \"./i18n/index.js\";\nimport { resolveLlbotLaunch } from \"./llbot-launch.js\";\nimport { inferLevel, pushLog as pushUnifiedLog } from \"./logs.js\";\nimport { findNodeServicePids, killNodeServiceByScript } from \"./node-service-probe.js\";\nimport { ensurePackUpdateConfigFile } from \"./pack-update/index.js\";\nimport { recordBdsVersion } from \"./bds-runtime-version.js\";\nimport { reportBdsPlayerSession } from \"./player-session.js\";\nimport { startModuleSidecars, stopModuleSidecars } from \"./module-sidecars.js\";\nimport { ROOT, spawnService, type ServiceId } from \"./runtime.js\";\n\nexport { ROOT } from \"./runtime.js\";\n\nexport interface LogLine {\n time: Date;\n text: string;\n stream: \"stdout\" | \"stderr\";\n}\n\n/** \u5B50\u8FDB\u7A0B\u8F93\u51FA\u5206\u884C\uFF1A\u8FC7\u6EE4\u7A7A\u4E32\u4EE5\u53CA Windows CRLF \u62C6\u5206\u540E\u6B8B\u7559\u7684\u7EAF\u7A7A\u767D\u884C\u3002 */\nexport function nonBlankOutputLines(text: string): string[] {\n return text.split(/\\r?\\n/).filter((line) => line.trim().length > 0);\n}\n\nexport type ServiceName = \"bds\" | \"db\" | \"tunnel\" | \"qq\" | \"llbot\";\nexport const SERVICE_NAMES: ServiceName[] = [\"bds\", \"db\", \"tunnel\", \"qq\", \"llbot\"];\n\n/** \u5355\u670D\u52A1 start \u7ED3\u679C\uFF1Aoptional \u670D\u52A1 validate \u5931\u8D25\u8BB0\u4E3A skipped\uFF0C\u4E0D\u629B\u9519 */\nexport type StartOutcome = { status: \"started\" } | { status: \"already\" } | { status: \"skipped\"; reason: string };\n\n/**\n * \u5355\u670D\u52A1 stop \u7ED3\u679C\uFF0C\u4F9B CLI \u533A\u5206\u6587\u6848\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A`stop <name>` / `restart <name>` \u4E0E `stop all` \u90FD\u8D70 Service.stop\uFF0C\u4F46\u53EA\u6709\u524D\u8005\u4F1A\u5F97\u5230 external\u3002\n * - managed\uFF1A\u505C\u7684\u662F\u672C\u8FDB\u7A0B\u62C9\u8D77\u7684\u5B50\u8FDB\u7A0B\n * - external\uFF1A\u6CA1\u6709\u6258\u7BA1\u53E5\u67C4\uFF0C\u4F46\u6E05\u6389\u4E86\u5916\u90E8\u5B9E\u4F8B\uFF08\u4EC5 external=true \u65F6\uFF09\n * - idle\uFF1A\u672C\u6765\u5C31\u6CA1\u5728\u8DD1\uFF0C\u6216\u6279\u91CF\u505C\u6B62\u65F6\u6545\u610F\u4E0D\u52A8\u5916\u90E8\u5B9E\u4F8B\n */\nexport type StopKind = \"managed\" | \"external\" | \"idle\";\n\nexport interface StartAllResult {\n started: ServiceName[];\n skipped: Array<{ name: ServiceName; reason: string }>;\n failed: Array<{ name: ServiceName; reason: string }>;\n}\n\nexport interface ServiceStatus {\n name: ServiceName;\n title: string;\n running: boolean;\n pid: number;\n uptime: string;\n ownership?: \"managed\" | \"external\";\n}\n\n/** \u5F53\u524D db \u5065\u5EB7\u63A2\u6D4B\u7AEF\u53E3\uFF08\u4E0E createServices \u540C\u6B65\uFF09 */\nlet dbHealthPort = 3001;\n/** \u5F53\u524D QQ \u540E\u7AEF\uFF08\u4E0E createServices \u540C\u6B65\uFF0C\u4F9B Tab/\u7A97\u6807\u9898\uFF09 */\nlet qqBackendMode: QQBackend = \"official\";\n\nexport function getQqBackendMode(): QQBackend {\n return qqBackendMode;\n}\n\nasync function probeDbHealth(port: number): Promise<boolean> {\n try {\n const res = await fetch(`http://127.0.0.1:${port}/api/health`, { signal: AbortSignal.timeout(2000) });\n return res.ok;\n } catch {\n return false;\n }\n}\n\n/** \u8BFB `.sfmc/qq.runtime.json` + pid \u5B58\u6D3B\uFF0C\u63A2\u6D4B\u5916\u90E8/\u672C\u673A qq-bridge */\nasync function probeQqRuntime(): Promise<{ alive: boolean; pid: number }> {\n const status = readJson<QqRuntimeStatus>(qqRuntimeStatusPath(ROOT));\n if (!status?.pid || status.pid <= 0) return { alive: false, pid: 0 };\n if (!(await isProcessAlive(status.pid))) return { alive: false, pid: 0 };\n return { alive: true, pid: status.pid };\n}\n\nconst tunnelRuntimePath = path.join(ROOT, \".sfmc\", \"tunnel.runtime.json\");\n\nasync function probeTunnelRuntime(): Promise<number> {\n const pid = readJson<{ pid?: number }>(tunnelRuntimePath)?.pid;\n return typeof pid === \"number\" && pid > 0 && (await isProcessAlive(pid)) ? pid : 0;\n}\n\nfunction writeTunnelRuntime(pid: number): void {\n fs.mkdirSync(path.dirname(tunnelRuntimePath), { recursive: true });\n fs.writeFileSync(tunnelRuntimePath, JSON.stringify({ pid, startedAt: Date.now() }) + \"\\n\");\n}\n\nfunction clearTunnelRuntime(pid: number): void {\n if (readJson<{ pid?: number }>(tunnelRuntimePath)?.pid !== pid) return;\n try {\n fs.unlinkSync(tunnelRuntimePath);\n } catch {\n /* \u8FDB\u7A0B\u9000\u51FA\u65F6\u5141\u8BB8\u6587\u4EF6\u5DF2\u88AB\u79FB\u9664 */\n }\n}\n\n/** \u6E05\u6389 qq-bridge \u8FD0\u884C\u65F6\u6587\u4EF6\uFF0C\u907F\u514D status \u4ECD\u628A\u5DF2\u9000\u51FA\u7684\u5916\u90E8\u8FDB\u7A0B\u5F53\u6210\u5B58\u6D3B\u3002 */\nfunction clearQqRuntimeFile(): void {\n try {\n const file = qqRuntimeStatusPath(ROOT);\n if (fs.existsSync(file)) fs.unlinkSync(file);\n } catch {\n /* \u8FD0\u884C\u65F6\u6587\u4EF6\u53EF\u80FD\u5DF2\u88AB\u8FDB\u7A0B\u81EA\u5DF1\u5220\u6389 */\n }\n}\n\n/**\n * \u6309\u955C\u50CF\u540D\u7ED3\u675F\u5916\u90E8 BDS\uFF0C\u5E76\u7B49\u5230\u8FDB\u7A0B\u4ECE\u8FDB\u7A0B\u8868\u6D88\u5931\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A\u4EC5\u5355\u670D\u52A1 stop / restart\uFF08Service.stop \u7684 external=true\uFF09\u6E05\u6389\u975E\u672C\u8FDB\u7A0B\u62C9\u8D77\u7684 bedrock\u3002\n * stop all \u4E0E\u5B88\u62A4\u8FDB\u7A0B shutdown \u4E0D\u8C03\u7528\u8FD9\u91CC\uFF0C\u907F\u514D taskkill \u8BEF\u6740\u540C\u673A\u5176\u4ED6 Bedrock\u3002\n * taskkill \u8FD4\u56DE\u540E\u8FDB\u7A0B\u8868\u53EF\u80FD\u4ECD\u77ED\u6682\u53EF\u89C1\uFF0Crestart \u4F1A\u7ACB\u523B\u63A2\u6D3B\uFF0C\u56E0\u6B64\u8FD9\u91CC\u7B49\u5230\u6D88\u5931\u518D\u8FD4\u56DE\u3002\n */\nasync function killExternalBedrock(): Promise<void> {\n await killBedrockServerByImage();\n clearBdsPidFile(ROOT);\n const deadline = Date.now() + 8000;\n while (Date.now() < deadline) {\n if ((await findBedrockServerPids()).length === 0) return;\n await new Promise((r) => setTimeout(r, 200));\n }\n await killBedrockServerByImage();\n clearBdsPidFile(ROOT);\n}\n\ninterface ServiceDef {\n name: ServiceName;\n title: string;\n service?: ServiceId;\n cmd?: string;\n args?: string[];\n cwd: string;\n env?: Record<string, string>;\n stopCommand?: string;\n stopTimeout: number;\n autoRestart: boolean;\n restartDelay: number;\n /**\n * \u53EF\u9009\u670D\u52A1\uFF1Avalidate \u5931\u8D25\u65F6 start \u8FD4\u56DE skipped\uFF08startAll \u4E0D\u5F53\u4F5C\u5931\u8D25\uFF09\u3002\n * \u7528\u4E8E official \u4E0B\u8DF3\u8FC7 llbot\u3001\u4EE5\u53CA qq_enabled=false\u3002\n */\n optional?: boolean;\n validate?: () => string | null;\n /** \u542F\u52A8\u524D\u94A9\u5B50(\u5982 BDS \u88C5\u8F7D\u4E00\u81F4\u6027\u6821\u9A8C);\u5931\u8D25\u5219\u7981\u6B62 spawn */\n beforeStart?: () => Promise<void>;\n /** \u539F\u59CB\u65E5\u5FD7\u884C\u89C2\u5BDF\u5668\uFF0C\u4E0D\u5F97\u963B\u585E\u5B50\u8FDB\u7A0B\u8F93\u51FA\u3002 */\n onLogLine?: (line: string) => void;\n}\n\nclass Service {\n name: ServiceName;\n title: string;\n proc: ChildProcess | null = null;\n running = false;\n pid = 0;\n startTime: Date | null = null;\n logs: LogLine[] = [];\n events = new EventEmitter();\n\n private def: ServiceDef;\n private manualStop = false;\n private updateInProgress = false;\n private restartTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(def: ServiceDef) {\n this.name = def.name;\n this.title = def.title;\n this.def = def;\n if (def.name === \"tunnel\") {\n this.events.on(\"output\", (text: string, level: \"info\" | \"error\") => {\n pushUnifiedLog(text, \"tunnel\", level);\n });\n }\n }\n\n get uptime(): string {\n if (!this.startTime || !this.running) return \"\u2014\";\n const ms = Date.now() - this.startTime.getTime();\n const m = Math.floor(ms / 60000);\n const h = Math.floor(m / 60);\n if (h > 0) return `${h}h ${m % 60}m`;\n if (m > 0) return `${m}m`;\n return `${Math.floor(ms / 1000)}s`;\n }\n\n pushLog(text: string, stream: \"stdout\" | \"stderr\"): void {\n const line: LogLine = { time: new Date(), text, stream };\n this.logs.push(line);\n if (this.logs.length > 2000) this.logs.splice(0, this.logs.length - 2000);\n this.events.emit(\"log\", line);\n // stderr \u89C6\u4E3A error; stdout \u7528 inferLevel \u63A8\u65AD (bare \u5B50\u8FDB\u7A0B\u7EAF text \u65F6\u9ED8\u8BA4 info,\n // BDS \u7B49\u81EA\u5E26 [LEVEL] \u6807\u7B7E\u7684\u4ECD\u53EF\u6B63\u786E\u63A8\u65AD)\n const level = stream === \"stderr\" ? \"error\" : inferLevel(text);\n pushUnifiedLog(text, this.name, level);\n this.def.onLogLine?.(text);\n }\n\n async start(): Promise<StartOutcome> {\n if (this.updateInProgress) throw new Error(\"BDS \u6B63\u5728\u66F4\u65B0\uFF0C\u6682\u4E0D\u53EF\u542F\u52A8\");\n if (this.running) return { status: \"already\" };\n if (this.name === \"bds\") {\n const probe = await probeBdsStatus({ rootDir: ROOT });\n if (probe.state !== \"stopped\") {\n throw new Error(\n t(\"svc.bdsAlreadyRunning\", {\n pid: String(probe.pid),\n kind: t(probe.state === \"managed\" ? \"svc.running\" : \"svc.runningExternal\"),\n })\n );\n }\n }\n if (this.name === \"db\" || this.name === \"qq\") {\n const external = await findNodeServicePids(this.name);\n if (external.length > 0) {\n return { status: \"already\" };\n }\n }\n if (this.name === \"tunnel\" && (await probeTunnelRuntime())) return { status: \"already\" };\n if (this.def.validate) {\n const v = this.def.validate();\n if (v) {\n // optional\uFF1A\u914D\u7F6E\u5C42\u9762\u8DF3\u8FC7\uFF08\u5982 official \u4E0B llbot\uFF09\uFF0C\u4E0D\u5F53\u5931\u8D25\u3001\u4E5F\u4E0D spawn\n if (this.def.optional) return { status: \"skipped\", reason: v };\n throw new Error(v);\n }\n }\n if (this.def.beforeStart) {\n await this.def.beforeStart();\n }\n if (this.name === \"bds\") {\n await startModuleSidecars(ROOT, (line, stream) => this.pushLog(line, stream));\n }\n // beforeStart \u542B\u5F02\u6B65\u68C0\u67E5\uFF1B\u66F4\u65B0\u53EF\u80FD\u5728\u7B49\u5F85\u671F\u95F4\u5F00\u59CB\u3002\n if (this.updateInProgress) throw new Error(\"BDS \u6B63\u5728\u66F4\u65B0\uFF0C\u6682\u4E0D\u53EF\u542F\u52A8\");\n this.manualStop = false;\n /* \u5B50\u8FDB\u7A0B\u59CB\u7EC8\u7531\u5B88\u62A4\u8FDB\u7A0B\u7528\u7BA1\u9053\u6301\u6709\uFF08stdin \u53D1 stop\u3001stdout \u65E5\u5FD7\u3001autoRestart\uFF09\uFF1B\n * \u4E0D\u518D\u5BF9\u5B50\u670D\u52A1\u505A detached/unref\u2014\u2014\u8131\u79BB\u7EC8\u7AEF\u7531 daemon \u8FDB\u7A0B\u81EA\u8EAB\u8D1F\u8D23\u3002\n * windowsHide\uFF1AWindows \u4E0A\u907F\u514D\u4E3A\u6BCF\u4E2A\u670D\u52A1\u5F39\u51FA\u7A7A\u767D\u63A7\u5236\u53F0\uFF08stdout \u5DF2 pipe\uFF0C\u7A97\u5185\u65E0\u8F93\u51FA\uFF09\u3002 */\n const spawnOpts = {\n cwd: this.def.cwd,\n stdio: [\"pipe\", \"pipe\", \"pipe\"] as Array<\"pipe\">,\n env: this.def.env ? { ...process.env, ...this.def.env } : process.env,\n windowsHide: true,\n };\n const child = this.def.service\n ? spawnService(this.def.service, this.def.args ?? [], spawnOpts)\n : spawn(this.def.cmd as string, this.def.args ?? [], spawnOpts);\n this.proc = child;\n this.pid = child.pid ?? 0;\n this.running = true;\n this.startTime = new Date();\n if (this.name === \"bds\" && this.pid > 0) {\n writeBdsPidFile(this.pid, ROOT);\n }\n if (this.name === \"tunnel\" && this.pid > 0) writeTunnelRuntime(this.pid);\n this.events.emit(\"output\", `started (PID ${this.pid})`, \"info\");\n this.events.emit(\"state\", { name: this.name, running: true, pid: this.pid });\n\n let lifecycleReported = false;\n const reportExit = (code?: number | null) => {\n if (this.name !== \"bds\" || lifecycleReported) return;\n lifecycleReported = true;\n const planned = this.manualStop || this.updateInProgress;\n void postBdsLifecycleEvent(planned ? \"stop\" : \"crash\", planned ? undefined : `code=${code ?? \"?\"}`, {\n port: dbHealthPort,\n });\n };\n if (this.name === \"bds\") {\n child.once(\"spawn\", () => {\n void postBdsLifecycleEvent(\"start\", undefined, { port: dbHealthPort });\n });\n }\n\n child.on(\"error\", (e) => {\n this.events.emit(\"output\", `process error: ${e.message}`, \"error\");\n reportExit();\n this.cleanup();\n this.scheduleRestart();\n });\n\n let versionLineBuffer = \"\";\n child.stdout?.on(\"data\", (d: Buffer) => {\n if (this.name === \"bds\" && this.startTime) {\n versionLineBuffer += d.toString();\n const versionLines = versionLineBuffer.split(/\\r?\\n/);\n versionLineBuffer = (versionLines.pop() ?? \"\").slice(-4096);\n for (const versionLine of versionLines) recordBdsVersion(ROOT, versionLine, this.pid, this.startTime.getTime());\n }\n for (const line of nonBlankOutputLines(d.toString())) {\n this.pushLog(line, \"stdout\");\n }\n });\n child.stderr?.on(\"data\", (d: Buffer) => {\n for (const line of nonBlankOutputLines(d.toString())) {\n this.pushLog(line, \"stderr\");\n }\n });\n\n child.on(\"exit\", (code) => {\n if (this.proc && this.proc !== child) return;\n this.events.emit(\"output\", `exited (code: ${code})`, \"info\");\n reportExit(code);\n this.cleanup();\n this.scheduleRestart();\n });\n return { status: \"started\" };\n }\n\n private scheduleRestart(): void {\n if (this.manualStop || this.updateInProgress || !this.def.autoRestart || this.restartTimer) return;\n this.restartTimer = setTimeout(() => {\n this.restartTimer = null;\n if (!this.updateInProgress && !this.manualStop && !this.running) {\n void this.start().catch((e: Error) => {\n this.events.emit(\"output\", `restart failed: ${e.message}`, \"error\");\n });\n }\n }, this.def.restartDelay);\n }\n\n /** \u66F4\u65B0\u5668\u72EC\u7ACB\u8FDB\u7A0B\u505C\u670D\u65F6\uFF0C\u7981\u6B62\u5C06\u8BA1\u5212\u5185\u9000\u51FA\u5F53\u4F5C\u5D29\u6E83\u5E76\u81EA\u52A8\u62C9\u8D77\u3002 */\n beginUpdate(): void {\n if (this.name !== \"bds\") return;\n if (this.updateInProgress) throw new Error(\"BDS \u66F4\u65B0\u5DF2\u5728\u8FDB\u884C\u4E2D\");\n this.updateInProgress = true;\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n }\n\n endUpdate(): void {\n this.updateInProgress = false;\n }\n\n /**\n * \u505C\u6B62\u672C\u670D\u52A1\u3002\u6258\u7BA1\u5B50\u8FDB\u7A0B\u59CB\u7EC8\u8D70\u539F\u6765\u7684\u4F18\u96C5\u505C\u6B62\uFF08stdin stop / SIGTERM\uFF09\u3002\n * @param external \u662F\u5426\u989D\u5916\u6E05\u6389\u975E\u672C\u8FDB\u7A0B\u62C9\u8D77\u7684\u5916\u90E8\u5B9E\u4F8B\u3002\u9ED8\u8BA4 false\uFF0C\u53EA\u505C\u6258\u7BA1\u5B50\u8FDB\u7A0B\u3002\n * \u4E24\u79CD\u8C03\u7528\u573A\u666F\uFF1A\n * - true\uFF1A\u5355\u670D\u52A1 `stop <name>` / `restart <name>`\uFF08cmdStopLocal\uFF0C\u4EE5\u53CA\u4ECD\u5B58\u5728\u7684 Service.restart\uFF09\u3002\n * BDS \u5916\u90E8\u8D70 killExternalBedrock\uFF1Bdb/qq \u5916\u90E8\u8D70 killNodeServiceByScript\u3002\n * - false \u6216\u4E0D\u4F20\uFF1A`stop all`\u3001`restart -all`\u3001\u5B88\u62A4\u8FDB\u7A0B shutdown / SIGTERM\uFF08\u7ECF stopAll\uFF09\u3002\n * \u4E0D\u6309\u955C\u50CF\u540D\u6216\u811A\u672C\u540D\u6740\u5916\u90E8\u8FDB\u7A0B\uFF0C\u907F\u514D\u8BEF\u6740\u540C\u673A\u5176\u4ED6 Bedrock\u3001db\u3001qq\u3002\n */\n async stop(external = false, forceOnTimeout = true): Promise<StopKind> {\n this.manualStop = true;\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n\n /* \u4E0E\u539F\u5148 cmdStop \u4E00\u81F4\uFF1A\u4EC5\u5355\u670D\u52A1\u505C\u6B62\u65F6\uFF0CBDS \u88AB\u5224\u5B9A\u4E3A\u5916\u90E8\u624D\u6309\u955C\u50CF\u7ED3\u675F\uFF0C\u4E0D\u8D70 stdin stop */\n if (external && this.name === \"bds\") {\n const probe = await probeBdsStatus({\n managedPid: this.pid,\n hasStdin: Boolean(this.proc?.stdin),\n rootDir: ROOT,\n });\n if (probe.state === \"external\") {\n await killExternalBedrock();\n this.dropStaleHandle();\n return \"external\";\n }\n }\n\n const managed = Boolean(this.proc && this.running);\n if (managed) await this.stopManagedChild(forceOnTimeout);\n\n /* db / qq\uFF1A\u4EC5\u5355\u670D\u52A1\u505C\u6B62\u65F6\uFF0C\u6258\u7BA1\u505C\u5B8C\u540E\u4ECD\u6309\u811A\u672C\u518D\u626B\u4E00\u904D\uFF0C\u6E05\u6389\u540C\u673A\u4E0A\u7684\u5916\u90E8\u5B9E\u4F8B */\n if (external && (this.name === \"db\" || this.name === \"qq\")) {\n const killed = await killNodeServiceByScript(this.name);\n if (this.name === \"qq\") clearQqRuntimeFile();\n if (managed) return \"managed\";\n return killed.length > 0 ? \"external\" : \"idle\";\n }\n\n if (managed) return \"managed\";\n return \"idle\";\n }\n\n /**\n * \u4F18\u96C5\u505C\u6B62\u5F53\u524D\u6258\u7BA1\u5B50\u8FDB\u7A0B\uFF08stdin stop \u6216 SIGTERM\uFF0C\u8D85\u65F6\u540E SIGKILL\uFF09\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1AService.stop \u786E\u8BA4\u672C\u8FDB\u7A0B\u4ECD\u6301\u6709\u5B50\u8FDB\u7A0B\u65F6\u8C03\u7528\uFF1B\u903B\u8F91\u4E0E\u539F\u5148 stop \u4E3B\u4F53\u76F8\u540C\u3002\n */\n private async stopManagedChild(forceOnTimeout = true): Promise<void> {\n if (!this.proc || !this.running) return;\n this.events.emit(\"output\", \"stopping...\", \"info\");\n\n if (this.def.stopCommand && this.proc.stdin) {\n this.proc.stdin.write(this.def.stopCommand + \"\\n\");\n } else {\n this.proc.kill(\"SIGTERM\");\n }\n\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n if (!forceOnTimeout && this.proc) {\n reject(new Error(`${this.name} \u672A\u5728\u8D85\u65F6\u5185\u4F18\u96C5\u9000\u51FA\uFF1B\u5DF2\u4E2D\u6B62\u7EF4\u62A4\uFF0C\u4E0D\u5F3A\u5236\u7ED3\u675F\u8FDB\u7A0B`));\n return;\n }\n if (this.proc) {\n this.events.emit(\"output\", \"force kill\", \"error\");\n try {\n this.proc.kill(\"SIGKILL\");\n } catch {\n /* ignore */\n }\n }\n resolve();\n }, this.def.stopTimeout);\n\n this.proc?.on(\"exit\", () => {\n clearTimeout(timeout);\n resolve();\n });\n });\n }\n\n /**\n * \u5916\u90E8\u505C\u670D\u540E\u4E22\u6389\u5931\u6548\u7684\u6258\u7BA1\u53E5\u67C4\uFF0C\u907F\u514D\u7D27\u63A5\u7740\u7684 start/restart \u8BEF\u5224\u300C\u5DF2\u5728\u8FD0\u884C\u300D\u3002\n * \u4E0D\u8D70 cleanup\uFF1A\u90A3\u4F1A\u8FDE\u5E26\u505C\u6389\u6A21\u5757\u9644\u5C5E\u8FDB\u7A0B\uFF0C\u800C\u539F\u5148\u7684\u5916\u90E8 BDS stop \u5E76\u4E0D\u8FD9\u4E48\u505A\u3002\n */\n private dropStaleHandle(): void {\n if (!this.running && !this.proc) return;\n const stale = this.proc;\n this.proc = null;\n this.running = false;\n this.pid = 0;\n this.startTime = null;\n this.events.emit(\"state\", { name: this.name, running: false, pid: 0 });\n if (stale && stale.exitCode === null) {\n try {\n stale.kill(\"SIGKILL\");\n } catch {\n /* \u5916\u90E8\u955C\u50CF\u7ED3\u675F\u65F6\u8FD9\u4E2A\u53E5\u67C4\u53EF\u80FD\u5DF2\u7ECF\u9000\u51FA */\n }\n }\n }\n\n forceStop(): void {\n const child = this.proc;\n this.manualStop = true;\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n this.cleanup();\n if (!child) return;\n try {\n child.kill(\"SIGKILL\");\n } catch {\n /* ignore */\n }\n }\n\n /**\n * \u5355\u670D\u52A1\u91CD\u542F\uFF1A\u5148\u505C\u518D\u8D77\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A\u82E5\u4ECD\u6709\u8C03\u7528\u65B9\u76F4\u63A5\u8D70 Service.restart\uFF08\u4E0D\u7ECF cmdStopLocal\uFF09\uFF0C\u4E0E\u5355\u670D\u52A1 stop \u4E00\u6837\u6E05\u5916\u90E8\u5B9E\u4F8B\uFF08external true\uFF09\u3002\n * \u6279\u91CF `restart -all` \u548C\u5B88\u62A4\u8FDB\u7A0B shutdown \u4E0D\u8D70\u8FD9\u91CC\uFF0C\u5B83\u4EEC\u7ECF stopAll \u8C03\u7528 stop(false)\uFF0C\u53EA\u505C\u6258\u7BA1\u5B50\u8FDB\u7A0B\u3002\n */\n async restart(): Promise<StartOutcome> {\n await this.stop(true);\n return this.start();\n }\n\n getRecentLogs(n: number): LogLine[] {\n return this.logs.slice(-n);\n }\n\n /**\n * \u63A2\u6D4B\u53D1\u73B0\u8FDB\u7A0B\u5DF2\u6B7B\u540E\u56DE\u5199\u672C\u5730\u72B6\u6001\uFF08\u4E0D\u8BBE manualStop\uFF0C\u4EE5\u4FBF exit \u56DE\u8C03\u4ECD\u53EF\u6309\u9700 autoRestart\uFF09\u3002\n */\n markStoppedFromProbe(): void {\n if (!this.running && !this.proc) return;\n this.cleanup();\n }\n\n private cleanup(): void {\n const wasRunning = this.running || this.proc !== null;\n const exitingPid = this.pid;\n this.proc = null;\n this.running = false;\n this.pid = 0;\n this.startTime = null;\n if (this.name === \"bds\" && exitingPid > 0) {\n const filePid = readBdsPidFile(ROOT);\n if (filePid === exitingPid) {\n clearBdsPidFile(ROOT);\n }\n stopModuleSidecars();\n }\n if (this.name === \"tunnel\" && exitingPid > 0) clearTunnelRuntime(exitingPid);\n if (wasRunning) {\n this.events.emit(\"state\", { name: this.name, running: false, pid: 0 });\n }\n }\n}\n\nfunction createServices(): Record<ServiceName, Service> {\n /* \u5404\u670D\u52A1/CLI \u7528 SDK ensureCoreConfigs \u64AD\u79CD\uFF08\u542B $schema\uFF09\uFF0C\u4E0D\u518D\u4ECE configs-default \u62F7\u8D1D\u3002 */\n ensureCoreConfigs(ROOT, [\"bds_updater\", \"qq_config\", \"db_config\"]);\n ensurePackUpdateConfigFile();\n void import(\"./module-update/index.js\")\n .then((mod) => mod.ensureModuleUpdateConfigFile())\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n pushUnifiedLog(message, \"module\", \"warn\");\n });\n const bdsCfg = loadEnsuredConfig(ROOT, \"bds_updater.json\", \"bds_updater\", { ...DEFAULT_BDS_UPDATER_CONFIG } as Record<\n string,\n unknown\n >) as BdsUpdaterConfig;\n const qqCfg = loadEnsuredConfig(ROOT, \"qq_config.json\", \"qq_config\", { ...DEFAULT_QQ_CONFIG } as Record<\n string,\n unknown\n >) as QQBridgeConfig;\n const dbCfg = loadEnsuredConfig(ROOT, \"db_config.json\", \"db_config\", { ...DEFAULT_DB_CONFIG } as Record<\n string,\n unknown\n >) as DBConfig;\n const rawBdsPath = String(bdsCfg.bds_path ?? \"\").trim();\n if (process.platform !== \"win32\" && /^[A-Za-z]:[\\\\/]/.test(rawBdsPath)) {\n throw new Error(\n `configs/bds_updater.json \u7684 bds_path \u662F Windows \u8DEF\u5F84\uFF08${rawBdsPath}\uFF09\u3002` +\n `\u8BF7\u6539\u6210\u76F8\u5BF9 SFMC_ROOT \u7684\u8DEF\u5F84\uFF0C\u4F8B\u5982 \"BDS\"\u3002`\n );\n }\n const bdsPath = path.resolve(ROOT, rawBdsPath || \".\");\n const useLlbotBackend = qqCfg.qq_backend === \"llbot\";\n const qqEnabled = qqCfg.qq_enabled !== false;\n // \u5B98\u65B9 Webhook \u7531\u4E91\u7AEF\u63A5\u6536\uFF1B\u4EC5\u5207\u6362\u4F20\u8F93\u65B9\u5F0F\u5373\u53EF\u907F\u514D\u672C\u673A\u518D\u542F\u52A8\u4E00\u4E2A\u6865\u3002\n const qqExternal = !useLlbotBackend && qqCfg.official?.transport === \"webhook\";\n const tunnelCfg = qqCfg.official?.tunnel;\n const tunnelEnabled = qqEnabled && qqExternal && tunnelCfg?.enabled === true;\n const tunnelHost = String(tunnelCfg?.host ?? \"\").trim();\n const tunnelRemotePort = tunnelCfg?.remotePort ?? 13001;\n const llbotEnabled = qqCfg.llbot?.enabled !== false;\n const llbotLaunch = resolveLlbotLaunch(qqCfg.llbot?.path, qqCfg.llbot?.cwd);\n const llbotPath = llbotLaunch.exe;\n const llbotCwd = llbotLaunch.cwd;\n const dbPort = dbCfg.db_port ?? 3001;\n dbHealthPort = dbPort;\n qqBackendMode = useLlbotBackend ? \"llbot\" : \"official\";\n const bdsExe = bdsExePath(bdsPath);\n const qqTitle = useLlbotBackend ? \"QQ (llbot)\" : \"QQ (official)\";\n\n return {\n bds: new Service({\n name: \"bds\",\n title: \"BDS\",\n cmd: bdsExe,\n args: [],\n cwd: bdsPath,\n env: bdsSpawnEnvExtra(bdsPath),\n stopCommand: \"stop\",\n stopTimeout: 30000,\n /* \u5D29\u6E83\u62C9\u8D77\u7531 sfmc daemon \u56FA\u5B9A\u5F00\u542F\uFF1B\u4E0D\u518D\u8BFB bds_updater.crash_restart */\n autoRestart: true,\n restartDelay: 5000,\n validate: () => {\n if (!fs.existsSync(bdsExe)) return `not found: ${bdsExe}`;\n return null;\n },\n beforeStart: async () => {\n ensureBdsExecutable(bdsExe);\n /* \u5148\u88C5\u6536\u4EF6\u7BB1\u7B2C\u4E09\u65B9\u5305\uFF0C\u518D\u68C0\u67E5 CF \u66F4\u65B0\uFF0C\u518D\u8DD1\u6A21\u5757\u805A\u5408\u95F8\u95E8 */\n /* \u4E1A\u52A1\u6A21\u5757\u66F4\u65B0\u53EA\u8D70\u663E\u5F0F\u547D\u4EE4\uFF0C\u4E0D\u8FDB\u5F00\u670D\u94A9\u5B50\u3002 */\n const { scanAndInstallInbox } = await import(\"./world-packs.js\");\n await scanAndInstallInbox({ interactive: false });\n const { runPackUpdatesOnBdsStart } = await import(\"./pack-update/index.js\");\n await runPackUpdatesOnBdsStart();\n const { ensurePacksReady } = await import(\"./pack-lifecycle.js\");\n await ensurePacksReady();\n },\n onLogLine: (line) =>\n reportBdsPlayerSession(line, {\n port: dbPort,\n ...(dbCfg.http_auth ? { authToken: dbCfg.http_auth } : {}),\n }),\n }),\n\n db: new Service({\n name: \"db\",\n title: \"DB Server\",\n service: \"db\",\n cwd: ROOT,\n stopTimeout: 10000,\n autoRestart: true,\n restartDelay: 3000,\n env: { DB_PORT: String(dbPort) },\n }),\n\n tunnel: new Service({\n name: \"tunnel\",\n title: \"QQ SSH Tunnel\",\n cmd: \"ssh\",\n args: [\n \"-N\", \"-T\", \"-o\", \"BatchMode=yes\", \"-o\", \"ConnectTimeout=10\",\n \"-o\", \"ExitOnForwardFailure=yes\", \"-o\", \"ServerAliveInterval=30\",\n \"-o\", \"ServerAliveCountMax=3\",\n \"-R\", `127.0.0.1:${tunnelRemotePort}:127.0.0.1:${dbPort}`,\n tunnelHost,\n ],\n cwd: ROOT,\n stopTimeout: 10000,\n autoRestart: true,\n restartDelay: 5000,\n optional: !tunnelEnabled,\n validate: () => {\n if (!tunnelEnabled) return \"QQ tunnel disabled (official webhook tunnel.enabled=false)\";\n if (!/^[A-Za-z0-9_][A-Za-z0-9_.-]*$/.test(tunnelHost)) return \"invalid official.tunnel.host\";\n if (!Number.isInteger(tunnelRemotePort) || tunnelRemotePort < 1 || tunnelRemotePort > 65535) {\n return \"invalid official.tunnel.remotePort\";\n }\n return null;\n },\n }),\n\n qq: new Service({\n name: \"qq\",\n title: qqTitle,\n service: \"qq\",\n cwd: ROOT,\n stopTimeout: 10000,\n // \u7F3A\u51ED\u636E\u65F6 validate \u62E6\u4E0B\uFF0C\u4E0D\u4F1A spawn\u2192exit(1)\u2192autoRestart \u6B7B\u5FAA\u73AF\n autoRestart: true,\n restartDelay: 3000,\n optional: !qqEnabled || qqExternal,\n validate: () => {\n if (!qqEnabled) return \"QQ bridge disabled (qq_enabled=false)\";\n if (qqExternal) return \"QQ bridge runs externally (official.transport=webhook)\";\n if (!useLlbotBackend) {\n if (!String(qqCfg.official?.app_id ?? \"\").trim() || !String(qqCfg.official?.app_secret ?? \"\").trim()) {\n return \"missing official.app_id / official.app_secret\";\n }\n }\n return null;\n },\n }),\n\n llbot: new Service({\n name: \"llbot\",\n title: \"LLBot\",\n cmd: llbotPath,\n args: [],\n cwd: llbotCwd,\n stopTimeout: 10000,\n autoRestart: false,\n restartDelay: 5000,\n // official \u6216\u672A\u542F\u7528\u65F6\u771F\u6B63 skip\uFF0C\u4E0D throw\n optional: !useLlbotBackend || !llbotEnabled,\n validate: () => {\n if (!useLlbotBackend) return \"LLBot skipped (qq_backend!=llbot)\";\n if (!llbotEnabled) return \"LLBot disabled (llbot.enabled=false)\";\n if (!fs.existsSync(llbotPath)) return `not found: ${llbotPath}`;\n return null;\n },\n }),\n };\n}\n\nexport let services: Record<ServiceName, Service> = createServices();\n\nexport function refreshServices(): void {\n forceStopAll();\n services = createServices();\n}\n\nexport const START_ORDER: ServiceName[] = [\"db\", \"tunnel\", \"qq\", \"llbot\", \"bds\"];\n\nexport async function startAll(): Promise<StartAllResult> {\n const result: StartAllResult = { started: [], skipped: [], failed: [] };\n for (const name of START_ORDER) {\n const svc = services[name];\n if (!svc) continue;\n try {\n const outcome = await svc.start();\n if (outcome.status === \"skipped\") {\n result.skipped.push({ name, reason: outcome.reason });\n svc.events.emit(\"output\", `skipped: ${outcome.reason}`, \"info\");\n } else {\n result.started.push(name);\n }\n } catch (e) {\n const reason = (e as Error).message;\n result.failed.push({ name, reason });\n svc.events.emit(\"output\", `start error: ${reason}`, \"error\");\n }\n }\n return result;\n}\n\n/**\n * \u6309\u542F\u52A8\u9006\u5E8F\u505C\u6B62\u672C\u8FDB\u7A0B\u62C9\u8D77\u7684\u6258\u7BA1\u5B50\u8FDB\u7A0B\uFF08\u4F18\u96C5 stop / stdin stop\uFF09\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A`stop all`\u3001`restart -all`\u3001\u5B88\u62A4\u8FDB\u7A0B shutdown / SIGTERM\u3002\n * \u663E\u5F0F\u4F20 external false\uFF1A\u4E0D\u6309\u955C\u50CF\u540D\u6216\u811A\u672C\u540D\u6740\u5916\u90E8 BDS / db / qq\u3002\n */\nexport async function stopAll(): Promise<void> {\n const pending = [...START_ORDER]\n .reverse()\n .map((name) => services[name])\n .filter((service): service is Service => Boolean(service))\n .map((service) => service.stop(false));\n await Promise.allSettled(pending);\n}\n\nexport function forceStopAll(): void {\n for (const service of Object.values(services)) service.forceStop();\n}\n\nexport type ServiceStateEvent = { name: ServiceName; running: boolean; pid: number };\n\n/** \u8BA2\u9605\u4EFB\u610F\u670D\u52A1\u542F\u505C\uFF08\u542B\u63A2\u6D4B\u56DE\u5199\uFF09\uFF1B\u8FD4\u56DE\u53D6\u6D88\u51FD\u6570 */\nexport function onServiceStateChange(fn: (ev: ServiceStateEvent) => void): () => void {\n /* CLI \u8FDB\u7A0B\u4E0D\u6301\u6709 Service \u5B50\u8FDB\u7A0B\uFF1A\u6539\u8BA2\u5B88\u62A4\u8FDB\u7A0B\u63A8\u9001\u7684\u8FDC\u7A0B\u72B6\u6001\u4E8B\u4EF6 */\n if (!isDaemonServer()) {\n return onRemoteServiceStateChange(fn);\n }\n const handler = (ev: ServiceStateEvent): void => {\n fn(ev);\n };\n for (const service of Object.values(services)) {\n service.events.on(\"state\", handler);\n }\n return () => {\n for (const service of Object.values(services)) {\n service.events.off(\"state\", handler);\n }\n };\n}\n\n/** \u82E5\u672C\u5730\u6807\u8BB0 running \u4F46 OS \u8FDB\u7A0B\u5DF2\u6B7B\uFF0C\u56DE\u6536\u5185\u5B58\u6807\u5FD7 */\nasync function reconcileManagedAlive(service: Service): Promise<boolean> {\n if (!service.running) return false;\n if (service.pid > 0 && !(await isProcessAlive(service.pid))) {\n service.markStoppedFromProbe();\n return false;\n }\n return service.running;\n}\n\n/**\n * \u7EDF\u4E00\u8FD0\u884C\u6001\u67E5\u8BE2\uFF08\u6743\u5A01\u5165\u53E3\uFF09\uFF1AOS/\u5065\u5EB7\u63A2\u6D4B + \u56DE\u5199 Service \u5185\u5B58\u6807\u5FD7\u3002\n * status / Tab \u53D1\u9001\u76EE\u6807 / reload \u7B49\u5747\u5E94\u8D70\u6B64\u63A5\u53E3\uFF0C\u52FF\u76F4\u63A5\u8BFB `service.running`\u3002\n * CLI \u8FDB\u7A0B\u7ECF\u5B88\u62A4\u8FDB\u7A0B RPC \u83B7\u53D6\uFF1B\u5B88\u62A4\u8FDB\u7A0B\u5185\u8D70\u672C\u5730\u63A2\u6D3B\u3002\n */\nexport async function queryServicesRuntime(): Promise<ServiceStatus[]> {\n if (!isDaemonServer()) {\n const { queryRuntimeViaDaemon } = await import(\"./daemon/client.js\");\n return queryRuntimeViaDaemon();\n }\n return queryServicesRuntimeLocal();\n}\n\n/** \u5B88\u62A4\u8FDB\u7A0B\u5185\u672C\u5730\u63A2\u6D3B\u5B9E\u73B0\uFF08\u4EA6\u4F9B server status \u7EC4\u88C5 rows\uFF09 */\nexport async function queryServicesRuntimeLocal(): Promise<ServiceStatus[]> {\n return Promise.all(\n SERVICE_NAMES.map(async (name) => {\n const service = services[name];\n let running = false;\n let pid = 0;\n let uptime = \"\u2014\";\n let ownership: \"managed\" | \"external\" | undefined;\n\n if (name === \"bds\") {\n const probe = await probeBdsStatus({\n managedPid: service.pid,\n hasStdin: Boolean(service.proc?.stdin),\n rootDir: ROOT,\n });\n if (probe.state === \"managed\") {\n running = true;\n pid = probe.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n /* \u63A2\u6D4B\u4E3A managed \u4F46\u672C\u5730\u5DF2\u6807\u505C\uFF1A\u4FDD\u6301\u63A2\u6D4B\u7ED3\u679C\uFF0C\u4E0D\u5F3A\u5236\u6539\u5185\u5B58\uFF08stdin \u4ECD\u53EF\u7528\uFF09 */\n } else if (probe.state === \"external\") {\n running = true;\n pid = probe.pid;\n ownership = \"external\";\n /* \u5916\u90E8\u8FDB\u7A0B\uFF1A\u672C\u5730 managed \u53E5\u67C4\u5DF2\u5931\u6548\u5219\u56DE\u6536 */\n if (service.running && service.pid !== probe.pid) {\n service.markStoppedFromProbe();\n } else if (service.running && !(await isProcessAlive(service.pid))) {\n service.markStoppedFromProbe();\n }\n } else {\n running = false;\n if (service.running || service.proc) {\n service.markStoppedFromProbe();\n }\n }\n } else if (name === \"db\") {\n const managed = await reconcileManagedAlive(service);\n if (managed) {\n running = true;\n pid = service.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n } else if (await probeDbHealth(dbHealthPort)) {\n running = true;\n ownership = \"external\";\n const pids = await findNodeServicePids(\"db\");\n pid = pids[0] ?? 0;\n }\n } else if (name === \"qq\") {\n const managed = await reconcileManagedAlive(service);\n if (managed) {\n running = true;\n pid = service.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n } else {\n const probe = await probeQqRuntime();\n if (probe.alive) {\n running = true;\n pid = probe.pid;\n ownership = \"external\";\n } else {\n const pids = await findNodeServicePids(\"qq\");\n if (pids.length > 0) {\n running = true;\n pid = pids[0]!;\n ownership = \"external\";\n }\n }\n }\n } else if (name === \"tunnel\") {\n const managed = await reconcileManagedAlive(service);\n if (managed) {\n running = true;\n pid = service.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n } else {\n pid = await probeTunnelRuntime();\n running = pid > 0;\n if (running) ownership = \"external\";\n }\n } else {\n const managed = await reconcileManagedAlive(service);\n if (managed) {\n running = true;\n pid = service.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n }\n }\n\n return {\n name,\n title: service.title,\n running,\n pid,\n uptime,\n ...(ownership ? { ownership } : {}),\n };\n })\n );\n}\n\n/** \u5355\u670D\u52A1\u662F\u5426\u5728\u8DD1\uFF08\u542B\u5916\u90E8\u5B9E\u4F8B\uFF09 */\nexport async function isServiceRunning(name: ServiceName): Promise<boolean> {\n const rows = await queryServicesRuntime();\n return rows.some((r) => r.name === name && r.running);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * services.ts \u2014 CLI \u8FDB\u7A0B\u7F16\u6392\u4E0E\u670D\u52A1\u751F\u547D\u5468\u671F\u7BA1\u7406\n *\n * \u6838\u5FC3\u7BA1\u7406\u5BF9\u8C61\uFF08ServiceName\uFF09\uFF1A\n * - `bds`\uFF1AMinecraft \u57FA\u5CA9\u7248\u670D\u52A1\u7AEF\uFF08\u652F\u6301 stdin \u7BA1\u9053\u6307\u4EE4\u4EA4\u4E92\u4E0E\u4F18\u96C5\u505C\u670D\uFF09\n * - `db`\uFF1Adb-server SQLite HTTP \u670D\u52A1\uFF08\u7AEF\u53E3\u5065\u5EB7\u68C0\u67E5\u4E0E loopback \u63A2\u6D3B\uFF09\n * - `tunnel`\uFF1A\u4E91\u7AEF QQ Webhook \u5230\u672C\u673A db-server \u7684 SSH \u53CD\u5411\u96A7\u9053\n * - `qq`\uFF1Aqq-bridge \u6D88\u606F\u7F51\u6865\u670D\u52A1\uFF08\u652F\u6301\u5B98\u65B9 Bot \u4E0E LLBot \u53CC\u540E\u7AEF\uFF09\n * - `llbot`\uFF1ALLBot \u72EC\u7ACB\u673A\u5668\u4EBA\u8FDB\u7A0B\uFF08\u6761\u4EF6\u542F\u52A8\uFF09\n *\n * \u6838\u5FC3\u80FD\u529B\uFF1A\n * - \u8FDB\u7A0B\u751F\u547D\u5468\u671F\uFF1A\u6309\u4F9D\u8D56\u6B21\u5E8F\u7F16\u6392\u670D\u52A1\u542F\u52A8\uFF08db \u2192 qq \u2192 bds\uFF09\u3001\u4F18\u96C5\u505C\u6B62\u4E0E\u5F02\u5E38\u81EA\u52A8\u62C9\u8D77\n * - \u591A\u6E90\u63A2\u6D3B\u611F\u77E5\uFF1A\u81EA\u52A8\u63A2\u6D4B\u6258\u7BA1\u8FDB\u7A0B\u4E0E\u5916\u90E8\u72EC\u7ACB\u8FDB\u7A0B\u72B6\u6001\n * - \u65E5\u5FD7\u6D41\u7EDF\u4E00\u805A\u5408\uFF1A\u6355\u83B7\u5E76\u5F52\u4E00\u5316\u5404\u670D\u52A1\u7684 stdout / stderr \u6570\u636E\u6D41\n */\n\nimport type { BdsUpdaterConfig, DBConfig, QQBackend, QQBridgeConfig } from \"@sfmc-bds/sdk/node/config\";\nimport {\n DEFAULT_BDS_UPDATER_CONFIG,\n DEFAULT_DB_CONFIG,\n DEFAULT_QQ_CONFIG,\n ensureCoreConfigs,\n loadEnsuredConfig,\n qqRuntimeStatusPath,\n readJson,\n type QqRuntimeStatus,\n} from \"@sfmc-bds/sdk/node/config\";\n\nimport { bdsExePath, bdsSpawnEnvExtra, ensureBdsExecutable } from \"@sfmc-bds/bds-tools/host-platform\";\nimport {\n clearBdsPidFile,\n findBedrockServerPids,\n isProcessAlive,\n killBedrockServerByImage,\n probeBdsStatus,\n readBdsPidFile,\n writeBdsPidFile,\n} from \"@sfmc-bds/bds-tools/process-probe\";\nimport { postBdsLifecycleEvent } from \"@sfmc-bds/bds-tools/qq-events-notify\";\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { EventEmitter } from \"node:events\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { isDaemonServer } from \"./daemon/role.js\";\nimport { onRemoteServiceStateChange } from \"./daemon/client.js\";\nimport { t } from \"./i18n/index.js\";\nimport { resolveLlbotLaunch } from \"./llbot-launch.js\";\nimport { inferLevel, pushLog as pushUnifiedLog } from \"./logs.js\";\nimport { findNodeServicePids, killNodeServiceByScript } from \"./node-service-probe.js\";\nimport { ensurePackUpdateConfigFile } from \"./pack-update/index.js\";\nimport { recordBdsVersion } from \"./bds-runtime-version.js\";\nimport { reportBdsPlayerSession } from \"./player-session.js\";\nimport { startModuleSidecars, stopModuleSidecars } from \"./module-sidecars.js\";\nimport { ROOT, spawnService, type ServiceId } from \"./runtime.js\";\n\nexport { ROOT } from \"./runtime.js\";\n\nexport interface LogLine {\n time: Date;\n text: string;\n stream: \"stdout\" | \"stderr\";\n}\n\n/** \u5B50\u8FDB\u7A0B\u8F93\u51FA\u5206\u884C\uFF1A\u8FC7\u6EE4\u7A7A\u4E32\u4EE5\u53CA Windows CRLF \u62C6\u5206\u540E\u6B8B\u7559\u7684\u7EAF\u7A7A\u767D\u884C\u3002 */\nexport function nonBlankOutputLines(text: string): string[] {\n return text.split(/\\r?\\n/).filter((line) => line.trim().length > 0);\n}\n\nexport type ServiceName = \"bds\" | \"db\" | \"tunnel\" | \"qq\" | \"llbot\";\nexport const SERVICE_NAMES: ServiceName[] = [\"bds\", \"db\", \"tunnel\", \"qq\", \"llbot\"];\n\n/** \u5355\u670D\u52A1 start \u7ED3\u679C\uFF1Aoptional \u670D\u52A1 validate \u5931\u8D25\u8BB0\u4E3A skipped\uFF0C\u4E0D\u629B\u9519 */\nexport type StartOutcome = { status: \"started\" } | { status: \"already\" } | { status: \"skipped\"; reason: string };\n\n/**\n * \u5355\u670D\u52A1 stop \u7ED3\u679C\uFF0C\u4F9B CLI \u533A\u5206\u6587\u6848\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A`stop <name>` / `restart <name>` \u4E0E `stop all` \u90FD\u8D70 Service.stop\uFF0C\u4F46\u53EA\u6709\u524D\u8005\u4F1A\u5F97\u5230 external\u3002\n * - managed\uFF1A\u505C\u7684\u662F\u672C\u8FDB\u7A0B\u62C9\u8D77\u7684\u5B50\u8FDB\u7A0B\n * - external\uFF1A\u6CA1\u6709\u6258\u7BA1\u53E5\u67C4\uFF0C\u4F46\u6E05\u6389\u4E86\u5916\u90E8\u5B9E\u4F8B\uFF08\u4EC5 external=true \u65F6\uFF09\n * - idle\uFF1A\u672C\u6765\u5C31\u6CA1\u5728\u8DD1\uFF0C\u6216\u6279\u91CF\u505C\u6B62\u65F6\u6545\u610F\u4E0D\u52A8\u5916\u90E8\u5B9E\u4F8B\n */\nexport type StopKind = \"managed\" | \"external\" | \"idle\";\n\nexport interface StartAllResult {\n started: ServiceName[];\n skipped: Array<{ name: ServiceName; reason: string }>;\n failed: Array<{ name: ServiceName; reason: string }>;\n}\n\nexport interface ServiceStatus {\n name: ServiceName;\n title: string;\n running: boolean;\n pid: number;\n uptime: string;\n ownership?: \"managed\" | \"external\";\n}\n\n/** \u5F53\u524D db \u5065\u5EB7\u63A2\u6D4B\u7AEF\u53E3\uFF08\u4E0E createServices \u540C\u6B65\uFF09 */\nlet dbHealthPort = 3001;\n/** \u5F53\u524D QQ \u540E\u7AEF\uFF08\u4E0E createServices \u540C\u6B65\uFF0C\u4F9B Tab/\u7A97\u6807\u9898\uFF09 */\nlet qqBackendMode: QQBackend = \"official\";\n\nexport function getQqBackendMode(): QQBackend {\n return qqBackendMode;\n}\n\nasync function probeDbHealth(port: number): Promise<boolean> {\n try {\n const res = await fetch(`http://127.0.0.1:${port}/api/health`, { signal: AbortSignal.timeout(2000) });\n return res.ok;\n } catch {\n return false;\n }\n}\n\n/** \u8BFB `.sfmc/qq.runtime.json` + pid \u5B58\u6D3B\uFF0C\u63A2\u6D4B\u5916\u90E8/\u672C\u673A qq-bridge */\nasync function probeQqRuntime(): Promise<{ alive: boolean; pid: number }> {\n const status = readJson<QqRuntimeStatus>(qqRuntimeStatusPath(ROOT));\n if (!status?.pid || status.pid <= 0) return { alive: false, pid: 0 };\n if (!(await isProcessAlive(status.pid))) return { alive: false, pid: 0 };\n return { alive: true, pid: status.pid };\n}\n\nconst tunnelRuntimePath = path.join(ROOT, \".sfmc\", \"tunnel.runtime.json\");\n\nasync function probeTunnelRuntime(): Promise<number> {\n const pid = readJson<{ pid?: number }>(tunnelRuntimePath)?.pid;\n return typeof pid === \"number\" && pid > 0 && (await isProcessAlive(pid)) ? pid : 0;\n}\n\nfunction writeTunnelRuntime(pid: number): void {\n fs.mkdirSync(path.dirname(tunnelRuntimePath), { recursive: true });\n fs.writeFileSync(tunnelRuntimePath, JSON.stringify({ pid, startedAt: Date.now() }) + \"\\n\");\n}\n\nfunction clearTunnelRuntime(pid: number): void {\n if (readJson<{ pid?: number }>(tunnelRuntimePath)?.pid !== pid) return;\n try {\n fs.unlinkSync(tunnelRuntimePath);\n } catch {\n /* \u8FDB\u7A0B\u9000\u51FA\u65F6\u5141\u8BB8\u6587\u4EF6\u5DF2\u88AB\u79FB\u9664 */\n }\n}\n\n/** \u6E05\u6389 qq-bridge \u8FD0\u884C\u65F6\u6587\u4EF6\uFF0C\u907F\u514D status \u4ECD\u628A\u5DF2\u9000\u51FA\u7684\u5916\u90E8\u8FDB\u7A0B\u5F53\u6210\u5B58\u6D3B\u3002 */\nfunction clearQqRuntimeFile(): void {\n try {\n const file = qqRuntimeStatusPath(ROOT);\n if (fs.existsSync(file)) fs.unlinkSync(file);\n } catch {\n /* \u8FD0\u884C\u65F6\u6587\u4EF6\u53EF\u80FD\u5DF2\u88AB\u8FDB\u7A0B\u81EA\u5DF1\u5220\u6389 */\n }\n}\n\n/**\n * \u6309\u955C\u50CF\u540D\u7ED3\u675F\u5916\u90E8 BDS\uFF0C\u5E76\u7B49\u5230\u8FDB\u7A0B\u4ECE\u8FDB\u7A0B\u8868\u6D88\u5931\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A\u4EC5\u5355\u670D\u52A1 stop / restart\uFF08Service.stop \u7684 external=true\uFF09\u6E05\u6389\u975E\u672C\u8FDB\u7A0B\u62C9\u8D77\u7684 bedrock\u3002\n * stop all \u4E0E\u5B88\u62A4\u8FDB\u7A0B shutdown \u4E0D\u8C03\u7528\u8FD9\u91CC\uFF0C\u907F\u514D taskkill \u8BEF\u6740\u540C\u673A\u5176\u4ED6 Bedrock\u3002\n * taskkill \u8FD4\u56DE\u540E\u8FDB\u7A0B\u8868\u53EF\u80FD\u4ECD\u77ED\u6682\u53EF\u89C1\uFF0Crestart \u4F1A\u7ACB\u523B\u63A2\u6D3B\uFF0C\u56E0\u6B64\u8FD9\u91CC\u7B49\u5230\u6D88\u5931\u518D\u8FD4\u56DE\u3002\n */\nasync function killExternalBedrock(): Promise<void> {\n await killBedrockServerByImage();\n clearBdsPidFile(ROOT);\n const deadline = Date.now() + 8000;\n while (Date.now() < deadline) {\n if ((await findBedrockServerPids()).length === 0) return;\n await new Promise((r) => setTimeout(r, 200));\n }\n await killBedrockServerByImage();\n clearBdsPidFile(ROOT);\n}\n\ninterface ServiceDef {\n name: ServiceName;\n title: string;\n service?: ServiceId;\n cmd?: string;\n args?: string[];\n cwd: string;\n env?: Record<string, string>;\n stopCommand?: string;\n stopTimeout: number;\n autoRestart: boolean;\n restartDelay: number;\n /**\n * \u53EF\u9009\u670D\u52A1\uFF1Avalidate \u5931\u8D25\u65F6 start \u8FD4\u56DE skipped\uFF08startAll \u4E0D\u5F53\u4F5C\u5931\u8D25\uFF09\u3002\n * \u7528\u4E8E official \u4E0B\u8DF3\u8FC7 llbot\u3001\u4EE5\u53CA qq_enabled=false\u3002\n */\n optional?: boolean;\n validate?: () => string | null;\n /** \u542F\u52A8\u524D\u94A9\u5B50(\u5982 BDS \u88C5\u8F7D\u4E00\u81F4\u6027\u6821\u9A8C);\u5931\u8D25\u5219\u7981\u6B62 spawn */\n beforeStart?: () => Promise<void>;\n /** \u539F\u59CB\u65E5\u5FD7\u884C\u89C2\u5BDF\u5668\uFF0C\u4E0D\u5F97\u963B\u585E\u5B50\u8FDB\u7A0B\u8F93\u51FA\u3002 */\n onLogLine?: (line: string) => void;\n}\n\nclass Service {\n name: ServiceName;\n title: string;\n proc: ChildProcess | null = null;\n running = false;\n pid = 0;\n startTime: Date | null = null;\n logs: LogLine[] = [];\n events = new EventEmitter();\n\n private def: ServiceDef;\n private manualStop = false;\n private updateInProgress = false;\n private restartTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(def: ServiceDef) {\n this.name = def.name;\n this.title = def.title;\n this.def = def;\n if (def.name === \"tunnel\") {\n this.events.on(\"output\", (text: string, level: \"info\" | \"error\") => {\n pushUnifiedLog(text, \"tunnel\", level);\n });\n }\n }\n\n get uptime(): string {\n if (!this.startTime || !this.running) return \"\u2014\";\n const ms = Date.now() - this.startTime.getTime();\n const m = Math.floor(ms / 60000);\n const h = Math.floor(m / 60);\n if (h > 0) return `${h}h ${m % 60}m`;\n if (m > 0) return `${m}m`;\n return `${Math.floor(ms / 1000)}s`;\n }\n\n pushLog(text: string, stream: \"stdout\" | \"stderr\"): void {\n const line: LogLine = { time: new Date(), text, stream };\n this.logs.push(line);\n if (this.logs.length > 2000) this.logs.splice(0, this.logs.length - 2000);\n this.events.emit(\"log\", line);\n // stderr \u89C6\u4E3A error; stdout \u7528 inferLevel \u63A8\u65AD (bare \u5B50\u8FDB\u7A0B\u7EAF text \u65F6\u9ED8\u8BA4 info,\n // BDS \u7B49\u81EA\u5E26 [LEVEL] \u6807\u7B7E\u7684\u4ECD\u53EF\u6B63\u786E\u63A8\u65AD)\n const level = stream === \"stderr\" ? \"error\" : inferLevel(text);\n pushUnifiedLog(text, this.name, level);\n this.def.onLogLine?.(text);\n }\n\n async start(): Promise<StartOutcome> {\n if (this.updateInProgress) throw new Error(\"BDS \u6B63\u5728\u66F4\u65B0\uFF0C\u6682\u4E0D\u53EF\u542F\u52A8\");\n if (this.running) return { status: \"already\" };\n if (this.name === \"bds\") {\n const probe = await probeBdsStatus({ rootDir: ROOT });\n if (probe.state !== \"stopped\") {\n throw new Error(\n t(\"svc.bdsAlreadyRunning\", {\n pid: String(probe.pid),\n kind: t(probe.state === \"managed\" ? \"svc.running\" : \"svc.runningExternal\"),\n })\n );\n }\n }\n if (this.name === \"db\" || this.name === \"qq\") {\n const external = await findNodeServicePids(this.name);\n if (external.length > 0) {\n return { status: \"already\" };\n }\n }\n if (this.name === \"tunnel\" && (await probeTunnelRuntime())) return { status: \"already\" };\n if (this.def.validate) {\n const v = this.def.validate();\n if (v) {\n // optional\uFF1A\u914D\u7F6E\u5C42\u9762\u8DF3\u8FC7\uFF08\u5982 official \u4E0B llbot\uFF09\uFF0C\u4E0D\u5F53\u5931\u8D25\u3001\u4E5F\u4E0D spawn\n if (this.def.optional) return { status: \"skipped\", reason: v };\n throw new Error(v);\n }\n }\n if (this.def.beforeStart) {\n await this.def.beforeStart();\n }\n if (this.name === \"bds\") {\n await startModuleSidecars(ROOT, (line, stream) => this.pushLog(line, stream));\n }\n // beforeStart \u542B\u5F02\u6B65\u68C0\u67E5\uFF1B\u66F4\u65B0\u53EF\u80FD\u5728\u7B49\u5F85\u671F\u95F4\u5F00\u59CB\u3002\n if (this.updateInProgress) throw new Error(\"BDS \u6B63\u5728\u66F4\u65B0\uFF0C\u6682\u4E0D\u53EF\u542F\u52A8\");\n this.manualStop = false;\n /* \u5B50\u8FDB\u7A0B\u59CB\u7EC8\u7531\u5B88\u62A4\u8FDB\u7A0B\u7528\u7BA1\u9053\u6301\u6709\uFF08stdin \u53D1 stop\u3001stdout \u65E5\u5FD7\u3001autoRestart\uFF09\uFF1B\n * \u4E0D\u518D\u5BF9\u5B50\u670D\u52A1\u505A detached/unref\u2014\u2014\u8131\u79BB\u7EC8\u7AEF\u7531 daemon \u8FDB\u7A0B\u81EA\u8EAB\u8D1F\u8D23\u3002\n * windowsHide\uFF1AWindows \u4E0A\u907F\u514D\u4E3A\u6BCF\u4E2A\u670D\u52A1\u5F39\u51FA\u7A7A\u767D\u63A7\u5236\u53F0\uFF08stdout \u5DF2 pipe\uFF0C\u7A97\u5185\u65E0\u8F93\u51FA\uFF09\u3002 */\n const spawnOpts = {\n cwd: this.def.cwd,\n stdio: [\"pipe\", \"pipe\", \"pipe\"] as Array<\"pipe\">,\n env: this.def.env ? { ...process.env, ...this.def.env } : process.env,\n windowsHide: true,\n };\n const child = this.def.service\n ? spawnService(this.def.service, this.def.args ?? [], spawnOpts)\n : spawn(this.def.cmd as string, this.def.args ?? [], spawnOpts);\n this.proc = child;\n this.pid = child.pid ?? 0;\n this.running = true;\n this.startTime = new Date();\n if (this.name === \"bds\" && this.pid > 0) {\n writeBdsPidFile(this.pid, ROOT);\n }\n if (this.name === \"tunnel\" && this.pid > 0) writeTunnelRuntime(this.pid);\n this.events.emit(\"output\", `started (PID ${this.pid})`, \"info\");\n this.events.emit(\"state\", { name: this.name, running: true, pid: this.pid });\n\n let lifecycleReported = false;\n const reportExit = (code?: number | null) => {\n if (this.name !== \"bds\" || lifecycleReported) return;\n lifecycleReported = true;\n const planned = this.manualStop || this.updateInProgress;\n void postBdsLifecycleEvent(planned ? \"stop\" : \"crash\", planned ? undefined : `code=${code ?? \"?\"}`, {\n port: dbHealthPort,\n });\n };\n if (this.name === \"bds\") {\n child.once(\"spawn\", () => {\n void postBdsLifecycleEvent(\"start\", undefined, { port: dbHealthPort });\n });\n }\n\n child.on(\"error\", (e) => {\n this.events.emit(\"output\", `process error: ${e.message}`, \"error\");\n reportExit();\n this.cleanup();\n this.scheduleRestart();\n });\n\n let versionLineBuffer = \"\";\n child.stdout?.on(\"data\", (d: Buffer) => {\n if (this.name === \"bds\" && this.startTime) {\n versionLineBuffer += d.toString();\n const versionLines = versionLineBuffer.split(/\\r?\\n/);\n versionLineBuffer = (versionLines.pop() ?? \"\").slice(-4096);\n for (const versionLine of versionLines) recordBdsVersion(ROOT, versionLine, this.pid, this.startTime.getTime());\n }\n for (const line of nonBlankOutputLines(d.toString())) {\n this.pushLog(line, \"stdout\");\n }\n });\n child.stderr?.on(\"data\", (d: Buffer) => {\n for (const line of nonBlankOutputLines(d.toString())) {\n this.pushLog(line, \"stderr\");\n }\n });\n\n child.on(\"exit\", (code) => {\n if (this.proc && this.proc !== child) return;\n this.events.emit(\"output\", `exited (code: ${code})`, \"info\");\n reportExit(code);\n this.cleanup();\n this.scheduleRestart();\n });\n return { status: \"started\" };\n }\n\n private scheduleRestart(): void {\n if (this.manualStop || this.updateInProgress || !this.def.autoRestart || this.restartTimer) return;\n this.restartTimer = setTimeout(() => {\n this.restartTimer = null;\n if (!this.updateInProgress && !this.manualStop && !this.running) {\n void this.start().catch((e: Error) => {\n this.events.emit(\"output\", `restart failed: ${e.message}`, \"error\");\n });\n }\n }, this.def.restartDelay);\n }\n\n /** \u66F4\u65B0\u5668\u72EC\u7ACB\u8FDB\u7A0B\u505C\u670D\u65F6\uFF0C\u7981\u6B62\u5C06\u8BA1\u5212\u5185\u9000\u51FA\u5F53\u4F5C\u5D29\u6E83\u5E76\u81EA\u52A8\u62C9\u8D77\u3002 */\n beginUpdate(): void {\n if (this.name !== \"bds\") return;\n if (this.updateInProgress) throw new Error(\"BDS \u66F4\u65B0\u5DF2\u5728\u8FDB\u884C\u4E2D\");\n this.updateInProgress = true;\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n }\n\n endUpdate(): void {\n this.updateInProgress = false;\n }\n\n /**\n * \u505C\u6B62\u672C\u670D\u52A1\u3002\u6258\u7BA1\u5B50\u8FDB\u7A0B\u59CB\u7EC8\u8D70\u539F\u6765\u7684\u4F18\u96C5\u505C\u6B62\uFF08stdin stop / SIGTERM\uFF09\u3002\n * @param external \u662F\u5426\u989D\u5916\u6E05\u6389\u975E\u672C\u8FDB\u7A0B\u62C9\u8D77\u7684\u5916\u90E8\u5B9E\u4F8B\u3002\u9ED8\u8BA4 false\uFF0C\u53EA\u505C\u6258\u7BA1\u5B50\u8FDB\u7A0B\u3002\n * \u4E24\u79CD\u8C03\u7528\u573A\u666F\uFF1A\n * - true\uFF1A\u5355\u670D\u52A1 `stop <name>` / `restart <name>`\uFF08cmdStopLocal\uFF0C\u4EE5\u53CA\u4ECD\u5B58\u5728\u7684 Service.restart\uFF09\u3002\n * BDS \u5916\u90E8\u8D70 killExternalBedrock\uFF1Bdb/qq \u5916\u90E8\u8D70 killNodeServiceByScript\u3002\n * - false \u6216\u4E0D\u4F20\uFF1A`stop all`\u3001`restart -all`\u3001\u5B88\u62A4\u8FDB\u7A0B shutdown / SIGTERM\uFF08\u7ECF stopAll\uFF09\u3002\n * \u4E0D\u6309\u955C\u50CF\u540D\u6216\u811A\u672C\u540D\u6740\u5916\u90E8\u8FDB\u7A0B\uFF0C\u907F\u514D\u8BEF\u6740\u540C\u673A\u5176\u4ED6 Bedrock\u3001db\u3001qq\u3002\n */\n async stop(external = false, forceOnTimeout = true): Promise<StopKind> {\n this.manualStop = true;\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n\n /* \u4E0E\u539F\u5148 cmdStop \u4E00\u81F4\uFF1A\u4EC5\u5355\u670D\u52A1\u505C\u6B62\u65F6\uFF0CBDS \u88AB\u5224\u5B9A\u4E3A\u5916\u90E8\u624D\u6309\u955C\u50CF\u7ED3\u675F\uFF0C\u4E0D\u8D70 stdin stop */\n if (external && this.name === \"bds\") {\n const probe = await probeBdsStatus({\n managedPid: this.pid,\n hasStdin: Boolean(this.proc?.stdin),\n rootDir: ROOT,\n });\n if (probe.state === \"external\") {\n await killExternalBedrock();\n this.dropStaleHandle();\n return \"external\";\n }\n }\n\n const managed = Boolean(this.proc && this.running);\n if (managed) await this.stopManagedChild(forceOnTimeout);\n\n /* db / qq\uFF1A\u4EC5\u5355\u670D\u52A1\u505C\u6B62\u65F6\uFF0C\u6258\u7BA1\u505C\u5B8C\u540E\u4ECD\u6309\u811A\u672C\u518D\u626B\u4E00\u904D\uFF0C\u6E05\u6389\u540C\u673A\u4E0A\u7684\u5916\u90E8\u5B9E\u4F8B */\n if (external && (this.name === \"db\" || this.name === \"qq\")) {\n const killed = await killNodeServiceByScript(this.name);\n if (this.name === \"qq\") clearQqRuntimeFile();\n if (managed) return \"managed\";\n return killed.length > 0 ? \"external\" : \"idle\";\n }\n\n if (managed) return \"managed\";\n return \"idle\";\n }\n\n /**\n * \u4F18\u96C5\u505C\u6B62\u5F53\u524D\u6258\u7BA1\u5B50\u8FDB\u7A0B\uFF08stdin stop \u6216 SIGTERM\uFF0C\u8D85\u65F6\u540E SIGKILL\uFF09\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1AService.stop \u786E\u8BA4\u672C\u8FDB\u7A0B\u4ECD\u6301\u6709\u5B50\u8FDB\u7A0B\u65F6\u8C03\u7528\uFF1B\u903B\u8F91\u4E0E\u539F\u5148 stop \u4E3B\u4F53\u76F8\u540C\u3002\n */\n private async stopManagedChild(forceOnTimeout = true): Promise<void> {\n if (!this.proc || !this.running) return;\n this.events.emit(\"output\", \"stopping...\", \"info\");\n\n if (this.def.stopCommand && this.proc.stdin) {\n this.proc.stdin.write(this.def.stopCommand + \"\\n\");\n } else {\n this.proc.kill(\"SIGTERM\");\n }\n\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n if (!forceOnTimeout && this.proc) {\n reject(new Error(`${this.name} \u672A\u5728\u8D85\u65F6\u5185\u4F18\u96C5\u9000\u51FA\uFF1B\u5DF2\u4E2D\u6B62\u7EF4\u62A4\uFF0C\u4E0D\u5F3A\u5236\u7ED3\u675F\u8FDB\u7A0B`));\n return;\n }\n if (this.proc) {\n this.events.emit(\"output\", \"force kill\", \"error\");\n try {\n this.proc.kill(\"SIGKILL\");\n } catch {\n /* ignore */\n }\n }\n resolve();\n }, this.def.stopTimeout);\n\n this.proc?.on(\"exit\", () => {\n clearTimeout(timeout);\n resolve();\n });\n });\n }\n\n /**\n * \u5916\u90E8\u505C\u670D\u540E\u4E22\u6389\u5931\u6548\u7684\u6258\u7BA1\u53E5\u67C4\uFF0C\u907F\u514D\u7D27\u63A5\u7740\u7684 start/restart \u8BEF\u5224\u300C\u5DF2\u5728\u8FD0\u884C\u300D\u3002\n * \u4E0D\u8D70 cleanup\uFF1A\u90A3\u4F1A\u8FDE\u5E26\u505C\u6389\u6A21\u5757\u9644\u5C5E\u8FDB\u7A0B\uFF0C\u800C\u539F\u5148\u7684\u5916\u90E8 BDS stop \u5E76\u4E0D\u8FD9\u4E48\u505A\u3002\n */\n private dropStaleHandle(): void {\n if (!this.running && !this.proc) return;\n const stale = this.proc;\n this.proc = null;\n this.running = false;\n this.pid = 0;\n this.startTime = null;\n this.events.emit(\"state\", { name: this.name, running: false, pid: 0 });\n if (stale && stale.exitCode === null) {\n try {\n stale.kill(\"SIGKILL\");\n } catch {\n /* \u5916\u90E8\u955C\u50CF\u7ED3\u675F\u65F6\u8FD9\u4E2A\u53E5\u67C4\u53EF\u80FD\u5DF2\u7ECF\u9000\u51FA */\n }\n }\n }\n\n forceStop(): void {\n const child = this.proc;\n this.manualStop = true;\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n this.cleanup();\n if (!child) return;\n try {\n child.kill(\"SIGKILL\");\n } catch {\n /* ignore */\n }\n }\n\n /**\n * \u5355\u670D\u52A1\u91CD\u542F\uFF1A\u5148\u505C\u518D\u8D77\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A\u82E5\u4ECD\u6709\u8C03\u7528\u65B9\u76F4\u63A5\u8D70 Service.restart\uFF08\u4E0D\u7ECF cmdStopLocal\uFF09\uFF0C\u4E0E\u5355\u670D\u52A1 stop \u4E00\u6837\u6E05\u5916\u90E8\u5B9E\u4F8B\uFF08external true\uFF09\u3002\n * \u6279\u91CF `restart -all` \u548C\u5B88\u62A4\u8FDB\u7A0B shutdown \u4E0D\u8D70\u8FD9\u91CC\uFF0C\u5B83\u4EEC\u7ECF stopAll \u8C03\u7528 stop(false)\uFF0C\u53EA\u505C\u6258\u7BA1\u5B50\u8FDB\u7A0B\u3002\n */\n async restart(): Promise<StartOutcome> {\n await this.stop(true);\n return this.start();\n }\n\n getRecentLogs(n: number): LogLine[] {\n return this.logs.slice(-n);\n }\n\n /**\n * \u63A2\u6D4B\u53D1\u73B0\u8FDB\u7A0B\u5DF2\u6B7B\u540E\u56DE\u5199\u672C\u5730\u72B6\u6001\uFF08\u4E0D\u8BBE manualStop\uFF0C\u4EE5\u4FBF exit \u56DE\u8C03\u4ECD\u53EF\u6309\u9700 autoRestart\uFF09\u3002\n */\n markStoppedFromProbe(): void {\n if (!this.running && !this.proc) return;\n this.cleanup();\n }\n\n private cleanup(): void {\n const wasRunning = this.running || this.proc !== null;\n const exitingPid = this.pid;\n this.proc = null;\n this.running = false;\n this.pid = 0;\n this.startTime = null;\n if (this.name === \"bds\" && exitingPid > 0) {\n const filePid = readBdsPidFile(ROOT);\n if (filePid === exitingPid) {\n clearBdsPidFile(ROOT);\n }\n stopModuleSidecars();\n }\n if (this.name === \"tunnel\" && exitingPid > 0) clearTunnelRuntime(exitingPid);\n if (wasRunning) {\n this.events.emit(\"state\", { name: this.name, running: false, pid: 0 });\n }\n }\n}\n\nfunction createServices(): Record<ServiceName, Service> {\n /* \u5404\u670D\u52A1/CLI \u7528 SDK ensureCoreConfigs \u64AD\u79CD\uFF08\u542B $schema\uFF09\uFF0C\u4E0D\u518D\u4ECE configs-default \u62F7\u8D1D\u3002 */\n ensureCoreConfigs(ROOT, [\"bds_updater\", \"qq_config\", \"db_config\", \"qq_link\"]);\n ensurePackUpdateConfigFile();\n void import(\"./module-update/index.js\")\n .then((mod) => mod.ensureModuleUpdateConfigFile())\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n pushUnifiedLog(message, \"module\", \"warn\");\n });\n const bdsCfg = loadEnsuredConfig(ROOT, \"bds_updater.json\", \"bds_updater\", { ...DEFAULT_BDS_UPDATER_CONFIG } as Record<\n string,\n unknown\n >) as BdsUpdaterConfig;\n const qqCfg = loadEnsuredConfig(ROOT, \"qq_config.json\", \"qq_config\", { ...DEFAULT_QQ_CONFIG } as Record<\n string,\n unknown\n >) as QQBridgeConfig;\n const dbCfg = loadEnsuredConfig(ROOT, \"db_config.json\", \"db_config\", { ...DEFAULT_DB_CONFIG } as Record<\n string,\n unknown\n >) as DBConfig;\n const rawBdsPath = String(bdsCfg.bds_path ?? \"\").trim();\n if (process.platform !== \"win32\" && /^[A-Za-z]:[\\\\/]/.test(rawBdsPath)) {\n throw new Error(\n `configs/bds_updater.json \u7684 bds_path \u662F Windows \u8DEF\u5F84\uFF08${rawBdsPath}\uFF09\u3002` +\n `\u8BF7\u6539\u6210\u76F8\u5BF9 SFMC_ROOT \u7684\u8DEF\u5F84\uFF0C\u4F8B\u5982 \"BDS\"\u3002`\n );\n }\n const bdsPath = path.resolve(ROOT, rawBdsPath || \".\");\n const useLlbotBackend = qqCfg.qq_backend === \"llbot\";\n const qqEnabled = qqCfg.qq_enabled !== false;\n // \u5B98\u65B9 Webhook \u7531\u4E91\u7AEF\u63A5\u6536\uFF1B\u4EC5\u5207\u6362\u4F20\u8F93\u65B9\u5F0F\u5373\u53EF\u907F\u514D\u672C\u673A\u518D\u542F\u52A8\u4E00\u4E2A\u6865\u3002\n const qqExternal = !useLlbotBackend && qqCfg.official?.transport === \"webhook\";\n const tunnelCfg = qqCfg.official?.tunnel;\n const tunnelEnabled = qqEnabled && qqExternal && tunnelCfg?.enabled === true;\n const tunnelHost = String(tunnelCfg?.host ?? \"\").trim();\n const tunnelRemotePort = tunnelCfg?.remotePort ?? 13001;\n const llbotEnabled = qqCfg.llbot?.enabled !== false;\n const llbotLaunch = resolveLlbotLaunch(qqCfg.llbot?.path, qqCfg.llbot?.cwd);\n const llbotPath = llbotLaunch.exe;\n const llbotCwd = llbotLaunch.cwd;\n const dbPort = dbCfg.db_port ?? 3001;\n dbHealthPort = dbPort;\n qqBackendMode = useLlbotBackend ? \"llbot\" : \"official\";\n const bdsExe = bdsExePath(bdsPath);\n const qqTitle = useLlbotBackend ? \"QQ (llbot)\" : \"QQ (official)\";\n\n return {\n bds: new Service({\n name: \"bds\",\n title: \"BDS\",\n cmd: bdsExe,\n args: [],\n cwd: bdsPath,\n env: bdsSpawnEnvExtra(bdsPath),\n stopCommand: \"stop\",\n stopTimeout: 30000,\n /* \u5D29\u6E83\u62C9\u8D77\u7531 sfmc daemon \u56FA\u5B9A\u5F00\u542F\uFF1B\u4E0D\u518D\u8BFB bds_updater.crash_restart */\n autoRestart: true,\n restartDelay: 5000,\n validate: () => {\n if (!fs.existsSync(bdsExe)) return `not found: ${bdsExe}`;\n return null;\n },\n beforeStart: async () => {\n ensureBdsExecutable(bdsExe);\n /* \u5148\u88C5\u6536\u4EF6\u7BB1\u7B2C\u4E09\u65B9\u5305\uFF0C\u518D\u68C0\u67E5 CF \u66F4\u65B0\uFF0C\u518D\u8DD1\u6A21\u5757\u805A\u5408\u95F8\u95E8 */\n /* \u4E1A\u52A1\u6A21\u5757\u66F4\u65B0\u53EA\u8D70\u663E\u5F0F\u547D\u4EE4\uFF0C\u4E0D\u8FDB\u5F00\u670D\u94A9\u5B50\u3002 */\n const { scanAndInstallInbox } = await import(\"./world-packs.js\");\n await scanAndInstallInbox({ interactive: false });\n const { runPackUpdatesOnBdsStart } = await import(\"./pack-update/index.js\");\n await runPackUpdatesOnBdsStart();\n const { ensurePacksReady } = await import(\"./pack-lifecycle.js\");\n await ensurePacksReady();\n },\n onLogLine: (line) =>\n reportBdsPlayerSession(line, {\n port: dbPort,\n ...(dbCfg.http_auth ? { authToken: dbCfg.http_auth } : {}),\n }),\n }),\n\n db: new Service({\n name: \"db\",\n title: \"DB Server\",\n service: \"db\",\n cwd: ROOT,\n stopTimeout: 10000,\n autoRestart: true,\n restartDelay: 3000,\n env: { DB_PORT: String(dbPort) },\n }),\n\n tunnel: new Service({\n name: \"tunnel\",\n title: \"QQ SSH Tunnel\",\n cmd: \"ssh\",\n args: [\n \"-N\", \"-T\", \"-o\", \"BatchMode=yes\", \"-o\", \"ConnectTimeout=10\",\n \"-o\", \"ExitOnForwardFailure=yes\", \"-o\", \"ServerAliveInterval=30\",\n \"-o\", \"ServerAliveCountMax=3\",\n \"-R\", `127.0.0.1:${tunnelRemotePort}:127.0.0.1:${dbPort}`,\n tunnelHost,\n ],\n cwd: ROOT,\n stopTimeout: 10000,\n autoRestart: true,\n restartDelay: 5000,\n optional: !tunnelEnabled,\n validate: () => {\n if (!tunnelEnabled) return \"QQ tunnel disabled (official webhook tunnel.enabled=false)\";\n if (!/^[A-Za-z0-9_][A-Za-z0-9_.-]*$/.test(tunnelHost)) return \"invalid official.tunnel.host\";\n if (!Number.isInteger(tunnelRemotePort) || tunnelRemotePort < 1 || tunnelRemotePort > 65535) {\n return \"invalid official.tunnel.remotePort\";\n }\n return null;\n },\n }),\n\n qq: new Service({\n name: \"qq\",\n title: qqTitle,\n service: \"qq\",\n cwd: ROOT,\n stopTimeout: 10000,\n // \u7F3A\u51ED\u636E\u65F6 validate \u62E6\u4E0B\uFF0C\u4E0D\u4F1A spawn\u2192exit(1)\u2192autoRestart \u6B7B\u5FAA\u73AF\n autoRestart: true,\n restartDelay: 3000,\n optional: !qqEnabled || qqExternal,\n validate: () => {\n if (!qqEnabled) return \"QQ bridge disabled (qq_enabled=false)\";\n if (qqExternal) return \"QQ bridge runs externally (official.transport=webhook)\";\n if (!useLlbotBackend) {\n if (!String(qqCfg.official?.app_id ?? \"\").trim() || !String(qqCfg.official?.app_secret ?? \"\").trim()) {\n return \"missing official.app_id / official.app_secret\";\n }\n }\n return null;\n },\n }),\n\n llbot: new Service({\n name: \"llbot\",\n title: \"LLBot\",\n cmd: llbotPath,\n args: [],\n cwd: llbotCwd,\n stopTimeout: 10000,\n autoRestart: false,\n restartDelay: 5000,\n // official \u6216\u672A\u542F\u7528\u65F6\u771F\u6B63 skip\uFF0C\u4E0D throw\n optional: !useLlbotBackend || !llbotEnabled,\n validate: () => {\n if (!useLlbotBackend) return \"LLBot skipped (qq_backend!=llbot)\";\n if (!llbotEnabled) return \"LLBot disabled (llbot.enabled=false)\";\n if (!fs.existsSync(llbotPath)) return `not found: ${llbotPath}`;\n return null;\n },\n }),\n };\n}\n\nexport let services: Record<ServiceName, Service> = createServices();\n\nexport function refreshServices(): void {\n forceStopAll();\n services = createServices();\n}\n\nexport const START_ORDER: ServiceName[] = [\"db\", \"tunnel\", \"qq\", \"llbot\", \"bds\"];\n\nexport async function startAll(): Promise<StartAllResult> {\n const result: StartAllResult = { started: [], skipped: [], failed: [] };\n for (const name of START_ORDER) {\n const svc = services[name];\n if (!svc) continue;\n try {\n const outcome = await svc.start();\n if (outcome.status === \"skipped\") {\n result.skipped.push({ name, reason: outcome.reason });\n svc.events.emit(\"output\", `skipped: ${outcome.reason}`, \"info\");\n } else {\n result.started.push(name);\n }\n } catch (e) {\n const reason = (e as Error).message;\n result.failed.push({ name, reason });\n svc.events.emit(\"output\", `start error: ${reason}`, \"error\");\n }\n }\n return result;\n}\n\n/**\n * \u6309\u542F\u52A8\u9006\u5E8F\u505C\u6B62\u672C\u8FDB\u7A0B\u62C9\u8D77\u7684\u6258\u7BA1\u5B50\u8FDB\u7A0B\uFF08\u4F18\u96C5 stop / stdin stop\uFF09\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A`stop all`\u3001`restart -all`\u3001\u5B88\u62A4\u8FDB\u7A0B shutdown / SIGTERM\u3002\n * \u663E\u5F0F\u4F20 external false\uFF1A\u4E0D\u6309\u955C\u50CF\u540D\u6216\u811A\u672C\u540D\u6740\u5916\u90E8 BDS / db / qq\u3002\n */\nexport async function stopAll(): Promise<void> {\n const pending = [...START_ORDER]\n .reverse()\n .map((name) => services[name])\n .filter((service): service is Service => Boolean(service))\n .map((service) => service.stop(false));\n await Promise.allSettled(pending);\n}\n\nexport function forceStopAll(): void {\n for (const service of Object.values(services)) service.forceStop();\n}\n\nexport type ServiceStateEvent = { name: ServiceName; running: boolean; pid: number };\n\n/** \u8BA2\u9605\u4EFB\u610F\u670D\u52A1\u542F\u505C\uFF08\u542B\u63A2\u6D4B\u56DE\u5199\uFF09\uFF1B\u8FD4\u56DE\u53D6\u6D88\u51FD\u6570 */\nexport function onServiceStateChange(fn: (ev: ServiceStateEvent) => void): () => void {\n /* CLI \u8FDB\u7A0B\u4E0D\u6301\u6709 Service \u5B50\u8FDB\u7A0B\uFF1A\u6539\u8BA2\u5B88\u62A4\u8FDB\u7A0B\u63A8\u9001\u7684\u8FDC\u7A0B\u72B6\u6001\u4E8B\u4EF6 */\n if (!isDaemonServer()) {\n return onRemoteServiceStateChange(fn);\n }\n const handler = (ev: ServiceStateEvent): void => {\n fn(ev);\n };\n for (const service of Object.values(services)) {\n service.events.on(\"state\", handler);\n }\n return () => {\n for (const service of Object.values(services)) {\n service.events.off(\"state\", handler);\n }\n };\n}\n\n/** \u82E5\u672C\u5730\u6807\u8BB0 running \u4F46 OS \u8FDB\u7A0B\u5DF2\u6B7B\uFF0C\u56DE\u6536\u5185\u5B58\u6807\u5FD7 */\nasync function reconcileManagedAlive(service: Service): Promise<boolean> {\n if (!service.running) return false;\n if (service.pid > 0 && !(await isProcessAlive(service.pid))) {\n service.markStoppedFromProbe();\n return false;\n }\n return service.running;\n}\n\n/**\n * \u7EDF\u4E00\u8FD0\u884C\u6001\u67E5\u8BE2\uFF08\u6743\u5A01\u5165\u53E3\uFF09\uFF1AOS/\u5065\u5EB7\u63A2\u6D4B + \u56DE\u5199 Service \u5185\u5B58\u6807\u5FD7\u3002\n * status / Tab \u53D1\u9001\u76EE\u6807 / reload \u7B49\u5747\u5E94\u8D70\u6B64\u63A5\u53E3\uFF0C\u52FF\u76F4\u63A5\u8BFB `service.running`\u3002\n * CLI \u8FDB\u7A0B\u7ECF\u5B88\u62A4\u8FDB\u7A0B RPC \u83B7\u53D6\uFF1B\u5B88\u62A4\u8FDB\u7A0B\u5185\u8D70\u672C\u5730\u63A2\u6D3B\u3002\n */\nexport async function queryServicesRuntime(): Promise<ServiceStatus[]> {\n if (!isDaemonServer()) {\n const { queryRuntimeViaDaemon } = await import(\"./daemon/client.js\");\n return queryRuntimeViaDaemon();\n }\n return queryServicesRuntimeLocal();\n}\n\n/** \u5B88\u62A4\u8FDB\u7A0B\u5185\u672C\u5730\u63A2\u6D3B\u5B9E\u73B0\uFF08\u4EA6\u4F9B server status \u7EC4\u88C5 rows\uFF09 */\nexport async function queryServicesRuntimeLocal(): Promise<ServiceStatus[]> {\n return Promise.all(\n SERVICE_NAMES.map(async (name) => {\n const service = services[name];\n let running = false;\n let pid = 0;\n let uptime = \"\u2014\";\n let ownership: \"managed\" | \"external\" | undefined;\n\n if (name === \"bds\") {\n const probe = await probeBdsStatus({\n managedPid: service.pid,\n hasStdin: Boolean(service.proc?.stdin),\n rootDir: ROOT,\n });\n if (probe.state === \"managed\") {\n running = true;\n pid = probe.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n /* \u63A2\u6D4B\u4E3A managed \u4F46\u672C\u5730\u5DF2\u6807\u505C\uFF1A\u4FDD\u6301\u63A2\u6D4B\u7ED3\u679C\uFF0C\u4E0D\u5F3A\u5236\u6539\u5185\u5B58\uFF08stdin \u4ECD\u53EF\u7528\uFF09 */\n } else if (probe.state === \"external\") {\n running = true;\n pid = probe.pid;\n ownership = \"external\";\n /* \u5916\u90E8\u8FDB\u7A0B\uFF1A\u672C\u5730 managed \u53E5\u67C4\u5DF2\u5931\u6548\u5219\u56DE\u6536 */\n if (service.running && service.pid !== probe.pid) {\n service.markStoppedFromProbe();\n } else if (service.running && !(await isProcessAlive(service.pid))) {\n service.markStoppedFromProbe();\n }\n } else {\n running = false;\n if (service.running || service.proc) {\n service.markStoppedFromProbe();\n }\n }\n } else if (name === \"db\") {\n const managed = await reconcileManagedAlive(service);\n if (managed) {\n running = true;\n pid = service.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n } else if (await probeDbHealth(dbHealthPort)) {\n running = true;\n ownership = \"external\";\n const pids = await findNodeServicePids(\"db\");\n pid = pids[0] ?? 0;\n }\n } else if (name === \"qq\") {\n const managed = await reconcileManagedAlive(service);\n if (managed) {\n running = true;\n pid = service.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n } else {\n const probe = await probeQqRuntime();\n if (probe.alive) {\n running = true;\n pid = probe.pid;\n ownership = \"external\";\n } else {\n const pids = await findNodeServicePids(\"qq\");\n if (pids.length > 0) {\n running = true;\n pid = pids[0]!;\n ownership = \"external\";\n }\n }\n }\n } else if (name === \"tunnel\") {\n const managed = await reconcileManagedAlive(service);\n if (managed) {\n running = true;\n pid = service.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n } else {\n pid = await probeTunnelRuntime();\n running = pid > 0;\n if (running) ownership = \"external\";\n }\n } else {\n const managed = await reconcileManagedAlive(service);\n if (managed) {\n running = true;\n pid = service.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n }\n }\n\n return {\n name,\n title: service.title,\n running,\n pid,\n uptime,\n ...(ownership ? { ownership } : {}),\n };\n })\n );\n}\n\n/** \u5355\u670D\u52A1\u662F\u5426\u5728\u8DD1\uFF08\u542B\u5916\u90E8\u5B9E\u4F8B\uFF09 */\nexport async function isServiceRunning(name: ServiceName): Promise<boolean> {\n const rows = await queryServicesRuntime();\n return rows.some((r) => r.name === name && r.running);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["ROOT"]
|
|
7
7
|
}
|
package/dist/wizard.js
CHANGED
|
@@ -71,7 +71,7 @@ async function prepareRuntimeAssets(rootDir) {
|
|
|
71
71
|
seedNpmRuntimeLayout(rootDir);
|
|
72
72
|
}
|
|
73
73
|
function seedNpmRuntimeLayout(rootDir) {
|
|
74
|
-
ensureCoreConfigs(rootDir, ["db_config", "qq_config", "bds_updater", "permissions"]);
|
|
74
|
+
ensureCoreConfigs(rootDir, ["db_config", "qq_config", "bds_updater", "permissions", "qq_link"]);
|
|
75
75
|
if (path.resolve(rootDir) === path.resolve(ROOT)) {
|
|
76
76
|
ensurePackUpdateConfigFile();
|
|
77
77
|
void import("./module-update/index.js").then((mod) => mod.ensureModuleUpdateConfigFile()).catch(() => {
|
package/dist/wizard.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/wizard.ts"],
|
|
4
|
-
"sourcesContent": ["import { confirm, intro, isCancel, multiselect, note, outro, password, select, spinner, tasks, text } from \"@clack/prompts\";\nimport {\n configPath,\n ensureCoreConfigs,\n modulePath,\n patchJson as patchConfig,\n readJson,\n withConfigSchema,\n writeJson,\n type Catalog,\n type ConfigName,\n type ModuleLock,\n type QQBridgeConfig,\n} from \"@sfmc-bds/sdk/node/config\";\nimport { bdsExePath } from \"@sfmc-bds/bds-tools/host-platform\";\nimport { execFileSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { ensureDirectory, pickDirectory } from \"./interactive-prompts.js\";\nimport { persistLocale, t, type Locale } from \"./i18n/index.js\";\nimport { llbotExeName } from \"./llbot-launch.js\";\nimport { ROOT, isMonorepoLayout, isRuntimeInitialized, resolveFetchModule, spawnService } from \"./runtime.js\";\nimport { ensurePackUpdateConfigFile } from \"./pack-update/index.js\";\nimport { resolveRegistryIndex } from \"./registry.js\";\nimport { c } from \"./theme.js\";\n\n/** Shallow-merge write for top-level configs. Delegates to SDK; do not mkdir+writeFileSync here. */\nfunction patchJson<T extends object>(rootDir: string, name: ConfigName, updates: Partial<T>): void {\n patchConfig<T>(configPath(rootDir, name), updates);\n}\n\nasync function waitForHealth(port: number, ms = 15000): Promise<boolean> {\n const t = Date.now();\n while (Date.now() - t < ms) {\n try {\n if ((await fetch(`http://127.0.0.1:${port}/api/health`)).ok) return true;\n } catch {\n /* retry */\n }\n await new Promise((r) => setTimeout(r, 300));\n }\n return false;\n}\n\n/** \u8FD0\u884C\u65F6\u5FC5\u9700\u76EE\u5F55\u63A2\u6D4B(configs / modules) */\nconst RUNTIME_DIRS = [\n { target: \"configs\", npmTarget: \"configs\" },\n { target: \"modules\", npmTarget: \"modules\" },\n] as const;\n\nfunction missingRuntimeAssets(rootDir: string): string[] {\n return RUNTIME_DIRS.flatMap(({ target, npmTarget }) => {\n const directory = path.join(rootDir, npmTarget);\n try {\n return fs.statSync(directory).isDirectory() && fs.readdirSync(directory).length > 0 ? [] : [target];\n } catch {\n return [target];\n }\n });\n}\n\nasync function runBdsUpdate(rootDir: string, channel: string): Promise<{ code: number | null; output: string }> {\n const child = spawnService(\"update\", [`--channel=${channel}`, \"--force\", \"--no-start\"], {\n cwd: rootDir,\n stdio: \"pipe\",\n });\n const output: string[] = [];\n child.stdout?.on(\"data\", (data: Buffer) => output.push(data.toString()));\n child.stderr?.on(\"data\", (data: Buffer) => output.push(data.toString()));\n\n return new Promise((resolve) => {\n child.once(\"error\", (error) => resolve({ code: null, output: `${output.join(\"\")}${error.message}` }));\n child.once(\"close\", (code) => resolve({ code, output: output.join(\"\") }));\n });\n}\n\nasync function prepareRuntimeAssets(rootDir: string): Promise<void> {\n /* monorepo \u5E03\u5C40\uFF1Aconfigs/ modules/ \u5E94\u7531 pnpm workspace \u63D0\u4F9B */\n if (isMonorepoLayout(rootDir)) {\n const missing = missingRuntimeAssets(rootDir);\n if (missing.length > 0) {\n throw new Error(t(\"wizard.runtimeMissingAssets\", { list: missing.join(\", \") }));\n }\n return;\n }\n\n seedNpmRuntimeLayout(rootDir);\n}\n\n/** \u975E monorepo \u7684 npm \u5B89\u88C5\u5E03\u5C40\uFF1Aensure \u914D\u7F6E\u9AA8\u67B6 + \u7A7A modules */\nfunction seedNpmRuntimeLayout(rootDir: string): void {\n ensureCoreConfigs(rootDir, [\"db_config\", \"qq_config\", \"bds_updater\", \"permissions\"]);\n /* pack-update \u7684 ensure \u4F7F\u7528 runtime ROOT\uFF1Bnpm \u5E03\u5C40\u4E0B\u5E94\u4E0E rootDir \u4E00\u81F4 */\n if (path.resolve(rootDir) === path.resolve(ROOT)) {\n ensurePackUpdateConfigFile();\n void import(\"./module-update/index.js\")\n .then((mod) => mod.ensureModuleUpdateConfigFile())\n .catch(() => {\n /* \u7B56\u7565\u6587\u4EF6\u7A0D\u540E\u5728 mod update / \u5F00\u670D\u65F6\u8FD8\u4F1A\u518D\u786E\u4FDD\u4E00\u6B21 */\n });\n }\n\n const modulesRoot = path.join(rootDir, \"modules\");\n const packagesDir = path.join(modulesRoot, \"packages\");\n fs.mkdirSync(packagesDir, { recursive: true });\n\n const catalogPath = path.join(modulesRoot, \"catalog.json\");\n if (!fs.existsSync(catalogPath)) {\n writeJson(\n catalogPath,\n withConfigSchema({ version: 1, modules: [] }, \"module_catalog\", \"modules\")\n );\n }\n const lockPath = path.join(modulesRoot, \"module-lock.json\");\n if (!fs.existsSync(lockPath)) {\n writeJson(lockPath, { version: 1, modules: {} });\n }\n}\n\n/** \u66F4\u65B0\u65F6\u9ED8\u8BA4\u4FDD\u7559\u7684 BDS \u6587\u4EF6\uFF0C\u4E0E\u9010\u9879\u8BE2\u95EE\u65F6\u7684\u521D\u59CB\u52FE\u9009\u76F8\u540C\u3002 */\nconst DEFAULT_PRESERVE = [\n \"server.properties\",\n \"whitelist.json\",\n \"permissions.json\",\n \"allowlist.json\",\n \"worlds\",\n \"config\",\n] as const;\n\n/** \u5411\u5BFC\u5199\u8FDB db / bds_updater \u7684\u8DEF\u5F84\u4E0E\u7AEF\u53E3\u3002 */\ninterface RuntimeLayout {\n dbDir: string;\n dbPort: number;\n backupDir: string;\n preserve: string[];\n}\n\n/** \u5411\u5BFC\u6536\u96C6\u7684 QQ \u6865\u9009\u62E9\u3002\u53D6\u6D88\u9009\u62E9\u65F6\u4E0D\u4EA7\u751F\u8BE5\u5BF9\u8C61\u3002 */\ninterface QqWizardChoice {\n qqEnabled: boolean;\n qqBackend: \"official\" | \"llbot\";\n qqAppId: string;\n qqAppSecret: string;\n qqSandbox: boolean;\n qqGroupOpenid: string;\n llbotPath?: string;\n llbotEnabled: boolean;\n}\n\n/**\n * \u6570\u636E\u5E93\u3001\u5907\u4EFD\u76EE\u5F55\u548C\u66F4\u65B0\u4FDD\u7559\u9879\u3002\n * \u63A5\u53D7\u9ED8\u8BA4\u503C\u65F6\u4E0D\u518D\u9010\u9879\u63D0\u95EE\uFF1B\u62D2\u7EDD\u540E\u4ECD\u8BE2\u95EE\u76EE\u5F55\u3001\u7AEF\u53E3\u548C\u4FDD\u7559\u9879\u3002\u53D6\u6D88\u5355\u9879\u65F6\u6CBF\u7528\u8BE5\u9879\u9ED8\u8BA4\u3002\n */\nasync function askRuntimeLayout(rootDir: string, bdsResolved: string): Promise<RuntimeLayout> {\n const defaultDbDir = path.join(rootDir, \"data\");\n const defaultBackup = path.join(path.dirname(bdsResolved), \"backups\");\n const useDefaults = await confirm({\n message: t(\"wizard.useDefaults\"),\n initialValue: true,\n });\n if (isCancel(useDefaults) || useDefaults) {\n ensureDirectory(defaultDbDir);\n note(\n c.text(\n t(\"wizard.defaultsApplied\", {\n db: defaultDbDir,\n port: \"3001\",\n backup: defaultBackup,\n })\n ),\n t(\"common.tips\")\n );\n note(c.yellow(t(\"wizard.updaterTip\")), t(\"common.tips\"));\n return {\n dbDir: defaultDbDir,\n dbPort: 3001,\n backupDir: defaultBackup,\n preserve: [...DEFAULT_PRESERVE],\n };\n }\n\n const dbDirInput = await pickDirectory(t(\"wizard.dbDir\"), defaultDbDir);\n const dbDir = ensureDirectory(dbDirInput) ? dbDirInput : defaultDbDir;\n if (dbDir !== dbDirInput) {\n note(c.text(t(\"wizard.usingDefault\", { path: dbDir })), t(\"common.tips\"));\n }\n const dbPortRaw = await text({\n message: t(\"wizard.dbPort\"),\n initialValue: \"3001\",\n validate: (v: any): any => {\n const n = parseInt(v, 10);\n if (isNaN(n) || n < 1024 || n > 65535) return t(\"wizard.portRange\");\n if (v.length === 0) return t(\"wizard.valueRequired\");\n },\n });\n const dbPort = isCancel(dbPortRaw) ? 3001 : parseInt(dbPortRaw as string, 10);\n const backupDir = await pickDirectory(t(\"wizard.backupDir\"), defaultBackup);\n const preserveOptions = [\n { value: \"server.properties\", label: \"server.properties\", hint: t(\"wizard.preserve.serverProps\") },\n { value: \"whitelist.json\", label: \"whitelist.json\" },\n { value: \"permissions.json\", label: \"permissions.json\" },\n { value: \"allowlist.json\", label: \"allowlist.json\" },\n { value: \"worlds\", label: \"worlds/\", hint: t(\"wizard.preserve.worlds\") },\n { value: \"config\", label: \"config/\", hint: t(\"wizard.preserve.config\") },\n ] as const;\n const pr = await multiselect({\n message: t(\"wizard.preserve\"),\n options: [...preserveOptions],\n initialValues: [...DEFAULT_PRESERVE],\n required: false,\n });\n note(c.yellow(t(\"wizard.updaterTip\")), t(\"common.tips\"));\n return {\n dbDir,\n dbPort,\n backupDir,\n preserve: isCancel(pr) ? [] : (pr as string[]),\n };\n}\n\n/**\n * \u9009\u62E9 QQ \u6865\u540E\u7AEF\u3002\u9ED8\u8BA4\u4E0D\u542F\u7528\u3002\n * \u53D6\u6D88\u65F6\u8FD4\u56DE null\uFF0C\u8C03\u7528\u65B9\u7ED3\u675F\u5411\u5BFC\u4E14\u4E0D\u5199\u5165 initialized_at\u3002\n */\nasync function askQqBridge(rootDir: string): Promise<QqWizardChoice | null> {\n const qqBackendPick = await select({\n message: t(\"wizard.qqBackend\"),\n options: [\n { value: \"disabled\", label: t(\"wizard.qqBackend.disabled\"), hint: t(\"wizard.qqBackend.disabledHint\") },\n { value: \"official\", label: t(\"wizard.qqBackend.official\"), hint: t(\"wizard.qqBackend.officialHint\") },\n { value: \"llbot\", label: t(\"wizard.qqBackend.llbot\"), hint: t(\"wizard.qqBackend.llbotHint\") },\n ],\n initialValue: \"disabled\",\n });\n if (isCancel(qqBackendPick)) return null;\n\n const qqBackendChoice = String(qqBackendPick || \"disabled\");\n if (qqBackendChoice === \"disabled\") {\n return {\n qqEnabled: false,\n qqBackend: \"official\",\n qqAppId: \"\",\n qqAppSecret: \"\",\n qqSandbox: false,\n qqGroupOpenid: \"\",\n llbotEnabled: false,\n };\n }\n if (qqBackendChoice === \"llbot\") {\n const picked = await pickDirectory(t(\"wizard.llbotDir\"), path.join(rootDir, \"LLBOT\"));\n let llbotPath = picked;\n if (!ensureDirectory(picked)) {\n llbotPath = path.join(rootDir, \"LLBOT\");\n note(c.text(t(\"wizard.usingDefault\", { path: llbotPath })), t(\"common.tips\"));\n }\n return {\n qqEnabled: true,\n qqBackend: \"llbot\",\n qqAppId: \"\",\n qqAppSecret: \"\",\n qqSandbox: false,\n qqGroupOpenid: \"\",\n llbotPath,\n llbotEnabled: true,\n };\n }\n\n const appIdRaw = await text({\n message: t(\"wizard.qqAppId\"),\n placeholder: \"102xxxxx\",\n validate: (v: any): any => {\n if (!String(v ?? \"\").trim()) return t(\"wizard.valueRequired\");\n },\n });\n const secretRaw = await password({\n message: t(\"wizard.qqAppSecret\"),\n validate: (v: any): any => {\n if (!String(v ?? \"\").trim()) return t(\"wizard.valueRequired\");\n },\n });\n const sandboxPick = await confirm({\n message: t(\"wizard.qqSandbox\"),\n initialValue: false,\n });\n const openidRaw = await text({\n message: t(\"wizard.qqGroupOpenid\"),\n placeholder: t(\"wizard.qqGroupOpenidHint\"),\n });\n return {\n qqEnabled: true,\n qqBackend: \"official\",\n qqAppId: isCancel(appIdRaw) ? \"\" : String(appIdRaw).trim(),\n qqAppSecret: isCancel(secretRaw) ? \"\" : String(secretRaw).trim(),\n qqSandbox: isCancel(sandboxPick) ? false : !!sandboxPick,\n qqGroupOpenid: isCancel(openidRaw) ? \"\" : String(openidRaw).trim(),\n llbotEnabled: false,\n };\n}\n\n/**\n * \u9009\u62E9\u8981\u542F\u7528\u6216\u5B89\u88C5\u7684\u6A21\u5757\u3002\n * \u76EE\u5F55\u91CC\u5DF2\u6709\u6A21\u5757\u65F6\u53EA\u95EE\u542F\u505C\uFF1B\u7A7A\u76EE\u5F55\u624D\u8BFB\u5B98\u65B9\u7D22\u5F15\uFF0C\u907F\u514D\u628A\u542F\u7528\u548C\u5B89\u88C5\u6DF7\u6210\u540C\u4E00\u6B21\u9009\u62E9\u3002\n */\nasync function askModules(rootDir: string): Promise<string[]> {\n const catalog = readJson<Catalog>(modulePath(rootDir, \"catalog.json\")) ?? {\n version: 1,\n modules: [],\n };\n const catalogModules: Array<{ id: string; name?: string; description?: string; canDisable?: boolean }> = [];\n if (Array.isArray(catalog.modules)) {\n for (const m of catalog.modules) {\n catalogModules.push({\n id: String(m.id ?? \"\"),\n name: String(m.name ?? m.id ?? \"\"),\n description: String(m.description ?? \"\"),\n canDisable: m.canDisable !== false,\n });\n }\n }\n\n if (catalogModules.length > 0) {\n note(c.text(t(\"wizard.modulesFound\", { count: catalogModules.length })), t(\"wizard.step4\"));\n const lockedMd: Array<{ value: string; label: string; hint: string; disabled?: boolean }> = [];\n const optionalMd: Array<{ value: string; label: string; hint: string }> = [];\n for (const k of catalogModules) {\n const option = {\n value: k.id,\n label: String(k.name),\n hint: String(k.description ?? t(\"wizard.emptyHint\")),\n };\n if (k.canDisable === false) lockedMd.push({ ...option, disabled: true });\n else optionalMd.push(option);\n }\n const picked = await multiselect({\n message: t(\"wizard.enableModules\"),\n options: [...lockedMd, ...optionalMd],\n required: false,\n });\n return isCancel(picked) ? [] : (picked as string[]);\n }\n\n note(c.text(t(\"wizard.modulesNone\")), t(\"wizard.step4\"));\n const spin = spinner();\n spin.start(t(\"wizard.registryLoading\"));\n const { index } = await resolveRegistryIndex();\n const ids = Object.keys(index).sort((a, b) => a.localeCompare(b));\n if (ids.length === 0) {\n spin.stop(t(\"wizard.registryOffline\"));\n return [];\n }\n spin.stop(t(\"wizard.modulesFound\", { count: String(ids.length) }));\n const picked = await multiselect({\n message: t(\"wizard.installFromRegistry\"),\n options: ids.map((id) => ({ value: id, label: id })),\n required: false,\n });\n return isCancel(picked) ? [] : (picked as string[]);\n}\n\nexport async function runWizard(): Promise<void> {\n intro(c.bold(t(\"wizard.intro\")));\n\n const langPick = await select({\n message: t(\"locale.wizard\"),\n options: [\n { value: \"zh-CN\", label: t(\"locale.opt.zh\") },\n { value: \"en\", label: t(\"locale.opt.en\") },\n ],\n initialValue: \"zh-CN\",\n });\n if (!isCancel(langPick)) {\n persistLocale(ROOT, langPick as Locale);\n }\n\n // Already initialized only when runtime.json#initialized_at is set (empty db_config skeleton does not count).\n if (isRuntimeInitialized()) {\n const r = await confirm({ message: t(\"wizard.rerun\"), initialValue: false });\n if (isCancel(r) || !r) {\n outro(c.dim(t(\"wizard.skipped\")));\n return;\n }\n }\n // Step 1: Runtime Environment\uFF08\u53EA\u64AD\u79CD configs/modules\uFF0C\u4E0D\u5199 initialized_at\u3001\u4E0D\u5EFA data/\uFF09\n const rootDir = ROOT;\n note(c.text(t(\"wizard.runtimeRoot\", { root: rootDir })), t(\"wizard.step1\"));\n\n try {\n await prepareRuntimeAssets(rootDir);\n } catch (error) {\n outro(c.red(t(\"wizard.prepFailed\", { message: (error as Error).message })));\n return;\n }\n\n // Step 2: BDS \u76EE\u5F55\u3002\u6570\u636E\u5E93\u548C QQ \u653E\u5230\u540E\u9762\uFF0C\u80FD\u7528\u9ED8\u8BA4\u503C\u5C31\u4E0D\u518D\u9010\u9879\u95EE\u3002\n note(c.text(t(\"wizard.step2Note\")), t(\"wizard.step2\"));\n\n const bdsResolved = await pickDirectory(t(\"wizard.bdsDir\"), path.join(rootDir, \"BDS\"));\n if (!ensureDirectory(bdsResolved)) {\n outro(c.red(t(\"wizard.cannotCreateBds\", { dir: bdsResolved })));\n return;\n }\n\n // Step 3: \u5148\u786E\u8BA4\u53EF\u6267\u884C\u6587\u4EF6\u548C EULA\uFF0C\u518D\u51B3\u5B9A\u8981\u4E0D\u8981\u4E0B\u8F7D\u3002\n const bdsExe = bdsExePath(bdsResolved);\n const bdsExists = fs.existsSync(bdsExe);\n\n note(\n bdsExists\n ? c.green(t(\"wizard.bdsFound\", { path: bdsResolved }))\n : c.yellow(t(\"wizard.bdsNotFound\", { path: bdsResolved })),\n t(\"wizard.step3\")\n );\n\n const EULA = await confirm({\n message: t(\"wizard.eula\"),\n initialValue: false,\n });\n if (isCancel(EULA) || !EULA) {\n outro(c.yellow(t(\"wizard.disagreed\")));\n return;\n }\n\n let downloadBds = false;\n let bdsChannel = \"release\";\n\n if (!bdsExists) {\n const d = await confirm({ message: t(\"wizard.downloadBds\"), initialValue: true });\n if (!isCancel(d) && d) {\n const ch = await select({\n message: t(\"wizard.selectChannel\"),\n options: [\n { value: \"release\", label: t(\"wizard.channel.release\"), hint: t(\"wizard.channel.releaseHint\") },\n { value: \"preview\", label: t(\"wizard.channel.preview\"), hint: t(\"wizard.channel.previewHint\") },\n ],\n initialValue: \"release\",\n });\n if (!isCancel(ch)) {\n bdsChannel = ch as string;\n downloadBds = true;\n }\n }\n }\n\n const { dbDir, dbPort, backupDir, preserve } = await askRuntimeLayout(rootDir, bdsResolved);\n if (downloadBds && !ensureDirectory(backupDir)) {\n outro(c.red(t(\"wizard.cannotCreateBackup\", { dir: backupDir })));\n return;\n }\n\n const qq = await askQqBridge(rootDir);\n if (!qq) {\n outro(c.dim(t(\"wizard.skipped\")));\n return;\n }\n const { qqEnabled, qqBackend, qqAppId, qqAppSecret, qqSandbox, qqGroupOpenid, llbotPath, llbotEnabled } = qq;\n\n const selectedModules = await askModules(rootDir);\n\n const wizardTasks = [\n {\n title: t(\"wizard.updatingConfigs\"),\n task: () => {\n const slashPath = (value: string) => value.replace(/\\\\/g, \"/\");\n patchJson(rootDir, \"db_config.json\", {\n db_port: dbPort,\n dbDir: slashPath(path.relative(rootDir, path.join(dbDir, \"sfmc_data.db\"))),\n modulesDir: \"modules\",\n });\n\n const llbotOn = qqBackend === \"llbot\" && !!llbotEnabled && !!llbotPath;\n const qqNotify = qqEnabled && (qqBackend === \"official\" || llbotOn);\n const exeName = llbotExeName();\n const currentQq = readJson<QQBridgeConfig>(configPath(rootDir, \"qq_config.json\")) ?? {};\n patchJson(rootDir, \"qq_config.json\", {\n qq_enabled: qqEnabled,\n qq_backend: qqBackend,\n official: {\n ...currentQq.official,\n app_id: qqAppId,\n app_secret: qqAppSecret,\n sandbox: qqSandbox,\n group_openid: qqGroupOpenid,\n },\n llbot: {\n ...currentQq.llbot,\n enabled: llbotOn,\n // path = \u53EF\u6267\u884C\u6587\u4EF6\uFF1Bcwd = \u8FD0\u884C\u76EE\u5F55\uFF08\u5411\u5BFC\u9009\u7684\u662F\u76EE\u5F55\uFF09\n path: llbotPath ? slashPath(path.join(llbotPath, exeName)) : \"\",\n cwd: llbotPath ? slashPath(llbotPath) : \"\",\n },\n });\n patchJson(rootDir, \"bds_updater.json\", {\n bds_path: slashPath(bdsResolved),\n channel: bdsChannel,\n backup_dir: slashPath(backupDir),\n preserve,\n qq_notify: qqNotify,\n });\n /* \u8DEF\u5F84\u9009\u5B9A\u540E\u518D\u6807\u8BB0\u5DF2\u521D\u59CB\u5316\uFF0C\u907F\u514D\u534A\u9014\u53D6\u6D88\u4ECD\u7559\u4E0B data/ \u8BED\u4E49 */\n patchJson(rootDir, \"runtime.json\", {\n runtime_root: rootDir,\n initialized_at: new Date().toISOString(),\n locale: isCancel(langPick) ? undefined : (langPick as string),\n });\n return t(\"wizard.configsUpdated\");\n },\n },\n {\n title: t(\"wizard.updatingModules\"),\n task: async (): Promise<string> => {\n const lock = readJson<ModuleLock>(modulePath(rootDir, \"module-lock.json\")) ?? {\n version: 1,\n modules: {},\n };\n if (!lock.modules) lock.modules = {};\n const now = Date.now();\n for (const id of selectedModules) lock.modules[id] = { enabled: true, updatedAt: now };\n writeJson(modulePath(rootDir, \"module-lock.json\"), lock);\n return t(\"wizard.modulesUpdated\");\n },\n },\n {\n title: t(\"wizard.initDb\"),\n task: async (): Promise<string> => {\n const child = spawnService(\"db\", [], {\n cwd: rootDir,\n stdio: \"ignore\",\n env: { ...process.env, DB_PORT: String(dbPort) },\n });\n if (!(await waitForHealth(dbPort))) {\n child.kill(\"SIGTERM\");\n return t(\"wizard.dbTimeout\");\n }\n\n /* /api/health \u5728 listen \u4E4B\u540E\u624D\u8FD4\u56DE\uFF0C\u800C\u5EFA\u8868\u53D1\u751F\u5728 listen \u4E4B\u524D\uFF0C\u4E0D\u5FC5\u518D\u7A7A\u7B49\u3002 */\n child.kill(\"SIGTERM\");\n setTimeout(() => child.kill(\"SIGKILL\"), 3000).unref();\n return t(\"wizard.dbOk\");\n },\n },\n ];\n if (downloadBds) {\n wizardTasks.push({\n title: t(\"wizard.downloadingBds\"),\n task: async (): Promise<string> => {\n const result = await runBdsUpdate(rootDir, bdsChannel);\n if (result.code !== 0) {\n return t(\"wizard.downloadFail\");\n }\n return t(\"wizard.bdsDownloaded\");\n },\n });\n }\n try {\n await tasks(wizardTasks);\n } catch (e) {\n outro(c.red(t(\"common.error\", { message: (e as Error).message })));\n return;\n }\n\n /* install \u2192 build \u2192 deploy chain */\n await runInstallBuildDeploy(rootDir, selectedModules, bdsResolved);\n\n outro(c.green(t(\"wizard.done\")));\n}\n\nasync function runInstallBuildDeploy(rootDir: string, selectedModules: string[], bdsResolved: string): Promise<void> {\n if (selectedModules.length > 0) {\n const fetchScript = resolveFetchModule();\n if (fetchScript) {\n const installT = [\n {\n title: t(\"wizard.installing\", { count: selectedModules.length }),\n task: async (): Promise<string> => {\n /* \u5411\u5BFC\u91CC\u52FE\u9009\u7684\u542F\u505C\u5DF2\u7ECF\u5199\u5165 lock\uFF0C\u5B89\u88C5\u65F6\u4FDD\u7559\uFF0C\u4E0D\u7528\u6E05\u5355\u91CC\u7684\u9ED8\u8BA4\u503C\u8986\u76D6\u3002 */\n execFileSync(process.execPath, [fetchScript, \"install\", ...selectedModules, \"--preserve-lock\"], {\n cwd: rootDir,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, SFMC_ROOT: rootDir },\n });\n return t(\"wizard.installed\", { count: selectedModules.length });\n },\n },\n ];\n try {\n await tasks(installT);\n } catch (e) {\n note(c.yellow(t(\"wizard.installFailed\", { message: (e as Error).message })));\n }\n } else {\n note(c.yellow(t(\"wizard.fetchMissing\", { list: selectedModules.join(\", \") })));\n }\n } else {\n note(c.dim(t(\"wizard.noModulesSelected\")));\n }\n\n const { cmdBehaviorPackBuild, cmdBehaviorPackDeploy } = await import(\"./commands-behavior-pack.js\");\n const buildT = [\n {\n title: t(\"wizard.buildingBp\"),\n task: async (): Promise<string> => {\n const r = await cmdBehaviorPackBuild([]);\n if (!r.ok) throw new Error(r.message);\n return r.message;\n },\n },\n ];\n try {\n await tasks(buildT);\n } catch (e) {\n note(c.yellow(t(\"wizard.buildFailed\", { message: (e as Error).message })));\n return;\n }\n\n const deployT = [\n {\n title: t(\"wizard.deploying\", { path: bdsResolved }),\n task: async (): Promise<string> => {\n const r = await cmdBehaviorPackDeploy([]);\n if (!r.ok) throw new Error(r.message);\n return r.message;\n },\n },\n ];\n try {\n await tasks(deployT);\n note(c.green(t(\"wizard.restartBds\")));\n } catch (e) {\n note(c.yellow(t(\"wizard.deployFailed\", { message: (e as Error).message })));\n }\n void rootDir;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { confirm, intro, isCancel, multiselect, note, outro, password, select, spinner, tasks, text } from \"@clack/prompts\";\nimport {\n configPath,\n ensureCoreConfigs,\n modulePath,\n patchJson as patchConfig,\n readJson,\n withConfigSchema,\n writeJson,\n type Catalog,\n type ConfigName,\n type ModuleLock,\n type QQBridgeConfig,\n} from \"@sfmc-bds/sdk/node/config\";\nimport { bdsExePath } from \"@sfmc-bds/bds-tools/host-platform\";\nimport { execFileSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { ensureDirectory, pickDirectory } from \"./interactive-prompts.js\";\nimport { persistLocale, t, type Locale } from \"./i18n/index.js\";\nimport { llbotExeName } from \"./llbot-launch.js\";\nimport { ROOT, isMonorepoLayout, isRuntimeInitialized, resolveFetchModule, spawnService } from \"./runtime.js\";\nimport { ensurePackUpdateConfigFile } from \"./pack-update/index.js\";\nimport { resolveRegistryIndex } from \"./registry.js\";\nimport { c } from \"./theme.js\";\n\n/** Shallow-merge write for top-level configs. Delegates to SDK; do not mkdir+writeFileSync here. */\nfunction patchJson<T extends object>(rootDir: string, name: ConfigName, updates: Partial<T>): void {\n patchConfig<T>(configPath(rootDir, name), updates);\n}\n\nasync function waitForHealth(port: number, ms = 15000): Promise<boolean> {\n const t = Date.now();\n while (Date.now() - t < ms) {\n try {\n if ((await fetch(`http://127.0.0.1:${port}/api/health`)).ok) return true;\n } catch {\n /* retry */\n }\n await new Promise((r) => setTimeout(r, 300));\n }\n return false;\n}\n\n/** \u8FD0\u884C\u65F6\u5FC5\u9700\u76EE\u5F55\u63A2\u6D4B(configs / modules) */\nconst RUNTIME_DIRS = [\n { target: \"configs\", npmTarget: \"configs\" },\n { target: \"modules\", npmTarget: \"modules\" },\n] as const;\n\nfunction missingRuntimeAssets(rootDir: string): string[] {\n return RUNTIME_DIRS.flatMap(({ target, npmTarget }) => {\n const directory = path.join(rootDir, npmTarget);\n try {\n return fs.statSync(directory).isDirectory() && fs.readdirSync(directory).length > 0 ? [] : [target];\n } catch {\n return [target];\n }\n });\n}\n\nasync function runBdsUpdate(rootDir: string, channel: string): Promise<{ code: number | null; output: string }> {\n const child = spawnService(\"update\", [`--channel=${channel}`, \"--force\", \"--no-start\"], {\n cwd: rootDir,\n stdio: \"pipe\",\n });\n const output: string[] = [];\n child.stdout?.on(\"data\", (data: Buffer) => output.push(data.toString()));\n child.stderr?.on(\"data\", (data: Buffer) => output.push(data.toString()));\n\n return new Promise((resolve) => {\n child.once(\"error\", (error) => resolve({ code: null, output: `${output.join(\"\")}${error.message}` }));\n child.once(\"close\", (code) => resolve({ code, output: output.join(\"\") }));\n });\n}\n\nasync function prepareRuntimeAssets(rootDir: string): Promise<void> {\n /* monorepo \u5E03\u5C40\uFF1Aconfigs/ modules/ \u5E94\u7531 pnpm workspace \u63D0\u4F9B */\n if (isMonorepoLayout(rootDir)) {\n const missing = missingRuntimeAssets(rootDir);\n if (missing.length > 0) {\n throw new Error(t(\"wizard.runtimeMissingAssets\", { list: missing.join(\", \") }));\n }\n return;\n }\n\n seedNpmRuntimeLayout(rootDir);\n}\n\n/** \u975E monorepo \u7684 npm \u5B89\u88C5\u5E03\u5C40\uFF1Aensure \u914D\u7F6E\u9AA8\u67B6 + \u7A7A modules */\nfunction seedNpmRuntimeLayout(rootDir: string): void {\n ensureCoreConfigs(rootDir, [\"db_config\", \"qq_config\", \"bds_updater\", \"permissions\", \"qq_link\"]);\n /* pack-update \u7684 ensure \u4F7F\u7528 runtime ROOT\uFF1Bnpm \u5E03\u5C40\u4E0B\u5E94\u4E0E rootDir \u4E00\u81F4 */\n if (path.resolve(rootDir) === path.resolve(ROOT)) {\n ensurePackUpdateConfigFile();\n void import(\"./module-update/index.js\")\n .then((mod) => mod.ensureModuleUpdateConfigFile())\n .catch(() => {\n /* \u7B56\u7565\u6587\u4EF6\u7A0D\u540E\u5728 mod update / \u5F00\u670D\u65F6\u8FD8\u4F1A\u518D\u786E\u4FDD\u4E00\u6B21 */\n });\n }\n\n const modulesRoot = path.join(rootDir, \"modules\");\n const packagesDir = path.join(modulesRoot, \"packages\");\n fs.mkdirSync(packagesDir, { recursive: true });\n\n const catalogPath = path.join(modulesRoot, \"catalog.json\");\n if (!fs.existsSync(catalogPath)) {\n writeJson(\n catalogPath,\n withConfigSchema({ version: 1, modules: [] }, \"module_catalog\", \"modules\")\n );\n }\n const lockPath = path.join(modulesRoot, \"module-lock.json\");\n if (!fs.existsSync(lockPath)) {\n writeJson(lockPath, { version: 1, modules: {} });\n }\n}\n\n/** \u66F4\u65B0\u65F6\u9ED8\u8BA4\u4FDD\u7559\u7684 BDS \u6587\u4EF6\uFF0C\u4E0E\u9010\u9879\u8BE2\u95EE\u65F6\u7684\u521D\u59CB\u52FE\u9009\u76F8\u540C\u3002 */\nconst DEFAULT_PRESERVE = [\n \"server.properties\",\n \"whitelist.json\",\n \"permissions.json\",\n \"allowlist.json\",\n \"worlds\",\n \"config\",\n] as const;\n\n/** \u5411\u5BFC\u5199\u8FDB db / bds_updater \u7684\u8DEF\u5F84\u4E0E\u7AEF\u53E3\u3002 */\ninterface RuntimeLayout {\n dbDir: string;\n dbPort: number;\n backupDir: string;\n preserve: string[];\n}\n\n/** \u5411\u5BFC\u6536\u96C6\u7684 QQ \u6865\u9009\u62E9\u3002\u53D6\u6D88\u9009\u62E9\u65F6\u4E0D\u4EA7\u751F\u8BE5\u5BF9\u8C61\u3002 */\ninterface QqWizardChoice {\n qqEnabled: boolean;\n qqBackend: \"official\" | \"llbot\";\n qqAppId: string;\n qqAppSecret: string;\n qqSandbox: boolean;\n qqGroupOpenid: string;\n llbotPath?: string;\n llbotEnabled: boolean;\n}\n\n/**\n * \u6570\u636E\u5E93\u3001\u5907\u4EFD\u76EE\u5F55\u548C\u66F4\u65B0\u4FDD\u7559\u9879\u3002\n * \u63A5\u53D7\u9ED8\u8BA4\u503C\u65F6\u4E0D\u518D\u9010\u9879\u63D0\u95EE\uFF1B\u62D2\u7EDD\u540E\u4ECD\u8BE2\u95EE\u76EE\u5F55\u3001\u7AEF\u53E3\u548C\u4FDD\u7559\u9879\u3002\u53D6\u6D88\u5355\u9879\u65F6\u6CBF\u7528\u8BE5\u9879\u9ED8\u8BA4\u3002\n */\nasync function askRuntimeLayout(rootDir: string, bdsResolved: string): Promise<RuntimeLayout> {\n const defaultDbDir = path.join(rootDir, \"data\");\n const defaultBackup = path.join(path.dirname(bdsResolved), \"backups\");\n const useDefaults = await confirm({\n message: t(\"wizard.useDefaults\"),\n initialValue: true,\n });\n if (isCancel(useDefaults) || useDefaults) {\n ensureDirectory(defaultDbDir);\n note(\n c.text(\n t(\"wizard.defaultsApplied\", {\n db: defaultDbDir,\n port: \"3001\",\n backup: defaultBackup,\n })\n ),\n t(\"common.tips\")\n );\n note(c.yellow(t(\"wizard.updaterTip\")), t(\"common.tips\"));\n return {\n dbDir: defaultDbDir,\n dbPort: 3001,\n backupDir: defaultBackup,\n preserve: [...DEFAULT_PRESERVE],\n };\n }\n\n const dbDirInput = await pickDirectory(t(\"wizard.dbDir\"), defaultDbDir);\n const dbDir = ensureDirectory(dbDirInput) ? dbDirInput : defaultDbDir;\n if (dbDir !== dbDirInput) {\n note(c.text(t(\"wizard.usingDefault\", { path: dbDir })), t(\"common.tips\"));\n }\n const dbPortRaw = await text({\n message: t(\"wizard.dbPort\"),\n initialValue: \"3001\",\n validate: (v: any): any => {\n const n = parseInt(v, 10);\n if (isNaN(n) || n < 1024 || n > 65535) return t(\"wizard.portRange\");\n if (v.length === 0) return t(\"wizard.valueRequired\");\n },\n });\n const dbPort = isCancel(dbPortRaw) ? 3001 : parseInt(dbPortRaw as string, 10);\n const backupDir = await pickDirectory(t(\"wizard.backupDir\"), defaultBackup);\n const preserveOptions = [\n { value: \"server.properties\", label: \"server.properties\", hint: t(\"wizard.preserve.serverProps\") },\n { value: \"whitelist.json\", label: \"whitelist.json\" },\n { value: \"permissions.json\", label: \"permissions.json\" },\n { value: \"allowlist.json\", label: \"allowlist.json\" },\n { value: \"worlds\", label: \"worlds/\", hint: t(\"wizard.preserve.worlds\") },\n { value: \"config\", label: \"config/\", hint: t(\"wizard.preserve.config\") },\n ] as const;\n const pr = await multiselect({\n message: t(\"wizard.preserve\"),\n options: [...preserveOptions],\n initialValues: [...DEFAULT_PRESERVE],\n required: false,\n });\n note(c.yellow(t(\"wizard.updaterTip\")), t(\"common.tips\"));\n return {\n dbDir,\n dbPort,\n backupDir,\n preserve: isCancel(pr) ? [] : (pr as string[]),\n };\n}\n\n/**\n * \u9009\u62E9 QQ \u6865\u540E\u7AEF\u3002\u9ED8\u8BA4\u4E0D\u542F\u7528\u3002\n * \u53D6\u6D88\u65F6\u8FD4\u56DE null\uFF0C\u8C03\u7528\u65B9\u7ED3\u675F\u5411\u5BFC\u4E14\u4E0D\u5199\u5165 initialized_at\u3002\n */\nasync function askQqBridge(rootDir: string): Promise<QqWizardChoice | null> {\n const qqBackendPick = await select({\n message: t(\"wizard.qqBackend\"),\n options: [\n { value: \"disabled\", label: t(\"wizard.qqBackend.disabled\"), hint: t(\"wizard.qqBackend.disabledHint\") },\n { value: \"official\", label: t(\"wizard.qqBackend.official\"), hint: t(\"wizard.qqBackend.officialHint\") },\n { value: \"llbot\", label: t(\"wizard.qqBackend.llbot\"), hint: t(\"wizard.qqBackend.llbotHint\") },\n ],\n initialValue: \"disabled\",\n });\n if (isCancel(qqBackendPick)) return null;\n\n const qqBackendChoice = String(qqBackendPick || \"disabled\");\n if (qqBackendChoice === \"disabled\") {\n return {\n qqEnabled: false,\n qqBackend: \"official\",\n qqAppId: \"\",\n qqAppSecret: \"\",\n qqSandbox: false,\n qqGroupOpenid: \"\",\n llbotEnabled: false,\n };\n }\n if (qqBackendChoice === \"llbot\") {\n const picked = await pickDirectory(t(\"wizard.llbotDir\"), path.join(rootDir, \"LLBOT\"));\n let llbotPath = picked;\n if (!ensureDirectory(picked)) {\n llbotPath = path.join(rootDir, \"LLBOT\");\n note(c.text(t(\"wizard.usingDefault\", { path: llbotPath })), t(\"common.tips\"));\n }\n return {\n qqEnabled: true,\n qqBackend: \"llbot\",\n qqAppId: \"\",\n qqAppSecret: \"\",\n qqSandbox: false,\n qqGroupOpenid: \"\",\n llbotPath,\n llbotEnabled: true,\n };\n }\n\n const appIdRaw = await text({\n message: t(\"wizard.qqAppId\"),\n placeholder: \"102xxxxx\",\n validate: (v: any): any => {\n if (!String(v ?? \"\").trim()) return t(\"wizard.valueRequired\");\n },\n });\n const secretRaw = await password({\n message: t(\"wizard.qqAppSecret\"),\n validate: (v: any): any => {\n if (!String(v ?? \"\").trim()) return t(\"wizard.valueRequired\");\n },\n });\n const sandboxPick = await confirm({\n message: t(\"wizard.qqSandbox\"),\n initialValue: false,\n });\n const openidRaw = await text({\n message: t(\"wizard.qqGroupOpenid\"),\n placeholder: t(\"wizard.qqGroupOpenidHint\"),\n });\n return {\n qqEnabled: true,\n qqBackend: \"official\",\n qqAppId: isCancel(appIdRaw) ? \"\" : String(appIdRaw).trim(),\n qqAppSecret: isCancel(secretRaw) ? \"\" : String(secretRaw).trim(),\n qqSandbox: isCancel(sandboxPick) ? false : !!sandboxPick,\n qqGroupOpenid: isCancel(openidRaw) ? \"\" : String(openidRaw).trim(),\n llbotEnabled: false,\n };\n}\n\n/**\n * \u9009\u62E9\u8981\u542F\u7528\u6216\u5B89\u88C5\u7684\u6A21\u5757\u3002\n * \u76EE\u5F55\u91CC\u5DF2\u6709\u6A21\u5757\u65F6\u53EA\u95EE\u542F\u505C\uFF1B\u7A7A\u76EE\u5F55\u624D\u8BFB\u5B98\u65B9\u7D22\u5F15\uFF0C\u907F\u514D\u628A\u542F\u7528\u548C\u5B89\u88C5\u6DF7\u6210\u540C\u4E00\u6B21\u9009\u62E9\u3002\n */\nasync function askModules(rootDir: string): Promise<string[]> {\n const catalog = readJson<Catalog>(modulePath(rootDir, \"catalog.json\")) ?? {\n version: 1,\n modules: [],\n };\n const catalogModules: Array<{ id: string; name?: string; description?: string; canDisable?: boolean }> = [];\n if (Array.isArray(catalog.modules)) {\n for (const m of catalog.modules) {\n catalogModules.push({\n id: String(m.id ?? \"\"),\n name: String(m.name ?? m.id ?? \"\"),\n description: String(m.description ?? \"\"),\n canDisable: m.canDisable !== false,\n });\n }\n }\n\n if (catalogModules.length > 0) {\n note(c.text(t(\"wizard.modulesFound\", { count: catalogModules.length })), t(\"wizard.step4\"));\n const lockedMd: Array<{ value: string; label: string; hint: string; disabled?: boolean }> = [];\n const optionalMd: Array<{ value: string; label: string; hint: string }> = [];\n for (const k of catalogModules) {\n const option = {\n value: k.id,\n label: String(k.name),\n hint: String(k.description ?? t(\"wizard.emptyHint\")),\n };\n if (k.canDisable === false) lockedMd.push({ ...option, disabled: true });\n else optionalMd.push(option);\n }\n const picked = await multiselect({\n message: t(\"wizard.enableModules\"),\n options: [...lockedMd, ...optionalMd],\n required: false,\n });\n return isCancel(picked) ? [] : (picked as string[]);\n }\n\n note(c.text(t(\"wizard.modulesNone\")), t(\"wizard.step4\"));\n const spin = spinner();\n spin.start(t(\"wizard.registryLoading\"));\n const { index } = await resolveRegistryIndex();\n const ids = Object.keys(index).sort((a, b) => a.localeCompare(b));\n if (ids.length === 0) {\n spin.stop(t(\"wizard.registryOffline\"));\n return [];\n }\n spin.stop(t(\"wizard.modulesFound\", { count: String(ids.length) }));\n const picked = await multiselect({\n message: t(\"wizard.installFromRegistry\"),\n options: ids.map((id) => ({ value: id, label: id })),\n required: false,\n });\n return isCancel(picked) ? [] : (picked as string[]);\n}\n\nexport async function runWizard(): Promise<void> {\n intro(c.bold(t(\"wizard.intro\")));\n\n const langPick = await select({\n message: t(\"locale.wizard\"),\n options: [\n { value: \"zh-CN\", label: t(\"locale.opt.zh\") },\n { value: \"en\", label: t(\"locale.opt.en\") },\n ],\n initialValue: \"zh-CN\",\n });\n if (!isCancel(langPick)) {\n persistLocale(ROOT, langPick as Locale);\n }\n\n // Already initialized only when runtime.json#initialized_at is set (empty db_config skeleton does not count).\n if (isRuntimeInitialized()) {\n const r = await confirm({ message: t(\"wizard.rerun\"), initialValue: false });\n if (isCancel(r) || !r) {\n outro(c.dim(t(\"wizard.skipped\")));\n return;\n }\n }\n // Step 1: Runtime Environment\uFF08\u53EA\u64AD\u79CD configs/modules\uFF0C\u4E0D\u5199 initialized_at\u3001\u4E0D\u5EFA data/\uFF09\n const rootDir = ROOT;\n note(c.text(t(\"wizard.runtimeRoot\", { root: rootDir })), t(\"wizard.step1\"));\n\n try {\n await prepareRuntimeAssets(rootDir);\n } catch (error) {\n outro(c.red(t(\"wizard.prepFailed\", { message: (error as Error).message })));\n return;\n }\n\n // Step 2: BDS \u76EE\u5F55\u3002\u6570\u636E\u5E93\u548C QQ \u653E\u5230\u540E\u9762\uFF0C\u80FD\u7528\u9ED8\u8BA4\u503C\u5C31\u4E0D\u518D\u9010\u9879\u95EE\u3002\n note(c.text(t(\"wizard.step2Note\")), t(\"wizard.step2\"));\n\n const bdsResolved = await pickDirectory(t(\"wizard.bdsDir\"), path.join(rootDir, \"BDS\"));\n if (!ensureDirectory(bdsResolved)) {\n outro(c.red(t(\"wizard.cannotCreateBds\", { dir: bdsResolved })));\n return;\n }\n\n // Step 3: \u5148\u786E\u8BA4\u53EF\u6267\u884C\u6587\u4EF6\u548C EULA\uFF0C\u518D\u51B3\u5B9A\u8981\u4E0D\u8981\u4E0B\u8F7D\u3002\n const bdsExe = bdsExePath(bdsResolved);\n const bdsExists = fs.existsSync(bdsExe);\n\n note(\n bdsExists\n ? c.green(t(\"wizard.bdsFound\", { path: bdsResolved }))\n : c.yellow(t(\"wizard.bdsNotFound\", { path: bdsResolved })),\n t(\"wizard.step3\")\n );\n\n const EULA = await confirm({\n message: t(\"wizard.eula\"),\n initialValue: false,\n });\n if (isCancel(EULA) || !EULA) {\n outro(c.yellow(t(\"wizard.disagreed\")));\n return;\n }\n\n let downloadBds = false;\n let bdsChannel = \"release\";\n\n if (!bdsExists) {\n const d = await confirm({ message: t(\"wizard.downloadBds\"), initialValue: true });\n if (!isCancel(d) && d) {\n const ch = await select({\n message: t(\"wizard.selectChannel\"),\n options: [\n { value: \"release\", label: t(\"wizard.channel.release\"), hint: t(\"wizard.channel.releaseHint\") },\n { value: \"preview\", label: t(\"wizard.channel.preview\"), hint: t(\"wizard.channel.previewHint\") },\n ],\n initialValue: \"release\",\n });\n if (!isCancel(ch)) {\n bdsChannel = ch as string;\n downloadBds = true;\n }\n }\n }\n\n const { dbDir, dbPort, backupDir, preserve } = await askRuntimeLayout(rootDir, bdsResolved);\n if (downloadBds && !ensureDirectory(backupDir)) {\n outro(c.red(t(\"wizard.cannotCreateBackup\", { dir: backupDir })));\n return;\n }\n\n const qq = await askQqBridge(rootDir);\n if (!qq) {\n outro(c.dim(t(\"wizard.skipped\")));\n return;\n }\n const { qqEnabled, qqBackend, qqAppId, qqAppSecret, qqSandbox, qqGroupOpenid, llbotPath, llbotEnabled } = qq;\n\n const selectedModules = await askModules(rootDir);\n\n const wizardTasks = [\n {\n title: t(\"wizard.updatingConfigs\"),\n task: () => {\n const slashPath = (value: string) => value.replace(/\\\\/g, \"/\");\n patchJson(rootDir, \"db_config.json\", {\n db_port: dbPort,\n dbDir: slashPath(path.relative(rootDir, path.join(dbDir, \"sfmc_data.db\"))),\n modulesDir: \"modules\",\n });\n\n const llbotOn = qqBackend === \"llbot\" && !!llbotEnabled && !!llbotPath;\n const qqNotify = qqEnabled && (qqBackend === \"official\" || llbotOn);\n const exeName = llbotExeName();\n const currentQq = readJson<QQBridgeConfig>(configPath(rootDir, \"qq_config.json\")) ?? {};\n patchJson(rootDir, \"qq_config.json\", {\n qq_enabled: qqEnabled,\n qq_backend: qqBackend,\n official: {\n ...currentQq.official,\n app_id: qqAppId,\n app_secret: qqAppSecret,\n sandbox: qqSandbox,\n group_openid: qqGroupOpenid,\n },\n llbot: {\n ...currentQq.llbot,\n enabled: llbotOn,\n // path = \u53EF\u6267\u884C\u6587\u4EF6\uFF1Bcwd = \u8FD0\u884C\u76EE\u5F55\uFF08\u5411\u5BFC\u9009\u7684\u662F\u76EE\u5F55\uFF09\n path: llbotPath ? slashPath(path.join(llbotPath, exeName)) : \"\",\n cwd: llbotPath ? slashPath(llbotPath) : \"\",\n },\n });\n patchJson(rootDir, \"bds_updater.json\", {\n bds_path: slashPath(bdsResolved),\n channel: bdsChannel,\n backup_dir: slashPath(backupDir),\n preserve,\n qq_notify: qqNotify,\n });\n /* \u8DEF\u5F84\u9009\u5B9A\u540E\u518D\u6807\u8BB0\u5DF2\u521D\u59CB\u5316\uFF0C\u907F\u514D\u534A\u9014\u53D6\u6D88\u4ECD\u7559\u4E0B data/ \u8BED\u4E49 */\n patchJson(rootDir, \"runtime.json\", {\n runtime_root: rootDir,\n initialized_at: new Date().toISOString(),\n locale: isCancel(langPick) ? undefined : (langPick as string),\n });\n return t(\"wizard.configsUpdated\");\n },\n },\n {\n title: t(\"wizard.updatingModules\"),\n task: async (): Promise<string> => {\n const lock = readJson<ModuleLock>(modulePath(rootDir, \"module-lock.json\")) ?? {\n version: 1,\n modules: {},\n };\n if (!lock.modules) lock.modules = {};\n const now = Date.now();\n for (const id of selectedModules) lock.modules[id] = { enabled: true, updatedAt: now };\n writeJson(modulePath(rootDir, \"module-lock.json\"), lock);\n return t(\"wizard.modulesUpdated\");\n },\n },\n {\n title: t(\"wizard.initDb\"),\n task: async (): Promise<string> => {\n const child = spawnService(\"db\", [], {\n cwd: rootDir,\n stdio: \"ignore\",\n env: { ...process.env, DB_PORT: String(dbPort) },\n });\n if (!(await waitForHealth(dbPort))) {\n child.kill(\"SIGTERM\");\n return t(\"wizard.dbTimeout\");\n }\n\n /* /api/health \u5728 listen \u4E4B\u540E\u624D\u8FD4\u56DE\uFF0C\u800C\u5EFA\u8868\u53D1\u751F\u5728 listen \u4E4B\u524D\uFF0C\u4E0D\u5FC5\u518D\u7A7A\u7B49\u3002 */\n child.kill(\"SIGTERM\");\n setTimeout(() => child.kill(\"SIGKILL\"), 3000).unref();\n return t(\"wizard.dbOk\");\n },\n },\n ];\n if (downloadBds) {\n wizardTasks.push({\n title: t(\"wizard.downloadingBds\"),\n task: async (): Promise<string> => {\n const result = await runBdsUpdate(rootDir, bdsChannel);\n if (result.code !== 0) {\n return t(\"wizard.downloadFail\");\n }\n return t(\"wizard.bdsDownloaded\");\n },\n });\n }\n try {\n await tasks(wizardTasks);\n } catch (e) {\n outro(c.red(t(\"common.error\", { message: (e as Error).message })));\n return;\n }\n\n /* install \u2192 build \u2192 deploy chain */\n await runInstallBuildDeploy(rootDir, selectedModules, bdsResolved);\n\n outro(c.green(t(\"wizard.done\")));\n}\n\nasync function runInstallBuildDeploy(rootDir: string, selectedModules: string[], bdsResolved: string): Promise<void> {\n if (selectedModules.length > 0) {\n const fetchScript = resolveFetchModule();\n if (fetchScript) {\n const installT = [\n {\n title: t(\"wizard.installing\", { count: selectedModules.length }),\n task: async (): Promise<string> => {\n /* \u5411\u5BFC\u91CC\u52FE\u9009\u7684\u542F\u505C\u5DF2\u7ECF\u5199\u5165 lock\uFF0C\u5B89\u88C5\u65F6\u4FDD\u7559\uFF0C\u4E0D\u7528\u6E05\u5355\u91CC\u7684\u9ED8\u8BA4\u503C\u8986\u76D6\u3002 */\n execFileSync(process.execPath, [fetchScript, \"install\", ...selectedModules, \"--preserve-lock\"], {\n cwd: rootDir,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, SFMC_ROOT: rootDir },\n });\n return t(\"wizard.installed\", { count: selectedModules.length });\n },\n },\n ];\n try {\n await tasks(installT);\n } catch (e) {\n note(c.yellow(t(\"wizard.installFailed\", { message: (e as Error).message })));\n }\n } else {\n note(c.yellow(t(\"wizard.fetchMissing\", { list: selectedModules.join(\", \") })));\n }\n } else {\n note(c.dim(t(\"wizard.noModulesSelected\")));\n }\n\n const { cmdBehaviorPackBuild, cmdBehaviorPackDeploy } = await import(\"./commands-behavior-pack.js\");\n const buildT = [\n {\n title: t(\"wizard.buildingBp\"),\n task: async (): Promise<string> => {\n const r = await cmdBehaviorPackBuild([]);\n if (!r.ok) throw new Error(r.message);\n return r.message;\n },\n },\n ];\n try {\n await tasks(buildT);\n } catch (e) {\n note(c.yellow(t(\"wizard.buildFailed\", { message: (e as Error).message })));\n return;\n }\n\n const deployT = [\n {\n title: t(\"wizard.deploying\", { path: bdsResolved }),\n task: async (): Promise<string> => {\n const r = await cmdBehaviorPackDeploy([]);\n if (!r.ok) throw new Error(r.message);\n return r.message;\n },\n },\n ];\n try {\n await tasks(deployT);\n note(c.green(t(\"wizard.restartBds\")));\n } catch (e) {\n note(c.yellow(t(\"wizard.deployFailed\", { message: (e as Error).message })));\n }\n void rootDir;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["t", "picked"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sfmc-bds/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "SFMC management CLI — REPL, service supervisor, module install, behavior-pack build/deploy",
|
|
5
5
|
"author": "Shiroha7z",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -55,13 +55,13 @@
|
|
|
55
55
|
"esbuild": "^0.28.1",
|
|
56
56
|
"ajv": "8.20.0",
|
|
57
57
|
"jsonc-parser": "3.3.1",
|
|
58
|
-
"@sfmc-bds/bds-tools": "0.2.
|
|
59
|
-
"@sfmc-bds/devkit": "2.0.
|
|
60
|
-
"@sfmc-bds/sdk": "0.
|
|
58
|
+
"@sfmc-bds/bds-tools": "0.2.8",
|
|
59
|
+
"@sfmc-bds/devkit": "2.0.4",
|
|
60
|
+
"@sfmc-bds/sdk": "0.4.0",
|
|
61
61
|
"@sfmc-bds/management": "0.3.2"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@sfmc-bds/tools": "0.2.
|
|
64
|
+
"@sfmc-bds/tools": "0.2.8"
|
|
65
65
|
},
|
|
66
66
|
"publishConfig": {
|
|
67
67
|
"access": "public",
|
|
@@ -261,7 +261,9 @@ function afterInstall(folder, opts = {}) {
|
|
|
261
261
|
const moduleRoot = path.join(TARGET, folder);
|
|
262
262
|
const preview = loadPackageCatalogEntry(folder);
|
|
263
263
|
if (!preview) throw new Error(`packages/${folder}: 无法读取 sapi/manifest.json`);
|
|
264
|
-
if (isRetiredPlatformModule(preview.id))
|
|
264
|
+
if (isRetiredPlatformModule(preview.id)) {
|
|
265
|
+
throw new Error(`${preview.id} 已收编至平台,无需安装;请更新平台行为包。`);
|
|
266
|
+
}
|
|
265
267
|
const seeded = seedModuleConfig({
|
|
266
268
|
moduleRoot,
|
|
267
269
|
projectRoot: ROOT,
|
|
@@ -896,7 +898,9 @@ async function copyDir(src, dst) {
|
|
|
896
898
|
* @param {{ from: any; sha256?: null; link: any; }} flags
|
|
897
899
|
*/
|
|
898
900
|
async function installOne(id, flags) {
|
|
899
|
-
if (isRetiredPlatformModule(id))
|
|
901
|
+
if (isRetiredPlatformModule(id)) {
|
|
902
|
+
throw new Error(`${id} 已收编至平台,无需安装;请更新平台行为包。`);
|
|
903
|
+
}
|
|
900
904
|
let from = flags.from;
|
|
901
905
|
if (!from) {
|
|
902
906
|
from = await defaultSourceFor(id);
|