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

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 (142) 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/log-filter.d.ts +69 -0
  47. package/dist/log-filter.d.ts.map +1 -0
  48. package/dist/log-filter.js +150 -0
  49. package/dist/log-filter.js.map +7 -0
  50. package/dist/logs.d.ts +33 -8
  51. package/dist/logs.d.ts.map +1 -1
  52. package/dist/logs.js +232 -194
  53. package/dist/logs.js.map +7 -1
  54. package/dist/main.js +135 -173
  55. package/dist/main.js.map +7 -1
  56. package/dist/module-commands.d.ts +43 -4
  57. package/dist/module-commands.d.ts.map +1 -1
  58. package/dist/module-commands.js +440 -327
  59. package/dist/module-commands.js.map +7 -1
  60. package/dist/module-fingerprint.d.ts +7 -0
  61. package/dist/module-fingerprint.d.ts.map +1 -0
  62. package/dist/module-fingerprint.js +31 -0
  63. package/dist/module-fingerprint.js.map +7 -0
  64. package/dist/module-wizard.d.ts +14 -0
  65. package/dist/module-wizard.d.ts.map +1 -0
  66. package/dist/module-wizard.js +313 -0
  67. package/dist/module-wizard.js.map +7 -0
  68. package/dist/pack-lifecycle.d.ts +95 -0
  69. package/dist/pack-lifecycle.d.ts.map +1 -0
  70. package/dist/pack-lifecycle.js +634 -0
  71. package/dist/pack-lifecycle.js.map +7 -0
  72. package/dist/pack-update/bindings.d.ts +12 -0
  73. package/dist/pack-update/bindings.d.ts.map +1 -0
  74. package/dist/pack-update/bindings.js +64 -0
  75. package/dist/pack-update/bindings.js.map +7 -0
  76. package/dist/pack-update/config.d.ts +22 -0
  77. package/dist/pack-update/config.d.ts.map +1 -0
  78. package/dist/pack-update/config.js +141 -0
  79. package/dist/pack-update/config.js.map +7 -0
  80. package/dist/pack-update/providers/curseforge.d.ts +23 -0
  81. package/dist/pack-update/providers/curseforge.d.ts.map +1 -0
  82. package/dist/pack-update/providers/curseforge.js +229 -0
  83. package/dist/pack-update/providers/curseforge.js.map +7 -0
  84. package/dist/pack-update/providers/index.d.ts +16 -0
  85. package/dist/pack-update/providers/index.d.ts.map +1 -0
  86. package/dist/pack-update/providers/index.js +37 -0
  87. package/dist/pack-update/providers/index.js.map +7 -0
  88. package/dist/pack-update/service.d.ts +21 -0
  89. package/dist/pack-update/service.d.ts.map +1 -0
  90. package/dist/pack-update/service.js +572 -0
  91. package/dist/pack-update/service.js.map +7 -0
  92. package/dist/pack-update/types.d.ts +126 -0
  93. package/dist/pack-update/types.d.ts.map +1 -0
  94. package/dist/pack-update/types.js +8 -0
  95. package/dist/pack-update/types.js.map +7 -0
  96. package/dist/pack-update/version-policy.d.ts +81 -0
  97. package/dist/pack-update/version-policy.d.ts.map +1 -0
  98. package/dist/pack-update/version-policy.js +210 -0
  99. package/dist/pack-update/version-policy.js.map +7 -0
  100. package/dist/registry.d.ts +12 -4
  101. package/dist/registry.d.ts.map +1 -1
  102. package/dist/registry.js +73 -106
  103. package/dist/registry.js.map +7 -1
  104. package/dist/remote-agent.d.ts.map +1 -1
  105. package/dist/remote-agent.js +160 -176
  106. package/dist/remote-agent.js.map +7 -1
  107. package/dist/repl.d.ts +4 -0
  108. package/dist/repl.d.ts.map +1 -1
  109. package/dist/repl.js +683 -605
  110. package/dist/repl.js.map +7 -1
  111. package/dist/runtime.d.ts +40 -14
  112. package/dist/runtime.d.ts.map +1 -1
  113. package/dist/runtime.js +185 -62
  114. package/dist/runtime.js.map +7 -1
  115. package/dist/services.d.ts +2 -0
  116. package/dist/services.d.ts.map +1 -1
  117. package/dist/services.js +251 -238
  118. package/dist/services.js.map +7 -1
  119. package/dist/sfmc-modules-root.d.ts +24 -0
  120. package/dist/sfmc-modules-root.d.ts.map +1 -0
  121. package/dist/sfmc-modules-root.js +70 -0
  122. package/dist/sfmc-modules-root.js.map +7 -0
  123. package/dist/theme.d.ts +4 -0
  124. package/dist/theme.d.ts.map +1 -1
  125. package/dist/theme.js +134 -48
  126. package/dist/theme.js.map +7 -1
  127. package/dist/wizard.d.ts.map +1 -1
  128. package/dist/wizard.js +363 -438
  129. package/dist/wizard.js.map +7 -1
  130. package/dist/world-packs.d.ts +37 -0
  131. package/dist/world-packs.d.ts.map +1 -0
  132. package/dist/world-packs.js +872 -0
  133. package/dist/world-packs.js.map +7 -0
  134. package/package.json +10 -10
  135. package/dist/dispatcher.d.ts +0 -13
  136. package/dist/dispatcher.d.ts.map +0 -1
  137. package/dist/dispatcher.js +0 -23
  138. package/dist/dispatcher.js.map +0 -1
  139. package/dist/terminal.d.ts +0 -3
  140. package/dist/terminal.d.ts.map +0 -1
  141. package/dist/terminal.js +0 -178
  142. package/dist/terminal.js.map +0 -1
@@ -0,0 +1,572 @@
1
+ import { confirm, isCancel } from "@clack/prompts";
2
+ import {
3
+ enableInstalledPack,
4
+ ensureVersionGreaterThan,
5
+ findInstalledPackById,
6
+ installPackDirectory,
7
+ listInstalledWorldPacks,
8
+ readPackDependencyUuids,
9
+ readPackManifestInfo,
10
+ resolvePackRoots,
11
+ worldPackParentDir
12
+ } from "@sfmc-bds/bds-tools/world-packs";
13
+ import fs from "node:fs";
14
+ import os from "node:os";
15
+ import path from "node:path";
16
+ import { t } from "../i18n/index.js";
17
+ import { pushLog } from "../logs.js";
18
+ import { resolveBdsContext } from "../pack-lifecycle.js";
19
+ import { c } from "../theme.js";
20
+ import { getBinding, listBindings, packSourcesPath, setBinding } from "./bindings.js";
21
+ import {
22
+ ensurePackUpdateConfigFile,
23
+ getPackMatchConfig,
24
+ loadPackUpdateConfig,
25
+ packUpdateConfigPath
26
+ } from "./config.js";
27
+ import {
28
+ createPackSourceProvider,
29
+ providerShortLabel,
30
+ resolveConfiguredPackProvider
31
+ } from "./providers/index.js";
32
+ import {
33
+ decideVersionPolicy,
34
+ buildSearchQueries,
35
+ buildSearchQueriesFromSources,
36
+ packSourceScore
37
+ } from "./version-policy.js";
38
+ function logPack(text, level = "info") {
39
+ pushLog(text, "pack", level);
40
+ }
41
+ function fmtVer(v) {
42
+ return v.join(".");
43
+ }
44
+ function bindingEnabledLabel(enabled) {
45
+ return enabled ? t("packs.list.on").trim() : t("packs.list.off").trim();
46
+ }
47
+ function needKeyText() {
48
+ return t("packUpdate.needKey", { path: packUpdateConfigPath() });
49
+ }
50
+ function bindOkParams(opts) {
51
+ return {
52
+ uuid: opts.uuid,
53
+ provider: providerShortLabel(opts.provider),
54
+ slug: opts.slug,
55
+ enabled: bindingEnabledLabel(opts.enabled),
56
+ path: packSourcesPath()
57
+ };
58
+ }
59
+ function touchBinding(bpUuid, binding, patch) {
60
+ if (patch) Object.assign(binding, patch);
61
+ setBinding(bpUuid, binding);
62
+ }
63
+ function isFileIdApplied(binding, fileId) {
64
+ return binding.lastAppliedFileId != null && binding.lastAppliedFileId === fileId;
65
+ }
66
+ async function searchAndRankHits(provider, queries, stripFolderTags) {
67
+ const byId = /* @__PURE__ */ new Map();
68
+ for (const q of queries) {
69
+ const hits = await provider.search(q);
70
+ for (const h of hits) byId.set(h.projectId, h);
71
+ }
72
+ return [...byId.values()].map((h) => ({
73
+ hit: h,
74
+ score: Math.max(...queries.map((q) => packSourceScore(q, h, stripFolderTags)))
75
+ })).sort((a, b) => b.score - a.score);
76
+ }
77
+ function makeBindingFromHit(hit, pairedResourceUuid, opts) {
78
+ const prev = opts?.prev;
79
+ return {
80
+ /* 重绑保留原 enabled;新建走配置契约 defaultBindingEnabled(LSP) */
81
+ enabled: prev?.enabled ?? opts?.defaultEnabled ?? false,
82
+ provider: hit.provider,
83
+ projectId: hit.projectId,
84
+ slug: hit.slug,
85
+ websiteUrl: hit.websiteUrl,
86
+ pairedResourceUuid,
87
+ lastFileId: prev?.lastFileId ?? null,
88
+ lastCheckedAt: null,
89
+ lastAppliedFileId: prev?.lastAppliedFileId ?? null
90
+ };
91
+ }
92
+ function pairedRpUuidFromBpDir(bpDir) {
93
+ const deps = readPackDependencyUuids(bpDir);
94
+ return deps[0] ?? null;
95
+ }
96
+ async function probeSourceAfterInstall(opts) {
97
+ const cfg = loadPackUpdateConfig();
98
+ if (!cfg.enabled || !cfg.probeSourceAfterInstall) return;
99
+ if (opts.info.kind !== "behavior") return;
100
+ ensurePackUpdateConfigFile();
101
+ const provider = resolveConfiguredPackProvider(cfg);
102
+ if (!provider) {
103
+ logPack(needKeyText(), "warn");
104
+ return;
105
+ }
106
+ const match = getPackMatchConfig(cfg);
107
+ const folderName = opts.folderName && String(opts.folderName).trim() || (opts.packDir ? path.basename(opts.packDir) : "");
108
+ const plan = buildSearchQueriesFromSources(
109
+ [
110
+ { id: "header", raw: opts.info.name },
111
+ { id: "folder", raw: folderName }
112
+ ],
113
+ match.stripFolderTags
114
+ );
115
+ const queries = plan.queries;
116
+ if (queries.length === 0) {
117
+ logPack(t("packUpdate.probeNoName"), "warn");
118
+ return;
119
+ }
120
+ logPack(
121
+ t("packUpdate.probeQueries", {
122
+ header: opts.info.name || "-",
123
+ folder: folderName || "-",
124
+ queries: queries.join(" | ")
125
+ }),
126
+ "info"
127
+ );
128
+ let scored;
129
+ try {
130
+ scored = await searchAndRankHits(provider, queries, match.stripFolderTags);
131
+ } catch (e) {
132
+ logPack(t("packUpdate.probeFail", { message: e.message }), "warn");
133
+ return;
134
+ }
135
+ if (scored.length === 0) {
136
+ logPack(t("packUpdate.probeMiss", { name: queries.join(", ") }), "info");
137
+ return;
138
+ }
139
+ const primary = queries.find((q) => /[A-Za-z]/.test(q)) ?? queries[0];
140
+ const best = scored[0];
141
+ if (best.score < match.nameMinScore) {
142
+ logPack(
143
+ t("packUpdate.probeLowScore", {
144
+ name: primary,
145
+ hit: `${best.hit.name} (${best.hit.slug})`,
146
+ score: best.score.toFixed(2),
147
+ url: best.hit.websiteUrl
148
+ }),
149
+ "info"
150
+ );
151
+ return;
152
+ }
153
+ logPack(
154
+ t("packUpdate.probeHit", {
155
+ name: `${opts.info.name} / ${folderName || "-"}`,
156
+ hit: `${best.hit.name} [${best.hit.slug}]`,
157
+ url: best.hit.websiteUrl,
158
+ score: best.score.toFixed(2)
159
+ }),
160
+ "success"
161
+ );
162
+ logPack(t("packUpdate.editHint", { path: packSourcesPath() }), "info");
163
+ const interactive = opts.interactive ?? !!process.stdin.isTTY;
164
+ let accept = false;
165
+ if (interactive && cfg.askConfirmOnBind && process.stdin.isTTY) {
166
+ const ans = await confirm({
167
+ message: t("packUpdate.confirmBind", { hit: best.hit.name }),
168
+ initialValue: true
169
+ });
170
+ if (isCancel(ans)) return;
171
+ accept = !!ans;
172
+ } else {
173
+ accept = true;
174
+ logPack(
175
+ t("packUpdate.probeAutoBind", {
176
+ provider: providerShortLabel(best.hit.provider),
177
+ slug: best.hit.slug,
178
+ path: packSourcesPath()
179
+ }),
180
+ "info"
181
+ );
182
+ }
183
+ if (!accept) {
184
+ logPack(t("packUpdate.bindSkipped"), "info");
185
+ return;
186
+ }
187
+ const paired = (opts.packDir ? pairedRpUuidFromBpDir(opts.packDir) : null) ?? null;
188
+ const binding = makeBindingFromHit(best.hit, paired, { defaultEnabled: cfg.defaultBindingEnabled });
189
+ setBinding(opts.info.uuid, binding);
190
+ logPack(
191
+ t(
192
+ "packUpdate.bindOk",
193
+ bindOkParams({
194
+ uuid: opts.info.uuid,
195
+ provider: best.hit.provider,
196
+ slug: best.hit.slug,
197
+ enabled: binding.enabled
198
+ })
199
+ ),
200
+ "success"
201
+ );
202
+ }
203
+ async function searchRemote(query) {
204
+ const cfg = loadPackUpdateConfig();
205
+ const provider = resolveConfiguredPackProvider(cfg);
206
+ if (!provider) {
207
+ return c.yellow(needKeyText());
208
+ }
209
+ const match = getPackMatchConfig(cfg);
210
+ const queries = buildSearchQueries(query, match.stripFolderTags);
211
+ const ranked = await searchAndRankHits(provider, queries, match.stripFolderTags);
212
+ if (ranked.length === 0) return c.dim(t("packUpdate.searchEmpty", { query }));
213
+ return ranked.map(
214
+ ({ hit: h, score }, i) => `${c.cyan(String(i + 1).padStart(2))}. ${h.name} ${c.dim(`id=${h.projectId} slug=${h.slug} score=${score.toFixed(2)}`)}
215
+ ${h.websiteUrl}`
216
+ ).join("\n");
217
+ }
218
+ async function bindPackSource(packId, ref) {
219
+ const cfg = loadPackUpdateConfig();
220
+ const provider = resolveConfiguredPackProvider(cfg);
221
+ if (!provider) {
222
+ return c.yellow(needKeyText());
223
+ }
224
+ const { bdsRoot, levelName } = resolveBdsContext();
225
+ const packs = listInstalledWorldPacks(bdsRoot, levelName);
226
+ const pack = findInstalledPackById(packs, packId);
227
+ if (!pack) return c.red(t("packs.notFound", { id: packId }));
228
+ if (pack.kind !== "behavior") return c.red(t("packUpdate.bindBpOnly"));
229
+ const hit = await provider.resolveProject(ref);
230
+ if (!hit) return c.red(t("packUpdate.resolveFail", { ref }));
231
+ const paired = pairedRpUuidFromBpDir(pack.dir);
232
+ const binding = makeBindingFromHit(hit, paired, {
233
+ prev: getBinding(pack.uuid),
234
+ defaultEnabled: cfg.defaultBindingEnabled
235
+ });
236
+ setBinding(pack.uuid, binding);
237
+ return c.green(
238
+ t(
239
+ "packUpdate.bindOk",
240
+ bindOkParams({
241
+ uuid: pack.uuid,
242
+ provider: hit.provider,
243
+ slug: hit.slug,
244
+ enabled: binding.enabled
245
+ })
246
+ )
247
+ );
248
+ }
249
+ function formatSourcesList() {
250
+ ensurePackUpdateConfigFile();
251
+ const bindings = listBindings();
252
+ const lines = [
253
+ t("packUpdate.sourcesHeader", {
254
+ config: packUpdateConfigPath(),
255
+ sources: packSourcesPath()
256
+ })
257
+ ];
258
+ if (bindings.length === 0) {
259
+ lines.push(c.dim(t("packUpdate.sourcesEmpty")));
260
+ return lines.join("\n");
261
+ }
262
+ for (const { bpUuid, binding } of bindings) {
263
+ const label = bindingEnabledLabel(binding.enabled);
264
+ const en = binding.enabled ? c.green(label) : c.dim(label);
265
+ const tag = providerShortLabel(binding.provider);
266
+ lines.push(
267
+ ` [${en}] ${bpUuid} ${tag}:${binding.slug || binding.projectId} ${c.dim(binding.websiteUrl || "")}`
268
+ );
269
+ }
270
+ return lines.join("\n");
271
+ }
272
+ function withLocalBp(base, localBp) {
273
+ return localBp ? { ...base, localBp } : { ...base };
274
+ }
275
+ function baseCheckFields(bpUuid, name, localVer, binding, extras) {
276
+ return {
277
+ bpUuid,
278
+ name,
279
+ localVer,
280
+ remoteVer: null,
281
+ updateAvailable: false,
282
+ majorHigher: false,
283
+ shouldBumpRp: false,
284
+ fileId: null,
285
+ binding,
286
+ ...extras
287
+ };
288
+ }
289
+ async function prepareCheck(bpUuid, binding, cfg, packs, downloadArchive) {
290
+ const localBp = packs.find((p) => p.uuid.toLowerCase() === bpUuid.toLowerCase() && p.kind === "behavior");
291
+ const name = localBp?.name ?? bpUuid;
292
+ const localVer = localBp?.version ?? [0, 0, 0];
293
+ const provider = createPackSourceProvider(cfg, binding.provider);
294
+ touchBinding(bpUuid, binding, { lastCheckedAt: (/* @__PURE__ */ new Date()).toISOString() });
295
+ if (!binding.enabled) {
296
+ return withLocalBp(
297
+ baseCheckFields(bpUuid, name, localVer, binding, { message: t("packUpdate.bindingDisabled") }),
298
+ localBp
299
+ );
300
+ }
301
+ const file = await provider.getLatestFile(binding.projectId);
302
+ if (!file) {
303
+ return withLocalBp(
304
+ baseCheckFields(bpUuid, name, localVer, binding, { message: t("packUpdate.noRemoteFile") }),
305
+ localBp
306
+ );
307
+ }
308
+ if (isFileIdApplied(binding, file.fileId)) {
309
+ touchBinding(bpUuid, binding, { lastFileId: file.fileId });
310
+ return withLocalBp(
311
+ baseCheckFields(bpUuid, name, localVer, binding, {
312
+ fileId: file.fileId,
313
+ message: t("packUpdate.upToDate")
314
+ }),
315
+ localBp
316
+ );
317
+ }
318
+ if (!downloadArchive) {
319
+ return withLocalBp(
320
+ baseCheckFields(bpUuid, name, localVer, binding, {
321
+ updateAvailable: true,
322
+ fileId: file.fileId,
323
+ message: t("packUpdate.fileNewer", { file: file.fileName, id: String(file.fileId) })
324
+ }),
325
+ localBp
326
+ );
327
+ }
328
+ const stagingDir = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-pack-upd-"));
329
+ const archiveFile = path.join(stagingDir, file.fileName || "pack.zip");
330
+ await provider.download(file, archiveFile);
331
+ const resolved = await resolvePackRoots(archiveFile);
332
+ const roots = resolved.roots;
333
+ const bpRoot = roots.find((r) => readPackManifestInfo(r)?.kind === "behavior");
334
+ const remoteBpInfo = bpRoot ? readPackManifestInfo(bpRoot) : null;
335
+ if (!remoteBpInfo) {
336
+ resolved.dispose();
337
+ try {
338
+ fs.rmSync(stagingDir, { recursive: true, force: true });
339
+ } catch {
340
+ }
341
+ return withLocalBp(
342
+ baseCheckFields(bpUuid, name, localVer, binding, {
343
+ fileId: file.fileId,
344
+ message: t("packUpdate.remoteNoBp")
345
+ }),
346
+ localBp
347
+ );
348
+ }
349
+ const decision = decideVersionPolicy(localVer, remoteBpInfo.version, cfg.versionPolicy, {
350
+ treatAsUpdate: true
351
+ });
352
+ touchBinding(bpUuid, binding, { lastFileId: file.fileId });
353
+ const message = decision.remoteNewer ? t("packUpdate.bpNewer", {
354
+ local: fmtVer(localVer),
355
+ remote: fmtVer(remoteBpInfo.version)
356
+ }) : t("packUpdate.needSync", {
357
+ local: fmtVer(localVer),
358
+ remote: fmtVer(remoteBpInfo.version),
359
+ id: String(file.fileId)
360
+ });
361
+ return withLocalBp(
362
+ {
363
+ bpUuid,
364
+ name,
365
+ localVer,
366
+ remoteVer: remoteBpInfo.version,
367
+ updateAvailable: true,
368
+ majorHigher: decision.majorHigher,
369
+ shouldBumpRp: decision.shouldBumpRp,
370
+ fileId: file.fileId,
371
+ message,
372
+ binding,
373
+ remoteBpInfo,
374
+ remoteRoots: roots,
375
+ stagingDir,
376
+ disposeRoots: resolved.dispose
377
+ },
378
+ localBp
379
+ );
380
+ }
381
+ function cleanupCheck(r) {
382
+ if (r.disposeRoots) {
383
+ try {
384
+ r.disposeRoots();
385
+ } catch {
386
+ }
387
+ }
388
+ for (const d of [r.tempDir, r.stagingDir]) {
389
+ if (!d) continue;
390
+ try {
391
+ fs.rmSync(d, { recursive: true, force: true });
392
+ } catch {
393
+ }
394
+ }
395
+ }
396
+ async function tryInstallResourcePack(opts) {
397
+ for (const root of opts.rpRoots) {
398
+ const info = readPackManifestInfo(root);
399
+ if (!info || !opts.accept(info)) continue;
400
+ const rpDest = worldPackParentDir(opts.bdsRoot, opts.levelName, "resource");
401
+ const rpInstall = await installPackDirectory({
402
+ srcDir: root,
403
+ destParent: rpDest,
404
+ force: true,
405
+ ...opts.folderName ? { folderName: opts.folderName } : {}
406
+ });
407
+ if (rpInstall.ok && rpInstall.info && rpInstall.destDir) {
408
+ return { info: rpInstall.info, destDir: rpInstall.destDir };
409
+ }
410
+ }
411
+ return null;
412
+ }
413
+ async function applyUpdate(r, cfg) {
414
+ if (!r.updateAvailable || !r.remoteRoots || !r.remoteBpInfo) {
415
+ return { ok: true, message: r.message };
416
+ }
417
+ const { bdsRoot, levelName } = resolveBdsContext();
418
+ const packs = listInstalledWorldPacks(bdsRoot, levelName);
419
+ const oldRp = r.binding.pairedResourceUuid != null ? packs.find((p) => p.kind === "resource" && p.uuid.toLowerCase() === r.binding.pairedResourceUuid.toLowerCase()) : void 0;
420
+ const oldRpVer = oldRp?.version ?? [0, 0, 0];
421
+ const bpRoot = r.remoteRoots.find((x) => readPackManifestInfo(x)?.kind === "behavior");
422
+ const rpRoots = r.remoteRoots.filter((x) => readPackManifestInfo(x)?.kind === "resource");
423
+ if (!bpRoot) return { ok: false, message: t("packUpdate.remoteNoBp") };
424
+ const bpDest = worldPackParentDir(bdsRoot, levelName, "behavior");
425
+ const bpInstall = await installPackDirectory({
426
+ srcDir: bpRoot,
427
+ destParent: bpDest,
428
+ force: true,
429
+ ...r.localBp?.folderName ? { folderName: r.localBp.folderName } : {}
430
+ });
431
+ if (!bpInstall.ok || !bpInstall.info || !bpInstall.destDir) {
432
+ return { ok: false, message: t("packUpdate.installFail", { reason: bpInstall.reason ?? "?" }) };
433
+ }
434
+ await enableInstalledPack({ bdsRoot, levelName, info: bpInstall.info });
435
+ logPack(
436
+ t("packUpdate.installedBp", {
437
+ dir: bpInstall.destDir,
438
+ version: fmtVer(bpInstall.info.version)
439
+ }),
440
+ "success"
441
+ );
442
+ let rpInfo = null;
443
+ let rpDir = null;
444
+ const wantRp = r.binding.pairedResourceUuid?.toLowerCase();
445
+ const installed = await tryInstallResourcePack({
446
+ rpRoots,
447
+ bdsRoot,
448
+ levelName,
449
+ ...oldRp?.folderName ? { folderName: oldRp.folderName } : {},
450
+ accept: (info) => !wantRp || info.uuid.toLowerCase() === wantRp
451
+ });
452
+ if (installed) {
453
+ rpInfo = installed.info;
454
+ rpDir = installed.destDir;
455
+ }
456
+ if (!rpInfo && rpRoots.length > 0) {
457
+ const deps = readPackDependencyUuids(bpInstall.destDir);
458
+ const fallback = await tryInstallResourcePack({
459
+ rpRoots,
460
+ bdsRoot,
461
+ levelName,
462
+ accept: (info) => deps.length === 0 || deps.some((d) => d.toLowerCase() === info.uuid.toLowerCase())
463
+ });
464
+ if (fallback) {
465
+ rpInfo = fallback.info;
466
+ rpDir = fallback.destDir;
467
+ r.binding.pairedResourceUuid = fallback.info.uuid;
468
+ }
469
+ }
470
+ if (rpInfo && rpDir && r.shouldBumpRp) {
471
+ const next = ensureVersionGreaterThan(rpDir, oldRpVer, cfg.versionPolicy.rpBumpComponent);
472
+ rpInfo = { ...rpInfo, version: next };
473
+ }
474
+ if (rpInfo) {
475
+ await enableInstalledPack({ bdsRoot, levelName, info: rpInfo });
476
+ logPack(
477
+ t("packUpdate.installedRp", {
478
+ dir: rpDir ?? "-",
479
+ version: fmtVer(rpInfo.version)
480
+ }),
481
+ "success"
482
+ );
483
+ } else if (rpRoots.length > 0) {
484
+ logPack(t("packUpdate.rpInstallMiss"), "warn");
485
+ }
486
+ touchBinding(r.bpUuid, r.binding, {
487
+ lastAppliedFileId: r.fileId,
488
+ lastFileId: r.fileId,
489
+ lastCheckedAt: (/* @__PURE__ */ new Date()).toISOString()
490
+ });
491
+ return {
492
+ ok: true,
493
+ message: t("packUpdate.applied", {
494
+ name: r.name,
495
+ bp: fmtVer(bpInstall.info.version),
496
+ rp: rpInfo ? fmtVer(rpInfo.version) : "-"
497
+ })
498
+ };
499
+ }
500
+ async function checkPackUpdates(opts) {
501
+ const cfg = loadPackUpdateConfig();
502
+ if (!cfg.enabled) return c.dim(t("packUpdate.disabled"));
503
+ if (!resolveConfiguredPackProvider(cfg)) {
504
+ return c.yellow(needKeyText());
505
+ }
506
+ const { bdsRoot, levelName } = resolveBdsContext();
507
+ const packs = listInstalledWorldPacks(bdsRoot, levelName);
508
+ let targets = listBindings();
509
+ if (opts?.packId) {
510
+ const pack = findInstalledPackById(packs, opts.packId);
511
+ const uuid = pack?.uuid ?? opts.packId;
512
+ targets = targets.filter((x) => x.bpUuid.toLowerCase() === uuid.toLowerCase());
513
+ if (targets.length === 0) {
514
+ const b = getBinding(uuid);
515
+ if (b) targets = [{ bpUuid: uuid, binding: b }];
516
+ }
517
+ if (targets.length === 0) return c.red(t("packUpdate.noBinding", { id: opts.packId }));
518
+ }
519
+ if (targets.length === 0) return c.dim(t("packUpdate.sourcesEmpty"));
520
+ const lines = [];
521
+ for (const { bpUuid, binding } of targets) {
522
+ if (cfg.startup.skipDisabledBindings && !binding.enabled && !opts?.packId) continue;
523
+ let result = null;
524
+ try {
525
+ result = await prepareCheck(bpUuid, binding, cfg, packs, true);
526
+ if (opts?.apply && result.updateAvailable) {
527
+ const applied = await applyUpdate(result, cfg);
528
+ lines.push(applied.ok ? c.green(applied.message) : c.red(applied.message));
529
+ } else {
530
+ lines.push(
531
+ result.updateAvailable ? c.yellow(`${result.name}: ${result.message}`) : c.dim(`${result.name}: ${result.message}`)
532
+ );
533
+ }
534
+ } catch (e) {
535
+ lines.push(c.red(`${bpUuid}: ${e.message}`));
536
+ if (cfg.startup.failMode === "abort") break;
537
+ } finally {
538
+ if (result) cleanupCheck(result);
539
+ }
540
+ if (cfg.startup.delayMsBetweenPacks > 0) {
541
+ await new Promise((r) => setTimeout(r, cfg.startup.delayMsBetweenPacks));
542
+ }
543
+ }
544
+ return lines.join("\n") || c.dim(t("packUpdate.sourcesEmpty"));
545
+ }
546
+ async function runPackUpdatesOnBdsStart() {
547
+ const cfg = loadPackUpdateConfig();
548
+ if (!cfg.enabled || !cfg.checkOnBdsStart) return;
549
+ try {
550
+ const out = await checkPackUpdates({ apply: cfg.applyOnBdsStart });
551
+ if (out.trim()) logPack(out.replace(/\x1B\[[0-9;]*m/g, ""), "info");
552
+ } catch (e) {
553
+ logPack(t("packUpdate.startupFail", { message: e.message }), "warn");
554
+ }
555
+ }
556
+ function bindingLabelForUuid(uuid) {
557
+ const b = getBinding(uuid);
558
+ if (!b) return "src=-";
559
+ const tag = `${providerShortLabel(b.provider)}:${b.slug || b.projectId}`;
560
+ return b.enabled ? `src=${tag}` : `src=${tag}:off`;
561
+ }
562
+ export {
563
+ bindPackSource,
564
+ bindingLabelForUuid,
565
+ checkPackUpdates,
566
+ formatSourcesList,
567
+ pairedRpUuidFromBpDir,
568
+ probeSourceAfterInstall,
569
+ runPackUpdatesOnBdsStart,
570
+ searchRemote
571
+ };
572
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/pack-update/service.ts"],
4
+ "sourcesContent": ["/**\n * pack-update \u7F16\u6392\uFF1A\u63A2\u6D4B\u7ED1\u5B9A / \u68C0\u67E5 / \u5E94\u7528\u66F4\u65B0\n */\nimport { confirm, isCancel } from \"@clack/prompts\";\nimport {\n enableInstalledPack,\n ensureVersionGreaterThan,\n findInstalledPackById,\n installPackDirectory,\n listInstalledWorldPacks,\n readPackDependencyUuids,\n readPackManifestInfo,\n resolvePackRoots,\n worldPackParentDir,\n type InstalledWorldPack,\n type PackManifestInfo,\n} from \"@sfmc-bds/bds-tools/world-packs\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { t } from \"../i18n/index.js\";\nimport { pushLog } from \"../logs.js\";\nimport { resolveBdsContext } from \"../pack-lifecycle.js\";\nimport { c } from \"../theme.js\";\nimport { getBinding, listBindings, packSourcesPath, setBinding } from \"./bindings.js\";\nimport {\n ensurePackUpdateConfigFile,\n getPackMatchConfig,\n loadPackUpdateConfig,\n packUpdateConfigPath,\n} from \"./config.js\";\nimport {\n createPackSourceProvider,\n providerShortLabel,\n resolveConfiguredPackProvider,\n} from \"./providers/index.js\";\nimport type {\n PackSourceBinding,\n PackSourceProvider,\n PackUpdateConfig,\n SemVer3,\n SourceSearchHit,\n} from \"./types.js\";\nimport {\n decideVersionPolicy,\n buildSearchQueries,\n buildSearchQueriesFromSources,\n packSourceScore,\n} from \"./version-policy.js\";\n\nfunction logPack(text: string, level: \"info\" | \"warn\" | \"error\" | \"success\" = \"info\"): void {\n pushLog(text, \"pack\", level);\n}\n\nfunction fmtVer(v: SemVer3): string {\n return v.join(\".\");\n}\n\n/** \u7ED1\u5B9A\u542F\u7528\u6001\u6587\u6848\uFF1AbindOk / sources list \u5171\u7528\uFF08DRY\uFF09\uFF0C\u8D70 packs.list i18n */\nfunction bindingEnabledLabel(enabled: boolean): string {\n return enabled ? t(\"packs.list.on\").trim() : t(\"packs.list.off\").trim();\n}\n\n/** \u672A\u914D\u7F6E\u6E90\u65F6\u7684\u7EDF\u4E00\u6587\u6848\uFF08DRY\uFF1A\u5165\u53E3\u52FF\u5404\u81EA\u62FC needKey\uFF1B\u6587\u6848\u6E90\u65E0\u5173 \u2014 OCP\uFF09 */\nfunction needKeyText(): string {\n return t(\"packUpdate.needKey\", { path: packUpdateConfigPath() });\n}\n\n/** bindOk \u53C2\u6570\u552F\u4E00\u6784\u9020\u70B9\uFF08probe / bind \u5171\u7528 \u2014 DRY\uFF09\uFF0C\u62A5\u544A\u5B9E\u9645 binding.enabled\uFF08LSP\uFF09 */\nfunction bindOkParams(opts: {\n uuid: string;\n provider: PackSourceBinding[\"provider\"] | SourceSearchHit[\"provider\"];\n slug: string;\n enabled: boolean;\n}): Record<string, string> {\n return {\n uuid: opts.uuid,\n provider: providerShortLabel(opts.provider),\n slug: opts.slug,\n enabled: bindingEnabledLabel(opts.enabled),\n path: packSourcesPath(),\n };\n}\n\n/** \u5C31\u5730\u8865\u4E01\u5E76\u843D\u76D8\uFF08prepareCheck \u591A\u51FA\u53E3\u5171\u7528 \u2014 DRY\uFF1B\u52FF\u6563\u843D Object.assign+setBinding\uFF09 */\nfunction touchBinding(bpUuid: string, binding: PackSourceBinding, patch?: Partial<PackSourceBinding>): void {\n if (patch) Object.assign(binding, patch);\n setBinding(bpUuid, binding);\n}\n\n/** \u8BE5 fileId \u662F\u5426\u5DF2\u6210\u529F\u5199\u5165\u4E16\u754C\u76EE\u5F55\uFF08DRY\uFF1AprepareCheck \u591A\u5904\u52FF\u624B\u5199 null/!==\uFF09 */\nfunction isFileIdApplied(binding: PackSourceBinding, fileId: number): boolean {\n return binding.lastAppliedFileId != null && binding.lastAppliedFileId === fileId;\n}\n\n/** \u591A\u67E5\u8BE2\u641C\u7D22 + \u7EFC\u5408\u6253\u5206\u6392\u5E8F\uFF08probe / searchRemote \u5171\u7528\uFF09 */\nasync function searchAndRankHits(\n provider: PackSourceProvider,\n queries: string[],\n stripFolderTags: boolean\n): Promise<Array<{ hit: SourceSearchHit; score: number }>> {\n const byId = new Map<number, SourceSearchHit>();\n for (const q of queries) {\n const hits = await provider.search(q);\n for (const h of hits) byId.set(h.projectId, h);\n }\n return [...byId.values()]\n .map((h) => ({\n hit: h,\n score: Math.max(...queries.map((q) => packSourceScore(q, h, stripFolderTags))),\n }))\n .sort((a, b) => b.score - a.score);\n}\n\nfunction makeBindingFromHit(\n hit: SourceSearchHit,\n pairedResourceUuid: string | null,\n opts?: { prev?: PackSourceBinding | null; defaultEnabled: boolean }\n): PackSourceBinding {\n const prev = opts?.prev;\n return {\n /* \u91CD\u7ED1\u4FDD\u7559\u539F enabled\uFF1B\u65B0\u5EFA\u8D70\u914D\u7F6E\u5951\u7EA6 defaultBindingEnabled\uFF08LSP\uFF09 */\n enabled: prev?.enabled ?? opts?.defaultEnabled ?? false,\n provider: hit.provider,\n projectId: hit.projectId,\n slug: hit.slug,\n websiteUrl: hit.websiteUrl,\n pairedResourceUuid,\n lastFileId: prev?.lastFileId ?? null,\n lastCheckedAt: null,\n lastAppliedFileId: prev?.lastAppliedFileId ?? null,\n };\n}\n\n/** \u4ECE\u5DF2\u5B89\u88C5 BP \u63D0\u53D6\u914D\u5BF9 RP uuid */\nexport function pairedRpUuidFromBpDir(bpDir: string): string | null {\n const deps = readPackDependencyUuids(bpDir);\n return deps[0] ?? null;\n}\n\nexport async function probeSourceAfterInstall(opts: {\n info: PackManifestInfo;\n packDir?: string;\n /** \u5B89\u88C5\u540E\u7684\u6587\u4EF6\u5939\u540D\uFF08\u4F18\u5148\u4E8E basename(packDir)\uFF09 */\n folderName?: string;\n interactive?: boolean;\n}): Promise<void> {\n const cfg = loadPackUpdateConfig();\n if (!cfg.enabled || !cfg.probeSourceAfterInstall) return;\n if (opts.info.kind !== \"behavior\") return;\n\n ensurePackUpdateConfigFile();\n const provider = resolveConfiguredPackProvider(cfg);\n if (!provider) {\n logPack(needKeyText(), \"warn\");\n return;\n }\n\n const match = getPackMatchConfig(cfg);\n /* header \u5E38\u672C\u5730\u5316\uFF1B\u6587\u4EF6\u5939\u540D\u5F80\u5F80\u542B\u62C9\u4E01\u6838\u5FC3 \u2014 \u4E24\u6E90\u5206\u522B\u6D3E\u751F\u518D\u5408\u5E76\uFF0C\u6709\u62C9\u4E01\u5219\u4E0D\u641C\u7EAF\u4E2D\u6587 */\n const folderName =\n (opts.folderName && String(opts.folderName).trim()) ||\n (opts.packDir ? path.basename(opts.packDir) : \"\");\n const plan = buildSearchQueriesFromSources(\n [\n { id: \"header\", raw: opts.info.name },\n { id: \"folder\", raw: folderName },\n ],\n match.stripFolderTags\n );\n const queries = plan.queries;\n if (queries.length === 0) {\n logPack(t(\"packUpdate.probeNoName\"), \"warn\");\n return;\n }\n\n logPack(\n t(\"packUpdate.probeQueries\", {\n header: opts.info.name || \"-\",\n folder: folderName || \"-\",\n queries: queries.join(\" | \"),\n }),\n \"info\"\n );\n\n let scored: Array<{ hit: SourceSearchHit; score: number }>;\n try {\n scored = await searchAndRankHits(provider, queries, match.stripFolderTags);\n } catch (e) {\n logPack(t(\"packUpdate.probeFail\", { message: (e as Error).message }), \"warn\");\n return;\n }\n\n if (scored.length === 0) {\n logPack(t(\"packUpdate.probeMiss\", { name: queries.join(\", \") }), \"info\");\n return;\n }\n\n const primary = queries.find((q) => /[A-Za-z]/.test(q)) ?? queries[0]!;\n const best = scored[0]!;\n if (best.score < match.nameMinScore) {\n logPack(\n t(\"packUpdate.probeLowScore\", {\n name: primary,\n hit: `${best.hit.name} (${best.hit.slug})`,\n score: best.score.toFixed(2),\n url: best.hit.websiteUrl,\n }),\n \"info\"\n );\n return;\n }\n\n logPack(\n t(\"packUpdate.probeHit\", {\n name: `${opts.info.name} / ${folderName || \"-\"}`,\n hit: `${best.hit.name} [${best.hit.slug}]`,\n url: best.hit.websiteUrl,\n score: best.score.toFixed(2),\n }),\n \"success\"\n );\n logPack(t(\"packUpdate.editHint\", { path: packSourcesPath() }), \"info\");\n\n const interactive = opts.interactive ?? !!process.stdin.isTTY;\n let accept = false;\n if (interactive && cfg.askConfirmOnBind && process.stdin.isTTY) {\n const ans = await confirm({\n message: t(\"packUpdate.confirmBind\", { hit: best.hit.name }),\n initialValue: true,\n });\n if (isCancel(ans)) return;\n accept = !!ans;\n } else {\n /* \u975E TTY / BDS \u6536\u4EF6\u7BB1 / askConfirmOnBind=false\uFF1A\u547D\u4E2D\u5373\u5199\u5165\uFF0C\u907F\u514D\u63A2\u6D4B\u6210\u529F\u5374\u65E0 pack-sources.json */\n accept = true;\n logPack(\n t(\"packUpdate.probeAutoBind\", {\n provider: providerShortLabel(best.hit.provider),\n slug: best.hit.slug,\n path: packSourcesPath(),\n }),\n \"info\"\n );\n }\n\n if (!accept) {\n logPack(t(\"packUpdate.bindSkipped\"), \"info\");\n return;\n }\n\n const paired = (opts.packDir ? pairedRpUuidFromBpDir(opts.packDir) : null) ?? null;\n const binding = makeBindingFromHit(best.hit, paired, { defaultEnabled: cfg.defaultBindingEnabled });\n setBinding(opts.info.uuid, binding);\n logPack(\n t(\n \"packUpdate.bindOk\",\n bindOkParams({\n uuid: opts.info.uuid,\n provider: best.hit.provider,\n slug: best.hit.slug,\n enabled: binding.enabled,\n })\n ),\n \"success\"\n );\n}\n\nexport async function searchRemote(query: string): Promise<string> {\n const cfg = loadPackUpdateConfig();\n const provider = resolveConfiguredPackProvider(cfg);\n if (!provider) {\n return c.yellow(needKeyText());\n }\n const match = getPackMatchConfig(cfg);\n const queries = buildSearchQueries(query, match.stripFolderTags);\n const ranked = await searchAndRankHits(provider, queries, match.stripFolderTags);\n if (ranked.length === 0) return c.dim(t(\"packUpdate.searchEmpty\", { query }));\n return ranked\n .map(\n ({ hit: h, score }, i) =>\n `${c.cyan(String(i + 1).padStart(2))}. ${h.name} ${c.dim(`id=${h.projectId} slug=${h.slug} score=${score.toFixed(2)}`)}\\n ${h.websiteUrl}`\n )\n .join(\"\\n\");\n}\n\nexport async function bindPackSource(packId: string, ref: string): Promise<string> {\n const cfg = loadPackUpdateConfig();\n const provider = resolveConfiguredPackProvider(cfg);\n if (!provider) {\n return c.yellow(needKeyText());\n }\n const { bdsRoot, levelName } = resolveBdsContext();\n const packs = listInstalledWorldPacks(bdsRoot, levelName);\n const pack = findInstalledPackById(packs, packId);\n if (!pack) return c.red(t(\"packs.notFound\", { id: packId }));\n if (pack.kind !== \"behavior\") return c.red(t(\"packUpdate.bindBpOnly\"));\n\n const hit = await provider.resolveProject(ref);\n if (!hit) return c.red(t(\"packUpdate.resolveFail\", { ref }));\n\n const paired = pairedRpUuidFromBpDir(pack.dir);\n const binding = makeBindingFromHit(hit, paired, {\n prev: getBinding(pack.uuid),\n defaultEnabled: cfg.defaultBindingEnabled,\n });\n setBinding(pack.uuid, binding);\n return c.green(\n t(\n \"packUpdate.bindOk\",\n bindOkParams({\n uuid: pack.uuid,\n provider: hit.provider,\n slug: hit.slug,\n enabled: binding.enabled,\n })\n )\n );\n}\n\nexport function formatSourcesList(): string {\n ensurePackUpdateConfigFile();\n const bindings = listBindings();\n const lines = [\n t(\"packUpdate.sourcesHeader\", {\n config: packUpdateConfigPath(),\n sources: packSourcesPath(),\n }),\n ];\n if (bindings.length === 0) {\n lines.push(c.dim(t(\"packUpdate.sourcesEmpty\")));\n return lines.join(\"\\n\");\n }\n for (const { bpUuid, binding } of bindings) {\n const label = bindingEnabledLabel(binding.enabled);\n const en = binding.enabled ? c.green(label) : c.dim(label);\n const tag = providerShortLabel(binding.provider);\n lines.push(\n ` [${en}] ${bpUuid} ${tag}:${binding.slug || binding.projectId} ${c.dim(binding.websiteUrl || \"\")}`\n );\n }\n return lines.join(\"\\n\");\n}\n\ninterface CheckResult {\n bpUuid: string;\n name: string;\n localVer: SemVer3;\n remoteVer: SemVer3 | null;\n updateAvailable: boolean;\n majorHigher: boolean;\n shouldBumpRp: boolean;\n fileId: number | null;\n message: string;\n binding: PackSourceBinding;\n localBp?: InstalledWorldPack;\n remoteBpInfo?: PackManifestInfo;\n remoteRoots?: string[];\n tempDir?: string;\n /** \u4E0B\u8F7D\u5F52\u6863\u6240\u5728\u7684\u4E34\u65F6 staging \u76EE\u5F55\uFF08\u975E zip \u6587\u4EF6\u8DEF\u5F84\uFF09 */\n stagingDir?: string;\n /** resolvePackRoots \u521B\u5EFA\u7684\u4E34\u65F6\u6811\u6E05\u7406 */\n disposeRoots?: () => void;\n}\n\nfunction withLocalBp(base: Omit<CheckResult, \"localBp\">, localBp: InstalledWorldPack | undefined): CheckResult {\n return localBp ? { ...base, localBp } : { ...base };\n}\n\nfunction baseCheckFields(\n bpUuid: string,\n name: string,\n localVer: SemVer3,\n binding: PackSourceBinding,\n extras: Partial<CheckResult> & { message: string }\n): Omit<CheckResult, \"localBp\"> {\n return {\n bpUuid,\n name,\n localVer,\n remoteVer: null,\n updateAvailable: false,\n majorHigher: false,\n shouldBumpRp: false,\n fileId: null,\n binding,\n ...extras,\n };\n}\n\nasync function prepareCheck(\n bpUuid: string,\n binding: PackSourceBinding,\n cfg: PackUpdateConfig,\n packs: InstalledWorldPack[],\n downloadArchive: boolean\n): Promise<CheckResult> {\n const localBp = packs.find((p) => p.uuid.toLowerCase() === bpUuid.toLowerCase() && p.kind === \"behavior\");\n const name = localBp?.name ?? bpUuid;\n const localVer: SemVer3 = localBp?.version ?? [0, 0, 0];\n const provider = createPackSourceProvider(cfg, binding.provider);\n\n touchBinding(bpUuid, binding, { lastCheckedAt: new Date().toISOString() });\n\n if (!binding.enabled) {\n return withLocalBp(\n baseCheckFields(bpUuid, name, localVer, binding, { message: t(\"packUpdate.bindingDisabled\") }),\n localBp\n );\n }\n\n const file = await provider.getLatestFile(binding.projectId);\n if (!file) {\n return withLocalBp(\n baseCheckFields(bpUuid, name, localVer, binding, { message: t(\"packUpdate.noRemoteFile\") }),\n localBp\n );\n }\n\n /* \u5DF2\u6210\u529F\u5E94\u7528\u540C\u4E00 fileId\uFF1A\u4E0D\u518D\u4E0B\u8F7D */\n if (isFileIdApplied(binding, file.fileId)) {\n touchBinding(bpUuid, binding, { lastFileId: file.fileId });\n return withLocalBp(\n baseCheckFields(bpUuid, name, localVer, binding, {\n fileId: file.fileId,\n message: t(\"packUpdate.upToDate\"),\n }),\n localBp\n );\n }\n\n if (!downloadArchive) {\n /* \u4EC5\u6587\u4EF6 id \u6BD4\u8F83\u7684\u8F7B\u91CF\u68C0\u67E5\uFF08\u672A apply \u5373\u89C6\u4E3A\u6709\u66F4\u65B0\uFF09 */\n return withLocalBp(\n baseCheckFields(bpUuid, name, localVer, binding, {\n updateAvailable: true,\n fileId: file.fileId,\n message: t(\"packUpdate.fileNewer\", { file: file.fileName, id: String(file.fileId) }),\n }),\n localBp\n );\n }\n\n const stagingDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-pack-upd-\"));\n const archiveFile = path.join(stagingDir, file.fileName || \"pack.zip\");\n await provider.download(file, archiveFile);\n const resolved = await resolvePackRoots(archiveFile);\n const roots = resolved.roots;\n const bpRoot = roots.find((r) => readPackManifestInfo(r)?.kind === \"behavior\");\n const remoteBpInfo = bpRoot ? readPackManifestInfo(bpRoot) : null;\n if (!remoteBpInfo) {\n resolved.dispose();\n try {\n fs.rmSync(stagingDir, { recursive: true, force: true });\n } catch {\n /* ignore */\n }\n return withLocalBp(\n baseCheckFields(bpUuid, name, localVer, binding, {\n fileId: file.fileId,\n message: t(\"packUpdate.remoteNoBp\"),\n }),\n localBp\n );\n }\n\n /*\n * \u80FD\u8D70\u5230\u6B64\u5904\u8BF4\u660E\u8BE5 fileId \u5C1A\u672A\u6210\u529F apply\uFF08\u4E0A\u65B9\u5DF2 early-return\uFF09\u3002\n * - \u8FDC\u7A0B BP \u7248\u672C\u66F4\u9AD8 \u2192 \u8986\u76D6\n * - \u7248\u672C\u672A\u66F4\u9AD8 \u2192 \u4ECD\u8986\u76D6\uFF08\u6C49\u5316\u5305\u7B49\u540C\u7248\u672C\u53F7\u4E0D\u540C\u5185\u5BB9\uFF1B\u52FF\u5728\u672A install \u65F6\u5199 lastAppliedFileId\uFF09\n * RP bump \u89C4\u5219\u96C6\u4E2D\u5728 decideVersionPolicy\uFF08OCP/DRY\uFF1A\u52FF\u5728\u7F16\u6392\u5C42\u590D\u523B policy \u5B57\u6BB5\uFF09\u3002\n */\n const decision = decideVersionPolicy(localVer, remoteBpInfo.version, cfg.versionPolicy, {\n treatAsUpdate: true,\n });\n\n touchBinding(bpUuid, binding, { lastFileId: file.fileId });\n\n const message = decision.remoteNewer\n ? t(\"packUpdate.bpNewer\", {\n local: fmtVer(localVer),\n remote: fmtVer(remoteBpInfo.version),\n })\n : t(\"packUpdate.needSync\", {\n local: fmtVer(localVer),\n remote: fmtVer(remoteBpInfo.version),\n id: String(file.fileId),\n });\n\n return withLocalBp(\n {\n bpUuid,\n name,\n localVer,\n remoteVer: remoteBpInfo.version,\n updateAvailable: true,\n majorHigher: decision.majorHigher,\n shouldBumpRp: decision.shouldBumpRp,\n fileId: file.fileId,\n message,\n binding,\n remoteBpInfo,\n remoteRoots: roots,\n stagingDir,\n disposeRoots: resolved.dispose,\n },\n localBp\n );\n}\n\nfunction cleanupCheck(r: CheckResult): void {\n if (r.disposeRoots) {\n try {\n r.disposeRoots();\n } catch {\n /* ignore */\n }\n }\n for (const d of [r.tempDir, r.stagingDir]) {\n if (!d) continue;\n try {\n fs.rmSync(d, { recursive: true, force: true });\n } catch {\n /* ignore */\n }\n }\n}\n\n/** \u5C1D\u8BD5\u5B89\u88C5\u914D\u5BF9 RP\uFF1Baccept \u4E3A\u8FC7\u6EE4\u8C13\u8BCD\uFF08DRY\uFF1A\u4E24\u5904\u5FAA\u73AF\u5408\u4E00\uFF09 */\nasync function tryInstallResourcePack(opts: {\n rpRoots: string[];\n bdsRoot: string;\n levelName: string;\n folderName?: string;\n accept: (info: PackManifestInfo) => boolean;\n}): Promise<{ info: PackManifestInfo; destDir: string } | null> {\n for (const root of opts.rpRoots) {\n const info = readPackManifestInfo(root);\n if (!info || !opts.accept(info)) continue;\n const rpDest = worldPackParentDir(opts.bdsRoot, opts.levelName, \"resource\");\n const rpInstall = await installPackDirectory({\n srcDir: root,\n destParent: rpDest,\n force: true,\n ...(opts.folderName ? { folderName: opts.folderName } : {}),\n });\n if (rpInstall.ok && rpInstall.info && rpInstall.destDir) {\n return { info: rpInstall.info, destDir: rpInstall.destDir };\n }\n }\n return null;\n}\n\nasync function applyUpdate(r: CheckResult, cfg: PackUpdateConfig): Promise<{ ok: boolean; message: string }> {\n if (!r.updateAvailable || !r.remoteRoots || !r.remoteBpInfo) {\n return { ok: true, message: r.message };\n }\n const { bdsRoot, levelName } = resolveBdsContext();\n const packs = listInstalledWorldPacks(bdsRoot, levelName);\n\n const oldRp =\n r.binding.pairedResourceUuid != null\n ? packs.find((p) => p.kind === \"resource\" && p.uuid.toLowerCase() === r.binding.pairedResourceUuid!.toLowerCase())\n : undefined;\n const oldRpVer: SemVer3 = oldRp?.version ?? [0, 0, 0];\n\n const bpRoot = r.remoteRoots.find((x) => readPackManifestInfo(x)?.kind === \"behavior\");\n const rpRoots = r.remoteRoots.filter((x) => readPackManifestInfo(x)?.kind === \"resource\");\n\n if (!bpRoot) return { ok: false, message: t(\"packUpdate.remoteNoBp\") };\n\n /* \u5B89\u88C5 BP\uFF08force \u8986\u76D6\u540C uuid / \u540C\u6587\u4EF6\u5939\uFF09 */\n const bpDest = worldPackParentDir(bdsRoot, levelName, \"behavior\");\n const bpInstall = await installPackDirectory({\n srcDir: bpRoot,\n destParent: bpDest,\n force: true,\n ...(r.localBp?.folderName ? { folderName: r.localBp.folderName } : {}),\n });\n if (!bpInstall.ok || !bpInstall.info || !bpInstall.destDir) {\n return { ok: false, message: t(\"packUpdate.installFail\", { reason: bpInstall.reason ?? \"?\" }) };\n }\n await enableInstalledPack({ bdsRoot, levelName, info: bpInstall.info });\n logPack(\n t(\"packUpdate.installedBp\", {\n dir: bpInstall.destDir,\n version: fmtVer(bpInstall.info.version),\n }),\n \"success\"\n );\n\n /* \u5B89\u88C5\u914D\u5BF9 RP\uFF1A\u5148\u6309 binding uuid\uFF0C\u518D\u6309\u65B0 BP dependencies */\n let rpInfo: PackManifestInfo | null = null;\n let rpDir: string | null = null;\n const wantRp = r.binding.pairedResourceUuid?.toLowerCase();\n const installed = await tryInstallResourcePack({\n rpRoots,\n bdsRoot,\n levelName,\n ...(oldRp?.folderName ? { folderName: oldRp.folderName } : {}),\n accept: (info) => !wantRp || info.uuid.toLowerCase() === wantRp,\n });\n if (installed) {\n rpInfo = installed.info;\n rpDir = installed.destDir;\n }\n\n if (!rpInfo && rpRoots.length > 0) {\n const deps = readPackDependencyUuids(bpInstall.destDir);\n const fallback = await tryInstallResourcePack({\n rpRoots,\n bdsRoot,\n levelName,\n accept: (info) =>\n deps.length === 0 || deps.some((d) => d.toLowerCase() === info.uuid.toLowerCase()),\n });\n if (fallback) {\n rpInfo = fallback.info;\n rpDir = fallback.destDir;\n r.binding.pairedResourceUuid = fallback.info.uuid;\n }\n }\n\n /* \u542F\u7528\u7248\u672C = bump(max(\u65B0\u5305, \u65E7 RP))\uFF0C\u5355\u4E00\u89C4\u5219\u89E6\u53D1\u5BA2\u6237\u7AEF\u5237\u65B0 */\n if (rpInfo && rpDir && r.shouldBumpRp) {\n const next = ensureVersionGreaterThan(rpDir, oldRpVer, cfg.versionPolicy.rpBumpComponent);\n rpInfo = { ...rpInfo, version: next };\n }\n\n if (rpInfo) {\n await enableInstalledPack({ bdsRoot, levelName, info: rpInfo });\n logPack(\n t(\"packUpdate.installedRp\", {\n dir: rpDir ?? \"-\",\n version: fmtVer(rpInfo.version),\n }),\n \"success\"\n );\n } else if (rpRoots.length > 0) {\n logPack(t(\"packUpdate.rpInstallMiss\"), \"warn\");\n }\n\n touchBinding(r.bpUuid, r.binding, {\n lastAppliedFileId: r.fileId,\n lastFileId: r.fileId,\n lastCheckedAt: new Date().toISOString(),\n });\n\n return {\n ok: true,\n message: t(\"packUpdate.applied\", {\n name: r.name,\n bp: fmtVer(bpInstall.info.version),\n rp: rpInfo ? fmtVer(rpInfo.version) : \"-\",\n }),\n };\n}\n\nexport async function checkPackUpdates(opts?: { packId?: string; apply?: boolean }): Promise<string> {\n const cfg = loadPackUpdateConfig();\n if (!cfg.enabled) return c.dim(t(\"packUpdate.disabled\"));\n /* \u5165\u53E3\u9884\u68C0\uFF1A\u4EFB\u4E00\u5DF2\u914D\u7F6E\u6E90\u5373\u53EF\uFF1B\u9010 binding \u4ECD\u6309 binding.provider \u5206\u6D3E\uFF08LSP/OCP\uFF09 */\n if (!resolveConfiguredPackProvider(cfg)) {\n return c.yellow(needKeyText());\n }\n\n const { bdsRoot, levelName } = resolveBdsContext();\n const packs = listInstalledWorldPacks(bdsRoot, levelName);\n let targets = listBindings();\n if (opts?.packId) {\n const pack = findInstalledPackById(packs, opts.packId);\n const uuid = pack?.uuid ?? opts.packId;\n targets = targets.filter((x) => x.bpUuid.toLowerCase() === uuid.toLowerCase());\n if (targets.length === 0) {\n const b = getBinding(uuid);\n if (b) targets = [{ bpUuid: uuid, binding: b }];\n }\n if (targets.length === 0) return c.red(t(\"packUpdate.noBinding\", { id: opts.packId }));\n }\n\n if (targets.length === 0) return c.dim(t(\"packUpdate.sourcesEmpty\"));\n\n const lines: string[] = [];\n for (const { bpUuid, binding } of targets) {\n if (cfg.startup.skipDisabledBindings && !binding.enabled && !opts?.packId) continue;\n let result: CheckResult | null = null;\n try {\n /* \u59CB\u7EC8\u4E0B\u8F7D\u5F52\u6863\u5E76\u6309 BP \u7248\u672C\u6BD4\u8F83 */\n result = await prepareCheck(bpUuid, binding, cfg, packs, true);\n if (opts?.apply && result.updateAvailable) {\n const applied = await applyUpdate(result, cfg);\n lines.push(applied.ok ? c.green(applied.message) : c.red(applied.message));\n } else {\n lines.push(\n result.updateAvailable\n ? c.yellow(`${result.name}: ${result.message}`)\n : c.dim(`${result.name}: ${result.message}`)\n );\n }\n } catch (e) {\n lines.push(c.red(`${bpUuid}: ${(e as Error).message}`));\n if (cfg.startup.failMode === \"abort\") break;\n } finally {\n if (result) cleanupCheck(result);\n }\n if (cfg.startup.delayMsBetweenPacks > 0) {\n await new Promise((r) => setTimeout(r, cfg.startup.delayMsBetweenPacks));\n }\n }\n return lines.join(\"\\n\") || c.dim(t(\"packUpdate.sourcesEmpty\"));\n}\n\n/** BDS \u542F\u52A8\u94A9\u5B50\uFF1A\u9010\u4E2A\u68C0\u67E5\u5E76\u6309\u914D\u7F6E\u5E94\u7528 */\nexport async function runPackUpdatesOnBdsStart(): Promise<void> {\n const cfg = loadPackUpdateConfig();\n if (!cfg.enabled || !cfg.checkOnBdsStart) return;\n try {\n const out = await checkPackUpdates({ apply: cfg.applyOnBdsStart });\n if (out.trim()) logPack(out.replace(/\\x1B\\[[0-9;]*m/g, \"\"), \"info\");\n } catch (e) {\n logPack(t(\"packUpdate.startupFail\", { message: (e as Error).message }), \"warn\");\n }\n}\n\nexport function bindingLabelForUuid(uuid: string): string {\n const b = getBinding(uuid);\n if (!b) return \"src=-\";\n const tag = `${providerShortLabel(b.provider)}:${b.slug || b.projectId}`;\n /* \u4E0E packs list / sources \u4E00\u81F4\uFF1A\u5173\u95ED\u65F6\u4ECD\u663E\u793A\u6E90\uFF0C\u5E76\u6807\u6CE8 off */\n return b.enabled ? `src=${tag}` : `src=${tag}:off`;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }