@jonathanyee/devtunnel-ctl 0.1.0 → 0.2.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.
@@ -0,0 +1,327 @@
1
+ import net from 'node:net';
2
+ import { Agent } from 'node:https';
3
+ import { TunnelRelayTunnelHost, ConnectionStatus, RelayConnectionError } from '@microsoft/dev-tunnels-connections';
4
+ import { TunnelManagementHttpClient, ManagementApiVersions } from '@microsoft/dev-tunnels-management';
5
+ import { SshDisconnectReason } from '@microsoft/dev-tunnels-ssh';
6
+ import { TokenProvider } from "./auth.js";
7
+ import { bounded, Fault, safeFault } from "./core.js";
8
+ import { resolveTunnel, sdkCall, sdkRefresh, SdkTransport } from "./sdk-transport.js";
9
+ import { sleep } from "./host.js";
10
+ export function hostManagement(agent) {
11
+ const management = Object.assign(new TunnelManagementHttpClient({ name: 'devtunnel-ctl', version: '0.1.0' }, ManagementApiVersions.Version20230927preview, undefined, undefined, agent), { httpsAgent: agent });
12
+ management.trace = () => { };
13
+ management.enableEventsReporting = false;
14
+ return management;
15
+ }
16
+ export function localPort(port, signal) {
17
+ return bounded(inner => new Promise((resolve, reject) => {
18
+ const socket = net.connect({ host: '127.0.0.1', port });
19
+ const abort = () => { socket.destroy(); reject(new Fault('aborted')); };
20
+ inner.addEventListener('abort', abort, { once: true });
21
+ const finish = (error) => {
22
+ inner.removeEventListener('abort', abort);
23
+ socket.destroy();
24
+ if (error)
25
+ reject(error);
26
+ else
27
+ resolve();
28
+ };
29
+ socket.once('connect', () => finish());
30
+ socket.once('error', () => finish(new Fault('remote-unavailable')));
31
+ }), 3000, signal);
32
+ }
33
+ export class HostProbe {
34
+ ports;
35
+ deps;
36
+ failures = new Map();
37
+ retryAt = 0;
38
+ constructor(ports, deps) { this.ports = ports; this.deps = deps; }
39
+ async check(ports, signal, age) {
40
+ const status = { kind: 'status', state: 'connected', relayConnected: true,
41
+ ports, localUnavailable: [], verifiedPorts: [] };
42
+ let replace = false;
43
+ for (const port of this.ports) {
44
+ if (!ports.includes(port))
45
+ throw new Fault('invalid-config', 'A probe port is not configured on this tunnel.');
46
+ if (age < this.retryAt) {
47
+ status.probeFault = 'throttled';
48
+ continue;
49
+ }
50
+ try {
51
+ await this.deps.local(port, signal);
52
+ }
53
+ catch (error) {
54
+ if (signal.aborted)
55
+ throw new Fault('aborted');
56
+ if (!['remote-unavailable', 'timeout'].includes(safeFault(error).code))
57
+ throw error;
58
+ status.localUnavailable.push(port);
59
+ this.failures.delete(port);
60
+ continue;
61
+ }
62
+ try {
63
+ await this.deps.remote(port, signal);
64
+ status.verifiedPorts.push(port);
65
+ this.failures.delete(port);
66
+ }
67
+ catch (error) {
68
+ if (signal.aborted)
69
+ throw new Fault('aborted');
70
+ const fault = safeFault(error);
71
+ status.probeFault = fault.code;
72
+ if (['login-required', 'access-denied', 'invalid-config', 'throttled'].includes(fault.code)) {
73
+ this.failures.delete(port);
74
+ if (fault.code === 'throttled')
75
+ this.retryAt = age + Math.max(1000, fault.retryAfterMs);
76
+ }
77
+ else {
78
+ // Recheck the application after a failed tunnel attempt to avoid a downtime race.
79
+ try {
80
+ await this.deps.local(port, signal);
81
+ }
82
+ catch {
83
+ status.localUnavailable.push(port);
84
+ this.failures.delete(port);
85
+ continue;
86
+ }
87
+ const count = (this.failures.get(port) ?? 0) + 1;
88
+ this.failures.set(port, count);
89
+ if (count >= 2 && age >= 30000)
90
+ replace = true;
91
+ }
92
+ }
93
+ }
94
+ status.state = this.ports.length && status.verifiedPorts.length === this.ports.length ? 'verified' :
95
+ status.localUnavailable.length || status.probeFault ? 'degraded' : 'connected';
96
+ return { status, replace };
97
+ }
98
+ }
99
+ export async function runHostSdk(options, report, parent, deps = {}) {
100
+ const tokens = deps.tokens ?? new TokenProvider(options.helperPath);
101
+ const now = deps.now ?? Date.now;
102
+ const agent = new Agent({ keepAlive: false, maxSockets: 16, timeout: 10000 });
103
+ const management = Object.assign((deps.management ?? hostManagement)(agent), { httpsAgent: agent });
104
+ const host = deps.host?.(management) ?? new TunnelRelayTunnelHost(management, () => { });
105
+ host.trace = () => { };
106
+ const life = new AbortController(), signal = AbortSignal.any([parent, life.signal]);
107
+ const subscriptions = [];
108
+ let fault, metadata;
109
+ let refreshFailure, refreshEpoch = 0, refreshes = 0, graceUntil = 0;
110
+ let established = false, authRetried = false;
111
+ const fail = (error) => {
112
+ fault ??= classify(error);
113
+ life.abort();
114
+ };
115
+ const classify = (error) => {
116
+ if (host.disconnectReason === SshDisconnectReason.tooManyConnections ||
117
+ (error instanceof Error && 'reason' in error && error.reason === SshDisconnectReason.tooManyConnections)) {
118
+ return new Fault('host-superseded');
119
+ }
120
+ if (error instanceof RelayConnectionError && error.errorContext.statusCode === 401 && refreshFailure)
121
+ return refreshFailure;
122
+ return safeFault(error);
123
+ };
124
+ const readMetadata = async (inner) => {
125
+ const tunnel = await resolveTunnel(options, tokens, management, inner, 'host');
126
+ const ports = tunnel.ports?.map(p => p.portNumber) ?? [];
127
+ if (options.probePorts.some(p => !ports.includes(p)))
128
+ throw new Fault('invalid-config', 'A probe port is not configured on this tunnel.');
129
+ // SDK 1.3.61 refreshPorts() iterates its Map with Object.entries(), missing removals.
130
+ for (const [key, forwarder] of host.remoteForwarders) {
131
+ if (!ports.includes(forwarder.localPort)) {
132
+ host.remoteForwarders.delete(key);
133
+ forwarder.dispose();
134
+ }
135
+ }
136
+ metadata = tunnel;
137
+ return tunnel;
138
+ };
139
+ const originalUpdate = management.updateTunnelEndpoint.bind(management);
140
+ management.updateTunnelEndpoint = async (tunnel, endpoint, requestOptions, cancellation) => {
141
+ if (signal.aborted)
142
+ throw new Fault('aborted');
143
+ if (!endpoint.id || !tunnel.tunnelId || !tunnel.clusterId)
144
+ throw new Fault('invalid-config');
145
+ // The supervisor records the exact owned ID before a request can be interrupted.
146
+ await report({ kind: 'endpoint', id: endpoint.id, tunnelId: tunnel.tunnelId, clusterId: tunnel.clusterId });
147
+ return sdkRefresh(signal, cancellation, 8000, inner => sdkCall(inner, cancel => originalUpdate(tunnel, endpoint, requestOptions, cancel)));
148
+ };
149
+ const relayFactory = host.streamFactory;
150
+ host.streamFactory = {
151
+ createRelayStream: async (...args) => {
152
+ if (!args[0].startsWith('wss://'))
153
+ throw new Fault('invalid-config', 'Host relay must use authenticated TLS.');
154
+ const config = { ...args[3], keepalive: true, useNativeKeepalive: false, keepaliveInterval: 10000,
155
+ dropConnectionOnKeepaliveTimeout: true, keepaliveGracePeriod: 10000,
156
+ tlsOptions: { ...args[3]?.tlsOptions, agent } };
157
+ return bounded(() => relayFactory.createRelayStream(args[0], args[1], args[2], config, args[4]), 10000, signal, late => bounded(() => late.stream.close(), 1000));
158
+ },
159
+ };
160
+ subscriptions.push(host.connectionStatusChanged(e => {
161
+ if (signal.aborted)
162
+ return;
163
+ if (e.status === ConnectionStatus.Connected) {
164
+ established = true;
165
+ authRetried = false;
166
+ graceUntil = 0;
167
+ refreshFailure = undefined;
168
+ refreshes = 0;
169
+ refreshEpoch++;
170
+ report({ kind: 'status', state: 'connected', relayConnected: true,
171
+ ports: (host.tunnel ?? metadata)?.ports?.map(p => p.portNumber) ?? [], localUnavailable: [], verifiedPorts: [] });
172
+ }
173
+ else {
174
+ if (e.status === ConnectionStatus.Connecting && e.previousStatus === ConnectionStatus.Connected) {
175
+ refreshEpoch++;
176
+ refreshFailure = undefined;
177
+ refreshes = 0;
178
+ authRetried = false;
179
+ }
180
+ if (host.disconnectReason === SshDisconnectReason.tooManyConnections) {
181
+ fail(new Fault('host-superseded'));
182
+ return;
183
+ }
184
+ if (e.disconnectError) {
185
+ const error = classify(e.disconnectError);
186
+ if (['host-superseded', 'login-required', 'access-denied', 'invalid-config', 'throttled'].includes(error.code)) {
187
+ fail(error);
188
+ return;
189
+ }
190
+ }
191
+ graceUntil ||= now() + 8000;
192
+ report({ kind: 'status', state: 'connecting', relayConnected: false,
193
+ ports: metadata?.ports?.map(p => p.portNumber) ?? [], localUnavailable: [], verifiedPorts: [] });
194
+ }
195
+ }));
196
+ subscriptions.push(host.retryingTunnelConnection(e => {
197
+ const error = classify(e.error);
198
+ const initialAuthRetry = !established && refreshes === 1 && !authRetried && !refreshFailure;
199
+ if (initialAuthRetry)
200
+ authRetried = true;
201
+ e.retry = !signal.aborted && !refreshFailure && (initialAuthRetry || (established && now() < graceUntil)) &&
202
+ !['host-superseded', 'access-denied', 'invalid-config', 'throttled'].includes(error.code);
203
+ if (!e.retry)
204
+ fail(error);
205
+ }));
206
+ subscriptions.push(host.refreshingTunnelAccessToken(e => {
207
+ const epoch = ++refreshEpoch;
208
+ refreshFailure = undefined;
209
+ e.tunnelAccessToken = sdkRefresh(signal, e.cancellation, 12000, async (inner) => {
210
+ if (++refreshes > 1)
211
+ throw new Fault('login-required');
212
+ return (await tokens.get(options, inner, true, 'host')).value;
213
+ }).then(token => {
214
+ if (epoch !== refreshEpoch || signal.aborted)
215
+ throw new Fault('aborted');
216
+ return token;
217
+ }).catch(error => {
218
+ if (epoch !== refreshEpoch || signal.aborted)
219
+ throw new Fault('aborted');
220
+ const failure = safeFault(error);
221
+ refreshFailure = new Fault(failure.code, undefined, failure.retryAfterMs);
222
+ throw refreshFailure;
223
+ });
224
+ }));
225
+ subscriptions.push(host.refreshingTunnel(e => { e.tunnelPromise = sdkRefresh(signal, e.cancellation, 20000, readMetadata); }));
226
+ const transport = new SdkTransport(tokens);
227
+ const probes = new HostProbe(options.probePorts, {
228
+ local: localPort,
229
+ remote: async (port, inner) => {
230
+ const profile = { ...options, name: 'host-probe', remotePort: port, localPort: 1, paused: false };
231
+ const session = await bounded(s => transport.connect(profile, s, () => { }), 25000, inner, late => late.dispose());
232
+ try {
233
+ const stream = await session.open(inner);
234
+ stream.destroy();
235
+ }
236
+ finally {
237
+ await bounded(() => session.dispose(), 2000);
238
+ }
239
+ },
240
+ });
241
+ const destroy = () => agent.destroy();
242
+ signal.addEventListener('abort', destroy, { once: true });
243
+ try {
244
+ report({ kind: 'status', state: 'connecting', relayConnected: false, ports: [], localUnavailable: [], verifiedPorts: [] });
245
+ const tunnel = await bounded(readMetadata, 25000, signal);
246
+ await bounded(inner => sdkCall(inner, cancellation => host.connect(tunnel, {
247
+ enableRetry: true, enableReconnect: true, httpAgent: agent,
248
+ }, cancellation)), 15000, signal);
249
+ const connectedAt = now();
250
+ let nextProbe = 0, nextRefresh = connectedAt + 60000;
251
+ while (!signal.aborted) {
252
+ if (host.disconnectReason === SshDisconnectReason.tooManyConnections)
253
+ throw new Fault('host-superseded');
254
+ if (host.connectionStatus !== ConnectionStatus.Connected) {
255
+ graceUntil ||= now() + 8000;
256
+ if (now() >= graceUntil)
257
+ throw new Fault('retrying');
258
+ }
259
+ else if (now() >= nextProbe) {
260
+ const ports = (host.tunnel ?? metadata)?.ports?.map(p => p.portNumber) ?? [];
261
+ const result = await probes.check(ports, signal, now() - connectedAt);
262
+ report(result.status);
263
+ if (result.replace)
264
+ throw new Fault('remote-unavailable');
265
+ nextProbe = now() + 10000;
266
+ }
267
+ if (now() >= nextRefresh && host.connectionStatus === ConnectionStatus.Connected) {
268
+ await bounded(inner => sdkCall(inner, cancellation => host.refreshPorts(cancellation)), 12000, signal);
269
+ nextRefresh = now() + 60000;
270
+ }
271
+ await (deps.wait ?? sleep)(1000, signal);
272
+ }
273
+ }
274
+ catch (error) {
275
+ if (!parent.aborted)
276
+ fault ??= classify(error);
277
+ }
278
+ finally {
279
+ refreshEpoch++;
280
+ for (const subscription of subscriptions)
281
+ subscription.dispose();
282
+ signal.removeEventListener('abort', destroy);
283
+ // Delete only the SDK instance's own endpoint; never bulk-delete by host/tunnel.
284
+ try {
285
+ await bounded(() => host.dispose(), 2000);
286
+ }
287
+ catch {
288
+ if (!parent.aborted)
289
+ fault ??= new Fault('retrying');
290
+ }
291
+ agent.destroy();
292
+ life.abort();
293
+ tokens.clear();
294
+ await bounded(() => management.dispose(), 1000);
295
+ }
296
+ if (fault && !parent.aborted)
297
+ throw fault;
298
+ }
299
+ export async function retireHostEndpoint(options, endpoint, deps = {}) {
300
+ if (options.clusterId && endpoint.clusterId !== options.clusterId)
301
+ throw new Fault('host-cleanup-failed');
302
+ const tokens = deps.tokens ?? new TokenProvider(options.helperPath);
303
+ const agent = new Agent({ keepAlive: false, timeout: 10000 });
304
+ const management = (deps.management ?? hostManagement)(agent);
305
+ try {
306
+ await bounded(async (signal) => {
307
+ const token = await tokens.get(options, signal, false, 'host');
308
+ await sdkCall(signal, cancellation => management.deleteTunnelEndpoints({
309
+ tunnelId: endpoint.tunnelId, clusterId: endpoint.clusterId, accessTokens: { host: token.value },
310
+ }, endpoint.id, undefined, cancellation));
311
+ }, 20000);
312
+ }
313
+ catch {
314
+ throw new Fault('host-cleanup-failed');
315
+ }
316
+ finally {
317
+ agent.destroy();
318
+ tokens.clear();
319
+ try {
320
+ await bounded(() => management.dispose(), 1000);
321
+ }
322
+ catch {
323
+ throw new Fault('host-cleanup-failed');
324
+ }
325
+ }
326
+ }
327
+ //# sourceMappingURL=host-sdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-sdk.js","sourceRoot":"","sources":["../src/host-sdk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { runHost } from './host-process.ts';
2
+ import type { HostMessage, HostOptions } from './host.ts';
3
+ export declare function hostJobPaths(root: string, options: HostOptions): {
4
+ label: string;
5
+ dir: string;
6
+ };
7
+ interface HostAgent {
8
+ label: string;
9
+ node: string;
10
+ entry: string;
11
+ state: string;
12
+ options: HostOptions;
13
+ }
14
+ export declare function hostLaunchAgent(agent: HostAgent): string;
15
+ export declare function readHostState(dir: string, expectedPid?: number): Promise<{
16
+ responsive: boolean;
17
+ snapshot?: unknown;
18
+ }>;
19
+ export declare function serveHost(options: HostOptions, root: string, runner?: typeof runHost, output?: (message: HostMessage) => void): Promise<void>;
20
+ export declare function hostService(action: string, options: HostOptions, root: string, entry: string): Promise<unknown>;
21
+ export {};
@@ -0,0 +1,193 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { isAbsolute, join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ import { open, rename, readFile, writeFile, mkdir, unlink, realpath, lstat } from 'node:fs/promises';
5
+ import { constants } from 'node:fs';
6
+ import { Fault, record } from "./core.js";
7
+ import { privateDir, privatePath, executable } from "./paths.js";
8
+ import { DaemonLock } from "./lock.js";
9
+ import { Log } from "./log.js";
10
+ import { launchctl, xml } from "./launchd.js";
11
+ import { runHost } from "./host-process.js";
12
+ import { parseHostMessage } from "./host.js";
13
+ export function hostJobPaths(root, options) {
14
+ const hash = createHash('sha256').update(JSON.stringify([root, options.tunnelId, options.clusterId ?? ''])).digest('hex').slice(0, 20);
15
+ return { label: `local.devtunnel-ctl.host.${hash}`, dir: join(root, 'hosts', hash) };
16
+ }
17
+ export function hostLaunchAgent(agent) {
18
+ if (![agent.node, agent.entry, agent.state, agent.options.helperPath].every(p => isAbsolute(p) && !/[\0\r\n]/.test(p))) {
19
+ throw new Fault('invalid-config', 'Host service requires absolute runtime, entrypoint, helper and state paths.');
20
+ }
21
+ const args = [agent.node, agent.entry, '--state-dir', agent.state, 'host', agent.options.tunnelId,
22
+ '--helper', agent.options.helperPath, ...(agent.options.clusterId ? ['--cluster', agent.options.clusterId] : []),
23
+ ...agent.options.probePorts.flatMap(p => ['--probe-port', String(p)])];
24
+ return `<?xml version="1.0" encoding="UTF-8"?>
25
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
26
+ <plist version="1.0"><dict>
27
+ <key>Label</key><string>${xml(agent.label)}</string>
28
+ <key>ProgramArguments</key><array>${args.map(a => `<string>${xml(a)}</string>`).join('')}</array>
29
+ <key>RunAtLoad</key><true/>
30
+ <key>KeepAlive</key><dict><key>SuccessfulExit</key><false/></dict>
31
+ <key>ThrottleInterval</key><integer>15</integer>
32
+ <key>ProcessType</key><string>Background</string>
33
+ <key>StandardOutPath</key><string>/dev/null</string>
34
+ <key>StandardErrorPath</key><string>/dev/null</string>
35
+ </dict></plist>
36
+ `;
37
+ }
38
+ async function hostDirectory(root, options) {
39
+ await privateDir(root);
40
+ await privateDir(join(root, 'hosts'));
41
+ const { dir } = hostJobPaths(root, options);
42
+ await privateDir(dir);
43
+ return dir;
44
+ }
45
+ export async function readHostState(dir, expectedPid) {
46
+ const path = join(dir, 'status.json');
47
+ try {
48
+ await privatePath(dir, true);
49
+ await privatePath(path);
50
+ if ((await lstat(path)).size > 65536)
51
+ throw new Fault('protocol');
52
+ const value = JSON.parse(await readFile(path, 'utf8'));
53
+ if (!record(value) || !Number.isSafeInteger(value.pid) || typeof value.updatedAt !== 'number' ||
54
+ typeof value.running !== 'boolean' || !parseHostMessage(value.message))
55
+ throw new Fault('protocol');
56
+ return { responsive: value.running && expectedPid !== undefined && value.pid === expectedPid &&
57
+ Date.now() >= value.updatedAt && Date.now() - value.updatedAt < 5000,
58
+ snapshot: { pid: value.pid, running: value.running, updatedAt: value.updatedAt,
59
+ observedAt: typeof value.observedAt === 'number' ? value.observedAt : value.updatedAt,
60
+ message: parseHostMessage(value.message) } };
61
+ }
62
+ catch (error) {
63
+ if (error instanceof Error && 'code' in error && error.code === 'ENOENT')
64
+ return { responsive: false };
65
+ throw error instanceof Fault ? error : new Fault('protocol', 'Cannot read private host status.');
66
+ }
67
+ }
68
+ export async function serveHost(options, root, runner = runHost, output = (message) => console.log(JSON.stringify(message))) {
69
+ const dir = await hostDirectory(root, options);
70
+ const lock = new DaemonLock(dir);
71
+ await lock.acquire();
72
+ const log = new Log(dir);
73
+ const life = new AbortController();
74
+ const instance = randomUUID();
75
+ let message = { kind: 'status', state: 'connecting', relayConnected: false,
76
+ ports: [], localUnavailable: [], verifiedPorts: [] };
77
+ let running = true, failure, pending = 0, observedAt = Date.now();
78
+ const fail = (error) => { failure ??= error; life.abort(); };
79
+ let tail = Promise.resolve();
80
+ const snapshot = () => {
81
+ if (failure)
82
+ return;
83
+ if (pending >= 32) {
84
+ fail(new Fault('internal', 'Host status backlog exceeded its limit.'));
85
+ return;
86
+ }
87
+ pending++;
88
+ const value = { instance, pid: process.pid, running, observedAt, updatedAt: Date.now(), message };
89
+ tail = tail.then(async () => {
90
+ const path = join(dir, 'status.json'), temp = join(dir, `status-${instance}.tmp`);
91
+ try {
92
+ await privatePath(path);
93
+ }
94
+ catch (error) {
95
+ if (!(error instanceof Error && 'code' in error && error.code === 'ENOENT'))
96
+ throw error;
97
+ }
98
+ const handle = await open(temp, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
99
+ try {
100
+ await handle.writeFile(JSON.stringify(value) + '\n');
101
+ await handle.sync();
102
+ }
103
+ finally {
104
+ await handle.close();
105
+ }
106
+ await rename(temp, path);
107
+ }).catch(fail).finally(() => { pending--; });
108
+ };
109
+ const report = (value) => {
110
+ if (value.kind === 'heartbeat' || value.kind === 'endpoint')
111
+ return;
112
+ message = value;
113
+ observedAt = Date.now();
114
+ output(value);
115
+ void log.write({ event: 'host', state: value.kind === 'status' ? value.state : value.kind,
116
+ ...(value.kind === 'status' ? { relayConnected: value.relayConnected } : {}),
117
+ ...(value.kind === 'fault' ? { message: new Fault(value.code).message } : {}),
118
+ ...(value.kind === 'retry' ? { attempt: value.attempt, nextRetryAt: value.nextRetryAt } : {}),
119
+ }).catch(fail);
120
+ snapshot();
121
+ };
122
+ let tick;
123
+ try {
124
+ await log.init();
125
+ snapshot();
126
+ await tail;
127
+ if (failure)
128
+ throw failure;
129
+ tick = setInterval(snapshot, 2000);
130
+ await runner(options, report, life.signal);
131
+ }
132
+ finally {
133
+ clearInterval(tick);
134
+ running = false;
135
+ snapshot();
136
+ try {
137
+ await tail;
138
+ await log.flush();
139
+ }
140
+ catch (error) {
141
+ fail(error);
142
+ }
143
+ finally {
144
+ await lock.release();
145
+ }
146
+ }
147
+ if (failure)
148
+ throw new Fault('internal', 'Cannot maintain private host status or logs.');
149
+ }
150
+ export async function hostService(action, options, root, entry) {
151
+ if (process.platform !== 'darwin' || process.getuid?.() === 0)
152
+ throw new Fault('invalid-config', 'Host services require a non-root macOS user. Use foreground host mode on Linux or Windows.');
153
+ const { label, dir } = hostJobPaths(root, options);
154
+ const plistDir = join(homedir(), 'Library', 'LaunchAgents'), path = join(plistDir, label + '.plist');
155
+ const target = `gui/${process.getuid()}`;
156
+ if (action === 'install') {
157
+ await hostDirectory(root, options);
158
+ const node = await executable(process.execPath), main = await realpath(entry), helperPath = await executable(options.helperPath);
159
+ await mkdir(plistDir, { recursive: true, mode: 0o700 });
160
+ try {
161
+ await writeFile(path, hostLaunchAgent({ label, node, entry: main, state: root, options: { ...options, helperPath } }), { mode: 0o600, flag: 'wx' });
162
+ }
163
+ catch (error) {
164
+ if (error instanceof Error && 'code' in error && error.code === 'EEXIST')
165
+ throw new Fault('invalid-config', 'Host service is already installed. Stop and uninstall it before changing its arguments.');
166
+ throw error;
167
+ }
168
+ return { installed: true, loaded: false, label, path };
169
+ }
170
+ if (action === 'status') {
171
+ const registration = await launchctl(['print', `${target}/${label}`], true);
172
+ const status = await readHostState(dir, registration.pid);
173
+ return { label, ...registration, ...status };
174
+ }
175
+ await privatePath(path);
176
+ if (action === 'start') {
177
+ await launchctl(['bootstrap', target, path]);
178
+ return { label, loaded: true };
179
+ }
180
+ if (action === 'stop') {
181
+ await launchctl(['bootout', `${target}/${label}`]);
182
+ return { label, loaded: false };
183
+ }
184
+ if (action === 'uninstall') {
185
+ const registration = await launchctl(['print', `${target}/${label}`], true);
186
+ if (registration.loaded)
187
+ await launchctl(['bootout', `${target}/${label}`]);
188
+ await unlink(path);
189
+ return { label, installed: false };
190
+ }
191
+ throw new Fault('invalid-config', 'Unknown host service action.');
192
+ }
193
+ //# sourceMappingURL=host-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-service.js","sourceRoot":"","sources":["../src/host-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};