@max-null/dsh-plugin-center 0.2.7 → 0.2.10
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/update.d.ts +14 -0
- package/dist/update.js +50 -2
- package/package.json +1 -1
package/dist/update.d.ts
CHANGED
|
@@ -60,6 +60,20 @@ export declare function logPnpm(profileDir: string, args: readonly string[], res
|
|
|
60
60
|
* CreateProcess 只找 pnpm.exe(.cmd/.ps1 必须经 shell)——2026-08-17 实测
|
|
61
61
|
* spawn('pnpm', shell:false) 直接 ENOENT,更新永远假成功。 */
|
|
62
62
|
export declare function pnpmCandidates(): string[];
|
|
63
|
+
/** 归档 profile 的 node_modules 由 pnpm `<major>` 生成(SSiD 部署时把构建机
|
|
64
|
+
* store 元数据改写成本机路径且保留 major 后缀——shell/main.mjs rewire)。
|
|
65
|
+
* 若执行机全局 pnpm 是另一个 major(常见:机器装 pnpm 10,归档是 pnpm 11
|
|
66
|
+
* 打的),任何 pnpm 操作都报 ERR_PNPM_UNEXPECTED_STORE(不同 major 的 store
|
|
67
|
+
* 目录不兼容)。这里从 `.modules.yaml` 探测布局用的 major,候选命令里追
|
|
68
|
+
* 加 `npx --yes pnpm@<major>`(npx 拉取同 major CLI,之后走 npm 缓存),
|
|
69
|
+
* 保证以「与布局一致」的 pnpm 执行更新。
|
|
70
|
+
* @returns 布局的 pnpm major(如 11),读不到时 undefined。
|
|
71
|
+
*/
|
|
72
|
+
export declare function detectStoreMajor(profileDir: string): number | undefined;
|
|
73
|
+
/** 完整 pnpm 命令候选序列:壳内捆绑 pnpm(SSID_PNPM,与归档 store 布局同
|
|
74
|
+
* major)最优先;本地 pnpm(PATH/用户级)其次;最终以 npx pnpm@<major>
|
|
75
|
+
* 兜底(仅当探测到布局 major)。 */
|
|
76
|
+
export declare function pnpmCommandCandidates(profileDir: string): string[];
|
|
63
77
|
/**
|
|
64
78
|
* Run pnpm in the profile directory, trying each candidate command in turn.
|
|
65
79
|
* Output is captured (no named-pipe stdio — the host process is the web or
|
package/dist/update.js
CHANGED
|
@@ -184,16 +184,55 @@ export function pnpmCandidates() {
|
|
|
184
184
|
}
|
|
185
185
|
return commands;
|
|
186
186
|
}
|
|
187
|
+
/** 归档 profile 的 node_modules 由 pnpm `<major>` 生成(SSiD 部署时把构建机
|
|
188
|
+
* store 元数据改写成本机路径且保留 major 后缀——shell/main.mjs rewire)。
|
|
189
|
+
* 若执行机全局 pnpm 是另一个 major(常见:机器装 pnpm 10,归档是 pnpm 11
|
|
190
|
+
* 打的),任何 pnpm 操作都报 ERR_PNPM_UNEXPECTED_STORE(不同 major 的 store
|
|
191
|
+
* 目录不兼容)。这里从 `.modules.yaml` 探测布局用的 major,候选命令里追
|
|
192
|
+
* 加 `npx --yes pnpm@<major>`(npx 拉取同 major CLI,之后走 npm 缓存),
|
|
193
|
+
* 保证以「与布局一致」的 pnpm 执行更新。
|
|
194
|
+
* @returns 布局的 pnpm major(如 11),读不到时 undefined。
|
|
195
|
+
*/
|
|
196
|
+
export function detectStoreMajor(profileDir) {
|
|
197
|
+
try {
|
|
198
|
+
const meta = readFileSync(join(profileDir, 'node_modules', '.modules.yaml'), 'utf8');
|
|
199
|
+
// JSON 转义(\\v11)与 YAML 字面(\v11)两种形态都覆盖。
|
|
200
|
+
const match = /storeDir[^\n]*store[\\/]+v?(\d+)/.exec(meta);
|
|
201
|
+
if (match === null)
|
|
202
|
+
return undefined;
|
|
203
|
+
return Number(match[1]);
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
return undefined;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/** 完整 pnpm 命令候选序列:壳内捆绑 pnpm(SSID_PNPM,与归档 store 布局同
|
|
210
|
+
* major)最优先;本地 pnpm(PATH/用户级)其次;最终以 npx pnpm@<major>
|
|
211
|
+
* 兜底(仅当探测到布局 major)。 */
|
|
212
|
+
export function pnpmCommandCandidates(profileDir) {
|
|
213
|
+
const commands = [];
|
|
214
|
+
const bundled = process.env.SSID_PNPM;
|
|
215
|
+
if (bundled !== undefined && bundled !== '')
|
|
216
|
+
commands.push(bundled);
|
|
217
|
+
commands.push(...pnpmCandidates());
|
|
218
|
+
const major = detectStoreMajor(profileDir);
|
|
219
|
+
if (major !== undefined) {
|
|
220
|
+
commands.push(`npx --yes pnpm@${major}`);
|
|
221
|
+
}
|
|
222
|
+
return commands;
|
|
223
|
+
}
|
|
187
224
|
function runOne(command, args, cwd) {
|
|
188
225
|
return new Promise((resolve) => {
|
|
189
226
|
let child;
|
|
190
227
|
try {
|
|
191
228
|
// shell: true —— Windows 下 .cmd shim 必须经 shell 才能 spawn;
|
|
229
|
+
// command 与 args 合并为整行(command 可能是多词命令,如
|
|
230
|
+
// `npx --yes pnpm@11`;args 是内部生成的固定形态,无注入面)。
|
|
192
231
|
// windowsHide —— GUI 宿主下不弹 cmd 窗口(2026-08-18 用户实测闪烁)。
|
|
193
232
|
// stdio 走默认 pipe:捕获 pnpm 输出,失败时把尾部输出放进 detail
|
|
194
233
|
// (2026-08-22 起——此前 inherit 只有 exit code,SSiD 下更新失败
|
|
195
234
|
// 无法诊断;宿主进程(web/electron)非 DSH 工具沙箱,pipe 可用)。
|
|
196
|
-
child = spawn(command,
|
|
235
|
+
child = spawn([command, ...args].join(' '), { cwd, shell: true, windowsHide: true });
|
|
197
236
|
}
|
|
198
237
|
catch (e) {
|
|
199
238
|
resolve({ ok: false, detail: e instanceof Error ? e.message : String(e), durationMs: 0 });
|
|
@@ -231,11 +270,20 @@ function runOne(command, args, cwd) {
|
|
|
231
270
|
*/
|
|
232
271
|
export async function runPnpm(args, cwd) {
|
|
233
272
|
let last = { ok: false, detail: 'no pnpm candidate found', durationMs: 0 };
|
|
234
|
-
for (const command of
|
|
273
|
+
for (const command of pnpmCommandCandidates(cwd)) {
|
|
235
274
|
last = await runOne(command, args, cwd);
|
|
236
275
|
if (last.ok)
|
|
237
276
|
break;
|
|
238
277
|
}
|
|
278
|
+
// 自更新鸡生蛋兜底提示:所有候选都失败且是 store 版本不匹配时,把可复制
|
|
279
|
+
// 的手动命令放进 detail,用户按提示在 profile 目录执行即可(2026-08-23
|
|
280
|
+
// 另一台电脑 v10/v11 实测——旧 host 无自动兜底,需要一条显式命令)。
|
|
281
|
+
if (!last.ok && last.detail.includes('ERR_PNPM_UNEXPECTED_STORE')) {
|
|
282
|
+
const major = detectStoreMajor(cwd);
|
|
283
|
+
if (major !== undefined) {
|
|
284
|
+
last.detail += `\n\nHint: 在 profile 目录(${cwd})执行:\n npx --yes pnpm@${major} ${args.join(' ')}`;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
239
287
|
logPnpm(cwd, args, last);
|
|
240
288
|
return last;
|
|
241
289
|
}
|
package/package.json
CHANGED