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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/README.md +7 -1
  2. package/dist/cli-result.d.ts +12 -0
  3. package/dist/cli-result.d.ts.map +1 -0
  4. package/dist/cli-result.js +15 -0
  5. package/dist/cli-result.js.map +7 -0
  6. package/dist/commands-behavior-pack.d.ts +11 -42
  7. package/dist/commands-behavior-pack.d.ts.map +1 -1
  8. package/dist/commands-behavior-pack.js +40 -159
  9. package/dist/commands-behavior-pack.js.map +7 -1
  10. package/dist/commands-reload.d.ts +9 -0
  11. package/dist/commands-reload.d.ts.map +1 -0
  12. package/dist/commands-reload.js +30 -0
  13. package/dist/commands-reload.js.map +7 -0
  14. package/dist/commands.d.ts +7 -0
  15. package/dist/commands.d.ts.map +1 -1
  16. package/dist/commands.js +182 -172
  17. package/dist/commands.js.map +7 -1
  18. package/dist/i18n/index.d.ts +26 -0
  19. package/dist/i18n/index.d.ts.map +1 -0
  20. package/dist/i18n/index.js +107 -0
  21. package/dist/i18n/index.js.map +7 -0
  22. package/dist/i18n/locales/en.d.ts +381 -0
  23. package/dist/i18n/locales/en.d.ts.map +1 -0
  24. package/dist/i18n/locales/en.js +393 -0
  25. package/dist/i18n/locales/en.js.map +7 -0
  26. package/dist/i18n/locales/zh-CN.d.ts +4 -0
  27. package/dist/i18n/locales/zh-CN.d.ts.map +1 -0
  28. package/dist/i18n/locales/zh-CN.js +379 -0
  29. package/dist/i18n/locales/zh-CN.js.map +7 -0
  30. package/dist/i18n/types.d.ts +7 -0
  31. package/dist/i18n/types.d.ts.map +1 -0
  32. package/dist/i18n/types.js +17 -0
  33. package/dist/i18n/types.js.map +7 -0
  34. package/dist/index.d.ts +5 -11
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +51 -43
  37. package/dist/index.js.map +7 -1
  38. package/dist/interactive-prompts.d.ts +8 -0
  39. package/dist/interactive-prompts.d.ts.map +1 -0
  40. package/dist/interactive-prompts.js +57 -0
  41. package/dist/interactive-prompts.js.map +7 -0
  42. package/dist/locale-command.d.ts +3 -0
  43. package/dist/locale-command.d.ts.map +1 -0
  44. package/dist/locale-command.js +19 -0
  45. package/dist/locale-command.js.map +7 -0
  46. package/dist/logs.d.ts +22 -4
  47. package/dist/logs.d.ts.map +1 -1
  48. package/dist/logs.js +208 -193
  49. package/dist/logs.js.map +7 -1
  50. package/dist/main.js +135 -173
  51. package/dist/main.js.map +7 -1
  52. package/dist/module-commands.d.ts +43 -4
  53. package/dist/module-commands.d.ts.map +1 -1
  54. package/dist/module-commands.js +440 -327
  55. package/dist/module-commands.js.map +7 -1
  56. package/dist/module-fingerprint.d.ts +7 -0
  57. package/dist/module-fingerprint.d.ts.map +1 -0
  58. package/dist/module-fingerprint.js +31 -0
  59. package/dist/module-fingerprint.js.map +7 -0
  60. package/dist/module-wizard.d.ts +14 -0
  61. package/dist/module-wizard.d.ts.map +1 -0
  62. package/dist/module-wizard.js +313 -0
  63. package/dist/module-wizard.js.map +7 -0
  64. package/dist/pack-lifecycle.d.ts +95 -0
  65. package/dist/pack-lifecycle.d.ts.map +1 -0
  66. package/dist/pack-lifecycle.js +634 -0
  67. package/dist/pack-lifecycle.js.map +7 -0
  68. package/dist/pack-update/bindings.d.ts +12 -0
  69. package/dist/pack-update/bindings.d.ts.map +1 -0
  70. package/dist/pack-update/bindings.js +64 -0
  71. package/dist/pack-update/bindings.js.map +7 -0
  72. package/dist/pack-update/config.d.ts +22 -0
  73. package/dist/pack-update/config.d.ts.map +1 -0
  74. package/dist/pack-update/config.js +141 -0
  75. package/dist/pack-update/config.js.map +7 -0
  76. package/dist/pack-update/providers/curseforge.d.ts +23 -0
  77. package/dist/pack-update/providers/curseforge.d.ts.map +1 -0
  78. package/dist/pack-update/providers/curseforge.js +209 -0
  79. package/dist/pack-update/providers/curseforge.js.map +7 -0
  80. package/dist/pack-update/providers/index.d.ts +16 -0
  81. package/dist/pack-update/providers/index.d.ts.map +1 -0
  82. package/dist/pack-update/providers/index.js +37 -0
  83. package/dist/pack-update/providers/index.js.map +7 -0
  84. package/dist/pack-update/service.d.ts +21 -0
  85. package/dist/pack-update/service.d.ts.map +1 -0
  86. package/dist/pack-update/service.js +567 -0
  87. package/dist/pack-update/service.js.map +7 -0
  88. package/dist/pack-update/types.d.ts +126 -0
  89. package/dist/pack-update/types.d.ts.map +1 -0
  90. package/dist/pack-update/types.js +8 -0
  91. package/dist/pack-update/types.js.map +7 -0
  92. package/dist/pack-update/version-policy.d.ts +80 -0
  93. package/dist/pack-update/version-policy.d.ts.map +1 -0
  94. package/dist/pack-update/version-policy.js +216 -0
  95. package/dist/pack-update/version-policy.js.map +7 -0
  96. package/dist/registry.d.ts +12 -4
  97. package/dist/registry.d.ts.map +1 -1
  98. package/dist/registry.js +73 -106
  99. package/dist/registry.js.map +7 -1
  100. package/dist/remote-agent.d.ts.map +1 -1
  101. package/dist/remote-agent.js +160 -176
  102. package/dist/remote-agent.js.map +7 -1
  103. package/dist/repl.d.ts +4 -0
  104. package/dist/repl.d.ts.map +1 -1
  105. package/dist/repl.js +683 -605
  106. package/dist/repl.js.map +7 -1
  107. package/dist/runtime.d.ts +40 -14
  108. package/dist/runtime.d.ts.map +1 -1
  109. package/dist/runtime.js +185 -62
  110. package/dist/runtime.js.map +7 -1
  111. package/dist/services.d.ts +2 -0
  112. package/dist/services.d.ts.map +1 -1
  113. package/dist/services.js +251 -238
  114. package/dist/services.js.map +7 -1
  115. package/dist/sfmc-modules-root.d.ts +24 -0
  116. package/dist/sfmc-modules-root.d.ts.map +1 -0
  117. package/dist/sfmc-modules-root.js +70 -0
  118. package/dist/sfmc-modules-root.js.map +7 -0
  119. package/dist/theme.d.ts +4 -0
  120. package/dist/theme.d.ts.map +1 -1
  121. package/dist/theme.js +134 -48
  122. package/dist/theme.js.map +7 -1
  123. package/dist/wizard.d.ts.map +1 -1
  124. package/dist/wizard.js +363 -438
  125. package/dist/wizard.js.map +7 -1
  126. package/dist/world-packs.d.ts +22 -0
  127. package/dist/world-packs.d.ts.map +1 -0
  128. package/dist/world-packs.js +872 -0
  129. package/dist/world-packs.js.map +7 -0
  130. package/package.json +10 -10
  131. package/dist/dispatcher.d.ts +0 -13
  132. package/dist/dispatcher.d.ts.map +0 -1
  133. package/dist/dispatcher.js +0 -23
  134. package/dist/dispatcher.js.map +0 -1
  135. package/dist/terminal.d.ts +0 -3
  136. package/dist/terminal.d.ts.map +0 -1
  137. package/dist/terminal.js +0 -178
  138. package/dist/terminal.js.map +0 -1
@@ -0,0 +1,567 @@
1
+ import { confirm, isCancel } from "@clack/prompts";
2
+ import {
3
+ discoverPackRoots,
4
+ enableInstalledPack,
5
+ ensureVersionGreaterThan,
6
+ extractArchiveToTemp,
7
+ findInstalledPackById,
8
+ installPackDirectory,
9
+ listInstalledWorldPacks,
10
+ readPackDependencyUuids,
11
+ readPackManifestInfo,
12
+ worldPackParentDir
13
+ } from "@sfmc-bds/bds-tools/world-packs";
14
+ import fs from "node:fs";
15
+ import os from "node:os";
16
+ import path from "node:path";
17
+ import { t } from "../i18n/index.js";
18
+ import { pushLog } from "../logs.js";
19
+ import { resolveBdsContext } from "../pack-lifecycle.js";
20
+ import { c } from "../theme.js";
21
+ import { getBinding, listBindings, packSourcesPath, setBinding } from "./bindings.js";
22
+ import {
23
+ ensurePackUpdateConfigFile,
24
+ getPackMatchConfig,
25
+ loadPackUpdateConfig,
26
+ packUpdateConfigPath
27
+ } from "./config.js";
28
+ import {
29
+ createPackSourceProvider,
30
+ providerShortLabel,
31
+ resolveConfiguredPackProvider
32
+ } from "./providers/index.js";
33
+ import {
34
+ decideVersionPolicy,
35
+ buildSearchQueries,
36
+ buildSearchQueriesFromSources,
37
+ packSourceScore
38
+ } from "./version-policy.js";
39
+ function logPack(text, level = "info") {
40
+ pushLog(text, "pack", level);
41
+ }
42
+ function fmtVer(v) {
43
+ return v.join(".");
44
+ }
45
+ function bindingEnabledLabel(enabled) {
46
+ return enabled ? t("packs.list.on").trim() : t("packs.list.off").trim();
47
+ }
48
+ function needKeyText() {
49
+ return t("packUpdate.needKey", { path: packUpdateConfigPath() });
50
+ }
51
+ function bindOkParams(opts) {
52
+ return {
53
+ uuid: opts.uuid,
54
+ provider: providerShortLabel(opts.provider),
55
+ slug: opts.slug,
56
+ enabled: bindingEnabledLabel(opts.enabled),
57
+ path: packSourcesPath()
58
+ };
59
+ }
60
+ function touchBinding(bpUuid, binding, patch) {
61
+ if (patch) Object.assign(binding, patch);
62
+ setBinding(bpUuid, binding);
63
+ }
64
+ function isFileIdApplied(binding, fileId) {
65
+ return binding.lastAppliedFileId != null && binding.lastAppliedFileId === fileId;
66
+ }
67
+ async function searchAndRankHits(provider, queries, stripFolderTags) {
68
+ const byId = /* @__PURE__ */ new Map();
69
+ for (const q of queries) {
70
+ const hits = await provider.search(q);
71
+ for (const h of hits) byId.set(h.projectId, h);
72
+ }
73
+ return [...byId.values()].map((h) => ({
74
+ hit: h,
75
+ score: Math.max(...queries.map((q) => packSourceScore(q, h, stripFolderTags)))
76
+ })).sort((a, b) => b.score - a.score);
77
+ }
78
+ function makeBindingFromHit(hit, pairedResourceUuid, opts) {
79
+ const prev = opts?.prev;
80
+ return {
81
+ /* 重绑保留原 enabled;新建走配置契约 defaultBindingEnabled(LSP) */
82
+ enabled: prev?.enabled ?? opts?.defaultEnabled ?? false,
83
+ provider: hit.provider,
84
+ projectId: hit.projectId,
85
+ slug: hit.slug,
86
+ websiteUrl: hit.websiteUrl,
87
+ pairedResourceUuid,
88
+ lastFileId: prev?.lastFileId ?? null,
89
+ lastCheckedAt: null,
90
+ lastAppliedFileId: prev?.lastAppliedFileId ?? null
91
+ };
92
+ }
93
+ function pairedRpUuidFromBpDir(bpDir) {
94
+ const deps = readPackDependencyUuids(bpDir);
95
+ return deps[0] ?? null;
96
+ }
97
+ async function probeSourceAfterInstall(opts) {
98
+ const cfg = loadPackUpdateConfig();
99
+ if (!cfg.enabled || !cfg.probeSourceAfterInstall) return;
100
+ if (opts.info.kind !== "behavior") return;
101
+ ensurePackUpdateConfigFile();
102
+ const provider = resolveConfiguredPackProvider(cfg);
103
+ if (!provider) {
104
+ logPack(needKeyText(), "warn");
105
+ return;
106
+ }
107
+ const match = getPackMatchConfig(cfg);
108
+ const folderName = opts.folderName && String(opts.folderName).trim() || (opts.packDir ? path.basename(opts.packDir) : "");
109
+ const plan = buildSearchQueriesFromSources(
110
+ [
111
+ { id: "header", raw: opts.info.name },
112
+ { id: "folder", raw: folderName }
113
+ ],
114
+ match.stripFolderTags
115
+ );
116
+ const queries = plan.queries;
117
+ if (queries.length === 0) {
118
+ logPack(t("packUpdate.probeNoName"), "warn");
119
+ return;
120
+ }
121
+ logPack(
122
+ t("packUpdate.probeQueries", {
123
+ header: opts.info.name || "-",
124
+ folder: folderName || "-",
125
+ queries: queries.join(" | ")
126
+ }),
127
+ "info"
128
+ );
129
+ let scored;
130
+ try {
131
+ scored = await searchAndRankHits(provider, queries, match.stripFolderTags);
132
+ } catch (e) {
133
+ logPack(t("packUpdate.probeFail", { message: e.message }), "warn");
134
+ return;
135
+ }
136
+ if (scored.length === 0) {
137
+ logPack(t("packUpdate.probeMiss", { name: queries.join(", ") }), "info");
138
+ return;
139
+ }
140
+ const primary = queries.find((q) => /[A-Za-z]/.test(q)) ?? queries[0];
141
+ const best = scored[0];
142
+ if (best.score < match.nameMinScore) {
143
+ logPack(
144
+ t("packUpdate.probeLowScore", {
145
+ name: primary,
146
+ hit: `${best.hit.name} (${best.hit.slug})`,
147
+ score: best.score.toFixed(2),
148
+ url: best.hit.websiteUrl
149
+ }),
150
+ "info"
151
+ );
152
+ return;
153
+ }
154
+ logPack(
155
+ t("packUpdate.probeHit", {
156
+ name: `${opts.info.name} / ${folderName || "-"}`,
157
+ hit: `${best.hit.name} [${best.hit.slug}]`,
158
+ url: best.hit.websiteUrl,
159
+ score: best.score.toFixed(2)
160
+ }),
161
+ "success"
162
+ );
163
+ logPack(t("packUpdate.editHint", { path: packSourcesPath() }), "info");
164
+ const interactive = opts.interactive ?? !!process.stdin.isTTY;
165
+ let accept = false;
166
+ if (interactive && cfg.askConfirmOnBind && process.stdin.isTTY) {
167
+ const ans = await confirm({
168
+ message: t("packUpdate.confirmBind", { hit: best.hit.name }),
169
+ initialValue: true
170
+ });
171
+ if (isCancel(ans)) return;
172
+ accept = !!ans;
173
+ } else {
174
+ accept = true;
175
+ logPack(
176
+ t("packUpdate.probeAutoBind", {
177
+ provider: providerShortLabel(best.hit.provider),
178
+ slug: best.hit.slug,
179
+ path: packSourcesPath()
180
+ }),
181
+ "info"
182
+ );
183
+ }
184
+ if (!accept) {
185
+ logPack(t("packUpdate.bindSkipped"), "info");
186
+ return;
187
+ }
188
+ const paired = (opts.packDir ? pairedRpUuidFromBpDir(opts.packDir) : null) ?? null;
189
+ const binding = makeBindingFromHit(best.hit, paired, { defaultEnabled: cfg.defaultBindingEnabled });
190
+ setBinding(opts.info.uuid, binding);
191
+ logPack(
192
+ t(
193
+ "packUpdate.bindOk",
194
+ bindOkParams({
195
+ uuid: opts.info.uuid,
196
+ provider: best.hit.provider,
197
+ slug: best.hit.slug,
198
+ enabled: binding.enabled
199
+ })
200
+ ),
201
+ "success"
202
+ );
203
+ }
204
+ async function searchRemote(query) {
205
+ const cfg = loadPackUpdateConfig();
206
+ const provider = resolveConfiguredPackProvider(cfg);
207
+ if (!provider) {
208
+ return c.yellow(needKeyText());
209
+ }
210
+ const match = getPackMatchConfig(cfg);
211
+ const queries = buildSearchQueries(query, match.stripFolderTags);
212
+ const ranked = await searchAndRankHits(provider, queries, match.stripFolderTags);
213
+ if (ranked.length === 0) return c.dim(t("packUpdate.searchEmpty", { query }));
214
+ return ranked.map(
215
+ ({ 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)}`)}
216
+ ${h.websiteUrl}`
217
+ ).join("\n");
218
+ }
219
+ async function bindPackSource(packId, ref) {
220
+ const cfg = loadPackUpdateConfig();
221
+ const provider = resolveConfiguredPackProvider(cfg);
222
+ if (!provider) {
223
+ return c.yellow(needKeyText());
224
+ }
225
+ const { bdsRoot, levelName } = resolveBdsContext();
226
+ const packs = listInstalledWorldPacks(bdsRoot, levelName);
227
+ const pack = findInstalledPackById(packs, packId);
228
+ if (!pack) return c.red(t("packs.notFound", { id: packId }));
229
+ if (pack.kind !== "behavior") return c.red(t("packUpdate.bindBpOnly"));
230
+ const hit = await provider.resolveProject(ref);
231
+ if (!hit) return c.red(t("packUpdate.resolveFail", { ref }));
232
+ const paired = pairedRpUuidFromBpDir(pack.dir);
233
+ const binding = makeBindingFromHit(hit, paired, {
234
+ prev: getBinding(pack.uuid),
235
+ defaultEnabled: cfg.defaultBindingEnabled
236
+ });
237
+ setBinding(pack.uuid, binding);
238
+ return c.green(
239
+ t(
240
+ "packUpdate.bindOk",
241
+ bindOkParams({
242
+ uuid: pack.uuid,
243
+ provider: hit.provider,
244
+ slug: hit.slug,
245
+ enabled: binding.enabled
246
+ })
247
+ )
248
+ );
249
+ }
250
+ function formatSourcesList() {
251
+ ensurePackUpdateConfigFile();
252
+ const bindings = listBindings();
253
+ const lines = [
254
+ t("packUpdate.sourcesHeader", {
255
+ config: packUpdateConfigPath(),
256
+ sources: packSourcesPath()
257
+ })
258
+ ];
259
+ if (bindings.length === 0) {
260
+ lines.push(c.dim(t("packUpdate.sourcesEmpty")));
261
+ return lines.join("\n");
262
+ }
263
+ for (const { bpUuid, binding } of bindings) {
264
+ const label = bindingEnabledLabel(binding.enabled);
265
+ const en = binding.enabled ? c.green(label) : c.dim(label);
266
+ const tag = providerShortLabel(binding.provider);
267
+ lines.push(
268
+ ` [${en}] ${bpUuid} ${tag}:${binding.slug || binding.projectId} ${c.dim(binding.websiteUrl || "")}`
269
+ );
270
+ }
271
+ return lines.join("\n");
272
+ }
273
+ function withLocalBp(base, localBp) {
274
+ return localBp ? { ...base, localBp } : { ...base };
275
+ }
276
+ function baseCheckFields(bpUuid, name, localVer, binding, extras) {
277
+ return {
278
+ bpUuid,
279
+ name,
280
+ localVer,
281
+ remoteVer: null,
282
+ updateAvailable: false,
283
+ majorHigher: false,
284
+ shouldBumpRp: false,
285
+ fileId: null,
286
+ binding,
287
+ ...extras
288
+ };
289
+ }
290
+ async function prepareCheck(bpUuid, binding, cfg, packs, downloadArchive) {
291
+ const localBp = packs.find((p) => p.uuid.toLowerCase() === bpUuid.toLowerCase() && p.kind === "behavior");
292
+ const name = localBp?.name ?? bpUuid;
293
+ const localVer = localBp?.version ?? [0, 0, 0];
294
+ const provider = createPackSourceProvider(cfg, binding.provider);
295
+ touchBinding(bpUuid, binding, { lastCheckedAt: (/* @__PURE__ */ new Date()).toISOString() });
296
+ if (!binding.enabled) {
297
+ return withLocalBp(
298
+ baseCheckFields(bpUuid, name, localVer, binding, { message: t("packUpdate.bindingDisabled") }),
299
+ localBp
300
+ );
301
+ }
302
+ const file = await provider.getLatestFile(binding.projectId);
303
+ if (!file) {
304
+ return withLocalBp(
305
+ baseCheckFields(bpUuid, name, localVer, binding, { message: t("packUpdate.noRemoteFile") }),
306
+ localBp
307
+ );
308
+ }
309
+ if (isFileIdApplied(binding, file.fileId)) {
310
+ touchBinding(bpUuid, binding, { lastFileId: file.fileId });
311
+ return withLocalBp(
312
+ baseCheckFields(bpUuid, name, localVer, binding, {
313
+ fileId: file.fileId,
314
+ message: t("packUpdate.upToDate")
315
+ }),
316
+ localBp
317
+ );
318
+ }
319
+ if (!downloadArchive) {
320
+ return withLocalBp(
321
+ baseCheckFields(bpUuid, name, localVer, binding, {
322
+ updateAvailable: true,
323
+ fileId: file.fileId,
324
+ message: t("packUpdate.fileNewer", { file: file.fileName, id: String(file.fileId) })
325
+ }),
326
+ localBp
327
+ );
328
+ }
329
+ const stagingDir = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-pack-upd-"));
330
+ const archiveFile = path.join(stagingDir, file.fileName || "pack.zip");
331
+ await provider.download(file, archiveFile);
332
+ const tempDir = await extractArchiveToTemp(archiveFile);
333
+ const roots = discoverPackRoots(tempDir, { maxDepth: 3 });
334
+ const bpRoot = roots.find((r) => readPackManifestInfo(r)?.kind === "behavior");
335
+ const remoteBpInfo = bpRoot ? readPackManifestInfo(bpRoot) : null;
336
+ if (!remoteBpInfo) {
337
+ try {
338
+ fs.rmSync(stagingDir, { recursive: true, force: true });
339
+ fs.rmSync(tempDir, { recursive: true, force: true });
340
+ } catch {
341
+ }
342
+ return withLocalBp(
343
+ baseCheckFields(bpUuid, name, localVer, binding, {
344
+ fileId: file.fileId,
345
+ message: t("packUpdate.remoteNoBp")
346
+ }),
347
+ localBp
348
+ );
349
+ }
350
+ const decision = decideVersionPolicy(localVer, remoteBpInfo.version, cfg.versionPolicy, {
351
+ treatAsUpdate: true
352
+ });
353
+ touchBinding(bpUuid, binding, { lastFileId: file.fileId });
354
+ const message = decision.remoteNewer ? t("packUpdate.bpNewer", {
355
+ local: fmtVer(localVer),
356
+ remote: fmtVer(remoteBpInfo.version)
357
+ }) : t("packUpdate.needSync", {
358
+ local: fmtVer(localVer),
359
+ remote: fmtVer(remoteBpInfo.version),
360
+ id: String(file.fileId)
361
+ });
362
+ return withLocalBp(
363
+ {
364
+ bpUuid,
365
+ name,
366
+ localVer,
367
+ remoteVer: remoteBpInfo.version,
368
+ updateAvailable: true,
369
+ majorHigher: decision.majorHigher,
370
+ shouldBumpRp: decision.shouldBumpRp,
371
+ fileId: file.fileId,
372
+ message,
373
+ binding,
374
+ remoteBpInfo,
375
+ remoteRoots: roots,
376
+ tempDir,
377
+ stagingDir
378
+ },
379
+ localBp
380
+ );
381
+ }
382
+ function cleanupCheck(r) {
383
+ for (const d of [r.tempDir, r.stagingDir]) {
384
+ if (!d) continue;
385
+ try {
386
+ fs.rmSync(d, { recursive: true, force: true });
387
+ } catch {
388
+ }
389
+ }
390
+ }
391
+ async function tryInstallResourcePack(opts) {
392
+ for (const root of opts.rpRoots) {
393
+ const info = readPackManifestInfo(root);
394
+ if (!info || !opts.accept(info)) continue;
395
+ const rpDest = worldPackParentDir(opts.bdsRoot, opts.levelName, "resource");
396
+ const rpInstall = await installPackDirectory({
397
+ srcDir: root,
398
+ destParent: rpDest,
399
+ force: true,
400
+ ...opts.folderName ? { folderName: opts.folderName } : {}
401
+ });
402
+ if (rpInstall.ok && rpInstall.info && rpInstall.destDir) {
403
+ return { info: rpInstall.info, destDir: rpInstall.destDir };
404
+ }
405
+ }
406
+ return null;
407
+ }
408
+ async function applyUpdate(r, cfg) {
409
+ if (!r.updateAvailable || !r.remoteRoots || !r.remoteBpInfo) {
410
+ return { ok: true, message: r.message };
411
+ }
412
+ const { bdsRoot, levelName } = resolveBdsContext();
413
+ const packs = listInstalledWorldPacks(bdsRoot, levelName);
414
+ const oldRp = r.binding.pairedResourceUuid != null ? packs.find((p) => p.kind === "resource" && p.uuid.toLowerCase() === r.binding.pairedResourceUuid.toLowerCase()) : void 0;
415
+ const oldRpVer = oldRp?.version ?? [0, 0, 0];
416
+ const bpRoot = r.remoteRoots.find((x) => readPackManifestInfo(x)?.kind === "behavior");
417
+ const rpRoots = r.remoteRoots.filter((x) => readPackManifestInfo(x)?.kind === "resource");
418
+ if (!bpRoot) return { ok: false, message: t("packUpdate.remoteNoBp") };
419
+ const bpDest = worldPackParentDir(bdsRoot, levelName, "behavior");
420
+ const bpInstall = await installPackDirectory({
421
+ srcDir: bpRoot,
422
+ destParent: bpDest,
423
+ force: true,
424
+ ...r.localBp?.folderName ? { folderName: r.localBp.folderName } : {}
425
+ });
426
+ if (!bpInstall.ok || !bpInstall.info || !bpInstall.destDir) {
427
+ return { ok: false, message: t("packUpdate.installFail", { reason: bpInstall.reason ?? "?" }) };
428
+ }
429
+ await enableInstalledPack({ bdsRoot, levelName, info: bpInstall.info });
430
+ logPack(
431
+ t("packUpdate.installedBp", {
432
+ dir: bpInstall.destDir,
433
+ version: fmtVer(bpInstall.info.version)
434
+ }),
435
+ "success"
436
+ );
437
+ let rpInfo = null;
438
+ let rpDir = null;
439
+ const wantRp = r.binding.pairedResourceUuid?.toLowerCase();
440
+ const installed = await tryInstallResourcePack({
441
+ rpRoots,
442
+ bdsRoot,
443
+ levelName,
444
+ ...oldRp?.folderName ? { folderName: oldRp.folderName } : {},
445
+ accept: (info) => !wantRp || info.uuid.toLowerCase() === wantRp
446
+ });
447
+ if (installed) {
448
+ rpInfo = installed.info;
449
+ rpDir = installed.destDir;
450
+ }
451
+ if (!rpInfo && rpRoots.length > 0) {
452
+ const deps = readPackDependencyUuids(bpInstall.destDir);
453
+ const fallback = await tryInstallResourcePack({
454
+ rpRoots,
455
+ bdsRoot,
456
+ levelName,
457
+ accept: (info) => deps.length === 0 || deps.some((d) => d.toLowerCase() === info.uuid.toLowerCase())
458
+ });
459
+ if (fallback) {
460
+ rpInfo = fallback.info;
461
+ rpDir = fallback.destDir;
462
+ r.binding.pairedResourceUuid = fallback.info.uuid;
463
+ }
464
+ }
465
+ if (rpInfo && rpDir && r.shouldBumpRp) {
466
+ const next = ensureVersionGreaterThan(rpDir, oldRpVer, cfg.versionPolicy.rpBumpComponent);
467
+ rpInfo = { ...rpInfo, version: next };
468
+ }
469
+ if (rpInfo) {
470
+ await enableInstalledPack({ bdsRoot, levelName, info: rpInfo });
471
+ logPack(
472
+ t("packUpdate.installedRp", {
473
+ dir: rpDir ?? "-",
474
+ version: fmtVer(rpInfo.version)
475
+ }),
476
+ "success"
477
+ );
478
+ } else if (rpRoots.length > 0) {
479
+ logPack(t("packUpdate.rpInstallMiss"), "warn");
480
+ }
481
+ touchBinding(r.bpUuid, r.binding, {
482
+ lastAppliedFileId: r.fileId,
483
+ lastFileId: r.fileId,
484
+ lastCheckedAt: (/* @__PURE__ */ new Date()).toISOString()
485
+ });
486
+ return {
487
+ ok: true,
488
+ message: t("packUpdate.applied", {
489
+ name: r.name,
490
+ bp: fmtVer(bpInstall.info.version),
491
+ rp: rpInfo ? fmtVer(rpInfo.version) : "-"
492
+ })
493
+ };
494
+ }
495
+ async function checkPackUpdates(opts) {
496
+ const cfg = loadPackUpdateConfig();
497
+ if (!cfg.enabled) return c.dim(t("packUpdate.disabled"));
498
+ if (!resolveConfiguredPackProvider(cfg)) {
499
+ return c.yellow(needKeyText());
500
+ }
501
+ const { bdsRoot, levelName } = resolveBdsContext();
502
+ const packs = listInstalledWorldPacks(bdsRoot, levelName);
503
+ let targets = listBindings();
504
+ if (opts?.packId) {
505
+ const pack = findInstalledPackById(packs, opts.packId);
506
+ const uuid = pack?.uuid ?? opts.packId;
507
+ targets = targets.filter((x) => x.bpUuid.toLowerCase() === uuid.toLowerCase());
508
+ if (targets.length === 0) {
509
+ const b = getBinding(uuid);
510
+ if (b) targets = [{ bpUuid: uuid, binding: b }];
511
+ }
512
+ if (targets.length === 0) return c.red(t("packUpdate.noBinding", { id: opts.packId }));
513
+ }
514
+ if (targets.length === 0) return c.dim(t("packUpdate.sourcesEmpty"));
515
+ const lines = [];
516
+ for (const { bpUuid, binding } of targets) {
517
+ if (cfg.startup.skipDisabledBindings && !binding.enabled && !opts?.packId) continue;
518
+ let result = null;
519
+ try {
520
+ result = await prepareCheck(bpUuid, binding, cfg, packs, true);
521
+ if (opts?.apply && result.updateAvailable) {
522
+ const applied = await applyUpdate(result, cfg);
523
+ lines.push(applied.ok ? c.green(applied.message) : c.red(applied.message));
524
+ } else {
525
+ lines.push(
526
+ result.updateAvailable ? c.yellow(`${result.name}: ${result.message}`) : c.dim(`${result.name}: ${result.message}`)
527
+ );
528
+ }
529
+ } catch (e) {
530
+ lines.push(c.red(`${bpUuid}: ${e.message}`));
531
+ if (cfg.startup.failMode === "abort") break;
532
+ } finally {
533
+ if (result) cleanupCheck(result);
534
+ }
535
+ if (cfg.startup.delayMsBetweenPacks > 0) {
536
+ await new Promise((r) => setTimeout(r, cfg.startup.delayMsBetweenPacks));
537
+ }
538
+ }
539
+ return lines.join("\n") || c.dim(t("packUpdate.sourcesEmpty"));
540
+ }
541
+ async function runPackUpdatesOnBdsStart() {
542
+ const cfg = loadPackUpdateConfig();
543
+ if (!cfg.enabled || !cfg.checkOnBdsStart) return;
544
+ try {
545
+ const out = await checkPackUpdates({ apply: cfg.applyOnBdsStart });
546
+ if (out.trim()) logPack(out.replace(/\x1B\[[0-9;]*m/g, ""), "info");
547
+ } catch (e) {
548
+ logPack(t("packUpdate.startupFail", { message: e.message }), "warn");
549
+ }
550
+ }
551
+ function bindingLabelForUuid(uuid) {
552
+ const b = getBinding(uuid);
553
+ if (!b) return "src=-";
554
+ const tag = `${providerShortLabel(b.provider)}:${b.slug || b.projectId}`;
555
+ return b.enabled ? `src=${tag}` : `src=${tag}:off`;
556
+ }
557
+ export {
558
+ bindPackSource,
559
+ bindingLabelForUuid,
560
+ checkPackUpdates,
561
+ formatSourcesList,
562
+ pairedRpUuidFromBpDir,
563
+ probeSourceAfterInstall,
564
+ runPackUpdatesOnBdsStart,
565
+ searchRemote
566
+ };
567
+ //# 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 discoverPackRoots,\n enableInstalledPack,\n ensureVersionGreaterThan,\n extractArchiveToTemp,\n findInstalledPackById,\n installPackDirectory,\n listInstalledWorldPacks,\n readPackDependencyUuids,\n readPackManifestInfo,\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}\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 tempDir = await extractArchiveToTemp(archiveFile);\n const roots = discoverPackRoots(tempDir, { maxDepth: 3 });\n const bpRoot = roots.find((r) => readPackManifestInfo(r)?.kind === \"behavior\");\n const remoteBpInfo = bpRoot ? readPackManifestInfo(bpRoot) : null;\n if (!remoteBpInfo) {\n try {\n fs.rmSync(stagingDir, { recursive: true, force: true });\n fs.rmSync(tempDir, { 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 tempDir,\n stagingDir,\n },\n localBp\n );\n}\n\nfunction cleanupCheck(r: CheckResult): void {\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 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
+ }