chore: Enable "curly" rule to avoid single-statement if confusion/errors.

This commit is contained in:
cpojer
2026-01-31 16:19:20 +09:00
parent 009b16fab8
commit 5ceff756e1
1266 changed files with 27871 additions and 9393 deletions

View File

@@ -28,11 +28,17 @@ import { elide } from "./util.js";
function resolveHeartbeatReplyPayload(
replyResult: ReplyPayload | ReplyPayload[] | undefined,
): ReplyPayload | undefined {
if (!replyResult) return undefined;
if (!Array.isArray(replyResult)) return replyResult;
if (!replyResult) {
return undefined;
}
if (!Array.isArray(replyResult)) {
return replyResult;
}
for (let idx = replyResult.length - 1; idx >= 0; idx -= 1) {
const payload = replyResult[idx];
if (!payload) continue;
if (!payload) {
continue;
}
if (payload.text || payload.mediaUrl || (payload.mediaUrls && payload.mediaUrls.length > 0)) {
return payload;
}
@@ -221,7 +227,9 @@ export async function runWebHeartbeatOnce(opts: {
store[sessionSnapshot.key].updatedAt = sessionSnapshot.entry.updatedAt;
await updateSessionStore(storePath, (nextStore) => {
const nextEntry = nextStore[sessionSnapshot.key];
if (!nextEntry) return;
if (!nextEntry) {
return;
}
nextStore[sessionSnapshot.key] = {
...nextEntry,
updatedAt: sessionSnapshot.entry.updatedAt,

View File

@@ -45,10 +45,14 @@ export function isBotMentionedFromTargets(
const hasMentions = (msg.mentionedJids?.length ?? 0) > 0;
if (hasMentions && !isSelfChat) {
if (targets.selfE164 && targets.normalizedMentions.includes(targets.selfE164)) return true;
if (targets.selfE164 && targets.normalizedMentions.includes(targets.selfE164)) {
return true;
}
if (targets.selfJid) {
// Some mentions use the bare JID; match on E.164 to be safe.
if (targets.normalizedMentions.includes(targets.selfJid)) return true;
if (targets.normalizedMentions.includes(targets.selfJid)) {
return true;
}
}
// If the message explicitly mentions someone else, do not fall back to regex matches.
return false;
@@ -56,17 +60,23 @@ export function isBotMentionedFromTargets(
// Self-chat mode: ignore WhatsApp @mention JIDs, otherwise @mentioning the owner in group chats triggers the bot.
}
const bodyClean = clean(msg.body);
if (mentionCfg.mentionRegexes.some((re) => re.test(bodyClean))) return true;
if (mentionCfg.mentionRegexes.some((re) => re.test(bodyClean))) {
return true;
}
// Fallback: detect body containing our own number (with or without +, spacing)
if (targets.selfE164) {
const selfDigits = targets.selfE164.replace(/\D/g, "");
if (selfDigits) {
const bodyDigits = bodyClean.replace(/[^\d]/g, "");
if (bodyDigits.includes(selfDigits)) return true;
if (bodyDigits.includes(selfDigits)) {
return true;
}
const bodyNoSpace = msg.body.replace(/[\s-]/g, "");
const pattern = new RegExp(`\\+?${selfDigits}`, "i");
if (pattern.test(bodyNoSpace)) return true;
if (pattern.test(bodyNoSpace)) {
return true;
}
}
}

View File

@@ -141,7 +141,9 @@ export async function monitorWebChannel(
let reconnectAttempts = 0;
while (true) {
if (stopRequested()) break;
if (stopRequested()) {
break;
}
const connectionId = newConnectionId();
const startedAt = Date.now();
@@ -175,9 +177,15 @@ export async function monitorWebChannel(
const inboundDebounceMs = resolveInboundDebounceMs({ cfg, channel: "whatsapp" });
const shouldDebounce = (msg: WebInboundMsg) => {
if (msg.mediaPath || msg.mediaType) return false;
if (msg.location) return false;
if (msg.replyToId || msg.replyToBody) return false;
if (msg.mediaPath || msg.mediaType) {
return false;
}
if (msg.location) {
return false;
}
if (msg.replyToId || msg.replyToBody) {
return false;
}
return !hasControlCommand(msg.body, cfg);
};
@@ -219,7 +227,9 @@ export async function monitorWebChannel(
setActiveWebListener(account.accountId, listener);
unregisterUnhandled = registerUnhandledRejectionHandler((reason) => {
if (!isLikelyWhatsAppCryptoError(reason)) return false;
if (!isLikelyWhatsAppCryptoError(reason)) {
return false;
}
const errorStr = formatError(reason);
reconnectLogger.warn(
{ connectionId, error: errorStr },
@@ -239,8 +249,12 @@ export async function monitorWebChannel(
unregisterUnhandled();
unregisterUnhandled = null;
}
if (heartbeat) clearInterval(heartbeat);
if (watchdogTimer) clearInterval(watchdogTimer);
if (heartbeat) {
clearInterval(heartbeat);
}
if (watchdogTimer) {
clearInterval(watchdogTimer);
}
if (backgroundTasks.size > 0) {
await Promise.allSettled(backgroundTasks);
backgroundTasks.clear();
@@ -279,9 +293,13 @@ export async function monitorWebChannel(
}, heartbeatSeconds * 1000);
watchdogTimer = setInterval(() => {
if (!lastMessageAt) return;
if (!lastMessageAt) {
return;
}
const timeSinceLastMessage = Date.now() - lastMessageAt;
if (timeSinceLastMessage <= MESSAGE_TIMEOUT_MS) return;
if (timeSinceLastMessage <= MESSAGE_TIMEOUT_MS) {
return;
}
const minutesSinceLastMessage = Math.floor(timeSinceLastMessage / 60000);
heartbeatLogger.warn(
{

View File

@@ -17,7 +17,9 @@ export function maybeSendAckReaction(params: {
info: (obj: unknown, msg: string) => void;
warn: (obj: unknown, msg: string) => void;
}) {
if (!params.msg.id) return;
if (!params.msg.id) {
return;
}
const ackConfig = params.cfg.channels?.whatsapp?.ackReaction;
const emoji = (ackConfig?.emoji ?? "").trim();
@@ -45,7 +47,9 @@ export function maybeSendAckReaction(params: {
groupActivated: activation === "always",
});
if (!shouldSendReaction()) return;
if (!shouldSendReaction()) {
return;
}
params.info(
{ chatId: params.msg.chatId, messageId: params.msg.id, emoji },

View File

@@ -29,8 +29,12 @@ export async function maybeBroadcastMessage(params: {
) => Promise<boolean>;
}) {
const broadcastAgents = params.cfg.broadcast?.[params.peerId];
if (!broadcastAgents || !Array.isArray(broadcastAgents)) return false;
if (broadcastAgents.length === 0) return false;
if (!broadcastAgents || !Array.isArray(broadcastAgents)) {
return false;
}
if (broadcastAgents.length === 0) {
return false;
}
const strategy = params.cfg.broadcast?.strategy || "parallel";
whatsappInboundLog.info(`Broadcasting message to ${broadcastAgents.length} agents (${strategy})`);

View File

@@ -1,6 +1,8 @@
export function isStatusCommand(body: string) {
const trimmed = body.trim().toLowerCase();
if (!trimmed) return false;
if (!trimmed) {
return false;
}
return trimmed === "/status" || trimmed === "status" || trimmed.startsWith("/status ");
}

View File

@@ -25,13 +25,17 @@ export function createEchoTracker(params: {
const trim = () => {
while (recentlySent.size > maxItems) {
const firstKey = recentlySent.values().next().value;
if (!firstKey) break;
if (!firstKey) {
break;
}
recentlySent.delete(firstKey);
}
};
const rememberText: EchoTracker["rememberText"] = (text, opts) => {
if (!text) return;
if (!text) {
return;
}
recentlySent.add(text);
if (opts.combinedBody && opts.combinedBodySessionKey) {
recentlySent.add(

View File

@@ -21,7 +21,9 @@ export type GroupHistoryEntry = {
function isOwnerSender(baseMentionConfig: MentionConfig, msg: WebInboundMsg) {
const sender = normalizeE164(msg.senderE164 ?? "");
if (!sender) return false;
if (!sender) {
return false;
}
const owners = resolveOwnerList(baseMentionConfig, msg.selfE164 ?? undefined);
return owners.includes(sender);
}

View File

@@ -6,10 +6,14 @@ export function noteGroupMember(
e164?: string,
name?: string,
) {
if (!e164 || !name) return;
if (!e164 || !name) {
return;
}
const normalized = normalizeE164(e164);
const key = normalized ?? e164;
if (!key) return;
if (!key) {
return;
}
let roster = groupMemberNames.get(conversationId);
if (!roster) {
roster = new Map();
@@ -28,9 +32,13 @@ export function formatGroupMembers(params: {
const ordered: string[] = [];
if (participants?.length) {
for (const entry of participants) {
if (!entry) continue;
if (!entry) {
continue;
}
const normalized = normalizeE164(entry) ?? entry;
if (!normalized || seen.has(normalized)) continue;
if (!normalized || seen.has(normalized)) {
continue;
}
seen.add(normalized);
ordered.push(normalized);
}
@@ -38,16 +46,22 @@ export function formatGroupMembers(params: {
if (roster) {
for (const entry of roster.keys()) {
const normalized = normalizeE164(entry) ?? entry;
if (!normalized || seen.has(normalized)) continue;
if (!normalized || seen.has(normalized)) {
continue;
}
seen.add(normalized);
ordered.push(normalized);
}
}
if (ordered.length === 0 && fallbackE164) {
const normalized = normalizeE164(fallbackE164) ?? fallbackE164;
if (normalized) ordered.push(normalized);
if (normalized) {
ordered.push(normalized);
}
}
if (ordered.length === 0) {
return undefined;
}
if (ordered.length === 0) return undefined;
return ordered
.map((entry) => {
const name = roster?.get(entry);

View File

@@ -51,7 +51,9 @@ export function updateLastRouteInBackground(params: {
}
export function awaitBackgroundTasks(backgroundTasks: Set<Promise<unknown>>) {
if (backgroundTasks.size === 0) return Promise.resolve();
if (backgroundTasks.size === 0) {
return Promise.resolve();
}
return Promise.allSettled(backgroundTasks).then(() => {
backgroundTasks.clear();
});

View File

@@ -4,7 +4,9 @@ import type { loadConfig } from "../../../config/config.js";
import type { WebInboundMsg } from "../types.js";
export function formatReplyContext(msg: WebInboundMsg) {
if (!msg.replyToBody) return null;
if (!msg.replyToBody) {
return null;
}
const sender = msg.replyToSender ?? "unknown sender";
const idPart = msg.replyToId ? ` id:${msg.replyToId}` : "";
return `[Replying to ${sender}${idPart}]\n${msg.replyToBody}\n[/Replying]`;

View File

@@ -138,7 +138,9 @@ export function createWebOnMessageHandler(params: {
logVerbose,
replyLogger: params.replyLogger,
});
if (!gating.shouldProcess) return;
if (!gating.shouldProcess) {
return;
}
} else {
// Ensure `peerId` for DMs is stable and stored as E.164 when possible.
if (!msg.senderE164 && peerId && peerId.startsWith("+")) {

View File

@@ -2,8 +2,14 @@ import { jidToE164, normalizeE164 } from "../../../utils.js";
import type { WebInboundMsg } from "../types.js";
export function resolvePeerId(msg: WebInboundMsg) {
if (msg.chatType === "group") return msg.conversationId ?? msg.from;
if (msg.senderE164) return normalizeE164(msg.senderE164) ?? msg.senderE164;
if (msg.from.includes("@")) return jidToE164(msg.from) ?? msg.from;
if (msg.chatType === "group") {
return msg.conversationId ?? msg.from;
}
if (msg.senderE164) {
return normalizeE164(msg.senderE164) ?? msg.senderE164;
}
if (msg.from.includes("@")) {
return jidToE164(msg.from) ?? msg.from;
}
return normalizeE164(msg.from) ?? msg.from;
}

View File

@@ -60,13 +60,17 @@ async function resolveWhatsAppCommandAuthorized(params: {
msg: WebInboundMsg;
}): Promise<boolean> {
const useAccessGroups = params.cfg.commands?.useAccessGroups !== false;
if (!useAccessGroups) return true;
if (!useAccessGroups) {
return true;
}
const isGroup = params.msg.chatType === "group";
const senderE164 = normalizeE164(
isGroup ? (params.msg.senderE164 ?? "") : (params.msg.senderE164 ?? params.msg.from ?? ""),
);
if (!senderE164) return false;
if (!senderE164) {
return false;
}
const configuredAllowFrom = params.cfg.channels?.whatsapp?.allowFrom ?? [];
const configuredGroupAllowFrom =
@@ -74,8 +78,12 @@ async function resolveWhatsAppCommandAuthorized(params: {
(configuredAllowFrom.length > 0 ? configuredAllowFrom : undefined);
if (isGroup) {
if (!configuredGroupAllowFrom || configuredGroupAllowFrom.length === 0) return false;
if (configuredGroupAllowFrom.some((v) => String(v).trim() === "*")) return true;
if (!configuredGroupAllowFrom || configuredGroupAllowFrom.length === 0) {
return false;
}
if (configuredGroupAllowFrom.some((v) => String(v).trim() === "*")) {
return true;
}
return normalizeAllowFromE164(configuredGroupAllowFrom).includes(senderE164);
}
@@ -89,7 +97,9 @@ async function resolveWhatsAppCommandAuthorized(params: {
: params.msg.selfE164
? [params.msg.selfE164]
: [];
if (allowFrom.some((v) => String(v).trim() === "*")) return true;
if (allowFrom.some((v) => String(v).trim() === "*")) {
return true;
}
return normalizeAllowFromE164(allowFrom).includes(senderE164);
}
@@ -221,9 +231,13 @@ export async function processMessage(params: {
const dmRouteTarget =
params.msg.chatType !== "group"
? (() => {
if (params.msg.senderE164) return normalizeE164(params.msg.senderE164);
if (params.msg.senderE164) {
return normalizeE164(params.msg.senderE164);
}
// In direct chats, `msg.from` is already the canonical conversation id.
if (params.msg.from.includes("@")) return jidToE164(params.msg.from);
if (params.msg.from.includes("@")) {
return jidToE164(params.msg.from);
}
return normalizeE164(params.msg.from);
})()
: undefined;

View File

@@ -1,13 +1,21 @@
export function elide(text?: string, limit = 400) {
if (!text) return text;
if (text.length <= limit) return text;
if (!text) {
return text;
}
if (text.length <= limit) {
return text;
}
return `${text.slice(0, limit)}… (truncated ${text.length - limit} chars)`;
}
export function isLikelyWhatsAppCryptoError(reason: unknown) {
const formatReason = (value: unknown): string => {
if (value == null) return "";
if (typeof value === "string") return value;
if (value == null) {
return "";
}
if (typeof value === "string") {
return value;
}
if (value instanceof Error) {
return `${value.message}\n${value.stack ?? ""}`;
}
@@ -18,11 +26,21 @@ export function isLikelyWhatsAppCryptoError(reason: unknown) {
return Object.prototype.toString.call(value);
}
}
if (typeof value === "number") return String(value);
if (typeof value === "boolean") return String(value);
if (typeof value === "bigint") return String(value);
if (typeof value === "symbol") return value.description ?? value.toString();
if (typeof value === "function") return value.name ? `[function ${value.name}]` : "[function]";
if (typeof value === "number") {
return String(value);
}
if (typeof value === "boolean") {
return String(value);
}
if (typeof value === "bigint") {
return String(value);
}
if (typeof value === "symbol") {
return value.description ?? value.toString();
}
if (typeof value === "function") {
return value.name ? `[function ${value.name}]` : "[function]";
}
return Object.prototype.toString.call(value);
};
const raw =
@@ -31,7 +49,9 @@ export function isLikelyWhatsAppCryptoError(reason: unknown) {
const hasAuthError =
haystack.includes("unsupported state or unable to authenticate data") ||
haystack.includes("bad mac");
if (!hasAuthError) return false;
if (!hasAuthError) {
return false;
}
return (
haystack.includes("@whiskeysockets/baileys") ||
haystack.includes("baileys") ||