From fa3f51729c248266446b5b3971bc64cb5728965c Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Wed, 12 Mar 2025 12:54:22 -0300 Subject: [PATCH 1/3] update readme content and shuffle some things --- README.md | 84 ++++++++++++++++++++++++++++++++++++++++++------- src/cli.ts | 22 +++++++------ src/cron.ts | 7 +++++ src/nlp.test.ts | 6 ++++ 4 files changed, 98 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 0500b26..41ad5fe 100644 --- a/README.md +++ b/README.md @@ -5,19 +5,12 @@ a typescript library and cli for using cron on any platform powered by [Deno.cron](https://docs.deno.com/examples/cron/) -## cli - -### usage - -```bash -cronx 'echo hello world from the future' -n "every tuesday at 3pm" -# ? Do you want to schedule 'echo hello world from the future' to run 'At 3:00 PM on Tuesday'? (Y/n) › -# ❯ 0 15 * * 2 -``` - ## library -### usage +### nlp + +The `nlp` module provides functions for converting between natural language and +cron tab expressions. ```typescript import { @@ -36,7 +29,74 @@ Deno.cron('my job', cronTab, () => { }) ``` -## installation +### cronx + +The `cronx` module provides a simple interface for scheduling cron jobs with +command-line executables or async functions. + +```typescript +import { + scheduleCronWithExecutable, + scheduleCronWithFunction, +} from "@polyseam/cronx"; + +const expression = "0 15 * * 2"; // every tuesday at 3pm local time +const executable = 'echo "hello world from the future"'; + +scheduleCronWithExecutable(executable, { + cronxEpression: expression, + label: "hello-world", +}); + +scheduleCronWithFunction(async () => { + const res = await fetch("https://api.example.com"); + if (res.ok) { + console.log("service is live!"); + } else { + console.log("service is down!"); + } +}, { + cronxEpression: "* 0,8,16 * * *", // every 8 hours + label: "uptime", + offset: 0, // UTC time is offset=0 +}); +``` + +### cron + +The `cron` module provides helpers for taking user friendly cron expressions and +converting them to [Deno.cron]() compatible expressions. + +```typescript +import { + convertCronxExpressionToDenoCronExpression, + getLocalUTCOffset, +} from "@polyseam/cronx/cron"; + +const worknights = "0 21 * * 0-4"; // Sunday is 0, unlike in Deno.cron + +const timezoneAdjustedCronExpression = + convertCronxExpressionToDenoCronExpression( + worknights, + getLocalUTCOffset(), + ); + +Deno.cron("set-alarms", timezoneAdjustedCronExpression, () => { + console.log("don't forget to set your alarms for tomorrow!"); +}); +``` + +## cli + +### usage + +```bash +cronx 'echo hello world from the future' -n "every tuesday at 3pm" +# ? Do you want to schedule 'echo hello world from the future' to run 'At 3:00 PM on Tuesday'? (Y/n) › +# ❯ 0 15 * * 2 +``` + +### installation Shell (Mac, Linux): diff --git a/src/cli.ts b/src/cli.ts index ca815f7..7f064ea 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,27 +1,30 @@ import { Command, ValidationError } from "@cliffy/command"; import { Confirm, Input, Select } from "@cliffy/prompt"; import { colors } from "@cliffy/ansi/colors"; + import type { LogLevel } from "@polyseam/cconsole"; +import deno_json from "../deno.json" with { type: "json" }; + import { cconsole } from "cconsole"; import { runExecutable } from "src/executables.ts"; -import { JobLogger } from "./JobLogger.ts"; - -import deno_json from "../deno.json" with { type: "json" }; +import { JobLogger } from "src/JobLogger.ts"; import { scheduleCronWithExecutable, validateJobLabel } from "src/cronx.ts"; import { getCronTabExpressionForNaturalLanguageSchedule, getNaturalLanguageScheduleForCronTabExpression, -} from "./nlp.ts"; +} from "src/nlp.ts"; + +import { getLocalUTCOffset } from "src/cron.ts"; const DEFAULT_SCHEDULE_OPTIONS = [ { name: "Every minute", value: "* * * * *" }, { name: "Every hour", value: "0 * * * *" }, - { name: "Every day at midnight", value: "0 0 * * *" }, + { name: "Every day at 12am", value: "0 0 * * *" }, { name: "Every 15 minutes", value: "*/15 * * * *" }, { name: "Every 30 minutes", value: "*/30 * * * *" }, { name: "Every Sunday at 12am", value: "0 0 * * 0" }, @@ -41,7 +44,7 @@ export const cli = new Command().name("cronx") "Natural language description of schedule (e.g., 'every day at 2pm')", ) .option("--offset ", "The timezone offset in hours", { - default: new Date().getTimezoneOffset() / -60, + default: getLocalUTCOffset(), }) .option("-l, --label ", "A label for the job") .option("-v, --verbosity ", "Set the log level", { @@ -73,6 +76,7 @@ export const cli = new Command().name("cronx") const { tab, offset, + suppressStdio, } = options; if (options.label) { @@ -176,14 +180,14 @@ export const cli = new Command().name("cronx") }'(${cronExpression})`, ); - const { suppressStdio } = options; - const jobLogger = new JobLogger(label); if (options.run) { cconsole.debug(); cconsole.debug( - `Running job: ${job} ${suppressStdio ? "without" : "with"} stdio`, + `Running job: ${job} ${ + suppressStdio ? "and suppressing output to" : "writing output to" + } stdout and stderr`, ); cconsole.debug(); await runExecutable(job, { diff --git a/src/cron.ts b/src/cron.ts index 4d47da7..a1083f1 100644 --- a/src/cron.ts +++ b/src/cron.ts @@ -141,3 +141,10 @@ export function convertCronxExpressionToDenoCronExpression( offset, ); } + +/** + * Gets the local timezone offset in hours. + * + * @returns The local timezone offset in hours (e.g., -5 for EST, +1 for CET) + */ +export const getLocalUTCOffset = () => (new Date().getTimezoneOffset() / -60); diff --git a/src/nlp.test.ts b/src/nlp.test.ts index c4d6131..46d8001 100644 --- a/src/nlp.test.ts +++ b/src/nlp.test.ts @@ -348,6 +348,12 @@ Deno.test("Monthly and yearly patterns", async (t) => { ), "0 20 * * 6", ); + assertEquals( + getCronTabExpressionForNaturalLanguageSchedule( + "wednesdays and fridays at 3:30pm", + ), + "30 15 * * 3,5", + ); }); await t.step("yearly patterns", () => { From efc8c2f19903827b0ce2e0531d75cba4b714795f Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Wed, 12 Mar 2025 12:55:44 -0300 Subject: [PATCH 2/3] cli first in readme --- README.md | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 41ad5fe..4893510 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,30 @@ a typescript library and cli for using cron on any platform powered by [Deno.cron](https://docs.deno.com/examples/cron/) +## cli + +### usage + +```bash +cronx 'echo hello world from the future' -n "every tuesday at 3pm" +# ? Do you want to schedule 'echo hello world from the future' to run 'At 3:00 PM on Tuesday'? (Y/n) › +# ❯ 0 15 * * 2 +``` + +### installation + +Shell (Mac, Linux): + +```bash +curl -fsSL https://raw.githubusercontent.com/polyseam/cronx/main/install.sh | sh +``` + +PowerShell (Windows): + +```powershell +irm https://raw.githubusercontent.com/polyseam/cronx/main/install.ps1 | iex +``` + ## library ### nlp @@ -85,27 +109,3 @@ Deno.cron("set-alarms", timezoneAdjustedCronExpression, () => { console.log("don't forget to set your alarms for tomorrow!"); }); ``` - -## cli - -### usage - -```bash -cronx 'echo hello world from the future' -n "every tuesday at 3pm" -# ? Do you want to schedule 'echo hello world from the future' to run 'At 3:00 PM on Tuesday'? (Y/n) › -# ❯ 0 15 * * 2 -``` - -### installation - -Shell (Mac, Linux): - -```bash -curl -fsSL https://raw.githubusercontent.com/polyseam/cronx/main/install.sh | sh -``` - -PowerShell (Windows): - -```powershell -irm https://raw.githubusercontent.com/polyseam/cronx/main/install.ps1 | iex -``` From 34aaff86dcff01e3a0ad0c76f7c80148ed3b458f Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Wed, 12 Mar 2025 12:56:56 -0300 Subject: [PATCH 3/3] fmt --- src/cron.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cron.ts b/src/cron.ts index a1083f1..2534bdc 100644 --- a/src/cron.ts +++ b/src/cron.ts @@ -147,4 +147,5 @@ export function convertCronxExpressionToDenoCronExpression( * * @returns The local timezone offset in hours (e.g., -5 for EST, +1 for CET) */ -export const getLocalUTCOffset = () => (new Date().getTimezoneOffset() / -60); +export const getLocalUTCOffset = + (): number => (new Date().getTimezoneOffset() / -60);