Add command modules and tests; commit remaining changes

This commit is contained in:
Peter Steinberger
2025-11-25 00:12:12 +01:00
parent 52e0c8de25
commit 938e237411
31 changed files with 11269 additions and 7 deletions

44
src/commands/send.ts Normal file
View File

@@ -0,0 +1,44 @@
import { info } from "../globals.js";
import type { CliDeps, Provider, RuntimeEnv } from "../index.js";
export async function sendCommand(
opts: {
to: string;
message: string;
wait: string;
poll: string;
provider: Provider;
},
deps: CliDeps,
runtime: RuntimeEnv,
) {
deps.assertProvider(opts.provider);
const waitSeconds = Number.parseInt(opts.wait, 10);
const pollSeconds = Number.parseInt(opts.poll, 10);
if (Number.isNaN(waitSeconds) || waitSeconds < 0) {
throw new Error("Wait must be >= 0 seconds");
}
if (Number.isNaN(pollSeconds) || pollSeconds <= 0) {
throw new Error("Poll must be > 0 seconds");
}
if (opts.provider === "web") {
if (waitSeconds !== 0) {
runtime.log(info("Wait/poll are Twilio-only; ignored for provider=web."));
}
await deps.sendMessageWeb(opts.to, opts.message, { verbose: false });
return;
}
const result = await deps.sendMessage(opts.to, opts.message, runtime);
if (!result) return;
if (waitSeconds === 0) return;
await deps.waitForFinalStatus(
result.client,
result.sid,
waitSeconds,
pollSeconds,
runtime,
);
}

30
src/commands/status.ts Normal file
View File

@@ -0,0 +1,30 @@
import type { CliDeps, RuntimeEnv } from "../index.js";
import { formatMessageLine } from "../index.js";
export async function statusCommand(
opts: { limit: string; lookback: string; json?: boolean },
deps: CliDeps,
runtime: RuntimeEnv,
) {
const limit = Number.parseInt(opts.limit, 10);
const lookbackMinutes = Number.parseInt(opts.lookback, 10);
if (Number.isNaN(limit) || limit <= 0 || limit > 200) {
throw new Error("limit must be between 1 and 200");
}
if (Number.isNaN(lookbackMinutes) || lookbackMinutes <= 0) {
throw new Error("lookback must be > 0 minutes");
}
const messages = await deps.listRecentMessages(lookbackMinutes, limit);
if (opts.json) {
runtime.log(JSON.stringify(messages, null, 2));
return;
}
if (messages.length === 0) {
runtime.log("No messages found in the requested window.");
return;
}
for (const m of messages) {
runtime.log(formatMessageLine(m));
}
}

27
src/commands/webhook.ts Normal file
View File

@@ -0,0 +1,27 @@
import type { CliDeps, RuntimeEnv } from "../index.js";
export async function webhookCommand(
opts: {
port: string;
path: string;
reply?: string;
verbose?: boolean;
yes?: boolean;
},
deps: CliDeps,
runtime: RuntimeEnv,
) {
const port = Number.parseInt(opts.port, 10);
if (Number.isNaN(port) || port <= 0 || port >= 65536) {
throw new Error("Port must be between 1 and 65535");
}
await deps.ensurePortAvailable(port);
const server = await deps.startWebhook(
port,
opts.path,
opts.reply,
Boolean(opts.verbose),
runtime,
);
return server;
}