import type { z } from "zod"; import { runPassiveAccountLifecycle } from "./channel-runtime.js"; import { createLoggerBackedRuntime } from "./runtime.js"; type PassiveChannelStatusSnapshot = { configured?: boolean; running?: boolean; lastStartAt?: number | null; lastStopAt?: number | null; lastError?: string | null; probe?: unknown; lastProbeAt?: number | null; }; type TrafficStatusSnapshot = { lastInboundAt?: number | null; lastOutboundAt?: number | null; }; type StoppableMonitor = { stop: () => void; }; type RequireOpenAllowFromFn = (params: { policy?: string; allowFrom?: Array; ctx: z.RefinementCtx; path: Array; message: string; }) => void; export function buildPassiveChannelStatusSummary( snapshot: PassiveChannelStatusSnapshot, extra?: TExtra, ) { return { configured: snapshot.configured ?? false, ...(extra ?? ({} as TExtra)), running: snapshot.running ?? false, lastStartAt: snapshot.lastStartAt ?? null, lastStopAt: snapshot.lastStopAt ?? null, lastError: snapshot.lastError ?? null, }; } export function buildPassiveProbedChannelStatusSummary( snapshot: PassiveChannelStatusSnapshot, extra?: TExtra, ) { return { ...buildPassiveChannelStatusSummary(snapshot, extra), probe: snapshot.probe, lastProbeAt: snapshot.lastProbeAt ?? null, }; } export function buildTrafficStatusSummary( snapshot?: TSnapshot | null, ) { return { lastInboundAt: snapshot?.lastInboundAt ?? null, lastOutboundAt: snapshot?.lastOutboundAt ?? null, }; } export async function runStoppablePassiveMonitor(params: { abortSignal: AbortSignal; start: () => Promise; }): Promise { await runPassiveAccountLifecycle({ abortSignal: params.abortSignal, start: params.start, stop: async (monitor) => { monitor.stop(); }, }); } export function resolveLoggerBackedRuntime( runtime: TRuntime | undefined, logger: Parameters[0]["logger"], ): TRuntime { return ( runtime ?? (createLoggerBackedRuntime({ logger, exitError: () => new Error("Runtime exit not available"), }) as TRuntime) ); } export function requireChannelOpenAllowFrom(params: { channel: string; policy?: string; allowFrom?: Array; ctx: z.RefinementCtx; requireOpenAllowFrom: RequireOpenAllowFromFn; }) { params.requireOpenAllowFrom({ policy: params.policy, allowFrom: params.allowFrom, ctx: params.ctx, path: ["allowFrom"], message: `channels.${params.channel}.dmPolicy="open" requires channels.${params.channel}.allowFrom to include "*"`, }); } export function readStatusIssueFields( value: unknown, fields: readonly TField[], ): Record | null { if (!value || typeof value !== "object") { return null; } const record = value as Record; const result = {} as Record; for (const field of fields) { result[field] = record[field]; } return result; } export function coerceStatusIssueAccountId(value: unknown): string | undefined { return typeof value === "string" ? value : typeof value === "number" ? String(value) : undefined; } export function createDeferred() { let resolve!: (value: T | PromiseLike) => void; let reject!: (reason?: unknown) => void; const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); return { promise, resolve, reject }; }