@sfmc-bds/cli 0.2.5 → 0.3.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.
- package/dist/command-surface.d.ts.map +1 -1
- package/dist/command-surface.js +5 -1
- package/dist/command-surface.js.map +2 -2
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +20 -79
- package/dist/commands.js.map +2 -2
- package/dist/help-text.d.ts.map +1 -1
- package/dist/help-text.js +2 -0
- package/dist/help-text.js.map +2 -2
- package/dist/i18n/locales/en.d.ts +33 -0
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +33 -0
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.d.ts.map +1 -1
- package/dist/i18n/locales/zh-CN.js +33 -0
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/module-commands.d.ts.map +1 -1
- package/dist/module-commands.js +8 -0
- package/dist/module-commands.js.map +2 -2
- package/dist/module-update/index.d.ts +18 -0
- package/dist/module-update/index.d.ts.map +1 -0
- package/dist/module-update/index.js +223 -0
- package/dist/module-update/index.js.map +7 -0
- package/dist/repl.d.ts.map +1 -1
- package/dist/repl.js +11 -0
- package/dist/repl.js.map +2 -2
- package/dist/services.d.ts +29 -1
- package/dist/services.d.ts.map +1 -1
- package/dist/services.js +79 -1
- package/dist/services.js.map +2 -2
- package/dist/wizard.d.ts.map +1 -1
- package/dist/wizard.js +2 -0
- package/dist/wizard.js.map +2 -2
- package/package.json +1 -1
- package/scripts/module-install/fetch-module.mjs +164 -76
- package/scripts/module-install/lib/module-update-config.mjs +83 -0
- package/scripts/module-install/lib/module-update.mjs +507 -0
- package/scripts/module-install/lib/pins.mjs +436 -0
- package/scripts/module-install/lib/registry-cache.mjs +83 -0
- package/scripts/module-install/lib/semver.mjs +124 -0
- package/scripts/module-install/test/module-update.test.mjs +182 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { confirm, isCancel } from "@clack/prompts";
|
|
2
|
+
import { stdin } from "node:process";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
import { isCliTty } from "../command-surface.js";
|
|
6
|
+
import { t } from "../i18n/index.js";
|
|
7
|
+
import { pushLog } from "../logs.js";
|
|
8
|
+
import { ROOT, resolveFetchModule } from "../runtime.js";
|
|
9
|
+
import { c } from "../theme.js";
|
|
10
|
+
const REASON_KEYS = {
|
|
11
|
+
"auto-off": "mod.update.reason.autoOff",
|
|
12
|
+
"local-source": "mod.update.reason.localSource",
|
|
13
|
+
"registry-offline": "mod.update.reason.registryOffline",
|
|
14
|
+
"no-target": "mod.update.reason.noTarget",
|
|
15
|
+
"no-installed-version": "mod.update.reason.noInstalledVersion",
|
|
16
|
+
"up-to-date": "mod.update.reason.upToDate",
|
|
17
|
+
"installed-newer": "mod.update.reason.installedNewer",
|
|
18
|
+
major: "mod.update.reason.major",
|
|
19
|
+
sdk: "mod.update.reason.sdk",
|
|
20
|
+
"dependency-failed": "mod.update.reason.dependencyFailed",
|
|
21
|
+
"github-manual": "mod.update.reason.githubManual",
|
|
22
|
+
"missing-module": "mod.update.reason.missingModule",
|
|
23
|
+
"missing-dependency": "mod.update.reason.missingDependency",
|
|
24
|
+
"bad-version": "mod.update.reason.badVersion"
|
|
25
|
+
};
|
|
26
|
+
function fetchModuleUrl() {
|
|
27
|
+
const script = resolveFetchModule();
|
|
28
|
+
if (!script) return null;
|
|
29
|
+
return pathToFileURL(script);
|
|
30
|
+
}
|
|
31
|
+
function updateLibUrl() {
|
|
32
|
+
const script = resolveFetchModule();
|
|
33
|
+
if (!script) return null;
|
|
34
|
+
return pathToFileURL(path.join(path.dirname(script), "lib", "module-update.mjs"));
|
|
35
|
+
}
|
|
36
|
+
async function loadUpdateApi() {
|
|
37
|
+
const url = updateLibUrl();
|
|
38
|
+
if (!url) return null;
|
|
39
|
+
return await import(url.href);
|
|
40
|
+
}
|
|
41
|
+
async function loadFetchApi() {
|
|
42
|
+
const url = fetchModuleUrl();
|
|
43
|
+
if (!url) return null;
|
|
44
|
+
return await import(url.href);
|
|
45
|
+
}
|
|
46
|
+
async function ensureModuleUpdateConfigFile() {
|
|
47
|
+
try {
|
|
48
|
+
const api = await loadUpdateApi();
|
|
49
|
+
api?.ensureModuleUpdateConfigFile(ROOT);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
52
|
+
pushLog(message, "module", "warn");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function withCookedStdin(fn) {
|
|
56
|
+
const wasRaw = stdin.isRaw === true;
|
|
57
|
+
if (wasRaw) stdin.setRawMode(false);
|
|
58
|
+
try {
|
|
59
|
+
return await fn();
|
|
60
|
+
} finally {
|
|
61
|
+
if (wasRaw) stdin.setRawMode(true);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function reasonText(reason, detail) {
|
|
65
|
+
const key = REASON_KEYS[reason];
|
|
66
|
+
const label = key ? t(key) : reason;
|
|
67
|
+
return detail ? `${label} (${detail})` : label;
|
|
68
|
+
}
|
|
69
|
+
function versionText(value) {
|
|
70
|
+
return value || "?";
|
|
71
|
+
}
|
|
72
|
+
function formatPlan(plan, quiet, showAll, quietEmpty = false) {
|
|
73
|
+
if (plan.configSkipped === "disabled") return quietEmpty ? [] : [c.yellow(t("mod.update.disabled"))];
|
|
74
|
+
if (plan.configSkipped === "check-off") return quietEmpty ? [] : [c.dim(t("mod.update.checkOff"))];
|
|
75
|
+
const lines = [];
|
|
76
|
+
for (const item of plan.skipped) {
|
|
77
|
+
if (!showAll && quiet.has(item.reason)) continue;
|
|
78
|
+
lines.push(c.dim(` ${item.id} ${reasonText(item.reason, item.detail)}`));
|
|
79
|
+
}
|
|
80
|
+
for (const item of plan.upgrades) {
|
|
81
|
+
lines.push(
|
|
82
|
+
c.green(
|
|
83
|
+
` ${t("mod.update.upgrade", {
|
|
84
|
+
id: item.id,
|
|
85
|
+
from: versionText(item.fromVersion),
|
|
86
|
+
to: versionText(item.toVersion)
|
|
87
|
+
})}`
|
|
88
|
+
)
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
if (plan.upgrades.length === 0 && lines.length === 0 && !quietEmpty) lines.push(c.dim(t("mod.update.none")));
|
|
92
|
+
return lines;
|
|
93
|
+
}
|
|
94
|
+
function formatApply(result, hintReload) {
|
|
95
|
+
const lines = [];
|
|
96
|
+
for (const item of result.applied) {
|
|
97
|
+
lines.push(
|
|
98
|
+
c.green(
|
|
99
|
+
t("mod.update.applied", {
|
|
100
|
+
id: item.id,
|
|
101
|
+
from: versionText(item.fromVersion),
|
|
102
|
+
to: versionText(item.toVersion)
|
|
103
|
+
})
|
|
104
|
+
)
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
for (const item of result.skipped) {
|
|
108
|
+
lines.push(c.yellow(` ${item.id} ${reasonText(item.reason, item.detail)}`));
|
|
109
|
+
}
|
|
110
|
+
for (const item of result.failed) {
|
|
111
|
+
lines.push(c.red(t("mod.update.failed", { id: item.id, message: item.message })));
|
|
112
|
+
}
|
|
113
|
+
if (hintReload && result.applied.length > 0) lines.push(c.yellow(t("mod.update.reloadHint")));
|
|
114
|
+
return lines;
|
|
115
|
+
}
|
|
116
|
+
function parseUpdateFlags(args) {
|
|
117
|
+
const flags = { check: false, yes: false, allowMajor: false, ids: [] };
|
|
118
|
+
for (const arg of args) {
|
|
119
|
+
if (arg === "--check") flags.check = true;
|
|
120
|
+
else if (arg === "--yes") flags.yes = true;
|
|
121
|
+
else if (arg === "--allow-major") flags.allowMajor = true;
|
|
122
|
+
else if (arg.startsWith("--")) return null;
|
|
123
|
+
else flags.ids.push(arg);
|
|
124
|
+
}
|
|
125
|
+
return flags;
|
|
126
|
+
}
|
|
127
|
+
async function cmdModuleUpdate(args) {
|
|
128
|
+
const flags = parseUpdateFlags(args);
|
|
129
|
+
if (!flags) return c.yellow(t("mod.update.usage"));
|
|
130
|
+
const api = await loadUpdateApi();
|
|
131
|
+
if (!api) return c.red(t("mod.fetchMissing"));
|
|
132
|
+
const plan = await api.planModuleUpdates({
|
|
133
|
+
root: ROOT,
|
|
134
|
+
allowMajor: flags.allowMajor,
|
|
135
|
+
ids: flags.ids
|
|
136
|
+
});
|
|
137
|
+
const lines = formatPlan(plan, api.QUIET_SKIP_REASONS, flags.check);
|
|
138
|
+
if (flags.check || plan.configSkipped || plan.upgrades.length === 0) return lines.join("\n");
|
|
139
|
+
if (!flags.yes) {
|
|
140
|
+
if (!isCliTty()) return [...lines, c.yellow(t("mod.update.needYes"))].join("\n");
|
|
141
|
+
const ans = await withCookedStdin(
|
|
142
|
+
() => confirm({
|
|
143
|
+
message: t("mod.update.confirm", { count: plan.upgrades.length }),
|
|
144
|
+
initialValue: true
|
|
145
|
+
})
|
|
146
|
+
);
|
|
147
|
+
if (isCancel(ans) || !ans) return [...lines, c.dim(t("mod.update.cancelled"))].join("\n");
|
|
148
|
+
}
|
|
149
|
+
const fetchApi = await loadFetchApi();
|
|
150
|
+
if (!fetchApi) return c.red(t("mod.fetchMissing"));
|
|
151
|
+
const result = await api.applyModuleUpgrades(plan.upgrades, {
|
|
152
|
+
root: ROOT,
|
|
153
|
+
failMode: plan.failMode,
|
|
154
|
+
install: fetchApi.installPreservingLock,
|
|
155
|
+
resync: api.resyncInstalledCatalog
|
|
156
|
+
});
|
|
157
|
+
return [...lines, ...formatApply(result, true)].join("\n");
|
|
158
|
+
}
|
|
159
|
+
async function runModuleUpdatesOnBdsStart() {
|
|
160
|
+
try {
|
|
161
|
+
const api = await loadUpdateApi();
|
|
162
|
+
if (!api) return;
|
|
163
|
+
const plan = await api.planModuleUpdates({ root: ROOT, startup: true, ids: [] });
|
|
164
|
+
for (const line of formatPlan(plan, api.QUIET_SKIP_REASONS, false, true)) {
|
|
165
|
+
pushLog(stripColor(line), "module", "info");
|
|
166
|
+
}
|
|
167
|
+
if (!plan.applyOnStart || plan.upgrades.length === 0) return;
|
|
168
|
+
const fetchApi = await loadFetchApi();
|
|
169
|
+
if (!fetchApi) return;
|
|
170
|
+
const result = await api.applyModuleUpgrades(plan.upgrades, {
|
|
171
|
+
root: ROOT,
|
|
172
|
+
failMode: plan.failMode,
|
|
173
|
+
install: fetchApi.installPreservingLock,
|
|
174
|
+
resync: api.resyncInstalledCatalog
|
|
175
|
+
});
|
|
176
|
+
const level = result.failed.length > 0 ? "warn" : "info";
|
|
177
|
+
for (const line of formatApply(result, false)) {
|
|
178
|
+
pushLog(stripColor(line), "module", level);
|
|
179
|
+
}
|
|
180
|
+
} catch (error) {
|
|
181
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
182
|
+
pushLog(message, "module", "warn");
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function stripColor(text) {
|
|
186
|
+
return text.replace(/\x1b\[[0-9;]*m/g, "");
|
|
187
|
+
}
|
|
188
|
+
async function cmdModulePin(args) {
|
|
189
|
+
let id = "";
|
|
190
|
+
let auto = null;
|
|
191
|
+
for (let i = 0; i < args.length; i++) {
|
|
192
|
+
const arg = args[i];
|
|
193
|
+
if (arg === "--auto") {
|
|
194
|
+
const value = args[++i];
|
|
195
|
+
if (value === "on") auto = true;
|
|
196
|
+
else if (value === "off") auto = false;
|
|
197
|
+
else return c.yellow(t("mod.pin.usage"));
|
|
198
|
+
} else if (arg?.startsWith("--auto=")) {
|
|
199
|
+
const value = arg.slice("--auto=".length);
|
|
200
|
+
if (value === "on") auto = true;
|
|
201
|
+
else if (value === "off") auto = false;
|
|
202
|
+
else return c.yellow(t("mod.pin.usage"));
|
|
203
|
+
} else if (arg?.startsWith("--")) {
|
|
204
|
+
return c.yellow(t("mod.pin.usage"));
|
|
205
|
+
} else if (arg) {
|
|
206
|
+
id = arg;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (!id || auto === null) return c.yellow(t("mod.pin.usage"));
|
|
210
|
+
const api = await loadUpdateApi();
|
|
211
|
+
if (!api) return c.red(t("mod.fetchMissing"));
|
|
212
|
+
const result = api.setModulePinAuto(ROOT, id, auto);
|
|
213
|
+
if (!result.ok && result.code === "locked") return c.yellow(t("mod.pin.locked", { id: result.id || id }));
|
|
214
|
+
if (!result.ok) return c.yellow(t("mod.pin.missing", { id }));
|
|
215
|
+
return c.green(t("mod.pin.ok", { id: result.id, state: t(result.auto ? "mod.pin.on" : "mod.pin.off") }));
|
|
216
|
+
}
|
|
217
|
+
export {
|
|
218
|
+
cmdModulePin,
|
|
219
|
+
cmdModuleUpdate,
|
|
220
|
+
ensureModuleUpdateConfigFile,
|
|
221
|
+
runModuleUpdatesOnBdsStart
|
|
222
|
+
};
|
|
223
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/module-update/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * \u6A21\u5757\u81EA\u52A8\u66F4\u65B0\u7684 CLI \u5165\u53E3\u3002\n * \u8BA1\u5212\u4E0E\u6362\u5305\u5728 scripts/module-install/lib/module-update.mjs\uFF1B\n * \u8FD9\u91CC\u8D1F\u8D23\u786E\u8BA4\u3001\u6587\u6848\uFF0C\u4EE5\u53CA\u5F00\u670D\u524D\u8C03\u7528\u3002\n */\nimport { confirm, isCancel } from \"@clack/prompts\";\nimport { stdin } from \"node:process\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { isCliTty } from \"../command-surface.js\";\nimport { t, type MessageKey } from \"../i18n/index.js\";\nimport { pushLog } from \"../logs.js\";\nimport { ROOT, resolveFetchModule } from \"../runtime.js\";\nimport { c } from \"../theme.js\";\n\n/** \u4E0E module-update.mjs \u7684\u5347\u7EA7\u5019\u9009\u4E00\u81F4\u3002 */\ninterface ModuleUpgrade {\n id: string;\n fromVersion: string | null;\n toVersion: string | null;\n spec: string;\n requires: string[];\n}\n\n/** \u4E0E module-update.mjs \u7684\u8DF3\u8FC7\u8BB0\u5F55\u4E00\u81F4\u3002 */\ninterface ModuleSkip {\n id: string;\n reason: string;\n fromVersion: string | null;\n toVersion: string | null;\n detail: string;\n}\n\n/** planModuleUpdates \u7684\u8FD4\u56DE\u3002 */\ninterface ModuleUpdatePlan {\n configSkipped: \"disabled\" | \"check-off\" | null;\n applyOnStart: boolean;\n failMode: \"continue\" | \"abort\";\n upgrades: ModuleUpgrade[];\n skipped: ModuleSkip[];\n}\n\n/** applyModuleUpgrades \u7684\u8FD4\u56DE\u3002 */\ninterface ModuleUpdateApplyResult {\n applied: ModuleUpgrade[];\n skipped: ModuleSkip[];\n failed: Array<{ id: string; message: string }>;\n}\n\n/** \u5B89\u88C5\u5668\u5BFC\u51FA\u7684\u4FDD\u7559\u542F\u505C\u5B89\u88C5\u53E3\u3002 */\ninterface FetchModuleApi {\n installPreservingLock: (id: string, spec: string) => Promise<void>;\n}\n\n/** module-update.mjs \u5BFC\u51FA\u9762\u3002\u5F53\u524D\u547D\u4EE4\u4E0E\u5F00\u670D\u94A9\u5B50\u90FD\u53EA\u4F9D\u8D56\u8FD9\u4E00\u5C42\u3002 */\ninterface ModuleUpdateApi {\n ensureModuleUpdateConfigFile: (root?: string) => string;\n planModuleUpdates: (options: {\n root?: string;\n startup?: boolean;\n allowMajor?: boolean;\n ids?: string[];\n }) => Promise<ModuleUpdatePlan>;\n applyModuleUpgrades: (\n upgrades: ModuleUpgrade[],\n deps: {\n root: string;\n failMode: \"continue\" | \"abort\";\n install: (id: string, spec: string) => Promise<void>;\n resync?: (id: string) => void;\n }\n ) => Promise<ModuleUpdateApplyResult>;\n resyncInstalledCatalog: (folder: string) => void;\n setModulePinAuto: (\n root: string,\n id: string,\n auto: boolean\n ) => { ok: true; code: \"ok\"; id: string; auto: boolean } | { ok: false; code: \"missing\" | \"locked\"; id?: string };\n QUIET_SKIP_REASONS: Set<string>;\n}\n\nconst REASON_KEYS: Record<string, MessageKey> = {\n \"auto-off\": \"mod.update.reason.autoOff\",\n \"local-source\": \"mod.update.reason.localSource\",\n \"registry-offline\": \"mod.update.reason.registryOffline\",\n \"no-target\": \"mod.update.reason.noTarget\",\n \"no-installed-version\": \"mod.update.reason.noInstalledVersion\",\n \"up-to-date\": \"mod.update.reason.upToDate\",\n \"installed-newer\": \"mod.update.reason.installedNewer\",\n major: \"mod.update.reason.major\",\n sdk: \"mod.update.reason.sdk\",\n \"dependency-failed\": \"mod.update.reason.dependencyFailed\",\n \"github-manual\": \"mod.update.reason.githubManual\",\n \"missing-module\": \"mod.update.reason.missingModule\",\n \"missing-dependency\": \"mod.update.reason.missingDependency\",\n \"bad-version\": \"mod.update.reason.badVersion\",\n};\n\n/** \u5B9A\u4F4D fetch-module.mjs\u3002\u627E\u4E0D\u5230\u65F6\u8FD4\u56DE null\uFF0C\u8C03\u7528\u65B9\u7ED9\u51FA\u5B89\u88C5\u63D0\u793A\u3002 */\nfunction fetchModuleUrl(): URL | null {\n const script = resolveFetchModule();\n if (!script) return null;\n return pathToFileURL(script);\n}\n\n/** \u4E0E fetch-module \u540C\u76EE\u5F55\u7684\u66F4\u65B0\u5E93\u3002\u4F7F\u7528\u6587\u4EF6\u7CFB\u7EDF\u8DEF\u5F84\u62FC\u63A5\uFF0C\u907F\u514D Windows \u4E0B file URL \u7684 pathname \u88AB dirname \u62C6\u574F\u3002 */\nfunction updateLibUrl(): URL | null {\n const script = resolveFetchModule();\n if (!script) return null;\n return pathToFileURL(path.join(path.dirname(script), \"lib\", \"module-update.mjs\"));\n}\n\nasync function loadUpdateApi(): Promise<ModuleUpdateApi | null> {\n const url = updateLibUrl();\n if (!url) return null;\n return (await import(url.href)) as ModuleUpdateApi;\n}\n\nasync function loadFetchApi(): Promise<FetchModuleApi | null> {\n const url = fetchModuleUrl();\n if (!url) return null;\n return (await import(url.href)) as FetchModuleApi;\n}\n\n/** \u7F3A\u6587\u4EF6\u65F6\u5199\u5165\u9ED8\u8BA4\u7B56\u7565\u3002\u5931\u8D25\u4E0D\u5F71\u54CD\u5176\u4ED6\u547D\u4EE4\u3002 */\nexport async function ensureModuleUpdateConfigFile(): Promise<void> {\n try {\n const api = await loadUpdateApi();\n api?.ensureModuleUpdateConfigFile(ROOT);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n pushLog(message, \"module\", \"warn\");\n }\n}\n\n/**\n * REPL \u5904\u4E8E raw \u6A21\u5F0F\u65F6\uFF0C\u5148\u6682\u65F6\u5173\u6389\uFF0C\u8BA9\u786E\u8BA4\u63D0\u793A\u80FD\u8BFB\u5230\u6574\u884C\u3002\n */\nasync function withCookedStdin<T>(fn: () => Promise<T>): Promise<T> {\n const wasRaw = stdin.isRaw === true;\n if (wasRaw) stdin.setRawMode(false);\n try {\n return await fn();\n } finally {\n if (wasRaw) stdin.setRawMode(true);\n }\n}\n\n/** \u8DF3\u8FC7\u539F\u56E0\u7684\u53EF\u8BFB\u6587\u6848\u3002\u672A\u77E5\u539F\u56E0\u4FDD\u6301\u539F\u6837\u3002 */\nfunction reasonText(reason: string, detail: string): string {\n const key = REASON_KEYS[reason];\n const label = key ? t(key) : reason;\n return detail ? `${label} (${detail})` : label;\n}\n\nfunction versionText(value: string | null): string {\n return value || \"?\";\n}\n\n/**\n * \u628A\u8BA1\u5212\u683C\u5F0F\u5316\u6210\u591A\u884C\u3002startup \u6216\u975E --check \u65F6\u9690\u85CF\u201C\u5DF2\u5173\u95ED / \u5DF2\u6700\u65B0\u201D\u8FD9\u7C7B\u5B89\u9759\u8DF3\u8FC7\u3002\n */\nfunction formatPlan(\n plan: ModuleUpdatePlan,\n quiet: Set<string>,\n showAll: boolean,\n quietEmpty = false\n): string[] {\n if (plan.configSkipped === \"disabled\") return quietEmpty ? [] : [c.yellow(t(\"mod.update.disabled\"))];\n if (plan.configSkipped === \"check-off\") return quietEmpty ? [] : [c.dim(t(\"mod.update.checkOff\"))];\n const lines: string[] = [];\n for (const item of plan.skipped) {\n if (!showAll && quiet.has(item.reason)) continue;\n lines.push(c.dim(` ${item.id} ${reasonText(item.reason, item.detail)}`));\n }\n for (const item of plan.upgrades) {\n lines.push(\n c.green(\n ` ${t(\"mod.update.upgrade\", {\n id: item.id,\n from: versionText(item.fromVersion),\n to: versionText(item.toVersion),\n })}`\n )\n );\n }\n if (plan.upgrades.length === 0 && lines.length === 0 && !quietEmpty) lines.push(c.dim(t(\"mod.update.none\")));\n return lines;\n}\n\nfunction formatApply(result: ModuleUpdateApplyResult, hintReload: boolean): string[] {\n const lines: string[] = [];\n for (const item of result.applied) {\n lines.push(\n c.green(\n t(\"mod.update.applied\", {\n id: item.id,\n from: versionText(item.fromVersion),\n to: versionText(item.toVersion),\n })\n )\n );\n }\n for (const item of result.skipped) {\n lines.push(c.yellow(` ${item.id} ${reasonText(item.reason, item.detail)}`));\n }\n for (const item of result.failed) {\n lines.push(c.red(t(\"mod.update.failed\", { id: item.id, message: item.message })));\n }\n if (hintReload && result.applied.length > 0) lines.push(c.yellow(t(\"mod.update.reloadHint\")));\n return lines;\n}\n\ninterface UpdateFlags {\n check: boolean;\n yes: boolean;\n allowMajor: boolean;\n ids: string[];\n}\n\n/** \u89E3\u6790 mod update \u7684\u65D7\u6807\u3002\u672A\u77E5\u65D7\u6807\u8FD4\u56DE null\u3002 */\nfunction parseUpdateFlags(args: string[]): UpdateFlags | null {\n const flags: UpdateFlags = { check: false, yes: false, allowMajor: false, ids: [] };\n for (const arg of args) {\n if (arg === \"--check\") flags.check = true;\n else if (arg === \"--yes\") flags.yes = true;\n else if (arg === \"--allow-major\") flags.allowMajor = true;\n else if (arg.startsWith(\"--\")) return null;\n else flags.ids.push(arg);\n }\n return flags;\n}\n\n/**\n * mod update\uFF1A\u5148\u51FA\u8BA1\u5212\uFF0C\u4EA4\u4E92\u786E\u8BA4\u540E\u518D\u6362\u5305\u3002\n * --check \u53EA\u62A5\u544A\u3002\u5F00\u670D\u8DEF\u5F84\u8D70 runModuleUpdatesOnBdsStart\uFF0C\u4E0D\u7ECF\u8FC7\u786E\u8BA4\u3002\n */\nexport async function cmdModuleUpdate(args: string[]): Promise<string> {\n const flags = parseUpdateFlags(args);\n if (!flags) return c.yellow(t(\"mod.update.usage\"));\n const api = await loadUpdateApi();\n if (!api) return c.red(t(\"mod.fetchMissing\"));\n const plan = await api.planModuleUpdates({\n root: ROOT,\n allowMajor: flags.allowMajor,\n ids: flags.ids,\n });\n const lines = formatPlan(plan, api.QUIET_SKIP_REASONS, flags.check);\n if (flags.check || plan.configSkipped || plan.upgrades.length === 0) return lines.join(\"\\n\");\n if (!flags.yes) {\n if (!isCliTty()) return [...lines, c.yellow(t(\"mod.update.needYes\"))].join(\"\\n\");\n const ans = await withCookedStdin(() =>\n confirm({\n message: t(\"mod.update.confirm\", { count: plan.upgrades.length }),\n initialValue: true,\n })\n );\n if (isCancel(ans) || !ans) return [...lines, c.dim(t(\"mod.update.cancelled\"))].join(\"\\n\");\n }\n const fetchApi = await loadFetchApi();\n if (!fetchApi) return c.red(t(\"mod.fetchMissing\"));\n const result = await api.applyModuleUpgrades(plan.upgrades, {\n root: ROOT,\n failMode: plan.failMode,\n install: fetchApi.installPreservingLock,\n resync: api.resyncInstalledCatalog,\n });\n return [...lines, ...formatApply(result, true)].join(\"\\n\");\n}\n\n/**\n * BDS beforeStart\uFF1A\u6309\u914D\u7F6E\u68C0\u67E5\uFF0C\u5E76\u5728 applyOnBdsStart \u65F6\u76F4\u63A5\u6362\u5305\u3002\n * \u5931\u8D25\u53EA\u8BB0\u65E5\u5FD7\uFF0C\u4E0D\u963B\u6B62\u968F\u540E\u7684\u884C\u4E3A\u5305\u88C5\u914D\u3002\n */\nexport async function runModuleUpdatesOnBdsStart(): Promise<void> {\n try {\n const api = await loadUpdateApi();\n if (!api) return;\n const plan = await api.planModuleUpdates({ root: ROOT, startup: true, ids: [] });\n for (const line of formatPlan(plan, api.QUIET_SKIP_REASONS, false, true)) {\n pushLog(stripColor(line), \"module\", \"info\");\n }\n if (!plan.applyOnStart || plan.upgrades.length === 0) return;\n const fetchApi = await loadFetchApi();\n if (!fetchApi) return;\n const result = await api.applyModuleUpgrades(plan.upgrades, {\n root: ROOT,\n failMode: plan.failMode,\n install: fetchApi.installPreservingLock,\n resync: api.resyncInstalledCatalog,\n });\n const level = result.failed.length > 0 ? \"warn\" : \"info\";\n for (const line of formatApply(result, false)) {\n pushLog(stripColor(line), \"module\", level);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n pushLog(message, \"module\", \"warn\");\n }\n}\n\n/** \u53BB\u6389\u4E3B\u9898\u8272\uFF0C\u907F\u514D\u65E5\u5FD7\u6587\u4EF6\u91CC\u7559\u4E0B ANSI\u3002 */\nfunction stripColor(text: string): string {\n return text.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n}\n\n/**\n * mod pin <id> --auto on|off\n * \u94FE\u63A5\u548C\u672C\u5730\u76EE\u5F55\u4E0D\u80FD\u6253\u5F00\u81EA\u52A8\u66F4\u65B0\u3002\n */\nexport async function cmdModulePin(args: string[]): Promise<string> {\n let id = \"\";\n let auto: boolean | null = null;\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === \"--auto\") {\n const value = args[++i];\n if (value === \"on\") auto = true;\n else if (value === \"off\") auto = false;\n else return c.yellow(t(\"mod.pin.usage\"));\n } else if (arg?.startsWith(\"--auto=\")) {\n const value = arg.slice(\"--auto=\".length);\n if (value === \"on\") auto = true;\n else if (value === \"off\") auto = false;\n else return c.yellow(t(\"mod.pin.usage\"));\n } else if (arg?.startsWith(\"--\")) {\n return c.yellow(t(\"mod.pin.usage\"));\n } else if (arg) {\n id = arg;\n }\n }\n if (!id || auto === null) return c.yellow(t(\"mod.pin.usage\"));\n const api = await loadUpdateApi();\n if (!api) return c.red(t(\"mod.fetchMissing\"));\n const result = api.setModulePinAuto(ROOT, id, auto);\n if (!result.ok && result.code === \"locked\") return c.yellow(t(\"mod.pin.locked\", { id: result.id || id }));\n if (!result.ok) return c.yellow(t(\"mod.pin.missing\", { id }));\n return c.green(t(\"mod.pin.ok\", { id: result.id, state: t(result.auto ? \"mod.pin.on\" : \"mod.pin.off\") }));\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/repl.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repl.d.ts","sourceRoot":"","sources":["../src/repl.ts"],"names":[],"mappings":"AAcA,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AA+M9B,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAiD1D;AAcD,wBAAgB,OAAO,CAAC,IAAI,GAAE,WAAoB,GAAG,MAAM,CAE1D;
|
|
1
|
+
{"version":3,"file":"repl.d.ts","sourceRoot":"","sources":["../src/repl.ts"],"names":[],"mappings":"AAcA,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AA+M9B,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAiD1D;AAcD,wBAAgB,OAAO,CAAC,IAAI,GAAE,WAAoB,GAAG,MAAM,CAE1D;AAkgBD,mCAAmC;AACnC,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAG9D,CAAC;AAmBJ,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAkS/C"}
|
package/dist/repl.js
CHANGED
|
@@ -303,6 +303,17 @@ function getCompletions(parsed) {
|
|
|
303
303
|
if (argIndex >= 1 && verb === "install") {
|
|
304
304
|
return ["--from", "--sha256", "--link"].filter(sw);
|
|
305
305
|
}
|
|
306
|
+
if (argIndex >= 1 && verb === "update") {
|
|
307
|
+
const flags = ["--check", "--yes", "--allow-major"].filter(sw);
|
|
308
|
+
if (flags.length > 0 && current.startsWith("--")) return flags;
|
|
309
|
+
return listInstalledModuleIdsSync().filter(sw);
|
|
310
|
+
}
|
|
311
|
+
if (argIndex === 1 && verb === "pin") {
|
|
312
|
+
return listInstalledModuleIdsSync().filter(sw);
|
|
313
|
+
}
|
|
314
|
+
if (argIndex >= 2 && verb === "pin") {
|
|
315
|
+
return ["--auto", "on", "off"].filter(sw);
|
|
316
|
+
}
|
|
306
317
|
if (argIndex >= 1 && verb === "list") {
|
|
307
318
|
return ["--from", "--sha256"].filter(sw);
|
|
308
319
|
}
|