@sfmc-bds/cli 0.6.1 → 0.8.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 (39) hide show
  1. package/dist/logs.d.ts +21 -0
  2. package/dist/logs.d.ts.map +1 -1
  3. package/dist/logs.js +67 -1
  4. package/dist/logs.js.map +2 -2
  5. package/dist/management/config.d.ts.map +1 -1
  6. package/dist/management/config.js +5 -1
  7. package/dist/management/config.js.map +2 -2
  8. package/dist/management/domain.d.ts +46 -2
  9. package/dist/management/domain.d.ts.map +1 -1
  10. package/dist/management/domain.js +112 -26
  11. package/dist/management/domain.js.map +2 -2
  12. package/dist/management/maintenance.d.ts +8 -0
  13. package/dist/management/maintenance.d.ts.map +1 -1
  14. package/dist/management/maintenance.js +18 -0
  15. package/dist/management/maintenance.js.map +2 -2
  16. package/dist/management/pack-import.d.ts +29 -0
  17. package/dist/management/pack-import.d.ts.map +1 -0
  18. package/dist/management/pack-import.js +108 -0
  19. package/dist/management/pack-import.js.map +7 -0
  20. package/dist/management/server.d.ts.map +1 -1
  21. package/dist/management/server.js +67 -10
  22. package/dist/management/server.js.map +2 -2
  23. package/dist/module-sidecars.d.ts.map +1 -1
  24. package/dist/module-sidecars.js +23 -0
  25. package/dist/module-sidecars.js.map +2 -2
  26. package/dist/registry.d.ts +11 -5
  27. package/dist/registry.d.ts.map +1 -1
  28. package/dist/registry.js +35 -11
  29. package/dist/registry.js.map +2 -2
  30. package/dist/services.d.ts.map +1 -1
  31. package/dist/services.js +14 -0
  32. package/dist/services.js.map +2 -2
  33. package/dist/world-packs.d.ts +47 -0
  34. package/dist/world-packs.d.ts.map +1 -1
  35. package/dist/world-packs.js +38 -11
  36. package/dist/world-packs.js.map +2 -2
  37. package/package.json +7 -7
  38. package/scripts/module-install/.sfmc-registry-cache.json +151 -28
  39. package/scripts/module-install/lib/registry-index.mjs +50 -13
package/dist/logs.d.ts CHANGED
@@ -48,12 +48,33 @@ export type ReadDiskLogsOpts = {
48
48
  dir?: string;
49
49
  /** 仅保留时间序最后 N 条;省略则返回全部解析结果 */
50
50
  limit?: number;
51
+ /** 含此时间。设置后读取整个日志文件,不再只取文件末尾 */
52
+ since?: Date;
53
+ /** 含此时间 */
54
+ until?: Date;
55
+ };
56
+ /** 删除落盘日志时的筛选。使用场景:桌面 logs.delete。 */
57
+ export type DeleteDiskLogsOpts = {
58
+ since: Date;
59
+ until: Date;
60
+ source?: string;
61
+ text?: string;
62
+ /** 覆盖日志目录(测试用) */
63
+ dir?: string;
51
64
  };
52
65
  /**
53
66
  * 从 `.sfmc/logs/*.log` 读取并解析为 UnifiedLog(按时间升序)。
54
67
  * CLI 重连后主面板 /logs 的历史权威来源;内存缓冲仅承载本进程订阅到的实时增量。
55
68
  */
56
69
  export declare function readDiskLogs(opts?: ReadDiskLogsOpts): UnifiedLog[];
70
+ /**
71
+ * 按时间范围删除已知日志文件中的行。
72
+ * 使用场景:桌面 logs.delete。符号链接和非文件直接拒绝。
73
+ * 写入前会再读一次期间追加的内容;替换文件的瞬间新写入的行可能留下来。
74
+ */
75
+ export declare function deleteStoredLogs(opts: DeleteDiskLogsOpts): {
76
+ removed: number;
77
+ };
57
78
  export interface SourceMeta {
58
79
  value: string;
59
80
  /** 方括号内固定 3 字符,与 [INF] 对齐 */
@@ -1 +1 @@
1
- {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAQL,KAAK,QAAQ,EACb,KAAK,QAAQ,IAAI,cAAc,EAChC,MAAM,oBAAoB,CAAC;AAa5B,MAAM,MAAM,QAAQ,GAAG,cAAc,CAAC;AACtC,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAC/B,MAAM,WAAW,UAAW,SAAQ,QAAQ;CAAG;AAE/C,wDAAwD;AACxD,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAShG,yCAAyC;AACzC,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG/D;AAwBD,yBAAyB;AACzB,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CA+C9E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CAEtF;AAED,uBAAuB;AACvB,wBAAgB,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI,CAE/D;AAED,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,UAAU,EAAE,CAG/F;AAED,qDAAqD;AACrD,wBAAgB,UAAU,IAAI,UAAU,EAAE,CAGzC;AASD,6BAA6B;AAC7B,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAIxD;AAuBD,2BAA2B;AAC3B,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAS/D;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;IACtB,yCAAyC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,gBAAqB,GAAG,UAAU,EAAE,CA6CtE;AAMD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CAC9B;AAED,eAAO,MAAM,WAAW,EAAE,UAAU,EASnC,CAAC;AASF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKtD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,UAAU,GAAG,QAAQ,CAM3D;AAED,oCAAoC;AACpC,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAEjD;AA+BD,4CAA4C;AAC5C,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAW/C;AAwBD,2CAA2C;AAC3C,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK9C;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAKpD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAa7D"}
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"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"}
package/dist/logs.js CHANGED
@@ -134,6 +134,9 @@ function readDiskLogs(opts = {}) {
134
134
  const levels = opts.levels ?? [];
135
135
  const sources = opts.sources ?? [];
136
136
  const dir = opts.dir ?? logsDir(ROOT);
137
+ const sinceMs = opts.since?.getTime();
138
+ const untilMs = opts.until?.getTime();
139
+ const ranged = sinceMs !== void 0 || untilMs !== void 0;
137
140
  const fileNames = /* @__PURE__ */ new Set();
138
141
  if (sources.length === 0) {
139
142
  for (const n of DISK_LOG_FILES) fileNames.add(n);
@@ -145,7 +148,7 @@ function readDiskLogs(opts = {}) {
145
148
  const fp = path.join(dir, name.endsWith(".log") ? name : `${name}.log`);
146
149
  let text;
147
150
  try {
148
- if (opts.limit) {
151
+ if (opts.limit && !ranged) {
149
152
  const fd = fs.openSync(fp, "r");
150
153
  try {
151
154
  const size = fs.fstatSync(fd).size;
@@ -165,6 +168,9 @@ function readDiskLogs(opts = {}) {
165
168
  if (!raw) continue;
166
169
  const entry = parseDiskLogLine(raw);
167
170
  if (!entry) continue;
171
+ const time = entry.time.getTime();
172
+ if (sinceMs !== void 0 && time < sinceMs) continue;
173
+ if (untilMs !== void 0 && time > untilMs) continue;
168
174
  if (sources.length && !sources.includes(entry.source)) continue;
169
175
  if (levels.length && !levels.includes(entry.level)) continue;
170
176
  out.push(entry);
@@ -177,6 +183,65 @@ function readDiskLogs(opts = {}) {
177
183
  }
178
184
  return out;
179
185
  }
186
+ function diskLineMatchesRemoval(entry, opts) {
187
+ const time = entry.time.getTime();
188
+ if (time < opts.since.getTime() || time > opts.until.getTime()) return false;
189
+ if (opts.source !== void 0 && entry.source !== opts.source) return false;
190
+ if (opts.text !== void 0 && entry.text !== opts.text) return false;
191
+ return true;
192
+ }
193
+ function filterLogText(text, opts) {
194
+ if (!text) return { text: "", removed: 0 };
195
+ const newline = text.includes("\r\n") ? "\r\n" : "\n";
196
+ const ended = text.endsWith("\n");
197
+ const lines = text.split(/\r?\n/);
198
+ if (ended) lines.pop();
199
+ let removed = 0;
200
+ const kept = [];
201
+ for (const raw of lines) {
202
+ const entry = raw ? parseDiskLogLine(raw) : null;
203
+ if (entry && diskLineMatchesRemoval(entry, opts)) {
204
+ removed++;
205
+ continue;
206
+ }
207
+ kept.push(raw);
208
+ }
209
+ if (!kept.length) return { text: "", removed };
210
+ return { text: kept.join(newline) + (ended ? newline : ""), removed };
211
+ }
212
+ function deleteStoredLogs(opts) {
213
+ if (opts.until.getTime() < opts.since.getTime()) throw new Error("\u7ED3\u675F\u65F6\u95F4\u4E0D\u80FD\u65E9\u4E8E\u5F00\u59CB\u65F6\u95F4");
214
+ const dir = opts.dir ?? logsDir(ROOT);
215
+ let removed = 0;
216
+ for (const name of DISK_LOG_FILES) {
217
+ const file = path.join(dir, `${name}.log`);
218
+ removed += rewriteLogFile(file, opts);
219
+ }
220
+ return { removed };
221
+ }
222
+ function rewriteLogFile(file, opts) {
223
+ let stat;
224
+ try {
225
+ stat = fs.lstatSync(file);
226
+ } catch (error) {
227
+ if (error.code === "ENOENT") return 0;
228
+ throw error;
229
+ }
230
+ if (stat.isSymbolicLink()) throw new Error(`\u62D2\u7EDD\u6539\u5199\u7B26\u53F7\u94FE\u63A5\u65E5\u5FD7 ${path.basename(file)}`);
231
+ if (!stat.isFile()) throw new Error(`\u62D2\u7EDD\u6539\u5199\u975E\u6587\u4EF6\u65E5\u5FD7 ${path.basename(file)}`);
232
+ let text = fs.readFileSync(file, "utf8");
233
+ if (fs.statSync(file).size > Buffer.byteLength(text)) text = fs.readFileSync(file, "utf8");
234
+ const filtered = filterLogText(text, opts);
235
+ if (!filtered.removed) return 0;
236
+ const temp = `${file}.${process.pid}.filtering`;
237
+ fs.writeFileSync(temp, filtered.text, "utf8");
238
+ try {
239
+ fs.copyFileSync(temp, file);
240
+ } finally {
241
+ fs.rmSync(temp, { force: true });
242
+ }
243
+ return filtered.removed;
244
+ }
180
245
  const SOURCE_META = [
181
246
  { value: "bds", name: "BDS", paint: (s) => c.green(s) },
182
247
  { value: "db", name: "DB ", paint: (s) => c.blue(s) },
@@ -319,6 +384,7 @@ function wrapSegment(s, cols, startPad, hangIndent) {
319
384
  }
320
385
  export {
321
386
  SOURCE_META,
387
+ deleteStoredLogs,
322
388
  diskFileForSource,
323
389
  formatLog,
324
390
  formatSourceTag,
package/dist/logs.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
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 * CLI \u91CD\u8FDE\u540E\u5386\u53F2\u56DE\u653E\u4EE5\u843D\u76D8\u4E3A\u51C6\uFF08readDiskLogs\uFF09\uFF1B\u5185\u5B58\u7F13\u51B2\u53EA\u670D\u52A1\u672C\u8FDB\u7A0B\u5B9E\u65F6\u8BA2\u9605\u3002\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 parseBdsEmbeddedLevel,\n stripBdsLogPrefix,\n type FileSink,\n type LogEntry,\n type LogLevel as SharedLogLevel,\n} from \"@sfmc-bds/sdk/logs\";\nimport { logFile, logsDir } from \"@sfmc-bds/sdk/node/config\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport {\n getCompiledLogFilter,\n shouldDropForDisk,\n shouldDropForDisplay,\n transformLogEntry,\n} from \"./log-filter.js\";\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\n/** \u518D\u5BFC\u51FA SDK BDS \u89E3\u6790\uFF08\u6D4B\u8BD5\u4E0E\u8C03\u7528\u65B9\u7EDF\u4E00\u5165\u53E3\uFF0C\u6743\u5A01\u5728 @sfmc-bds/sdk/logs\uFF09 */\nexport { mapBdsLevelToken, parseBdsEmbeddedLevel, stripBdsLogPrefix } from \"@sfmc-bds/sdk/logs\";\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/** \u5265\u79BB BDS \u81EA\u5E26\u524D\u7F00\uFF1B\u82E5\u524D\u7F00\u540E\u6CA1\u6709\u6B63\u6587\uFF0C\u5219\u5224\u5B9A\u4E3A\u4EC5\u7528\u4E8E\u6392\u7248\u7684\u7A7A\u884C\u3002 */\nexport function normalizeBdsLogBody(text: string): string | null {\n const body = stripBdsLogPrefix(text);\n return body.trim().length > 0 ? body : null;\n}\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\" || source === \"tunnel\") 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 let body = text;\n let lvl = level;\n /* BDS\uFF1A\u5148\u63D0\u53D6\u5185\u5D4C\u7EA7\u522B\uFF0C\u518D\u5265\u6389\u81EA\u5E26\u65F6\u95F4\u6233+\u7B49\u7EA7\uFF0C\u907F\u514D\u5C55\u793A/\u843D\u76D8\u91CD\u590D */\n if (source === \"bds\") {\n const embedded = parseBdsEmbeddedLevel(text);\n if (embedded) lvl = embedded;\n const normalized = normalizeBdsLogBody(text);\n if (normalized === null) return;\n body = normalized;\n }\n\n const rawEntry: LogEntry = { time: new Date(), text: body, source, level: lvl };\n const filter = getCompiledLogFilter((src) => {\n /* \u907F\u514D\u9012\u5F52\uFF1A\u975E\u6CD5\u6B63\u5219\u53EA\u5199\u6587\u4EF6 sink\uFF0C\u4E0D\u7ECF pushLog */\n try {\n const sink = sinkFor(\"system\");\n if (!sink) return;\n const warn: LogEntry = {\n time: new Date(),\n text: `log-filter: invalid regex skipped: ${src}`,\n source: \"system\",\n level: \"warn\",\n };\n sink.write(warn, formatLogLine(warn, false));\n } catch {\n /* ignore */\n }\n });\n\n const dropDisplay = shouldDropForDisplay(rawEntry, filter);\n const dropDisk = shouldDropForDisk(rawEntry, filter);\n const { entry: transformedEntry } = transformLogEntry(rawEntry, filter);\n\n if (!dropDisplay) {\n buffer.pushDirect(transformedEntry.text, source, lvl);\n }\n\n if (dropDisk) return;\n const sink = sinkFor(source);\n if (!sink) return;\n try {\n const diskEntry: LogEntry = filter.applyTo === \"all\" ? { ...rawEntry, text: transformedEntry.text } : rawEntry;\n sink.write(diskEntry, formatLogLine(diskEntry, false));\n } catch {\n /* \u843D\u76D8\u5931\u8D25\u4E0D\u963B\u65AD\u4E3B\u6D41\u7A0B */\n }\n}\n\n/**\n * \u6444\u5165\u5B88\u62A4\u8FDB\u7A0B\u8F6C\u53D1\u7684\u8FDC\u7A0B\u65E5\u5FD7\uFF1A\u53EA\u5199\u5165\u672C\u8FDB\u7A0B\u5185\u5B58\u7F13\u51B2\u5E76\u901A\u77E5\u8BA2\u9605\u8005\uFF0C\u4E0D\u518D\u843D\u76D8\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1ACLI \u5BA2\u6237\u7AEF subscribe \u540E\u628A daemon \u63A8\u9001\u7684 log \u4E8B\u4EF6\u704C\u5165\u672C\u5730\uFF0C\u4F9B REPL \u4E3B\u9762\u677F\u5B9E\u65F6\u5C55\u793A\uFF1B\n * \u843D\u76D8\u5DF2\u7531\u5B88\u62A4\u8FDB\u7A0B\u5B8C\u6210\uFF0C\u6B64\u5904\u8DF3\u8FC7\u907F\u514D\u91CD\u590D\u5199 `.sfmc/logs/*`\u3002\n */\nexport function ingestRemoteLog(text: string, source: LogSource, level: LogLevel): void {\n buffer.pushDirect(text, source, level);\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\u6700\u8FD1 n \u6761,\u53EF\u6309 level / source \u8FC7\u6EE4\uFF1B\u518D\u5957\u914D\u7F6E\u8FC7\u6EE4\uFF08display\uFF09 */\nexport function getRecentLogs(n: number, levels: LogLevel[], sources: LogSource[]): UnifiedLog[] {\n const filter = getCompiledLogFilter();\n return buffer.getRecent(n, levels, sources).filter((l) => !shouldDropForDisplay(l, filter));\n}\n\n/** \u83B7\u53D6\u5168\u90E8\u65E5\u5FD7\uFF1B\u914D\u7F6E\u8FC7\u6EE4\u4EC5\u5F71\u54CD\u8FD4\u56DE\u89C6\u56FE\uFF08\u7F13\u51B2\u5185\u53EF\u80FD\u4ECD\u6709\u5168\u91CF\uFF0C\u89C6 push \u65F6 applyTo\uFF09 */\nexport function getAllLogs(): UnifiedLog[] {\n const filter = getCompiledLogFilter();\n return buffer.getAll().filter((l) => !shouldDropForDisplay(l, filter));\n}\n\n/* ==================================================================\n * \u843D\u76D8\u6587\u4EF6\u8BFB\u53D6\uFF08/logs \u7A97\u7528\uFF0C\u4E0D\u8D70\u5185\u5B58\u7F13\u51B2\uFF09\n * ================================================================== */\n\n/** \u4E0E\u843D\u76D8\u7B56\u7565\u5BF9\u5E94\u7684\u6587\u4EF6\u57FA\u540D\uFF08\u4E0D\u542B .log\uFF09 */\nconst DISK_LOG_FILES = [\"bds\", \"llbot\", \"tunnel\", \"db\", \"qq\", \"bds-update\", \"sfmc\"] as const;\n\n/** source \u2192 \u843D\u76D8\u6587\u4EF6\u540D\uFF08\u542B\u5B50\u8FDB\u7A0B\u81EA\u5199\uFF09 */\nexport function diskFileForSource(source: string): string {\n if (source === \"update\") return \"bds-update\";\n if (source === \"bds\" || source === \"llbot\" || source === \"tunnel\" || source === \"db\" || source === \"qq\") return source;\n return \"sfmc\";\n}\n\n/** formatLogLine \u65E0\u8272\u884C\uFF1A`YYYY-MM-DD HH:mm:ss [source] [LEVEL] text` */\nconst DISK_LINE_RE =\n /^(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}) \\[([^\\]]+)\\] \\[(INFO|WARN|ERROR|OK|DEBUG|SUCCESS|FATAL)\\]\\s?(.*)$/;\n\nfunction mapDiskLevelTag(tag: string): LogLevel {\n switch (tag) {\n case \"ERROR\":\n case \"FATAL\":\n return \"error\";\n case \"WARN\":\n return \"warn\";\n case \"OK\":\n case \"SUCCESS\":\n return \"success\";\n case \"DEBUG\":\n return \"debug\";\n default:\n return \"info\";\n }\n}\n\n/** \u89E3\u6790\u5355\u884C\u843D\u76D8\u65E5\u5FD7\uFF1B\u4E0D\u7B26\u683C\u5F0F\u8FD4\u56DE null */\nexport function parseDiskLogLine(raw: string): UnifiedLog | null {\n const m = DISK_LINE_RE.exec(raw);\n if (!m) return null;\n const ts = m[1]!;\n const source = m[2]!.trim();\n const level = mapDiskLevelTag(m[3]!);\n const body = m[4] ?? \"\";\n const time = new Date(ts.replace(\" \", \"T\") + \"Z\");\n return { time, source, level, text: body };\n}\n\nexport type ReadDiskLogsOpts = {\n levels?: LogLevel[];\n sources?: LogSource[];\n /** \u8986\u76D6\u65E5\u5FD7\u76EE\u5F55\uFF08\u6D4B\u8BD5\u7528\uFF09\uFF1B\u9ED8\u8BA4 `<ROOT>/.sfmc/logs` */\n dir?: string;\n /** \u4EC5\u4FDD\u7559\u65F6\u95F4\u5E8F\u6700\u540E N \u6761\uFF1B\u7701\u7565\u5219\u8FD4\u56DE\u5168\u90E8\u89E3\u6790\u7ED3\u679C */\n limit?: number;\n};\n\n/**\n * \u4ECE `.sfmc/logs/*.log` \u8BFB\u53D6\u5E76\u89E3\u6790\u4E3A UnifiedLog\uFF08\u6309\u65F6\u95F4\u5347\u5E8F\uFF09\u3002\n * CLI \u91CD\u8FDE\u540E\u4E3B\u9762\u677F /logs \u7684\u5386\u53F2\u6743\u5A01\u6765\u6E90\uFF1B\u5185\u5B58\u7F13\u51B2\u4EC5\u627F\u8F7D\u672C\u8FDB\u7A0B\u8BA2\u9605\u5230\u7684\u5B9E\u65F6\u589E\u91CF\u3002\n */\nexport function readDiskLogs(opts: ReadDiskLogsOpts = {}): UnifiedLog[] {\n const levels = opts.levels ?? [];\n const sources = opts.sources ?? [];\n const dir = opts.dir ?? logsDir(ROOT);\n const fileNames = new Set<string>();\n if (sources.length === 0) {\n for (const n of DISK_LOG_FILES) fileNames.add(n);\n } else {\n for (const s of sources) fileNames.add(diskFileForSource(s));\n }\n\n const out: UnifiedLog[] = [];\n for (const name of fileNames) {\n const fp = path.join(dir, name.endsWith(\".log\") ? name : `${name}.log`);\n let text: string;\n try {\n if (opts.limit) {\n const fd = fs.openSync(fp, \"r\");\n try {\n const size = fs.fstatSync(fd).size;\n const start = Math.max(0, size - 4 * 1024 * 1024);\n const bytes = Buffer.alloc(size - start);\n fs.readSync(fd, bytes, 0, bytes.length, start);\n text = bytes.toString(\"utf8\");\n if (start > 0) text = text.slice(text.indexOf(\"\\n\") + 1);\n } finally { fs.closeSync(fd); }\n } else text = fs.readFileSync(fp, \"utf8\");\n } catch {\n continue;\n }\n for (const raw of text.split(/\\r?\\n/)) {\n if (!raw) continue;\n const entry = parseDiskLogLine(raw);\n if (!entry) continue;\n if (sources.length && !sources.includes(entry.source)) continue;\n if (levels.length && !levels.includes(entry.level)) continue;\n out.push(entry);\n }\n }\n out.sort((a, b) => a.time.getTime() - b.time.getTime());\n const limit = opts.limit;\n if (limit !== undefined && limit > 0 && out.length > limit) {\n return out.slice(out.length - limit);\n }\n return out;\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 /** \u65B9\u62EC\u53F7\u5185\u56FA\u5B9A 3 \u5B57\u7B26\uFF0C\u4E0E [INF] \u5BF9\u9F50 */\n name: string;\n paint: (s: string) => string;\n}\n\nexport const SOURCE_META: SourceMeta[] = [\n { value: \"bds\", name: \"BDS\", paint: (s) => c.green(s) },\n { value: \"db\", name: \"DB \", paint: (s) => c.blue(s) },\n { value: \"qq\", name: \"QQ \", paint: (s) => c.purple(s) },\n { value: \"llbot\", name: \"BOT\", paint: (s) => c.yellow(s) },\n { value: \"system\", name: \"SYS\", paint: (s) => c.cyan(s) },\n { value: \"update\", name: \"UPD\", paint: (s) => c.orange(s) },\n { value: \"pack\", name: \"PAK\", paint: (s) => c.purple(s) },\n { value: \"bds-tools\", name: \"TOL\", paint: (s) => c.red(s) },\n];\n\n/** \u6E90\u6807\u7B7E\u65E0\u8272\u6587\u672C\uFF08formatSourceTag / logPrefixWidth \u5171\u7528\uFF09 */\nfunction sourceTagPlain(source: string): string {\n const meta = SOURCE_META.find((m) => m.value === source);\n if (meta) return `[${meta.name}]`;\n return `[${source.toUpperCase().padEnd(3).slice(0, 3)}]`;\n}\n\nexport function formatSourceTag(source: string): string {\n const meta = SOURCE_META.find((m) => m.value === source);\n const plain = sourceTagPlain(source);\n if (meta) return meta.paint(plain);\n return c.bold(plain);\n}\n\n/**\n * \u5C55\u793A\u7528\u7EA7\u522B\uFF1ABDS \u82E5\u4ECD\u5E26\u65F6\u95F4\u6233\u524D\u7F00\u5219\u89E3\u6790\u5185\u5D4C\u7EA7\u522B\uFF1B\u5DF2\u5265\u79BB\uFF08pushLog \u5165\u5E93\uFF09\u5219\u4FE1\u4EFB entry.level\u3002\n * \u7981\u6B62\u5BF9\u6B63\u6587\u505A\u677E\u6563\u5173\u952E\u8BCD\u5339\u914D\uFF08\u4F1A\u628A `[Commands] Error on line` \u8BEF\u5224\u4E3A error\uFF09\u3002\n */\nexport function resolveDisplayLevel(l: UnifiedLog): LogLevel {\n if (l.source === \"bds\") {\n const embedded = parseBdsEmbeddedLevel(l.text);\n if (embedded) return embedded;\n }\n return l.level;\n}\n\n/** \u4ECE\u539F\u59CB\u6587\u672C\u63A8\u65AD\u7EA7\u522B\uFF1A\u59D4\u6258\u5171\u4EAB\u5305\uFF08\u5185\u542B BDS \u65F6\u95F4\u6233\u89E3\u6790\uFF09 */\nexport function inferLevel(text: string): LogLevel {\n return sharedInferLevel(text);\n}\n\n/** \u65E0\u8272\u7EA7\u522B\u6807\u7B7E\u6587\u672C\uFF08\u53EF\u89C1\u5BBD\u5EA6\u6743\u5A01\u6E90\uFF1B\u62EC\u53F7\u5185\u5747\u4E3A 3 \u5B57\u7B26\uFF09 */\nconst LEVEL_TAG_TEXT: Record<LogLevel, string> = {\n error: \"[ERR]\",\n warn: \"[WRN]\",\n success: \"[SUC]\",\n debug: \"[DBG]\",\n info: \"[INF]\",\n};\n\nfunction levelTagPlain(lvl: LogLevel): string {\n return LEVEL_TAG_TEXT[lvl] ?? LEVEL_TAG_TEXT.info;\n}\n\nfunction levelTag(lvl: LogLevel): string {\n const text = levelTagPlain(lvl);\n switch (lvl) {\n case \"error\":\n return c.red(text);\n case \"warn\":\n return c.yellow(text);\n case \"success\":\n return c.green(c.bold(text));\n case \"debug\":\n return c.dim(text);\n default:\n return c.blue(text);\n }\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 const level = resolveDisplayLevel(l);\n const lvl = levelTag(level);\n const src = formatSourceTag(l.source);\n /* BDS\uFF1A\u53BB\u6389\u81EA\u5E26\u65F6\u95F4\u6233+\u7B49\u7EA7\u524D\u7F00\u540E\u518D\u672C\u5730\u5316\u7FFB\u8BD1\u4E0E\u9AD8\u4EAE\u6B63\u6587\uFF08push \u65F6\u591A\u534A\u5DF2\u8F6C\u8FC7\uFF0C\u6B64\u5904\u5E42\u7B49\u4E14\u8986\u76D6\u56DE\u653E\uFF09 */\n const body = l.source === \"bds\" ? stripBdsLogPrefix(l.text) : l.text;\n const filter = getCompiledLogFilter();\n const { entry } = transformLogEntry({ text: body, source: l.source, level }, filter);\n const txt = highlightLogLine(entry.text);\n return `${ts} ${src} ${lvl} ${txt}`;\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/**\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\uFF08\u5171\u7528 resolveDisplayLevel / sourceTagPlain / levelTagPlain\uFF09\u3002\n */\nexport function logPrefixWidth(l: UnifiedLog): number {\n const ts = l.time.toLocaleTimeString();\n const src = sourceTagPlain(l.source);\n const level = resolveDisplayLevel(l);\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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",
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 * CLI \u91CD\u8FDE\u540E\u5386\u53F2\u56DE\u653E\u4EE5\u843D\u76D8\u4E3A\u51C6\uFF08readDiskLogs\uFF09\uFF1B\u5185\u5B58\u7F13\u51B2\u53EA\u670D\u52A1\u672C\u8FDB\u7A0B\u5B9E\u65F6\u8BA2\u9605\u3002\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 parseBdsEmbeddedLevel,\n stripBdsLogPrefix,\n type FileSink,\n type LogEntry,\n type LogLevel as SharedLogLevel,\n} from \"@sfmc-bds/sdk/logs\";\nimport { logFile, logsDir } from \"@sfmc-bds/sdk/node/config\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport {\n getCompiledLogFilter,\n shouldDropForDisk,\n shouldDropForDisplay,\n transformLogEntry,\n} from \"./log-filter.js\";\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\n/** \u518D\u5BFC\u51FA SDK BDS \u89E3\u6790\uFF08\u6D4B\u8BD5\u4E0E\u8C03\u7528\u65B9\u7EDF\u4E00\u5165\u53E3\uFF0C\u6743\u5A01\u5728 @sfmc-bds/sdk/logs\uFF09 */\nexport { mapBdsLevelToken, parseBdsEmbeddedLevel, stripBdsLogPrefix } from \"@sfmc-bds/sdk/logs\";\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/** \u5265\u79BB BDS \u81EA\u5E26\u524D\u7F00\uFF1B\u82E5\u524D\u7F00\u540E\u6CA1\u6709\u6B63\u6587\uFF0C\u5219\u5224\u5B9A\u4E3A\u4EC5\u7528\u4E8E\u6392\u7248\u7684\u7A7A\u884C\u3002 */\nexport function normalizeBdsLogBody(text: string): string | null {\n const body = stripBdsLogPrefix(text);\n return body.trim().length > 0 ? body : null;\n}\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\" || source === \"tunnel\") 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 let body = text;\n let lvl = level;\n /* BDS\uFF1A\u5148\u63D0\u53D6\u5185\u5D4C\u7EA7\u522B\uFF0C\u518D\u5265\u6389\u81EA\u5E26\u65F6\u95F4\u6233+\u7B49\u7EA7\uFF0C\u907F\u514D\u5C55\u793A/\u843D\u76D8\u91CD\u590D */\n if (source === \"bds\") {\n const embedded = parseBdsEmbeddedLevel(text);\n if (embedded) lvl = embedded;\n const normalized = normalizeBdsLogBody(text);\n if (normalized === null) return;\n body = normalized;\n }\n\n const rawEntry: LogEntry = { time: new Date(), text: body, source, level: lvl };\n const filter = getCompiledLogFilter((src) => {\n /* \u907F\u514D\u9012\u5F52\uFF1A\u975E\u6CD5\u6B63\u5219\u53EA\u5199\u6587\u4EF6 sink\uFF0C\u4E0D\u7ECF pushLog */\n try {\n const sink = sinkFor(\"system\");\n if (!sink) return;\n const warn: LogEntry = {\n time: new Date(),\n text: `log-filter: invalid regex skipped: ${src}`,\n source: \"system\",\n level: \"warn\",\n };\n sink.write(warn, formatLogLine(warn, false));\n } catch {\n /* ignore */\n }\n });\n\n const dropDisplay = shouldDropForDisplay(rawEntry, filter);\n const dropDisk = shouldDropForDisk(rawEntry, filter);\n const { entry: transformedEntry } = transformLogEntry(rawEntry, filter);\n\n if (!dropDisplay) {\n buffer.pushDirect(transformedEntry.text, source, lvl);\n }\n\n if (dropDisk) return;\n const sink = sinkFor(source);\n if (!sink) return;\n try {\n const diskEntry: LogEntry = filter.applyTo === \"all\" ? { ...rawEntry, text: transformedEntry.text } : rawEntry;\n sink.write(diskEntry, formatLogLine(diskEntry, false));\n } catch {\n /* \u843D\u76D8\u5931\u8D25\u4E0D\u963B\u65AD\u4E3B\u6D41\u7A0B */\n }\n}\n\n/**\n * \u6444\u5165\u5B88\u62A4\u8FDB\u7A0B\u8F6C\u53D1\u7684\u8FDC\u7A0B\u65E5\u5FD7\uFF1A\u53EA\u5199\u5165\u672C\u8FDB\u7A0B\u5185\u5B58\u7F13\u51B2\u5E76\u901A\u77E5\u8BA2\u9605\u8005\uFF0C\u4E0D\u518D\u843D\u76D8\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1ACLI \u5BA2\u6237\u7AEF subscribe \u540E\u628A daemon \u63A8\u9001\u7684 log \u4E8B\u4EF6\u704C\u5165\u672C\u5730\uFF0C\u4F9B REPL \u4E3B\u9762\u677F\u5B9E\u65F6\u5C55\u793A\uFF1B\n * \u843D\u76D8\u5DF2\u7531\u5B88\u62A4\u8FDB\u7A0B\u5B8C\u6210\uFF0C\u6B64\u5904\u8DF3\u8FC7\u907F\u514D\u91CD\u590D\u5199 `.sfmc/logs/*`\u3002\n */\nexport function ingestRemoteLog(text: string, source: LogSource, level: LogLevel): void {\n buffer.pushDirect(text, source, level);\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\u6700\u8FD1 n \u6761,\u53EF\u6309 level / source \u8FC7\u6EE4\uFF1B\u518D\u5957\u914D\u7F6E\u8FC7\u6EE4\uFF08display\uFF09 */\nexport function getRecentLogs(n: number, levels: LogLevel[], sources: LogSource[]): UnifiedLog[] {\n const filter = getCompiledLogFilter();\n return buffer.getRecent(n, levels, sources).filter((l) => !shouldDropForDisplay(l, filter));\n}\n\n/** \u83B7\u53D6\u5168\u90E8\u65E5\u5FD7\uFF1B\u914D\u7F6E\u8FC7\u6EE4\u4EC5\u5F71\u54CD\u8FD4\u56DE\u89C6\u56FE\uFF08\u7F13\u51B2\u5185\u53EF\u80FD\u4ECD\u6709\u5168\u91CF\uFF0C\u89C6 push \u65F6 applyTo\uFF09 */\nexport function getAllLogs(): UnifiedLog[] {\n const filter = getCompiledLogFilter();\n return buffer.getAll().filter((l) => !shouldDropForDisplay(l, filter));\n}\n\n/* ==================================================================\n * \u843D\u76D8\u6587\u4EF6\u8BFB\u53D6\uFF08/logs \u7A97\u7528\uFF0C\u4E0D\u8D70\u5185\u5B58\u7F13\u51B2\uFF09\n * ================================================================== */\n\n/** \u4E0E\u843D\u76D8\u7B56\u7565\u5BF9\u5E94\u7684\u6587\u4EF6\u57FA\u540D\uFF08\u4E0D\u542B .log\uFF09 */\nconst DISK_LOG_FILES = [\"bds\", \"llbot\", \"tunnel\", \"db\", \"qq\", \"bds-update\", \"sfmc\"] as const;\n\n/** source \u2192 \u843D\u76D8\u6587\u4EF6\u540D\uFF08\u542B\u5B50\u8FDB\u7A0B\u81EA\u5199\uFF09 */\nexport function diskFileForSource(source: string): string {\n if (source === \"update\") return \"bds-update\";\n if (source === \"bds\" || source === \"llbot\" || source === \"tunnel\" || source === \"db\" || source === \"qq\") return source;\n return \"sfmc\";\n}\n\n/** formatLogLine \u65E0\u8272\u884C\uFF1A`YYYY-MM-DD HH:mm:ss [source] [LEVEL] text` */\nconst DISK_LINE_RE =\n /^(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}) \\[([^\\]]+)\\] \\[(INFO|WARN|ERROR|OK|DEBUG|SUCCESS|FATAL)\\]\\s?(.*)$/;\n\nfunction mapDiskLevelTag(tag: string): LogLevel {\n switch (tag) {\n case \"ERROR\":\n case \"FATAL\":\n return \"error\";\n case \"WARN\":\n return \"warn\";\n case \"OK\":\n case \"SUCCESS\":\n return \"success\";\n case \"DEBUG\":\n return \"debug\";\n default:\n return \"info\";\n }\n}\n\n/** \u89E3\u6790\u5355\u884C\u843D\u76D8\u65E5\u5FD7\uFF1B\u4E0D\u7B26\u683C\u5F0F\u8FD4\u56DE null */\nexport function parseDiskLogLine(raw: string): UnifiedLog | null {\n const m = DISK_LINE_RE.exec(raw);\n if (!m) return null;\n const ts = m[1]!;\n const source = m[2]!.trim();\n const level = mapDiskLevelTag(m[3]!);\n const body = m[4] ?? \"\";\n const time = new Date(ts.replace(\" \", \"T\") + \"Z\");\n return { time, source, level, text: body };\n}\n\nexport type ReadDiskLogsOpts = {\n levels?: LogLevel[];\n sources?: LogSource[];\n /** \u8986\u76D6\u65E5\u5FD7\u76EE\u5F55\uFF08\u6D4B\u8BD5\u7528\uFF09\uFF1B\u9ED8\u8BA4 `<ROOT>/.sfmc/logs` */\n dir?: string;\n /** \u4EC5\u4FDD\u7559\u65F6\u95F4\u5E8F\u6700\u540E N \u6761\uFF1B\u7701\u7565\u5219\u8FD4\u56DE\u5168\u90E8\u89E3\u6790\u7ED3\u679C */\n limit?: number;\n /** \u542B\u6B64\u65F6\u95F4\u3002\u8BBE\u7F6E\u540E\u8BFB\u53D6\u6574\u4E2A\u65E5\u5FD7\u6587\u4EF6\uFF0C\u4E0D\u518D\u53EA\u53D6\u6587\u4EF6\u672B\u5C3E */\n since?: Date;\n /** \u542B\u6B64\u65F6\u95F4 */\n until?: Date;\n};\n\n/** \u5220\u9664\u843D\u76D8\u65E5\u5FD7\u65F6\u7684\u7B5B\u9009\u3002\u4F7F\u7528\u573A\u666F\uFF1A\u684C\u9762 logs.delete\u3002 */\nexport type DeleteDiskLogsOpts = {\n since: Date;\n until: Date;\n source?: string;\n text?: string;\n /** \u8986\u76D6\u65E5\u5FD7\u76EE\u5F55\uFF08\u6D4B\u8BD5\u7528\uFF09 */\n dir?: string;\n};\n\n/**\n * \u4ECE `.sfmc/logs/*.log` \u8BFB\u53D6\u5E76\u89E3\u6790\u4E3A UnifiedLog\uFF08\u6309\u65F6\u95F4\u5347\u5E8F\uFF09\u3002\n * CLI \u91CD\u8FDE\u540E\u4E3B\u9762\u677F /logs \u7684\u5386\u53F2\u6743\u5A01\u6765\u6E90\uFF1B\u5185\u5B58\u7F13\u51B2\u4EC5\u627F\u8F7D\u672C\u8FDB\u7A0B\u8BA2\u9605\u5230\u7684\u5B9E\u65F6\u589E\u91CF\u3002\n */\nexport function readDiskLogs(opts: ReadDiskLogsOpts = {}): UnifiedLog[] {\n const levels = opts.levels ?? [];\n const sources = opts.sources ?? [];\n const dir = opts.dir ?? logsDir(ROOT);\n const sinceMs = opts.since?.getTime();\n const untilMs = opts.until?.getTime();\n const ranged = sinceMs !== undefined || untilMs !== undefined;\n const fileNames = new Set<string>();\n if (sources.length === 0) {\n for (const n of DISK_LOG_FILES) fileNames.add(n);\n } else {\n for (const s of sources) fileNames.add(diskFileForSource(s));\n }\n\n const out: UnifiedLog[] = [];\n for (const name of fileNames) {\n const fp = path.join(dir, name.endsWith(\".log\") ? name : `${name}.log`);\n let text: string;\n try {\n if (opts.limit && !ranged) {\n const fd = fs.openSync(fp, \"r\");\n try {\n const size = fs.fstatSync(fd).size;\n const start = Math.max(0, size - 4 * 1024 * 1024);\n const bytes = Buffer.alloc(size - start);\n fs.readSync(fd, bytes, 0, bytes.length, start);\n text = bytes.toString(\"utf8\");\n if (start > 0) text = text.slice(text.indexOf(\"\\n\") + 1);\n } finally { fs.closeSync(fd); }\n } else text = fs.readFileSync(fp, \"utf8\");\n } catch {\n continue;\n }\n for (const raw of text.split(/\\r?\\n/)) {\n if (!raw) continue;\n const entry = parseDiskLogLine(raw);\n if (!entry) continue;\n const time = entry.time.getTime();\n if (sinceMs !== undefined && time < sinceMs) continue;\n if (untilMs !== undefined && time > untilMs) continue;\n if (sources.length && !sources.includes(entry.source)) continue;\n if (levels.length && !levels.includes(entry.level)) continue;\n out.push(entry);\n }\n }\n out.sort((a, b) => a.time.getTime() - b.time.getTime());\n const limit = opts.limit;\n if (limit !== undefined && limit > 0 && out.length > limit) {\n return out.slice(out.length - limit);\n }\n return out;\n}\n\n/** \u8FD9\u4E00\u884C\u662F\u5426\u843D\u5728\u5220\u9664\u6761\u4EF6\u91CC\u3002\u89E3\u6790\u5931\u8D25\u7684\u884C\u4E0D\u5220\u3002 */\nfunction diskLineMatchesRemoval(entry: UnifiedLog, opts: DeleteDiskLogsOpts): boolean {\n const time = entry.time.getTime();\n if (time < opts.since.getTime() || time > opts.until.getTime()) return false;\n if (opts.source !== undefined && entry.source !== opts.source) return false;\n if (opts.text !== undefined && entry.text !== opts.text) return false;\n return true;\n}\n\n/**\n * \u4ECE\u4E00\u6BB5\u65E5\u5FD7\u6587\u672C\u91CC\u53BB\u6389\u547D\u4E2D\u7684\u884C\uFF0C\u4FDD\u7559\u65E0\u6CD5\u89E3\u6790\u7684\u884C\u548C\u539F\u6765\u7684\u6362\u884C\u98CE\u683C\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A\u6539\u5199 `.sfmc/logs/*.log` \u65F6\u4E0D\u628A\u574F\u884C\u4E00\u8D77\u4E22\u6389\u3002\n */\nfunction filterLogText(text: string, opts: DeleteDiskLogsOpts): { text: string; removed: number } {\n if (!text) return { text: \"\", removed: 0 };\n const newline = text.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\";\n const ended = text.endsWith(\"\\n\");\n const lines = text.split(/\\r?\\n/);\n if (ended) lines.pop();\n let removed = 0;\n const kept: string[] = [];\n for (const raw of lines) {\n const entry = raw ? parseDiskLogLine(raw) : null;\n if (entry && diskLineMatchesRemoval(entry, opts)) {\n removed++;\n continue;\n }\n kept.push(raw);\n }\n if (!kept.length) return { text: \"\", removed };\n return { text: kept.join(newline) + (ended ? newline : \"\"), removed };\n}\n\n/**\n * \u6309\u65F6\u95F4\u8303\u56F4\u5220\u9664\u5DF2\u77E5\u65E5\u5FD7\u6587\u4EF6\u4E2D\u7684\u884C\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A\u684C\u9762 logs.delete\u3002\u7B26\u53F7\u94FE\u63A5\u548C\u975E\u6587\u4EF6\u76F4\u63A5\u62D2\u7EDD\u3002\n * \u5199\u5165\u524D\u4F1A\u518D\u8BFB\u4E00\u6B21\u671F\u95F4\u8FFD\u52A0\u7684\u5185\u5BB9\uFF1B\u66FF\u6362\u6587\u4EF6\u7684\u77AC\u95F4\u65B0\u5199\u5165\u7684\u884C\u53EF\u80FD\u7559\u4E0B\u6765\u3002\n */\nexport function deleteStoredLogs(opts: DeleteDiskLogsOpts): { removed: number } {\n if (opts.until.getTime() < opts.since.getTime()) throw new Error(\"\u7ED3\u675F\u65F6\u95F4\u4E0D\u80FD\u65E9\u4E8E\u5F00\u59CB\u65F6\u95F4\");\n const dir = opts.dir ?? logsDir(ROOT);\n let removed = 0;\n for (const name of DISK_LOG_FILES) {\n const file = path.join(dir, `${name}.log`);\n removed += rewriteLogFile(file, opts);\n }\n return { removed };\n}\n\n/** \u6539\u5199\u4E00\u4E2A\u65E5\u5FD7\u6587\u4EF6\u3002\u6587\u4EF6\u4E0D\u5B58\u5728\u5219\u8DF3\u8FC7\u3002 */\nfunction rewriteLogFile(file: string, opts: DeleteDiskLogsOpts): number {\n let stat: fs.Stats;\n try {\n stat = fs.lstatSync(file);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return 0;\n throw error;\n }\n if (stat.isSymbolicLink()) throw new Error(`\u62D2\u7EDD\u6539\u5199\u7B26\u53F7\u94FE\u63A5\u65E5\u5FD7 ${path.basename(file)}`);\n if (!stat.isFile()) throw new Error(`\u62D2\u7EDD\u6539\u5199\u975E\u6587\u4EF6\u65E5\u5FD7 ${path.basename(file)}`);\n let text = fs.readFileSync(file, \"utf8\");\n if (fs.statSync(file).size > Buffer.byteLength(text)) text = fs.readFileSync(file, \"utf8\");\n const filtered = filterLogText(text, opts);\n if (!filtered.removed) return 0;\n const temp = `${file}.${process.pid}.filtering`;\n fs.writeFileSync(temp, filtered.text, \"utf8\");\n try {\n fs.copyFileSync(temp, file);\n } finally {\n fs.rmSync(temp, { force: true });\n }\n return filtered.removed;\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 /** \u65B9\u62EC\u53F7\u5185\u56FA\u5B9A 3 \u5B57\u7B26\uFF0C\u4E0E [INF] \u5BF9\u9F50 */\n name: string;\n paint: (s: string) => string;\n}\n\nexport const SOURCE_META: SourceMeta[] = [\n { value: \"bds\", name: \"BDS\", paint: (s) => c.green(s) },\n { value: \"db\", name: \"DB \", paint: (s) => c.blue(s) },\n { value: \"qq\", name: \"QQ \", paint: (s) => c.purple(s) },\n { value: \"llbot\", name: \"BOT\", paint: (s) => c.yellow(s) },\n { value: \"system\", name: \"SYS\", paint: (s) => c.cyan(s) },\n { value: \"update\", name: \"UPD\", paint: (s) => c.orange(s) },\n { value: \"pack\", name: \"PAK\", paint: (s) => c.purple(s) },\n { value: \"bds-tools\", name: \"TOL\", paint: (s) => c.red(s) },\n];\n\n/** \u6E90\u6807\u7B7E\u65E0\u8272\u6587\u672C\uFF08formatSourceTag / logPrefixWidth \u5171\u7528\uFF09 */\nfunction sourceTagPlain(source: string): string {\n const meta = SOURCE_META.find((m) => m.value === source);\n if (meta) return `[${meta.name}]`;\n return `[${source.toUpperCase().padEnd(3).slice(0, 3)}]`;\n}\n\nexport function formatSourceTag(source: string): string {\n const meta = SOURCE_META.find((m) => m.value === source);\n const plain = sourceTagPlain(source);\n if (meta) return meta.paint(plain);\n return c.bold(plain);\n}\n\n/**\n * \u5C55\u793A\u7528\u7EA7\u522B\uFF1ABDS \u82E5\u4ECD\u5E26\u65F6\u95F4\u6233\u524D\u7F00\u5219\u89E3\u6790\u5185\u5D4C\u7EA7\u522B\uFF1B\u5DF2\u5265\u79BB\uFF08pushLog \u5165\u5E93\uFF09\u5219\u4FE1\u4EFB entry.level\u3002\n * \u7981\u6B62\u5BF9\u6B63\u6587\u505A\u677E\u6563\u5173\u952E\u8BCD\u5339\u914D\uFF08\u4F1A\u628A `[Commands] Error on line` \u8BEF\u5224\u4E3A error\uFF09\u3002\n */\nexport function resolveDisplayLevel(l: UnifiedLog): LogLevel {\n if (l.source === \"bds\") {\n const embedded = parseBdsEmbeddedLevel(l.text);\n if (embedded) return embedded;\n }\n return l.level;\n}\n\n/** \u4ECE\u539F\u59CB\u6587\u672C\u63A8\u65AD\u7EA7\u522B\uFF1A\u59D4\u6258\u5171\u4EAB\u5305\uFF08\u5185\u542B BDS \u65F6\u95F4\u6233\u89E3\u6790\uFF09 */\nexport function inferLevel(text: string): LogLevel {\n return sharedInferLevel(text);\n}\n\n/** \u65E0\u8272\u7EA7\u522B\u6807\u7B7E\u6587\u672C\uFF08\u53EF\u89C1\u5BBD\u5EA6\u6743\u5A01\u6E90\uFF1B\u62EC\u53F7\u5185\u5747\u4E3A 3 \u5B57\u7B26\uFF09 */\nconst LEVEL_TAG_TEXT: Record<LogLevel, string> = {\n error: \"[ERR]\",\n warn: \"[WRN]\",\n success: \"[SUC]\",\n debug: \"[DBG]\",\n info: \"[INF]\",\n};\n\nfunction levelTagPlain(lvl: LogLevel): string {\n return LEVEL_TAG_TEXT[lvl] ?? LEVEL_TAG_TEXT.info;\n}\n\nfunction levelTag(lvl: LogLevel): string {\n const text = levelTagPlain(lvl);\n switch (lvl) {\n case \"error\":\n return c.red(text);\n case \"warn\":\n return c.yellow(text);\n case \"success\":\n return c.green(c.bold(text));\n case \"debug\":\n return c.dim(text);\n default:\n return c.blue(text);\n }\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 const level = resolveDisplayLevel(l);\n const lvl = levelTag(level);\n const src = formatSourceTag(l.source);\n /* BDS\uFF1A\u53BB\u6389\u81EA\u5E26\u65F6\u95F4\u6233+\u7B49\u7EA7\u524D\u7F00\u540E\u518D\u672C\u5730\u5316\u7FFB\u8BD1\u4E0E\u9AD8\u4EAE\u6B63\u6587\uFF08push \u65F6\u591A\u534A\u5DF2\u8F6C\u8FC7\uFF0C\u6B64\u5904\u5E42\u7B49\u4E14\u8986\u76D6\u56DE\u653E\uFF09 */\n const body = l.source === \"bds\" ? stripBdsLogPrefix(l.text) : l.text;\n const filter = getCompiledLogFilter();\n const { entry } = transformLogEntry({ text: body, source: l.source, level }, filter);\n const txt = highlightLogLine(entry.text);\n return `${ts} ${src} ${lvl} ${txt}`;\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/**\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\uFF08\u5171\u7528 resolveDisplayLevel / sourceTagPlain / levelTagPlain\uFF09\u3002\n */\nexport function logPrefixWidth(l: UnifiedLog): number {\n const ts = l.time.toLocaleTimeString();\n const src = sourceTagPlain(l.source);\n const level = resolveDisplayLevel(l);\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
6
  "names": ["parseBdsEmbeddedLevel", "stripBdsLogPrefix", "sink"]
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/management/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAc3D,wBAAgB,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAsBjD;AACD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK9C;AACD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,UAA6D;AAClG,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAaxD;AACD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,QAqBtE;AACD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAQvE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/management/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAiB3D,wBAAgB,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAsBjD;AACD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK9C;AACD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,UAA6D;AAClG,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAgBxD;AACD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,QAqBtE;AACD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAQvE"}
@@ -3,6 +3,7 @@ import path from "node:path";
3
3
  import { createHash, randomUUID } from "node:crypto";
4
4
  import Ajv2020 from "ajv/dist/2020.js";
5
5
  import { parse } from "jsonc-parser";
6
+ import { serverPropertyFormFields } from "@sfmc-bds/bds-tools/server-properties-fields";
6
7
  import { resolveSdkPackageRoot, ROOT } from "../runtime.js";
7
8
  import { resolveBdsContext } from "../pack-lifecycle.js";
8
9
  import { readJson, stripBom } from "./domain.js";
@@ -12,6 +13,7 @@ const SCHEMA_STEM = {
12
13
  "module-update.json": "module_update",
13
14
  "pack-update.json": "pack_update"
14
15
  };
16
+ const MANAGEMENT_UI_LOCALE = "zh-CN";
15
17
  const ajv = new Ajv2020.default({ allErrors: true, strict: false });
16
18
  const validators = /* @__PURE__ */ new Map();
17
19
  function configFiles() {
@@ -57,7 +59,9 @@ function readDocument(key) {
57
59
  const schemaFile = path.join(path.dirname(file), `${path.basename(file).replace(/\.jsonc?$/, "")}.schema.json`);
58
60
  if (fs.existsSync(schemaFile)) schema = JSON.parse(fs.readFileSync(schemaFile, "utf8"));
59
61
  }
60
- return { key, text, revision: revision(text), ...schema ? { schema } : {}, format: file.endsWith(".properties") ? "properties" : file.endsWith(".jsonc") ? "jsonc" : "json", affectedServices: ["db", "tunnel", "qq", "llbot", "bds"] };
62
+ const format = file.endsWith(".properties") ? "properties" : file.endsWith(".jsonc") ? "jsonc" : "json";
63
+ const fields = format === "properties" ? serverPropertyFormFields(MANAGEMENT_UI_LOCALE) : void 0;
64
+ return { key, text, revision: revision(text), ...schema ? { schema } : {}, format, affectedServices: ["db", "tunnel", "qq", "llbot", "bds"], ...fields ? { fields } : {} };
61
65
  }
62
66
  function validateDocument(document, text) {
63
67
  if (Buffer.byteLength(text) > 2 * 1024 * 1024) throw new Error("\u914D\u7F6E\u6587\u4EF6\u8FC7\u5927");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/management/config.ts"],
4
- "sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport Ajv2020 from \"ajv/dist/2020.js\";\nimport { parse, type ParseError } from \"jsonc-parser\";\nimport type { ConfigDocument } from \"@sfmc-bds/management\";\nimport { resolveSdkPackageRoot, ROOT } from \"../runtime.js\";\nimport { resolveBdsContext } from \"../pack-lifecycle.js\";\nimport { readJson, stripBom } from \"./domain.js\";\n\n/** \u78C1\u76D8\u4E0A\u7684\u771F\u5B9E\u6587\u4EF6\u540D\u3002schema \u6587\u4EF6\u4ECD\u7528\u4E0B\u5212\u7EBF\uFF08log_filter.schema.json\uFF09\u3002 */\nconst CORE_FILES = [\"runtime.json\", \"db_config.json\", \"qq_config.json\", \"bds_updater.json\", \"permissions.json\", \"log-filter.json\", \"module-update.json\", \"pack-update.json\"];\nconst SCHEMA_STEM: Record<string, string> = {\n \"log-filter.json\": \"log_filter\",\n \"module-update.json\": \"module_update\",\n \"pack-update.json\": \"pack_update\",\n};\nconst ajv = new Ajv2020.default({ allErrors: true, strict: false });\nconst validators = new Map<string, ReturnType<typeof ajv.compile>>();\nexport function configFiles(): Map<string, string> {\n const files = new Map(CORE_FILES.map(name => [`core/${name}`, path.join(ROOT, \"configs\", name)]));\n files.set(\"bds/server.properties\", path.join(resolveBdsContext().bdsRoot, \"server.properties\"));\n const modules = path.join(ROOT, \"modules\", \"packages\");\n if (fs.existsSync(modules)) for (const entry of fs.readdirSync(modules, { withFileTypes: true })) {\n if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;\n const configDir = path.join(modules, entry.name, \"configs\");\n if (!fs.existsSync(configDir)) continue;\n for (const filename of fs.readdirSync(configDir)) if (/^[\\w.-]+\\.jsonc?$/.test(filename)) files.set(`module/${entry.name}/${filename}`, path.join(configDir, filename));\n }\n // \u771F\u5B9E\u5B9E\u4F8B\u7684\u6A21\u5757\u914D\u7F6E\u5199\u5728 <SFMC_ROOT>/configs/<configKey>.json\uFF0C\u76EE\u5F55\u540D\u6765\u81EA catalog.configKey\u3002\n const catalog = readJson<{ modules?: { id?: string; configKey?: string }[] }>(path.join(ROOT, \"modules\", \"catalog.json\"), {});\n const taken = new Set([...files.values()].map(file => path.resolve(file)));\n for (const row of catalog.modules ?? []) {\n if (!row.id || !row.configKey || !/^[\\w.-]+$/.test(row.id) || !/^[\\w.-]+$/.test(row.configKey)) continue;\n const filename = `${row.configKey}.json`;\n const file = path.join(ROOT, \"configs\", filename);\n if (!fs.existsSync(file) || taken.has(path.resolve(file))) continue;\n files.set(`module/${row.id}/${filename}`, file);\n taken.add(path.resolve(file));\n }\n return files;\n}\nexport function configPath(key: string): string {\n const file = configFiles().get(key);\n if (!file) throw Object.assign(new Error(\"\u914D\u7F6E\u4E0D\u5728\u5141\u8BB8\u7F16\u8F91\u7684\u5217\u8868\u4E2D\"), { code: \"validation\" });\n if (fs.existsSync(file) && fs.lstatSync(file).isSymbolicLink()) throw new Error(\"\u4E0D\u80FD\u901A\u8FC7\u914D\u7F6E\u6587\u4EF6\u94FE\u63A5\u5199\u5165\u5176\u4ED6\u6587\u4EF6\");\n return file;\n}\nexport function revision(text: string) { return createHash(\"sha256\").update(text).digest(\"hex\"); }\nexport function readDocument(key: string): ConfigDocument {\n const file = configPath(key);\n const text = fs.existsSync(file) ? stripBom(fs.readFileSync(file, \"utf8\")) : \"\";\n let schema: object | undefined;\n if (key.startsWith(\"core/\")) {\n const name = SCHEMA_STEM[path.basename(file)] ?? path.basename(file, \".json\");\n const schemaFile = path.join(resolveSdkPackageRoot(), \"schemas\", `${name}.schema.json`);\n if (fs.existsSync(schemaFile)) schema = JSON.parse(fs.readFileSync(schemaFile, \"utf8\")) as object;\n } else if (key.startsWith(\"module/\")) {\n const schemaFile = path.join(path.dirname(file), `${path.basename(file).replace(/\\.jsonc?$/, \"\")}.schema.json`);\n if (fs.existsSync(schemaFile)) schema = JSON.parse(fs.readFileSync(schemaFile, \"utf8\")) as object;\n }\n return { key, text, revision: revision(text), ...(schema ? { schema } : {}), format: file.endsWith(\".properties\") ? \"properties\" : file.endsWith(\".jsonc\") ? \"jsonc\" : \"json\", affectedServices: [\"db\", \"tunnel\", \"qq\", \"llbot\", \"bds\"] };\n}\nexport function validateDocument(document: ConfigDocument, text: string) {\n if (Buffer.byteLength(text) > 2 * 1024 * 1024) throw new Error(\"\u914D\u7F6E\u6587\u4EF6\u8FC7\u5927\");\n if (document.format === \"properties\") {\n for (const line of text.split(/\\r?\\n/)) if (line.trim() && !line.trim().startsWith(\"#\") && !/^[^=\\r\\n]+=.*$/.test(line)) throw new Error(\"server.properties \u5305\u542B\u975E\u6CD5\u914D\u7F6E\u884C\");\n return;\n }\n const errors: ParseError[] = [];\n const value: unknown = parse(text, errors, { allowTrailingComma: document.format === \"jsonc\", disallowComments: document.format === \"json\" });\n if (errors.length) throw Object.assign(new Error(\"\u914D\u7F6E\u8BED\u6CD5\u9519\u8BEF\"), { code: \"validation\", details: errors });\n if (document.schema) {\n // \u4FDD\u7559\u5DF2\u6709\u672A\u77E5\u5B57\u6BB5\uFF1B\u53EA\u4ECE\u6821\u9A8C\u526F\u672C\u6392\u9664\u672A\u4FEE\u6539\u7684\u672A\u77E5\u5B57\u6BB5\uFF0C\u4FDD\u5B58\u7684\u539F\u6587\u4ECD\u5B8C\u5168\u4FDD\u7559\u3002\n const schemaObject = document.schema as { additionalProperties?: boolean; properties?: Record<string, unknown> };\n if (schemaObject.additionalProperties === false && value && typeof value === \"object\" && !Array.isArray(value)) {\n const previous = parse(document.text || \"{}\") as Record<string, unknown>;\n for (const key of Object.keys(value)) if (!(key in (schemaObject.properties ?? {})) && previous && key in previous && JSON.stringify(previous[key]) === JSON.stringify((value as Record<string, unknown>)[key])) delete (value as Record<string, unknown>)[key];\n }\n const hash = revision(JSON.stringify(document.schema));\n let validator = validators.get(hash);\n if (!validator) { const schema = { ...document.schema } as Record<string, unknown>; delete schema.$id; validator = ajv.compile(schema); validators.set(hash, validator); }\n if (!validator(value)) throw Object.assign(new Error(\"\u914D\u7F6E\u4E0D\u7B26\u5408 Schema\"), { code: \"validation\", details: validator.errors });\n }\n}\nexport function saveDocument(key: string, expected: string, text: string) {\n const document = readDocument(key);\n if (document.revision !== expected) throw Object.assign(new Error(\"\u914D\u7F6E\u5DF2\u88AB\u5176\u4ED6\u64CD\u4F5C\u4FEE\u6539\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\"), { code: \"conflict\" });\n validateDocument(document, text);\n const file = configPath(key); const temp = `${file}.${randomUUID()}.tmp`;\n fs.mkdirSync(path.dirname(file), { recursive: true });\n fs.writeFileSync(temp, text, { mode: 0o600 }); fs.renameSync(temp, file);\n return document;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport Ajv2020 from \"ajv/dist/2020.js\";\nimport { parse, type ParseError } from \"jsonc-parser\";\nimport type { ConfigDocument } from \"@sfmc-bds/management\";\nimport { serverPropertyFormFields } from \"@sfmc-bds/bds-tools/server-properties-fields\";\nimport { resolveSdkPackageRoot, ROOT } from \"../runtime.js\";\nimport { resolveBdsContext } from \"../pack-lifecycle.js\";\nimport { readJson, stripBom } from \"./domain.js\";\n\n/** \u78C1\u76D8\u4E0A\u7684\u771F\u5B9E\u6587\u4EF6\u540D\u3002schema \u6587\u4EF6\u4ECD\u7528\u4E0B\u5212\u7EBF\uFF08log_filter.schema.json\uFF09\u3002 */\nconst CORE_FILES = [\"runtime.json\", \"db_config.json\", \"qq_config.json\", \"bds_updater.json\", \"permissions.json\", \"log-filter.json\", \"module-update.json\", \"pack-update.json\"];\nconst SCHEMA_STEM: Record<string, string> = {\n \"log-filter.json\": \"log_filter\",\n \"module-update.json\": \"module_update\",\n \"pack-update.json\": \"pack_update\",\n};\n/** \u7BA1\u7406\u754C\u9762\uFF08\u684C\u9762\u7AEF\u3001\u5C0F\u7A0B\u5E8F\uFF09\u7684\u8BED\u8A00\uFF1Bserver.properties \u8868\u5355\u5B57\u6BB5\u7684\u540D\u79F0\u4E0E\u8BF4\u660E\u6309\u6B64\u751F\u6210\u3002\u754C\u9762\u76EE\u524D\u53EA\u6709\u7B80\u4F53\u4E2D\u6587\u3002 */\nconst MANAGEMENT_UI_LOCALE = \"zh-CN\";\nconst ajv = new Ajv2020.default({ allErrors: true, strict: false });\nconst validators = new Map<string, ReturnType<typeof ajv.compile>>();\nexport function configFiles(): Map<string, string> {\n const files = new Map(CORE_FILES.map(name => [`core/${name}`, path.join(ROOT, \"configs\", name)]));\n files.set(\"bds/server.properties\", path.join(resolveBdsContext().bdsRoot, \"server.properties\"));\n const modules = path.join(ROOT, \"modules\", \"packages\");\n if (fs.existsSync(modules)) for (const entry of fs.readdirSync(modules, { withFileTypes: true })) {\n if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;\n const configDir = path.join(modules, entry.name, \"configs\");\n if (!fs.existsSync(configDir)) continue;\n for (const filename of fs.readdirSync(configDir)) if (/^[\\w.-]+\\.jsonc?$/.test(filename)) files.set(`module/${entry.name}/${filename}`, path.join(configDir, filename));\n }\n // \u771F\u5B9E\u5B9E\u4F8B\u7684\u6A21\u5757\u914D\u7F6E\u5199\u5728 <SFMC_ROOT>/configs/<configKey>.json\uFF0C\u76EE\u5F55\u540D\u6765\u81EA catalog.configKey\u3002\n const catalog = readJson<{ modules?: { id?: string; configKey?: string }[] }>(path.join(ROOT, \"modules\", \"catalog.json\"), {});\n const taken = new Set([...files.values()].map(file => path.resolve(file)));\n for (const row of catalog.modules ?? []) {\n if (!row.id || !row.configKey || !/^[\\w.-]+$/.test(row.id) || !/^[\\w.-]+$/.test(row.configKey)) continue;\n const filename = `${row.configKey}.json`;\n const file = path.join(ROOT, \"configs\", filename);\n if (!fs.existsSync(file) || taken.has(path.resolve(file))) continue;\n files.set(`module/${row.id}/${filename}`, file);\n taken.add(path.resolve(file));\n }\n return files;\n}\nexport function configPath(key: string): string {\n const file = configFiles().get(key);\n if (!file) throw Object.assign(new Error(\"\u914D\u7F6E\u4E0D\u5728\u5141\u8BB8\u7F16\u8F91\u7684\u5217\u8868\u4E2D\"), { code: \"validation\" });\n if (fs.existsSync(file) && fs.lstatSync(file).isSymbolicLink()) throw new Error(\"\u4E0D\u80FD\u901A\u8FC7\u914D\u7F6E\u6587\u4EF6\u94FE\u63A5\u5199\u5165\u5176\u4ED6\u6587\u4EF6\");\n return file;\n}\nexport function revision(text: string) { return createHash(\"sha256\").update(text).digest(\"hex\"); }\nexport function readDocument(key: string): ConfigDocument {\n const file = configPath(key);\n const text = fs.existsSync(file) ? stripBom(fs.readFileSync(file, \"utf8\")) : \"\";\n let schema: object | undefined;\n if (key.startsWith(\"core/\")) {\n const name = SCHEMA_STEM[path.basename(file)] ?? path.basename(file, \".json\");\n const schemaFile = path.join(resolveSdkPackageRoot(), \"schemas\", `${name}.schema.json`);\n if (fs.existsSync(schemaFile)) schema = JSON.parse(fs.readFileSync(schemaFile, \"utf8\")) as object;\n } else if (key.startsWith(\"module/\")) {\n const schemaFile = path.join(path.dirname(file), `${path.basename(file).replace(/\\.jsonc?$/, \"\")}.schema.json`);\n if (fs.existsSync(schemaFile)) schema = JSON.parse(fs.readFileSync(schemaFile, \"utf8\")) as object;\n }\n const format = file.endsWith(\".properties\") ? \"properties\" : file.endsWith(\".jsonc\") ? \"jsonc\" : \"json\";\n // server.properties \u6CA1\u6709 Schema\uFF0C\u9644\u5E26 bds-tools \u7EF4\u62A4\u7684\u5B8C\u6574\u5B57\u6BB5\u6E05\u5355\u4F9B\u8868\u5355\u89C6\u56FE\u4F7F\u7528\n const fields = format === \"properties\" ? serverPropertyFormFields(MANAGEMENT_UI_LOCALE) : undefined;\n return { key, text, revision: revision(text), ...(schema ? { schema } : {}), format, affectedServices: [\"db\", \"tunnel\", \"qq\", \"llbot\", \"bds\"], ...(fields ? { fields } : {}) };\n}\nexport function validateDocument(document: ConfigDocument, text: string) {\n if (Buffer.byteLength(text) > 2 * 1024 * 1024) throw new Error(\"\u914D\u7F6E\u6587\u4EF6\u8FC7\u5927\");\n if (document.format === \"properties\") {\n for (const line of text.split(/\\r?\\n/)) if (line.trim() && !line.trim().startsWith(\"#\") && !/^[^=\\r\\n]+=.*$/.test(line)) throw new Error(\"server.properties \u5305\u542B\u975E\u6CD5\u914D\u7F6E\u884C\");\n return;\n }\n const errors: ParseError[] = [];\n const value: unknown = parse(text, errors, { allowTrailingComma: document.format === \"jsonc\", disallowComments: document.format === \"json\" });\n if (errors.length) throw Object.assign(new Error(\"\u914D\u7F6E\u8BED\u6CD5\u9519\u8BEF\"), { code: \"validation\", details: errors });\n if (document.schema) {\n // \u4FDD\u7559\u5DF2\u6709\u672A\u77E5\u5B57\u6BB5\uFF1B\u53EA\u4ECE\u6821\u9A8C\u526F\u672C\u6392\u9664\u672A\u4FEE\u6539\u7684\u672A\u77E5\u5B57\u6BB5\uFF0C\u4FDD\u5B58\u7684\u539F\u6587\u4ECD\u5B8C\u5168\u4FDD\u7559\u3002\n const schemaObject = document.schema as { additionalProperties?: boolean; properties?: Record<string, unknown> };\n if (schemaObject.additionalProperties === false && value && typeof value === \"object\" && !Array.isArray(value)) {\n const previous = parse(document.text || \"{}\") as Record<string, unknown>;\n for (const key of Object.keys(value)) if (!(key in (schemaObject.properties ?? {})) && previous && key in previous && JSON.stringify(previous[key]) === JSON.stringify((value as Record<string, unknown>)[key])) delete (value as Record<string, unknown>)[key];\n }\n const hash = revision(JSON.stringify(document.schema));\n let validator = validators.get(hash);\n if (!validator) { const schema = { ...document.schema } as Record<string, unknown>; delete schema.$id; validator = ajv.compile(schema); validators.set(hash, validator); }\n if (!validator(value)) throw Object.assign(new Error(\"\u914D\u7F6E\u4E0D\u7B26\u5408 Schema\"), { code: \"validation\", details: validator.errors });\n }\n}\nexport function saveDocument(key: string, expected: string, text: string) {\n const document = readDocument(key);\n if (document.revision !== expected) throw Object.assign(new Error(\"\u914D\u7F6E\u5DF2\u88AB\u5176\u4ED6\u64CD\u4F5C\u4FEE\u6539\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\"), { code: \"conflict\" });\n validateDocument(document, text);\n const file = configPath(key); const temp = `${file}.${randomUUID()}.tmp`;\n fs.mkdirSync(path.dirname(file), { recursive: true });\n fs.writeFileSync(temp, text, { mode: 0o600 }); fs.renameSync(temp, file);\n return document;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -22,10 +22,22 @@ export declare function searchModules(query: string): Promise<{
22
22
  sdk?: string;
23
23
  repo?: string;
24
24
  tag?: string;
25
+ name?: string;
26
+ description?: string;
27
+ category?: string;
28
+ license?: string;
29
+ official?: boolean;
30
+ requires?: string[];
25
31
  id: string;
26
32
  }[];
27
33
  stale: boolean;
28
34
  }>;
35
+ /**
36
+ * 安装前核对索引里的 requires。
37
+ * 使用场景:modules.install 在创建下载任务之前调用。索引没有这个 id 时返回 null,继续原来的安装路径。
38
+ * 有条目但没有合法 requires,或依赖未安装、未启用时返回说明,调用方不得开始安装。
39
+ */
40
+ export declare function moduleInstallBlock(id: string): Promise<string | null>;
29
41
  export declare function runFetch(args: string[]): Promise<{
30
42
  changed: boolean;
31
43
  }>;
@@ -44,13 +56,45 @@ export declare function listPacks(): {
44
56
  kind: import("@sfmc-bds/bds-tools/world-packs").WorldPackKind;
45
57
  enabled: boolean;
46
58
  version: string;
59
+ iconStamp?: string;
60
+ protected?: boolean;
47
61
  }[];
48
62
  };
49
- export declare function togglePack(id: string, enabled: boolean): Promise<{
63
+ /**
64
+ * 读取某个已安装世界包的 pack_icon.png。
65
+ * 使用场景:桌面世界包列表按 iconStamp 按需拉取,不放进每 5 秒的 packs.list。
66
+ * 找不到包、文件缺失或内容不是 PNG 时返回空图标,不抛错。
67
+ */
68
+ export declare function readPackIcon(id: string): {
69
+ id: string;
70
+ mime: "image/png" | null;
71
+ data: string | null;
72
+ };
73
+ /**
74
+ * 卸载一个世界包,并沿用 CLI 的配对资源包与回收站规则。
75
+ * 使用场景:桌面 packs.uninstall。平台聚合包直接拒绝。
76
+ */
77
+ export declare function uninstallPack(id: string): Promise<{
50
78
  changed: boolean;
51
79
  restartRequired: boolean;
80
+ removed: import("../world-packs.js").PackUninstallOutcome[];
52
81
  }>;
53
- export declare function importPack(filename: string): Promise<{
82
+ /**
83
+ * 解析桌面传入的资源包版本。
84
+ * 使用场景:packs.version。只接受 major.minor.patch,每一段都是非负安全整数。
85
+ */
86
+ export declare function parsePackVersion(value: unknown): [number, number, number];
87
+ /**
88
+ * 修改一个已安装资源包的清单版本,并在已启用时同步世界启用列表。
89
+ * 使用场景:桌面 packs.version。行为包直接拒绝。
90
+ * 模块条目写成与 header 相同的完整版本;命令行 packs bump 仍只抬修订号。
91
+ */
92
+ export declare function setPackVersion(id: string, versionText: unknown): Promise<{
93
+ changed: boolean;
94
+ restartRequired: boolean;
95
+ version: string;
96
+ }>;
97
+ export declare function togglePack(id: string, enabled: boolean): Promise<{
54
98
  changed: boolean;
55
99
  restartRequired: boolean;
56
100
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../src/management/domain.ts"],"names":[],"mappings":"AAWA;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AACD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAGxD;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGjD;AACD,wBAAsB,WAAW;;;;;;;;;GAMhC;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM;;;;;;;;;;GAGhD;AACD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE;;GAG5C;AACD,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAOvH;AACD,wBAAsB,UAAU,CAAC,GAAG,GAAE,MAAM,EAAO,oBAIlD;AACD,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE;YAI+B;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE;GAQlH;AACD,wBAAgB,SAAS;IAEd,KAAK;;;;;;;EACf;AACD,wBAAsB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;;;GAO5D;AACD,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM;;;GAiBhD;AACD,wBAAgB,WAAW;IAEhB,SAAS;IAAoC,WAAW;IAAsC,eAAe;EACvH;AACD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAWzD,KAAK;EACf"}
1
+ {"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../src/management/domain.ts"],"names":[],"mappings":"AAaA;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AACD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAGxD;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGjD;AACD,wBAAsB,WAAW;;;;;;;;;GAMhC;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM;;;;;;;;;;;;;;;;GAehD;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQ3E;AACD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE;;GAG5C;AACD,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAOvH;AACD,wBAAsB,UAAU,CAAC,GAAG,GAAE,MAAM,EAAO,oBAIlD;AACD,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE;YAI+B;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE;GAQlH;AAkBD,wBAAgB,SAAS;IAEd,KAAK;;;;;;;;;EAYf;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAUtG;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM;;;;GAS7C;AACD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAezE;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO;;;;GAcpE;AAED,wBAAsB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;;;GAO5D;AACD,wBAAgB,WAAW;IAEhB,SAAS;IAAoC,WAAW;IAAsC,eAAe;EACvH;AACD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAWzD,KAAK;EACf"}