@leviyuan/lodestar 0.11.3 → 0.11.4
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/package.json +1 -1
- package/scripts/postinstall.cjs +14 -76
package/package.json
CHANGED
package/scripts/postinstall.cjs
CHANGED
|
@@ -1,30 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
//
|
|
3
|
-
// 7+ default pipes postinstall stdio into its own log — `console.log`
|
|
4
|
-
// is invisible, plain `stdio:'inherit'` spawn inherits the same pipe.
|
|
5
|
-
// Two escape routes here:
|
|
2
|
+
// Postinstall banner — 只告诉用户下一步跑什么, 不在这里拉起向导。
|
|
6
3
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
4
|
+
// 为什么不自动拉向导: npm 7+ pipe 了 postinstall 的 stdio, 自动拉向导只能
|
|
5
|
+
// 靠接管 /dev/tty 把终端塞给子进程 —— 这套机制脆弱 (作者原注 "Tricky")。
|
|
6
|
+
// 实测在部分 mac 环境 /dev/tty 接管失败时, 向导的 readline 拿不到输入死等,
|
|
7
|
+
// 而父进程 npm 又 wait 在向导退出上 → npm 和向导互相卡死, 终端冻住 (文件
|
|
8
|
+
// 其实早装好了); 杀掉还会触发 npm 回滚删文件。
|
|
11
9
|
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
// Banner output goes to the same terminal device, not console.log, so
|
|
17
|
-
// the user sees "✓ Lodestar 已安装" even though npm captures stdout.
|
|
18
|
-
//
|
|
19
|
-
// If both escape routes fail (no console / CI / weird sandbox), we
|
|
20
|
-
// fall back to a hint, and the daemon entry (cli.ts) auto-triggers the
|
|
21
|
-
// wizard on first run regardless.
|
|
10
|
+
// 稳的做法是 trigger-on-first-run: 用户在真终端首跑 lodestar-daemon 时,
|
|
11
|
+
// cli.ts 发现没 config + isTTY 就自动进入向导 (真 TTY, readline 一定正常)。
|
|
12
|
+
// 所以这里只打个提示就 process.exit(0), 不 spawn 任何子进程, 永不卡死。
|
|
22
13
|
|
|
23
|
-
const { spawn } = require('child_process')
|
|
24
14
|
const fs = require('fs')
|
|
25
|
-
const path = require('path')
|
|
26
|
-
|
|
27
|
-
const setupBundle = path.join(__dirname, '..', 'dist', 'lodestar-setup.js')
|
|
28
15
|
|
|
29
16
|
function termWrite (msg) {
|
|
30
17
|
try {
|
|
@@ -36,62 +23,13 @@ function termWrite (msg) {
|
|
|
36
23
|
fs.writeFileSync('/dev/tty', msg)
|
|
37
24
|
}
|
|
38
25
|
} catch {
|
|
39
|
-
// No
|
|
26
|
+
// No controlling tty (CI / pipe) — best-effort stdout, npm 多半会吞掉。
|
|
40
27
|
try { process.stdout.write(msg) } catch {}
|
|
41
28
|
}
|
|
42
29
|
}
|
|
43
30
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
termWrite(' (会自动拉起向导)\n')
|
|
48
|
-
termWrite(' 或者只跑向导: \x1b[32mlodestar-setup\x1b[0m\n\n')
|
|
49
|
-
process.exit(0)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
termWrite('\n \x1b[1m\x1b[36m✓ Lodestar 已安装\x1b[0m\n\n')
|
|
53
|
-
|
|
54
|
-
// Path 1: npm started us with --foreground-scripts. Our own stdio is
|
|
55
|
-
// already a real TTY. Just inherit-spawn the wizard, same window.
|
|
56
|
-
if (process.stdout.isTTY && process.stdin.isTTY) {
|
|
57
|
-
termWrite(' \x1b[2m启动配置向导...\x1b[0m\n\n')
|
|
58
|
-
const child = spawn(process.execPath, [setupBundle], { stdio: 'inherit' })
|
|
59
|
-
child.on('exit', (code) => process.exit(code == null ? 0 : code))
|
|
60
|
-
child.on('error', (e) => fallback(`spawn 失败: ${e.message}`))
|
|
61
|
-
return
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Path 2: Windows. Open a NEW console window — that window is outside
|
|
65
|
-
// npm's stdio pipe and has a real terminal of its own. `cmd /k` keeps
|
|
66
|
-
// it open after the wizard exits so the success message is readable.
|
|
67
|
-
if (process.platform === 'win32') {
|
|
68
|
-
termWrite(' \x1b[2m启动配置向导 (新窗口) ...\x1b[0m\n')
|
|
69
|
-
termWrite(' \x1b[2m向导会在另一个 cmd 窗口里跑, 完成后按 Enter / 输入 exit 关掉它即可。\x1b[0m\n\n')
|
|
70
|
-
try {
|
|
71
|
-
const child = spawn(
|
|
72
|
-
'cmd.exe',
|
|
73
|
-
['/c', 'start', 'Lodestar Setup', 'cmd', '/k', process.execPath, setupBundle],
|
|
74
|
-
{ detached: true, stdio: 'ignore', windowsHide: false },
|
|
75
|
-
)
|
|
76
|
-
child.unref()
|
|
77
|
-
process.exit(0)
|
|
78
|
-
} catch (e) {
|
|
79
|
-
fallback(`新窗口启动失败: ${e.message}`)
|
|
80
|
-
}
|
|
81
|
-
return
|
|
82
|
-
}
|
|
31
|
+
termWrite('\n \x1b[1m\x1b[36m✓ Lodestar 已安装\x1b[0m\n')
|
|
32
|
+
termWrite('\n \x1b[2m下一步: 在终端跑 \x1b[32mlodestar-daemon\x1b[0m\x1b[2m 进入配置向导\x1b[0m')
|
|
33
|
+
termWrite('\n \x1b[2m(首次运行会自动拉起向导; 也可直接跑 \x1b[32mlodestar-setup\x1b[0m\x1b[2m)\x1b[0m\n\n')
|
|
83
34
|
|
|
84
|
-
|
|
85
|
-
// as a fd and pass it as child stdio. Bypasses npm's pipe in-place,
|
|
86
|
-
// same terminal window.
|
|
87
|
-
try {
|
|
88
|
-
const ttyFd = fs.openSync('/dev/tty', 'r+')
|
|
89
|
-
termWrite(' \x1b[2m启动配置向导...\x1b[0m\n\n')
|
|
90
|
-
const child = spawn(process.execPath, [setupBundle], {
|
|
91
|
-
stdio: [ttyFd, ttyFd, ttyFd],
|
|
92
|
-
})
|
|
93
|
-
child.on('exit', (code) => process.exit(code == null ? 0 : code))
|
|
94
|
-
child.on('error', (e) => fallback(`spawn 失败: ${e.message}`))
|
|
95
|
-
} catch (e) {
|
|
96
|
-
fallback(`/dev/tty 打不开: ${e.message}`)
|
|
97
|
-
}
|
|
35
|
+
process.exit(0)
|