chore: fix type regressions and helpers
This commit is contained in:
@@ -70,8 +70,8 @@ const ClaudeJsonSchema = z
|
|||||||
num_turns: z.number().optional(),
|
num_turns: z.number().optional(),
|
||||||
session_id: z.string().optional(),
|
session_id: z.string().optional(),
|
||||||
total_cost_usd: z.number().optional(),
|
total_cost_usd: z.number().optional(),
|
||||||
usage: z.record(z.any()).optional(),
|
usage: z.record(z.string(), z.any()).optional(),
|
||||||
modelUsage: z.record(z.any()).optional(),
|
modelUsage: z.record(z.string(), z.any()).optional(),
|
||||||
})
|
})
|
||||||
.passthrough()
|
.passthrough()
|
||||||
.refine(
|
.refine(
|
||||||
|
|||||||
@@ -197,6 +197,10 @@ With Tailscale:
|
|||||||
const deps = createDefaultDeps();
|
const deps = createDefaultDeps();
|
||||||
try {
|
try {
|
||||||
const server = await webhookCommand(opts, deps, defaultRuntime);
|
const server = await webhookCommand(opts, deps, defaultRuntime);
|
||||||
|
if (!server) {
|
||||||
|
defaultRuntime.log(info("Webhook dry-run complete; no server started."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
process.on("SIGINT", () => {
|
process.on("SIGINT", () => {
|
||||||
server.close(() => {
|
server.close(() => {
|
||||||
console.log("\n👋 Webhook stopped");
|
console.log("\n👋 Webhook stopped");
|
||||||
@@ -227,6 +231,10 @@ With Tailscale:
|
|||||||
const deps = createDefaultDeps();
|
const deps = createDefaultDeps();
|
||||||
try {
|
try {
|
||||||
const { server } = await upCommand(opts, deps, defaultRuntime);
|
const { server } = await upCommand(opts, deps, defaultRuntime);
|
||||||
|
if (!server) {
|
||||||
|
defaultRuntime.log(info("Up dry-run complete; no server started."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
process.on("SIGINT", () => {
|
process.on("SIGINT", () => {
|
||||||
server.close(() => {
|
server.close(() => {
|
||||||
console.log("\n👋 Webhook stopped");
|
console.log("\n👋 Webhook stopped");
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export async function upCommand(
|
|||||||
}
|
}
|
||||||
const twilioClient = deps.createClient(env);
|
const twilioClient = deps.createClient(env);
|
||||||
const senderSid = await deps.findWhatsappSenderSid(
|
const senderSid = await deps.findWhatsappSenderSid(
|
||||||
twilioClient,
|
twilioClient as unknown as import("../twilio/types.js").TwilioSenderListClient,
|
||||||
env.whatsappFrom,
|
env.whatsappFrom,
|
||||||
env.whatsappSenderSid,
|
env.whatsappSenderSid,
|
||||||
runtime,
|
runtime,
|
||||||
|
|||||||
@@ -1,18 +1,27 @@
|
|||||||
import { execFile, spawn } from "node:child_process";
|
import { execFile, spawn } from "node:child_process";
|
||||||
|
import { promisify } from "node:util";
|
||||||
|
|
||||||
import { danger, isVerbose } from "../globals.js";
|
import { danger, isVerbose } from "../globals.js";
|
||||||
import { logDebug, logError } from "../logger.js";
|
import { logDebug, logError } from "../logger.js";
|
||||||
|
|
||||||
|
const execFileAsync = promisify(execFile);
|
||||||
|
|
||||||
// Simple promise-wrapped execFile with optional verbosity logging.
|
// Simple promise-wrapped execFile with optional verbosity logging.
|
||||||
export async function runExec(
|
export async function runExec(
|
||||||
command: string,
|
command: string,
|
||||||
args: string[],
|
args: string[],
|
||||||
timeoutMs = 10_000,
|
opts: number | { timeoutMs?: number; maxBuffer?: number } = 10_000,
|
||||||
): Promise<{ stdout: string; stderr: string }> {
|
): Promise<{ stdout: string; stderr: string }> {
|
||||||
|
const options =
|
||||||
|
typeof opts === "number"
|
||||||
|
? { timeout: opts, encoding: "utf8" as const }
|
||||||
|
: {
|
||||||
|
timeout: opts.timeoutMs,
|
||||||
|
maxBuffer: opts.maxBuffer,
|
||||||
|
encoding: "utf8" as const,
|
||||||
|
};
|
||||||
try {
|
try {
|
||||||
const { stdout, stderr } = await execFile(command, args, {
|
const { stdout, stderr } = await execFileAsync(command, args, options);
|
||||||
timeout: timeoutMs,
|
|
||||||
});
|
|
||||||
if (isVerbose()) {
|
if (isVerbose()) {
|
||||||
if (stdout.trim()) logDebug(stdout.trim());
|
if (stdout.trim()) logDebug(stdout.trim());
|
||||||
if (stderr.trim()) logError(stderr.trim());
|
if (stderr.trim()) logError(stderr.trim());
|
||||||
|
|||||||
@@ -25,8 +25,9 @@ const WA_WEB_AUTH_DIR = path.join(os.homedir(), ".warelay", "credentials");
|
|||||||
export async function createWaSocket(printQr: boolean, verbose: boolean) {
|
export async function createWaSocket(printQr: boolean, verbose: boolean) {
|
||||||
const logger = pino({ level: verbose ? "info" : "silent" });
|
const logger = pino({ level: verbose ? "info" : "silent" });
|
||||||
// Some Baileys internals call logger.trace even when silent; ensure it's present.
|
// Some Baileys internals call logger.trace even when silent; ensure it's present.
|
||||||
if (typeof (logger as Record<string, unknown>).trace !== "function") {
|
const loggerAny = logger as unknown as Record<string, unknown>;
|
||||||
(logger as unknown as { trace: () => void }).trace = () => {};
|
if (typeof loggerAny.trace !== "function") {
|
||||||
|
loggerAny.trace = () => {};
|
||||||
}
|
}
|
||||||
await ensureDir(WA_WEB_AUTH_DIR);
|
await ensureDir(WA_WEB_AUTH_DIR);
|
||||||
const { state, saveCreds } = await useMultiFileAuthState(WA_WEB_AUTH_DIR);
|
const { state, saveCreds } = await useMultiFileAuthState(WA_WEB_AUTH_DIR);
|
||||||
@@ -81,7 +82,7 @@ export async function waitForWaConnection(
|
|||||||
|
|
||||||
const handler = (...args: unknown[]) => {
|
const handler = (...args: unknown[]) => {
|
||||||
const update = (args[0] ?? {}) as Partial<
|
const update = (args[0] ?? {}) as Partial<
|
||||||
import("baileys").ConnectionState
|
import("@whiskeysockets/baileys").ConnectionState
|
||||||
>;
|
>;
|
||||||
if (update.connection === "open") {
|
if (update.connection === "open") {
|
||||||
evWithOff.off?.("connection.update", handler);
|
evWithOff.off?.("connection.update", handler);
|
||||||
@@ -235,7 +236,7 @@ export async function monitorWebInbox(options: {
|
|||||||
continue;
|
continue;
|
||||||
const from = jidToE164(remoteJid);
|
const from = jidToE164(remoteJid);
|
||||||
if (!from) continue;
|
if (!from) continue;
|
||||||
const body = extractText(msg.message);
|
const body = extractText(msg.message ?? undefined);
|
||||||
if (!body) continue;
|
if (!body) continue;
|
||||||
const chatJid = remoteJid;
|
const chatJid = remoteJid;
|
||||||
const sendComposing = async () => {
|
const sendComposing = async () => {
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ async function handleMessages(
|
|||||||
if (!m.from || !m.to) continue;
|
if (!m.from || !m.to) continue;
|
||||||
try {
|
try {
|
||||||
await deps.autoReplyIfConfigured(
|
await deps.autoReplyIfConfigured(
|
||||||
client as unknown as {
|
client as unknown as import("./types.js").TwilioRequester & {
|
||||||
messages: { create: (opts: unknown) => Promise<unknown> };
|
messages: { create: (opts: unknown) => Promise<unknown> };
|
||||||
},
|
},
|
||||||
m as unknown as MessageInstance,
|
m as unknown as MessageInstance,
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ type TwilioRequester = {
|
|||||||
|
|
||||||
export async function sendTypingIndicator(
|
export async function sendTypingIndicator(
|
||||||
client: TwilioRequester,
|
client: TwilioRequester,
|
||||||
messageSid?: string,
|
|
||||||
runtime: RuntimeEnv,
|
runtime: RuntimeEnv,
|
||||||
|
messageSid?: string,
|
||||||
) {
|
) {
|
||||||
// Best-effort WhatsApp typing indicator (public beta as of Nov 2025).
|
// Best-effort WhatsApp typing indicator (public beta as of Nov 2025).
|
||||||
if (!messageSid) {
|
if (!messageSid) {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export async function startWebhook(
|
|||||||
replyText = await getReplyFromConfig(
|
replyText = await getReplyFromConfig(
|
||||||
{ Body, From, To, MessageSid },
|
{ Body, From, To, MessageSid },
|
||||||
{
|
{
|
||||||
onReplyStart: () => sendTypingIndicator(client, MessageSid, runtime),
|
onReplyStart: () => sendTypingIndicator(client, runtime, MessageSid),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user