2026-01-16 05:40:35 +00:00
|
|
|
import { Writable } from "node:stream";
|
|
|
|
|
import type { GatewayService } from "../../daemon/service.js";
|
|
|
|
|
import { defaultRuntime } from "../../runtime.js";
|
|
|
|
|
|
|
|
|
|
export type DaemonAction = "install" | "uninstall" | "start" | "stop" | "restart";
|
|
|
|
|
|
|
|
|
|
export type DaemonActionResponse = {
|
|
|
|
|
ok: boolean;
|
|
|
|
|
action: DaemonAction;
|
|
|
|
|
result?: string;
|
|
|
|
|
message?: string;
|
|
|
|
|
error?: string;
|
|
|
|
|
hints?: string[];
|
|
|
|
|
warnings?: string[];
|
|
|
|
|
service?: {
|
|
|
|
|
label: string;
|
|
|
|
|
loaded: boolean;
|
|
|
|
|
loadedText: string;
|
|
|
|
|
notLoadedText: string;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export function emitDaemonActionJson(payload: DaemonActionResponse) {
|
|
|
|
|
defaultRuntime.log(JSON.stringify(payload, null, 2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function buildDaemonServiceSnapshot(service: GatewayService, loaded: boolean) {
|
|
|
|
|
return {
|
|
|
|
|
label: service.label,
|
|
|
|
|
loaded,
|
|
|
|
|
loadedText: service.loadedText,
|
|
|
|
|
notLoadedText: service.notLoadedText,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function createNullWriter(): Writable {
|
|
|
|
|
return new Writable({
|
|
|
|
|
write(_chunk, _encoding, callback) {
|
|
|
|
|
callback();
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
2026-02-15 05:03:37 +00:00
|
|
|
|
|
|
|
|
export function createDaemonActionContext(params: { action: DaemonAction; json: boolean }): {
|
|
|
|
|
stdout: Writable;
|
|
|
|
|
warnings: string[];
|
|
|
|
|
emit: (payload: Omit<DaemonActionResponse, "action">) => void;
|
|
|
|
|
fail: (message: string, hints?: string[]) => void;
|
|
|
|
|
} {
|
|
|
|
|
const warnings: string[] = [];
|
|
|
|
|
const stdout = params.json ? createNullWriter() : process.stdout;
|
|
|
|
|
const emit = (payload: Omit<DaemonActionResponse, "action">) => {
|
|
|
|
|
if (!params.json) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
emitDaemonActionJson({
|
|
|
|
|
action: params.action,
|
|
|
|
|
...payload,
|
|
|
|
|
warnings: payload.warnings ?? (warnings.length ? warnings : undefined),
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
const fail = (message: string, hints?: string[]) => {
|
|
|
|
|
if (params.json) {
|
|
|
|
|
emit({
|
|
|
|
|
ok: false,
|
|
|
|
|
error: message,
|
|
|
|
|
hints,
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
defaultRuntime.error(message);
|
|
|
|
|
if (hints?.length) {
|
|
|
|
|
for (const hint of hints) {
|
|
|
|
|
defaultRuntime.log(`Tip: ${hint}`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
defaultRuntime.exit(1);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return { stdout, warnings, emit, fail };
|
|
|
|
|
}
|