rdsh-gateway 0.8.0 → 0.8.1
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/service.d.ts +3 -2
- package/dist/service.js +23 -12
- package/package.json +1 -1
package/dist/service.d.ts
CHANGED
|
@@ -21,8 +21,9 @@ export interface ServiceSpec {
|
|
|
21
21
|
}
|
|
22
22
|
/** systemd 用户级 unit 模板。 */
|
|
23
23
|
export declare function systemdUnit(execStart: string, spec: ServiceSpec): string;
|
|
24
|
-
/** launchd plist 模板。
|
|
25
|
-
|
|
24
|
+
/** launchd plist 模板。program 为启动前缀 argv([node, 脚本]),命令参数由 spec 提供——
|
|
25
|
+
* launchd 不做空格切分,每个 <string> 是一个 argv 元素,故 node 与脚本必须分开。 */
|
|
26
|
+
export declare function launchdPlist(program: string[], spec: ServiceSpec): string;
|
|
26
27
|
/** 安装并启动服务(用户级)。 */
|
|
27
28
|
export declare function installService(spec: ServiceSpec): Promise<string>;
|
|
28
29
|
/** 服务状态。 */
|
package/dist/service.js
CHANGED
|
@@ -58,9 +58,10 @@ RestartSec=3
|
|
|
58
58
|
WantedBy=default.target
|
|
59
59
|
`;
|
|
60
60
|
}
|
|
61
|
-
/** launchd plist 模板。
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
/** launchd plist 模板。program 为启动前缀 argv([node, 脚本]),命令参数由 spec 提供——
|
|
62
|
+
* launchd 不做空格切分,每个 <string> 是一个 argv 元素,故 node 与脚本必须分开。 */
|
|
63
|
+
export function launchdPlist(program, spec) {
|
|
64
|
+
const argLines = [...program, ...commandArgs(spec)].map((a) => ` <string>${a}</string>`).join("\n");
|
|
64
65
|
const envBlock = spec.pathEnv !== undefined
|
|
65
66
|
? ` <key>EnvironmentVariables</key>
|
|
66
67
|
<dict>
|
|
@@ -77,13 +78,15 @@ export function launchdPlist(execStart, spec) {
|
|
|
77
78
|
<string>com.${spec.name}</string>
|
|
78
79
|
<key>ProgramArguments</key>
|
|
79
80
|
<array>
|
|
80
|
-
|
|
81
|
-
${args}
|
|
81
|
+
${argLines}
|
|
82
82
|
</array>
|
|
83
83
|
<key>RunAtLoad</key>
|
|
84
84
|
<true/>
|
|
85
85
|
<key>KeepAlive</key>
|
|
86
|
-
<
|
|
86
|
+
<dict>
|
|
87
|
+
<key>SuccessfulExit</key>
|
|
88
|
+
<false/>
|
|
89
|
+
</dict>
|
|
87
90
|
${envBlock} <key>StandardOutPath</key>
|
|
88
91
|
<string>${serviceLogPath(spec.name)}</string>
|
|
89
92
|
<key>StandardErrorPath</key>
|
|
@@ -103,18 +106,25 @@ async function run(cmd, args) {
|
|
|
103
106
|
}
|
|
104
107
|
/** 安装并启动服务(用户级)。 */
|
|
105
108
|
export async function installService(spec) {
|
|
106
|
-
const
|
|
109
|
+
const bin = process.argv[1];
|
|
110
|
+
if (bin === undefined) {
|
|
111
|
+
throw new Error("cannot install a service: the running entry script (process.argv[1]) is unknown");
|
|
112
|
+
}
|
|
107
113
|
if (isLinux()) {
|
|
114
|
+
const execStart = `${process.execPath} ${bin}`;
|
|
108
115
|
await mkdir(SYSTEMD_DIR, { recursive: true });
|
|
109
116
|
await writeFile(systemdUnitPath(spec.name), systemdUnit(execStart, spec), { mode: 0o600 });
|
|
110
117
|
await run("systemctl", ["--user", "daemon-reload"]);
|
|
111
118
|
await run("systemctl", ["--user", "enable", "--now", spec.name]);
|
|
112
119
|
return `installed systemd user unit: ${systemdUnitPath(spec.name)}`;
|
|
113
120
|
}
|
|
121
|
+
// macOS(launchd):ProgramArguments 不做空格切分 —— node 与脚本必须作为独立 argv 元素
|
|
122
|
+
const plistPath = launchdPlistPath(spec.name);
|
|
114
123
|
await mkdir(LAUNCHD_DIR, { recursive: true });
|
|
115
|
-
await writeFile(
|
|
116
|
-
await run("launchctl", ["
|
|
117
|
-
|
|
124
|
+
await writeFile(plistPath, launchdPlist([process.execPath, bin], spec), { mode: 0o600 });
|
|
125
|
+
await run("launchctl", ["unload", plistPath]).catch(() => undefined); // 重装幂等:先卸旧 job(不存在时忽略)
|
|
126
|
+
await run("launchctl", ["load", plistPath]);
|
|
127
|
+
return `installed launchd plist: ${plistPath}`;
|
|
118
128
|
}
|
|
119
129
|
/** 服务状态。 */
|
|
120
130
|
export async function serviceStatus(name = SERVICE_NAME) {
|
|
@@ -128,8 +138,9 @@ export async function serviceStatus(name = SERVICE_NAME) {
|
|
|
128
138
|
}
|
|
129
139
|
}
|
|
130
140
|
try {
|
|
131
|
-
await run("launchctl", ["print", `com.${name}`]);
|
|
132
|
-
|
|
141
|
+
const out = await run("launchctl", ["print", `com.${name}`]);
|
|
142
|
+
// loaded 但进程已退出的 job(如 exec 失败)print 仍成功 —— 按 state 细分
|
|
143
|
+
return out.includes("state = running") ? "active" : "loaded (not running)";
|
|
133
144
|
}
|
|
134
145
|
catch {
|
|
135
146
|
return "unloaded";
|