@sfmc-bds/cli 0.1.0 → 0.2.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/README.md +7 -1
  2. package/dist/cli-result.d.ts +12 -0
  3. package/dist/cli-result.d.ts.map +1 -0
  4. package/dist/cli-result.js +15 -0
  5. package/dist/cli-result.js.map +7 -0
  6. package/dist/commands-behavior-pack.d.ts +11 -42
  7. package/dist/commands-behavior-pack.d.ts.map +1 -1
  8. package/dist/commands-behavior-pack.js +40 -159
  9. package/dist/commands-behavior-pack.js.map +7 -1
  10. package/dist/commands-reload.d.ts +9 -0
  11. package/dist/commands-reload.d.ts.map +1 -0
  12. package/dist/commands-reload.js +30 -0
  13. package/dist/commands-reload.js.map +7 -0
  14. package/dist/commands.d.ts +7 -0
  15. package/dist/commands.d.ts.map +1 -1
  16. package/dist/commands.js +182 -172
  17. package/dist/commands.js.map +7 -1
  18. package/dist/i18n/index.d.ts +26 -0
  19. package/dist/i18n/index.d.ts.map +1 -0
  20. package/dist/i18n/index.js +107 -0
  21. package/dist/i18n/index.js.map +7 -0
  22. package/dist/i18n/locales/en.d.ts +381 -0
  23. package/dist/i18n/locales/en.d.ts.map +1 -0
  24. package/dist/i18n/locales/en.js +393 -0
  25. package/dist/i18n/locales/en.js.map +7 -0
  26. package/dist/i18n/locales/zh-CN.d.ts +4 -0
  27. package/dist/i18n/locales/zh-CN.d.ts.map +1 -0
  28. package/dist/i18n/locales/zh-CN.js +379 -0
  29. package/dist/i18n/locales/zh-CN.js.map +7 -0
  30. package/dist/i18n/types.d.ts +7 -0
  31. package/dist/i18n/types.d.ts.map +1 -0
  32. package/dist/i18n/types.js +17 -0
  33. package/dist/i18n/types.js.map +7 -0
  34. package/dist/index.d.ts +5 -11
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +51 -43
  37. package/dist/index.js.map +7 -1
  38. package/dist/interactive-prompts.d.ts +8 -0
  39. package/dist/interactive-prompts.d.ts.map +1 -0
  40. package/dist/interactive-prompts.js +57 -0
  41. package/dist/interactive-prompts.js.map +7 -0
  42. package/dist/locale-command.d.ts +3 -0
  43. package/dist/locale-command.d.ts.map +1 -0
  44. package/dist/locale-command.js +19 -0
  45. package/dist/locale-command.js.map +7 -0
  46. package/dist/logs.d.ts +22 -4
  47. package/dist/logs.d.ts.map +1 -1
  48. package/dist/logs.js +208 -193
  49. package/dist/logs.js.map +7 -1
  50. package/dist/main.js +135 -173
  51. package/dist/main.js.map +7 -1
  52. package/dist/module-commands.d.ts +43 -4
  53. package/dist/module-commands.d.ts.map +1 -1
  54. package/dist/module-commands.js +440 -327
  55. package/dist/module-commands.js.map +7 -1
  56. package/dist/module-fingerprint.d.ts +7 -0
  57. package/dist/module-fingerprint.d.ts.map +1 -0
  58. package/dist/module-fingerprint.js +31 -0
  59. package/dist/module-fingerprint.js.map +7 -0
  60. package/dist/module-wizard.d.ts +14 -0
  61. package/dist/module-wizard.d.ts.map +1 -0
  62. package/dist/module-wizard.js +313 -0
  63. package/dist/module-wizard.js.map +7 -0
  64. package/dist/pack-lifecycle.d.ts +95 -0
  65. package/dist/pack-lifecycle.d.ts.map +1 -0
  66. package/dist/pack-lifecycle.js +634 -0
  67. package/dist/pack-lifecycle.js.map +7 -0
  68. package/dist/pack-update/bindings.d.ts +12 -0
  69. package/dist/pack-update/bindings.d.ts.map +1 -0
  70. package/dist/pack-update/bindings.js +64 -0
  71. package/dist/pack-update/bindings.js.map +7 -0
  72. package/dist/pack-update/config.d.ts +22 -0
  73. package/dist/pack-update/config.d.ts.map +1 -0
  74. package/dist/pack-update/config.js +141 -0
  75. package/dist/pack-update/config.js.map +7 -0
  76. package/dist/pack-update/providers/curseforge.d.ts +23 -0
  77. package/dist/pack-update/providers/curseforge.d.ts.map +1 -0
  78. package/dist/pack-update/providers/curseforge.js +209 -0
  79. package/dist/pack-update/providers/curseforge.js.map +7 -0
  80. package/dist/pack-update/providers/index.d.ts +16 -0
  81. package/dist/pack-update/providers/index.d.ts.map +1 -0
  82. package/dist/pack-update/providers/index.js +37 -0
  83. package/dist/pack-update/providers/index.js.map +7 -0
  84. package/dist/pack-update/service.d.ts +21 -0
  85. package/dist/pack-update/service.d.ts.map +1 -0
  86. package/dist/pack-update/service.js +567 -0
  87. package/dist/pack-update/service.js.map +7 -0
  88. package/dist/pack-update/types.d.ts +126 -0
  89. package/dist/pack-update/types.d.ts.map +1 -0
  90. package/dist/pack-update/types.js +8 -0
  91. package/dist/pack-update/types.js.map +7 -0
  92. package/dist/pack-update/version-policy.d.ts +80 -0
  93. package/dist/pack-update/version-policy.d.ts.map +1 -0
  94. package/dist/pack-update/version-policy.js +216 -0
  95. package/dist/pack-update/version-policy.js.map +7 -0
  96. package/dist/registry.d.ts +12 -4
  97. package/dist/registry.d.ts.map +1 -1
  98. package/dist/registry.js +73 -106
  99. package/dist/registry.js.map +7 -1
  100. package/dist/remote-agent.d.ts.map +1 -1
  101. package/dist/remote-agent.js +160 -176
  102. package/dist/remote-agent.js.map +7 -1
  103. package/dist/repl.d.ts +4 -0
  104. package/dist/repl.d.ts.map +1 -1
  105. package/dist/repl.js +683 -605
  106. package/dist/repl.js.map +7 -1
  107. package/dist/runtime.d.ts +40 -14
  108. package/dist/runtime.d.ts.map +1 -1
  109. package/dist/runtime.js +185 -62
  110. package/dist/runtime.js.map +7 -1
  111. package/dist/services.d.ts +2 -0
  112. package/dist/services.d.ts.map +1 -1
  113. package/dist/services.js +251 -238
  114. package/dist/services.js.map +7 -1
  115. package/dist/sfmc-modules-root.d.ts +24 -0
  116. package/dist/sfmc-modules-root.d.ts.map +1 -0
  117. package/dist/sfmc-modules-root.js +70 -0
  118. package/dist/sfmc-modules-root.js.map +7 -0
  119. package/dist/theme.d.ts +4 -0
  120. package/dist/theme.d.ts.map +1 -1
  121. package/dist/theme.js +134 -48
  122. package/dist/theme.js.map +7 -1
  123. package/dist/wizard.d.ts.map +1 -1
  124. package/dist/wizard.js +363 -438
  125. package/dist/wizard.js.map +7 -1
  126. package/dist/world-packs.d.ts +22 -0
  127. package/dist/world-packs.d.ts.map +1 -0
  128. package/dist/world-packs.js +872 -0
  129. package/dist/world-packs.js.map +7 -0
  130. package/package.json +10 -10
  131. package/dist/dispatcher.d.ts +0 -13
  132. package/dist/dispatcher.d.ts.map +0 -1
  133. package/dist/dispatcher.js +0 -23
  134. package/dist/dispatcher.js.map +0 -1
  135. package/dist/terminal.d.ts +0 -3
  136. package/dist/terminal.d.ts.map +0 -1
  137. package/dist/terminal.js +0 -178
  138. package/dist/terminal.js.map +0 -1
package/dist/logs.js CHANGED
@@ -1,202 +1,217 @@
1
- /**
2
- * logs.ts — sfmc 主进程统一日志聚合层
3
- *
4
- * 内部委托 @sfmc-bds/logs 共享包的 createMemoryBuffer + inferLevel,
5
- * 保持向后兼容的 pushLog / onLog / getAllLogs / getRecentLogs API
6
- * (services.ts 捕获子进程 stdout 后调用 pushLog 汇聚到此)。
7
- *
8
- * formatLog 保留 theme.ts (chalk) 配色,比共享包的纯 ANSI 版本视觉更丰富。
9
- */
10
- import { createMemoryBuffer, inferLevel as sharedInferLevel, } from "@sfmc-bds/sdk/logs";
11
- import { SOURCE_ITEMS } from "./repl.js";
12
- import { c } from "./theme.js";
13
- const buffer = createMemoryBuffer(5000);
14
- /** 推送一条日志到内存缓冲 (services.ts 捕获子进程 stdout 后调用) */
15
- export function pushLog(text, source, level) {
16
- buffer.pushDirect(text, source, level);
17
- }
18
- /** 订阅新日志事件,返回取消订阅函数 */
19
- export function onLog(fn) {
20
- return buffer.subscribe(fn);
21
- }
22
- /** 获取全部日志 (按时间顺序) */
23
- export function getAllLogs() {
24
- return buffer.getAll();
25
- }
26
- /** 获取最近 n 条,可按 level / source 过滤 */
27
- export function getRecentLogs(n, levels, sources) {
28
- return buffer.getRecent(n, levels, sources);
29
- }
30
- /** 从原始文本推断日志级别 (委托共享包) */
31
- export function inferLevel(text) {
32
- return sharedInferLevel(text);
33
- }
34
- /** 简化BDS日志 */
1
+ import {
2
+ createFileSink,
3
+ createMemoryBuffer,
4
+ formatLogLine,
5
+ inferLevel as sharedInferLevel
6
+ } from "@sfmc-bds/sdk/logs";
7
+ import { logFile } from "@sfmc-bds/sdk/node/config";
8
+ import { c, highlightLogLine } from "./theme.js";
9
+ import { ROOT } from "./runtime.js";
10
+ const buffer = createMemoryBuffer(5e3);
11
+ const CHILD_OWNED_SOURCES = /* @__PURE__ */ new Set(["db", "qq", "update"]);
12
+ const fileSinks = /* @__PURE__ */ new Map();
13
+ function resolveDiskLogName(source) {
14
+ if (CHILD_OWNED_SOURCES.has(source)) return null;
15
+ if (source === "bds" || source === "llbot") return source;
16
+ return "sfmc";
17
+ }
18
+ function sinkFor(source) {
19
+ const name = resolveDiskLogName(source);
20
+ if (!name) return null;
21
+ let sink = fileSinks.get(name);
22
+ if (!sink) {
23
+ sink = createFileSink(logFile(ROOT, name));
24
+ fileSinks.set(name, sink);
25
+ }
26
+ return sink;
27
+ }
28
+ process.on("exit", () => {
29
+ for (const sink of fileSinks.values()) sink.close();
30
+ });
31
+ function pushLog(text, source, level) {
32
+ buffer.pushDirect(text, source, level);
33
+ const sink = sinkFor(source);
34
+ if (!sink) return;
35
+ const entry = { time: /* @__PURE__ */ new Date(), text, source, level };
36
+ try {
37
+ sink.write(entry, formatLogLine(entry, false));
38
+ } catch {
39
+ }
40
+ }
41
+ function onLog(fn) {
42
+ return buffer.subscribe(fn);
43
+ }
44
+ function getAllLogs() {
45
+ return buffer.getAll();
46
+ }
47
+ function getRecentLogs(n, levels, sources) {
48
+ return buffer.getRecent(n, levels, sources);
49
+ }
50
+ function inferLevel(text) {
51
+ return sharedInferLevel(text);
52
+ }
53
+ const SOURCE_META = [
54
+ { value: "bds", name: "BDServer", paint: (s) => c.green(s) },
55
+ { value: "db", name: "DataBase", paint: (s) => c.blue(s) },
56
+ { value: "qq", name: "QQBridge", paint: (s) => c.purple(s) },
57
+ { value: "llbot", name: " LL-BOT ", paint: (s) => c.yellow(s) },
58
+ { value: "system", name: " SYSTEM ", paint: (s) => c.cyan(s) },
59
+ { value: "update", name: " UPDATE ", paint: (s) => c.orange(s) },
60
+ { value: "pack", name: " PACK ", paint: (s) => c.purple(s) },
61
+ { value: "bds-tools", name: "BDSTools", paint: (s) => c.red(s) }
62
+ ];
63
+ function formatSourceTag(source) {
64
+ const meta = SOURCE_META.find((m) => m.value === source);
65
+ if (meta) return meta.paint(`[${meta.name}]`);
66
+ return c.bold(`[${source.padEnd(7).slice(0, 8)}]`);
67
+ }
35
68
  function stripLogPrefix(line) {
36
- // 匹配格式: [2026-07-18 23:56:06:778 INFO]
37
- const prefixRegex = /^\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}:\d{3} (INFO|WARNING|ERROR|FATAL|DEBUG)\]\s*/;
38
- return line.replace(prefixRegex, "");
39
- }
40
- /**
41
- * 从一行 BDS 日志中提取日志等级
42
- * @param line 日志行字符串
43
- * @returns 日志等级(大写),若无法识别则返回 'UNKNOWN'
44
- */
69
+ const prefixRegex = /^\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}:\d{3} (INFO|WARNING|ERROR|FATAL|DEBUG)\]\s*/;
70
+ return line.replace(prefixRegex, "");
71
+ }
45
72
  function getLogLevel(line) {
46
- // 定义所有可能出现的等级(不区分大小写)
47
- const levelNames = ["INFO", "WARNING", "ERROR", "FATAL", "DEBUG", "TRACE", "WARN"];
48
- const levelPattern = levelNames.join("|");
49
- // 1. 等级在方括号内,如 [INFO] [WARNING]
50
- let match = line.match(new RegExp(`\\[(${levelPattern})\\]`, "i"));
51
- if (match && match[1])
52
- return match[1].toUpperCase();
53
- // 2. 等级紧跟在时间戳方括号之后,如 [2026-...] INFO
54
- match = line.match(new RegExp(`^\\[.*?\\]\\s*(${levelPattern})`, "i"));
55
- if (match && match[1])
56
- return match[1].toUpperCase();
57
- // 3. 等级在行首,后跟冒号,如 INFO: 或 ERROR:
58
- match = line.match(new RegExp(`^(${levelPattern})\\s*:`, "i"));
59
- if (match && match[1])
60
- return match[1].toUpperCase();
61
- // 4. 等级在类似 [Server] 后的方括号外,如 [Server] INFO:
62
- match = line.match(new RegExp(`\\[.*?\\]\\s*(${levelPattern})\\s*:`, "i"));
63
- if (match && match[1])
64
- return match[1].toUpperCase();
65
- // 5. 若上述均未匹配,返回未知
66
- return "UNKNOWN";
67
- }
68
- /** 格式化日志用于 REPL 展示 (用 theme.ts chalk 配色) */
69
- export function formatLog(l) {
70
- let src = c.bold(padSource(l.source));
71
- let ts = c.dim(l.time.toLocaleTimeString());
72
- let lvl = levelTag(l.level);
73
- let txt = highlightText(l.text);
74
- for (let _src of SOURCE_ITEMS) {
75
- if (_src["value"] === l.source)
76
- src = `[${_src["label"]}]`;
77
- continue;
78
- }
79
- if (l.source === "bds") {
80
- lvl = getLogLevel(l.text);
81
- switch (lvl) {
82
- case "INFO":
83
- lvl = "info";
84
- break;
85
- case "WARNING":
86
- lvl = "warn";
87
- break;
88
- case "ERROR":
89
- lvl = "error";
90
- break;
91
- case "DEBUG":
92
- lvl = "debug";
93
- break;
94
- default:
95
- lvl = "info";
96
- break;
97
- }
98
- txt = stripLogPrefix(l.text);
99
- lvl = levelTag(l.level);
100
- }
101
- return `${ts} ${src} ${lvl} ${txt}`;
73
+ const levelNames = ["INFO", "WARNING", "ERROR", "FATAL", "DEBUG", "TRACE", "WARN"];
74
+ const levelPattern = levelNames.join("|");
75
+ let match = line.match(new RegExp(`\\[(${levelPattern})\\]`, "i"));
76
+ if (match && match[1]) return match[1].toUpperCase();
77
+ match = line.match(new RegExp(`^\\[.*?\\]\\s*(${levelPattern})`, "i"));
78
+ if (match && match[1]) return match[1].toUpperCase();
79
+ match = line.match(new RegExp(`^(${levelPattern})\\s*:`, "i"));
80
+ if (match && match[1]) return match[1].toUpperCase();
81
+ match = line.match(new RegExp(`\\[.*?\\]\\s*(${levelPattern})\\s*:`, "i"));
82
+ if (match && match[1]) return match[1].toUpperCase();
83
+ return "UNKNOWN";
102
84
  }
103
- function padSource(s) {
104
- return s.padEnd(7);
85
+ function formatLog(l) {
86
+ const ts = c.dim(l.time.toLocaleTimeString());
87
+ let lvl = levelTag(l.level);
88
+ let txt = highlightLogLine(l.text);
89
+ const src = formatSourceTag(l.source);
90
+ if (l.source === "bds") {
91
+ const parsed = getLogLevel(l.text);
92
+ const mapped = parsed === "WARNING" || parsed === "WARN" ? "warn" : parsed === "ERROR" || parsed === "FATAL" ? "error" : parsed === "DEBUG" || parsed === "TRACE" ? "debug" : "info";
93
+ txt = highlightLogLine(stripLogPrefix(l.text));
94
+ lvl = levelTag(mapped);
95
+ }
96
+ return `${ts} ${src} ${lvl} ${txt}`;
105
97
  }
106
98
  function levelTag(lvl) {
107
- switch (lvl) {
108
- case "error":
109
- return c.red("[ERR]");
110
- case "warn":
111
- return c.yellow("[WRN]");
112
- case "success":
113
- return c.green(c.bold("[OK]"));
114
- case "debug":
115
- return c.dim("[DBG]");
116
- default:
117
- return c.blue("[INF]");
118
- }
99
+ switch (lvl) {
100
+ case "error":
101
+ return c.red("[ERR]");
102
+ case "warn":
103
+ return c.yellow("[WRN]");
104
+ case "success":
105
+ return c.green(c.bold("[OK]"));
106
+ case "debug":
107
+ return c.dim("[DBG]");
108
+ default:
109
+ return c.blue("[INF]");
110
+ }
119
111
  }
120
- function highlightText(raw) {
121
- let s = raw;
122
- s = s.replace(/§[0-9a-fklmnor]/g, "");
123
- s = s.replace(/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(:\d+)?\b/g, (m) => c.cyan(m));
124
- s = s.replace(/\b(TPS|MSPT|tick|loaded|saved)\b/gi, (m) => c.cyan(m));
125
- return s;
126
- }
127
- /* ==================================================================
128
- * 软换行: 超终端宽度时换行,后续行缩进对齐
129
- * ================================================================== */
130
- /** 单个字符在终端的显示宽度 (CJK 全角=2, 其余=1) */
131
112
  function charWidth(ch) {
132
- const c = ch.codePointAt(0) ?? 0;
133
- if (c >= 0x1100 &&
134
- (c <= 0x115f ||
135
- (c >= 0x2e80 && c <= 0xa4cf && c !== 0x303f) ||
136
- (c >= 0xac00 && c <= 0xd7a3) ||
137
- (c >= 0xf900 && c <= 0xfaff) ||
138
- (c >= 0xfe30 && c <= 0xfe4f) ||
139
- (c >= 0xff00 && c <= 0xff60) ||
140
- (c >= 0xffe0 && c <= 0xffe6) ||
141
- (c >= 0x20000 && c <= 0x2fffd)))
142
- return 2;
143
- return 1;
144
- }
145
- /** 字符串在终端的可见宽度 (strip ANSI 后按 CJK 宽度累加) */
146
- export function visibleWidth(s) {
147
- const stripped = s.replace(/\x1b\[[0-9;]*m/g, "");
148
- let w = 0;
149
- for (const ch of stripped)
150
- w += charWidth(ch);
151
- return w;
152
- }
153
- /**
154
- * 按终端可见宽度换行,后续行左侧缩进 indent 个空格。
155
- * 保留 ANSI 颜色码:换行时先 reset 避免缩进空格带色,新行恢复颜色状态。
156
- * 宽字符(CJK)按 2 列计算,避免中文行换行位置偏后。
157
- */
158
- export function wrapLogLine(s, indent) {
159
- const cols = process.stdout.columns || 80;
160
- if (visibleWidth(s) <= cols)
161
- return s;
162
- const lines = [];
163
- let cur = "";
164
- let w = 0;
165
- let limit = cols;
166
- let activeAnsi = "";
167
- let i = 0;
168
- while (i < s.length) {
169
- const m = /^\x1b\[[0-9;]*m/.exec(s.slice(i));
170
- if (m) {
171
- const code = m[0];
172
- cur += code;
173
- if (code === "\x1b[0m")
174
- activeAnsi = "";
175
- else
176
- activeAnsi = code;
177
- i += code.length;
178
- }
179
- else {
180
- const ch = s[i];
181
- const cw = charWidth(ch);
182
- if (w + cw > limit) {
183
- if (activeAnsi)
184
- cur += "\x1b[0m";
185
- lines.push(cur);
186
- cur = " ".repeat(indent);
187
- if (activeAnsi)
188
- cur += activeAnsi;
189
- w = 0;
190
- limit = cols - indent;
191
- }
192
- cur += ch;
193
- w += cw;
194
- i++;
195
- }
113
+ const cp = ch.codePointAt(0) ?? 0;
114
+ if (cp >= 4352 && (cp <= 4447 || cp >= 11904 && cp <= 42191 && cp !== 12351 || cp >= 44032 && cp <= 55203 || cp >= 63744 && cp <= 64255 || cp >= 65072 && cp <= 65103 || cp >= 65280 && cp <= 65376 || cp >= 65504 && cp <= 65510 || cp >= 131072 && cp <= 196605))
115
+ return 2;
116
+ return 1;
117
+ }
118
+ function visibleWidth(s) {
119
+ const stripped = s.replace(/\x1b\[[0-9;]*m/g, "");
120
+ let w = 0;
121
+ for (const ch of stripped) w += charWidth(ch);
122
+ return w;
123
+ }
124
+ function levelTagPlain(lvl) {
125
+ switch (lvl) {
126
+ case "error":
127
+ return "[ERR]";
128
+ case "warn":
129
+ return "[WRN]";
130
+ case "success":
131
+ return "[OK]";
132
+ case "debug":
133
+ return "[DBG]";
134
+ default:
135
+ return "[INF]";
136
+ }
137
+ }
138
+ function logPrefixWidth(l) {
139
+ const ts = l.time.toLocaleTimeString();
140
+ const meta = SOURCE_META.find((m) => m.value === l.source);
141
+ const src = meta ? `[${meta.name}]` : `[${l.source.padEnd(7).slice(0, 8)}]`;
142
+ let level = l.level;
143
+ if (l.source === "bds") {
144
+ const parsed = getLogLevel(l.text);
145
+ level = parsed === "WARNING" || parsed === "WARN" ? "warn" : parsed === "ERROR" || parsed === "FATAL" ? "error" : parsed === "DEBUG" || parsed === "TRACE" ? "debug" : "info";
146
+ }
147
+ return visibleWidth(`${ts} ${src} ${levelTagPlain(level)} `);
148
+ }
149
+ function wrapLogLine(s, indent) {
150
+ const rawCols = process.stdout.columns || 80;
151
+ const cols = Math.max(rawCols - 1, indent + 4);
152
+ const segments = s.split(/\r?\n/);
153
+ const out = [];
154
+ for (let si = 0; si < segments.length; si++) {
155
+ const raw = segments[si];
156
+ const piece = si === 0 ? raw : raw.replace(/^[ \t]+/, "");
157
+ out.push(wrapSegment(piece, cols, si === 0 ? 0 : indent, indent));
158
+ }
159
+ return out.join("\n");
160
+ }
161
+ function wrapSegment(s, cols, startPad, hangIndent) {
162
+ if (s.length === 0) return startPad > 0 ? " ".repeat(startPad) : "";
163
+ const lines = [];
164
+ let cur = startPad > 0 ? " ".repeat(startPad) : "";
165
+ let w = startPad;
166
+ const ansiStack = [];
167
+ const resetIfNeeded = () => {
168
+ if (ansiStack.length) cur += "\x1B[0m";
169
+ };
170
+ const replayAnsi = () => {
171
+ for (const code of ansiStack) cur += code;
172
+ };
173
+ let i = 0;
174
+ while (i < s.length) {
175
+ const m = /^\x1b\[[0-9;]*m/.exec(s.slice(i));
176
+ if (m) {
177
+ const code = m[0];
178
+ cur += code;
179
+ if (code === "\x1B[0m") ansiStack.length = 0;
180
+ else ansiStack.push(code);
181
+ i += code.length;
182
+ continue;
183
+ }
184
+ const cp = s.codePointAt(i);
185
+ const ch = String.fromCodePoint(cp);
186
+ const cw = charWidth(ch);
187
+ const advance = ch.length;
188
+ if (w + cw > cols && w > startPad) {
189
+ resetIfNeeded();
190
+ lines.push(cur);
191
+ cur = " ".repeat(hangIndent);
192
+ replayAnsi();
193
+ w = hangIndent;
194
+ startPad = hangIndent;
196
195
  }
197
- if (activeAnsi)
198
- cur += "\x1b[0m";
199
- lines.push(cur);
200
- return lines.join("\n");
196
+ cur += ch;
197
+ w += cw;
198
+ i += advance;
199
+ }
200
+ if (ansiStack.length) cur += "\x1B[0m";
201
+ lines.push(cur);
202
+ return lines.join("\n");
201
203
  }
202
- //# sourceMappingURL=logs.js.map
204
+ export {
205
+ SOURCE_META,
206
+ formatLog,
207
+ formatSourceTag,
208
+ getAllLogs,
209
+ getRecentLogs,
210
+ inferLevel,
211
+ logPrefixWidth,
212
+ onLog,
213
+ pushLog,
214
+ visibleWidth,
215
+ wrapLogLine
216
+ };
217
+ //# sourceMappingURL=logs.js.map
package/dist/logs.js.map CHANGED
@@ -1 +1,7 @@
1
- {"version":3,"file":"logs.js","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"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"}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/logs.ts"],
4
+ "sourcesContent": ["/**\n * logs.ts \u2014 sfmc \u4E3B\u8FDB\u7A0B\u7EDF\u4E00\u65E5\u5FD7\u805A\u5408\u5C42\n *\n * \u5185\u90E8\u59D4\u6258 @sfmc-bds/logs \u5171\u4EAB\u5305\u7684 createMemoryBuffer + inferLevel,\n * \u4FDD\u6301\u5411\u540E\u517C\u5BB9\u7684 pushLog / onLog / getAllLogs / getRecentLogs API\n * (services.ts \u6355\u83B7\u5B50\u8FDB\u7A0B stdout \u540E\u8C03\u7528 pushLog \u6C47\u805A\u5230\u6B64)\u3002\n *\n * \u843D\u76D8\u7B56\u7565(\u4E0E\u5B50\u8FDB\u7A0B\u81EA\u5199\u6587\u4EF6\u5206\u5DE5,\u907F\u514D\u91CD\u590D):\n * - db / qq / update \u2192 \u5B50\u8FDB\u7A0B\u5DF2\u5199 `.sfmc/logs/{db,qq,bds-update}.log`,\u6B64\u5904\u8DF3\u8FC7\n * - bds / llbot \u2192 `.sfmc/logs/{bds,llbot}.log`(\u5916\u90E8\u8FDB\u7A0B\u65E0\u81EA\u5E26 file sink)\n * - \u5176\u4F59(system / pack / \u2026) \u2192 `.sfmc/logs/sfmc.log`\n *\n * formatLog \u4FDD\u7559 theme.ts (chalk) \u914D\u8272,\u6BD4\u5171\u4EAB\u5305\u7684\u7EAF ANSI \u7248\u672C\u89C6\u89C9\u66F4\u4E30\u5BCC\u3002\n */\n\nimport {\n createFileSink,\n createMemoryBuffer,\n formatLogLine,\n inferLevel as sharedInferLevel,\n type FileSink,\n type LogEntry,\n type LogLevel as SharedLogLevel,\n} from \"@sfmc-bds/sdk/logs\";\nimport { logFile } from \"@sfmc-bds/sdk/node/config\";\nimport { c, highlightLogLine } from \"./theme.js\";\nimport { ROOT } from \"./runtime.js\";\n\nexport type LogLevel = SharedLogLevel;\nexport type LogSource = string;\nexport interface UnifiedLog extends LogEntry {}\n\nconst buffer = createMemoryBuffer(5000);\n\n/** \u5B50\u8FDB\u7A0B\u5DF2\u7528 createNodeServiceLogger \u81EA\u884C\u843D\u76D8\u7684 source */\nconst CHILD_OWNED_SOURCES = new Set([\"db\", \"qq\", \"update\"]);\n\nconst fileSinks = new Map<string, FileSink>();\n\n/** \u89E3\u6790\u672C\u6761\u65E5\u5FD7\u5E94\u5199\u5165\u7684\u6587\u4EF6\u540D(\u4E0D\u542B .log);null \u8868\u793A\u8DF3\u8FC7(\u5B50\u8FDB\u7A0B\u5DF2\u5199) */\nfunction resolveDiskLogName(source: string): string | null {\n if (CHILD_OWNED_SOURCES.has(source)) return null;\n if (source === \"bds\" || source === \"llbot\") return source;\n return \"sfmc\";\n}\n\nfunction sinkFor(source: string): FileSink | null {\n const name = resolveDiskLogName(source);\n if (!name) return null;\n let sink = fileSinks.get(name);\n if (!sink) {\n sink = createFileSink(logFile(ROOT, name));\n fileSinks.set(name, sink);\n }\n return sink;\n}\n\nprocess.on(\"exit\", () => {\n for (const sink of fileSinks.values()) sink.close();\n});\n\n/** \u63A8\u9001\u4E00\u6761\u65E5\u5FD7\u5230\u5185\u5B58\u7F13\u51B2,\u5E76\u6309\u7B56\u7565\u843D\u76D8 */\nexport function pushLog(text: string, source: LogSource, level: LogLevel): void {\n buffer.pushDirect(text, source, level);\n const sink = sinkFor(source);\n if (!sink) return;\n const entry: LogEntry = { time: new Date(), text, source, level };\n try {\n sink.write(entry, formatLogLine(entry, false));\n } catch {\n /* \u843D\u76D8\u5931\u8D25\u4E0D\u963B\u65AD\u4E3B\u6D41\u7A0B */\n }\n}\n\n/** \u8BA2\u9605\u65B0\u65E5\u5FD7\u4E8B\u4EF6,\u8FD4\u56DE\u53D6\u6D88\u8BA2\u9605\u51FD\u6570 */\nexport function onLog(fn: (log: UnifiedLog) => void): () => void {\n return buffer.subscribe(fn);\n}\n\n/** \u83B7\u53D6\u5168\u90E8\u65E5\u5FD7 (\u6309\u65F6\u95F4\u987A\u5E8F) */\nexport function getAllLogs(): UnifiedLog[] {\n return buffer.getAll();\n}\n\n/** \u83B7\u53D6\u6700\u8FD1 n \u6761,\u53EF\u6309 level / source \u8FC7\u6EE4 */\nexport function getRecentLogs(n: number, levels: LogLevel[], sources: LogSource[]): UnifiedLog[] {\n return buffer.getRecent(n, levels, sources);\n}\n\n/** \u4ECE\u539F\u59CB\u6587\u672C\u63A8\u65AD\u65E5\u5FD7\u7EA7\u522B (\u59D4\u6258\u5171\u4EAB\u5305) */\nexport function inferLevel(text: string): LogLevel {\n return sharedInferLevel(text);\n}\n\n/* ==================================================================\n * \u6765\u6E90\u6807\u7B7E\u5143\u6570\u636E (\u65B9\u62EC\u53F7\u4E0E\u6587\u5B57\u540C\u8272,\u5BF9\u9F50 levelTag)\n * ================================================================== */\n\nexport interface SourceMeta {\n value: string;\n /** \u663E\u793A\u540D,\u5C3D\u91CF 8 \u5BBD\u5BF9\u9F50 */\n name: string;\n paint: (s: string) => string;\n}\n\nexport const SOURCE_META: SourceMeta[] = [\n { value: \"bds\", name: \"BDServer\", paint: (s) => c.green(s) },\n { value: \"db\", name: \"DataBase\", paint: (s) => c.blue(s) },\n { value: \"qq\", name: \"QQBridge\", paint: (s) => c.purple(s) },\n { value: \"llbot\", name: \" LL-BOT \", paint: (s) => c.yellow(s) },\n { value: \"system\", name: \" SYSTEM \", paint: (s) => c.cyan(s) },\n { value: \"update\", name: \" UPDATE \", paint: (s) => c.orange(s) },\n { value: \"pack\", name: \" PACK \", paint: (s) => c.purple(s) },\n { value: \"bds-tools\", name: \"BDSTools\", paint: (s) => c.red(s) },\n];\n\nexport function formatSourceTag(source: string): string {\n const meta = SOURCE_META.find((m) => m.value === source);\n if (meta) return meta.paint(`[${meta.name}]`);\n return c.bold(`[${source.padEnd(7).slice(0, 8)}]`);\n}\n\n/** \u7B80\u5316BDS\u65E5\u5FD7 */\nfunction stripLogPrefix(line: string): string {\n // \u5339\u914D\u683C\u5F0F: [2026-07-18 23:56:06:778 INFO]\n const prefixRegex = /^\\[\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}:\\d{3} (INFO|WARNING|ERROR|FATAL|DEBUG)\\]\\s*/;\n return line.replace(prefixRegex, \"\");\n}\n\n/**\n * \u4ECE\u4E00\u884C BDS \u65E5\u5FD7\u4E2D\u63D0\u53D6\u65E5\u5FD7\u7B49\u7EA7\n * @param line \u65E5\u5FD7\u884C\u5B57\u7B26\u4E32\n * @returns \u65E5\u5FD7\u7B49\u7EA7\uFF08\u5927\u5199\uFF09\uFF0C\u82E5\u65E0\u6CD5\u8BC6\u522B\u5219\u8FD4\u56DE 'UNKNOWN'\n */\nfunction getLogLevel(line: string): string {\n const levelNames = [\"INFO\", \"WARNING\", \"ERROR\", \"FATAL\", \"DEBUG\", \"TRACE\", \"WARN\"];\n const levelPattern = levelNames.join(\"|\");\n\n let match = line.match(new RegExp(`\\\\[(${levelPattern})\\\\]`, \"i\"));\n if (match && match[1]) return match[1].toUpperCase();\n\n match = line.match(new RegExp(`^\\\\[.*?\\\\]\\\\s*(${levelPattern})`, \"i\"));\n if (match && match[1]) return match[1].toUpperCase();\n\n match = line.match(new RegExp(`^(${levelPattern})\\\\s*:`, \"i\"));\n if (match && match[1]) return match[1].toUpperCase();\n\n match = line.match(new RegExp(`\\\\[.*?\\\\]\\\\s*(${levelPattern})\\\\s*:`, \"i\"));\n if (match && match[1]) return match[1].toUpperCase();\n\n return \"UNKNOWN\";\n}\n\n/** \u683C\u5F0F\u5316\u65E5\u5FD7\u7528\u4E8E REPL \u5C55\u793A (\u7528 theme.ts chalk \u914D\u8272) */\nexport function formatLog(l: UnifiedLog): string {\n const ts = c.dim(l.time.toLocaleTimeString());\n let lvl = levelTag(l.level);\n let txt = highlightLogLine(l.text);\n const src = formatSourceTag(l.source);\n if (l.source === \"bds\") {\n const parsed = getLogLevel(l.text);\n const mapped: LogLevel =\n parsed === \"WARNING\" || parsed === \"WARN\"\n ? \"warn\"\n : parsed === \"ERROR\" || parsed === \"FATAL\"\n ? \"error\"\n : parsed === \"DEBUG\" || parsed === \"TRACE\"\n ? \"debug\"\n : \"info\";\n /* \u53BB\u6389 BDS \u81EA\u5E26\u65F6\u95F4\u6233\u524D\u7F00\u540E\u518D\u9AD8\u4EAE\u6B63\u6587 */\n txt = highlightLogLine(stripLogPrefix(l.text));\n lvl = levelTag(mapped);\n }\n return `${ts} ${src} ${lvl} ${txt}`;\n}\n\nfunction levelTag(lvl: LogLevel): string {\n switch (lvl) {\n case \"error\":\n return c.red(\"[ERR]\");\n case \"warn\":\n return c.yellow(\"[WRN]\");\n case \"success\":\n return c.green(c.bold(\"[OK]\"));\n case \"debug\":\n return c.dim(\"[DBG]\");\n default:\n return c.blue(\"[INF]\");\n }\n}\n\n/* ==================================================================\n * \u8F6F\u6362\u884C: \u8D85\u7EC8\u7AEF\u5BBD\u5EA6\u65F6\u6362\u884C,\u540E\u7EED\u884C\u7F29\u8FDB\u5BF9\u9F50\n * ================================================================== */\n\n/** \u5355\u4E2A\u5B57\u7B26\u5728\u7EC8\u7AEF\u7684\u663E\u793A\u5BBD\u5EA6 (CJK \u5168\u89D2=2, \u5176\u4F59=1) */\nfunction charWidth(ch: string): number {\n const cp = ch.codePointAt(0) ?? 0;\n if (\n cp >= 0x1100 &&\n (cp <= 0x115f ||\n (cp >= 0x2e80 && cp <= 0xa4cf && cp !== 0x303f) ||\n (cp >= 0xac00 && cp <= 0xd7a3) ||\n (cp >= 0xf900 && cp <= 0xfaff) ||\n (cp >= 0xfe30 && cp <= 0xfe4f) ||\n (cp >= 0xff00 && cp <= 0xff60) ||\n (cp >= 0xffe0 && cp <= 0xffe6) ||\n (cp >= 0x20000 && cp <= 0x2fffd))\n )\n return 2;\n return 1;\n}\n\n/** \u5B57\u7B26\u4E32\u5728\u7EC8\u7AEF\u7684\u53EF\u89C1\u5BBD\u5EA6 (strip ANSI \u540E\u6309 CJK \u5BBD\u5EA6\u7D2F\u52A0) */\nexport function visibleWidth(s: string): number {\n const stripped = s.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n let w = 0;\n for (const ch of stripped) w += charWidth(ch);\n return w;\n}\n\n/** \u65E0\u8272\u7EA7\u522B\u6807\u7B7E,\u4E0E levelTag \u53EF\u89C1\u5BBD\u5EA6\u4E00\u81F4 */\nfunction levelTagPlain(lvl: LogLevel): string {\n switch (lvl) {\n case \"error\":\n return \"[ERR]\";\n case \"warn\":\n return \"[WRN]\";\n case \"success\":\n return \"[OK]\";\n case \"debug\":\n return \"[DBG]\";\n default:\n return \"[INF]\";\n }\n}\n\n/**\n * \u65E5\u5FD7\u524D\u7F00\u53EF\u89C1\u5BBD\u5EA6(\u65F6\u95F4 + \u6E90 + \u7EA7\u522B + \u5C3E\u7A7A\u683C),\u4F9B\u60AC\u6302\u7F29\u8FDB\u5BF9\u9F50\u6B63\u6587\u8D77\u70B9\u3002\n * \u4E0E formatLog \u62FC\u63A5\u987A\u5E8F\u4FDD\u6301\u4E00\u81F4\u3002\n */\nexport function logPrefixWidth(l: UnifiedLog): number {\n const ts = l.time.toLocaleTimeString();\n const meta = SOURCE_META.find((m) => m.value === l.source);\n const src = meta ? `[${meta.name}]` : `[${l.source.padEnd(7).slice(0, 8)}]`;\n let level: LogLevel = l.level;\n if (l.source === \"bds\") {\n const parsed = getLogLevel(l.text);\n level =\n parsed === \"WARNING\" || parsed === \"WARN\"\n ? \"warn\"\n : parsed === \"ERROR\" || parsed === \"FATAL\"\n ? \"error\"\n : parsed === \"DEBUG\" || parsed === \"TRACE\"\n ? \"debug\"\n : \"info\";\n }\n return visibleWidth(`${ts} ${src} ${levelTagPlain(level)} `);\n}\n\n/**\n * \u6309\u7EC8\u7AEF\u53EF\u89C1\u5BBD\u5EA6\u6362\u884C;\u663E\u5F0F \\\\n \u4E0E\u8F6F\u6362\u884C\u7684\u540E\u7EED\u884C\u4E00\u5F8B\u5DE6\u4FA7\u7F29\u8FDB indent \u5217\u3002\n * \u4FDD\u7559 ANSI:\u6362\u884C\u65F6 reset,\u65B0\u884C\u6062\u590D\u5F53\u524D\u989C\u8272\u72B6\u6001(\u53EF\u591A\u5C42\u53E0\u52A0)\u3002\n * \u5BBD\u5B57\u7B26(CJK)\u6309 2 \u5217;cols \u9884\u7559 1 \u5217,\u907F\u514D Windows Terminal \u8FB9\u754C\u518D\u8F6F\u6298\u5230\u7B2C 0 \u5217\u3002\n */\nexport function wrapLogLine(s: string, indent: number): string {\n const rawCols = process.stdout.columns || 80;\n /* \u81F3\u5C11\u7559\u7ED9\u6B63\u6587\u82E5\u5E72\u5217,\u907F\u514D indent >= cols \u65F6\u6B7B\u5FAA\u73AF */\n const cols = Math.max(rawCols - 1, indent + 4);\n const segments = s.split(/\\r?\\n/);\n const out: string[] = [];\n for (let si = 0; si < segments.length; si++) {\n const raw = segments[si]!;\n /* \u663E\u5F0F\u6362\u884C\u6BB5\u53BB\u6389\u6587\u6848\u81EA\u5E26\u7684\u5DE6\u7A7A\u683C,\u7EDF\u4E00\u7531 hang indent \u5BF9\u9F50\u6B63\u6587 */\n const piece = si === 0 ? raw : raw.replace(/^[ \\t]+/, \"\");\n out.push(wrapSegment(piece, cols, si === 0 ? 0 : indent, indent));\n }\n return out.join(\"\\n\");\n}\n\n/** \u5355\u6BB5(\u65E0\u5185\u5D4C \\\\n)\u8F6F\u6362\u884C;startPad>0 \u8868\u793A\u672C\u6BB5\u5F00\u5934\u5DF2\u5360\u7528\u7684\u5217(\u663E\u5F0F\u6362\u884C\u540E\u7684\u60AC\u6302) */\nfunction wrapSegment(s: string, cols: number, startPad: number, hangIndent: number): string {\n if (s.length === 0) return startPad > 0 ? \" \".repeat(startPad) : \"\";\n\n const lines: string[] = [];\n let cur = startPad > 0 ? \" \".repeat(startPad) : \"\";\n let w = startPad;\n /** \u5F53\u524D\u751F\u6548\u7684 ANSI \u5F00\u7801\u6808(\u4E0D\u542B reset),\u6362\u884C\u540E\u91CD\u653E */\n const ansiStack: string[] = [];\n\n const resetIfNeeded = (): void => {\n if (ansiStack.length) cur += \"\\x1b[0m\";\n };\n const replayAnsi = (): void => {\n for (const code of ansiStack) cur += code;\n };\n\n let i = 0;\n while (i < s.length) {\n const m = /^\\x1b\\[[0-9;]*m/.exec(s.slice(i));\n if (m) {\n const code = m[0]!;\n cur += code;\n if (code === \"\\x1b[0m\") ansiStack.length = 0;\n else ansiStack.push(code);\n i += code.length;\n continue;\n }\n\n const cp = s.codePointAt(i)!;\n const ch = String.fromCodePoint(cp);\n const cw = charWidth(ch);\n const advance = ch.length;\n\n /* w > startPad:\u5F53\u524D\u884C\u9664\u5DE6\u57AB\u5916\u5DF2\u6709\u5185\u5BB9,\u53EF\u4EE5\u62C6\u884C;\u5426\u5219\u5F3A\u5236\u585E\u5165\u907F\u514D\u6B7B\u5FAA\u73AF */\n if (w + cw > cols && w > startPad) {\n resetIfNeeded();\n lines.push(cur);\n cur = \" \".repeat(hangIndent);\n replayAnsi();\n w = hangIndent;\n startPad = hangIndent;\n }\n\n cur += ch;\n w += cw;\n i += advance;\n }\n\n if (ansiStack.length) cur += \"\\x1b[0m\";\n lines.push(cur);\n return lines.join(\"\\n\");\n}\n\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }