@karmaniverous/jeeves-runner 0.1.0 → 0.1.2
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/jeeves-runner/index.js +30 -3
- package/dist/mjs/index.js +30 -3
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { mkdirSync, readFileSync } from 'node:fs';
|
|
3
|
-
import { dirname, resolve } from 'node:path';
|
|
3
|
+
import { dirname, extname, resolve } from 'node:path';
|
|
4
4
|
import { Command } from 'commander';
|
|
5
5
|
import { DatabaseSync } from 'node:sqlite';
|
|
6
6
|
import { pino } from 'pino';
|
|
@@ -406,6 +406,23 @@ function parseResultLines(stdout) {
|
|
|
406
406
|
}
|
|
407
407
|
return { tokens, resultMeta };
|
|
408
408
|
}
|
|
409
|
+
/** Resolve the command and arguments for a script based on its file extension. */
|
|
410
|
+
function resolveCommand(script) {
|
|
411
|
+
const ext = extname(script).toLowerCase();
|
|
412
|
+
switch (ext) {
|
|
413
|
+
case '.ps1':
|
|
414
|
+
return {
|
|
415
|
+
command: 'powershell.exe',
|
|
416
|
+
args: ['-NoProfile', '-File', script],
|
|
417
|
+
};
|
|
418
|
+
case '.cmd':
|
|
419
|
+
case '.bat':
|
|
420
|
+
return { command: 'cmd.exe', args: ['/c', script] };
|
|
421
|
+
default:
|
|
422
|
+
// .js, .mjs, .cjs, or anything else: run with node
|
|
423
|
+
return { command: 'node', args: [script] };
|
|
424
|
+
}
|
|
425
|
+
}
|
|
409
426
|
/**
|
|
410
427
|
* Execute a job script as a child process. Captures output, parses metadata, enforces timeout.
|
|
411
428
|
*/
|
|
@@ -415,7 +432,8 @@ function executeJob(options) {
|
|
|
415
432
|
return new Promise((resolve) => {
|
|
416
433
|
const stdoutBuffer = new RingBuffer(100);
|
|
417
434
|
const stderrBuffer = new RingBuffer(100);
|
|
418
|
-
const
|
|
435
|
+
const { command, args } = resolveCommand(script);
|
|
436
|
+
const child = spawn(command, args, {
|
|
419
437
|
env: {
|
|
420
438
|
...process.env,
|
|
421
439
|
JR_DB_PATH: dbPath,
|
|
@@ -604,8 +622,17 @@ function createScheduler(deps) {
|
|
|
604
622
|
logger.info({ count: jobs.length }, 'Loading jobs');
|
|
605
623
|
for (const job of jobs) {
|
|
606
624
|
try {
|
|
625
|
+
const jobId = job.id;
|
|
607
626
|
const cron = new Cron(job.schedule, () => {
|
|
608
|
-
|
|
627
|
+
// Re-read job from DB to get current configuration
|
|
628
|
+
const currentJob = db
|
|
629
|
+
.prepare('SELECT * FROM jobs WHERE id = ? AND enabled = 1')
|
|
630
|
+
.get(jobId);
|
|
631
|
+
if (!currentJob) {
|
|
632
|
+
logger.warn({ jobId }, 'Job no longer exists or disabled, skipping');
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
void onScheduledRun(currentJob);
|
|
609
636
|
});
|
|
610
637
|
crons.set(job.id, cron);
|
|
611
638
|
logger.info({ jobId: job.id, schedule: job.schedule }, 'Scheduled job');
|
package/dist/mjs/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
import { mkdirSync, readFileSync } from 'node:fs';
|
|
3
3
|
import { pino } from 'pino';
|
|
4
4
|
import Fastify from 'fastify';
|
|
5
|
-
import { dirname } from 'node:path';
|
|
5
|
+
import { dirname, extname } from 'node:path';
|
|
6
6
|
import { DatabaseSync } from 'node:sqlite';
|
|
7
7
|
import { request } from 'node:https';
|
|
8
8
|
import { spawn } from 'node:child_process';
|
|
@@ -486,6 +486,23 @@ function parseResultLines(stdout) {
|
|
|
486
486
|
}
|
|
487
487
|
return { tokens, resultMeta };
|
|
488
488
|
}
|
|
489
|
+
/** Resolve the command and arguments for a script based on its file extension. */
|
|
490
|
+
function resolveCommand(script) {
|
|
491
|
+
const ext = extname(script).toLowerCase();
|
|
492
|
+
switch (ext) {
|
|
493
|
+
case '.ps1':
|
|
494
|
+
return {
|
|
495
|
+
command: 'powershell.exe',
|
|
496
|
+
args: ['-NoProfile', '-File', script],
|
|
497
|
+
};
|
|
498
|
+
case '.cmd':
|
|
499
|
+
case '.bat':
|
|
500
|
+
return { command: 'cmd.exe', args: ['/c', script] };
|
|
501
|
+
default:
|
|
502
|
+
// .js, .mjs, .cjs, or anything else: run with node
|
|
503
|
+
return { command: 'node', args: [script] };
|
|
504
|
+
}
|
|
505
|
+
}
|
|
489
506
|
/**
|
|
490
507
|
* Execute a job script as a child process. Captures output, parses metadata, enforces timeout.
|
|
491
508
|
*/
|
|
@@ -495,7 +512,8 @@ function executeJob(options) {
|
|
|
495
512
|
return new Promise((resolve) => {
|
|
496
513
|
const stdoutBuffer = new RingBuffer(100);
|
|
497
514
|
const stderrBuffer = new RingBuffer(100);
|
|
498
|
-
const
|
|
515
|
+
const { command, args } = resolveCommand(script);
|
|
516
|
+
const child = spawn(command, args, {
|
|
499
517
|
env: {
|
|
500
518
|
...process.env,
|
|
501
519
|
JR_DB_PATH: dbPath,
|
|
@@ -684,8 +702,17 @@ function createScheduler(deps) {
|
|
|
684
702
|
logger.info({ count: jobs.length }, 'Loading jobs');
|
|
685
703
|
for (const job of jobs) {
|
|
686
704
|
try {
|
|
705
|
+
const jobId = job.id;
|
|
687
706
|
const cron = new Cron(job.schedule, () => {
|
|
688
|
-
|
|
707
|
+
// Re-read job from DB to get current configuration
|
|
708
|
+
const currentJob = db
|
|
709
|
+
.prepare('SELECT * FROM jobs WHERE id = ? AND enabled = 1')
|
|
710
|
+
.get(jobId);
|
|
711
|
+
if (!currentJob) {
|
|
712
|
+
logger.warn({ jobId }, 'Job no longer exists or disabled, skipping');
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
void onScheduledRun(currentJob);
|
|
689
716
|
});
|
|
690
717
|
crons.set(job.id, cron);
|
|
691
718
|
logger.info({ jobId: job.id, schedule: job.schedule }, 'Scheduled job');
|
package/package.json
CHANGED