diff --git a/src/config.test.ts b/src/config.test.ts index ee0cadc..93927b2 100644 --- a/src/config.test.ts +++ b/src/config.test.ts @@ -1,7 +1,7 @@ import assert from "node:assert/strict"; import test from "node:test"; -import { loadConfig, parseDuration } from "./config.ts"; +import { loadConfig, parseDurationToMs } from "./config.ts"; const baseEnv = { ATPROTO_HANDLE: "test.example", @@ -50,10 +50,11 @@ test("invalid day and time throw", () => { }); test("parseDuration handles Go-style durations", () => { - assert.equal(parseDuration("30s"), 30_000); - assert.equal(parseDuration("5m"), 300_000); - assert.equal(parseDuration("1h30m"), 5_400_000); - assert.throws(() => parseDuration("5"), /invalid duration/); - assert.throws(() => parseDuration("fast"), /invalid duration/); - assert.throws(() => parseDuration(""), /invalid duration/); + assert.equal(parseDurationToMs("30s"), 30_000); + assert.equal(parseDurationToMs("5m"), 300_000); + assert.equal(parseDurationToMs("1h30m"), 5_400_000); + assert.throws(() => parseDurationToMs("5"), /invalid duration/); + assert.throws(() => parseDurationToMs("fast"), /invalid duration/); + assert.throws(() => parseDurationToMs(""), /invalid duration/); + assert.throws(() => parseDurationToMs("249ms"), /must be at least 250ms/); }); diff --git a/src/config.ts b/src/config.ts index 5483c3b..bbaff4d 100644 --- a/src/config.ts +++ b/src/config.ts @@ -50,7 +50,7 @@ export function loadConfig(env: Record = process.env weeklyNotifyDay: dayIndex + 1, weeklyNotifyHour: hour, weeklyNotifyMinute: minute, - checkIntervalMs: parseDuration(required("CHECK_INTERVAL")), + checkIntervalMs: parseDurationToMs(required("CHECK_INTERVAL")), enableStdout: env.ENABLE_STDOUT === "true", openMeetBaseUrl: env.OPENMEET_BASE_URL || "https://api.openmeet.net", atprotoPdsUrl: env.ATPROTO_PDS_URL || undefined, @@ -64,8 +64,7 @@ const DURATION_UNITS: Record = { h: 3_600_000, }; -// Parses Go-style durations like "30s", "5m", "1h30m" into milliseconds. -export function parseDuration(input: string): number { +export function parseDurationToMs(input: string): number { let total = 0; let matched = ""; for (const m of input.matchAll(/(\d+)(ms|s|m|h)/g)) { @@ -75,5 +74,8 @@ export function parseDuration(input: string): number { if (matched !== input || input === "") { throw new Error(`invalid duration "${input}" (expected e.g. "30s", "5m", "1h")`); } + if (total < 250) { + throw new Error("check duration must be at least 250ms"); + } return total; }