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