crnd 0.0.1 → 0.0.3
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/bin/crnd +88 -0
- package/package.json +19 -43
- package/drizzle/0000_init.sql +0 -35
- package/drizzle/0001_add_runs.sql +0 -13
- package/drizzle/meta/_journal.json +0 -20
- package/src/cli/commands/createDeleteCommand.ts +0 -93
- package/src/cli/commands/createDoctorCommand.ts +0 -93
- package/src/cli/commands/createExportCommand.ts +0 -75
- package/src/cli/commands/createImportCommand.ts +0 -80
- package/src/cli/commands/createKillCommand.ts +0 -89
- package/src/cli/commands/createListCommand.ts +0 -67
- package/src/cli/commands/createLogsCommand.ts +0 -125
- package/src/cli/commands/createPauseCommand.ts +0 -78
- package/src/cli/commands/createResetCommand.ts +0 -78
- package/src/cli/commands/createResumeCommand.ts +0 -78
- package/src/cli/commands/createRootCommand.ts +0 -50
- package/src/cli/commands/createRunOnceCommand.ts +0 -77
- package/src/cli/commands/createRunsCommand.ts +0 -106
- package/src/cli/commands/createScheduleCommand.ts +0 -184
- package/src/cli/commands/createShowCommand.ts +0 -92
- package/src/cli/commands/createStatusCommand.ts +0 -145
- package/src/cli/commands/createStopCommand.ts +0 -89
- package/src/cli/commands/createUpdateCommand.ts +0 -13
- package/src/cli/commands/daemon/createDaemonCommand.ts +0 -24
- package/src/cli/commands/daemon/createDaemonInstallCommand.ts +0 -144
- package/src/cli/commands/daemon/createDaemonServeCommand.ts +0 -14
- package/src/cli/commands/daemon/createDaemonStartCommand.ts +0 -73
- package/src/cli/commands/daemon/createDaemonStatusCommand.ts +0 -5
- package/src/cli/commands/daemon/createDaemonStopCommand.ts +0 -59
- package/src/cli/commands/daemon/createDaemonUninstallCommand.ts +0 -99
- package/src/cli/commands/daemon/createLaunchdPlist.ts +0 -34
- package/src/cli/commands/daemon/createSystemdService.ts +0 -24
- package/src/cli/commands/daemon/escapeXml.ts +0 -8
- package/src/cli/commands/daemon/getDaemonServiceArgs.ts +0 -10
- package/src/cli/commands/daemon/quoteWindowsArg.ts +0 -4
- package/src/cli/commands/getCommandArgs.ts +0 -8
- package/src/cli/commands/parseEnvArgs.ts +0 -28
- package/src/cli/getDaemonSpawnArgs.ts +0 -9
- package/src/cli/main.ts +0 -8
- package/src/daemon/autostart/ensureAutostart.ts +0 -30
- package/src/daemon/autostart/getAutostartPath.ts +0 -29
- package/src/daemon/autostart/getDaemonInstallArgs.ts +0 -10
- package/src/daemon/createLogger.ts +0 -13
- package/src/daemon/createShutdownHandler.ts +0 -29
- package/src/daemon/jobs/createJobsFileSync.ts +0 -113
- package/src/daemon/jobs/deleteJobByName.ts +0 -18
- package/src/daemon/jobs/upsertJob.ts +0 -85
- package/src/daemon/main.ts +0 -64
- package/src/daemon/runner/createRunOutputFds.ts +0 -18
- package/src/daemon/runner/getRunStatus.ts +0 -14
- package/src/daemon/runner/recordSkippedRun.ts +0 -27
- package/src/daemon/runner/recoverRunningRuns.ts +0 -36
- package/src/daemon/runner/runJob.ts +0 -94
- package/src/daemon/scheduler/createScheduler.ts +0 -45
- package/src/daemon/scheduler/createSchedulerState.ts +0 -8
- package/src/daemon/scheduler/loadJobs.ts +0 -10
- package/src/daemon/scheduler/runJobWithTracking.ts +0 -48
- package/src/daemon/scheduler/scheduleJob.ts +0 -32
- package/src/daemon/scheduler/unscheduleJob.ts +0 -11
- package/src/daemon/scheduler/updateNextRunAt.ts +0 -14
- package/src/daemon/server/createApp.ts +0 -76
- package/src/daemon/server/createAuthMiddleware.ts +0 -16
- package/src/daemon/server/routes/registerExportRoute.ts +0 -21
- package/src/daemon/server/routes/registerHealthRoute.ts +0 -16
- package/src/daemon/server/routes/registerImportRoute.ts +0 -22
- package/src/daemon/server/routes/registerJobRunsRoute.ts +0 -46
- package/src/daemon/server/routes/registerJobsDeleteRoute.ts +0 -37
- package/src/daemon/server/routes/registerJobsGetRoute.ts +0 -29
- package/src/daemon/server/routes/registerJobsKillRoute.ts +0 -45
- package/src/daemon/server/routes/registerJobsListRoute.ts +0 -13
- package/src/daemon/server/routes/registerJobsPauseRoute.ts +0 -53
- package/src/daemon/server/routes/registerJobsResetRoute.ts +0 -54
- package/src/daemon/server/routes/registerJobsResumeRoute.ts +0 -53
- package/src/daemon/server/routes/registerJobsRunRoute.ts +0 -37
- package/src/daemon/server/routes/registerJobsStopRoute.ts +0 -45
- package/src/daemon/server/routes/registerJobsUpsertRoute.ts +0 -30
- package/src/daemon/server/routes/registerRunGetRoute.ts +0 -25
- package/src/daemon/server/routes/registerRunLogsRoute.ts +0 -32
- package/src/daemon/server/routes/registerShutdownRoute.ts +0 -9
- package/src/daemon/server/startServer.ts +0 -23
- package/src/db/getMigrationsDir.ts +0 -5
- package/src/db/migrateDatabase.ts +0 -21
- package/src/db/openDatabase.ts +0 -12
- package/src/db/schema/jobs.ts +0 -26
- package/src/db/schema/jobsSchemas.ts +0 -10
- package/src/db/schema/runs.ts +0 -23
- package/src/db/schema/runsSchemas.ts +0 -10
- package/src/db/schema.ts +0 -5
- package/src/shared/auth/createToken.ts +0 -5
- package/src/shared/events/appendEvent.ts +0 -16
- package/src/shared/jobs/createCommandSchema.ts +0 -5
- package/src/shared/jobs/createEnvSchema.ts +0 -5
- package/src/shared/jobs/createJobInputSchema.ts +0 -31
- package/src/shared/jobs/createTomlJobSchema.ts +0 -31
- package/src/shared/jobs/formatJobRow.ts +0 -14
- package/src/shared/jobs/isOverlapPolicy.ts +0 -5
- package/src/shared/jobs/parseCommand.ts +0 -6
- package/src/shared/jobs/parseEnv.ts +0 -10
- package/src/shared/jobs/parseJobsToml.ts +0 -36
- package/src/shared/jobs/readJobsToml.ts +0 -17
- package/src/shared/jobs/serializeCommand.ts +0 -6
- package/src/shared/jobs/serializeEnv.ts +0 -6
- package/src/shared/jobs/serializeJobsToml.ts +0 -45
- package/src/shared/jobs/writeJobsToml.ts +0 -12
- package/src/shared/paths/ensureDir.ts +0 -6
- package/src/shared/paths/getConfigDir.ts +0 -6
- package/src/shared/paths/getEventsPath.ts +0 -6
- package/src/shared/paths/getJobRunsDir.ts +0 -7
- package/src/shared/paths/getJobsTomlPath.ts +0 -6
- package/src/shared/paths/getPaths.ts +0 -16
- package/src/shared/paths/getRunOutputPaths.ts +0 -10
- package/src/shared/paths/getRunsDir.ts +0 -7
- package/src/shared/paths/getStateDir.ts +0 -8
- package/src/shared/rpc/createRpcClient.ts +0 -20
- package/src/shared/runs/formatRunRow.ts +0 -6
- package/src/shared/state/daemonStateSchema.ts +0 -13
- package/src/shared/state/getDaemonStatePath.ts +0 -6
- package/src/shared/state/readDaemonState.ts +0 -14
- package/src/shared/state/removeDaemonState.ts +0 -9
- package/src/shared/state/writeDaemonState.ts +0 -8
- package/src/shared/utils/isRecord.ts +0 -5
- package/src/shared/version.ts +0 -5
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { appendFileSync } from "node:fs";
|
|
2
|
-
import getEventsPath from "../paths/getEventsPath";
|
|
3
|
-
|
|
4
|
-
export default function appendEvent(
|
|
5
|
-
type: string,
|
|
6
|
-
payload?: Record<string, unknown>,
|
|
7
|
-
) {
|
|
8
|
-
const record = {
|
|
9
|
-
type,
|
|
10
|
-
timestamp: new Date().toISOString(),
|
|
11
|
-
payload,
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const line = `${JSON.stringify(record)}\n`;
|
|
15
|
-
appendFileSync(getEventsPath(), line, "utf-8");
|
|
16
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import createCommandSchema from "./createCommandSchema";
|
|
3
|
-
import createEnvSchema from "./createEnvSchema";
|
|
4
|
-
|
|
5
|
-
export default function createJobInputSchema() {
|
|
6
|
-
return z
|
|
7
|
-
.object({
|
|
8
|
-
name: z.string().min(1),
|
|
9
|
-
description: z.string().min(1).optional(),
|
|
10
|
-
command: createCommandSchema(),
|
|
11
|
-
cwd: z.string().min(1).optional(),
|
|
12
|
-
env: createEnvSchema().optional(),
|
|
13
|
-
schedule: z.string().min(1).optional(),
|
|
14
|
-
runAt: z.string().datetime().optional(),
|
|
15
|
-
timezone: z.string().min(1).optional(),
|
|
16
|
-
timeoutMs: z.number().int().positive().optional(),
|
|
17
|
-
paused: z.boolean().optional(),
|
|
18
|
-
overlapPolicy: z.enum(["skip", "allow"]).optional(),
|
|
19
|
-
})
|
|
20
|
-
.superRefine((value, ctx) => {
|
|
21
|
-
const hasSchedule = Boolean(value.schedule);
|
|
22
|
-
const hasRunAt = Boolean(value.runAt);
|
|
23
|
-
if (hasSchedule === hasRunAt) {
|
|
24
|
-
ctx.addIssue({
|
|
25
|
-
code: z.ZodIssueCode.custom,
|
|
26
|
-
message: "Provide schedule or runAt",
|
|
27
|
-
path: ["schedule"],
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import createCommandSchema from "./createCommandSchema";
|
|
3
|
-
import createEnvSchema from "./createEnvSchema";
|
|
4
|
-
|
|
5
|
-
export default function createTomlJobSchema() {
|
|
6
|
-
return z
|
|
7
|
-
.object({
|
|
8
|
-
id: z.string().min(1).optional(),
|
|
9
|
-
command: createCommandSchema(),
|
|
10
|
-
cwd: z.string().min(1).optional(),
|
|
11
|
-
env: createEnvSchema().optional(),
|
|
12
|
-
schedule: z.string().min(1).optional(),
|
|
13
|
-
run_at: z.string().datetime().optional(),
|
|
14
|
-
timezone: z.string().min(1).optional(),
|
|
15
|
-
timeout_ms: z.number().int().positive().optional(),
|
|
16
|
-
paused: z.boolean().optional(),
|
|
17
|
-
overlap_policy: z.enum(["skip", "allow"]).optional(),
|
|
18
|
-
description: z.string().min(1).optional(),
|
|
19
|
-
})
|
|
20
|
-
.superRefine((value, ctx) => {
|
|
21
|
-
const hasSchedule = Boolean(value.schedule);
|
|
22
|
-
const hasRunAt = Boolean(value.run_at);
|
|
23
|
-
if (hasSchedule === hasRunAt) {
|
|
24
|
-
ctx.addIssue({
|
|
25
|
-
code: z.ZodIssueCode.custom,
|
|
26
|
-
message: "Provide schedule or run_at",
|
|
27
|
-
path: ["schedule"],
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import createJobsSchemas from "../../db/schema/jobsSchemas";
|
|
2
|
-
import parseCommand from "./parseCommand";
|
|
3
|
-
import parseEnv from "./parseEnv";
|
|
4
|
-
|
|
5
|
-
export default function formatJobRow(row: unknown) {
|
|
6
|
-
const schema = createJobsSchemas().select;
|
|
7
|
-
const parsed = schema.parse(row);
|
|
8
|
-
|
|
9
|
-
return {
|
|
10
|
-
...parsed,
|
|
11
|
-
command: parseCommand(parsed.command),
|
|
12
|
-
env: parseEnv(parsed.env),
|
|
13
|
-
};
|
|
14
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import toml from "@iarna/toml";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
import isRecord from "../utils/isRecord";
|
|
4
|
-
import createTomlJobSchema from "./createTomlJobSchema";
|
|
5
|
-
|
|
6
|
-
export default function parseJobsToml(content: string) {
|
|
7
|
-
const parsed = toml.parse(content);
|
|
8
|
-
if (!isRecord(parsed)) {
|
|
9
|
-
throw new Error("Invalid jobs.toml");
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const jobsValue = parsed.jobs;
|
|
13
|
-
if (jobsValue === undefined) {
|
|
14
|
-
return [];
|
|
15
|
-
}
|
|
16
|
-
if (!isRecord(jobsValue)) {
|
|
17
|
-
throw new Error("Invalid jobs section");
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const namedSchema = createTomlJobSchema().and(
|
|
21
|
-
z.object({
|
|
22
|
-
name: z.string().min(1),
|
|
23
|
-
}),
|
|
24
|
-
);
|
|
25
|
-
const result: Array<z.infer<typeof namedSchema>> = [];
|
|
26
|
-
|
|
27
|
-
for (const [name, value] of Object.entries(jobsValue)) {
|
|
28
|
-
if (!isRecord(value)) {
|
|
29
|
-
throw new Error(`Invalid job entry: ${name}`);
|
|
30
|
-
}
|
|
31
|
-
const job = namedSchema.parse({ name, ...value });
|
|
32
|
-
result.push(job);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return result;
|
|
36
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import getJobsTomlPath from "../paths/getJobsTomlPath";
|
|
3
|
-
import parseJobsToml from "./parseJobsToml";
|
|
4
|
-
|
|
5
|
-
export default function readJobsToml() {
|
|
6
|
-
const path = getJobsTomlPath();
|
|
7
|
-
if (!existsSync(path)) {
|
|
8
|
-
return [];
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const content = readFileSync(path, "utf-8");
|
|
12
|
-
if (!content.trim()) {
|
|
13
|
-
return [];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return parseJobsToml(content);
|
|
17
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import type { JsonMap } from "@iarna/toml";
|
|
2
|
-
import toml from "@iarna/toml";
|
|
3
|
-
import type formatJobRow from "./formatJobRow";
|
|
4
|
-
|
|
5
|
-
export default function serializeJobsToml(
|
|
6
|
-
jobs: Array<ReturnType<typeof formatJobRow>>,
|
|
7
|
-
) {
|
|
8
|
-
const jobsSection: JsonMap = {};
|
|
9
|
-
const doc: JsonMap = { jobs: jobsSection };
|
|
10
|
-
|
|
11
|
-
for (const job of jobs) {
|
|
12
|
-
const entry: JsonMap = {
|
|
13
|
-
id: job.id,
|
|
14
|
-
command: job.command,
|
|
15
|
-
paused: job.paused,
|
|
16
|
-
overlap_policy: job.overlapPolicy,
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
if (job.description) {
|
|
20
|
-
entry.description = job.description;
|
|
21
|
-
}
|
|
22
|
-
if (job.cwd) {
|
|
23
|
-
entry.cwd = job.cwd;
|
|
24
|
-
}
|
|
25
|
-
if (job.env) {
|
|
26
|
-
entry.env = job.env;
|
|
27
|
-
}
|
|
28
|
-
if (job.scheduleType === "cron" && job.cron) {
|
|
29
|
-
entry.schedule = job.cron;
|
|
30
|
-
}
|
|
31
|
-
if (job.scheduleType === "once" && job.runAt) {
|
|
32
|
-
entry.run_at = job.runAt;
|
|
33
|
-
}
|
|
34
|
-
if (job.timezone) {
|
|
35
|
-
entry.timezone = job.timezone;
|
|
36
|
-
}
|
|
37
|
-
if (job.timeoutMs) {
|
|
38
|
-
entry.timeout_ms = job.timeoutMs;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
jobsSection[job.name] = entry;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return toml.stringify(doc);
|
|
45
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { writeFileSync } from "node:fs";
|
|
2
|
-
import getJobsTomlPath from "../paths/getJobsTomlPath";
|
|
3
|
-
import type formatJobRow from "./formatJobRow";
|
|
4
|
-
import serializeJobsToml from "./serializeJobsToml";
|
|
5
|
-
|
|
6
|
-
export default function writeJobsToml(
|
|
7
|
-
jobs: Array<ReturnType<typeof formatJobRow>>,
|
|
8
|
-
) {
|
|
9
|
-
const path = getJobsTomlPath();
|
|
10
|
-
const content = serializeJobsToml(jobs);
|
|
11
|
-
writeFileSync(path, content, "utf-8");
|
|
12
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import envPaths from "env-paths";
|
|
2
|
-
|
|
3
|
-
export default function getPaths() {
|
|
4
|
-
const root = process.env.CRND_PATHS_ROOT;
|
|
5
|
-
if (root) {
|
|
6
|
-
return {
|
|
7
|
-
data: root,
|
|
8
|
-
config: root,
|
|
9
|
-
cache: root,
|
|
10
|
-
log: root,
|
|
11
|
-
temp: root,
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
return envPaths("crnd");
|
|
16
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import getJobRunsDir from "./getJobRunsDir";
|
|
3
|
-
|
|
4
|
-
export default function getRunOutputPaths(jobId: string, runId: string) {
|
|
5
|
-
const dir = getJobRunsDir(jobId);
|
|
6
|
-
return {
|
|
7
|
-
stdoutPath: path.join(dir, `${runId}.out`),
|
|
8
|
-
stderrPath: path.join(dir, `${runId}.err`),
|
|
9
|
-
};
|
|
10
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { hc } from "hono/client";
|
|
2
|
-
import type { AppType } from "../../daemon/server/createApp";
|
|
3
|
-
import readDaemonState from "../state/readDaemonState";
|
|
4
|
-
|
|
5
|
-
export default function createRpcClient() {
|
|
6
|
-
try {
|
|
7
|
-
const state = readDaemonState();
|
|
8
|
-
if (!state) {
|
|
9
|
-
return null;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
return hc<AppType>(`http://127.0.0.1:${state.port}`, {
|
|
13
|
-
headers: {
|
|
14
|
-
Authorization: `Bearer ${state.token}`,
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
|
-
} catch {
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
|
|
3
|
-
export default function createDaemonStateSchema() {
|
|
4
|
-
return z.object({
|
|
5
|
-
port: z.number().int().positive(),
|
|
6
|
-
token: z.string().min(1),
|
|
7
|
-
pid: z.number().int().positive(),
|
|
8
|
-
startedAt: z.string().datetime(),
|
|
9
|
-
version: z.string().min(1),
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export type DaemonState = z.infer<ReturnType<typeof createDaemonStateSchema>>;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import createDaemonStateSchema from "./daemonStateSchema";
|
|
3
|
-
import getDaemonStatePath from "./getDaemonStatePath";
|
|
4
|
-
|
|
5
|
-
export default function readDaemonState() {
|
|
6
|
-
const path = getDaemonStatePath();
|
|
7
|
-
if (!existsSync(path)) {
|
|
8
|
-
return null;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const raw = readFileSync(path, "utf-8");
|
|
12
|
-
const parsed = JSON.parse(raw);
|
|
13
|
-
return createDaemonStateSchema().parse(parsed);
|
|
14
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { writeFileSync } from "node:fs";
|
|
2
|
-
import type { DaemonState } from "./daemonStateSchema";
|
|
3
|
-
import getDaemonStatePath from "./getDaemonStatePath";
|
|
4
|
-
|
|
5
|
-
export default function writeDaemonState(state: DaemonState) {
|
|
6
|
-
const path = getDaemonStatePath();
|
|
7
|
-
writeFileSync(path, `${JSON.stringify(state, null, 2)}\n`, "utf-8");
|
|
8
|
-
}
|