mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-21 05:32:53 +00:00
refactor: dedupe cron lowercase helpers
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import { z, type ZodType } from "zod";
|
||||
import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
|
||||
|
||||
const trimStringPreprocess = (value: unknown) => (typeof value === "string" ? value.trim() : value);
|
||||
|
||||
const trimLowercaseStringPreprocess = (value: unknown) =>
|
||||
typeof value === "string" ? value.trim().toLowerCase() : value;
|
||||
normalizeOptionalLowercaseString(value) ?? value;
|
||||
|
||||
export const DeliveryModeFieldSchema = z
|
||||
.preprocess(trimLowercaseStringPreprocess, z.enum(["deliver", "announce", "none", "webhook"]))
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import type { CronFailureDestinationConfig } from "../config/types.cron.js";
|
||||
import { normalizeOptionalString, normalizeOptionalThreadValue } from "../shared/string-coerce.js";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalLowercaseString,
|
||||
normalizeOptionalString,
|
||||
normalizeOptionalThreadValue,
|
||||
} from "../shared/string-coerce.js";
|
||||
import type { CronDelivery, CronDeliveryMode, CronJob, CronMessageChannel } from "./types.js";
|
||||
|
||||
export type CronDeliveryPlan = {
|
||||
@@ -14,10 +19,7 @@ export type CronDeliveryPlan = {
|
||||
};
|
||||
|
||||
function normalizeChannel(value: unknown): CronMessageChannel | undefined {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const trimmed = value.trim().toLowerCase();
|
||||
const trimmed = normalizeOptionalLowercaseString(value);
|
||||
if (!trimmed) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -28,7 +30,8 @@ export function resolveCronDeliveryPlan(job: CronJob): CronDeliveryPlan {
|
||||
const delivery = job.delivery;
|
||||
const hasDelivery = delivery && typeof delivery === "object";
|
||||
const rawMode = hasDelivery ? (delivery as { mode?: unknown }).mode : undefined;
|
||||
const normalizedMode = typeof rawMode === "string" ? rawMode.trim().toLowerCase() : rawMode;
|
||||
const normalizedMode =
|
||||
typeof rawMode === "string" ? normalizeLowercaseStringOrEmpty(rawMode) : rawMode;
|
||||
const mode =
|
||||
normalizedMode === "announce"
|
||||
? "announce"
|
||||
@@ -97,10 +100,7 @@ export type CronFailureDestinationInput = {
|
||||
};
|
||||
|
||||
function normalizeFailureMode(value: unknown): "announce" | "webhook" | undefined {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const trimmed = value.trim().toLowerCase();
|
||||
const trimmed = normalizeOptionalLowercaseString(value);
|
||||
if (trimmed === "announce" || trimmed === "webhook") {
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { sanitizeAgentId } from "../routing/session-key.js";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalLowercaseString,
|
||||
} from "../shared/string-coerce.js";
|
||||
import { isRecord } from "../utils.js";
|
||||
import {
|
||||
TimeoutSecondsFieldSchema,
|
||||
@@ -61,7 +65,7 @@ function normalizeTrimmedStringArray(
|
||||
|
||||
function coerceSchedule(schedule: UnknownRecord) {
|
||||
const next: UnknownRecord = { ...schedule };
|
||||
const rawKind = typeof schedule.kind === "string" ? schedule.kind.trim().toLowerCase() : "";
|
||||
const rawKind = normalizeLowercaseStringOrEmpty(schedule.kind);
|
||||
const kind = rawKind === "at" || rawKind === "every" || rawKind === "cron" ? rawKind : undefined;
|
||||
const exprRaw = typeof schedule.expr === "string" ? schedule.expr.trim() : "";
|
||||
const legacyCronRaw = typeof schedule.cron === "string" ? schedule.cron.trim() : "";
|
||||
@@ -141,7 +145,7 @@ function coerceSchedule(schedule: UnknownRecord) {
|
||||
|
||||
function coercePayload(payload: UnknownRecord) {
|
||||
const next: UnknownRecord = { ...payload };
|
||||
const kindRaw = typeof next.kind === "string" ? next.kind.trim().toLowerCase() : "";
|
||||
const kindRaw = normalizeLowercaseStringOrEmpty(next.kind);
|
||||
if (kindRaw === "agentturn") {
|
||||
next.kind = "agentTurn";
|
||||
} else if (kindRaw === "systemevent") {
|
||||
@@ -316,7 +320,7 @@ function normalizeSessionTarget(raw: unknown) {
|
||||
return undefined;
|
||||
}
|
||||
const trimmed = raw.trim();
|
||||
const lower = trimmed.toLowerCase();
|
||||
const lower = normalizeLowercaseStringOrEmpty(trimmed);
|
||||
if (lower === "main" || lower === "isolated" || lower === "current") {
|
||||
return lower;
|
||||
}
|
||||
@@ -331,7 +335,7 @@ function normalizeWakeMode(raw: unknown) {
|
||||
if (typeof raw !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const trimmed = raw.trim().toLowerCase();
|
||||
const trimmed = normalizeOptionalLowercaseString(raw);
|
||||
if (trimmed === "now" || trimmed === "next-heartbeat") {
|
||||
return trimmed;
|
||||
}
|
||||
@@ -439,7 +443,7 @@ export function normalizeCronJobInput(
|
||||
if (typeof enabled === "boolean") {
|
||||
next.enabled = enabled;
|
||||
} else if (typeof enabled === "string") {
|
||||
const trimmed = enabled.trim().toLowerCase();
|
||||
const trimmed = normalizeOptionalLowercaseString(enabled);
|
||||
if (trimmed === "true") {
|
||||
next.enabled = true;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,10 @@ import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { parseByteSize } from "../cli/parse-bytes.js";
|
||||
import type { CronConfig } from "../config/types.cron.js";
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString,
|
||||
} from "../shared/string-coerce.js";
|
||||
import type { CronDeliveryStatus, CronRunStatus, CronRunTelemetry } from "./types.js";
|
||||
|
||||
export type CronRunLogEntry = {
|
||||
@@ -361,7 +364,7 @@ export async function readCronRunLogEntriesPage(
|
||||
const raw = await fs.readFile(path.resolve(filePath), "utf-8").catch(() => "");
|
||||
const statuses = normalizeRunStatuses(opts);
|
||||
const deliveryStatuses = normalizeDeliveryStatuses(opts);
|
||||
const query = opts?.query?.trim().toLowerCase() ?? "";
|
||||
const query = normalizeLowercaseStringOrEmpty(opts?.query);
|
||||
const sortDir: CronRunLogSortDir = opts?.sortDir === "asc" ? "asc" : "desc";
|
||||
const all = parseAllRunLogEntries(raw, { jobId: opts?.jobId });
|
||||
const filtered = filterRunLogEntries(all, {
|
||||
@@ -394,7 +397,7 @@ export async function readCronRunLogEntriesPageAll(
|
||||
const limit = Math.max(1, Math.min(200, Math.floor(opts.limit ?? 50)));
|
||||
const statuses = normalizeRunStatuses(opts);
|
||||
const deliveryStatuses = normalizeDeliveryStatuses(opts);
|
||||
const query = opts.query?.trim().toLowerCase() ?? "";
|
||||
const query = normalizeLowercaseStringOrEmpty(opts.query);
|
||||
const sortDir: CronRunLogSortDir = opts.sortDir === "asc" ? "asc" : "desc";
|
||||
const runsDir = path.resolve(path.dirname(path.resolve(opts.storePath)), "runs");
|
||||
const files = await fs.readdir(runsDir, { withFileTypes: true }).catch(() => []);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { enqueueCommandInLane } from "../../process/command-queue.js";
|
||||
import { CommandLane } from "../../process/lanes.js";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js";
|
||||
import {
|
||||
completeTaskRunByRunId,
|
||||
createRunningTaskRun,
|
||||
@@ -220,7 +221,7 @@ function sortJobs(jobs: CronJob[], sortBy: CronJobsSortBy, sortDir: CronSortDir)
|
||||
export async function listPage(state: CronServiceState, opts?: CronListPageOptions) {
|
||||
return await locked(state, async () => {
|
||||
await ensureLoadedForRead(state);
|
||||
const query = opts?.query?.trim().toLowerCase() ?? "";
|
||||
const query = normalizeLowercaseStringOrEmpty(opts?.query);
|
||||
const enabledFilter = resolveEnabledFilter(opts);
|
||||
const sortBy = opts?.sortBy ?? "nextRunAtMs";
|
||||
const sortDir = opts?.sortDir ?? "asc";
|
||||
|
||||
@@ -2,6 +2,7 @@ import { resolveFailoverReasonFromError } from "../../agents/failover-error.js";
|
||||
import type { CronConfig, CronRetryOn } from "../../config/types.cron.js";
|
||||
import type { HeartbeatRunResult } from "../../infra/heartbeat-wake.js";
|
||||
import { DEFAULT_AGENT_ID } from "../../routing/session-key.js";
|
||||
import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js";
|
||||
import {
|
||||
completeTaskRunByRunId,
|
||||
createRunningTaskRun,
|
||||
@@ -262,10 +263,7 @@ function resolveDeliveryStatus(params: { job: CronJob; delivered?: boolean }): C
|
||||
}
|
||||
|
||||
function normalizeCronMessageChannel(input: unknown): CronMessageChannel | undefined {
|
||||
if (typeof input !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const channel = input.trim().toLowerCase();
|
||||
const channel = normalizeOptionalLowercaseString(input);
|
||||
return channel ? (channel as CronMessageChannel) : undefined;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user