@dbx-tools/cli-service 0.9.36

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,221 @@
1
+ import { spawn } from "node:child_process";
2
+ import { closeSync, openSync } from "node:fs";
3
+ import { appendFile, mkdir } from "node:fs/promises";
4
+ import { dirname, join } from "node:path";
5
+ import * as systrayModule from "systray2";
6
+ import { readServiceDefinition } from "./_config.js";
7
+ import { closeServiceControl, listenForServiceControl, } from "./_control.js";
8
+ import { defaultRuntimeContext, resolveServicePaths } from "./_paths.js";
9
+ const CHILD_STOP_TIMEOUT_MILLISECONDS = 5_000;
10
+ const SysTray = systrayConstructor();
11
+ function systrayConstructor() {
12
+ const loaded = systrayModule.default;
13
+ if (typeof loaded === "function")
14
+ return loaded;
15
+ const nested = loaded && typeof loaded === "object" ? loaded.default : undefined;
16
+ if (typeof nested === "function")
17
+ return nested;
18
+ throw new TypeError("systray2 did not provide a constructor");
19
+ }
20
+ class CliServiceHost {
21
+ definition;
22
+ paths;
23
+ requestStop;
24
+ tray;
25
+ service;
26
+ control;
27
+ stopping = false;
28
+ constructor(definition, paths, requestStop) {
29
+ this.definition = definition;
30
+ this.paths = paths;
31
+ this.requestStop = requestStop;
32
+ }
33
+ async start() {
34
+ await mkdir(this.paths.directory, { recursive: true });
35
+ this.service = this.definition.command
36
+ ? this.startProcess(this.definition.command, true)
37
+ : undefined;
38
+ this.tray = this.createTray();
39
+ await this.tray.ready();
40
+ this.tray.onError((error) => {
41
+ void logError(this.paths.hostLog, error);
42
+ this.requestStop();
43
+ });
44
+ this.tray.onExit((code, signal) => {
45
+ if (this.stopping)
46
+ return;
47
+ void logMessage(this.paths.hostLog, `system tray exited (${signal ?? String(code)})`);
48
+ this.requestStop();
49
+ });
50
+ await this.tray.onClick((action) => {
51
+ const item = action.item;
52
+ item.click?.();
53
+ });
54
+ this.control = await listenForServiceControl(this.paths.controlAddress, () => this.status(), this.requestStop);
55
+ }
56
+ async stop() {
57
+ if (this.stopping)
58
+ return;
59
+ this.stopping = true;
60
+ if (this.control) {
61
+ await closeServiceControl(this.control, this.paths.controlAddress);
62
+ this.control = undefined;
63
+ }
64
+ if (this.tray) {
65
+ if (this.tray.process.exitCode === null && this.tray.process.signalCode === null) {
66
+ await this.tray.kill(false);
67
+ }
68
+ this.tray = undefined;
69
+ }
70
+ if (this.service) {
71
+ await stopProcess(this.service);
72
+ this.service = undefined;
73
+ }
74
+ }
75
+ status() {
76
+ return {
77
+ running: true,
78
+ pid: process.pid,
79
+ ...(this.service?.pid ? { servicePid: this.service.pid } : {}),
80
+ };
81
+ }
82
+ startProcess(command, managed) {
83
+ if (!command.executable) {
84
+ throw new Error("installed service commands require an executable");
85
+ }
86
+ const logDescriptor = openSync(this.paths.processLog, "a");
87
+ const child = spawn(command.executable, command.arguments ?? [], {
88
+ cwd: command.cwd,
89
+ env: { ...process.env, ...command.environment },
90
+ stdio: ["ignore", logDescriptor, logDescriptor],
91
+ });
92
+ closeSync(logDescriptor);
93
+ child.once("error", (error) => {
94
+ void logError(this.paths.hostLog, error);
95
+ if (managed)
96
+ this.requestStop();
97
+ });
98
+ child.once("exit", (code, signal) => {
99
+ if (!this.stopping && managed) {
100
+ void logMessage(this.paths.hostLog, `managed service exited (${signal ?? String(code)})`);
101
+ this.requestStop();
102
+ }
103
+ });
104
+ return child;
105
+ }
106
+ createTray() {
107
+ return new SysTray({
108
+ menu: {
109
+ icon: this.definition.icon,
110
+ title: "",
111
+ tooltip: `${this.definition.name} ${this.definition.version}`,
112
+ items: this.menuItems(),
113
+ isTemplateIcon: this.definition.isTemplateIcon,
114
+ },
115
+ debug: false,
116
+ copyDir: false,
117
+ });
118
+ }
119
+ menuItems() {
120
+ const custom = (this.definition.menu ?? []).map((item) => this.menuItem(item));
121
+ return [
122
+ {
123
+ title: `${this.definition.name} - ${this.definition.version}`,
124
+ tooltip: "",
125
+ enabled: false,
126
+ },
127
+ ...custom,
128
+ { ...SysTray.separator },
129
+ {
130
+ title: "Quit",
131
+ tooltip: `Stop ${this.definition.name}`,
132
+ click: this.requestStop,
133
+ },
134
+ ];
135
+ }
136
+ menuItem(item) {
137
+ if (item.type === "separator")
138
+ return { ...SysTray.separator };
139
+ if (item.type === "url") {
140
+ return {
141
+ title: item.label,
142
+ tooltip: item.url,
143
+ click: () => {
144
+ this.openUrl(item.url);
145
+ },
146
+ };
147
+ }
148
+ return {
149
+ title: item.label,
150
+ tooltip: "",
151
+ click: () => {
152
+ const child = this.startProcess(item.command, false);
153
+ child.unref();
154
+ },
155
+ };
156
+ }
157
+ openUrl(url) {
158
+ const command = process.platform === "darwin"
159
+ ? { executable: "open", arguments: [url] }
160
+ : process.platform === "win32"
161
+ ? {
162
+ executable: "rundll32.exe",
163
+ arguments: ["url.dll,FileProtocolHandler", url],
164
+ }
165
+ : { executable: "xdg-open", arguments: [url] };
166
+ const child = this.startProcess(command, false);
167
+ child.unref();
168
+ }
169
+ }
170
+ async function runCliServiceHost(configFile) {
171
+ process.chdir(dirname(process.execPath));
172
+ const definition = await readServiceDefinition(configFile);
173
+ const runtime = defaultRuntimeContext();
174
+ const paths = resolveServicePaths(definition, runtime);
175
+ let requestStop = () => { };
176
+ const stopped = new Promise((resolve) => {
177
+ requestStop = resolve;
178
+ });
179
+ const host = new CliServiceHost(definition, paths, requestStop);
180
+ process.once("SIGINT", requestStop);
181
+ process.once("SIGTERM", requestStop);
182
+ try {
183
+ await host.start();
184
+ await stopped;
185
+ }
186
+ finally {
187
+ await host.stop();
188
+ }
189
+ }
190
+ async function stopProcess(child) {
191
+ if (child.exitCode !== null || child.signalCode !== null)
192
+ return;
193
+ const exited = new Promise((resolve) => child.once("exit", () => resolve()));
194
+ child.kill("SIGTERM");
195
+ const timedOut = new Promise((resolve) => {
196
+ setTimeout(() => resolve("timeout"), CHILD_STOP_TIMEOUT_MILLISECONDS);
197
+ });
198
+ if ((await Promise.race([exited, timedOut])) === "timeout") {
199
+ child.kill("SIGKILL");
200
+ await exited;
201
+ }
202
+ }
203
+ async function logError(path, error) {
204
+ await logMessage(path, error instanceof Error ? (error.stack ?? error.message) : String(error));
205
+ }
206
+ async function logMessage(path, message) {
207
+ await mkdir(dirname(path), { recursive: true });
208
+ await appendFile(path, `${new Date().toISOString()} ${message}\n`, "utf8");
209
+ }
210
+ function argumentValue(name) {
211
+ const index = process.argv.indexOf(name);
212
+ return index >= 0 ? process.argv[index + 1] : undefined;
213
+ }
214
+ const configFile = argumentValue("--service-config");
215
+ if (configFile) {
216
+ void runCliServiceHost(configFile).catch(async (error) => {
217
+ await logError(join(dirname(configFile), "host.log"), error);
218
+ process.exitCode = 1;
219
+ });
220
+ }
221
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2hvc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvX2hvc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBcUIsTUFBTSxvQkFBb0IsQ0FBQztBQUM5RCxPQUFPLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM5QyxPQUFPLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRTFDLE9BQU8sS0FBSyxhQUFhLE1BQU0sVUFBVSxDQUFDO0FBSTFDLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNyRCxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLHVCQUF1QixHQUV4QixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUscUJBQXFCLEVBQUUsbUJBQW1CLEVBQXFCLE1BQU0sYUFBYSxDQUFDO0FBRzVGLE1BQU0sK0JBQStCLEdBQUcsS0FBSyxDQUFDO0FBQzlDLE1BQU0sT0FBTyxHQUFHLGtCQUFrQixFQUFFLENBQUM7QUFNckMsU0FBUyxrQkFBa0I7SUFDekIsTUFBTSxNQUFNLEdBQVksYUFBYSxDQUFDLE9BQU8sQ0FBQztJQUM5QyxJQUFJLE9BQU8sTUFBTSxLQUFLLFVBQVU7UUFBRSxPQUFPLE1BQTRCLENBQUM7SUFDdEUsTUFBTSxNQUFNLEdBQ1YsTUFBTSxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUUsTUFBZ0MsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUMvRixJQUFJLE9BQU8sTUFBTSxLQUFLLFVBQVU7UUFBRSxPQUFPLE1BQTRCLENBQUM7SUFDdEUsTUFBTSxJQUFJLFNBQVMsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO0FBQ2hFLENBQUM7QUFFRCxNQUFNLGNB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QUFNLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzdELE9BQU8sQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZCLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHNwYXduLCB0eXBlIENoaWxkUHJvY2VzcyB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IGNsb3NlU3luYywgb3BlblN5bmMgfSBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHsgYXBwZW5kRmlsZSwgbWtkaXIgfSBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHsgZGlybmFtZSwgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcblxuaW1wb3J0ICogYXMgc3lzdHJheU1vZHVsZSBmcm9tIFwic3lzdHJheTJcIjtcbmltcG9ydCB0eXBlIFN5c1RyYXlUeXBlIGZyb20gXCJzeXN0cmF5MlwiO1xuaW1wb3J0IHR5cGUgeyBNZW51SXRlbSB9IGZyb20gXCJzeXN0cmF5MlwiO1xuXG5pbXBvcnQgeyByZWFkU2VydmljZURlZmluaXRpb24gfSBmcm9tIFwiLi9fY29uZmlnLnRzXCI7XG5pbXBvcnQge1xuICBjbG9zZVNlcnZpY2VDb250cm9sLFxuICBsaXN0ZW5Gb3JTZXJ2aWNlQ29udHJvbCxcbiAgdHlwZSBTZXJ2aWNlQ29udHJvbFJlc3BvbnNlLFxufSBmcm9tIFwiLi9fY29udHJvbC50c1wiO1xuaW1wb3J0IHsgZGVmYXVsdFJ1bnRpbWVDb250ZXh0LCByZXNvbHZlU2VydmljZVBhdGhzLCB0eXBlIFNlcnZpY2VQYXRocyB9IGZyb20gXCIuL19wYXRocy50c1wiO1xuaW1wb3J0IHR5cGUgeyBDbGlTZXJ2aWNlQ29tbWFuZCwgQ2xpU2VydmljZURlZmluaXRpb24sIENsaVNlcnZpY2VNZW51SXRlbSB9IGZyb20gXCIuL2RlZmluaXRpb24udHNcIjtcblxuY29uc3QgQ0hJTERfU1RPUF9USU1FT1VUX01JTExJU0VDT05EUyA9IDVfMDAwO1xuY29uc3QgU3lzVHJheSA9IHN5c3RyYXlDb25zdHJ1Y3RvcigpO1xuXG5pbnRlcmZhY2UgQWN0aW9uTWVudUl0ZW0gZXh0ZW5kcyBNZW51SXRlbSB7XG4gIHJlYWRvbmx5IGNsaWNrPzogKCkgPT4gdm9pZDtcbn1cblxuZnVuY3Rpb24gc3lzdHJheUNvbnN0cnVjdG9yKCk6IHR5cGVvZiBTeXNUcmF5VHlwZSB7XG4gIGNvbnN0IGxvYWRlZDogdW5rbm93biA9IHN5c3RyYXlNb2R1bGUuZGVmYXVsdDtcbiAgaWYgKHR5cGVvZiBsb2FkZWQgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIGxvYWRlZCBhcyB0eXBlb2YgU3lzVHJheVR5cGU7XG4gIGNvbnN0IG5lc3RlZCA9XG4gICAgbG9hZGVkICYmIHR5cGVvZiBsb2FkZWQgPT09IFwib2JqZWN0XCIgPyAobG9hZGVkIGFzIHsgZGVmYXVsdD86IHVua25vd24gfSkuZGVmYXVsdCA6IHVuZGVmaW5lZDtcbiAgaWYgKHR5cGVvZiBuZXN0ZWQgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIG5lc3RlZCBhcyB0eXBlb2YgU3lzVHJheVR5cGU7XG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXCJzeXN0cmF5MiBkaWQgbm90IHByb3ZpZGUgYSBjb25zdHJ1Y3RvclwiKTtcbn1cblxuY2xhc3MgQ2xpU2VydmljZUhvc3Qge1xuICBwcml2YXRlIHJlYWRvbmx5IGRlZmluaXRpb246IENsaVNlcnZpY2VEZWZpbml0aW9uO1xuICBwcml2YXRlIHJlYWRvbmx5IHBhdGhzOiBTZXJ2aWNlUGF0aHM7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVxdWVzdFN0b3A6ICgpID0+IHZvaWQ7XG4gIHByaXZhdGUgdHJheT86IFN5c1RyYXlUeXBlO1xuICBwcml2YXRlIHNlcnZpY2U/OiBDaGlsZFByb2Nlc3M7XG4gIHByaXZhdGUgY29udHJvbD86IEF3YWl0ZWQ8UmV0dXJuVHlwZTx0eXBlb2YgbGlzdGVuRm9yU2VydmljZUNvbnRyb2w+PjtcbiAgcHJpdmF0ZSBzdG9wcGluZyA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKGRlZmluaXRpb246IENsaVNlcnZpY2VEZWZpbml0aW9uLCBwYXRoczogU2VydmljZVBhdGhzLCByZXF1ZXN0U3RvcDogKCkgPT4gdm9pZCkge1xuICAgIHRoaXMuZGVmaW5pdGlvbiA9IGRlZmluaXRpb247XG4gICAgdGhpcy5wYXRocyA9IHBhdGhzO1xuICAgIHRoaXMucmVxdWVzdFN0b3AgPSByZXF1ZXN0U3RvcDtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IG1rZGlyKHRoaXMucGF0aHMuZGlyZWN0b3J5LCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICB0aGlzLnNlcnZpY2UgPSB0aGlzLmRlZmluaXRpb24uY29tbWFuZFxuICAgICAgPyB0aGlzLnN0YXJ0UHJvY2Vzcyh0aGlzLmRlZmluaXRpb24uY29tbWFuZCwgdHJ1ZSlcbiAgICAgIDogdW5kZWZpbmVkO1xuICAgIHRoaXMudHJheSA9IHRoaXMuY3JlYXRlVHJheSgpO1xuICAgIGF3YWl0IHRoaXMudHJheS5yZWFkeSgpO1xuICAgIHRoaXMudHJheS5vbkVycm9yKChlcnJvcikgPT4ge1xuICAgICAgdm9pZCBsb2dFcnJvcih0aGlzLnBhdGhzLmhvc3RMb2csIGVycm9yKTtcbiAgICAgIHRoaXMucmVxdWVzdFN0b3AoKTtcbiAgICB9KTtcbiAgICB0aGlzLnRyYXkub25FeGl0KChjb2RlLCBzaWduYWwpID0+IHtcbiAgICAgIGlmICh0aGlzLnN0b3BwaW5nKSByZXR1cm47XG4gICAgICB2b2lkIGxvZ01lc3NhZ2UodGhpcy5wYXRocy5ob3N0TG9nLCBgc3lzdGVtIHRyYXkgZXhpdGVkICgke3NpZ25hbCA/PyBTdHJpbmcoY29kZSl9KWApO1xuICAgICAgdGhpcy5yZXF1ZXN0U3RvcCgpO1xuICAgIH0pO1xuICAgIGF3YWl0IHRoaXMudHJheS5vbkNsaWNrKChhY3Rpb24pID0+IHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBhY3Rpb24uaXRlbSBhcyBBY3Rpb25NZW51SXRlbTtcbiAgICAgIGl0ZW0uY2xpY2s/LigpO1xuICAgIH0pO1xuICAgIHRoaXMuY29udHJvbCA9IGF3YWl0IGxpc3RlbkZvclNlcnZpY2VDb250cm9sKFxuICAgICAgdGhpcy5wYXRocy5jb250cm9sQWRkcmVzcyxcbiAgICAgICgpID0+IHRoaXMuc3RhdHVzKCksXG4gICAgICB0aGlzLnJlcXVlc3RTdG9wLFxuICAgICk7XG4gIH1cblxuICBhc3luYyBzdG9wKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLnN0b3BwaW5nKSByZXR1cm47XG4gICAgdGhpcy5zdG9wcGluZyA9IHRydWU7XG4gICAgaWYgKHRoaXMuY29udHJvbCkge1xuICAgICAgYXdhaXQgY2xvc2VTZXJ2aWNlQ29udHJvbCh0aGlzLmNvbnRyb2wsIHRoaXMucGF0aHMuY29udHJvbEFkZHJlc3MpO1xuICAgICAgdGhpcy5jb250cm9sID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBpZiAodGhpcy50cmF5KSB7XG4gICAgICBpZiAodGhpcy50cmF5LnByb2Nlc3MuZXhpdENvZGUgPT09IG51bGwgJiYgdGhpcy50cmF5LnByb2Nlc3Muc2lnbmFsQ29kZSA9PT0gbnVsbCkge1xuICAgICAgICBhd2FpdCB0aGlzLnRyYXkua2lsbChmYWxzZSk7XG4gICAgICB9XG4gICAgICB0aGlzLnRyYXkgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGlmICh0aGlzLnNlcnZpY2UpIHtcbiAgICAgIGF3YWl0IHN0b3BQcm9jZXNzKHRoaXMuc2VydmljZSk7XG4gICAgICB0aGlzLnNlcnZpY2UgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0dXMoKTogU2VydmljZUNvbnRyb2xSZXNwb25zZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHJ1bm5pbmc6IHRydWUsXG4gICAgICBwaWQ6IHByb2Nlc3MucGlkLFxuICAgICAgLi4uKHRoaXMuc2VydmljZT8ucGlkID8geyBzZXJ2aWNlUGlkOiB0aGlzLnNlcnZpY2UucGlkIH0gOiB7fSksXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhcnRQcm9jZXNzKGNvbW1hbmQ6IENsaVNlcnZpY2VDb21tYW5kLCBtYW5hZ2VkOiBib29sZWFuKTogQ2hpbGRQcm9jZXNzIHtcbiAgICBpZiAoIWNvbW1hbmQuZXhlY3V0YWJsZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW5zdGFsbGVkIHNlcnZpY2UgY29tbWFuZHMgcmVxdWlyZSBhbiBleGVjdXRhYmxlXCIpO1xuICAgIH1cbiAgICBjb25zdCBsb2dEZXNjcmlwdG9yID0gb3BlblN5bmModGhpcy5wYXRocy5wcm9jZXNzTG9nLCBcImFcIik7XG4gICAgY29uc3QgY2hpbGQgPSBzcGF3bihjb21tYW5kLmV4ZWN1dGFibGUsIGNvbW1hbmQuYXJndW1lbnRzID8/IFtdLCB7XG4gICAgICBjd2Q6IGNvbW1hbmQuY3dkLFxuICAgICAgZW52OiB7IC4uLnByb2Nlc3MuZW52LCAuLi5jb21tYW5kLmVudmlyb25tZW50IH0sXG4gICAgICBzdGRpbzogW1wiaWdub3JlXCIsIGxvZ0Rlc2NyaXB0b3IsIGxvZ0Rlc2NyaXB0b3JdLFxuICAgIH0pO1xuICAgIGNsb3NlU3luYyhsb2dEZXNjcmlwdG9yKTtcbiAgICBjaGlsZC5vbmNlKFwiZXJyb3JcIiwgKGVycm9yKSA9PiB7XG4gICAgICB2b2lkIGxvZ0Vycm9yKHRoaXMucGF0aHMuaG9zdExvZywgZXJyb3IpO1xuICAgICAgaWYgKG1hbmFnZWQpIHRoaXMucmVxdWVzdFN0b3AoKTtcbiAgICB9KTtcbiAgICBjaGlsZC5vbmNlKFwiZXhpdFwiLCAoY29kZSwgc2lnbmFsKSA9PiB7XG4gICAgICBpZiAoIXRoaXMuc3RvcHBpbmcgJiYgbWFuYWdlZCkge1xuICAgICAgICB2b2lkIGxvZ01lc3NhZ2UodGhpcy5wYXRocy5ob3N0TG9nLCBgbWFuYWdlZCBzZXJ2aWNlIGV4aXRlZCAoJHtzaWduYWwgPz8gU3RyaW5nKGNvZGUpfSlgKTtcbiAgICAgICAgdGhpcy5yZXF1ZXN0U3RvcCgpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBjaGlsZDtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVHJheSgpOiBTeXNUcmF5VHlwZSB7XG4gICAgcmV0dXJuIG5ldyBTeXNUcmF5KHtcbiAgICAgIG1lbnU6IHtcbiAgICAgICAgaWNvbjogdGhpcy5kZWZpbml0aW9uLmljb24sXG4gICAgICAgIHRpdGxlOiBcIlwiLFxuICAgICAgICB0b29sdGlwOiBgJHt0aGlzLmRlZmluaXRpb24ubmFtZX0gJHt0aGlzLmRlZmluaXRpb24udmVyc2lvbn1gLFxuICAgICAgICBpdGVtczogdGhpcy5tZW51SXRlbXMoKSxcbiAgICAgICAgaXNUZW1wbGF0ZUljb246IHRoaXMuZGVmaW5pdGlvbi5pc1RlbXBsYXRlSWNvbixcbiAgICAgIH0sXG4gICAgICBkZWJ1ZzogZmFsc2UsXG4gICAgICBjb3B5RGlyOiBmYWxzZSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbWVudUl0ZW1zKCk6IEFjdGlvbk1lbnVJdGVtW10ge1xuICAgIGNvbnN0IGN1c3RvbSA9ICh0aGlzLmRlZmluaXRpb24ubWVudSA/PyBbXSkubWFwKChpdGVtKSA9PiB0aGlzLm1lbnVJdGVtKGl0ZW0pKTtcbiAgICByZXR1cm4gW1xuICAgICAge1xuICAgICAgICB0aXRsZTogYCR7dGhpcy5kZWZpbml0aW9uLm5hbWV9IC0gJHt0aGlzLmRlZmluaXRpb24udmVyc2lvbn1gLFxuICAgICAgICB0b29sdGlwOiBcIlwiLFxuICAgICAgICBlbmFibGVkOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICAuLi5jdXN0b20sXG4gICAgICB7IC4uLlN5c1RyYXkuc2VwYXJhdG9yIH0sXG4gICAgICB7XG4gICAgICAgIHRpdGxlOiBcIlF1aXRcIixcbiAgICAgICAgdG9vbHRpcDogYFN0b3AgJHt0aGlzLmRlZmluaXRpb24ubmFtZX1gLFxuICAgICAgICBjbGljazogdGhpcy5yZXF1ZXN0U3RvcCxcbiAgICAgIH0sXG4gICAgXTtcbiAgfVxuXG4gIHByaXZhdGUgbWVudUl0ZW0oaXRlbTogQ2xpU2VydmljZU1lbnVJdGVtKTogQWN0aW9uTWVudUl0ZW0ge1xuICAgIGlmIChpdGVtLnR5cGUgPT09IFwic2VwYXJhdG9yXCIpIHJldHVybiB7IC4uLlN5c1RyYXkuc2VwYXJhdG9yIH07XG4gICAgaWYgKGl0ZW0udHlwZSA9PT0gXCJ1cmxcIikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdGl0bGU6IGl0ZW0ubGFiZWwsXG4gICAgICAgIHRvb2x0aXA6IGl0ZW0udXJsLFxuICAgICAgICBjbGljazogKCkgPT4ge1xuICAgICAgICAgIHRoaXMub3BlblVybChpdGVtLnVybCk7XG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgdGl0bGU6IGl0ZW0ubGFiZWwsXG4gICAgICB0b29sdGlwOiBcIlwiLFxuICAgICAgY2xpY2s6ICgpID0+IHtcbiAgICAgICAgY29uc3QgY2hpbGQgPSB0aGlzLnN0YXJ0UHJvY2VzcyhpdGVtLmNvbW1hbmQsIGZhbHNlKTtcbiAgICAgICAgY2hpbGQudW5yZWYoKTtcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgb3BlblVybCh1cmw6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGNvbW1hbmQgPVxuICAgICAgcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gXCJkYXJ3aW5cIlxuICAgICAgICA/IHsgZXhlY3V0YWJsZTogXCJvcGVuXCIsIGFyZ3VtZW50czogW3VybF0gfVxuICAgICAgICA6IHByb2Nlc3MucGxhdGZvcm0gPT09IFwid2luMzJcIlxuICAgICAgICAgID8ge1xuICAgICAgICAgICAgICBleGVjdXRhYmxlOiBcInJ1bmRsbDMyLmV4ZVwiLFxuICAgICAgICAgICAgICBhcmd1bWVudHM6IFtcInVybC5kbGwsRmlsZVByb3RvY29sSGFuZGxlclwiLCB1cmxdLFxuICAgICAgICAgICAgfVxuICAgICAgICAgIDogeyBleGVjdXRhYmxlOiBcInhkZy1vcGVuXCIsIGFyZ3VtZW50czogW3VybF0gfTtcbiAgICBjb25zdCBjaGlsZCA9IHRoaXMuc3RhcnRQcm9jZXNzKGNvbW1hbmQsIGZhbHNlKTtcbiAgICBjaGlsZC51bnJlZigpO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJ1bkNsaVNlcnZpY2VIb3N0KGNvbmZpZ0ZpbGU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICBwcm9jZXNzLmNoZGlyKGRpcm5hbWUocHJvY2Vzcy5leGVjUGF0aCkpO1xuICBjb25zdCBkZWZpbml0aW9uID0gYXdhaXQgcmVhZFNlcnZpY2VEZWZpbml0aW9uKGNvbmZpZ0ZpbGUpO1xuICBjb25zdCBydW50aW1lID0gZGVmYXVsdFJ1bnRpbWVDb250ZXh0KCk7XG4gIGNvbnN0IHBhdGhzID0gcmVzb2x2ZVNlcnZpY2VQYXRocyhkZWZpbml0aW9uLCBydW50aW1lKTtcbiAgbGV0IHJlcXVlc3RTdG9wOiAoKSA9PiB2b2lkID0gKCkgPT4ge307XG4gIGNvbnN0IHN0b3BwZWQgPSBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgIHJlcXVlc3RTdG9wID0gcmVzb2x2ZTtcbiAgfSk7XG4gIGNvbnN0IGhvc3QgPSBuZXcgQ2xpU2VydmljZUhvc3QoZGVmaW5pdGlvbiwgcGF0aHMsIHJlcXVlc3RTdG9wKTtcbiAgcHJvY2Vzcy5vbmNlKFwiU0lHSU5UXCIsIHJlcXVlc3RTdG9wKTtcbiAgcHJvY2Vzcy5vbmNlKFwiU0lHVEVSTVwiLCByZXF1ZXN0U3RvcCk7XG4gIHRyeSB7XG4gICAgYXdhaXQgaG9zdC5zdGFydCgpO1xuICAgIGF3YWl0IHN0b3BwZWQ7XG4gIH0gZmluYWxseSB7XG4gICAgYXdhaXQgaG9zdC5zdG9wKCk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gc3RvcFByb2Nlc3MoY2hpbGQ6IENoaWxkUHJvY2Vzcyk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoY2hpbGQuZXhpdENvZGUgIT09IG51bGwgfHwgY2hpbGQuc2lnbmFsQ29kZSAhPT0gbnVsbCkgcmV0dXJuO1xuICBjb25zdCBleGl0ZWQgPSBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4gY2hpbGQub25jZShcImV4aXRcIiwgKCkgPT4gcmVzb2x2ZSgpKSk7XG4gIGNoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuICBjb25zdCB0aW1lZE91dCA9IG5ldyBQcm9taXNlPFwidGltZW91dFwiPigocmVzb2x2ZSkgPT4ge1xuICAgIHNldFRpbWVvdXQoKCkgPT4gcmVzb2x2ZShcInRpbWVvdXRcIiksIENISUxEX1NUT1BfVElNRU9VVF9NSUxMSVNFQ09ORFMpO1xuICB9KTtcbiAgaWYgKChhd2FpdCBQcm9taXNlLnJhY2UoW2V4aXRlZCwgdGltZWRPdXRdKSkgPT09IFwidGltZW91dFwiKSB7XG4gICAgY2hpbGQua2lsbChcIlNJR0tJTExcIik7XG4gICAgYXdhaXQgZXhpdGVkO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGxvZ0Vycm9yKHBhdGg6IHN0cmluZywgZXJyb3I6IHVua25vd24pOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgbG9nTWVzc2FnZShwYXRoLCBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gKGVycm9yLnN0YWNrID8/IGVycm9yLm1lc3NhZ2UpIDogU3RyaW5nKGVycm9yKSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGxvZ01lc3NhZ2UocGF0aDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgbWtkaXIoZGlybmFtZShwYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIGF3YWl0IGFwcGVuZEZpbGUocGF0aCwgYCR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpfSAke21lc3NhZ2V9XFxuYCwgXCJ1dGY4XCIpO1xufVxuXG5mdW5jdGlvbiBhcmd1bWVudFZhbHVlKG5hbWU6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGluZGV4ID0gcHJvY2Vzcy5hcmd2LmluZGV4T2YobmFtZSk7XG4gIHJldHVybiBpbmRleCA+PSAwID8gcHJvY2Vzcy5hcmd2W2luZGV4ICsgMV0gOiB1bmRlZmluZWQ7XG59XG5cbmNvbnN0IGNvbmZpZ0ZpbGUgPSBhcmd1bWVudFZhbHVlKFwiLS1zZXJ2aWNlLWNvbmZpZ1wiKTtcbmlmIChjb25maWdGaWxlKSB7XG4gIHZvaWQgcnVuQ2xpU2VydmljZUhvc3QoY29uZmlnRmlsZSkuY2F0Y2goYXN5bmMgKGVycm9yOiB1bmtub3duKSA9PiB7XG4gICAgYXdhaXQgbG9nRXJyb3Ioam9pbihkaXJuYW1lKGNvbmZpZ0ZpbGUpLCBcImhvc3QubG9nXCIpLCBlcnJvcik7XG4gICAgcHJvY2Vzcy5leGl0Q29kZSA9IDE7XG4gIH0pO1xufVxuIl19
@@ -0,0 +1,12 @@
1
+ export interface ServicePackage {
2
+ readonly directory: string;
3
+ readonly name: string;
4
+ readonly version: string;
5
+ bin(name?: string): string;
6
+ dependencies(): Readonly<Record<string, string>>;
7
+ }
8
+ export declare function resolveServicePackage(reference: string, cwd?: string): ServicePackage;
9
+ export declare function servicePackageDefaults(pkg: ServicePackage): {
10
+ id: string;
11
+ name: string;
12
+ };
@@ -0,0 +1,140 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import { dirname, isAbsolute, join, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import * as projectUtils from "@dbx-tools/core/project-utils";
6
+ export function resolveServicePackage(reference, cwd = process.cwd()) {
7
+ const local = localManifest(reference);
8
+ if (local)
9
+ return servicePackage(local);
10
+ const name = reference;
11
+ const installed = installedManifest(name);
12
+ if (installed)
13
+ return servicePackage(installed, name);
14
+ const root = projectUtils.root(cwd);
15
+ if (!root)
16
+ throw new Error(`could not resolve package: ${name}`);
17
+ const manifest = readRecord(join(root, "package.json"));
18
+ const workspaces = Array.isArray(manifest.workspaces) ? manifest.workspaces : [];
19
+ for (const member of workspaces) {
20
+ if (typeof member !== "string" || /[*?[\]{}]/.test(member))
21
+ continue;
22
+ const path = join(root, member, "package.json");
23
+ if (!existsSync(path))
24
+ continue;
25
+ const candidate = readRecord(path);
26
+ if (candidate.name === name)
27
+ return servicePackage(path, name);
28
+ }
29
+ throw new Error(`could not resolve installed or workspace package: ${name}`);
30
+ }
31
+ export function servicePackageDefaults(pkg) {
32
+ const segments = pkg.name.replace(/^@/, "").split("/");
33
+ const rawName = segments.at(-1);
34
+ const rawScope = segments.length > 1 ? segments[0].split("-")[0] : "";
35
+ const name = rawName.replace(/^cli-/, "").replaceAll("-", " ");
36
+ return {
37
+ id: pkg.name
38
+ .replace(/^@/, "")
39
+ .replaceAll("/", ".")
40
+ .replace(/[^a-z0-9._-]+/gi, "-"),
41
+ name: [rawScope, name].filter(Boolean).join(" "),
42
+ };
43
+ }
44
+ function localManifest(reference) {
45
+ let path;
46
+ if (reference.startsWith("file:")) {
47
+ path = fileURLToPath(reference);
48
+ }
49
+ else if (isAbsolute(reference)) {
50
+ path = reference;
51
+ }
52
+ else {
53
+ return undefined;
54
+ }
55
+ let current = existsSync(path) ? dirname(path) : path;
56
+ while (true) {
57
+ const manifest = join(current, "package.json");
58
+ if (existsSync(manifest))
59
+ return manifest;
60
+ const parent = dirname(current);
61
+ if (parent === current)
62
+ return undefined;
63
+ current = parent;
64
+ }
65
+ }
66
+ function installedManifest(name) {
67
+ try {
68
+ return createRequire(import.meta.url).resolve(`${name}/package.json`);
69
+ }
70
+ catch (error) {
71
+ if (error.code === "MODULE_NOT_FOUND")
72
+ return undefined;
73
+ throw error;
74
+ }
75
+ }
76
+ function servicePackage(manifestPath, expectedName) {
77
+ const manifest = readRecord(manifestPath);
78
+ if (typeof manifest.name !== "string" || !manifest.name) {
79
+ throw new Error(`package has no name: ${manifestPath}`);
80
+ }
81
+ if (expectedName && manifest.name !== expectedName) {
82
+ throw new Error(`resolved package name does not match ${expectedName}: ${manifestPath}`);
83
+ }
84
+ if (typeof manifest.version !== "string" || !manifest.version) {
85
+ throw new Error(`package has no version: ${manifestPath}`);
86
+ }
87
+ const directory = dirname(manifestPath);
88
+ return {
89
+ directory,
90
+ name: manifest.name,
91
+ version: manifest.version,
92
+ bin(name) {
93
+ return resolveBin(directory, manifest.bin, name);
94
+ },
95
+ dependencies() {
96
+ const dependencies = isRecord(manifest.dependencies)
97
+ ? Object.keys(manifest.dependencies)
98
+ : [];
99
+ const require = createRequire(manifestPath);
100
+ return Object.fromEntries(dependencies.map((dependency) => {
101
+ const path = require.resolve(`${dependency}/package.json`);
102
+ const resolved = readRecord(path);
103
+ if (typeof resolved.version !== "string" || !resolved.version) {
104
+ throw new Error(`dependency has no version: ${path}`);
105
+ }
106
+ return [dependency, resolved.version];
107
+ }));
108
+ },
109
+ };
110
+ }
111
+ function resolveBin(directory, value, name) {
112
+ if (typeof value === "string") {
113
+ if (name)
114
+ throw new Error(`package exposes one unnamed bin, not ${name}`);
115
+ return resolve(directory, value);
116
+ }
117
+ if (!isRecord(value))
118
+ throw new Error("package has no bin");
119
+ if (name) {
120
+ const target = value[name];
121
+ if (typeof target !== "string")
122
+ throw new Error(`package has no bin named ${name}`);
123
+ return resolve(directory, target);
124
+ }
125
+ const targets = Object.values(value).filter((target) => typeof target === "string");
126
+ if (targets.length !== 1) {
127
+ throw new Error("package has multiple bins; command.binName is required");
128
+ }
129
+ return resolve(directory, targets[0]);
130
+ }
131
+ function readRecord(path) {
132
+ const value = JSON.parse(readFileSync(path, "utf8"));
133
+ if (!isRecord(value))
134
+ throw new Error(`package manifest is not an object: ${path}`);
135
+ return value;
136
+ }
137
+ function isRecord(value) {
138
+ return value !== null && typeof value === "object" && !Array.isArray(value);
139
+ }
140
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX3BhY2thZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvX3BhY2thZ2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDbkQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM1QyxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQy9ELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFekMsT0FBTyxLQUFLLFlBQVksTUFBTSwrQkFBK0IsQ0FBQztBQVU5RCxNQUFNLFVBQVUscUJBQXFCLENBQ25DLFNBQWlCLEVBQ2pCLE1BQWMsT0FBTyxDQUFDLEdBQUcsRUFBRTtJQUUzQixNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDdkMsSUFBSSxLQUFLO1FBQUUsT0FBTyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFeEMsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDO0lBQ3ZCLE1BQU0sU0FBUyxHQUFHLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzFDLElBQUksU0FBUztRQUFFLE9BQU8sY0FBYyxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUV0RCxNQUFNLElBQUksR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3BDLElBQUksQ0FBQyxJQUFJO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUNqRSxNQUFNLFFBQVEsR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxjQUFjLENBQUMsQ0FBQyxDQUFDO0lBQ3hELE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxD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QUFPLEtBQUssS0FBSyxJQUFJLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM5RSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhpc3RzU3luYywgcmVhZEZpbGVTeW5jIH0gZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tIFwibm9kZTptb2R1bGVcIjtcbmltcG9ydCB7IGRpcm5hbWUsIGlzQWJzb2x1dGUsIGpvaW4sIHJlc29sdmUgfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBmaWxlVVJMVG9QYXRoIH0gZnJvbSBcIm5vZGU6dXJsXCI7XG5cbmltcG9ydCAqIGFzIHByb2plY3RVdGlscyBmcm9tIFwiQGRieC10b29scy9jb3JlL3Byb2plY3QtdXRpbHNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBTZXJ2aWNlUGFja2FnZSB7XG4gIHJlYWRvbmx5IGRpcmVjdG9yeTogc3RyaW5nO1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHZlcnNpb246IHN0cmluZztcbiAgYmluKG5hbWU/OiBzdHJpbmcpOiBzdHJpbmc7XG4gIGRlcGVuZGVuY2llcygpOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+Pjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVTZXJ2aWNlUGFja2FnZShcbiAgcmVmZXJlbmNlOiBzdHJpbmcsXG4gIGN3ZDogc3RyaW5nID0gcHJvY2Vzcy5jd2QoKSxcbik6IFNlcnZpY2VQYWNrYWdlIHtcbiAgY29uc3QgbG9jYWwgPSBsb2NhbE1hbmlmZXN0KHJlZmVyZW5jZSk7XG4gIGlmIChsb2NhbCkgcmV0dXJuIHNlcnZpY2VQYWNrYWdlKGxvY2FsKTtcblxuICBjb25zdCBuYW1lID0gcmVmZXJlbmNlO1xuICBjb25zdCBpbnN0YWxsZWQgPSBpbnN0YWxsZWRNYW5pZmVzdChuYW1lKTtcbiAgaWYgKGluc3RhbGxlZCkgcmV0dXJuIHNlcnZpY2VQYWNrYWdlKGluc3RhbGxlZCwgbmFtZSk7XG5cbiAgY29uc3Qgcm9vdCA9IHByb2plY3RVdGlscy5yb290KGN3ZCk7XG4gIGlmICghcm9vdCkgdGhyb3cgbmV3IEVycm9yKGBjb3VsZCBub3QgcmVzb2x2ZSBwYWNrYWdlOiAke25hbWV9YCk7XG4gIGNvbnN0IG1hbmlmZXN0ID0gcmVhZFJlY29yZChqb2luKHJvb3QsIFwicGFja2FnZS5qc29uXCIpKTtcbiAgY29uc3Qgd29ya3NwYWNlcyA9IEFycmF5LmlzQXJyYXkobWFuaWZlc3Qud29ya3NwYWNlcykgPyBtYW5pZmVzdC53b3Jrc3BhY2VzIDogW107XG4gIGZvciAoY29uc3QgbWVtYmVyIG9mIHdvcmtzcGFjZXMpIHtcbiAgICBpZiAodHlwZW9mIG1lbWJlciAhPT0gXCJzdHJpbmdcIiB8fCAvWyo/W1xcXXt9XS8udGVzdChtZW1iZXIpKSBjb250aW51ZTtcbiAgICBjb25zdCBwYXRoID0gam9pbihyb290LCBtZW1iZXIsIFwicGFja2FnZS5qc29uXCIpO1xuICAgIGlmICghZXhpc3RzU3luYyhwYXRoKSkgY29udGludWU7XG4gICAgY29uc3QgY2FuZGlkYXRlID0gcmVhZFJlY29yZChwYXRoKTtcbiAgICBpZiAoY2FuZGlkYXRlLm5hbWUgPT09IG5hbWUpIHJldHVybiBzZXJ2aWNlUGFja2FnZShwYXRoLCBuYW1lKTtcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoYGNvdWxkIG5vdCByZXNvbHZlIGluc3RhbGxlZCBvciB3b3Jrc3BhY2UgcGFja2FnZTogJHtuYW1lfWApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2VydmljZVBhY2thZ2VEZWZhdWx0cyhwa2c6IFNlcnZpY2VQYWNrYWdlKToge1xuICBpZDogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG59IHtcbiAgY29uc3Qgc2VnbWVudHMgPSBwa2cubmFtZS5yZXBsYWNlKC9eQC8sIFwiXCIpLnNwbGl0KFwiL1wiKTtcbiAgY29uc3QgcmF3TmFtZSA9IHNlZ21lbnRzLmF0KC0xKSE7XG4gIGNvbnN0IHJhd1Njb3BlID0gc2VnbWVudHMubGVuZ3RoID4gMSA/IHNlZ21lbnRzWzBdIS5zcGxpdChcIi1cIilbMF0hIDogXCJcIjtcbiAgY29uc3QgbmFtZSA9IHJhd05hbWUucmVwbGFjZSgvXmNsaS0vLCBcIlwiKS5yZXBsYWNlQWxsKFwiLVwiLCBcIiBcIik7XG4gIHJldHVybiB7XG4gICAgaWQ6IHBrZy5uYW1lXG4gICAgICAucmVwbGFjZSgvXkAvLCBcIlwiKVxuICAgICAgLnJlcGxhY2VBbGwoXCIvXCIsIFwiLlwiKVxuICAgICAgLnJlcGxhY2UoL1teYS16MC05Ll8tXSsvZ2ksIFwiLVwiKSxcbiAgICBuYW1lOiBbcmF3U2NvcGUsIG5hbWVdLmZpbHRlcihCb29sZWFuKS5qb2luKFwiIFwiKSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbG9jYWxNYW5pZmVzdChyZWZlcmVuY2U6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGxldCBwYXRoOiBzdHJpbmc7XG4gIGlmIChyZWZlcmVuY2Uuc3RhcnRzV2l0aChcImZpbGU6XCIpKSB7XG4gICAgcGF0aCA9IGZpbGVVUkxUb1BhdGgocmVmZXJlbmNlKTtcbiAgfSBlbHNlIGlmIChpc0Fic29sdXRlKHJlZmVyZW5jZSkpIHtcbiAgICBwYXRoID0gcmVmZXJlbmNlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgbGV0IGN1cnJlbnQgPSBleGlzdHNTeW5jKHBhdGgpID8gZGlybmFtZShwYXRoKSA6IHBhdGg7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgY29uc3QgbWFuaWZlc3QgPSBqb2luKGN1cnJlbnQsIFwicGFja2FnZS5qc29uXCIpO1xuICAgIGlmIChleGlzdHNTeW5jKG1hbmlmZXN0KSkgcmV0dXJuIG1hbmlmZXN0O1xuICAgIGNvbnN0IHBhcmVudCA9IGRpcm5hbWUoY3VycmVudCk7XG4gICAgaWYgKHBhcmVudCA9PT0gY3VycmVudCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBjdXJyZW50ID0gcGFyZW50O1xuICB9XG59XG5cbmZ1bmN0aW9uIGluc3RhbGxlZE1hbmlmZXN0KG5hbWU6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGNyZWF0ZVJlcXVpcmUoaW1wb3J0Lm1ldGEudXJsKS5yZXNvbHZlKGAke25hbWV9L3BhY2thZ2UuanNvbmApO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmICgoZXJyb3IgYXMgTm9kZUpTLkVycm5vRXhjZXB0aW9uKS5jb2RlID09PSBcIk1PRFVMRV9OT1RfRk9VTkRcIikgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuXG5mdW5jdGlvbiBzZXJ2aWNlUGFja2FnZShtYW5pZmVzdFBhdGg6IHN0cmluZywgZXhwZWN0ZWROYW1lPzogc3RyaW5nKTogU2VydmljZVBhY2thZ2Uge1xuICBjb25zdCBtYW5pZmVzdCA9IHJlYWRSZWNvcmQobWFuaWZlc3RQYXRoKTtcbiAgaWYgKHR5cGVvZiBtYW5pZmVzdC5uYW1lICE9PSBcInN0cmluZ1wiIHx8ICFtYW5pZmVzdC5uYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBwYWNrYWdlIGhhcyBubyBuYW1lOiAke21hbmlmZXN0UGF0aH1gKTtcbiAgfVxuICBpZiAoZXhwZWN0ZWROYW1lICYmIG1hbmlmZXN0Lm5hbWUgIT09IGV4cGVjdGVkTmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgcmVzb2x2ZWQgcGFja2FnZSBuYW1lIGRvZXMgbm90IG1hdGNoICR7ZXhwZWN0ZWROYW1lfTogJHttYW5pZmVzdFBhdGh9YCk7XG4gIH1cbiAgaWYgKHR5cGVvZiBtYW5pZmVzdC52ZXJzaW9uICE9PSBcInN0cmluZ1wiIHx8ICFtYW5pZmVzdC52ZXJzaW9uKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBwYWNrYWdlIGhhcyBubyB2ZXJzaW9uOiAke21hbmlmZXN0UGF0aH1gKTtcbiAgfVxuICBjb25zdCBkaXJlY3RvcnkgPSBkaXJuYW1lKG1hbmlmZXN0UGF0aCk7XG4gIHJldHVybiB7XG4gICAgZGlyZWN0b3J5LFxuICAgIG5hbWU6IG1hbmlmZXN0Lm5hbWUsXG4gICAgdmVyc2lvbjogbWFuaWZlc3QudmVyc2lvbixcbiAgICBiaW4obmFtZSkge1xuICAgICAgcmV0dXJuIHJlc29sdmVCaW4oZGlyZWN0b3J5LCBtYW5pZmVzdC5iaW4sIG5hbWUpO1xuICAgIH0sXG4gICAgZGVwZW5kZW5jaWVzKCkge1xuICAgICAgY29uc3QgZGVwZW5kZW5jaWVzID0gaXNSZWNvcmQobWFuaWZlc3QuZGVwZW5kZW5jaWVzKVxuICAgICAgICA/IE9iamVjdC5rZXlzKG1hbmlmZXN0LmRlcGVuZGVuY2llcylcbiAgICAgICAgOiBbXTtcbiAgICAgIGNvbnN0IHJlcXVpcmUgPSBjcmVhdGVSZXF1aXJlKG1hbmlmZXN0UGF0aCk7XG4gICAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICBkZXBlbmRlbmNpZXMubWFwKChkZXBlbmRlbmN5KSA9PiB7XG4gICAgICAgICAgY29uc3QgcGF0aCA9IHJlcXVpcmUucmVzb2x2ZShgJHtkZXBlbmRlbmN5fS9wYWNrYWdlLmpzb25gKTtcbiAgICAgICAgICBjb25zdCByZXNvbHZlZCA9IHJlYWRSZWNvcmQocGF0aCk7XG4gICAgICAgICAgaWYgKHR5cGVvZiByZXNvbHZlZC52ZXJzaW9uICE9PSBcInN0cmluZ1wiIHx8ICFyZXNvbHZlZC52ZXJzaW9uKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGRlcGVuZGVuY3kgaGFzIG5vIHZlcnNpb246ICR7cGF0aH1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFtkZXBlbmRlbmN5LCByZXNvbHZlZC52ZXJzaW9uXTtcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVCaW4oZGlyZWN0b3J5OiBzdHJpbmcsIHZhbHVlOiB1bmtub3duLCBuYW1lPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIikge1xuICAgIGlmIChuYW1lKSB0aHJvdyBuZXcgRXJyb3IoYHBhY2thZ2UgZXhwb3NlcyBvbmUgdW5uYW1lZCBiaW4sIG5vdCAke25hbWV9YCk7XG4gICAgcmV0dXJuIHJlc29sdmUoZGlyZWN0b3J5LCB2YWx1ZSk7XG4gIH1cbiAgaWYgKCFpc1JlY29yZCh2YWx1ZSkpIHRocm93IG5ldyBFcnJvcihcInBhY2thZ2UgaGFzIG5vIGJpblwiKTtcbiAgaWYgKG5hbWUpIHtcbiAgICBjb25zdCB0YXJnZXQgPSB2YWx1ZVtuYW1lXTtcbiAgICBpZiAodHlwZW9mIHRhcmdldCAhPT0gXCJzdHJpbmdcIikgdGhyb3cgbmV3IEVycm9yKGBwYWNrYWdlIGhhcyBubyBiaW4gbmFtZWQgJHtuYW1lfWApO1xuICAgIHJldHVybiByZXNvbHZlKGRpcmVjdG9yeSwgdGFyZ2V0KTtcbiAgfVxuICBjb25zdCB0YXJnZXRzID0gT2JqZWN0LnZhbHVlcyh2YWx1ZSkuZmlsdGVyKFxuICAgICh0YXJnZXQpOiB0YXJnZXQgaXMgc3RyaW5nID0+IHR5cGVvZiB0YXJnZXQgPT09IFwic3RyaW5nXCIsXG4gICk7XG4gIGlmICh0YXJnZXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcInBhY2thZ2UgaGFzIG11bHRpcGxlIGJpbnM7IGNvbW1hbmQuYmluTmFtZSBpcyByZXF1aXJlZFwiKTtcbiAgfVxuICByZXR1cm4gcmVzb2x2ZShkaXJlY3RvcnksIHRhcmdldHNbMF0hKTtcbn1cblxuZnVuY3Rpb24gcmVhZFJlY29yZChwYXRoOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIGNvbnN0IHZhbHVlOiB1bmtub3duID0gSlNPTi5wYXJzZShyZWFkRmlsZVN5bmMocGF0aCwgXCJ1dGY4XCIpKTtcbiAgaWYgKCFpc1JlY29yZCh2YWx1ZSkpIHRocm93IG5ldyBFcnJvcihgcGFja2FnZSBtYW5pZmVzdCBpcyBub3QgYW4gb2JqZWN0OiAke3BhdGh9YCk7XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gaXNSZWNvcmQodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIHJldHVybiB2YWx1ZSAhPT0gbnVsbCAmJiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkodmFsdWUpO1xufVxuIl19
@@ -0,0 +1,17 @@
1
+ import type { CliServiceDefinition } from "./definition.ts";
2
+ export interface ServiceRuntimeContext {
3
+ readonly platform: NodeJS.Platform;
4
+ readonly environment: Readonly<NodeJS.ProcessEnv>;
5
+ readonly homeDirectory: string;
6
+ readonly temporaryDirectory: string;
7
+ }
8
+ export interface ServicePaths {
9
+ readonly directory: string;
10
+ readonly configFile: string;
11
+ readonly hostLog: string;
12
+ readonly processLog: string;
13
+ readonly controlAddress: string;
14
+ readonly startupFile: string;
15
+ }
16
+ export declare function defaultRuntimeContext(): ServiceRuntimeContext;
17
+ export declare function resolveServicePaths(definition: CliServiceDefinition, runtime: ServiceRuntimeContext): ServicePaths;
@@ -0,0 +1,55 @@
1
+ import { createHash } from "node:crypto";
2
+ import { homedir, tmpdir } from "node:os";
3
+ import { isAbsolute, join, resolve } from "node:path";
4
+ export function defaultRuntimeContext() {
5
+ return {
6
+ platform: process.platform,
7
+ environment: process.env,
8
+ homeDirectory: homedir(),
9
+ temporaryDirectory: tmpdir(),
10
+ };
11
+ }
12
+ export function resolveServicePaths(definition, runtime) {
13
+ const directory = definition.dataDirectory
14
+ ? resolve(definition.dataDirectory)
15
+ : join(configurationRoot(runtime), definition.id);
16
+ return {
17
+ directory,
18
+ configFile: join(directory, "service.json"),
19
+ hostLog: join(directory, "host.log"),
20
+ processLog: join(directory, "service.log"),
21
+ controlAddress: controlAddress(definition.id, runtime),
22
+ startupFile: startupFile(definition.id, runtime),
23
+ };
24
+ }
25
+ function configurationRoot(runtime) {
26
+ if (runtime.platform === "darwin") {
27
+ return join(runtime.homeDirectory, "Library", "Application Support");
28
+ }
29
+ if (runtime.platform === "win32") {
30
+ return resolveEnvironmentPath(runtime.environment.APPDATA, join(runtime.homeDirectory, "AppData", "Roaming"));
31
+ }
32
+ return resolveEnvironmentPath(runtime.environment.XDG_CONFIG_HOME, join(runtime.homeDirectory, ".config"));
33
+ }
34
+ function controlAddress(id, runtime) {
35
+ const token = createHash("sha256").update(id).digest("hex").slice(0, 16);
36
+ if (runtime.platform === "win32") {
37
+ return `\\\\.\\pipe\\dbx-tools-cli-service-${token}`;
38
+ }
39
+ return join(runtime.temporaryDirectory, `dbx-tools-cli-service-${token}.sock`);
40
+ }
41
+ function startupFile(id, runtime) {
42
+ if (runtime.platform === "darwin") {
43
+ return join(runtime.homeDirectory, "Library", "LaunchAgents", `${id}.plist`);
44
+ }
45
+ if (runtime.platform === "win32") {
46
+ return join(resolveEnvironmentPath(runtime.environment.APPDATA, join(runtime.homeDirectory, "AppData", "Roaming")), "Microsoft", "Windows", "Start Menu", "Programs", "Startup", `${id}.cmd`);
47
+ }
48
+ return join(resolveEnvironmentPath(runtime.environment.XDG_CONFIG_HOME, join(runtime.homeDirectory, ".config")), "autostart", `${id}.desktop`);
49
+ }
50
+ function resolveEnvironmentPath(value, fallback) {
51
+ if (!value)
52
+ return fallback;
53
+ return isAbsolute(value) ? value : resolve(value);
54
+ }
55
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX3BhdGhzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL19wYXRocy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQW9CdEQsTUFBTSxVQUFVLHFCQUFxQjtJQUNuQyxPQUFPO1FBQ0wsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRO1FBQzFCLFdBQVcsRUFBRSxPQUFPLENBQUMsR0FBRztRQUN4QixhQUFhLEVBQUUsT0FBTyxFQUFFO1FBQ3hCLGtCQUFrQixFQUFFLE1BQU0sRUFBRTtLQUM3QixDQUFDO0FBQ0osQ0FBQztBQUVELE1BQU0sVUFBVSxtQkFBbUIsQ0FDakMsVUFBZ0MsRUFDaEMsT0FBOEI7SUFFOUIsTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLGFBQWE7UUFDeEMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDO1FBQ25DLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLEVBQUUsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3BELE9BQU87UUFDTCxTQUFTO1FBQ1QsVUFBVSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsY0FBYyxDQUFDO1FBQzNDLE9BQU8sRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLFVBQVUsQ0FBQztRQUNwQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxhQUFhLENBQUM7UUFDMUMsY0FBYyxFQUFFLGNBQWMsQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFLE9BQU8sQ0FBQztRQUN0RCxXQUFXLEVBQUUsV0FBVyxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsT0FBTyxDQUFDO0tBQ2pELENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxpQkFBaUIsQ0FBQyxPQUE4QjtJQUN2RCxJQUFJLE9BQU8sQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDbEMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxTQUFTLEVBQUUscUJBQXFCLENBQUMsQ0FBQztJQUN2RSxDQUFDO0lBQ0QsSUFBSSxPQUFPLENBQUMsUUFBUSxLQUFLLE9BQU8sRUFBRSxDQUFDO1FBQ2pDLE9BQU8sc0JBQXNCLENBQzNCLE9BQU8sQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUMzQixJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQ2xELENBQUM7SUFDSixDQUFDO0lBQ0QsT0FBTyxzQkFBc0IsQ0FDM0IsT0FBTyxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQ25DLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLFNBQVMsQ0FBQyxDQUN2QyxDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsY0FBYyxDQUFDLEVBQVUsRUFBRSxPQUE4QjtJQUNoRSxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3pFLElBQUksT0FBTyxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUUsQ0FBQztRQUNqQyxPQUFPLHNDQUFzQyxLQUFLLEVBQUUsQ0FBQztJQUN2RCxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLGtCQUFrQixFQUFFLHlCQUF5QixLQUFLLE9BQU8sQ0FBQyxDQUFDO0FBQ2pGLENBQUM7QUFFRCxTQUFTLFdBQVcsQ0FBQyxFQUFVLEVBQUUsT0FBOEI7SUFDN0QsSUFBSSxPQUFPLENBQUMsUUFBUSxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ2xDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUNELElBQUksT0FBTyxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUUsQ0FBQztRQUNqQyxPQUFPLElBQUksQ0FDVCxzQkFBc0IsQ0FDcEIsT0FBTyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQzNCLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FDbEQsRUFDRCxXQUFXLEVBQ1gsU0FBUyxFQUNULFlBQVksRUFDWixVQUFVLEVBQ1YsU0FBUyxFQUNULEdBQUcsRUFBRSxNQUFNLENBQ1osQ0FBQztJQUNKLENBQUM7SUFDRCxPQUFPLElBQUksQ0FDVCxzQkFBc0IsQ0FDcEIsT0FBTyxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQ25DLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLFNBQVMsQ0FBQyxDQUN2QyxFQUNELFdBQVcsRUFDWCxHQUFHLEVBQUUsVUFBVSxDQUNoQixDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsc0JBQXNCLENBQUMsS0FBeUIsRUFBRSxRQUFnQjtJQUN6RSxJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sUUFBUSxDQUFDO0lBQzVCLE9BQU8sVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNwRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gXCJub2RlOmNyeXB0b1wiO1xuaW1wb3J0IHsgaG9tZWRpciwgdG1wZGlyIH0gZnJvbSBcIm5vZGU6b3NcIjtcbmltcG9ydCB7IGlzQWJzb2x1dGUsIGpvaW4sIHJlc29sdmUgfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5cbmltcG9ydCB0eXBlIHsgQ2xpU2VydmljZURlZmluaXRpb24gfSBmcm9tIFwiLi9kZWZpbml0aW9uLnRzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2VydmljZVJ1bnRpbWVDb250ZXh0IHtcbiAgcmVhZG9ubHkgcGxhdGZvcm06IE5vZGVKUy5QbGF0Zm9ybTtcbiAgcmVhZG9ubHkgZW52aXJvbm1lbnQ6IFJlYWRvbmx5PE5vZGVKUy5Qcm9jZXNzRW52PjtcbiAgcmVhZG9ubHkgaG9tZURpcmVjdG9yeTogc3RyaW5nO1xuICByZWFkb25seSB0ZW1wb3JhcnlEaXJlY3Rvcnk6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZXJ2aWNlUGF0aHMge1xuICByZWFkb25seSBkaXJlY3Rvcnk6IHN0cmluZztcbiAgcmVhZG9ubHkgY29uZmlnRmlsZTogc3RyaW5nO1xuICByZWFkb25seSBob3N0TG9nOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHByb2Nlc3NMb2c6IHN0cmluZztcbiAgcmVhZG9ubHkgY29udHJvbEFkZHJlc3M6IHN0cmluZztcbiAgcmVhZG9ubHkgc3RhcnR1cEZpbGU6IHN0cmluZztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlZmF1bHRSdW50aW1lQ29udGV4dCgpOiBTZXJ2aWNlUnVudGltZUNvbnRleHQge1xuICByZXR1cm4ge1xuICAgIHBsYXRmb3JtOiBwcm9jZXNzLnBsYXRmb3JtLFxuICAgIGVudmlyb25tZW50OiBwcm9jZXNzLmVudixcbiAgICBob21lRGlyZWN0b3J5OiBob21lZGlyKCksXG4gICAgdGVtcG9yYXJ5RGlyZWN0b3J5OiB0bXBkaXIoKSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVTZXJ2aWNlUGF0aHMoXG4gIGRlZmluaXRpb246IENsaVNlcnZpY2VEZWZpbml0aW9uLFxuICBydW50aW1lOiBTZXJ2aWNlUnVudGltZUNvbnRleHQsXG4pOiBTZXJ2aWNlUGF0aHMge1xuICBjb25zdCBkaXJlY3RvcnkgPSBkZWZpbml0aW9uLmRhdGFEaXJlY3RvcnlcbiAgICA/IHJlc29sdmUoZGVmaW5pdGlvbi5kYXRhRGlyZWN0b3J5KVxuICAgIDogam9pbihjb25maWd1cmF0aW9uUm9vdChydW50aW1lKSwgZGVmaW5pdGlvbi5pZCk7XG4gIHJldHVybiB7XG4gICAgZGlyZWN0b3J5LFxuICAgIGNvbmZpZ0ZpbGU6IGpvaW4oZGlyZWN0b3J5LCBcInNlcnZpY2UuanNvblwiKSxcbiAgICBob3N0TG9nOiBqb2luKGRpcmVjdG9yeSwgXCJob3N0LmxvZ1wiKSxcbiAgICBwcm9jZXNzTG9nOiBqb2luKGRpcmVjdG9yeSwgXCJzZXJ2aWNlLmxvZ1wiKSxcbiAgICBjb250cm9sQWRkcmVzczogY29udHJvbEFkZHJlc3MoZGVmaW5pdGlvbi5pZCwgcnVudGltZSksXG4gICAgc3RhcnR1cEZpbGU6IHN0YXJ0dXBGaWxlKGRlZmluaXRpb24uaWQsIHJ1bnRpbWUpLFxuICB9O1xufVxuXG5mdW5jdGlvbiBjb25maWd1cmF0aW9uUm9vdChydW50aW1lOiBTZXJ2aWNlUnVudGltZUNvbnRleHQpOiBzdHJpbmcge1xuICBpZiAocnVudGltZS5wbGF0Zm9ybSA9PT0gXCJkYXJ3aW5cIikge1xuICAgIHJldHVybiBqb2luKHJ1bnRpbWUuaG9tZURpcmVjdG9yeSwgXCJMaWJyYXJ5XCIsIFwiQXBwbGljYXRpb24gU3VwcG9ydFwiKTtcbiAgfVxuICBpZiAocnVudGltZS5wbGF0Zm9ybSA9PT0gXCJ3aW4zMlwiKSB7XG4gICAgcmV0dXJuIHJlc29sdmVFbnZpcm9ubWVudFBhdGgoXG4gICAgICBydW50aW1lLmVudmlyb25tZW50LkFQUERBVEEsXG4gICAgICBqb2luKHJ1bnRpbWUuaG9tZURpcmVjdG9yeSwgXCJBcHBEYXRhXCIsIFwiUm9hbWluZ1wiKSxcbiAgICApO1xuICB9XG4gIHJldHVybiByZXNvbHZlRW52aXJvbm1lbnRQYXRoKFxuICAgIHJ1bnRpbWUuZW52aXJvbm1lbnQuWERHX0NPTkZJR19IT01FLFxuICAgIGpvaW4ocnVudGltZS5ob21lRGlyZWN0b3J5LCBcIi5jb25maWdcIiksXG4gICk7XG59XG5cbmZ1bmN0aW9uIGNvbnRyb2xBZGRyZXNzKGlkOiBzdHJpbmcsIHJ1bnRpbWU6IFNlcnZpY2VSdW50aW1lQ29udGV4dCk6IHN0cmluZyB7XG4gIGNvbnN0IHRva2VuID0gY3JlYXRlSGFzaChcInNoYTI1NlwiKS51cGRhdGUoaWQpLmRpZ2VzdChcImhleFwiKS5zbGljZSgwLCAxNik7XG4gIGlmIChydW50aW1lLnBsYXRmb3JtID09PSBcIndpbjMyXCIpIHtcbiAgICByZXR1cm4gYFxcXFxcXFxcLlxcXFxwaXBlXFxcXGRieC10b29scy1jbGktc2VydmljZS0ke3Rva2VufWA7XG4gIH1cbiAgcmV0dXJuIGpvaW4ocnVudGltZS50ZW1wb3JhcnlEaXJlY3RvcnksIGBkYngtdG9vbHMtY2xpLXNlcnZpY2UtJHt0b2tlbn0uc29ja2ApO1xufVxuXG5mdW5jdGlvbiBzdGFydHVwRmlsZShpZDogc3RyaW5nLCBydW50aW1lOiBTZXJ2aWNlUnVudGltZUNvbnRleHQpOiBzdHJpbmcge1xuICBpZiAocnVudGltZS5wbGF0Zm9ybSA9PT0gXCJkYXJ3aW5cIikge1xuICAgIHJldHVybiBqb2luKHJ1bnRpbWUuaG9tZURpcmVjdG9yeSwgXCJMaWJyYXJ5XCIsIFwiTGF1bmNoQWdlbnRzXCIsIGAke2lkfS5wbGlzdGApO1xuICB9XG4gIGlmIChydW50aW1lLnBsYXRmb3JtID09PSBcIndpbjMyXCIpIHtcbiAgICByZXR1cm4gam9pbihcbiAgICAgIHJlc29sdmVFbnZpcm9ubWVudFBhdGgoXG4gICAgICAgIHJ1bnRpbWUuZW52aXJvbm1lbnQuQVBQREFUQSxcbiAgICAgICAgam9pbihydW50aW1lLmhvbWVEaXJlY3RvcnksIFwiQXBwRGF0YVwiLCBcIlJvYW1pbmdcIiksXG4gICAgICApLFxuICAgICAgXCJNaWNyb3NvZnRcIixcbiAgICAgIFwiV2luZG93c1wiLFxuICAgICAgXCJTdGFydCBNZW51XCIsXG4gICAgICBcIlByb2dyYW1zXCIsXG4gICAgICBcIlN0YXJ0dXBcIixcbiAgICAgIGAke2lkfS5jbWRgLFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGpvaW4oXG4gICAgcmVzb2x2ZUVudmlyb25tZW50UGF0aChcbiAgICAgIHJ1bnRpbWUuZW52aXJvbm1lbnQuWERHX0NPTkZJR19IT01FLFxuICAgICAgam9pbihydW50aW1lLmhvbWVEaXJlY3RvcnksIFwiLmNvbmZpZ1wiKSxcbiAgICApLFxuICAgIFwiYXV0b3N0YXJ0XCIsXG4gICAgYCR7aWR9LmRlc2t0b3BgLFxuICApO1xufVxuXG5mdW5jdGlvbiByZXNvbHZlRW52aXJvbm1lbnRQYXRoKHZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQsIGZhbGxiYWNrOiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAoIXZhbHVlKSByZXR1cm4gZmFsbGJhY2s7XG4gIHJldHVybiBpc0Fic29sdXRlKHZhbHVlKSA/IHZhbHVlIDogcmVzb2x2ZSh2YWx1ZSk7XG59XG4iXX0=
@@ -0,0 +1,2 @@
1
+ export declare function externalRuntimePackages(dependencies: Readonly<Record<string, string>>): string[];
2
+ export declare function installServiceRuntime(bunExecutable: string, directory: string, dependencies: Readonly<Record<string, string>>): Promise<void>;
@@ -0,0 +1,49 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import * as exec from "@dbx-tools/core/exec";
4
+ export function externalRuntimePackages(dependencies) {
5
+ return Object.keys(dependencies).filter((name) => !name.startsWith("@dbx-tools/"));
6
+ }
7
+ export async function installServiceRuntime(bunExecutable, directory, dependencies) {
8
+ await mkdir(directory, { recursive: true });
9
+ const manifestPath = join(directory, "package.json");
10
+ const current = await readOptionalRecord(manifestPath);
11
+ await writeFile(manifestPath, `${JSON.stringify({
12
+ ...current,
13
+ name: "@dbx-tools/service-runtime",
14
+ private: true,
15
+ dependencies: {
16
+ ...stringRecord(current.dependencies),
17
+ ...dependencies,
18
+ },
19
+ }, null, 2)}\n`, "utf8");
20
+ await exec.spawn(bunExecutable, ["install", "--production", "--cwd", directory], {
21
+ check: true,
22
+ cwd: directory,
23
+ stdin: "ignore",
24
+ stdout: "capture",
25
+ stderr: "capture",
26
+ });
27
+ }
28
+ async function readOptionalRecord(path) {
29
+ try {
30
+ const value = JSON.parse(await readFile(path, "utf8"));
31
+ if (!isRecord(value))
32
+ throw new Error(`JSON file is not an object: ${path}`);
33
+ return value;
34
+ }
35
+ catch (error) {
36
+ if (error.code === "ENOENT")
37
+ return {};
38
+ throw error;
39
+ }
40
+ }
41
+ function stringRecord(value) {
42
+ if (!isRecord(value))
43
+ return {};
44
+ return Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === "string"));
45
+ }
46
+ function isRecord(value) {
47
+ return value !== null && typeof value === "object" && !Array.isArray(value);
48
+ }
49
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX3J1bnRpbWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvX3J1bnRpbWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDOUQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUVqQyxPQUFPLEtBQUssSUFBSSxNQUFNLHNCQUFzQixDQUFDO0FBRTdDLE1BQU0sVUFBVSx1QkFBdUIsQ0FBQyxZQUE4QztJQUNwRixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztBQUNyRixDQUFDO0FBRUQsTUFBTSxDQUFDLEtBQUssVUFBVSxxQkFBcUIsQ0FDekMsYUFBcUIsRUFDckIsU0FBaUIsRUFDakIsWUFBOEM7SUFFOUMsTUFBTSxLQUFLLENBQUMsU0FBUyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDNUMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxjQUFjLENBQUMsQ0FBQztJQUNyRCxNQUFNLE9BQU8sR0FBRyxNQUFNLGtCQUFrQixDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ3ZELE1BQU0sU0FBUyxDQUNiLFlBQVksRUFDWixHQUFHLElBQUksQ0FBQyxTQUFTLENBQ2Y7UUFDRSxHQUFHLE9BQU87UUFDVixJQUFJLEVBQUUsNEJBQTRCO1FBQ2xDLE9BQU8sRUFBRSxJQUFJO1FBQ2IsWUFBWSxFQUFFO1lBQ1osR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQztZQUNyQyxHQUFHLFlBQVk7U0FDaEI7S0FDRixFQUNELElBQUksRUFDSixDQUFDLENBQ0YsSUFBSSxFQUNMLE1BQU0sQ0FDUCxDQUFDO0lBQ0YsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRSxDQUFDLFNBQVMsRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLFNBQVMsQ0FBQyxFQUFFO1FBQy9FLEtBQUssRUFBRSxJQUFJO1FBQ1gsR0FBRyxFQUFFLFNBQVM7UUFDZCxLQUFLLEVBQUUsUUFBUTtRQUNmLE1BQU0sRUFBRSxTQUFTO1FBQ2pCLE1BQU0sRUFBRSxTQUFTO0tBQ2xCLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxLQUFLLFVBQVUsa0JBQWtCLENBQUMsSUFBWTtJQUM1QyxJQUFJLENBQUM7UUFDSCxNQUFNLEtBQUssR0FBWSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sUUFBUSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ2hFLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQywrQkFBK0IsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUM3RSxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsSUFBSyxLQUErQixDQUFDLElBQUksS0FBSyxRQUFRO1lBQUUsT0FBTyxFQUFFLENBQUM7UUFDbEUsTUFBTSxLQUFLLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFDLEtBQWM7SUFDbEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUNoQyxPQUFPLE1BQU0sQ0FBQyxXQUFXLENBQ3ZCLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUMxQixDQUFDLEtBQUssRUFBNkIsRUFBRSxDQUFDLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLFFBQVEsQ0FDbkUsQ0FDRixDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsUUFBUSxDQUFDLEtBQWM7SUFDOUIsT0FBTyxLQUFLLEtBQUssSUFBSSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDOUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG1rZGlyLCByZWFkRmlsZSwgd3JpdGVGaWxlIH0gZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5cbmltcG9ydCAqIGFzIGV4ZWMgZnJvbSBcIkBkYngtdG9vbHMvY29yZS9leGVjXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBleHRlcm5hbFJ1bnRpbWVQYWNrYWdlcyhkZXBlbmRlbmNpZXM6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHN0cmluZz4+KTogc3RyaW5nW10ge1xuICByZXR1cm4gT2JqZWN0LmtleXMoZGVwZW5kZW5jaWVzKS5maWx0ZXIoKG5hbWUpID0+ICFuYW1lLnN0YXJ0c1dpdGgoXCJAZGJ4LXRvb2xzL1wiKSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpbnN0YWxsU2VydmljZVJ1bnRpbWUoXG4gIGJ1bkV4ZWN1dGFibGU6IHN0cmluZyxcbiAgZGlyZWN0b3J5OiBzdHJpbmcsXG4gIGRlcGVuZGVuY2llczogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgc3RyaW5nPj4sXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgbWtkaXIoZGlyZWN0b3J5LCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgY29uc3QgbWFuaWZlc3RQYXRoID0gam9pbihkaXJlY3RvcnksIFwicGFja2FnZS5qc29uXCIpO1xuICBjb25zdCBjdXJyZW50ID0gYXdhaXQgcmVhZE9wdGlvbmFsUmVjb3JkKG1hbmlmZXN0UGF0aCk7XG4gIGF3YWl0IHdyaXRlRmlsZShcbiAgICBtYW5pZmVzdFBhdGgsXG4gICAgYCR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICB7XG4gICAgICAgIC4uLmN1cnJlbnQsXG4gICAgICAgIG5hbWU6IFwiQGRieC10b29scy9zZXJ2aWNlLXJ1bnRpbWVcIixcbiAgICAgICAgcHJpdmF0ZTogdHJ1ZSxcbiAgICAgICAgZGVwZW5kZW5jaWVzOiB7XG4gICAgICAgICAgLi4uc3RyaW5nUmVjb3JkKGN1cnJlbnQuZGVwZW5kZW5jaWVzKSxcbiAgICAgICAgICAuLi5kZXBlbmRlbmNpZXMsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgbnVsbCxcbiAgICAgIDIsXG4gICAgKX1cXG5gLFxuICAgIFwidXRmOFwiLFxuICApO1xuICBhd2FpdCBleGVjLnNwYXduKGJ1bkV4ZWN1dGFibGUsIFtcImluc3RhbGxcIiwgXCItLXByb2R1Y3Rpb25cIiwgXCItLWN3ZFwiLCBkaXJlY3RvcnldLCB7XG4gICAgY2hlY2s6IHRydWUsXG4gICAgY3dkOiBkaXJlY3RvcnksXG4gICAgc3RkaW46IFwiaWdub3JlXCIsXG4gICAgc3Rkb3V0OiBcImNhcHR1cmVcIixcbiAgICBzdGRlcnI6IFwiY2FwdHVyZVwiLFxuICB9KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVhZE9wdGlvbmFsUmVjb3JkKHBhdGg6IHN0cmluZyk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCB2YWx1ZTogdW5rbm93biA9IEpTT04ucGFyc2UoYXdhaXQgcmVhZEZpbGUocGF0aCwgXCJ1dGY4XCIpKTtcbiAgICBpZiAoIWlzUmVjb3JkKHZhbHVlKSkgdGhyb3cgbmV3IEVycm9yKGBKU09OIGZpbGUgaXMgbm90IGFuIG9iamVjdDogJHtwYXRofWApO1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoKGVycm9yIGFzIE5vZGVKUy5FcnJub0V4Y2VwdGlvbikuY29kZSA9PT0gXCJFTk9FTlRcIikgcmV0dXJuIHt9O1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbmZ1bmN0aW9uIHN0cmluZ1JlY29yZCh2YWx1ZTogdW5rbm93bik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBpZiAoIWlzUmVjb3JkKHZhbHVlKSkgcmV0dXJuIHt9O1xuICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgIE9iamVjdC5lbnRyaWVzKHZhbHVlKS5maWx0ZXIoXG4gICAgICAoZW50cnkpOiBlbnRyeSBpcyBbc3RyaW5nLCBzdHJpbmddID0+IHR5cGVvZiBlbnRyeVsxXSA9PT0gXCJzdHJpbmdcIixcbiAgICApLFxuICApO1xufVxuXG5mdW5jdGlvbiBpc1JlY29yZCh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgcmV0dXJuIHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG59XG4iXX0=
@@ -0,0 +1,11 @@
1
+ import type { ServicePaths, ServiceRuntimeContext } from "./_paths.ts";
2
+ import type { CliServiceDefinition } from "./definition.ts";
3
+ export interface ServiceLaunch {
4
+ readonly executable: string;
5
+ readonly arguments: readonly string[];
6
+ }
7
+ export declare function installStartup(definition: CliServiceDefinition, paths: ServicePaths, runtime: ServiceRuntimeContext, launch: ServiceLaunch): Promise<void>;
8
+ export declare function removeStartup(paths: ServicePaths): Promise<void>;
9
+ export declare function renderLaunchAgent(definition: CliServiceDefinition, launch: ServiceLaunch): string;
10
+ export declare function renderDesktopEntry(definition: CliServiceDefinition, launch: ServiceLaunch): string;
11
+ export declare function renderWindowsStartup(launch: ServiceLaunch): string;