64 lines
1.4 KiB
TypeScript
64 lines
1.4 KiB
TypeScript
import type { CliDeps } from "../cli/deps.js";
|
|
import { retryAsync } from "../infra/retry.js";
|
|
import type { RuntimeEnv } from "../runtime.js";
|
|
import { upCommand } from "./up.js";
|
|
|
|
export async function webhookCommand(
|
|
opts: {
|
|
port: string;
|
|
path: string;
|
|
reply?: string;
|
|
verbose?: boolean;
|
|
yes?: boolean;
|
|
ingress?: "tailscale" | "none";
|
|
dryRun?: 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");
|
|
}
|
|
|
|
const ingress = opts.ingress ?? "tailscale";
|
|
|
|
// Tailscale ingress: reuse the `up` flow (Funnel + Twilio webhook update).
|
|
if (ingress === "tailscale") {
|
|
const result = await upCommand(
|
|
{
|
|
port: opts.port,
|
|
path: opts.path,
|
|
verbose: opts.verbose,
|
|
yes: opts.yes,
|
|
dryRun: opts.dryRun,
|
|
},
|
|
deps,
|
|
runtime,
|
|
);
|
|
return result.server;
|
|
}
|
|
|
|
// Local-only webhook (no ingress / no Twilio update).
|
|
await deps.ensurePortAvailable(port);
|
|
if (opts.reply === "dry-run" || opts.dryRun) {
|
|
runtime.log(
|
|
`[dry-run] would start webhook on port ${port} path ${opts.path}`,
|
|
);
|
|
return undefined;
|
|
}
|
|
const server = await retryAsync(
|
|
() =>
|
|
deps.startWebhook(
|
|
port,
|
|
opts.path,
|
|
opts.reply,
|
|
Boolean(opts.verbose),
|
|
runtime,
|
|
),
|
|
3,
|
|
300,
|
|
);
|
|
return server;
|
|
}
|