pidnap 0.0.0-dev.5 → 0.0.0-dev.7
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/cli.mjs +337 -446
- package/dist/cli.mjs.map +1 -1
- package/dist/client.d.mts +2 -1
- package/dist/client.d.mts.map +1 -1
- package/dist/client.mjs.map +1 -1
- package/dist/{logger-BU2RmetS.mjs → env-manager-FKhvfwIR.mjs} +117 -93
- package/dist/env-manager-FKhvfwIR.mjs.map +1 -0
- package/dist/index.d.mts +2 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +3 -2
- package/src/api/client.ts +2 -0
- package/src/cli.ts +312 -423
- package/src/env-manager.ts +43 -7
- package/src/manager.ts +13 -5
- package/dist/logger-BU2RmetS.mjs.map +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { _ as ProcessDefinition, a as TaskStateSchema, c as CronProcessState, h as RestartingProcessState, i as TaskList, m as RestartingProcessOptions, n as
|
|
2
|
+
import { _ as ProcessDefinition, a as TaskStateSchema, c as CronProcessState, h as RestartingProcessState, i as TaskList, m as RestartingProcessOptions, n as logger, o as CronProcess, p as RestartingProcess, s as CronProcessOptions, t as EnvManager } from "./env-manager-FKhvfwIR.mjs";
|
|
3
3
|
import { createClient } from "./client.mjs";
|
|
4
|
-
import { Command } from "commander";
|
|
5
4
|
import { createServer } from "node:http";
|
|
6
5
|
import { pathToFileURL } from "node:url";
|
|
7
6
|
import { join, resolve } from "node:path";
|
|
8
7
|
import { RPCHandler } from "@orpc/server/node";
|
|
9
|
-
import { implement, onError } from "@orpc/server";
|
|
8
|
+
import { implement, onError, os } from "@orpc/server";
|
|
10
9
|
import * as v from "valibot";
|
|
11
10
|
import { oc } from "@orpc/contract";
|
|
12
11
|
import { cwd } from "node:process";
|
|
13
12
|
import { mkdirSync } from "node:fs";
|
|
13
|
+
import { format } from "node:util";
|
|
14
14
|
import Table from "cli-table3";
|
|
15
|
+
import { createCli } from "trpc-cli";
|
|
15
16
|
|
|
16
17
|
//#region src/api/contract.ts
|
|
17
18
|
const oc$1 = oc.$input(v.void());
|
|
18
|
-
const ResourceTarget = v.union([v.string(), v.number()]);
|
|
19
|
+
const ResourceTarget$1 = v.union([v.string(), v.number()]);
|
|
19
20
|
const ManagerStateSchema = v.picklist([
|
|
20
21
|
"idle",
|
|
21
22
|
"initializing",
|
|
@@ -48,51 +49,51 @@ const TaskEntryInfoSchema = v.object({
|
|
|
48
49
|
});
|
|
49
50
|
const manager = { status: oc$1.output(ManagerStatusSchema) };
|
|
50
51
|
const processes = {
|
|
51
|
-
get: oc$1.input(v.object({ target: ResourceTarget })).output(RestartingProcessInfoSchema),
|
|
52
|
+
get: oc$1.input(v.object({ target: ResourceTarget$1 })).output(RestartingProcessInfoSchema),
|
|
52
53
|
list: oc$1.output(v.array(RestartingProcessInfoSchema)),
|
|
53
54
|
add: oc$1.input(v.object({
|
|
54
55
|
name: v.string(),
|
|
55
56
|
definition: ProcessDefinition
|
|
56
57
|
})).output(RestartingProcessInfoSchema),
|
|
57
|
-
start: oc$1.input(v.object({ target: ResourceTarget })).output(RestartingProcessInfoSchema),
|
|
58
|
-
stop: oc$1.input(v.object({ target: ResourceTarget })).output(RestartingProcessInfoSchema),
|
|
58
|
+
start: oc$1.input(v.object({ target: ResourceTarget$1 })).output(RestartingProcessInfoSchema),
|
|
59
|
+
stop: oc$1.input(v.object({ target: ResourceTarget$1 })).output(RestartingProcessInfoSchema),
|
|
59
60
|
restart: oc$1.input(v.object({
|
|
60
|
-
target: ResourceTarget,
|
|
61
|
+
target: ResourceTarget$1,
|
|
61
62
|
force: v.optional(v.boolean())
|
|
62
63
|
})).output(RestartingProcessInfoSchema),
|
|
63
64
|
reload: oc$1.input(v.object({
|
|
64
|
-
target: ResourceTarget,
|
|
65
|
+
target: ResourceTarget$1,
|
|
65
66
|
definition: ProcessDefinition,
|
|
66
67
|
restartImmediately: v.optional(v.boolean())
|
|
67
68
|
})).output(RestartingProcessInfoSchema),
|
|
68
|
-
remove: oc$1.input(v.object({ target: ResourceTarget })).output(v.object({ success: v.boolean() }))
|
|
69
|
+
remove: oc$1.input(v.object({ target: ResourceTarget$1 })).output(v.object({ success: v.boolean() }))
|
|
69
70
|
};
|
|
70
|
-
const tasks
|
|
71
|
-
get: oc$1.input(v.object({ target: ResourceTarget })).output(TaskEntryInfoSchema),
|
|
71
|
+
const tasks = {
|
|
72
|
+
get: oc$1.input(v.object({ target: ResourceTarget$1 })).output(TaskEntryInfoSchema),
|
|
72
73
|
list: oc$1.output(v.array(TaskEntryInfoSchema)),
|
|
73
74
|
add: oc$1.input(v.object({
|
|
74
75
|
name: v.string(),
|
|
75
76
|
definition: ProcessDefinition
|
|
76
77
|
})).output(TaskEntryInfoSchema),
|
|
77
|
-
remove: oc$1.input(v.object({ target: ResourceTarget })).output(TaskEntryInfoSchema)
|
|
78
|
+
remove: oc$1.input(v.object({ target: ResourceTarget$1 })).output(TaskEntryInfoSchema)
|
|
78
79
|
};
|
|
79
|
-
const crons
|
|
80
|
-
get: oc$1.input(v.object({ target: ResourceTarget })).output(CronProcessInfoSchema),
|
|
80
|
+
const crons = {
|
|
81
|
+
get: oc$1.input(v.object({ target: ResourceTarget$1 })).output(CronProcessInfoSchema),
|
|
81
82
|
list: oc$1.output(v.array(CronProcessInfoSchema)),
|
|
82
|
-
trigger: oc$1.input(v.object({ target: ResourceTarget })).output(CronProcessInfoSchema),
|
|
83
|
-
start: oc$1.input(v.object({ target: ResourceTarget })).output(CronProcessInfoSchema),
|
|
84
|
-
stop: oc$1.input(v.object({ target: ResourceTarget })).output(CronProcessInfoSchema)
|
|
83
|
+
trigger: oc$1.input(v.object({ target: ResourceTarget$1 })).output(CronProcessInfoSchema),
|
|
84
|
+
start: oc$1.input(v.object({ target: ResourceTarget$1 })).output(CronProcessInfoSchema),
|
|
85
|
+
stop: oc$1.input(v.object({ target: ResourceTarget$1 })).output(CronProcessInfoSchema)
|
|
85
86
|
};
|
|
86
87
|
const api = {
|
|
87
88
|
manager,
|
|
88
89
|
processes,
|
|
89
|
-
tasks
|
|
90
|
-
crons
|
|
90
|
+
tasks,
|
|
91
|
+
crons
|
|
91
92
|
};
|
|
92
93
|
|
|
93
94
|
//#endregion
|
|
94
95
|
//#region src/api/server.ts
|
|
95
|
-
const os = implement(api).$context();
|
|
96
|
+
const os$2 = implement(api).$context();
|
|
96
97
|
function serializeProcess(proc) {
|
|
97
98
|
return {
|
|
98
99
|
name: proc.name,
|
|
@@ -109,7 +110,7 @@ function serializeCron(cron) {
|
|
|
109
110
|
nextRun: cron.nextRun?.toISOString() ?? null
|
|
110
111
|
};
|
|
111
112
|
}
|
|
112
|
-
const managerStatus = os.manager.status.handler(async ({ context }) => {
|
|
113
|
+
const managerStatus = os$2.manager.status.handler(async ({ context }) => {
|
|
113
114
|
const manager = context.manager;
|
|
114
115
|
const taskList = manager.getTaskList();
|
|
115
116
|
return {
|
|
@@ -119,56 +120,56 @@ const managerStatus = os.manager.status.handler(async ({ context }) => {
|
|
|
119
120
|
taskCount: taskList?.tasks.length ?? 0
|
|
120
121
|
};
|
|
121
122
|
});
|
|
122
|
-
const getProcess = os.processes.get.handler(async ({ input, context }) => {
|
|
123
|
+
const getProcess = os$2.processes.get.handler(async ({ input, context }) => {
|
|
123
124
|
const proc = context.manager.getProcessByTarget(input.target);
|
|
124
125
|
if (!proc) throw new Error(`Process not found: ${input.target}`);
|
|
125
126
|
return serializeProcess(proc);
|
|
126
127
|
});
|
|
127
|
-
const listProcesses = os.processes.list.handler(async ({ context }) => {
|
|
128
|
+
const listProcesses = os$2.processes.list.handler(async ({ context }) => {
|
|
128
129
|
return Array.from(context.manager.getRestartingProcesses().values()).map(serializeProcess);
|
|
129
130
|
});
|
|
130
|
-
const addProcess = os.processes.add.handler(async ({ input, context }) => {
|
|
131
|
+
const addProcess = os$2.processes.add.handler(async ({ input, context }) => {
|
|
131
132
|
return serializeProcess(await context.manager.addProcess(input.name, input.definition));
|
|
132
133
|
});
|
|
133
|
-
const startProcess = os.processes.start.handler(async ({ input, context }) => {
|
|
134
|
+
const startProcess = os$2.processes.start.handler(async ({ input, context }) => {
|
|
134
135
|
return serializeProcess(await context.manager.startProcessByTarget(input.target));
|
|
135
136
|
});
|
|
136
|
-
const stopProcess = os.processes.stop.handler(async ({ input, context }) => {
|
|
137
|
+
const stopProcess = os$2.processes.stop.handler(async ({ input, context }) => {
|
|
137
138
|
return serializeProcess(await context.manager.stopProcessByTarget(input.target));
|
|
138
139
|
});
|
|
139
|
-
const restartProcess = os.processes.restart.handler(async ({ input, context }) => {
|
|
140
|
+
const restartProcess = os$2.processes.restart.handler(async ({ input, context }) => {
|
|
140
141
|
return serializeProcess(await context.manager.restartProcessByTarget(input.target, input.force));
|
|
141
142
|
});
|
|
142
|
-
const reloadProcess = os.processes.reload.handler(async ({ input, context }) => {
|
|
143
|
+
const reloadProcess = os$2.processes.reload.handler(async ({ input, context }) => {
|
|
143
144
|
return serializeProcess(await context.manager.reloadProcessByTarget(input.target, input.definition, { restartImmediately: input.restartImmediately }));
|
|
144
145
|
});
|
|
145
|
-
const removeProcess = os.processes.remove.handler(async ({ input, context }) => {
|
|
146
|
+
const removeProcess = os$2.processes.remove.handler(async ({ input, context }) => {
|
|
146
147
|
await context.manager.removeProcessByTarget(input.target);
|
|
147
148
|
return { success: true };
|
|
148
149
|
});
|
|
149
|
-
const getCron = os.crons.get.handler(async ({ input, context }) => {
|
|
150
|
+
const getCron = os$2.crons.get.handler(async ({ input, context }) => {
|
|
150
151
|
const cron = context.manager.getCronByTarget(input.target);
|
|
151
152
|
if (!cron) throw new Error(`Cron not found: ${input.target}`);
|
|
152
153
|
return serializeCron(cron);
|
|
153
154
|
});
|
|
154
|
-
const listCrons = os.crons.list.handler(async ({ context }) => {
|
|
155
|
+
const listCrons = os$2.crons.list.handler(async ({ context }) => {
|
|
155
156
|
return Array.from(context.manager.getCronProcesses().values()).map(serializeCron);
|
|
156
157
|
});
|
|
157
|
-
const triggerCron = os.crons.trigger.handler(async ({ input, context }) => {
|
|
158
|
+
const triggerCron = os$2.crons.trigger.handler(async ({ input, context }) => {
|
|
158
159
|
return serializeCron(await context.manager.triggerCronByTarget(input.target));
|
|
159
160
|
});
|
|
160
|
-
const startCron = os.crons.start.handler(async ({ input, context }) => {
|
|
161
|
+
const startCron = os$2.crons.start.handler(async ({ input, context }) => {
|
|
161
162
|
return serializeCron(context.manager.startCronByTarget(input.target));
|
|
162
163
|
});
|
|
163
|
-
const stopCron = os.crons.stop.handler(async ({ input, context }) => {
|
|
164
|
+
const stopCron = os$2.crons.stop.handler(async ({ input, context }) => {
|
|
164
165
|
return serializeCron(await context.manager.stopCronByTarget(input.target));
|
|
165
166
|
});
|
|
166
|
-
const getTask = os.tasks.get.handler(async ({ input, context }) => {
|
|
167
|
+
const getTask = os$2.tasks.get.handler(async ({ input, context }) => {
|
|
167
168
|
const task = context.manager.getTaskByTarget(input.target);
|
|
168
169
|
if (!task) throw new Error(`Task not found: ${input.target}`);
|
|
169
170
|
return task;
|
|
170
171
|
});
|
|
171
|
-
const listTasks = os.tasks.list.handler(async ({ context }) => {
|
|
172
|
+
const listTasks = os$2.tasks.list.handler(async ({ context }) => {
|
|
172
173
|
const taskList = context.manager.getTaskList();
|
|
173
174
|
if (!taskList) return [];
|
|
174
175
|
return taskList.tasks.map((t) => ({
|
|
@@ -177,13 +178,13 @@ const listTasks = os.tasks.list.handler(async ({ context }) => {
|
|
|
177
178
|
processNames: t.processes.map((p) => p.name)
|
|
178
179
|
}));
|
|
179
180
|
});
|
|
180
|
-
const addTask = os.tasks.add.handler(async ({ input, context }) => {
|
|
181
|
+
const addTask = os$2.tasks.add.handler(async ({ input, context }) => {
|
|
181
182
|
return context.manager.addTask(input.name, input.definition);
|
|
182
183
|
});
|
|
183
|
-
const removeTask = os.tasks.remove.handler(async ({ input, context }) => {
|
|
184
|
+
const removeTask = os$2.tasks.remove.handler(async ({ input, context }) => {
|
|
184
185
|
return context.manager.removeTaskByTarget(input.target);
|
|
185
186
|
});
|
|
186
|
-
const router = os.router({
|
|
187
|
+
const router = os$2.router({
|
|
187
188
|
manager: { status: managerStatus },
|
|
188
189
|
processes: {
|
|
189
190
|
add: addProcess,
|
|
@@ -282,7 +283,7 @@ var Manager = class {
|
|
|
282
283
|
cwd: cwd$1,
|
|
283
284
|
globalEnvFile: config.envFile,
|
|
284
285
|
customEnvFiles
|
|
285
|
-
});
|
|
286
|
+
}, this.logger.child("env-manager"));
|
|
286
287
|
this.envChangeUnsubscribe = this.envManager.onChange((event) => this.handleEnvChange(event));
|
|
287
288
|
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
288
289
|
const handler = () => this.handleSignal(signal);
|
|
@@ -682,6 +683,8 @@ var Manager = class {
|
|
|
682
683
|
this.envChangeUnsubscribe = null;
|
|
683
684
|
}
|
|
684
685
|
this.envManager.close();
|
|
686
|
+
for (const [signal, handler] of this.signalHandlers) process.off(signal, handler);
|
|
687
|
+
this.signalHandlers.clear();
|
|
685
688
|
if (this.taskList) await this.taskList.stop(timeout);
|
|
686
689
|
const cronStopPromises = Array.from(this.cronProcesses.values()).map((p) => p.stop(timeout));
|
|
687
690
|
const restartingStopPromises = Array.from(this.restartingProcesses.values()).map((p) => p.stop(timeout));
|
|
@@ -769,66 +772,116 @@ async function tImport(path) {
|
|
|
769
772
|
}
|
|
770
773
|
}
|
|
771
774
|
|
|
775
|
+
//#endregion
|
|
776
|
+
//#region package.json
|
|
777
|
+
var version = "0.0.0-dev.7";
|
|
778
|
+
|
|
772
779
|
//#endregion
|
|
773
780
|
//#region src/cli.ts
|
|
774
|
-
const
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
781
|
+
const os$1 = os.$context().$meta({});
|
|
782
|
+
const ResourceTarget = v.union([v.string(), v.number()]);
|
|
783
|
+
function printProcessTable(proc) {
|
|
784
|
+
const table = new Table({ head: [
|
|
785
|
+
"Name",
|
|
786
|
+
"State",
|
|
787
|
+
"Restarts"
|
|
788
|
+
] });
|
|
789
|
+
table.push([
|
|
790
|
+
proc.name,
|
|
791
|
+
proc.state,
|
|
792
|
+
proc.restarts
|
|
793
|
+
]);
|
|
794
|
+
console.log(table.toString());
|
|
795
|
+
}
|
|
796
|
+
function printTaskTable(task) {
|
|
797
|
+
const table = new Table({ head: [
|
|
798
|
+
"Id",
|
|
799
|
+
"State",
|
|
800
|
+
"Processes"
|
|
801
|
+
] });
|
|
802
|
+
table.push([
|
|
803
|
+
task.id,
|
|
804
|
+
task.state,
|
|
805
|
+
task.processNames.join(", ")
|
|
806
|
+
]);
|
|
807
|
+
console.log(table.toString());
|
|
808
|
+
}
|
|
809
|
+
function printCronTable(cron) {
|
|
810
|
+
const table = new Table({ head: [
|
|
811
|
+
"Name",
|
|
812
|
+
"State",
|
|
813
|
+
"Runs",
|
|
814
|
+
"Fails",
|
|
815
|
+
"Next Run"
|
|
816
|
+
] });
|
|
817
|
+
table.push([
|
|
818
|
+
cron.name,
|
|
819
|
+
cron.state,
|
|
820
|
+
cron.runCount,
|
|
821
|
+
cron.failCount,
|
|
822
|
+
cron.nextRun ?? "-"
|
|
823
|
+
]);
|
|
824
|
+
console.log(table.toString());
|
|
825
|
+
}
|
|
826
|
+
const cliRouter = os$1.router({
|
|
827
|
+
init: os.meta({
|
|
828
|
+
description: "Initialize and run the process manager with config file",
|
|
829
|
+
aliases: { options: { config: "c" } }
|
|
830
|
+
}).input(v.object({ config: v.optional(v.pipe(v.string(), v.description("Path to config file")), "pidnap.config.ts") })).handler(async ({ input }) => {
|
|
831
|
+
process.title = "pidnap";
|
|
832
|
+
const initLogger = logger({ name: "pidnap" });
|
|
833
|
+
try {
|
|
834
|
+
const configUrl = pathToFileURL(resolve(process.cwd(), input.config)).href;
|
|
835
|
+
const configModule = await tImport(configUrl);
|
|
836
|
+
const rawConfig = configModule.default.default || configModule.default || configModule.config || {};
|
|
837
|
+
const config = v.parse(ManagerConfig, rawConfig);
|
|
838
|
+
const host = config.http?.host ?? "127.0.0.1";
|
|
839
|
+
const port = config.http?.port ?? 9876;
|
|
840
|
+
const authToken = config.http?.authToken;
|
|
841
|
+
const managerLogger = logger({
|
|
842
|
+
name: "pidnap",
|
|
843
|
+
logFile: resolve(config.logDir ?? resolve(process.cwd(), "logs"), "pidnap.log")
|
|
844
|
+
});
|
|
845
|
+
const manager = new Manager(config, managerLogger);
|
|
846
|
+
const handler = new RPCHandler(router, { interceptors: [onError((error) => {
|
|
847
|
+
managerLogger.error(error);
|
|
848
|
+
})] });
|
|
849
|
+
const server = createServer(async (req, res) => {
|
|
850
|
+
if (authToken) {
|
|
851
|
+
if (req.headers["authorization"]?.replace("Bearer ", "") !== authToken) {
|
|
852
|
+
res.statusCode = 401;
|
|
853
|
+
res.end("Unauthorized");
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
801
856
|
}
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
857
|
+
const { matched } = await handler.handle(req, res, {
|
|
858
|
+
prefix: "/rpc",
|
|
859
|
+
context: { manager }
|
|
860
|
+
});
|
|
861
|
+
if (matched) return;
|
|
862
|
+
res.statusCode = 404;
|
|
863
|
+
res.end("Not found\n");
|
|
806
864
|
});
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
}
|
|
828
|
-
});
|
|
829
|
-
program.command("status").description("Show manager status").option("-u, --url <url>", "RPC server URL").action(async (options) => {
|
|
830
|
-
try {
|
|
831
|
-
const status = await createClient(options.url).manager.status();
|
|
865
|
+
server.listen(port, host, async () => {
|
|
866
|
+
managerLogger.info(`pidnap RPC server running on http://${host}:${port}`);
|
|
867
|
+
if (authToken) managerLogger.info("Auth token required for API access");
|
|
868
|
+
try {
|
|
869
|
+
await manager.start();
|
|
870
|
+
} catch (err) {
|
|
871
|
+
managerLogger.error("Failed to start manager:", err);
|
|
872
|
+
server.close();
|
|
873
|
+
process.exit(1);
|
|
874
|
+
}
|
|
875
|
+
});
|
|
876
|
+
await manager.waitForShutdown();
|
|
877
|
+
server.close();
|
|
878
|
+
} catch (error) {
|
|
879
|
+
initLogger.error("Failed to start pidnap:", error);
|
|
880
|
+
process.exit(1);
|
|
881
|
+
}
|
|
882
|
+
}),
|
|
883
|
+
status: os$1.meta({ description: "Show manager status" }).handler(async ({ context: { client } }) => {
|
|
884
|
+
const status = await client.manager.status();
|
|
832
885
|
const table = new Table({ head: [
|
|
833
886
|
"State",
|
|
834
887
|
"Processes",
|
|
@@ -842,356 +895,194 @@ program.command("status").description("Show manager status").option("-u, --url <
|
|
|
842
895
|
status.taskCount
|
|
843
896
|
]);
|
|
844
897
|
console.log(table.toString());
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
"
|
|
875
|
-
"
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
"
|
|
918
|
-
"
|
|
919
|
-
"
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
});
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
target:
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
cron
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
"
|
|
1011
|
-
"
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
]);
|
|
1023
|
-
console.log(table.toString());
|
|
1024
|
-
} catch (error) {
|
|
1025
|
-
console.error("Failed to get cron:", error);
|
|
1026
|
-
process.exit(1);
|
|
1027
|
-
}
|
|
1028
|
-
});
|
|
1029
|
-
crons.command("trigger").description("Trigger a cron process").argument("<target>", "Cron name or index").option("-u, --url <url>", "RPC server URL").action(async (target, options) => {
|
|
1030
|
-
try {
|
|
1031
|
-
const cron = await createClient(options.url).crons.trigger({ target: parseTarget(target) });
|
|
1032
|
-
const table = new Table({ head: [
|
|
1033
|
-
"Name",
|
|
1034
|
-
"State",
|
|
1035
|
-
"Runs",
|
|
1036
|
-
"Fails",
|
|
1037
|
-
"Next Run"
|
|
1038
|
-
] });
|
|
1039
|
-
table.push([
|
|
1040
|
-
cron.name,
|
|
1041
|
-
cron.state,
|
|
1042
|
-
cron.runCount,
|
|
1043
|
-
cron.failCount,
|
|
1044
|
-
cron.nextRun ?? "-"
|
|
1045
|
-
]);
|
|
1046
|
-
console.log(table.toString());
|
|
1047
|
-
} catch (error) {
|
|
1048
|
-
console.error("Failed to trigger cron:", error);
|
|
1049
|
-
process.exit(1);
|
|
1050
|
-
}
|
|
898
|
+
}),
|
|
899
|
+
process: os$1.router({
|
|
900
|
+
list: os$1.meta({ description: "List restarting processes" }).handler(async ({ context: { client } }) => {
|
|
901
|
+
const processes = await client.processes.list();
|
|
902
|
+
const table = new Table({ head: [
|
|
903
|
+
"Name",
|
|
904
|
+
"State",
|
|
905
|
+
"Restarts"
|
|
906
|
+
] });
|
|
907
|
+
for (const proc of processes) table.push([
|
|
908
|
+
proc.name,
|
|
909
|
+
proc.state,
|
|
910
|
+
proc.restarts
|
|
911
|
+
]);
|
|
912
|
+
console.log(table.toString());
|
|
913
|
+
}),
|
|
914
|
+
get: os$1.meta({
|
|
915
|
+
description: "Get a restarting process by name or index",
|
|
916
|
+
aliases: { options: { target: "t" } }
|
|
917
|
+
}).input(v.object({ target: v.pipe(ResourceTarget, v.description("Process name or index")) })).handler(async ({ input, context: { client } }) => {
|
|
918
|
+
printProcessTable(await client.processes.get({ target: input.target }));
|
|
919
|
+
}),
|
|
920
|
+
add: os$1.meta({
|
|
921
|
+
description: "Add a restarting process",
|
|
922
|
+
aliases: { options: {
|
|
923
|
+
name: "n",
|
|
924
|
+
definition: "d"
|
|
925
|
+
} }
|
|
926
|
+
}).input(v.object({
|
|
927
|
+
name: v.pipe(v.string(), v.description("Process name")),
|
|
928
|
+
definition: v.pipe(ProcessDefinition, v.description("Process definition JSON"))
|
|
929
|
+
})).handler(async ({ input, context: { client } }) => {
|
|
930
|
+
printProcessTable(await client.processes.add({
|
|
931
|
+
name: input.name,
|
|
932
|
+
definition: input.definition
|
|
933
|
+
}));
|
|
934
|
+
}),
|
|
935
|
+
start: os$1.meta({
|
|
936
|
+
description: "Start a restarting process",
|
|
937
|
+
aliases: { options: { target: "t" } }
|
|
938
|
+
}).input(v.object({ target: v.pipe(ResourceTarget, v.description("Process name or index")) })).handler(async ({ input, context: { client } }) => {
|
|
939
|
+
printProcessTable(await client.processes.start({ target: input.target }));
|
|
940
|
+
}),
|
|
941
|
+
stop: os$1.meta({
|
|
942
|
+
description: "Stop a restarting process",
|
|
943
|
+
aliases: { options: { target: "t" } }
|
|
944
|
+
}).input(v.object({ target: v.pipe(ResourceTarget, v.description("Process name or index")) })).handler(async ({ input, context: { client } }) => {
|
|
945
|
+
printProcessTable(await client.processes.stop({ target: input.target }));
|
|
946
|
+
}),
|
|
947
|
+
restart: os$1.meta({
|
|
948
|
+
description: "Restart a restarting process",
|
|
949
|
+
aliases: { options: {
|
|
950
|
+
target: "t",
|
|
951
|
+
force: "f"
|
|
952
|
+
} }
|
|
953
|
+
}).input(v.object({
|
|
954
|
+
target: v.pipe(ResourceTarget, v.description("Process name or index")),
|
|
955
|
+
force: v.optional(v.pipe(v.boolean(), v.description("Force restart")))
|
|
956
|
+
})).handler(async ({ input, context: { client } }) => {
|
|
957
|
+
printProcessTable(await client.processes.restart({
|
|
958
|
+
target: input.target,
|
|
959
|
+
force: input.force
|
|
960
|
+
}));
|
|
961
|
+
}),
|
|
962
|
+
reload: os$1.meta({
|
|
963
|
+
description: "Reload a restarting process definition",
|
|
964
|
+
aliases: { options: {
|
|
965
|
+
target: "t",
|
|
966
|
+
definition: "d",
|
|
967
|
+
restartImmediately: "r"
|
|
968
|
+
} }
|
|
969
|
+
}).input(v.object({
|
|
970
|
+
target: v.pipe(ResourceTarget, v.description("Process name or index")),
|
|
971
|
+
definition: v.pipe(ProcessDefinition, v.description("Process definition JSON")),
|
|
972
|
+
restartImmediately: v.optional(v.pipe(v.boolean(), v.description("Restart immediately after reload")))
|
|
973
|
+
})).handler(async ({ input, context: { client } }) => {
|
|
974
|
+
printProcessTable(await client.processes.reload({
|
|
975
|
+
target: input.target,
|
|
976
|
+
definition: input.definition,
|
|
977
|
+
restartImmediately: input.restartImmediately
|
|
978
|
+
}));
|
|
979
|
+
}),
|
|
980
|
+
remove: os$1.meta({
|
|
981
|
+
description: "Remove a restarting process",
|
|
982
|
+
aliases: { options: { target: "t" } }
|
|
983
|
+
}).input(v.object({ target: v.pipe(ResourceTarget, v.description("Process name or index")) })).handler(async ({ input, context: { client } }) => {
|
|
984
|
+
await client.processes.remove({ target: input.target });
|
|
985
|
+
console.log("Process removed");
|
|
986
|
+
})
|
|
987
|
+
}),
|
|
988
|
+
tasks: os$1.router({
|
|
989
|
+
list: os$1.meta({ description: "List tasks" }).handler(async ({ context: { client } }) => {
|
|
990
|
+
const tasks = await client.tasks.list();
|
|
991
|
+
const table = new Table({ head: [
|
|
992
|
+
"Id",
|
|
993
|
+
"State",
|
|
994
|
+
"Processes"
|
|
995
|
+
] });
|
|
996
|
+
for (const task of tasks) table.push([
|
|
997
|
+
task.id,
|
|
998
|
+
task.state,
|
|
999
|
+
task.processNames.join(", ")
|
|
1000
|
+
]);
|
|
1001
|
+
console.log(table.toString());
|
|
1002
|
+
}),
|
|
1003
|
+
get: os$1.meta({
|
|
1004
|
+
description: "Get a task by id or index",
|
|
1005
|
+
aliases: { options: { target: "t" } }
|
|
1006
|
+
}).input(v.object({ target: v.pipe(ResourceTarget, v.description("Task id or index")) })).handler(async ({ input, context: { client } }) => {
|
|
1007
|
+
printTaskTable(await client.tasks.get({ target: input.target }));
|
|
1008
|
+
}),
|
|
1009
|
+
add: os$1.meta({
|
|
1010
|
+
description: "Add a task",
|
|
1011
|
+
aliases: { options: {
|
|
1012
|
+
name: "n",
|
|
1013
|
+
definition: "d"
|
|
1014
|
+
} }
|
|
1015
|
+
}).input(v.object({
|
|
1016
|
+
name: v.pipe(v.string(), v.description("Task name")),
|
|
1017
|
+
definition: v.pipe(ProcessDefinition, v.description("Process definition JSON"))
|
|
1018
|
+
})).handler(async ({ input, context: { client } }) => {
|
|
1019
|
+
printTaskTable(await client.tasks.add({
|
|
1020
|
+
name: input.name,
|
|
1021
|
+
definition: input.definition
|
|
1022
|
+
}));
|
|
1023
|
+
}),
|
|
1024
|
+
remove: os$1.meta({
|
|
1025
|
+
description: "Remove a task by id or index",
|
|
1026
|
+
aliases: { options: { target: "t" } }
|
|
1027
|
+
}).input(v.object({ target: v.pipe(ResourceTarget, v.description("Task id or index")) })).handler(async ({ input, context: { client } }) => {
|
|
1028
|
+
printTaskTable(await client.tasks.remove({ target: input.target }));
|
|
1029
|
+
})
|
|
1030
|
+
}),
|
|
1031
|
+
crons: os$1.router({
|
|
1032
|
+
list: os$1.meta({ description: "List cron processes" }).handler(async ({ context: { client } }) => {
|
|
1033
|
+
const crons = await client.crons.list();
|
|
1034
|
+
const table = new Table({ head: [
|
|
1035
|
+
"Name",
|
|
1036
|
+
"State",
|
|
1037
|
+
"Runs",
|
|
1038
|
+
"Fails",
|
|
1039
|
+
"Next Run"
|
|
1040
|
+
] });
|
|
1041
|
+
for (const cron of crons) table.push([
|
|
1042
|
+
cron.name,
|
|
1043
|
+
cron.state,
|
|
1044
|
+
cron.runCount,
|
|
1045
|
+
cron.failCount,
|
|
1046
|
+
cron.nextRun ?? "-"
|
|
1047
|
+
]);
|
|
1048
|
+
console.log(table.toString());
|
|
1049
|
+
}),
|
|
1050
|
+
get: os$1.meta({
|
|
1051
|
+
description: "Get a cron process by name or index",
|
|
1052
|
+
aliases: { options: { target: "t" } }
|
|
1053
|
+
}).input(v.object({ target: v.pipe(ResourceTarget, v.description("Cron name or index")) })).handler(async ({ input, context: { client } }) => {
|
|
1054
|
+
printCronTable(await client.crons.get({ target: input.target }));
|
|
1055
|
+
}),
|
|
1056
|
+
trigger: os$1.meta({
|
|
1057
|
+
description: "Trigger a cron process",
|
|
1058
|
+
aliases: { options: { target: "t" } }
|
|
1059
|
+
}).input(v.object({ target: v.pipe(ResourceTarget, v.description("Cron name or index")) })).handler(async ({ input, context: { client } }) => {
|
|
1060
|
+
printCronTable(await client.crons.trigger({ target: input.target }));
|
|
1061
|
+
}),
|
|
1062
|
+
start: os$1.meta({
|
|
1063
|
+
description: "Start a cron process",
|
|
1064
|
+
aliases: { options: { target: "t" } }
|
|
1065
|
+
}).input(v.object({ target: v.pipe(ResourceTarget, v.description("Cron name or index")) })).handler(async ({ input, context: { client } }) => {
|
|
1066
|
+
printCronTable(await client.crons.start({ target: input.target }));
|
|
1067
|
+
}),
|
|
1068
|
+
stop: os$1.meta({
|
|
1069
|
+
description: "Stop a cron process",
|
|
1070
|
+
aliases: { options: { target: "t" } }
|
|
1071
|
+
}).input(v.object({ target: v.pipe(ResourceTarget, v.description("Cron name or index")) })).handler(async ({ input, context: { client } }) => {
|
|
1072
|
+
printCronTable(await client.crons.stop({ target: input.target }));
|
|
1073
|
+
})
|
|
1074
|
+
})
|
|
1051
1075
|
});
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
table.push([
|
|
1063
|
-
cron.name,
|
|
1064
|
-
cron.state,
|
|
1065
|
-
cron.runCount,
|
|
1066
|
-
cron.failCount,
|
|
1067
|
-
cron.nextRun ?? "-"
|
|
1068
|
-
]);
|
|
1069
|
-
console.log(table.toString());
|
|
1070
|
-
} catch (error) {
|
|
1071
|
-
console.error("Failed to start cron:", error);
|
|
1072
|
-
process.exit(1);
|
|
1073
|
-
}
|
|
1074
|
-
});
|
|
1075
|
-
crons.command("stop").description("Stop a cron process").argument("<target>", "Cron name or index").option("-u, --url <url>", "RPC server URL").action(async (target, options) => {
|
|
1076
|
-
try {
|
|
1077
|
-
const cron = await createClient(options.url).crons.stop({ target: parseTarget(target) });
|
|
1078
|
-
const table = new Table({ head: [
|
|
1079
|
-
"Name",
|
|
1080
|
-
"State",
|
|
1081
|
-
"Runs",
|
|
1082
|
-
"Fails",
|
|
1083
|
-
"Next Run"
|
|
1084
|
-
] });
|
|
1085
|
-
table.push([
|
|
1086
|
-
cron.name,
|
|
1087
|
-
cron.state,
|
|
1088
|
-
cron.runCount,
|
|
1089
|
-
cron.failCount,
|
|
1090
|
-
cron.nextRun ?? "-"
|
|
1091
|
-
]);
|
|
1092
|
-
console.log(table.toString());
|
|
1093
|
-
} catch (error) {
|
|
1094
|
-
console.error("Failed to stop cron:", error);
|
|
1095
|
-
process.exit(1);
|
|
1096
|
-
}
|
|
1097
|
-
});
|
|
1098
|
-
const tasks = program.command("tasks").description("Manage tasks");
|
|
1099
|
-
tasks.command("list").description("List tasks").option("-u, --url <url>", "RPC server URL").action(async (options) => {
|
|
1100
|
-
try {
|
|
1101
|
-
const tasks = await createClient(options.url).tasks.list();
|
|
1102
|
-
const table = new Table({ head: [
|
|
1103
|
-
"Id",
|
|
1104
|
-
"State",
|
|
1105
|
-
"Processes"
|
|
1106
|
-
] });
|
|
1107
|
-
for (const task of tasks) table.push([
|
|
1108
|
-
task.id,
|
|
1109
|
-
task.state,
|
|
1110
|
-
task.processNames.join(", ")
|
|
1111
|
-
]);
|
|
1112
|
-
console.log(table.toString());
|
|
1113
|
-
} catch (error) {
|
|
1114
|
-
console.error("Failed to list tasks:", error);
|
|
1115
|
-
process.exit(1);
|
|
1116
|
-
}
|
|
1117
|
-
});
|
|
1118
|
-
tasks.command("get").description("Get a task by id or index").argument("<target>", "Task id or index").option("-u, --url <url>", "RPC server URL").action(async (target, options) => {
|
|
1119
|
-
try {
|
|
1120
|
-
const task = await createClient(options.url).tasks.get({ target: parseTarget(target) });
|
|
1121
|
-
const table = new Table({ head: [
|
|
1122
|
-
"Id",
|
|
1123
|
-
"State",
|
|
1124
|
-
"Processes"
|
|
1125
|
-
] });
|
|
1126
|
-
table.push([
|
|
1127
|
-
task.id,
|
|
1128
|
-
task.state,
|
|
1129
|
-
task.processNames.join(", ")
|
|
1130
|
-
]);
|
|
1131
|
-
console.log(table.toString());
|
|
1132
|
-
} catch (error) {
|
|
1133
|
-
console.error("Failed to get task:", error);
|
|
1134
|
-
process.exit(1);
|
|
1135
|
-
}
|
|
1136
|
-
});
|
|
1137
|
-
tasks.command("add").description("Add a task").requiredOption("-n, --name <name>", "Task name").requiredOption("-d, --definition <json>", "Process definition JSON").option("-u, --url <url>", "RPC server URL").action(async (options) => {
|
|
1138
|
-
try {
|
|
1139
|
-
const client = createClient(options.url);
|
|
1140
|
-
const definition = parseDefinition(options.definition);
|
|
1141
|
-
const task = await client.tasks.add({
|
|
1142
|
-
name: options.name,
|
|
1143
|
-
definition
|
|
1144
|
-
});
|
|
1145
|
-
const table = new Table({ head: [
|
|
1146
|
-
"Id",
|
|
1147
|
-
"State",
|
|
1148
|
-
"Processes"
|
|
1149
|
-
] });
|
|
1150
|
-
table.push([
|
|
1151
|
-
task.id,
|
|
1152
|
-
task.state,
|
|
1153
|
-
task.processNames.join(", ")
|
|
1154
|
-
]);
|
|
1155
|
-
console.log(table.toString());
|
|
1156
|
-
} catch (error) {
|
|
1157
|
-
console.error("Failed to add task:", error);
|
|
1158
|
-
process.exit(1);
|
|
1159
|
-
}
|
|
1160
|
-
});
|
|
1161
|
-
tasks.command("remove").description("Remove a task by id or index").argument("<target>", "Task id or index").option("-u, --url <url>", "RPC server URL").action(async (target, options) => {
|
|
1162
|
-
try {
|
|
1163
|
-
const task = await createClient(options.url).tasks.remove({ target: parseTarget(target) });
|
|
1164
|
-
const table = new Table({ head: [
|
|
1165
|
-
"Id",
|
|
1166
|
-
"State",
|
|
1167
|
-
"Processes"
|
|
1168
|
-
] });
|
|
1169
|
-
table.push([
|
|
1170
|
-
task.id,
|
|
1171
|
-
task.state,
|
|
1172
|
-
task.processNames.join(", ")
|
|
1173
|
-
]);
|
|
1174
|
-
console.log(table.toString());
|
|
1175
|
-
} catch (error) {
|
|
1176
|
-
console.error("Failed to remove task:", error);
|
|
1177
|
-
process.exit(1);
|
|
1178
|
-
}
|
|
1179
|
-
});
|
|
1180
|
-
const TargetSchema = v.union([v.string(), v.number()]);
|
|
1181
|
-
function parseTarget(value) {
|
|
1182
|
-
const asNumber = Number(value);
|
|
1183
|
-
return v.parse(TargetSchema, Number.isNaN(asNumber) ? value : asNumber);
|
|
1184
|
-
}
|
|
1185
|
-
function parseDefinition(raw) {
|
|
1186
|
-
try {
|
|
1187
|
-
const parsed = JSON.parse(raw);
|
|
1188
|
-
return v.parse(ProcessDefinition, parsed);
|
|
1189
|
-
} catch (error) {
|
|
1190
|
-
console.error("Invalid --definition JSON. Expected a ProcessDefinition.");
|
|
1191
|
-
throw error;
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
program.parse();
|
|
1076
|
+
const client = createClient();
|
|
1077
|
+
createCli({
|
|
1078
|
+
name: "pidnap",
|
|
1079
|
+
version,
|
|
1080
|
+
router: cliRouter,
|
|
1081
|
+
context: { client }
|
|
1082
|
+
}).run({ formatError(error) {
|
|
1083
|
+
if (error?.cause?.code === "ECONNREFUSED") return `Failed to connect to RPC server, are you sure the server is running? If the Server is running of different url, use PIDNAP_RPC_URL environment variable to set it.\n` + format(error);
|
|
1084
|
+
return format(error);
|
|
1085
|
+
} });
|
|
1195
1086
|
|
|
1196
1087
|
//#endregion
|
|
1197
1088
|
export { };
|