Skip to content

code cleanups and performance optimization.#147

Merged
9cb14c1ec0 merged 8 commits intomasterfrom
clean-up-code
Jan 16, 2026
Merged

code cleanups and performance optimization.#147
9cb14c1ec0 merged 8 commits intomasterfrom
clean-up-code

Conversation

@9cb14c1ec0
Copy link
Copy Markdown
Collaborator

@9cb14c1ec0 9cb14c1ec0 commented Jan 14, 2026

Fixes # .

Changes proposed in this pull request

To test (it takes a while): npm install github:<username>/venom#<branch>

Summary by CodeRabbit

  • New Features

    • Debounced incoming-message queueing (1s) for smoother event delivery.
    • Improved group detection and richer group context in message events.
    • Standardized chat/user lookup and a new “get current user” entry for consistent operations.
  • Bug Fixes

    • Improved error handling and logging across chat/message flows.
    • Leaner serialized message/contact payloads returned by APIs.
  • Tests

    • Added Vitest setup and extensive unit tests for core helpers and WAPI flows.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 14, 2026

📝 Walkthrough

Walkthrough

This PR removes multiple WAPI serialize helpers, introduces findChat/getMeUser, replaces many sendExist/getMaybeMe calls with those helpers, adds a debounced message queue (_queueNewMessage) for listeners, and adds Vitest unit tests and test utilities.

Changes

Cohort / File(s) Summary
Serialization removals
src/lib/wapi/serialize/index.js, src/lib/wapi/serialize/serialize-chat.js, src/lib/wapi/serialize/serialize-contact.js, src/lib/wapi/serialize/serialize-message.js, src/lib/wapi/serialize/serialize-profile-pic-thumb.js, src/lib/wapi/serialize/serialize-raw.js, src/lib/wapi/serialize/serielize-me.js
Removed implementations and re-exports for multiple serialize* helpers (chat, contact, message, profile-pic-thumb, raw, me). Consumers relying on these helpers must be updated.
Message serializer adjustment
src/lib/wapi/serializers/serialize-message.js
Adjusted message serialization: adds isGroupMsg/groupInfo resolution, simplifies fallbacks, and removed streaming/button-related fields — verify downstream expectations.
Debounced message queue / listeners
src/api/layers/listener.layer.ts, src/lib/wapi/listeners/init-listeners.js, src/types/WAPI.d.ts
Adds window.WAPI._queueNewMessage, enqueues messages, debounces processing (1000ms) and changes immediate vs batched onMessage/onAnyMessage behavior. Inspect lifecycle, enqueue guards, and callback removal semantics.
Central chat/user helpers & WAPI surface
src/lib/wapi/functions/check-send-exist.js, src/lib/wapi/helper/get-me-user.js, src/lib/wapi/helper/index.js, src/lib/wapi/functions/index.js, src/lib/wapi/wapi.js
Introduces findChat and getMeUser, removes sendExist/returnChat exports, and exposes new helpers on window.WAPI. Validate replacement semantics and public API surface.
Widespread callsite updates
src/lib/wapi/functions/** (many files; e.g., send-message.js, send-link-preview.js, create-group.js, add-participant.js, etc.)
Replaced numerous WAPI.sendExist and Store.MaybeMeUser.getMaybeMePnUser usages with WAPI.findChat / WAPI.getMeUser. Review subtle behavioral differences (error shapes, 404 handling) across functions.
get-host / related flows
src/lib/wapi/functions/get-host.js, src/lib/wapi/functions/get-number-profile.js, src/lib/wapi/functions/get-all-chats.js
Switched to WAPI.getMeUser() and WAPI.findChat() flows; error/404 semantics may differ — check callers and serialization uses.
Helper expansion
src/lib/wapi/helper/filter-object.js, src/lib/wapi/helper/get-me-user.js
MaybeMeUser detection expanded to include getMaybeMeLidUser; new getMeUser helper added and exported.
Tests, mocks and tooling
package.json, vitest.config.ts, test/unit/**/*.test.ts, test/unit/wapi/mocks/*, test/unit/wapi/setup.ts
Adds Vitest config, scripts, coverage deps, many unit tests and test mocks (Store/WAPI) and setup utilities. Review tests and mock fidelity.
Minor import/path & housekeeping
.gitignore, src/api/layers/group.layer.ts, src/api/layers/sender.layer.ts, test/index.js
Restores yarn.lock in .gitignore, adds coverage/, adjusts some import paths to explicit index.js, and comments out parts of test pipeline.

Sequence Diagram(s)

sequenceDiagram
    participant Listener as Client (on add)
    participant WAPI as window.WAPI
    participant Queue as _newMessagesQueue
    participant Debouncer as Debouncer (1000ms)
    participant Callbacks as _newMessagesCallbacks

    Listener->>WAPI: process new message -> processMessageObj
    alt processMessageObj falsy
        WAPI-->>Listener: return early
    else
        WAPI->>Listener: dispatch onAnyMessage immediately
        alt message not from me
            Listener->>WAPI: _queueNewMessage(processedMessage)
            WAPI->>Queue: push message to buffers
            alt debouncer inactive
                WAPI->>Debouncer: setTimeout(1000ms)
            end
        end
    end

    Debouncer->>Queue: timeout fires
    Queue->>Callbacks: invoke each callback with queuedMessages
    Callbacks->>Listener: callback(queuedMessages) -> triggers onMessage handlers
    Callbacks->>WAPI: remove callbacks flagged rmAfterUse
    WAPI->>Queue: clear _newMessagesQueue/_newMessagesBuffer and debouncer
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

🐰 I nibbled at serializers gone astray,
queued the messages for a calmer day.
Tests hopped in with mocks and light,
helpers found their path just right.
A twitch of whiskers — code feels bright. 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.81% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'code cleanups and performance optimization' is vague and generic, using non-descriptive terms that fail to convey the actual changes made in the PR. Replace with a more specific title summarizing the main changes, such as 'Refactor serialization functions and migrate chat lookup API' or 'Replace sendExist with findChat and remove redundant serializers'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/lib/wapi/serializers/serialize-message.js`:
- Around line 6-16: isGroupMsg detects group messages using obj?.to?.server and
obj?.from?.server but groupInfo always uses obj.from._serialized; update the
retrieval to use the group ID depending on which side is the group (prefer
obj.to._serialized when obj.to.server === 'g.us', otherwise
obj.from._serialized) before calling window.Store.Chat.get and
WAPI._serializeContactObj; adjust the conditional that checks for a serialized
id to use this resolved groupId variable so outgoing group messages fetch the
correct group chat/contact info.
- Around line 63-64: The latitude/longitude assignments use the `|| undefined`
pattern which wrongly treats 0 as absent; change the `lat: obj?.lat ||
undefined` and `lng: obj?.lng || undefined` lines to use nullish coalescing so
that only null/undefined become undefined (e.g., `obj?.lat ?? undefined` and
`obj?.lng ?? undefined`) in the serialize logic in serialize-message.js.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0c521a3 and 10e4124.

⛔ Files ignored due to path filters (1)
  • dist/lib/wapi/wapi.js is excluded by !**/dist/**
📒 Files selected for processing (8)
  • src/lib/wapi/serialize/index.js
  • src/lib/wapi/serialize/serialize-chat.js
  • src/lib/wapi/serialize/serialize-contact.js
  • src/lib/wapi/serialize/serialize-message.js
  • src/lib/wapi/serialize/serialize-profile-pic-thumb.js
  • src/lib/wapi/serialize/serialize-raw.js
  • src/lib/wapi/serialize/serielize-me.js
  • src/lib/wapi/serializers/serialize-message.js
💤 Files with no reviewable changes (7)
  • src/lib/wapi/serialize/serialize-contact.js
  • src/lib/wapi/serialize/index.js
  • src/lib/wapi/serialize/serialize-profile-pic-thumb.js
  • src/lib/wapi/serialize/serialize-raw.js
  • src/lib/wapi/serialize/serialize-chat.js
  • src/lib/wapi/serialize/serialize-message.js
  • src/lib/wapi/serialize/serielize-me.js
🧰 Additional context used
📓 Path-based instructions (1)
src/lib/wapi/**/*.js

📄 CodeRabbit inference engine (CLAUDE.md)

WAPI layer code is built with webpack and injected into the Puppeteer browser context

Files:

  • src/lib/wapi/serializers/serialize-message.js
🔇 Additional comments (1)
src/lib/wapi/serializers/serialize-message.js (1)

22-25: LGTM!

Using || undefined for these serialized string IDs is appropriate—empty or falsy values aren't meaningful for these fields.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/api/layers/listener.layer.ts`:
- Around line 173-180: Guard against processMessageObj being undefined before
dispatch: after computing processMessageObj (from processMessageObj(...) or
similar), check it is truthy and only then call
window.onAnyMessage(processMessageObj) and
window.WAPI._queueNewMessage(processMessageObj) (retain existing isSentByMe
check for _queueNewMessage). This ensures you don't pass undefined to
onAnyMessage and only queue valid message objects.

In `@src/lib/wapi/listeners/init-listeners.js`:
- Around line 15-19: The debounce handler currently captures queuedMessages then
clears window.WAPI._newMessagesQueue, which can lose messages pushed
concurrently; fix by atomically swapping the queue: assign a new empty array to
window.WAPI._newMessagesQueue first (e.g., const queuedMessages =
window.WAPI._newMessagesQueue; window.WAPI._newMessagesQueue = []; OR better:
const queuedMessages = window.WAPI._newMessagesQueue.splice(0);), then process
queuedMessages, and only after processing set window.WAPI._newMessagesDebouncer
= null; ensure this change references window.WAPI._newMessagesDebouncer,
window.WAPI._newMessagesQueue, and the _queueNewMessage callers so no messages
are dropped.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 08b44e8 and c5e6d63.

⛔ Files ignored due to path filters (1)
  • dist/lib/wapi/wapi.js is excluded by !**/dist/**
📒 Files selected for processing (3)
  • src/api/layers/listener.layer.ts
  • src/lib/wapi/listeners/init-listeners.js
  • src/types/WAPI.d.ts
🧰 Additional context used
📓 Path-based instructions (2)
src/api/layers/*.layer.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Keep functionality layers in src/api/layers using the *.layer.ts naming (e.g., sender.layer.ts, listener.layer.ts, group.layer.ts, profile.layer.ts, controls.layer.ts, retriever.layer.ts)

Files:

  • src/api/layers/listener.layer.ts
src/lib/wapi/**/*.js

📄 CodeRabbit inference engine (CLAUDE.md)

WAPI layer code is built with webpack and injected into the Puppeteer browser context

Files:

  • src/lib/wapi/listeners/init-listeners.js
🧠 Learnings (1)
📚 Learning: 2025-09-08T17:49:03.345Z
Learnt from: CR
Repo: venomlib/venom PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T17:49:03.345Z
Learning: Applies to src/api/layers/*.layer.ts : Keep functionality layers in src/api/layers using the *.layer.ts naming (e.g., sender.layer.ts, listener.layer.ts, group.layer.ts, profile.layer.ts, controls.layer.ts, retriever.layer.ts)

Applied to files:

  • src/api/layers/listener.layer.ts
🧬 Code graph analysis (2)
src/api/layers/listener.layer.ts (1)
src/lib/wapi/functions/process-message-object.js (1)
  • processMessageObj (1-16)
src/lib/wapi/listeners/init-listeners.js (6)
src/lib/wapi/functions/sendMessageOptions.js (1)
  • message (105-121)
src/lib/wapi/functions/send-message-scope.js (2)
  • message (116-125)
  • message (148-159)
src/lib/wapi/functions/get-unread-messages-in-chat.js (1)
  • message (33-37)
src/lib/wapi/functions/get-unread-messages.js (1)
  • message (14-14)
src/lib/wapi/functions/get-all-messages-in-chat.js (1)
  • message (22-26)
src/lib/wapi/functions/get-data-messages.js (1)
  • message (96-96)
🔇 Additional comments (4)
src/lib/wapi/listeners/init-listeners.js (1)

1-40: LGTM on the debounce structure and callback handling.

The guard for null/undefined messages, the debounce pattern, and the callback removal logic are well-implemented. The dual-queue approach (queue for processing, buffer for persistence) aligns with the existing _unloadInform flow.

src/types/WAPI.d.ts (1)

271-271: LGTM on the type declaration.

The _queueNewMessage signature correctly matches the implementation. The underscore prefix appropriately signals this as an internal API.

src/api/layers/listener.layer.ts (2)

163-183: Good implementation of dual-path message handling.

The separation of concerns is clear:

  • onAnyMessage: immediate notification for all messages (including sent-by-me)
  • onMessage (via debounced queue): batched incoming messages only

The comment at line 163 effectively documents this architecture.


119-123: Clarify the dual-message-path design and verify intended behavior.

Two separate paths feed messages into onMessage handlers:

  1. window.WAPI.waitNewMessages (lines 119-123) — WAPI listener
  2. Store.Msg 'add' event → window.WAPI._queueNewMessage (line 179) — internal debounced path

Both ultimately invoke window.onMessage, which emits the onMessage event. The messageCache deduplication (lines 386-388) prevents duplicate user callbacks for identical messages (by from and id), but confirm whether this dual-path design is intentional or if one path should be disabled to avoid redundant processing.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@9cb14c1ec0
Copy link
Copy Markdown
Collaborator Author

@coderabbitai, please review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 15, 2026

@9cb14c1ec0, I'll review the pull request for you.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/lib/wapi/listeners/init-listeners.js`:
- Around line 4-8: The _newMessagesBuffer is unbounded—modify
window.WAPI._queueNewMessage (and the corresponding message-processing routine
that clears _newMessagesQueue) so the buffer is bounded: after pushing to
window.WAPI._newMessagesBuffer enforce a maximum size (e.g., MAX_BUFFER_LENGTH)
and drop oldest entries (shift) when exceeded, or alternatively remove messages
from window.WAPI._newMessagesBuffer when they are successfully processed by the
existing consumer that clears window.WAPI._newMessagesQueue; reference
_queueNewMessage, window.WAPI._newMessagesBuffer, and the
message-processing/flush callback to implement the trimming or removal logic.
- Around line 23-30: Wrap each invocation of callbackObj.callback inside a
try-catch so one throwing callback doesn't stop the forEach, ensuring you still
evaluate callbackObj.rmAfterUse and push to removeCallbacks even if the callback
throws; use the catch to log or swallow the error (including callback
identity/context) and continue so removeCallbacks is fully populated and
subsequent callbacks run.
🧹 Nitpick comments (2)
src/lib/wapi/functions/check-send-exist.js (2)

146-179: Extract duplicated error handling into a helper function.

The error handling logic in returnChat (lines 146-179) and sendExist (lines 276-309) is nearly identical. Consider extracting this into a shared helper to improve maintainability and reduce duplication.

♻️ Proposed refactor
+async function handleSendSeenError(e, chatId, chat, context) {
+  const errorInfo = {
+    message: e?.message,
+    stack: e?.stack,
+    undefinedProp: e?.message?.match(/Cannot read properties of undefined \(reading '(.+)'\)/)?.[1],
+    chatId: chatId,
+    chatExists: !!chat,
+    chatKeys: chat ? Object.keys(chat).slice(0, 30) : [],
+    chatProto: chat ? Object.getOwnPropertyNames(Object.getPrototypeOf(chat)).slice(0, 20) : []
+  };
+  window.onLog(`sendSeen failed in ${context}: ` + JSON.stringify(errorInfo));
+
+  try {
+    const stackMatch = e?.stack?.match(/(https:\/\/static\.whatsapp\.net\/[^\s:]+):(\d+):(\d+)/);
+    if (stackMatch) {
+      const [, url, line, col] = stackMatch;
+      const response = await fetch(url);
+      const source = await response.text();
+      const lineNum = parseInt(line, 10);
+      const colNum = parseInt(col, 10);
+      const lines = source.split('\n');
+      const targetLine = lines[lineNum - 1] || '';
+      const start = Math.max(0, colNum - 50);
+      const snippet = targetLine.substring(start, start + 100);
+      window.onLog('WA source context: ' + JSON.stringify({ url, line, col, snippet }));
+    }
+  } catch (srcErr) {
+    // Ignore source fetch errors
+  }
+}

Then in returnChat:

   if (Send) {
     try {
       await window.Store.ReadSeen.sendSeen(chat, false);
     } catch (e) {
-      const errorInfo = { ... };
-      // ... all the error handling code
+      await handleSendSeenError(e, chatId, chat, 'returnChat');
     }
   }

And similarly in sendExist.

Also applies to: 276-309


161-178: Consider adding a timeout for the source fetch.

Fetching WhatsApp's minified JS bundles (which can be several MB) on every error without a timeout could cause delays. Consider using AbortController with a reasonable timeout to prevent hanging on slow or failed network requests.

♻️ Suggested improvement
       if (stackMatch) {
         const [, url, line, col] = stackMatch;
-        const response = await fetch(url);
+        const controller = new AbortController();
+        const timeoutId = setTimeout(() => controller.abort(), 3000);
+        const response = await fetch(url, { signal: controller.signal });
+        clearTimeout(timeoutId);
         const source = await response.text();
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c5e6d63 and 82987c6.

⛔ Files ignored due to path filters (5)
  • dist/cjs/api/layers/listener.layer.js is excluded by !**/dist/**
  • dist/cjs/api/layers/listener.layer.js.map is excluded by !**/dist/**, !**/*.map
  • dist/esm/api/layers/listener.layer.js is excluded by !**/dist/**
  • dist/esm/api/layers/listener.layer.js.map is excluded by !**/dist/**, !**/*.map
  • dist/lib/wapi/wapi.js is excluded by !**/dist/**
📒 Files selected for processing (3)
  • src/api/layers/listener.layer.ts
  • src/lib/wapi/functions/check-send-exist.js
  • src/lib/wapi/listeners/init-listeners.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/api/layers/listener.layer.ts
🧰 Additional context used
📓 Path-based instructions (2)
src/lib/wapi/functions/**/*.js

📄 CodeRabbit inference engine (CLAUDE.md)

WAPI functions in src/lib/wapi/functions are JavaScript files injected into the browser; after changing them, run npm run build:wapi to rebuild

Files:

  • src/lib/wapi/functions/check-send-exist.js
src/lib/wapi/**/*.js

📄 CodeRabbit inference engine (CLAUDE.md)

WAPI layer code is built with webpack and injected into the Puppeteer browser context

Files:

  • src/lib/wapi/functions/check-send-exist.js
  • src/lib/wapi/listeners/init-listeners.js
🧬 Code graph analysis (1)
src/lib/wapi/listeners/init-listeners.js (6)
src/lib/wapi/functions/sendMessageOptions.js (1)
  • message (105-121)
src/lib/wapi/functions/send-message-scope.js (2)
  • message (116-125)
  • message (148-159)
src/lib/wapi/functions/get-unread-messages-in-chat.js (1)
  • message (33-37)
src/lib/wapi/functions/get-unread-messages.js (1)
  • message (14-14)
src/lib/wapi/functions/get-all-messages-in-chat.js (1)
  • message (22-26)
src/lib/wapi/functions/get-data-messages.js (1)
  • message (96-96)
🔇 Additional comments (3)
src/lib/wapi/functions/check-send-exist.js (1)

146-148: Good addition of error handling for sendSeen.

Wrapping sendSeen in try-catch ensures that failures in this non-critical "mark as seen" operation don't break the main chat retrieval flow. The detailed error logging will help diagnose issues with WhatsApp API changes.

src/lib/wapi/listeners/init-listeners.js (2)

16-19: Race condition fix looks correct.

The atomic swap pattern (capture queue reference, then immediately reassign to empty array) properly addresses the previously identified race condition. Messages arriving during callback processing will be queued for the next debounce cycle.


42-64: LGTM!

The _unloadInform handler correctly persists buffered messages and notifies callbacks of the page reload. This integrates well with the new queueing mechanism.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +4 to +8
window.WAPI._queueNewMessage = function (message) {
if (!message) return;

window.WAPI._newMessagesDebouncer = null;
window.WAPI._newMessagesQueue = [];
window.WAPI._newMessagesQueue.push(message);
window.WAPI._newMessagesBuffer.push(message);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

_newMessagesBuffer grows unboundedly during the session.

Messages are pushed to _newMessagesBuffer but never removed. While _newMessagesQueue is cleared after processing, the buffer accumulates all messages until page unload (when it's persisted to sessionStorage). In long-running sessions with high message volume, this could cause memory pressure.

Consider periodically trimming or capping the buffer size, or clearing processed messages from the buffer after successful callback execution.

🤖 Prompt for AI Agents
In `@src/lib/wapi/listeners/init-listeners.js` around lines 4 - 8, The
_newMessagesBuffer is unbounded—modify window.WAPI._queueNewMessage (and the
corresponding message-processing routine that clears _newMessagesQueue) so the
buffer is bounded: after pushing to window.WAPI._newMessagesBuffer enforce a
maximum size (e.g., MAX_BUFFER_LENGTH) and drop oldest entries (shift) when
exceeded, or alternatively remove messages from window.WAPI._newMessagesBuffer
when they are successfully processed by the existing consumer that clears
window.WAPI._newMessagesQueue; reference _queueNewMessage,
window.WAPI._newMessagesBuffer, and the message-processing/flush callback to
implement the trimming or removal logic.

Comment on lines +23 to +30
window.WAPI._newMessagesCallbacks.forEach(function (callbackObj) {
if (callbackObj.callback !== undefined) {
callbackObj.callback(queuedMessages);
}
}
}
);
});
if (callbackObj.rmAfterUse === true) {
removeCallbacks.push(callbackObj);
}
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Missing error handling: one throwing callback breaks all subsequent callbacks.

If any callback throws an exception at line 25, the forEach loop terminates early. This means:

  • Remaining callbacks won't execute
  • removeCallbacks won't be fully populated
  • Cleanup for rmAfterUse callbacks may be incomplete

Wrap each callback invocation in a try-catch to isolate failures.

🔧 Proposed fix to isolate callback failures
         window.WAPI._newMessagesCallbacks.forEach(function (callbackObj) {
           if (callbackObj.callback !== undefined) {
-            callbackObj.callback(queuedMessages);
+            try {
+              callbackObj.callback(queuedMessages);
+            } catch (err) {
+              console.error('Error in newMessagesCallback:', err);
+            }
           }
           if (callbackObj.rmAfterUse === true) {
             removeCallbacks.push(callbackObj);
           }
         });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
window.WAPI._newMessagesCallbacks.forEach(function (callbackObj) {
if (callbackObj.callback !== undefined) {
callbackObj.callback(queuedMessages);
}
}
}
);
});
if (callbackObj.rmAfterUse === true) {
removeCallbacks.push(callbackObj);
}
});
window.WAPI._newMessagesCallbacks.forEach(function (callbackObj) {
if (callbackObj.callback !== undefined) {
try {
callbackObj.callback(queuedMessages);
} catch (err) {
console.error('Error in newMessagesCallback:', err);
}
}
if (callbackObj.rmAfterUse === true) {
removeCallbacks.push(callbackObj);
}
});
🤖 Prompt for AI Agents
In `@src/lib/wapi/listeners/init-listeners.js` around lines 23 - 30, Wrap each
invocation of callbackObj.callback inside a try-catch so one throwing callback
doesn't stop the forEach, ensuring you still evaluate callbackObj.rmAfterUse and
push to removeCallbacks even if the callback throws; use the catch to log or
swallow the error (including callback identity/context) and continue so
removeCallbacks is fully populated and subsequent callbacks run.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
package.json (1)

93-118: Add explicit Node.js version requirement to package.json.

Vitest 3.x requires Node.js 18 or newer. The project should declare this minimum requirement using an "engines" field in package.json to prevent installation on incompatible Node versions. Add the following to clarify the supported runtime environment before release.

🤖 Fix all issues with AI agents
In `@coverage/api/helpers/deduplication-cache.ts.html`:
- Around line 1-415: The repo is tracking generated coverage HTML under
coverage/ (e.g., coverage/api/helpers/deduplication-cache.ts.html); add
coverage/ to .gitignore, remove the tracked coverage files from Git, and commit
the change. Specifically: add the line "coverage/" to .gitignore, run git rm
--cached -r coverage (or use your history-rewrite tool like git filter-repo/BFG
if you need to purge older commits), and commit & push the removal; this will
stop files like the generated deduplication-cache.ts.html from being committed
alongside code and keep classes like DeduplicationCache and exported alias
callbackWile out of versioned coverage artifacts.

In `@coverage/api/helpers/index.ts.html`:
- Around line 1-127: Add "coverage/" to the repository .gitignore and stop
tracking the already committed coverage artifacts (the files under coverage/,
e.g., coverage/api/helpers/index.ts.html) by running git rm -r --cached coverage
and committing that change so the directory is removed from history going
forward; after that, ensure CI is configured to generate/publish coverage as
build artifacts or push to a coverage service (e.g., Codecov/Coveralls) instead
of committing coverage output.

In `@coverage/api/helpers/layers-interface.ts.html`:
- Around line 145-162: The validation loop uses `for (let i in data)` which
yields string keys so the `typeof i == 'number'` check always fails and
validation never runs; replace the loop with a numeric index loop (e.g., `for
(let i = 0; i < data.length; i++)`) or a `for (const [i, item] of
data.entries())` pattern so `i` is a numeric index (or use `for (const item of
data)` and refer to `item`), then keep the existing logic that computes `result`
using `infoType(data[i].value, data[i].type)` (or `infoType(item.value,
item.type)`) and return the same error object when `!result`.

In `@coverage/api/helpers/scrape-deletetoken.ts.html`:
- Around line 110-122: The function scrapeDeleteToken has a type mismatch
because .catch(() => undefined) allows returning undefined despite the
Promise<boolean> signature; change the error path to return a boolean (e.g.,
replace .catch(() => undefined) with .catch(() => false)) and ensure the
page.evaluate callback always returns a boolean, or alternatively relax the
signature to Promise<boolean | undefined> if undefined is intended; also remove
the generated coverage artifact file from the commit so the coverage HTML isn't
included in source.

In `@coverage/base.css`:
- Around line 52-55: The .quiet class contains two duplicate color declarations;
remove the redundant one so only a single modern value remains (e.g., keep
color: rgba(0,0,0,0.5); and delete color: `#7f7f7f`;), or if you need the hex
fallback move the hex into an `@supports-compatible` fallback block and leave the
rgba as the primary value in the .quiet rule.
- Around line 5-8: The font-family declaration in the body selector uses an
unquoted multi-word family name; update the body { font-family: ... } rule to
quote "Helvetica Neue" (e.g., "Helvetica Neue", Helvetica, Arial) so the
multi-word family is treated as a single font family and to avoid duplicate-name
lint warnings.
- Around line 216-220: Remove the duplicate height declaration in the .wrapper
rule: delete the redundant "height: 100%;" line (leaving min-height and the
legacy "height: auto !important;" only) so there is a single, intentional height
declaration and the lint error is resolved.

In `@coverage/block-navigation.js`:
- Around line 24-38: The toggleClass/makeCurrent logic assumes
missingCoverageElements.item(...) returns an element; guard against empty lists
by checking missingCoverageElements.length and that currentIndex is not
null/undefined before accessing .classList; only call
missingCoverageElements.item(currentIndex).classList.remove(...) when
missingCoverageElements.length > 0 and currentIndex is a valid index, and
likewise ensure missingCoverageElements.item(index) exists before calling
.classList.add(...) and scrollIntoView in makeCurrent.

In `@coverage/prettify.js`:
- Around line 1-2: Summary: Biome is linting generated vendor file
coverage/prettify.js and raising noUselessUndefinedInitialization; exclude the
coverage/ directory in biome.json. Fix: open biome.json and add "coverage/**"
(or "coverage/") to the "exclude" array (or create an "exclude" array if
missing) so Biome ignores the generated files; ensure the pattern covers nested
files (use glob "**") and commit the change. Reference: the lint rule name
noUselessUndefinedInitialization and the generated file coverage/prettify.js to
verify the exclusion works.

In `@test/unit/wapi/send-message.test.ts`:
- Around line 189-202: The test and source contain a typo in the error string —
update the error message in the sendMessage implementation (function
sendMessage) from "Error to gerate newId" to "Error to generate newId" and then
update the unit test expectation in send-message.test.ts to expect 'Error to
generate newId' so both implementation and test match; ensure no other
occurrences of "gerate" remain.
♻️ Duplicate comments (7)
coverage/utils/sleep.ts.html (1)

2-88: Duplicate: generated coverage artifacts.

Same note as earlier about keeping coverage/ out of version control unless you intentionally publish reports in-repo.

coverage/api/helpers/delete-file.ts.html (1)

2-151: Duplicate: generated coverage artifacts.

Same note as earlier about keeping coverage/ out of version control unless you intentionally publish reports in-repo.

coverage/api/helpers/scrape-img-qr.ts.html (1)

1-22: Duplicate: generated coverage artifact.

Same suggestion as other coverage HTML files—consider excluding coverage/ from VCS unless intentionally versioned.

coverage/api/helpers/sleep.ts.html (1)

1-22: Duplicate: generated coverage artifact.

Same suggestion as other coverage HTML files—consider excluding coverage/ from VCS unless intentionally versioned.

coverage/utils/qr-generator.ts.html (1)

1-436: Skip - duplicate of coverage directory concern.

Same issue as coverage/api/helpers/index.ts.html - this is a generated coverage artifact that should not be committed.

coverage/utils/semver.ts.html (1)

2-169: Generated coverage artifact (see prior note).
Same repo-hygiene recommendation as in coverage/utils/index.html.

coverage/utils/logger.ts.html (1)

2-214: Generated coverage artifact (see prior note).
Same repo-hygiene recommendation as in coverage/utils/index.html.

🧹 Nitpick comments (12)
coverage/api/helpers/dowload-meta.ts.html (1)

1-322: Exclude generated coverage HTML from source control.

This is a generated Istanbul coverage report, which is typically better kept as a CI artifact rather than committed to the repo. Consider adding coverage outputs to .gitignore or documenting why these artifacts must be versioned.

coverage/api/helpers/layers-interface.ts.html (1)

2-185: Consider excluding generated coverage HTML from the repo.
This file looks like an Istanbul report artifact; committing it can bloat the repo and cause noisy diffs. Prefer generating in CI and publishing as an artifact, and add coverage output to .gitignore.

package.json (1)

53-55: Wire unit tests into the default test pipeline.

test:unit is opt‑in, while npm test/build:test still only run test/index.js. If unit coverage should run in CI, consider chaining the Vitest run into the default path.

Suggested tweak (if build:test is the CI entrypoint)
-    "build:test": "npm run build && npm test",
+    "build:test": "npm run build && npm test && npm run test:unit",
coverage/api/helpers/base64-mimetype.ts.html (1)

2-112: Avoid committing generated coverage HTML.

Coverage reports are typically build artifacts and tend to churn. Consider ignoring coverage/ and publishing reports as CI artifacts instead.

Example .gitignore addition
+coverage/
coverage/api/helpers/check-token-file.ts.html (1)

1-22: Consider excluding generated coverage artifacts from VCS.

This appears to be a generated coverage report; if it’s not intentionally versioned, add the coverage/ directory to .gitignore and publish reports via CI artifacts to reduce repo churn and size.

coverage/api/helpers/download-file.ts.html (1)

191-191: Empty catch block silently swallows errors in the source code.

The embedded source reveals that downloadFileToBase64 in src/api/helpers/download-file.ts has an empty catch block (line 191: } catch (error) {}). This silently swallows all HTTP errors, network failures, and other exceptions without any logging, making debugging difficult.

Consider adding error logging in the actual source file:

-  } catch (error) {}
+  } catch (error) {
+    console.error(`Failed to download file from ${_path}:`, error);
+  }

Also, this is a generated coverage artifact that should not be committed (see earlier comment about adding coverage/ to .gitignore).

coverage/api/helpers/select-sticker.ts.html (1)

205-207: Verify animated WebP output for _t === 1.

If _t === 1 is meant for animated stickers, sharp typically requires webp({ animated: true }) to preserve frames. Please confirm with the sharp docs.

🛠️ Suggested fix
-      _w = sharp(_B, { animated: true }).webp();
+      _w = sharp(_B, { animated: true }).webp({ animated: true });
coverage/api/helpers/force-connect.ts.html (1)

1-295: Confirm generated coverage artifacts are intentional.

This appears to be Istanbul HTML output; if it isn’t meant for version control, consider ignoring it or publishing as a build artifact to keep the repo lean.

test/unit/wapi/setup.ts (1)

11-30: Preserve any pre-existing window/globals in test setup.

Overwriting global.window can drop jsdom APIs and leak across suites; consider merging into an existing window and restoring previous values in cleanup.

♻️ Suggested safer setup/cleanup
-  // Set up global window object with Store and WAPI
-  (global as Record<string, unknown>).window = {
-    Store: storeMock,
-    WAPI: wapiMock,
-    onLog: vi.fn()
-  };
-
-  // Also expose at global level (some WAPI functions use Store directly)
-  (global as Record<string, unknown>).Store = storeMock;
-  (global as Record<string, unknown>).WAPI = wapiMock;
-
-  const cleanup = () => {
-    delete (global as Record<string, unknown>).window;
-    delete (global as Record<string, unknown>).Store;
-    delete (global as Record<string, unknown>).WAPI;
-  };
+  const globalAny = global as Record<string, unknown>;
+  const prevWindow = globalAny.window;
+  const prevStore = globalAny.Store;
+  const prevWapi = globalAny.WAPI;
+
+  const win =
+    prevWindow && typeof prevWindow === 'object'
+      ? (prevWindow as Record<string, unknown>)
+      : {};
+  win.Store = storeMock;
+  win.WAPI = wapiMock;
+  win.onLog = vi.fn();
+  globalAny.window = win;
+
+  // Also expose at global level (some WAPI functions use Store directly)
+  globalAny.Store = storeMock;
+  globalAny.WAPI = wapiMock;
+
+  const cleanup = () => {
+    if (prevWindow === undefined) delete globalAny.window;
+    else globalAny.window = prevWindow;
+    if (prevStore === undefined) delete globalAny.Store;
+    else globalAny.Store = prevStore;
+    if (prevWapi === undefined) delete globalAny.WAPI;
+    else globalAny.WAPI = prevWapi;
+  };
test/unit/wapi/get-all-chats.test.ts (1)

1-4: Import structure looks good, but vi import is missing here.

The vi import is needed on line 41 for vi.fn(), but it's imported at the bottom of the file (lines 91-92). While this works due to hoisting, it's unconventional and reduces readability.

♻️ Proposed fix: move vi import to top
-import { describe, it, expect, beforeEach, afterEach } from 'vitest';
+import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
 import { setupWapiTestEnv, type WapiTestEnv } from './setup.js';
 import { createChatMock } from './mocks/store-mock.js';
 import { getAllChats } from '../../../src/lib/wapi/functions/get-all-chats.js';

And remove lines 91-92:

-
-// Need to import vi for the doneFn mock
-import { vi } from 'vitest';
test/unit/helpers/deduplication-cache.test.ts (1)

115-125: Consider adding a test for the cleanup timer invocation.

The coverage report shows removeExpired() (the timer callback) is not covered. While TTL expiration is tested via get() and has(), consider adding a test that advances time past CLEANUP_INTERVAL_MS (60 seconds) to trigger the background cleanup and verify entries are removed.

💡 Suggested test for timer-based cleanup
it('should remove expired entries via background cleanup timer', () => {
  const ttlMs = 1000;
  cache = new DeduplicationCache(ttlMs);
  cache.add('msg1', 'serialized-content-1');

  // Advance past TTL
  vi.advanceTimersByTime(ttlMs + 100);
  
  // Advance past cleanup interval (60 seconds) to trigger removeExpired
  vi.advanceTimersByTime(60 * 1000);

  // Entry should be removed by the cleanup timer
  expect(cache.get('serialized-content-1')).toBeUndefined();
});
coverage/utils/index.html (1)

2-160: Consider excluding generated coverage artifacts from version control.
These HTML reports (with timestamps) add repo noise and churn; prefer generating in CI and ignoring coverage/.

♻️ Suggested .gitignore entry
+coverage/
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 82987c6 and 55c0f1d.

⛔ Files ignored due to path filters (3)
  • coverage/favicon.png is excluded by !**/*.png
  • coverage/sort-arrow-sprite.png is excluded by !**/*.png
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (45)
  • coverage/api/helpers/base64-mimetype.ts.html
  • coverage/api/helpers/check-token-file.ts.html
  • coverage/api/helpers/closes-browser.ts.html
  • coverage/api/helpers/decrypt.ts.html
  • coverage/api/helpers/deduplication-cache.ts.html
  • coverage/api/helpers/delete-file.ts.html
  • coverage/api/helpers/dowload-meta.ts.html
  • coverage/api/helpers/download-file.ts.html
  • coverage/api/helpers/exposed.enum.ts.html
  • coverage/api/helpers/file-to-base64.ts.html
  • coverage/api/helpers/filename-from-mimetype.ts.html
  • coverage/api/helpers/force-connect.ts.html
  • coverage/api/helpers/index.html
  • coverage/api/helpers/index.ts.html
  • coverage/api/helpers/layers-interface.ts.html
  • coverage/api/helpers/scrape-deletetoken.ts.html
  • coverage/api/helpers/scrape-desconnect.ts.html
  • coverage/api/helpers/scrape-img-qr.ts.html
  • coverage/api/helpers/scrape-login.ts.html
  • coverage/api/helpers/select-sticker.ts.html
  • coverage/api/helpers/sleep.ts.html
  • coverage/base.css
  • coverage/block-navigation.js
  • coverage/index.html
  • coverage/prettify.css
  • coverage/prettify.js
  • coverage/sorter.js
  • coverage/utils/index.html
  • coverage/utils/logger.ts.html
  • coverage/utils/qr-generator.ts.html
  • coverage/utils/semver.ts.html
  • coverage/utils/sleep.ts.html
  • package.json
  • test/unit/helpers/base64-mimetype.test.ts
  • test/unit/helpers/deduplication-cache.test.ts
  • test/unit/helpers/filename-from-mimetype.test.ts
  • test/unit/utils/logger.test.ts
  • test/unit/utils/semver.test.ts
  • test/unit/wapi/check-chat.test.ts
  • test/unit/wapi/get-all-chats.test.ts
  • test/unit/wapi/mocks/store-mock.ts
  • test/unit/wapi/mocks/wapi-mock.ts
  • test/unit/wapi/send-message.test.ts
  • test/unit/wapi/setup.ts
  • vitest.config.ts
✅ Files skipped from review due to trivial changes (8)
  • coverage/index.html
  • coverage/prettify.css
  • coverage/api/helpers/exposed.enum.ts.html
  • coverage/api/helpers/index.html
  • coverage/api/helpers/decrypt.ts.html
  • coverage/api/helpers/scrape-login.ts.html
  • coverage/api/helpers/scrape-desconnect.ts.html
  • coverage/api/helpers/file-to-base64.ts.html
🧰 Additional context used
🧠 Learnings (8)
📚 Learning: 2025-09-08T17:49:03.345Z
Learnt from: CR
Repo: venomlib/venom PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T17:49:03.345Z
Learning: Applies to test/index.js : Use test/index.js as the main test script; tests are basic scripts without a formal framework

Applied to files:

  • package.json
📚 Learning: 2025-09-10T17:12:13.000Z
Learnt from: 9cb14c1ec0
Repo: venomlib/venom PR: 65
File: src/api/helpers/delete-file.ts:3-8
Timestamp: 2025-09-10T17:12:13.000Z
Learning: The venom project build system does not support or prefers not to use Node built-in specifiers (node:path, node:fs) and has specific import pattern requirements that differ from modern Node.js conventions.

Applied to files:

  • package.json
📚 Learning: 2025-09-08T17:49:03.345Z
Learnt from: CR
Repo: venomlib/venom PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T17:49:03.345Z
Learning: Applies to tsconfig.json : TypeScript must target ESNext with CommonJS modules, output to ./dist, and generate declaration files and source maps

Applied to files:

  • package.json
📚 Learning: 2025-09-08T17:49:03.345Z
Learnt from: CR
Repo: venomlib/venom PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T17:49:03.345Z
Learning: Applies to src/api/helpers/**/*.{ts,js} : Put utility helpers (e.g., encryption, QR code utilities) under src/api/helpers

Applied to files:

  • coverage/api/helpers/index.ts.html
  • coverage/utils/qr-generator.ts.html
📚 Learning: 2025-09-08T17:49:03.345Z
Learnt from: CR
Repo: venomlib/venom PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T17:49:03.345Z
Learning: Applies to src/lib/wapi/**/*.js : WAPI layer code is built with webpack and injected into the Puppeteer browser context

Applied to files:

  • test/unit/wapi/setup.ts
📚 Learning: 2025-09-08T17:49:03.345Z
Learnt from: CR
Repo: venomlib/venom PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T17:49:03.345Z
Learning: Applies to src/lib/wapi/functions/**/*.js : WAPI functions in src/lib/wapi/functions are JavaScript files injected into the browser; after changing them, run `npm run build:wapi` to rebuild

Applied to files:

  • test/unit/wapi/setup.ts
📚 Learning: 2025-09-08T17:49:03.345Z
Learnt from: CR
Repo: venomlib/venom PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T17:49:03.345Z
Learning: Applies to src/api/layers/*.layer.ts : Keep functionality layers in src/api/layers using the *.layer.ts naming (e.g., sender.layer.ts, listener.layer.ts, group.layer.ts, profile.layer.ts, controls.layer.ts, retriever.layer.ts)

Applied to files:

  • coverage/api/helpers/layers-interface.ts.html
📚 Learning: 2025-09-08T17:49:03.345Z
Learnt from: CR
Repo: venomlib/venom PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T17:49:03.345Z
Learning: Applies to src/config/**/*.ts : Keep browser/Puppeteer and session management configuration under src/config

Applied to files:

  • vitest.config.ts
  • coverage/api/helpers/closes-browser.ts.html
🧬 Code graph analysis (10)
test/unit/helpers/base64-mimetype.test.ts (1)
src/api/helpers/file-to-base64.ts (2)
  • fileToBase64 (9-19)
  • Mine (21-27)
test/unit/wapi/get-all-chats.test.ts (3)
test/unit/wapi/setup.ts (2)
  • WapiTestEnv (5-9)
  • setupWapiTestEnv (11-33)
test/unit/wapi/mocks/store-mock.ts (1)
  • createChatMock (17-28)
src/types/WAPI.d.ts (1)
  • WAPI (14-271)
test/unit/wapi/setup.ts (4)
test/unit/wapi/mocks/store-mock.ts (2)
  • StoreMock (77-77)
  • createStoreMock (42-75)
test/unit/wapi/mocks/wapi-mock.ts (2)
  • WapiMock (77-77)
  • createWapiMock (11-75)
src/types/WAPI.d.ts (2)
  • Window (274-276)
  • WAPI (14-271)
src/lib/wapi/wapi.js (1)
  • window (534-537)
test/unit/wapi/mocks/store-mock.ts (4)
src/api/model/chat.ts (1)
  • Chat (5-31)
src/types/WAPI.d.ts (1)
  • WAPI (14-271)
src/lib/wapi/store/store-objects.js (6)
  • module (4-7)
  • module (285-286)
  • module (31-32)
  • module (68-69)
  • module (141-142)
  • module (146-146)
src/api/model/message.ts (1)
  • Message (1-81)
coverage/api/helpers/base64-mimetype.ts.html (2)
src/api/helpers/file-to-base64.ts (2)
  • fileToBase64 (9-19)
  • Mine (21-27)
src/api/layers/sender.layer.ts (1)
  • sendFileFromBase64 (856-894)
coverage/utils/qr-generator.ts.html (3)
src/utils/qr-generator.ts (1)
  • generateASCIIQR (30-117)
src/controllers/auth.ts (1)
  • asciiQr (93-100)
vendor/QRCode/index.js (2)
  • test (232-246)
  • test (248-285)
coverage/api/helpers/layers-interface.ts.html (1)
src/api/helpers/layers-interface.ts (1)
  • Scope (1-5)
test/unit/wapi/send-message.test.ts (3)
test/unit/wapi/setup.ts (2)
  • WapiTestEnv (5-9)
  • setupWapiTestEnv (11-33)
test/unit/wapi/mocks/store-mock.ts (1)
  • createChatMock (17-28)
src/lib/wapi/serializers/serialize-message.js (1)
  • groupId (13-16)
test/unit/utils/logger.test.ts (1)
src/utils/logger.ts (7)
  • LoggerFunction (3-3)
  • setLogger (17-19)
  • getLogger (21-23)
  • logInfo (29-31)
  • logSuccess (33-35)
  • logFail (37-39)
  • logWarn (41-43)
test/unit/wapi/mocks/wapi-mock.ts (1)
src/lib/wapi/functions/get-message-by-id.js (1)
  • erro (4-4)
🪛 Biome (2.1.2)
coverage/base.css

[error] 6-6: Duplicate font names are redundant and unnecessary: Helvetica

Remove duplicate font names within the property

(lint/suspicious/noDuplicateFontNames)


[error] 54-54: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.

color is already defined here.

Remove or rename the duplicate property to ensure consistent styling.

(lint/suspicious/noDuplicateProperties)


[error] 219-219: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.

height is already defined here.

Remove or rename the duplicate property to ensure consistent styling.

(lint/suspicious/noDuplicateProperties)

coverage/prettify.js

[error] 2-2: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 2-2: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 2-2: Shouldn't redeclare 'ar'. Consider to delete it or rename it.

'ar' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'ar'. Consider to delete it or rename it.

'ar' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'at'. Consider to delete it or rename it.

'at' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'ak'. Consider to delete it or rename it.

'ak' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'ak'. Consider to delete it or rename it.

'ak' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'am'. Consider to delete it or rename it.

'am' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'ag'. Consider to delete it or rename it.

'ag' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'af'. Consider to delete it or rename it.

'af' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'ak'. Consider to delete it or rename it.

'ak' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'am'. Consider to delete it or rename it.

'am' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'ak'. Consider to delete it or rename it.

'ak' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'ag'. Consider to delete it or rename it.

'ag' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'V'. Consider to delete it or rename it.

'V' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'U'. Consider to delete it or rename it.

'U' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'ae'. Consider to delete it or rename it.

'ae' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'Y'. Consider to delete it or rename it.

'Y' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'W'. Consider to delete it or rename it.

'W' is defined here:

(lint/suspicious/noRedeclare)

🔇 Additional comments (40)
vitest.config.ts (1)

1-13: Config looks good; confirm the test glob matches all intended unit tests.

include is limited to test/unit/**/*.test.ts. If any tests live elsewhere or use .spec.ts, they won't run.

test/unit/helpers/base64-mimetype.test.ts (1)

1-41: Solid test coverage for base64MimeType.

Covers valid data URIs, special-character MIME types, invalid inputs, non-strings, and non‑base64 markers.

coverage/api/helpers/filename-from-mimetype.ts.html (1)

1-22: No review comment for this generated report.

test/unit/helpers/filename-from-mimetype.test.ts (1)

1-39: LGTM! Comprehensive test coverage for the filename helper.

The tests cover important edge cases: matching extensions, mismatched MIME types, missing extensions, unknown MIME types, and special handling for audio/video/WebP formats. The structure follows vitest conventions correctly.

One minor note: Line 32 expects audio/mpeg.mpga. While .mpga is technically a valid IANA-registered extension for audio/mpeg, .mp3 is more commonly expected. Verify this matches the actual behavior of filenameFromMimeType and is intentional.

coverage/api/helpers/closes-browser.ts.html (1)

131-156: The infinite loop is intentional and has proper termination. This function is designed as a background monitoring task (fire-and-forget pattern) that polls every 2 seconds until the browser closes. It will always resolve when browser['isClose'] is detected or the browser disconnects, as set up by the close handler at line 218–219 in initializer.ts. The actual call site never awaits this function, only chains .catch() for error handling. An AbortSignal parameter is unnecessary for this use case.

coverage/api/helpers/select-sticker.ts.html (1)

213-227: The claim that metadata.pageHeight is undefined for static images is incorrect.

Sharp v0.34.0 documentation confirms that pageHeight is defined for both static and animated images. For static (single-page) images, pageHeight equals height. For animated images, pageHeight is the frame height and height is the total image height. The suggested fallback pattern is therefore unnecessary and based on a misunderstanding of the sharp library's behavior.

Likely an incorrect or invalid review comment.

test/unit/wapi/mocks/wapi-mock.ts (1)

3-24: No changes needed. The mock correctly implements the production scope() function behavior.

The production scope() function in check-send-exist.js always receives and returns a boolean erro value. All production calls to WAPI.scope() pass boolean literals (true or false). The getMessageById() function returns its own object shape with { erro: true } directly—it does not pass through scope(). These are separate code paths, so there is no divergence between the mock and production.

The mock's scopeFn correctly types erro as boolean and returns it as boolean in ScopeResult, matching how it's used throughout the codebase and how tests expect it.

Likely an incorrect or invalid review comment.

coverage/sorter.js (9)

10-25: Helper selectors are clean and scoped.

Centralizing table lookups keeps DOM queries consistent.


27-56: Filter input handling is robust.

Graceful regex fallback avoids runtime errors.


58-64: Search box wiring looks good.


66-89: Column metadata and sort UI setup are solid.

Default descending for numeric columns is a nice touch.


92-118: Row data caching is straightforward.

Parsing numeric values up front simplifies sorting.


120-149: Sorting and row reattachment logic is correct.

Comparator + descending inversion reads clearly.


150-163: Sort indicator toggling is clear.


165-196: UI event wiring is clean.

Handler toggles direction and updates indicators as expected.


198-210: Initialization sequence is cohesive.

Early table guard avoids unnecessary work.

test/unit/wapi/mocks/store-mock.ts (2)

3-40: Mock interfaces and factories are well-scoped.

Defaults plus override hooks make tests ergonomic.


42-77: Store mock surface looks aligned with test usage.

Nested namespaces with vi.fn stubs provide good isolation.

test/unit/wapi/setup.ts (1)

5-9: WapiTestEnv interface is clear.

test/unit/wapi/send-message.test.ts (3)

1-15: Well-structured test setup with proper isolation.

Good use of beforeEach and afterEach hooks to ensure test isolation. The cleanup pattern prevents global state leakage between tests.


17-52: Comprehensive input validation tests.

The input validation tests cover the key edge cases: empty content, non-string content, empty recipient, and non-string recipient. Good use of type casting (as unknown as string) to test type boundary conditions.


54-81: Status message boundary validation is well-tested.

Testing both the 701-character rejection and 700-character acceptance confirms proper boundary handling.

test/unit/wapi/get-all-chats.test.ts (2)

17-67: Good coverage of successful retrieval scenarios.

Tests properly validate array length, serialization call count, callback invocation, and empty list handling. The mock patterns are consistent with other test files.


69-88: User authentication edge cases are well-covered.

Testing both null user and 404 status ensures the function handles authentication failures gracefully.

test/unit/wapi/check-chat.test.ts (4)

1-15: Clean test setup following established patterns.

Consistent with other WAPI test files in the PR. Proper import ordering and test isolation via setup/cleanup.


17-51: Good coverage of valid ID format variations.

Tests all three valid chat ID formats: contact (@c.us), group (@g.us), and broadcast (@broadcast).


53-75: Invalid input handling is properly tested.

Tests cover missing suffix, non-string input, and empty string - good boundary validation.


77-114: Chat not found and successful lookup scenarios are well-covered.

The falsy timestamp test (line 92: mockChat.t = 0) is a good edge case to verify. The successful lookup test properly verifies serialization is called with the mock chat object.

test/unit/helpers/deduplication-cache.test.ts (4)

1-16: Excellent test setup with fake timers.

Proper use of vi.useFakeTimers() in beforeEach and vi.useRealTimers() in afterEach ensures deterministic TTL testing. The conditional cache.dispose() prevents errors if a test fails before cache initialization.


18-39: Good coverage of add behavior including duplicate handling.

Tests verify both the return value semantics (true for new, false for duplicate) and the side effect (id gets updated on duplicate).


41-89: Comprehensive has, get, and updateId tests.

Tests cover the key scenarios: existence checks with matching/non-matching IDs, successful retrieval, and update behavior on existing vs non-existing entries.


91-113: TTL expiration tests properly validate time-based eviction.

Good use of vi.advanceTimersByTime() to simulate TTL expiration. Testing both get() and has() for expired entries ensures both code paths are covered.

test/unit/utils/semver.test.ts (3)

4-31: Solid coverage for numeric semver ordering.
Covers equality and major/minor/patch comparisons cleanly.


33-50: Partial-version cases are well covered.
Two-part, single-part, and mixed partials are exercised.


52-69: Edge-case tests look thorough.
Empty inputs, null/undefined, and non-semver fallbacks are covered.

test/unit/utils/logger.test.ts (5)

16-19: Good test isolation via reset to default logger.
Keeps global logger state predictable between tests.


21-33: Custom vs default logger behavior is well validated.
Covers set/get and reset semantics.


35-47: Core log function behavior is well tested.
Explicit and default levels are both verified.


49-73: Level-specific helpers are covered cleanly.
Each helper routes to the expected level.


75-93: Default logger output expectations are clear.
Prefix formatting for each level is validated.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +1 to +415

<!doctype html>
<html lang="en">

<head>
<title>Code coverage report for api/helpers/deduplication-cache.ts</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="../../prettify.css" />
<link rel="stylesheet" href="../../base.css" />
<link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type='text/css'>
.coverage-summary .sorter {
background-image: url(../../sort-arrow-sprite.png);
}
</style>
</head>

<body>
<div class='wrapper'>
<div class='pad1'>
<h1><a href="../../index.html">All files</a> / <a href="index.html">api/helpers</a> deduplication-cache.ts</h1>
<div class='clearfix'>

<div class='fl pad1y space-right2'>
<span class="strong">89.87% </span>
<span class="quiet">Statements</span>
<span class='fraction'>71/79</span>
</div>


<div class='fl pad1y space-right2'>
<span class="strong">100% </span>
<span class="quiet">Branches</span>
<span class='fraction'>20/20</span>
</div>


<div class='fl pad1y space-right2'>
<span class="strong">88.88% </span>
<span class="quiet">Functions</span>
<span class='fraction'>8/9</span>
</div>


<div class='fl pad1y space-right2'>
<span class="strong">89.87% </span>
<span class="quiet">Lines</span>
<span class='fraction'>71/79</span>
</div>


</div>
<p class="quiet">
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
</p>
<template id="filterTemplate">
<div class="quiet">
Filter:
<input type="search" id="fileSearch">
</div>
</template>
</div>
<div class='status-line high'></div>
<pre><table class="coverage">
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
<a name='L2'></a><a href='#L2'>2</a>
<a name='L3'></a><a href='#L3'>3</a>
<a name='L4'></a><a href='#L4'>4</a>
<a name='L5'></a><a href='#L5'>5</a>
<a name='L6'></a><a href='#L6'>6</a>
<a name='L7'></a><a href='#L7'>7</a>
<a name='L8'></a><a href='#L8'>8</a>
<a name='L9'></a><a href='#L9'>9</a>
<a name='L10'></a><a href='#L10'>10</a>
<a name='L11'></a><a href='#L11'>11</a>
<a name='L12'></a><a href='#L12'>12</a>
<a name='L13'></a><a href='#L13'>13</a>
<a name='L14'></a><a href='#L14'>14</a>
<a name='L15'></a><a href='#L15'>15</a>
<a name='L16'></a><a href='#L16'>16</a>
<a name='L17'></a><a href='#L17'>17</a>
<a name='L18'></a><a href='#L18'>18</a>
<a name='L19'></a><a href='#L19'>19</a>
<a name='L20'></a><a href='#L20'>20</a>
<a name='L21'></a><a href='#L21'>21</a>
<a name='L22'></a><a href='#L22'>22</a>
<a name='L23'></a><a href='#L23'>23</a>
<a name='L24'></a><a href='#L24'>24</a>
<a name='L25'></a><a href='#L25'>25</a>
<a name='L26'></a><a href='#L26'>26</a>
<a name='L27'></a><a href='#L27'>27</a>
<a name='L28'></a><a href='#L28'>28</a>
<a name='L29'></a><a href='#L29'>29</a>
<a name='L30'></a><a href='#L30'>30</a>
<a name='L31'></a><a href='#L31'>31</a>
<a name='L32'></a><a href='#L32'>32</a>
<a name='L33'></a><a href='#L33'>33</a>
<a name='L34'></a><a href='#L34'>34</a>
<a name='L35'></a><a href='#L35'>35</a>
<a name='L36'></a><a href='#L36'>36</a>
<a name='L37'></a><a href='#L37'>37</a>
<a name='L38'></a><a href='#L38'>38</a>
<a name='L39'></a><a href='#L39'>39</a>
<a name='L40'></a><a href='#L40'>40</a>
<a name='L41'></a><a href='#L41'>41</a>
<a name='L42'></a><a href='#L42'>42</a>
<a name='L43'></a><a href='#L43'>43</a>
<a name='L44'></a><a href='#L44'>44</a>
<a name='L45'></a><a href='#L45'>45</a>
<a name='L46'></a><a href='#L46'>46</a>
<a name='L47'></a><a href='#L47'>47</a>
<a name='L48'></a><a href='#L48'>48</a>
<a name='L49'></a><a href='#L49'>49</a>
<a name='L50'></a><a href='#L50'>50</a>
<a name='L51'></a><a href='#L51'>51</a>
<a name='L52'></a><a href='#L52'>52</a>
<a name='L53'></a><a href='#L53'>53</a>
<a name='L54'></a><a href='#L54'>54</a>
<a name='L55'></a><a href='#L55'>55</a>
<a name='L56'></a><a href='#L56'>56</a>
<a name='L57'></a><a href='#L57'>57</a>
<a name='L58'></a><a href='#L58'>58</a>
<a name='L59'></a><a href='#L59'>59</a>
<a name='L60'></a><a href='#L60'>60</a>
<a name='L61'></a><a href='#L61'>61</a>
<a name='L62'></a><a href='#L62'>62</a>
<a name='L63'></a><a href='#L63'>63</a>
<a name='L64'></a><a href='#L64'>64</a>
<a name='L65'></a><a href='#L65'>65</a>
<a name='L66'></a><a href='#L66'>66</a>
<a name='L67'></a><a href='#L67'>67</a>
<a name='L68'></a><a href='#L68'>68</a>
<a name='L69'></a><a href='#L69'>69</a>
<a name='L70'></a><a href='#L70'>70</a>
<a name='L71'></a><a href='#L71'>71</a>
<a name='L72'></a><a href='#L72'>72</a>
<a name='L73'></a><a href='#L73'>73</a>
<a name='L74'></a><a href='#L74'>74</a>
<a name='L75'></a><a href='#L75'>75</a>
<a name='L76'></a><a href='#L76'>76</a>
<a name='L77'></a><a href='#L77'>77</a>
<a name='L78'></a><a href='#L78'>78</a>
<a name='L79'></a><a href='#L79'>79</a>
<a name='L80'></a><a href='#L80'>80</a>
<a name='L81'></a><a href='#L81'>81</a>
<a name='L82'></a><a href='#L82'>82</a>
<a name='L83'></a><a href='#L83'>83</a>
<a name='L84'></a><a href='#L84'>84</a>
<a name='L85'></a><a href='#L85'>85</a>
<a name='L86'></a><a href='#L86'>86</a>
<a name='L87'></a><a href='#L87'>87</a>
<a name='L88'></a><a href='#L88'>88</a>
<a name='L89'></a><a href='#L89'>89</a>
<a name='L90'></a><a href='#L90'>90</a>
<a name='L91'></a><a href='#L91'>91</a>
<a name='L92'></a><a href='#L92'>92</a>
<a name='L93'></a><a href='#L93'>93</a>
<a name='L94'></a><a href='#L94'>94</a>
<a name='L95'></a><a href='#L95'>95</a>
<a name='L96'></a><a href='#L96'>96</a>
<a name='L97'></a><a href='#L97'>97</a>
<a name='L98'></a><a href='#L98'>98</a>
<a name='L99'></a><a href='#L99'>99</a>
<a name='L100'></a><a href='#L100'>100</a>
<a name='L101'></a><a href='#L101'>101</a>
<a name='L102'></a><a href='#L102'>102</a>
<a name='L103'></a><a href='#L103'>103</a>
<a name='L104'></a><a href='#L104'>104</a>
<a name='L105'></a><a href='#L105'>105</a>
<a name='L106'></a><a href='#L106'>106</a>
<a name='L107'></a><a href='#L107'>107</a>
<a name='L108'></a><a href='#L108'>108</a>
<a name='L109'></a><a href='#L109'>109</a>
<a name='L110'></a><a href='#L110'>110</a>
<a name='L111'></a><a href='#L111'>111</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">11x</span>
<span class="cline-any cline-yes">11x</span>
<span class="cline-any cline-yes">11x</span>
<span class="cline-any cline-yes">11x</span>
<span class="cline-any cline-yes">11x</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-yes">3x</span>
<span class="cline-any cline-yes">3x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">14x</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-yes">14x</span>
<span class="cline-any cline-yes">14x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import { AckType } from '../model/enum/index.js';
&nbsp;
const DEFAULT_TTL_MS = 5 * 60 * 1000; // 5 minutes
const CLEANUP_INTERVAL_MS = 60 * 1000; // Clean up every minute
&nbsp;
interface CacheEntry {
id: AckType | string;
timestamp: number;
}
&nbsp;
export class DeduplicationCache {
private cache: Map&lt;string, CacheEntry&gt;;
private ttlMs: number;
private cleanupTimer: ReturnType&lt;typeof setInterval&gt; | null = null;
&nbsp;
constructor(ttlMs: number = DEFAULT_TTL_MS) {
this.cache = new Map();
this.ttlMs = ttlMs;
this.startCleanupTimer();
}
&nbsp;
private startCleanupTimer() {
this.cleanupTimer = setInterval(() =&gt; {
<span class="cstat-no" title="statement not covered" > this.removeExpired();</span>
}, CLEANUP_INTERVAL_MS);
&nbsp;
// Don't prevent process exit
if (this.cleanupTimer.unref) {
this.cleanupTimer.unref();
}
}
&nbsp;
private <span class="fstat-no" title="function not covered" >removeExpired() {</span>
<span class="cstat-no" title="statement not covered" > const now = Date.now();</span>
<span class="cstat-no" title="statement not covered" > for (const [key, entry] of this.cache) {</span>
<span class="cstat-no" title="statement not covered" > if (now - entry.timestamp &gt; this.ttlMs) {</span>
<span class="cstat-no" title="statement not covered" > this.cache.delete(key);</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
add(id: AckType | string, serialized: string): boolean {
const existing = this.cache.get(serialized);
&nbsp;
if (existing) {
// Update existing entry
existing.id = id;
existing.timestamp = Date.now();
return false;
}
&nbsp;
this.cache.set(serialized, {
id,
timestamp: Date.now()
});
return true;
}
&nbsp;
has(id: AckType | string, serialized: string): boolean {
const entry = this.cache.get(serialized);
if (!entry) {
return false;
}
&nbsp;
// Check if expired
if (Date.now() - entry.timestamp &gt; this.ttlMs) {
this.cache.delete(serialized);
return false;
}
&nbsp;
return entry.id === id;
}
&nbsp;
get(serialized: string): CacheEntry | undefined {
const entry = this.cache.get(serialized);
if (!entry) {
return undefined;
}
&nbsp;
// Check if expired
if (Date.now() - entry.timestamp &gt; this.ttlMs) {
this.cache.delete(serialized);
return undefined;
}
&nbsp;
return entry;
}
&nbsp;
updateId(serialized: string, newId: AckType | string): boolean {
const entry = this.cache.get(serialized);
if (!entry) {
return false;
}
&nbsp;
entry.id = newId;
entry.timestamp = Date.now();
return true;
}
&nbsp;
dispose() {
if (this.cleanupTimer) {
clearInterval(this.cleanupTimer);
this.cleanupTimer = null;
}
this.cache.clear();
}
}
&nbsp;
// Backwards compatibility alias
export { DeduplicationCache as callbackWile };
&nbsp;</pre></td></tr></table></pre>

<div class='push'></div><!-- for sticky footer -->
</div><!-- /wrapper -->
<div class='footer quiet pad2 space-top1 center small'>
Code coverage generated by
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
at 2026-01-16T00:43:53.943Z
</div>
<script src="../../prettify.js"></script>
<script>
window.onload = function () {
prettyPrint();
};
</script>
<script src="../../sorter.js"></script>
<script src="../../block-navigation.js"></script>
</body>
</html>

No newline at end of file
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if coverage directory is in .gitignore
if [ -f .gitignore ]; then
  echo "=== Contents of .gitignore ==="
  cat .gitignore | grep -i coverage || echo "coverage/ not found in .gitignore"
else
  echo ".gitignore file not found"
fi

# Check how many coverage files are being added
echo -e "\n=== Coverage files in repository ==="
find coverage -type f 2>/dev/null | wc -l
echo "Coverage files found"

# Show first few coverage files
echo -e "\n=== Sample of coverage files ==="
find coverage -type f 2>/dev/null | head -10

# Check if coverage is in git
echo -e "\n=== Git status for coverage directory ==="
git ls-files coverage/ 2>/dev/null | wc -l
echo "Coverage files tracked by git"

Repository: venomlib/venom

Length of output: 727


Add coverage/ directory to .gitignore to prevent committing auto-generated coverage reports.

This repository currently tracks 34 Istanbul coverage HTML files that are regenerated on every test run. These build artifacts should not be committed and are increasing repository size unnecessarily. Add coverage/ to .gitignore and remove the tracked coverage files from git history.

🤖 Prompt for AI Agents
In `@coverage/api/helpers/deduplication-cache.ts.html` around lines 1 - 415, The
repo is tracking generated coverage HTML under coverage/ (e.g.,
coverage/api/helpers/deduplication-cache.ts.html); add coverage/ to .gitignore,
remove the tracked coverage files from Git, and commit the change. Specifically:
add the line "coverage/" to .gitignore, run git rm --cached -r coverage (or use
your history-rewrite tool like git filter-repo/BFG if you need to purge older
commits), and commit & push the removal; this will stop files like the generated
deduplication-cache.ts.html from being committed alongside code and keep classes
like DeduplicationCache and exported alias callbackWile out of versioned
coverage artifacts.

Comment on lines +145 to +162
<span class="cstat-no" title="statement not covered" > for (let i in data) {</span>
<span class="cstat-no" title="statement not covered" > if (typeof i == 'number') {</span>
<span class="cstat-no" title="statement not covered" > let result =</span>
<span class="cstat-no" title="statement not covered" > data[i].type &amp;&amp; data[i].value &amp;&amp; infoType(data[i].value, data[i].type)</span>
<span class="cstat-no" title="statement not covered" > ? true</span>
<span class="cstat-no" title="statement not covered" > : !data[i].value &amp;&amp; data[i].isUser === false</span>
<span class="cstat-no" title="statement not covered" > ? true</span>
<span class="cstat-no" title="statement not covered" > : false;</span>
<span class="cstat-no" title="statement not covered" > if (!result) {</span>
<span class="cstat-no" title="statement not covered" > return {</span>
<span class="cstat-no" title="statement not covered" > erro: true,</span>
<span class="cstat-no" title="statement not covered" > param: data[i].param,</span>
<span class="cstat-no" title="statement not covered" > function: data[i].function,</span>
<span class="cstat-no" title="statement not covered" > text: `Invalid parameter in ${data[i].param}! Pass a variable of type ${data[i].type}!`</span>
<span class="cstat-no" title="statement not covered" > };</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > }</span>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

fd "layers-interface.ts" --type f

Repository: venomlib/venom

Length of output: 139


🏁 Script executed:

wc -l src/api/helpers/layers-interface.ts

Repository: venomlib/venom

Length of output: 96


🏁 Script executed:

cat -n src/api/helpers/layers-interface.ts

Repository: venomlib/venom

Length of output: 1195


Validation loop is effectively skipped — validation never runs.

for (let i in data) produces string keys ('0', '1', '2', etc.), so typeof i == 'number' is always false and the validation block never executes. This allows invalid array items to pass through unchecked. Switch to for (let i = 0; i < data.length; i++) or for (const item of data) with an index counter.

🤖 Prompt for AI Agents
In `@coverage/api/helpers/layers-interface.ts.html` around lines 145 - 162, The
validation loop uses `for (let i in data)` which yields string keys so the
`typeof i == 'number'` check always fails and validation never runs; replace the
loop with a numeric index loop (e.g., `for (let i = 0; i < data.length; i++)`)
or a `for (const [i, item] of data.entries())` pattern so `i` is a numeric index
(or use `for (const item of data)` and refer to `item`), then keep the existing
logic that computes `result` using `infoType(data[i].value, data[i].type)` (or
`infoType(item.value, item.type)`) and return the same error object when
`!result`.

Comment on lines +110 to +122
<span class="cstat-no" title="statement not covered" >export async function scrapeDeleteToken(page: Page): Promise&lt;boolean&gt; {</span>
<span class="cstat-no" title="statement not covered" > const result = await page</span>
<span class="cstat-no" title="statement not covered" > .evaluate(() =&gt; {</span>
<span class="cstat-no" title="statement not covered" > const scrape = window.pathSession;</span>
<span class="cstat-no" title="statement not covered" > if (scrape === true) {</span>
<span class="cstat-no" title="statement not covered" > return true;</span>
<span class="cstat-no" title="statement not covered" > } else {</span>
<span class="cstat-no" title="statement not covered" > return false;</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > })</span>
<span class="cstat-no" title="statement not covered" > .catch(() =&gt; undefined);</span>
<span class="cstat-no" title="statement not covered" > return result;</span>
<span class="cstat-no" title="statement not covered" >}</span>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Type mismatch: function can return undefined despite Promise<boolean> return type.

The embedded source reveals a type safety issue in src/api/helpers/scrape-deletetoken.ts. The function signature declares Promise<boolean>, but the .catch(() => undefined) on line 120 means result can be undefined, which is then returned on line 121.

This will cause issues for callers expecting a boolean. In the actual source file, consider:

 export async function scrapeDeleteToken(page: Page): Promise<boolean> {
   const result = await page
     .evaluate(() => {
       const scrape = window.pathSession;
-      if (scrape === true) {
-        return true;
-      } else {
-        return false;
-      }
+      return scrape === true;
     })
-    .catch(() => undefined);
-  return result;
+    .catch(() => false);
+  return result ?? false;
 }

Also, this is a generated coverage artifact that should not be committed.

🤖 Prompt for AI Agents
In `@coverage/api/helpers/scrape-deletetoken.ts.html` around lines 110 - 122, The
function scrapeDeleteToken has a type mismatch because .catch(() => undefined)
allows returning undefined despite the Promise<boolean> signature; change the
error path to return a boolean (e.g., replace .catch(() => undefined) with
.catch(() => false)) and ensure the page.evaluate callback always returns a
boolean, or alternatively relax the signature to Promise<boolean | undefined> if
undefined is intended; also remove the generated coverage artifact file from the
commit so the coverage HTML isn't included in source.

Comment on lines +5 to +8
body {
font-family: Helvetica Neue, Helvetica, Arial;
font-size: 14px;
color:#333;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Quote the multi-word font family to avoid unintended fallback.

Unquoted Helvetica Neue is parsed as two separate family names, so the intended font may never be selected and Helvetica is duplicated. Quoting it also resolves the duplicate-name lint warning.

🛠️ Suggested fix
-body {
-    font-family: Helvetica Neue, Helvetica, Arial;
+body {
+    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
body {
font-family: Helvetica Neue, Helvetica, Arial;
font-size: 14px;
color:#333;
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
color:`#333`;
🧰 Tools
🪛 Biome (2.1.2)

[error] 6-6: Duplicate font names are redundant and unnecessary: Helvetica

Remove duplicate font names within the property

(lint/suspicious/noDuplicateFontNames)

🤖 Prompt for AI Agents
In `@coverage/base.css` around lines 5 - 8, The font-family declaration in the
body selector uses an unquoted multi-word family name; update the body {
font-family: ... } rule to quote "Helvetica Neue" (e.g., "Helvetica Neue",
Helvetica, Arial) so the multi-word family is treated as a single font family
and to avoid duplicate-name lint warnings.

Comment on lines +52 to +55
.quiet {
color: #7f7f7f;
color: rgba(0,0,0,0.5);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove the duplicate color declaration to satisfy lint.

The second color overrides the first; keep a single modern value (or move fallback into @supports if you still need it).

🛠️ Suggested fix
 .quiet {
-  color: `#7f7f7f`;
-  color: rgba(0,0,0,0.5);
+  color: rgb(0 0 0 / 0.5);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.quiet {
color: #7f7f7f;
color: rgba(0,0,0,0.5);
}
.quiet {
color: rgb(0 0 0 / 0.5);
}
🧰 Tools
🪛 Biome (2.1.2)

[error] 54-54: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.

color is already defined here.

Remove or rename the duplicate property to ensure consistent styling.

(lint/suspicious/noDuplicateProperties)

🤖 Prompt for AI Agents
In `@coverage/base.css` around lines 52 - 55, The .quiet class contains two
duplicate color declarations; remove the redundant one so only a single modern
value remains (e.g., keep color: rgba(0,0,0,0.5); and delete color: `#7f7f7f`;),
or if you need the hex fallback move the hex into an `@supports-compatible`
fallback block and leave the rgba as the primary value in the .quiet rule.

Comment on lines +216 to +220
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -48px;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Drop the duplicate height rule in .wrapper.

Two height declarations trigger the lint error and the latter overrides the former. Remove the redundant line unless you still need the legacy hack.

🛠️ Suggested fix
 .wrapper {
   min-height: 100%;
   height: auto !important;
-  height: 100%;
   margin: 0 auto -48px;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -48px;
.wrapper {
min-height: 100%;
height: auto !important;
margin: 0 auto -48px;
}
🧰 Tools
🪛 Biome (2.1.2)

[error] 219-219: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.

height is already defined here.

Remove or rename the duplicate property to ensure consistent styling.

(lint/suspicious/noDuplicateProperties)

🤖 Prompt for AI Agents
In `@coverage/base.css` around lines 216 - 220, Remove the duplicate height
declaration in the .wrapper rule: delete the redundant "height: 100%;" line
(leaving min-height and the legacy "height: auto !important;" only) so there is
a single, intentional height declaration and the lint error is resolved.

Comment on lines +24 to +38
function toggleClass(index) {
missingCoverageElements
.item(currentIndex)
.classList.remove('highlighted');
missingCoverageElements.item(index).classList.add('highlighted');
}

function makeCurrent(index) {
toggleClass(index);
currentIndex = index;
missingCoverageElements.item(index).scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'center'
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Guard against empty coverage lists before toggling classes.

When there are no matching elements, .item(...) returns null and .classList will throw on the first keypress. Add a length check and only remove the previous highlight when currentIndex is set.

🛠️ Suggested fix
 function toggleClass(index) {
-    missingCoverageElements
-        .item(currentIndex)
-        .classList.remove('highlighted');
-    missingCoverageElements.item(index).classList.add('highlighted');
+    if (!missingCoverageElements.length) return;
+    if (typeof currentIndex === 'number') {
+        const currentEl = missingCoverageElements.item(currentIndex);
+        if (currentEl) currentEl.classList.remove('highlighted');
+    }
+    const nextEl = missingCoverageElements.item(index);
+    if (nextEl) nextEl.classList.add('highlighted');
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function toggleClass(index) {
missingCoverageElements
.item(currentIndex)
.classList.remove('highlighted');
missingCoverageElements.item(index).classList.add('highlighted');
}
function makeCurrent(index) {
toggleClass(index);
currentIndex = index;
missingCoverageElements.item(index).scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'center'
});
function toggleClass(index) {
if (!missingCoverageElements.length) return;
if (typeof currentIndex === 'number') {
const currentEl = missingCoverageElements.item(currentIndex);
if (currentEl) currentEl.classList.remove('highlighted');
}
const nextEl = missingCoverageElements.item(index);
if (nextEl) nextEl.classList.add('highlighted');
}
function makeCurrent(index) {
toggleClass(index);
currentIndex = index;
missingCoverageElements.item(index).scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'center'
});
🤖 Prompt for AI Agents
In `@coverage/block-navigation.js` around lines 24 - 38, The
toggleClass/makeCurrent logic assumes missingCoverageElements.item(...) returns
an element; guard against empty lists by checking missingCoverageElements.length
and that currentIndex is not null/undefined before accessing .classList; only
call missingCoverageElements.item(currentIndex).classList.remove(...) when
missingCoverageElements.length > 0 and currentIndex is a valid index, and
likewise ensure missingCoverageElements.item(index) exists before calling
.classList.add(...) and scrollIntoView in makeCurrent.

Comment on lines +1 to +2
/* eslint-disable */
window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V<U;++V){var ae=Z[V];if(ae.ignoreCase){ac=true}else{if(/[a-z]/i.test(ae.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,""))){S=true;ac=false;break}}}var Y={b:8,t:9,n:10,v:11,f:12,r:13};function ab(ah){var ag=ah.charCodeAt(0);if(ag!==92){return ag}var af=ah.charAt(1);ag=Y[af];if(ag){return ag}else{if("0"<=af&&af<="7"){return parseInt(ah.substring(1),8)}else{if(af==="u"||af==="x"){return parseInt(ah.substring(2),16)}else{return ah.charCodeAt(1)}}}}function T(af){if(af<32){return(af<16?"\\x0":"\\x")+af.toString(16)}var ag=String.fromCharCode(af);if(ag==="\\"||ag==="-"||ag==="["||ag==="]"){ag="\\"+ag}return ag}function X(am){var aq=am.substring(1,am.length-1).match(new RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g"));var ak=[];var af=[];var ao=aq[0]==="^";for(var ar=ao?1:0,aj=aq.length;ar<aj;++ar){var ah=aq[ar];if(/\\[bdsw]/i.test(ah)){ak.push(ah)}else{var ag=ab(ah);var al;if(ar+2<aj&&"-"===aq[ar+1]){al=ab(aq[ar+2]);ar+=2}else{al=ag}af.push([ag,al]);if(!(al<65||ag>122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;ar<af.length;++ar){var at=af[ar];if(at[0]<=ap[1]+1){ap[1]=Math.max(ap[1],at[1])}else{ai.push(ap=at)}}var an=["["];if(ao){an.push("^")}an.push.apply(an,ak);for(var ar=0;ar<ai.length;++ar){var at=ai[ar];an.push(T(at[0]));if(at[1]>at[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak<ah;++ak){var ag=aj[ak];if(ag==="("){++am}else{if("\\"===ag.charAt(0)){var af=+ag.substring(1);if(af&&af<=am){an[af]=-1}}}}for(var ak=1;ak<an.length;++ak){if(-1===an[ak]){an[ak]=++ad}}for(var ak=0,am=0;ak<ah;++ak){var ag=aj[ak];if(ag==="("){++am;if(an[am]===undefined){aj[ak]="(?:"}}else{if("\\"===ag.charAt(0)){var af=+ag.substring(1);if(af&&af<=am){aj[ak]="\\"+an[am]}}}}for(var ak=0,am=0;ak<ah;++ak){if("^"===aj[ak]&&"^"!==aj[ak+1]){aj[ak]=""}}if(al.ignoreCase&&S){for(var ak=0;ak<ah;++ak){var ag=aj[ak];var ai=ag.charAt(0);if(ag.length>=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V<U;++V){var ae=Z[V];if(ae.global||ae.multiline){throw new Error(""+ae)}aa.push("(?:"+W(ae)+")")}return new RegExp(aa.join("|"),ac?"gi":"g")}function a(V){var U=/(?:^|\s)nocode(?:\s|$)/;var X=[];var T=0;var Z=[];var W=0;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=document.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Y=S&&"pre"===S.substring(0,3);function aa(ab){switch(ab.nodeType){case 1:if(U.test(ab.className)){return}for(var ae=ab.firstChild;ae;ae=ae.nextSibling){aa(ae)}var ad=ab.nodeName;if("BR"===ad||"LI"===ad){X[W]="\n";Z[W<<1]=T++;Z[(W++<<1)|1]=ab}break;case 3:case 4:var ac=ab.nodeValue;if(ac.length){if(!Y){ac=ac.replace(/[ \t\r\n]+/g," ")}else{ac=ac.replace(/\r\n?/g,"\n")}X[W]=ac;Z[W<<1]=T;T+=ac.length;Z[(W++<<1)|1]=ab}break}}aa(V);return{sourceCode:X.join("").replace(/\n$/,""),spans:Z}}function B(S,U,W,T){if(!U){return}var V={sourceCode:U,basePos:S};W(V);T.push.apply(T,V.decorations)}var v=/\S/;function o(S){var V=undefined;for(var U=S.firstChild;U;U=U.nextSibling){var T=U.nodeType;V=(T===1)?(V?S:U):(T===3)?(v.test(U.nodeValue)?S:V):V}return V===S?undefined:V}function g(U,T){var S={};var V;(function(){var ad=U.concat(T);var ah=[];var ag={};for(var ab=0,Z=ad.length;ab<Z;++ab){var Y=ad[ab];var ac=Y[3];if(ac){for(var ae=ac.length;--ae>=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae<aq;++ae){var ag=an[ae];var ap=aj[ag];var ai=void 0;var am;if(typeof ap==="string"){am=false}else{var aa=S[ag.charAt(0)];if(aa){ai=ag.match(aa[1]);ap=aa[0]}else{for(var ao=0;ao<X;++ao){aa=T[ao];ai=ag.match(aa[1]);if(ai){ap=aa[0];break}}if(!ai){ap=F}}am=ap.length>=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y<W.length;++Y){ae(W[Y])}if(ag===(ag|0)){W[0].setAttribute("value",ag)}var aa=ac.createElement("OL");aa.className="linenums";var X=Math.max(0,((ag-1))|0)||0;for(var Y=0,T=W.length;Y<T;++Y){af=W[Y];af.className="L"+((Y+X)%10);if(!af.firstChild){af.appendChild(ac.createTextNode("\xA0"))}aa.appendChild(af)}V.appendChild(aa)}function D(ac){var aj=/\bMSIE\b/.test(navigator.userAgent);var am=/\n/g;var al=ac.sourceCode;var an=al.length;var V=0;var aa=ac.spans;var T=aa.length;var ah=0;var X=ac.decorations;var Y=X.length;var Z=0;X[Y]=an;var ar,aq;for(aq=ar=0;aq<Y;){if(X[aq]!==X[aq+2]){X[ar++]=X[aq++];X[ar++]=X[aq++]}else{aq+=2}}Y=ar;for(aq=ar=0;aq<Y;){var at=X[aq];var ab=X[aq+1];var W=aq+2;while(W+2<=Y&&X[W+1]===ab){W+=2}X[ar++]=at;X[ar++]=ab;aq=W}Y=X.length=ar;var ae=null;while(ah<T){var af=aa[ah];var S=aa[ah+2]||an;var ag=X[Z];var ap=X[Z+2]||an;var W=Math.min(S,ap);var ak=aa[ah+1];var U;if(ak.nodeType!==1&&(U=al.substring(V,W))){if(aj){U=U.replace(am,"\r")}ak.nodeValue=U;var ai=ak.ownerDocument;var ao=ai.createElement("SPAN");ao.className=X[Z+1];var ad=ak.parentNode;ad.replaceChild(ao,ak);ao.appendChild(ak);if(V<S){aa[ah+1]=ak=ai.createTextNode(al.substring(W,S));ad.insertBefore(ak,ao.nextSibling)}}V=W;if(V>=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*</.test(S)?"default-markup":"default-code"}return t[T]}c(K,["default-code"]);c(g([],[[F,/^[^<?]+/],[E,/^<!\w[^>]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa<ac.length;++aa){for(var Z=0,V=ac[aa].length;Z<V;++Z){T.push(ac[aa][Z])}}ac=null;var W=Date;if(!W.now){W={now:function(){return +(new Date)}}}var X=0;var S;var ab=/\blang(?:uage)?-([\w.]+)(?!\S)/;var ae=/\bprettyprint\b/;function U(){var ag=(window.PR_SHOULD_USE_CONTINUATION?W.now()+250:Infinity);for(;X<T.length&&W.now()<ag;X++){var aj=T[X];var ai=aj.className;if(ai.indexOf("prettyprint")>=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X<T.length){setTimeout(U,250)}else{if(ad){ad()}}}U()}window.prettyPrintOne=y;window.prettyPrint=b;window.PR={createSimpleLexer:g,registerLangHandler:c,sourceDecorator:i,PR_ATTRIB_NAME:P,PR_ATTRIB_VALUE:n,PR_COMMENT:j,PR_DECLARATION:E,PR_KEYWORD:z,PR_LITERAL:G,PR_NOCODE:N,PR_PLAIN:F,PR_PUNCTUATION:L,PR_SOURCE:J,PR_STRING:C,PR_TAG:m,PR_TYPE:O}})();PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_DECLARATION,/^<!\w[^>]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^<script\b[^>]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:<!--|-->)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check for Biome configuration files
find . -maxdepth 2 -type f \( -name "biome.json" -o -name ".biomeignore" -o -name "biome.jsonc" \) 2>/dev/null | head -20

Repository: venomlib/venom

Length of output: 70


🏁 Script executed:

# Check if coverage/ directory exists and its purpose
ls -la coverage/ 2>/dev/null | head -20

Repository: venomlib/venom

Length of output: 802


🏁 Script executed:

# Verify the file exists and is indeed minified
wc -l coverage/prettify.js 2>/dev/null
file coverage/prettify.js 2>/dev/null

Repository: venomlib/venom

Length of output: 82


🏁 Script executed:

# Look for Biome configuration in package.json or other config locations
if [ -f "package.json" ]; then cat package.json | grep -A 10 '"biome"'; fi

Repository: venomlib/venom

Length of output: 40


🏁 Script executed:

# Search for any existing ignores or patterns for minified/vendor files
find . -maxdepth 2 -type f \( -name ".prettierignore" -o -name ".eslintignore" -o -name ".gitignore" \) -exec head -30 {} + 2>/dev/null

Repository: venomlib/venom

Length of output: 305


🏁 Script executed:

# Read the biome.json to understand current configuration
cat biome.json

Repository: venomlib/venom

Length of output: 1832


🏁 Script executed:

# Check if there's a .biomeignore file that wasn't found in earlier search
cat .biomeignore 2>/dev/null || echo "No .biomeignore file found"

Repository: venomlib/venom

Length of output: 84


🏁 Script executed:

# Look for comments or directives in prettify.js that might already exclude it
head -5 coverage/prettify.js
tail -5 coverage/prettify.js

Repository: venomlib/venom

Length of output: 35237


🏁 Script executed:

# Search for any biome-related ignore patterns in root config files
find . -maxdepth 1 -type f -name "*.json" -o -name "*.jsonc" -o -name "*.js" -o -name "*.ts" 2>/dev/null | xargs grep -l "coverage\|prettify\|ignore" 2>/dev/null | head -10

Repository: venomlib/venom

Length of output: 123


🏁 Script executed:

# Check if this file is mentioned in any configuration or comments
rg "coverage/prettify|prettify\.js" --type json --type js --type ts -B 2 -A 2 2>/dev/null | head -30

Repository: venomlib/venom

Length of output: 40


🏁 Script executed:

# Check if coverage/ directory is generated or part of the build process
find . -maxdepth 2 -type f \( -name "*.json" -o -name "*.ts" -o -name "*.js" -o -name "Makefile" \) -exec grep -l "coverage\|prettify" {} + 2>/dev/null | head -10

Repository: venomlib/venom

Length of output: 132


🏁 Script executed:

# Check if there's a build script in package.json
if [ -f "package.json" ]; then grep -A 5 '"scripts"' package.json | head -20; fi

Repository: venomlib/venom

Length of output: 329


🏁 Script executed:

# Verify if the /* eslint-disable */ comment is sufficient or if Biome needs additional configuration
rg "biomeignore|ignorePatterns" biome.json

Repository: venomlib/venom

Length of output: 40


🏁 Script executed:

# Check Biome documentation or configuration for alternative ways to ignore files
# Look at full biome.json to see if there are any ignore patterns or overrides
cat biome.json | python3 -m json.tool 2>/dev/null | grep -A 5 -B 5 "ignore\|pattern\|exclude"

Repository: venomlib/venom

Length of output: 144


🏁 Script executed:

# Verify if biome supports ignore patterns in its config
rg "ignore|exclude|pattern" biome.json --no-heading

Repository: venomlib/venom

Length of output: 40


🏁 Script executed:

# Check if there's documentation or examples in the repo about handling vendor files
find . -maxdepth 2 -type f \( -name "README*" -o -name "CONTRIBUTING*" -o -name ".gitignore" \) -exec grep -l "coverage\|vendor\|generated" {} + 2>/dev/null

Repository: venomlib/venom

Length of output: 40


🏁 Script executed:

# Verify the coverage directory is indeed for test coverage or documentation
head -20 coverage/index.html 2>/dev/null | head -15

Repository: venomlib/venom

Length of output: 557


🏁 Script executed:

# Check Biome official documentation about ignore patterns - search for any references
web_search "Biome .biomeignore configuration"

Repository: venomlib/venom

Length of output: 108


🏁 Script executed:

# Look for any existing biome-ignore comments or patterns in the codebase
rg "biome-ignore|@biome" --type js --type ts -B 1 -A 1 2>/dev/null | head -20

Repository: venomlib/venom

Length of output: 40


🏁 Script executed:

# Check if there are any other vendor/minified files that might already be handled
find coverage -type f -name "*.js" -o -name "*.css" 2>/dev/null | xargs wc -l | sort -rn | head -10

Repository: venomlib/venom

Length of output: 208


🌐 Web query:

Biome ignore patterns configuration biomeignore

💡 Result:

Short guide — how to configure ignore patterns for Biome

  • Where to put them: in your project Biome config (biome.json / biome.config.*) under the files, formatter or linter sections depending on what you want to ignore. [1][2]

  • Basic files include/ignore:

    • Use files.includes with globs; negated patterns exclude. Example to include everything but ignore dist/:
      { "files": { "includes": ["", "!dist", "!/dist"] } }.
    • Note: excluding a folder using "!dist" will prevent traversal; using "!dist/**" only excludes files but still crawls the folder (worse perf). Prefer "!dist" for directories. [1][2]
  • Force-ignore (prevent the scanner from even indexing a path):

    • Start the negation with double bang !!. Example to never look inside any dist folder:
      { "files": { "includes": ["", "!!/dist"] } }. Use this for build/output folders or nested biome.json/.gitignore you want ignored. [2]
  • Formatter / Linter specific ignores:

    • Formatter: use formatter.ignore or formatter.include arrays (unix shell style globs). When both present, ignore takes precedence. Example:
      { "formatter": { "ignore": ["scripts/*.js"] } }. [4]
    • Linter: use overrides with include/ignore for per-pattern control. Both linter and formatter support per-override include/ignore. [4][6]
  • In-file suppressions:

    • Use single-line suppression comments for specific lint/format cases, e.g.:
      // biome-ignore lint: reason
      // biome-ignore format: reason
    • Biome does not provide an in-file comment to ignore an entire file; use config ignores for that. [1][3][6]

References

  • Biome configuration (files includes/ignore, force-ignore, scanner behavior). [1]
  • Biome configuration reference (force-ignore examples + scanner notes). [2]
  • Formatter ignore & ignore-code comments. [3][4]

If you want, tell me which files/folders you need to ignore and I’ll produce the exact biome.json snippet.


🏁 Script executed:

# Check Biome documentation or comments in biome.json schema reference
head -1 biome.json | grep schema

Repository: venomlib/venom

Length of output: 40


🏁 Script executed:

# Try running biome check on just that file to see if errors actually occur
# First, let's see if biome is installed/available
if command -v biome &> /dev/null; then biome --version; else echo "Biome not in PATH"; fi

Repository: venomlib/venom

Length of output: 73


🏁 Script executed:

# Now that we know biome is installed, let's check if it actually reports errors on prettify.js
biome check coverage/prettify.js 2>&1 | head -30

Repository: venomlib/venom

Length of output: 50371


🏁 Script executed:

# Check the current linter rules for JavaScript files in biome.json to understand what might trigger on this file
grep -A 50 '"linter"' biome.json | grep -E '"rules"|"recommended"'

Repository: venomlib/venom

Length of output: 187


Exclude the coverage/ directory from Biome linting.

Biome reports noUselessUndefinedInitialization on coverage/prettify.js—a minified vendor file used for test coverage reports. Since this is generated code, exclude it in biome.json:

Suggested configuration
# biome.json
{
  "linter": {
    "enabled": true,
+   "ignore": ["coverage"],
    "rules": {
🧰 Tools
🪛 Biome (2.1.2)

[error] 2-2: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 2-2: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 2-2: Shouldn't redeclare 'ar'. Consider to delete it or rename it.

'ar' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'ar'. Consider to delete it or rename it.

'ar' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'at'. Consider to delete it or rename it.

'at' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'ak'. Consider to delete it or rename it.

'ak' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'ak'. Consider to delete it or rename it.

'ak' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'am'. Consider to delete it or rename it.

'am' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'ag'. Consider to delete it or rename it.

'ag' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'af'. Consider to delete it or rename it.

'af' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'ak'. Consider to delete it or rename it.

'ak' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'am'. Consider to delete it or rename it.

'am' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'ak'. Consider to delete it or rename it.

'ak' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'ag'. Consider to delete it or rename it.

'ag' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'V'. Consider to delete it or rename it.

'V' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'U'. Consider to delete it or rename it.

'U' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'ae'. Consider to delete it or rename it.

'ae' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'Y'. Consider to delete it or rename it.

'Y' is defined here:

(lint/suspicious/noRedeclare)


[error] 2-2: Shouldn't redeclare 'W'. Consider to delete it or rename it.

'W' is defined here:

(lint/suspicious/noRedeclare)

🤖 Prompt for AI Agents
In `@coverage/prettify.js` around lines 1 - 2, Summary: Biome is linting generated
vendor file coverage/prettify.js and raising noUselessUndefinedInitialization;
exclude the coverage/ directory in biome.json. Fix: open biome.json and add
"coverage/**" (or "coverage/") to the "exclude" array (or create an "exclude"
array if missing) so Biome ignores the generated files; ensure the pattern
covers nested files (use glob "**") and commit the change. Reference: the lint
rule name noUselessUndefinedInitialization and the generated file
coverage/prettify.js to verify the exclusion works.

Comment on lines +189 to +202
it('should handle message ID generation failure', async () => {
const chatId = '1234567890@c.us';
const mockChat = createChatMock(chatId);

env.storeMock.FindOrCreateChat.findOrCreateLatestChat.mockResolvedValue({
chat: mockChat
});
env.wapiMock.getNewMessageId.mockResolvedValue(null);

const result = await sendMessage(chatId, 'Hello');

expect(result.erro).toBe(true);
expect(result.text).toBe('Error to gerate newId');
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

rg -n "gerate" --type=js

Repository: venomlib/venom

Length of output: 50371


Fix typo in error message: "gerate" should be "generate".

The source code at src/lib/wapi/functions/send-message.js:62 contains the typo 'Error to gerate newId'. Update this to 'Error to generate newId' and adjust the test expectation accordingly.

🤖 Prompt for AI Agents
In `@test/unit/wapi/send-message.test.ts` around lines 189 - 202, The test and
source contain a typo in the error string — update the error message in the
sendMessage implementation (function sendMessage) from "Error to gerate newId"
to "Error to generate newId" and then update the unit test expectation in
send-message.test.ts to expect 'Error to generate newId' so both implementation
and test match; ensure no other occurrences of "gerate" remain.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
src/lib/wapi/functions/mark-markSeen-message.js (1)

7-13: Handle falsy chat from findChat to avoid runtime errors.

When findChat returns null/false, chat.erro throws. Guard and return the error scope early.

🛠️ Proposed fix
-  const chat = await WAPI.findChat(id);
-  if (!chat.erro) {
-    //await Store.ReadSeen.markUnread(chat);
-    await Store.ReadSeen.sendSeen(chat, false);
-    return WAPI.scope(undefined, false, 'OK', null);
-  } else {
-    return WAPI.scope(undefined, true, 'Error', null);
-  }
+  const chat = await WAPI.findChat(id);
+  if (!chat || chat.erro) {
+    return WAPI.scope(undefined, true, 'Error', null);
+  }
+  //await Store.ReadSeen.markUnread(chat);
+  await Store.ReadSeen.sendSeen(chat, false);
+  return WAPI.scope(undefined, false, 'OK', null);
src/lib/wapi/functions/forward-messages.js (1)

18-26: Potential null dereference: chat.id accessed before validation.

Line 18-19 access chat.id._serialized and chat.id before the validation on line 24 checks if chat.id exists. If findChat returns an error object without an id property, this will throw.

Consider moving the chat.id check earlier:

+  if (!chat || !chat.id) {
+    throw chat;
+  }
+
   let newMsgId = await window.WAPI.getNewMessageId(chat.id._serialized);
   let inChat = await WAPI.getchatId(chat.id).catch(() => {});
   if (inChat) {
     chat.lastReceivedKey._serialized = inChat._serialized;
     chat.lastReceivedKey.id = inChat.id;
   }
-  if (!chat.id) {
-    throw chat;
-  }
src/lib/wapi/functions/promote-participant.js (1)

8-13: Guard against falsy results from WAPI.findChat.
If findChat returns false/null for any contact, the current filter dereferences c.erro and will throw. Add a null guard before accessing fields.

🔧 Proposed fix
-  contactsId = contactsId
-    .filter((c) => !c.erro && c.isUser)
+  contactsId = contactsId
+    .filter((c) => c && !c.erro && c.isUser)
     .map((c) => chat.groupMetadata.participants.get(c.id))
src/lib/wapi/functions/set-profile-pic.js (1)

2-8: Normalize WAPI.getMeUser() return value to a Wid before passing to sendSetPicture.

The code path when id is falsy passes the raw result from getMeUser() (a Store object) directly to sendSetPicture, while the truthy path wraps the id with Store.WidFactory.createWid(). This type inconsistency can cause sendSetPicture to receive incompatible types. Align both code paths to normalize the return value using Store.WidFactory.createWid(), following the pattern used elsewhere in the codebase (e.g., get-host.js).

src/lib/wapi/functions/set-new-message.js (1)

9-22: Guard against null chat before dereferencing chat.id.

WAPI.findChat can fail or return a 404-like object (as handled elsewhere). Accessing chat.id without checking chat can throw and break message creation.

🛠️ Proposed fix
-    if (chat.id) {
+    if (chat && chat.status !== 404 && chat.id) {
       const newMsgId = new Object();
       newMsgId.fromMe = true;
       newMsgId.id = info.id;
       newMsgId.remote = await new Store.WidFactory.createWid(
         chat.id._serialized
       );
       newMsgId._serialized = `${newMsgId.fromMe}_${newMsgId.remote}_${newMsgId.id}`;
       const Msgkey = await new Store.MsgKey(newMsgId);
       return Msgkey;
-    } else {
-      return false;
     }
+    return false;
src/lib/wapi/functions/simulate-status-chat.js (1)

6-68: Avoid chat.erro access when findChat returns null/false.

With the new findChat path, these functions will throw if it returns a falsy value. Add a guard before touching chat.erro (apply to all four helpers).

🛠️ Proposed fix (apply to each function)
 export async function startTyping(chatId, checkNumber = true) {
   const chat = await WAPI.findChat(chatId);
-  if (chat && chat.status != 404 && chat.id) {
+  if (!chat) return chat;
+  if (chat.status != 404 && chat.id) {
     await WAPI.presenceAvailable();
     const result = await Store.SetStatusChat.markComposing(chat);
     return WAPI.scope(undefined, false, result);
   }
   if (!chat.erro) {
     chat.erro = true;
   }
   return chat;
 }
🤖 Fix all issues with AI agents
In `@src/lib/wapi/functions/add-participant.js`:
- Around line 8-11: The code maps contactsId via WAPI.findChat then immediately
checks length and passes results to addParticipants, but Promise.all preserves
input length and findChat can return error objects (status === 404); update the
flow to filter the Promise.all results (for example filter out entries where
c.erro is truthy or c.isUser is false) before calling addParticipants and change
the emptiness check to use the filtered array (return false if filtered.length
=== 0); locate the logic around contactsId, WAPI.findChat, and the call to
addParticipants in add-participant.js to implement this filtering and adjusted
check (mirroring the pattern used in create-group.js).

In `@src/lib/wapi/functions/check-send-exist.js`:
- Around line 99-115: The findChat function is not awaiting async results: await
WAPI.sendCheckType(chatId) should be used so invalid IDs don't bypass
validation, and await window.Store.WidFactory.createWid(chatId) should be used
so findOrCreateLatestChat receives a Wid (not a Promise); update findChat to
await both WAPI.sendCheckType and WidFactory.createWid (keeping the try/catch
and returning WAPI.scope(...) on failure) to mirror the usage in get-chat.js.

In `@src/lib/wapi/functions/delete-all-message.js`:
- Around line 10-11: The error check after calling findChat uses "chat &&
chat.status != 404" which is inconsistent with the rest of the codebase that
checks for "!chat.erro"; update the check in the delete-all-message handler to
the standard pattern (e.g., if (chat && !chat.erro) or simply if (!chat.erro)
after ensuring chat is defined) so it matches send-contact-vcard-list.js and
send-seen.js; locate the findChat call and the "chat" variable in
delete-all-message.js and replace the status-based check with the erro-based
check, and run a quick grep for other findChat usages to ensure consistency
across files.

In `@src/lib/wapi/functions/delete-messages.js`:
- Line 10: The call to WAPI.findChat can return falsy and the code later
dereferences chat (e.g., accessing chat.erro), so add a null check immediately
after "const chat = await WAPI.findChat(chatId)" to handle missing chats: if
chat is falsy, return a scoped error result object (consistent with the
function's return shape) indicating the chatId was not found instead of
continuing; apply the same guard where chat is used later (the block around
lines 75-79) to prevent dereference errors.

In `@src/lib/wapi/functions/fix-chat.js`:
- Around line 8-9: The error check in fix-chat.js uses the nonstandard condition
"if (!chat.erro)"; update the validation to match the codebase pattern by
checking "chat.status !== 404" after calling WAPI.findChat(chatId), and also
ensure a valid chat id is present (e.g., verify chat.id) if pinning requires
it—mirror the checks used in pin.chat.js and other message functions to maintain
consistency and avoid the validation gap.

In `@src/lib/wapi/functions/get-new-message-id.js`:
- Around line 1-4: In getNewMessageId, add a null guard for the result of
WAPI.findChat by changing the conditional to check both chat and chat.id (e.g.,
if (chat && chat.id)) to avoid throwing when findChat returns falsy, and remove
the unused parameter checkNumber from the function signature (export async
function getNewMessageId(chatId)) as it is never used; update any internal
references within getNewMessageId (e.g., newMsgId creation/logic) accordingly
and run tests to ensure callers remain compatible.

In `@src/lib/wapi/functions/get-number-profile.js`:
- Line 5: The code calls WAPI.findChat(id) and later accesses chat.erro without
ensuring chat is not null; add a null guard after const chat = await
WAPI.findChat(id) (e.g., check if chat is truthy before any chat.erro access)
and handle the falsy case by returning or throwing an appropriate error/result
from get-number-profile so subsequent lines never access properties on a
null/undefined chat.

In `@src/lib/wapi/functions/mark-unseen-message.js`:
- Line 7: WAPI.findChat(id) can return undefined, so update the
mark-unseen-message logic to guard against a falsy chat before accessing
chat.erro: after calling WAPI.findChat(id) check that the returned chat is
truthy (e.g., if (!chat) { handle/not-found path or return false }) and only
then read chat.erro and proceed with setting isUnseen; reference the
WAPI.findChat call and the chat.erro access in mark-unseen-message.js and ensure
the function returns or handles the missing-chat case gracefully.

In `@src/lib/wapi/functions/only-send-data-admin.js`:
- Around line 10-14: The code calls WAPI.findChat(chat) but then uses the
original chat variable for the group ID, which can be a string and lead to
undefined IDs; update the flow in only-send-data-admin.js to use the resolved
chatObj (from WAPI.findChat) for the ID passed to
Store.onlySendAdmin.sendSetGroupProperty (i.e., use chatObj.id), and add a guard
to handle when chatObj is falsy before calling sendSetGroupProperty and before
returning via WAPI.scope to avoid passing undefined IDs.

In `@test/index.js`:
- Line 48: Replace the hardcoded recipient in the test that calls
client.sendText(...) with a configurable value: stop committing PII by reading
the destination number from an environment variable (e.g.,
process.env.TEST_WHATSAPP_NUMBER) or a test-only constant/mock, and update the
test harness to validate the variable is set (or skip the integration send when
not present); locate the call to client.sendText in test/index.js and refactor
it to use the env variable or mock-number and document the required env var in
the test README.
🧹 Nitpick comments (16)
test/index.js (3)

2-2: Unused import after commenting out FFmpeg block.

The fluent-ffmpeg import is no longer used since the FFmpeg audio processing block is commented out. Consider removing it to keep the test script clean.

Suggested fix
 import venom from '../dist/index.mjs';
-import ffmpeg from 'fluent-ffmpeg';

19-21: Unused variable f.

getHostDevice() result is assigned to f but is no longer used since the console.log is commented out. Consider either removing the assignment or uncommenting the log if it's needed for debugging.

Suggested fix (if host device info is not needed)
 async function start(client) {
-  const f = await client.getHostDevice();
   console.log(await client.getWAVersion());
-  //console.log(f);

26-47: Consider removing the commented-out FFmpeg block.

Large blocks of commented-out code clutter the codebase and can become stale. If this functionality is no longer needed for the test script, consider removing it entirely. If it's needed for occasional debugging, consider keeping it in a separate file or behind a feature flag.

src/lib/wapi/functions/send-file.js (1)

128-128: WAPI.getMeUser integration looks good; remember to rebuild WAPI bundle.

As per coding guidelines, run npm run build:wapi after modifying injected WAPI functions.

src/lib/wapi/functions/set-group-image.js (1)

13-13: LGTM on the findChat swap; remember to rebuild the WAPI bundle.

This aligns with the new lookup API. As per coding guidelines, please run npm run build:wapi after modifying WAPI function files.

src/lib/wapi/functions/archive-chat.js (1)

2-2: Looks good; aligns with the findChat migration.

No behavioral concerns with the lookup switch. Reminder: rebuild the injected WAPI bundle after modifying files under src/lib/wapi/functions (run npm run build:wapi). As per coding guidelines, please run npm run build:wapi after modifying WAPI functions.

src/lib/wapi/functions/send-message.js (1)

46-46: Guard against a null/undefined getMeUser() result before building the message.

If WAPI.getMeUser() can ever resolve to a falsy value (e.g., during initialization), message.from becomes invalid and send can fail unpredictably. Please confirm the helper’s guarantees, and consider a fail-fast guard if needed.

✅ Suggested guard
-    const fromwWid = await WAPI.getMeUser();
+    const fromwWid = await WAPI.getMeUser();
+    if (!fromwWid) {
+      return WAPI.scope(to, true, 404, 'Unable to resolve sender user');
+    }
src/lib/wapi/functions/send-seen.js (1)

3-14: Promise result is discarded; function always returns true on success path.

The WAPI.scope() return values from .then() and .catch() are never used. The function always returns true (line 11) regardless of whether markUnread succeeded or failed. This appears to be pre-existing behavior, but since this file is being touched, consider fixing it:

Proposed fix to properly return the result
 export async function sendSeen(id, done) {
   const chat = await WAPI.findChat(id);
   if (!chat.erro) {
-    await Store.ReadSeen.markUnread(chat, false)
+    return await Store.ReadSeen.markUnread(chat, false)
       .then(() => {
         return WAPI.scope(undefined, false, 'OK', null);
       })
       .catch(() => {
         return WAPI.scope(undefined, true, 'Error', null);
       });
-    return true;
   } else {
-    return false;
+    return WAPI.scope(undefined, true, 'Error', 'Chat not found');
   }
 }

Also note: the done parameter is unused and could be removed if it's not needed for a callback pattern.

src/lib/wapi/functions/forward-messages.js (1)

65-68: Empty catch clause loses error context.

The catch block discards the error, making debugging harder. Consider capturing and logging the error or including it in the thrown scope object.

♻️ Suggested improvement
-  } catch {
+  } catch (error) {
     var obj = WAPI.scope(newMsgId, true, 404, null);
     Object.assign(obj, m);
     throw obj;
   }
src/lib/wapi/functions/get-group-admins.js (1)

18-56: Consider using optional chaining to reduce verbosity.

The repetitive participant.contact && participant.contact.X ? participant.contact.X : null pattern can be simplified.

♻️ Suggested simplification
         return {
           id: participant.id ? participant.id : null,
-          displayName:
-            participant.contact && participant.contact.displayName
-              ? participant.contact.displayName
-              : null,
-          mentionName:
-            participant.contact && participant.contact.mentionName
-              ? participant.contact.mentionName
-              : null,
+          displayName: participant.contact?.displayName ?? null,
+          mentionName: participant.contact?.mentionName ?? null,
+          notifyName: participant.contact?.notifyName ?? null,
+          isBusiness: participant.contact?.isBusiness ?? null,
+          pushname: participant.contact?.pushname ?? null,
+          isUser: participant.contact?.isUser ?? null,
+          isMyContact: participant.contact?.isMyContact ?? null,
+          isMe: participant.contact?.isMe ?? null
           // ... apply same pattern to remaining properties
         };
src/lib/wapi/functions/send-type-buttons.js (1)

13-17: Dead code: redundant check is always false.

Line 15 checks if (!hButtons[index].urlButton) inside a block that's only entered when hButtons[index].urlButton is truthy (line 13). This condition can never be true.

The same pattern appears at lines 48 and 85 for callButton and quickReplyButton.

♻️ Remove unreachable checks
         if (hButtons[index].urlButton) {
           b++;
-          if (!hButtons[index].urlButton) {
-            return WAPI.scope(to, true, 404, 'passed object urlButton');
-          }
           if (typeof hButtons[index].urlButton !== 'object') {

Apply similar removal at lines 48-50 and 85-87.

src/lib/wapi/functions/promote-participant.js (1)

1-29: Remember to rebuild the injected WAPI bundle after edits.
Run npm run build:wapi after modifying src/lib/wapi/functions/**/*.js. As per coding guidelines, please rebuild the WAPI layer bundle.

src/lib/wapi/functions/demote-participant.js (1)

8-8: Harden lookup failures when using WAPI.findChat.

If WAPI.findChat can reject (or return a different error shape than sendExist), Promise.all will short‑circuit and the whole demotion fails. Consider normalizing failures so one bad ID doesn’t abort the batch, or confirm findChat never rejects.

💡 Possible hardening
-  contactsId = await Promise.all(contactsId.map((c) => WAPI.findChat(c)));
+  contactsId = await Promise.all(
+    contactsId.map((c) =>
+      WAPI.findChat(c).catch(() => ({ erro: true, isUser: false }))
+    )
+  );
src/lib/wapi/functions/get-all-chats.js (1)

2-4: Guard for WAPI.getMeUser() return shape before _serialized.

This assumes getMeUser() returns an object with _serialized. If it ever returns a string or null, Line 4 will throw. Please confirm the contract or make it tolerant.

💡 Compatibility guard
-  const fromwWid = await WAPI.getMeUser();
+  const me = await WAPI.getMeUser();
+  const fromwWid = typeof me === 'string' ? me : me?._serialized;
   if (fromwWid) {
-    const idUser = await WAPI.findChat(fromwWid._serialized);
+    const idUser = await WAPI.findChat(fromwWid);
src/lib/wapi/functions/remove-participant.js (1)

8-8: Confirm findChat rejection behavior in batch resolution.

If WAPI.findChat can reject, Promise.all will abort and skip removals entirely. Please confirm it never rejects, or consider normalizing failures to keep the batch resilient.

src/lib/wapi/functions/send-list-menu.js (1)

98-103: LGTM on the findChat / getMeUser switch.

This matches the updated WAPI usage pattern and keeps the existing guard intact.
As per coding guidelines, remember to run npm run build:wapi after changing WAPI injected functions.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0da892e and c5ec758.

⛔ Files ignored due to path filters (10)
  • dist/cjs/api/layers/group.layer.js is excluded by !**/dist/**
  • dist/cjs/api/layers/group.layer.js.map is excluded by !**/dist/**, !**/*.map
  • dist/cjs/api/layers/sender.layer.js is excluded by !**/dist/**
  • dist/cjs/api/layers/sender.layer.js.map is excluded by !**/dist/**, !**/*.map
  • dist/esm/api/layers/group.layer.js is excluded by !**/dist/**
  • dist/esm/api/layers/group.layer.js.map is excluded by !**/dist/**, !**/*.map
  • dist/esm/api/layers/sender.layer.js is excluded by !**/dist/**
  • dist/esm/api/layers/sender.layer.js.map is excluded by !**/dist/**, !**/*.map
  • dist/lib/wapi/wapi.js is excluded by !**/dist/**
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (58)
  • src/api/layers/group.layer.ts
  • src/api/layers/sender.layer.ts
  • src/lib/wapi/functions/add-participant.js
  • src/lib/wapi/functions/archive-chat.js
  • src/lib/wapi/functions/check-id-messagem.js
  • src/lib/wapi/functions/check-send-exist.js
  • src/lib/wapi/functions/create-group.js
  • src/lib/wapi/functions/delete-all-message.js
  • src/lib/wapi/functions/delete-messages.js
  • src/lib/wapi/functions/demote-participant.js
  • src/lib/wapi/functions/fix-chat.js
  • src/lib/wapi/functions/forward-messages.js
  • src/lib/wapi/functions/get-all-chats.js
  • src/lib/wapi/functions/get-all-messages-in-chat.js
  • src/lib/wapi/functions/get-data-messages.js
  • src/lib/wapi/functions/get-group-admins.js
  • src/lib/wapi/functions/get-host.js
  • src/lib/wapi/functions/get-new-message-id.js
  • src/lib/wapi/functions/get-number-profile.js
  • src/lib/wapi/functions/index.js
  • src/lib/wapi/functions/mark-markSeen-message.js
  • src/lib/wapi/functions/mark-unseen-message.js
  • src/lib/wapi/functions/only-send-admin.js
  • src/lib/wapi/functions/only-send-data-admin.js
  • src/lib/wapi/functions/open-chat.js
  • src/lib/wapi/functions/pin.chat.js
  • src/lib/wapi/functions/poll-creation.js
  • src/lib/wapi/functions/promote-participant.js
  • src/lib/wapi/functions/remove-participant.js
  • src/lib/wapi/functions/reply.js
  • src/lib/wapi/functions/send-buttons.js
  • src/lib/wapi/functions/send-contact-vcard-list.js
  • src/lib/wapi/functions/send-contact-vcard.js
  • src/lib/wapi/functions/send-file.js
  • src/lib/wapi/functions/send-link-preview.js
  • src/lib/wapi/functions/send-list-menu.js
  • src/lib/wapi/functions/send-location.js
  • src/lib/wapi/functions/send-message-scope.js
  • src/lib/wapi/functions/send-message.js
  • src/lib/wapi/functions/send-mute.js
  • src/lib/wapi/functions/send-ptt.js
  • src/lib/wapi/functions/send-seen.js
  • src/lib/wapi/functions/send-sticker.js
  • src/lib/wapi/functions/send-type-buttons.js
  • src/lib/wapi/functions/sendMessageOptions.js
  • src/lib/wapi/functions/set-group-description.js
  • src/lib/wapi/functions/set-group-image.js
  • src/lib/wapi/functions/set-group-settings.js
  • src/lib/wapi/functions/set-group-title.js
  • src/lib/wapi/functions/set-new-message.js
  • src/lib/wapi/functions/set-profile-pic.js
  • src/lib/wapi/functions/simulate-status-chat.js
  • src/lib/wapi/functions/test.js
  • src/lib/wapi/helper/filter-object.js
  • src/lib/wapi/helper/get-me-user.js
  • src/lib/wapi/helper/index.js
  • src/lib/wapi/wapi.js
  • test/index.js
🧰 Additional context used
📓 Path-based instructions (4)
src/lib/wapi/**/*.js

📄 CodeRabbit inference engine (CLAUDE.md)

WAPI layer code is built with webpack and injected into the Puppeteer browser context

Files:

  • src/lib/wapi/helper/index.js
  • src/lib/wapi/functions/send-mute.js
  • src/lib/wapi/functions/get-all-messages-in-chat.js
  • src/lib/wapi/functions/poll-creation.js
  • src/lib/wapi/functions/forward-messages.js
  • src/lib/wapi/functions/delete-messages.js
  • src/lib/wapi/functions/remove-participant.js
  • src/lib/wapi/functions/get-number-profile.js
  • src/lib/wapi/functions/set-group-description.js
  • src/lib/wapi/functions/test.js
  • src/lib/wapi/functions/send-type-buttons.js
  • src/lib/wapi/functions/get-group-admins.js
  • src/lib/wapi/functions/send-location.js
  • src/lib/wapi/helper/get-me-user.js
  • src/lib/wapi/functions/set-profile-pic.js
  • src/lib/wapi/functions/send-list-menu.js
  • src/lib/wapi/functions/mark-markSeen-message.js
  • src/lib/wapi/functions/send-link-preview.js
  • src/lib/wapi/functions/check-id-messagem.js
  • src/lib/wapi/functions/get-all-chats.js
  • src/lib/wapi/functions/send-message-scope.js
  • src/lib/wapi/functions/send-message.js
  • src/lib/wapi/functions/get-host.js
  • src/lib/wapi/functions/set-group-settings.js
  • src/lib/wapi/functions/delete-all-message.js
  • src/lib/wapi/wapi.js
  • src/lib/wapi/functions/fix-chat.js
  • src/lib/wapi/functions/get-new-message-id.js
  • src/lib/wapi/functions/simulate-status-chat.js
  • src/lib/wapi/functions/set-group-image.js
  • src/lib/wapi/functions/send-contact-vcard-list.js
  • src/lib/wapi/functions/demote-participant.js
  • src/lib/wapi/functions/create-group.js
  • src/lib/wapi/helper/filter-object.js
  • src/lib/wapi/functions/send-sticker.js
  • src/lib/wapi/functions/open-chat.js
  • src/lib/wapi/functions/get-data-messages.js
  • src/lib/wapi/functions/pin.chat.js
  • src/lib/wapi/functions/send-buttons.js
  • src/lib/wapi/functions/index.js
  • src/lib/wapi/functions/add-participant.js
  • src/lib/wapi/functions/promote-participant.js
  • src/lib/wapi/functions/sendMessageOptions.js
  • src/lib/wapi/functions/send-seen.js
  • src/lib/wapi/functions/send-ptt.js
  • src/lib/wapi/functions/send-file.js
  • src/lib/wapi/functions/check-send-exist.js
  • src/lib/wapi/functions/set-group-title.js
  • src/lib/wapi/functions/set-new-message.js
  • src/lib/wapi/functions/only-send-admin.js
  • src/lib/wapi/functions/archive-chat.js
  • src/lib/wapi/functions/only-send-data-admin.js
  • src/lib/wapi/functions/send-contact-vcard.js
  • src/lib/wapi/functions/reply.js
  • src/lib/wapi/functions/mark-unseen-message.js
src/lib/wapi/functions/**/*.js

📄 CodeRabbit inference engine (CLAUDE.md)

WAPI functions in src/lib/wapi/functions are JavaScript files injected into the browser; after changing them, run npm run build:wapi to rebuild

Files:

  • src/lib/wapi/functions/send-mute.js
  • src/lib/wapi/functions/get-all-messages-in-chat.js
  • src/lib/wapi/functions/poll-creation.js
  • src/lib/wapi/functions/forward-messages.js
  • src/lib/wapi/functions/delete-messages.js
  • src/lib/wapi/functions/remove-participant.js
  • src/lib/wapi/functions/get-number-profile.js
  • src/lib/wapi/functions/set-group-description.js
  • src/lib/wapi/functions/test.js
  • src/lib/wapi/functions/send-type-buttons.js
  • src/lib/wapi/functions/get-group-admins.js
  • src/lib/wapi/functions/send-location.js
  • src/lib/wapi/functions/set-profile-pic.js
  • src/lib/wapi/functions/send-list-menu.js
  • src/lib/wapi/functions/mark-markSeen-message.js
  • src/lib/wapi/functions/send-link-preview.js
  • src/lib/wapi/functions/check-id-messagem.js
  • src/lib/wapi/functions/get-all-chats.js
  • src/lib/wapi/functions/send-message-scope.js
  • src/lib/wapi/functions/send-message.js
  • src/lib/wapi/functions/get-host.js
  • src/lib/wapi/functions/set-group-settings.js
  • src/lib/wapi/functions/delete-all-message.js
  • src/lib/wapi/functions/fix-chat.js
  • src/lib/wapi/functions/get-new-message-id.js
  • src/lib/wapi/functions/simulate-status-chat.js
  • src/lib/wapi/functions/set-group-image.js
  • src/lib/wapi/functions/send-contact-vcard-list.js
  • src/lib/wapi/functions/demote-participant.js
  • src/lib/wapi/functions/create-group.js
  • src/lib/wapi/functions/send-sticker.js
  • src/lib/wapi/functions/open-chat.js
  • src/lib/wapi/functions/get-data-messages.js
  • src/lib/wapi/functions/pin.chat.js
  • src/lib/wapi/functions/send-buttons.js
  • src/lib/wapi/functions/index.js
  • src/lib/wapi/functions/add-participant.js
  • src/lib/wapi/functions/promote-participant.js
  • src/lib/wapi/functions/sendMessageOptions.js
  • src/lib/wapi/functions/send-seen.js
  • src/lib/wapi/functions/send-ptt.js
  • src/lib/wapi/functions/send-file.js
  • src/lib/wapi/functions/check-send-exist.js
  • src/lib/wapi/functions/set-group-title.js
  • src/lib/wapi/functions/set-new-message.js
  • src/lib/wapi/functions/only-send-admin.js
  • src/lib/wapi/functions/archive-chat.js
  • src/lib/wapi/functions/only-send-data-admin.js
  • src/lib/wapi/functions/send-contact-vcard.js
  • src/lib/wapi/functions/reply.js
  • src/lib/wapi/functions/mark-unseen-message.js
src/api/layers/*.layer.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Keep functionality layers in src/api/layers using the *.layer.ts naming (e.g., sender.layer.ts, listener.layer.ts, group.layer.ts, profile.layer.ts, controls.layer.ts, retriever.layer.ts)

Files:

  • src/api/layers/sender.layer.ts
  • src/api/layers/group.layer.ts
test/index.js

📄 CodeRabbit inference engine (CLAUDE.md)

Use test/index.js as the main test script; tests are basic scripts without a formal framework

Files:

  • test/index.js
🧠 Learnings (4)
📚 Learning: 2025-09-08T17:49:03.345Z
Learnt from: CR
Repo: venomlib/venom PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T17:49:03.345Z
Learning: Applies to src/lib/wapi/functions/**/*.js : WAPI functions in src/lib/wapi/functions are JavaScript files injected into the browser; after changing them, run `npm run build:wapi` to rebuild

Applied to files:

  • src/lib/wapi/functions/forward-messages.js
  • src/lib/wapi/functions/delete-messages.js
  • src/lib/wapi/functions/test.js
  • src/lib/wapi/functions/send-type-buttons.js
  • src/lib/wapi/functions/send-list-menu.js
  • src/lib/wapi/functions/send-link-preview.js
  • src/lib/wapi/functions/delete-all-message.js
  • src/lib/wapi/wapi.js
  • src/lib/wapi/functions/pin.chat.js
  • src/lib/wapi/functions/index.js
  • src/lib/wapi/functions/send-seen.js
  • src/lib/wapi/functions/only-send-data-admin.js
  • src/lib/wapi/functions/reply.js
📚 Learning: 2025-09-08T17:49:03.345Z
Learnt from: CR
Repo: venomlib/venom PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T17:49:03.345Z
Learning: Applies to src/api/layers/*.layer.ts : Keep functionality layers in src/api/layers using the *.layer.ts naming (e.g., sender.layer.ts, listener.layer.ts, group.layer.ts, profile.layer.ts, controls.layer.ts, retriever.layer.ts)

Applied to files:

  • src/api/layers/sender.layer.ts
  • src/api/layers/group.layer.ts
📚 Learning: 2025-09-08T17:49:03.345Z
Learnt from: CR
Repo: venomlib/venom PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T17:49:03.345Z
Learning: Applies to src/api/helpers/**/*.{ts,js} : Put utility helpers (e.g., encryption, QR code utilities) under src/api/helpers

Applied to files:

  • src/api/layers/sender.layer.ts
  • src/api/layers/group.layer.ts
📚 Learning: 2025-09-08T17:49:03.345Z
Learnt from: CR
Repo: venomlib/venom PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T17:49:03.345Z
Learning: Applies to test/index.js : Use test/index.js as the main test script; tests are basic scripts without a formal framework

Applied to files:

  • test/index.js
🧬 Code graph analysis (33)
src/lib/wapi/functions/get-all-messages-in-chat.js (1)
src/lib/wapi/functions/get-chat.js (1)
  • getChat (1-49)
src/lib/wapi/functions/poll-creation.js (13)
src/lib/wapi/functions/archive-chat.js (1)
  • chat (2-2)
src/lib/wapi/functions/check-id-messagem.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-all-message.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-messages.js (1)
  • chat (10-10)
src/lib/wapi/functions/get-all-messages-in-chat.js (1)
  • chat (7-7)
src/lib/wapi/functions/get-data-messages.js (1)
  • chat (42-42)
src/lib/wapi/functions/get-group-admins.js (1)
  • chat (5-5)
src/lib/wapi/functions/get-new-message-id.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-number-profile.js (1)
  • chat (5-5)
src/lib/wapi/functions/mark-markSeen-message.js (1)
  • chat (7-7)
src/lib/wapi/functions/send-buttons.js (1)
  • chat (40-40)
src/lib/wapi/wapi.js (3)
  • chat (443-443)
  • chat (502-502)
  • chat (511-511)
src/lib/wapi/functions/get-all-chats.js (1)
  • idUser (4-4)
src/lib/wapi/functions/forward-messages.js (9)
src/lib/wapi/functions/get-new-message-id.js (1)
  • chat (2-2)
src/lib/wapi/wapi.js (3)
  • chat (443-443)
  • chat (502-502)
  • chat (511-511)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/get-host.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/send-link-preview.js (1)
  • fromwWid (31-31)
src/lib/wapi/functions/send-message-scope.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-type-buttons.js (1)
  • fromwWid (122-122)
src/lib/wapi/functions/test.js (1)
  • fromwWid (6-6)
src/lib/wapi/functions/get-chat.js (1)
  • getChat (1-49)
src/lib/wapi/functions/get-number-profile.js (2)
src/lib/wapi/wapi.js (3)
  • chat (443-443)
  • chat (502-502)
  • chat (511-511)
src/lib/wapi/functions/get-chat.js (1)
  • getChat (1-49)
src/lib/wapi/functions/set-group-description.js (12)
src/lib/wapi/functions/archive-chat.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-data-messages.js (1)
  • chat (42-42)
src/lib/wapi/functions/get-group-admins.js (1)
  • chat (5-5)
src/lib/wapi/functions/send-buttons.js (1)
  • chat (40-40)
src/lib/wapi/functions/send-list-menu.js (1)
  • chat (98-98)
src/lib/wapi/functions/send-location.js (1)
  • chat (7-7)
src/lib/wapi/functions/send-message-scope.js (1)
  • chat (39-39)
src/lib/wapi/functions/set-group-image.js (1)
  • chat (13-13)
src/lib/wapi/functions/set-group-settings.js (1)
  • chat (16-16)
src/lib/wapi/functions/set-group-title.js (1)
  • chat (15-15)
src/lib/wapi/functions/get-chat.js (1)
  • getChat (1-49)
src/lib/wapi/business/send-message-with-buttons.js (1)
  • chatId (179-339)
src/lib/wapi/functions/test.js (6)
src/lib/wapi/functions/reply.js (3)
  • chat (26-26)
  • newMsgId (59-59)
  • fromwWid (60-60)
src/lib/wapi/functions/send-message-scope.js (3)
  • chat (39-39)
  • newMsgId (43-43)
  • fromwWid (44-44)
src/lib/wapi/functions/send-message.js (3)
  • chat (31-31)
  • newMsgId (43-45)
  • fromwWid (46-46)
src/lib/wapi/functions/send-link-preview.js (2)
  • newMsgId (30-30)
  • fromwWid (31-31)
src/lib/wapi/functions/get-host.js (2)
  • window (6-6)
  • fromwWid (2-2)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/send-type-buttons.js (13)
src/lib/wapi/functions/archive-chat.js (1)
  • chat (2-2)
src/lib/wapi/functions/delete-messages.js (1)
  • chat (10-10)
src/lib/wapi/functions/reply.js (2)
  • chat (26-26)
  • fromwWid (60-60)
src/lib/wapi/functions/send-buttons.js (2)
  • chat (40-40)
  • fromwWid (44-44)
src/lib/wapi/functions/send-contact-vcard.js (2)
  • chat (15-15)
  • fromwWid (43-43)
src/lib/wapi/functions/send-list-menu.js (2)
  • chat (98-98)
  • fromwWid (102-102)
src/lib/wapi/functions/send-location.js (2)
  • chat (7-7)
  • fromwWid (19-19)
src/lib/wapi/functions/send-message-scope.js (2)
  • chat (39-39)
  • fromwWid (44-44)
src/lib/wapi/functions/send-sticker.js (2)
  • chat (2-2)
  • fromwWid (6-6)
src/lib/wapi/functions/test.js (2)
  • chat (2-2)
  • fromwWid (6-6)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/get-host.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/send-link-preview.js (1)
  • fromwWid (31-31)
src/lib/wapi/functions/get-group-admins.js (13)
src/lib/wapi/functions/archive-chat.js (1)
  • chat (2-2)
src/lib/wapi/functions/check-id-messagem.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-all-message.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-messages.js (1)
  • chat (10-10)
src/lib/wapi/functions/send-buttons.js (1)
  • chat (40-40)
src/lib/wapi/functions/send-list-menu.js (1)
  • chat (98-98)
src/lib/wapi/functions/send-location.js (1)
  • chat (7-7)
src/lib/wapi/functions/set-group-description.js (1)
  • chat (15-15)
src/lib/wapi/functions/set-group-settings.js (1)
  • chat (16-16)
src/lib/wapi/functions/set-group-title.js (1)
  • chat (15-15)
src/lib/wapi/wapi.js (3)
  • chat (443-443)
  • chat (502-502)
  • chat (511-511)
src/lib/wapi/functions/clear-chat.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-chat.js (1)
  • getChat (1-49)
src/lib/wapi/functions/send-location.js (3)
src/lib/wapi/functions/get-new-message-id.js (1)
  • chat (2-2)
src/lib/wapi/wapi.js (3)
  • chat (443-443)
  • chat (502-502)
  • chat (511-511)
src/lib/wapi/functions/get-chat.js (2)
  • getChat (1-49)
  • window (44-46)
src/lib/wapi/functions/set-profile-pic.js (2)
src/api/layers/retriever.layer.ts (1)
  • getProfilePicFromServer (236-241)
src/api/layers/profile.layer.ts (1)
  • WAPI (104-104)
src/lib/wapi/functions/send-list-menu.js (6)
src/lib/wapi/functions/get-new-message-id.js (2)
  • chat (2-2)
  • newMsgId (4-4)
src/lib/wapi/functions/send-message.js (3)
  • chat (31-31)
  • newMsgId (43-45)
  • fromwWid (46-46)
src/lib/wapi/wapi.js (3)
  • chat (443-443)
  • chat (502-502)
  • chat (511-511)
src/lib/wapi/functions/send-link-preview.js (2)
  • newMsgId (30-30)
  • fromwWid (31-31)
src/lib/wapi/functions/set-new-message.js (1)
  • newMsgId (12-12)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/mark-markSeen-message.js (3)
src/lib/wapi/functions/get-data-messages.js (1)
  • chat (42-42)
src/lib/wapi/functions/get-number-profile.js (1)
  • chat (5-5)
src/lib/wapi/functions/mark-unseen-message.js (1)
  • chat (7-7)
src/lib/wapi/functions/send-link-preview.js (2)
src/lib/wapi/functions/send-contact-vcard-list.js (2)
  • chat (29-29)
  • fromwWid (52-52)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/get-all-chats.js (16)
src/lib/wapi/functions/get-host.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/reply.js (1)
  • fromwWid (60-60)
src/lib/wapi/functions/send-buttons.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-contact-vcard-list.js (1)
  • fromwWid (52-52)
src/lib/wapi/functions/send-contact-vcard.js (1)
  • fromwWid (43-43)
src/lib/wapi/functions/send-link-preview.js (1)
  • fromwWid (31-31)
src/lib/wapi/functions/send-list-menu.js (1)
  • fromwWid (102-102)
src/lib/wapi/functions/send-location.js (1)
  • fromwWid (19-19)
src/lib/wapi/functions/send-message-scope.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-message.js (1)
  • fromwWid (46-46)
src/lib/wapi/functions/send-sticker.js (1)
  • fromwWid (6-6)
src/lib/wapi/functions/send-type-buttons.js (1)
  • fromwWid (122-122)
src/lib/wapi/functions/sendMessageOptions.js (1)
  • fromwWid (104-104)
src/lib/wapi/functions/test.js (1)
  • fromwWid (6-6)
src/lib/wapi/functions/get-chat.js (1)
  • window (44-46)
src/api/layers/retriever.layer.ts (1)
  • WAPI (349-354)
src/lib/wapi/functions/send-message-scope.js (4)
src/lib/wapi/functions/delete-messages.js (1)
  • chat (10-10)
src/lib/wapi/functions/reply.js (2)
  • chat (26-26)
  • fromwWid (60-60)
src/lib/wapi/functions/send-buttons.js (2)
  • chat (40-40)
  • fromwWid (44-44)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/send-message.js (14)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/get-host.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/reply.js (1)
  • fromwWid (60-60)
src/lib/wapi/functions/send-buttons.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-contact-vcard-list.js (1)
  • fromwWid (52-52)
src/lib/wapi/functions/send-contact-vcard.js (1)
  • fromwWid (43-43)
src/lib/wapi/functions/send-link-preview.js (1)
  • fromwWid (31-31)
src/lib/wapi/functions/send-list-menu.js (1)
  • fromwWid (102-102)
src/lib/wapi/functions/send-location.js (1)
  • fromwWid (19-19)
src/lib/wapi/functions/send-message-scope.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-sticker.js (1)
  • fromwWid (6-6)
src/lib/wapi/functions/send-type-buttons.js (1)
  • fromwWid (122-122)
src/lib/wapi/functions/sendMessageOptions.js (1)
  • fromwWid (104-104)
src/lib/wapi/functions/test.js (1)
  • fromwWid (6-6)
src/lib/wapi/functions/get-host.js (4)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/send-message-scope.js (2)
  • fromwWid (44-44)
  • chat (39-39)
src/lib/wapi/functions/check-send-exist.js (2)
  • wid (106-106)
  • window (107-107)
src/lib/wapi/functions/send-file.js (2)
  • wid (59-59)
  • chat (60-60)
src/lib/wapi/wapi.js (1)
src/lib/wapi/helper/get-me-user.js (1)
  • getMeUser (5-11)
src/lib/wapi/functions/get-new-message-id.js (3)
src/lib/wapi/functions/get-data-messages.js (1)
  • chat (42-42)
src/lib/wapi/functions/get-chat.js (1)
  • getChat (1-49)
src/api/layers/retriever.layer.ts (2)
  • chatId (62-62)
  • getNewMessageId (44-70)
src/lib/wapi/functions/send-contact-vcard-list.js (7)
src/lib/wapi/functions/delete-messages.js (1)
  • chat (10-10)
src/lib/wapi/functions/reply.js (2)
  • chat (26-26)
  • fromwWid (60-60)
src/lib/wapi/functions/send-contact-vcard.js (2)
  • chat (15-15)
  • fromwWid (43-43)
src/lib/wapi/functions/send-list-menu.js (2)
  • chat (98-98)
  • fromwWid (102-102)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/get-host.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/get-chat.js (1)
  • getChat (1-49)
src/lib/wapi/functions/demote-participant.js (1)
dist/lib/wapi/wapi.js (5)
  • c (1-1)
  • c (1-1)
  • c (1-1)
  • c (1-1)
  • c (1-1)
src/lib/wapi/helper/filter-object.js (1)
src/lib/wapi/wapi.js (1)
  • module (166-166)
src/lib/wapi/functions/get-data-messages.js (18)
src/lib/wapi/functions/add-participant.js (1)
  • chat (2-2)
src/lib/wapi/functions/archive-chat.js (1)
  • chat (2-2)
src/lib/wapi/functions/check-id-messagem.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-all-message.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-messages.js (1)
  • chat (10-10)
src/lib/wapi/functions/demote-participant.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-all-messages-in-chat.js (1)
  • chat (7-7)
src/lib/wapi/functions/get-group-admins.js (1)
  • chat (5-5)
src/lib/wapi/functions/get-new-message-id.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-number-profile.js (1)
  • chat (5-5)
src/lib/wapi/functions/mark-markSeen-message.js (1)
  • chat (7-7)
src/lib/wapi/functions/mark-unseen-message.js (1)
  • chat (7-7)
src/lib/wapi/functions/only-send-admin.js (1)
  • chat (9-9)
src/lib/wapi/functions/send-message-scope.js (1)
  • chat (39-39)
src/lib/wapi/functions/set-group-description.js (1)
  • chat (15-15)
src/lib/wapi/functions/set-group-image.js (1)
  • chat (13-13)
src/lib/wapi/functions/get-chat.js (1)
  • getChat (1-49)
src/api/layers/retriever.layer.ts (3)
  • WAPI (330-331)
  • WAPI (349-354)
  • getAllMessagesInChat (324-334)
src/lib/wapi/functions/pin.chat.js (1)
src/lib/wapi/functions/get-chat.js (2)
  • getChat (1-49)
  • window (44-46)
src/lib/wapi/functions/promote-participant.js (1)
dist/lib/wapi/wapi.js (5)
  • c (1-1)
  • c (1-1)
  • c (1-1)
  • c (1-1)
  • c (1-1)
src/lib/wapi/functions/sendMessageOptions.js (15)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/get-host.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/reply.js (1)
  • fromwWid (60-60)
src/lib/wapi/functions/send-buttons.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-contact-vcard-list.js (1)
  • fromwWid (52-52)
src/lib/wapi/functions/send-contact-vcard.js (1)
  • fromwWid (43-43)
src/lib/wapi/functions/send-link-preview.js (1)
  • fromwWid (31-31)
src/lib/wapi/functions/send-list-menu.js (1)
  • fromwWid (102-102)
src/lib/wapi/functions/send-location.js (1)
  • fromwWid (19-19)
src/lib/wapi/functions/send-message-scope.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-message.js (1)
  • fromwWid (46-46)
src/lib/wapi/functions/send-sticker.js (1)
  • fromwWid (6-6)
src/lib/wapi/functions/send-type-buttons.js (1)
  • fromwWid (122-122)
src/lib/wapi/functions/test.js (1)
  • fromwWid (6-6)
src/api/model/message.ts (1)
  • Sender (83-101)
src/lib/wapi/functions/send-file.js (17)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/get-host.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/reply.js (1)
  • fromwWid (60-60)
src/lib/wapi/functions/send-buttons.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-contact-vcard-list.js (1)
  • fromwWid (52-52)
src/lib/wapi/functions/send-contact-vcard.js (1)
  • fromwWid (43-43)
src/lib/wapi/functions/send-link-preview.js (1)
  • fromwWid (31-31)
src/lib/wapi/functions/send-list-menu.js (1)
  • fromwWid (102-102)
src/lib/wapi/functions/send-location.js (1)
  • fromwWid (19-19)
src/lib/wapi/functions/send-message-scope.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-message.js (1)
  • fromwWid (46-46)
src/lib/wapi/functions/send-sticker.js (1)
  • fromwWid (6-6)
src/lib/wapi/functions/send-type-buttons.js (1)
  • fromwWid (122-122)
src/lib/wapi/functions/sendMessageOptions.js (1)
  • fromwWid (104-104)
src/lib/wapi/functions/test.js (1)
  • fromwWid (6-6)
src/api/whatsapp.ts (2)
  • WAPI (136-136)
  • () => undefined (166-166)
src/types/WAPI.d.ts (1)
  • WAPI (14-271)
src/lib/wapi/functions/check-send-exist.js (3)
src/lib/wapi/functions/get-host.js (2)
  • wid (4-4)
  • window (6-6)
src/lib/wapi/functions/load-earlier-chat-messages.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-chat.js (1)
  • getChat (1-49)
src/lib/wapi/functions/set-group-title.js (3)
src/lib/wapi/functions/archive-chat.js (1)
  • chat (2-2)
src/lib/wapi/functions/send-buttons.js (1)
  • chat (40-40)
src/lib/wapi/functions/send-list-menu.js (1)
  • chat (98-98)
src/lib/wapi/functions/set-new-message.js (5)
src/lib/wapi/functions/archive-chat.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-data-messages.js (1)
  • chat (42-42)
src/lib/wapi/functions/get-group-admins.js (1)
  • chat (5-5)
src/lib/wapi/functions/get-new-message-id.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-chat.js (1)
  • getChat (1-49)
src/lib/wapi/functions/archive-chat.js (14)
src/lib/wapi/functions/check-id-messagem.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-all-message.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-messages.js (1)
  • chat (10-10)
src/lib/wapi/functions/get-all-messages-in-chat.js (1)
  • chat (7-7)
src/lib/wapi/functions/get-data-messages.js (1)
  • chat (42-42)
src/lib/wapi/functions/get-group-admins.js (1)
  • chat (5-5)
src/lib/wapi/functions/get-new-message-id.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-number-profile.js (1)
  • chat (5-5)
src/lib/wapi/functions/mark-markSeen-message.js (1)
  • chat (7-7)
src/lib/wapi/functions/mark-unseen-message.js (1)
  • chat (7-7)
src/lib/wapi/functions/only-send-admin.js (1)
  • chat (9-9)
src/lib/wapi/functions/open-chat.js (3)
  • chat (7-7)
  • chat (16-16)
  • chat (18-18)
src/lib/wapi/functions/get-all-chats.js (1)
  • idUser (4-4)
src/api/layers/controls.layer.ts (2)
  • archiveChat (124-129)
  • WAPI (126-126)
src/lib/wapi/functions/only-send-data-admin.js (16)
src/lib/wapi/functions/add-participant.js (1)
  • chat (2-2)
src/lib/wapi/functions/archive-chat.js (1)
  • chat (2-2)
src/lib/wapi/functions/check-id-messagem.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-all-message.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-messages.js (1)
  • chat (10-10)
src/lib/wapi/functions/demote-participant.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-all-messages-in-chat.js (1)
  • chat (7-7)
src/lib/wapi/functions/get-data-messages.js (1)
  • chat (42-42)
src/lib/wapi/functions/get-group-admins.js (1)
  • chat (5-5)
src/lib/wapi/functions/get-new-message-id.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-number-profile.js (1)
  • chat (5-5)
src/lib/wapi/functions/mark-markSeen-message.js (1)
  • chat (7-7)
src/lib/wapi/functions/mark-unseen-message.js (1)
  • chat (7-7)
src/lib/wapi/functions/only-send-admin.js (1)
  • chat (9-9)
src/lib/wapi/functions/open-chat.js (2)
  • chat (7-7)
  • chat (16-16)
src/lib/wapi/functions/get-chat.js (1)
  • getChat (1-49)
src/lib/wapi/functions/reply.js (4)
src/lib/wapi/functions/delete-messages.js (1)
  • chat (10-10)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/get-host.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/test.js (1)
  • fromwWid (6-6)

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +8 to 11
contactsId = await Promise.all(contactsId.map((c) => WAPI.findChat(c)));
if (!contactsId.length) {
return false;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Missing filter for failed chat lookups.

findChat returns an error scope object (with status === 404) when the contact isn't found. Unlike create-group.js which filters results with contactsId.filter((c) => !c.erro && c.isUser), this code passes all results directly to addParticipants, including failed lookups. Additionally, the check !contactsId.length on line 9 will never be true since Promise.all preserves the input array length.

Proposed fix to filter invalid results
   contactsId = await Promise.all(contactsId.map((c) => WAPI.findChat(c)));
+  contactsId = contactsId.filter((c) => c && !c.erro && c.id);
   if (!contactsId.length) {
     return false;
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
contactsId = await Promise.all(contactsId.map((c) => WAPI.findChat(c)));
if (!contactsId.length) {
return false;
}
contactsId = await Promise.all(contactsId.map((c) => WAPI.findChat(c)));
contactsId = contactsId.filter((c) => c && !c.erro && c.id);
if (!contactsId.length) {
return false;
}
🤖 Prompt for AI Agents
In `@src/lib/wapi/functions/add-participant.js` around lines 8 - 11, The code maps
contactsId via WAPI.findChat then immediately checks length and passes results
to addParticipants, but Promise.all preserves input length and findChat can
return error objects (status === 404); update the flow to filter the Promise.all
results (for example filter out entries where c.erro is truthy or c.isUser is
false) before calling addParticipants and change the emptiness check to use the
filtered array (return false if filtered.length === 0); locate the logic around
contactsId, WAPI.findChat, and the call to addParticipants in add-participant.js
to implement this filtering and adjusted check (mirroring the pattern used in
create-group.js).

Comment on lines +99 to +115
export async function findChat(chatId) {
const checkType = WAPI.sendCheckType(chatId);
if (!!checkType && checkType.status === 404) {
if (checkType && checkType.status === 404) {
return checkType;
}

let chat = await WAPI.getChat(chatId);
if (!chat) {
var idUser = new Store.UserConstructor(chatId, {
intentionallyUsePrivateConstructor: true
});
const chatWid = new Store.WidFactory.createWid(chatId);
await Store.Chat.add(
{
createdLocally: true,
id: chatWid
},
{
merge: true
}
);
chat = await Store.Chat.find(idUser);
}

if (chat === undefined) {
const chatWid = new Store.WidFactory.createWid(chatId);
await Store.Chat.add(
{
createdLocally: true,
id: chatWid
},
{
merge: true
}
);
const storeChat = await Store.Chat.find(chatId);
if (storeChat) {
chat =
storeChat && storeChat.id && storeChat.id._serialized
? await WAPI.getChat(storeChat.id._serialized)
: undefined;
}
}

if (!chat) {
return WAPI.scope(chatId, true, 404);
}

if (Send) {
await window.Store.ReadSeen.sendSeen(chat, false);
}

if (returnChat) {
return chat;
}

return WAPI.scope(chatId, false, 200);
}

export async function sendExist(chatId, returnChat = true, Send = true) {
const checkType = await WAPI.sendCheckType(chatId);
if (!!checkType && checkType.status === 404) {
return checkType;
}

let ck = await window.WAPI.checkNumberStatus(chatId, false);

if (
(ck.status === 404 &&
!chatId.includes('@g.us') &&
!chatId.includes('@broadcast')) ||
(ck &&
ck.text &&
typeof ck.text.includes === 'function' &&
ck.text.includes('XmppParsingFailure'))
) {
return WAPI.scope(chatId, true, ck.status, 'The number does not exist');
}

const chatWid = new Store.WidFactory.createWid(chatId);

let chat =
ck && ck.id && ck.id._serialized
? await WAPI.getChat(ck.id._serialized)
: undefined;

if (ck.numberExists && chat === undefined) {
var idUser = new Store.UserConstructor(chatId, {
intentionallyUsePrivateConstructor: true
});
const chatWid = new Store.WidFactory.createWid(chatId);
await Store.Chat.add(
{
createdLocally: true,
id: chatWid
},
{
merge: true
}
);
chat = await Store.Chat.find(idUser);
}

if (!chat) {
const storeChat = await Store.Chat.find(chatWid);
if (storeChat) {
chat =
storeChat && storeChat.id && storeChat.id._serialized
? await WAPI.getChat(storeChat.id._serialized)
: undefined;
try {
const wid = window.Store.WidFactory.createWid(chatId);
const { chat } = await window.Store.FindOrCreateChat.findOrCreateLatestChat(wid);
if (chat) {
return chat;
}
} catch (err) {
window.onLog(`findChat error for ${chatId}: ${err?.message || err}`);
}

if (!chat) {
return WAPI.scope(chatId, true, 404);
}

if (!ck.numberExists && !chat.t && chat.isUser) {
return WAPI.scope(chatId, true, ck.status, 'The number does not exist');
}

if (!ck.numberExists && !chat.t && chat.isGroup) {
return WAPI.scope(
chatId,
true,
ck.status,
'The group number does not exist on your chat list, or it does not exist at all!'
);
}

if (
!ck.numberExists &&
!chat.t &&
chat.id &&
chat.id.user != 'status' &&
chat.isBroadcast
) {
return WAPI.scope(
chatId,
true,
ck.status,
'The transmission list number does not exist on your chat list, or it does not exist at all!'
);
}

if (Send) {
await window.Store.ReadSeen.sendSeen(chat, false);
}

if (returnChat) {
return chat;
}

return WAPI.scope(chatId, false, 200);
return WAPI.scope(chatId, true, 404, 'Chat not found');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Await validation and WID creation in findChat.
Line 100 calls WAPI.sendCheckType which returns a Promise (via async WAPI.scope), so without await invalid IDs can skip validation. Line 106 should await WidFactory.createWid to match usage in src/lib/wapi/functions/get-chat.js and avoid passing a Promise into findOrCreateLatestChat.

🛠️ Proposed fix
-export async function findChat(chatId) {
-  const checkType = WAPI.sendCheckType(chatId);
+export async function findChat(chatId) {
+  const checkType = await WAPI.sendCheckType(chatId);
   if (checkType && checkType.status === 404) {
     return checkType;
   }

   try {
-    const wid = window.Store.WidFactory.createWid(chatId);
+    const wid = await window.Store.WidFactory.createWid(chatId);
     const { chat } = await window.Store.FindOrCreateChat.findOrCreateLatestChat(wid);
     if (chat) {
       return chat;
     }
   } catch (err) {

Also, since this file lives under src/lib/wapi/functions, remember to run npm run build:wapi after changes. Based on learnings, this is required for WAPI injection rebuilds.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export async function findChat(chatId) {
const checkType = WAPI.sendCheckType(chatId);
if (!!checkType && checkType.status === 404) {
if (checkType && checkType.status === 404) {
return checkType;
}
let chat = await WAPI.getChat(chatId);
if (!chat) {
var idUser = new Store.UserConstructor(chatId, {
intentionallyUsePrivateConstructor: true
});
const chatWid = new Store.WidFactory.createWid(chatId);
await Store.Chat.add(
{
createdLocally: true,
id: chatWid
},
{
merge: true
}
);
chat = await Store.Chat.find(idUser);
}
if (chat === undefined) {
const chatWid = new Store.WidFactory.createWid(chatId);
await Store.Chat.add(
{
createdLocally: true,
id: chatWid
},
{
merge: true
}
);
const storeChat = await Store.Chat.find(chatId);
if (storeChat) {
chat =
storeChat && storeChat.id && storeChat.id._serialized
? await WAPI.getChat(storeChat.id._serialized)
: undefined;
}
}
if (!chat) {
return WAPI.scope(chatId, true, 404);
}
if (Send) {
await window.Store.ReadSeen.sendSeen(chat, false);
}
if (returnChat) {
return chat;
}
return WAPI.scope(chatId, false, 200);
}
export async function sendExist(chatId, returnChat = true, Send = true) {
const checkType = await WAPI.sendCheckType(chatId);
if (!!checkType && checkType.status === 404) {
return checkType;
}
let ck = await window.WAPI.checkNumberStatus(chatId, false);
if (
(ck.status === 404 &&
!chatId.includes('@g.us') &&
!chatId.includes('@broadcast')) ||
(ck &&
ck.text &&
typeof ck.text.includes === 'function' &&
ck.text.includes('XmppParsingFailure'))
) {
return WAPI.scope(chatId, true, ck.status, 'The number does not exist');
}
const chatWid = new Store.WidFactory.createWid(chatId);
let chat =
ck && ck.id && ck.id._serialized
? await WAPI.getChat(ck.id._serialized)
: undefined;
if (ck.numberExists && chat === undefined) {
var idUser = new Store.UserConstructor(chatId, {
intentionallyUsePrivateConstructor: true
});
const chatWid = new Store.WidFactory.createWid(chatId);
await Store.Chat.add(
{
createdLocally: true,
id: chatWid
},
{
merge: true
}
);
chat = await Store.Chat.find(idUser);
}
if (!chat) {
const storeChat = await Store.Chat.find(chatWid);
if (storeChat) {
chat =
storeChat && storeChat.id && storeChat.id._serialized
? await WAPI.getChat(storeChat.id._serialized)
: undefined;
try {
const wid = window.Store.WidFactory.createWid(chatId);
const { chat } = await window.Store.FindOrCreateChat.findOrCreateLatestChat(wid);
if (chat) {
return chat;
}
} catch (err) {
window.onLog(`findChat error for ${chatId}: ${err?.message || err}`);
}
if (!chat) {
return WAPI.scope(chatId, true, 404);
}
if (!ck.numberExists && !chat.t && chat.isUser) {
return WAPI.scope(chatId, true, ck.status, 'The number does not exist');
}
if (!ck.numberExists && !chat.t && chat.isGroup) {
return WAPI.scope(
chatId,
true,
ck.status,
'The group number does not exist on your chat list, or it does not exist at all!'
);
}
if (
!ck.numberExists &&
!chat.t &&
chat.id &&
chat.id.user != 'status' &&
chat.isBroadcast
) {
return WAPI.scope(
chatId,
true,
ck.status,
'The transmission list number does not exist on your chat list, or it does not exist at all!'
);
}
if (Send) {
await window.Store.ReadSeen.sendSeen(chat, false);
}
if (returnChat) {
return chat;
}
return WAPI.scope(chatId, false, 200);
return WAPI.scope(chatId, true, 404, 'Chat not found');
export async function findChat(chatId) {
const checkType = await WAPI.sendCheckType(chatId);
if (checkType && checkType.status === 404) {
return checkType;
}
try {
const wid = await window.Store.WidFactory.createWid(chatId);
const { chat } = await window.Store.FindOrCreateChat.findOrCreateLatestChat(wid);
if (chat) {
return chat;
}
} catch (err) {
window.onLog(`findChat error for ${chatId}: ${err?.message || err}`);
}
return WAPI.scope(chatId, true, 404, 'Chat not found');
🤖 Prompt for AI Agents
In `@src/lib/wapi/functions/check-send-exist.js` around lines 99 - 115, The
findChat function is not awaiting async results: await
WAPI.sendCheckType(chatId) should be used so invalid IDs don't bypass
validation, and await window.Store.WidFactory.createWid(chatId) should be used
so findOrCreateLatestChat receives a Wid (not a Promise); update findChat to
await both WAPI.sendCheckType and WidFactory.createWid (keeping the try/catch
and returning WAPI.scope(...) on failure) to mirror the usage in get-chat.js.

Comment on lines +10 to 11
const chat = await WAPI.findChat(chatId);
if (chat && chat.status != 404) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Inconsistent error handling pattern with findChat.

This file uses chat && chat.status != 404 for error checking, while other files in this PR (e.g., send-contact-vcard-list.js, send-seen.js) use !chat.erro. This inconsistency suggests that either:

  1. findChat returns different error structures in different scenarios, or
  2. Some files haven't been fully migrated to the correct error handling pattern

Consider standardizing the error check across all files to ensure consistent behavior.

Suggested verification
#!/bin/bash
# Find all error handling patterns after findChat calls
rg -n "findChat" --type js -A 2 src/lib/wapi/functions/ | rg -A 1 "findChat"
🤖 Prompt for AI Agents
In `@src/lib/wapi/functions/delete-all-message.js` around lines 10 - 11, The error
check after calling findChat uses "chat && chat.status != 404" which is
inconsistent with the rest of the codebase that checks for "!chat.erro"; update
the check in the delete-all-message handler to the standard pattern (e.g., if
(chat && !chat.erro) or simply if (!chat.erro) after ensuring chat is defined)
so it matches send-contact-vcard-list.js and send-seen.js; locate the findChat
call and the "chat" variable in delete-all-message.js and replace the
status-based check with the erro-based check, and run a quick grep for other
findChat usages to ensure consistency across files.

);
}
const chat = await WAPI.sendExist(chatId);
const chat = await WAPI.findChat(chatId);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Guard against falsy chat from findChat before dereferencing.

findChat can return a falsy value for invalid IDs; the current else branch will throw when accessing chat.erro. Add a null check and return a scoped error instead.

🛠️ Proposed fix
-  } else {
-    if (!chat.erro) {
-      chat.erro = true;
-    }
-    return chat;
-  }
+  } else {
+    if (!chat || typeof chat !== 'object') {
+      return WAPI.scope(chatId, true, 404, 'Chat not found');
+    }
+    if (!chat.erro) {
+      chat.erro = true;
+    }
+    return chat;
+  }

Also applies to: 75-79

🤖 Prompt for AI Agents
In `@src/lib/wapi/functions/delete-messages.js` at line 10, The call to
WAPI.findChat can return falsy and the code later dereferences chat (e.g.,
accessing chat.erro), so add a null check immediately after "const chat = await
WAPI.findChat(chatId)" to handle missing chats: if chat is falsy, return a
scoped error result object (consistent with the function's return shape)
indicating the chatId was not found instead of continuing; apply the same guard
where chat is used later (the block around lines 75-79) to prevent dereference
errors.

Comment on lines +8 to 9
var chat = await WAPI.findChat(chatId);
if (!chat.erro) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cd src/lib/wapi/functions && find . -name "fix-chat.js" -type f

Repository: venomlib/venom

Length of output: 71


🏁 Script executed:

cat -n src/lib/wapi/functions/fix-chat.js

Repository: venomlib/venom

Length of output: 1165


🏁 Script executed:

rg -A 5 -B 5 "findChat" src/lib/wapi/functions/ --type js | head -100

Repository: venomlib/venom

Length of output: 7271


🏁 Script executed:

rg "status.*404|404.*status" src/lib/wapi/ --type js | head -30

Repository: venomlib/venom

Length of output: 2568


🏁 Script executed:

rg "\.erro" src/lib/wapi/functions/ --type js -A 2 -B 2 | head -50

Repository: venomlib/venom

Length of output: 2842


Standardize error check to match codebase pattern.

fix-chat.js uses if (!chat.erro) while the rest of the codebase checks chat.status !== 404 (present in 20+ functions). This inconsistency creates a validation gap. Replace with the standard pattern used elsewhere:

-  if (!chat.erro) {
+  if (chat && chat.status != 404) {

Or include chat.id check if pinning requires a valid chat ID, matching the pattern in pin.chat.js and other message functions.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var chat = await WAPI.findChat(chatId);
if (!chat.erro) {
var chat = await WAPI.findChat(chatId);
if (chat && chat.status != 404) {
🤖 Prompt for AI Agents
In `@src/lib/wapi/functions/fix-chat.js` around lines 8 - 9, The error check in
fix-chat.js uses the nonstandard condition "if (!chat.erro)"; update the
validation to match the codebase pattern by checking "chat.status !== 404" after
calling WAPI.findChat(chatId), and also ensure a valid chat id is present (e.g.,
verify chat.id) if pinning requires it—mirror the checks used in pin.chat.js and
other message functions to maintain consistency and avoid the validation gap.

Comment on lines 1 to 4
export async function getNewMessageId(chatId, checkNumber = true) {
const chat = checkNumber
? await WAPI.sendExist(chatId)
: await WAPI.returnChat(chatId);
const chat = await WAPI.findChat(chatId);
if (chat.id) {
const newMsgId = new Object();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n src/lib/wapi/functions/get-new-message-id.js

Repository: venomlib/venom

Length of output: 661


🏁 Script executed:

rg -nP --type=js --type=ts 'getNewMessageId' -C 3

Repository: venomlib/venom

Length of output: 50371


🏁 Script executed:

rg -nP --type=js --type=ts -C 2 '\bgetNewMessageId\s*\([^)]*,\s*false\b'

Repository: venomlib/venom

Length of output: 40


Add null guard and remove the unused checkNumber parameter.

Line 3 accesses chat.id without verifying chat exists—if findChat returns falsy, this throws. The checkNumber parameter is declared but never used in the function, and no callers pass checkNumber = false.

Fix: Change if (chat.id) to if (chat && chat.id) on line 3, and remove the unused checkNumber parameter from line 1.

🤖 Prompt for AI Agents
In `@src/lib/wapi/functions/get-new-message-id.js` around lines 1 - 4, In
getNewMessageId, add a null guard for the result of WAPI.findChat by changing
the conditional to check both chat and chat.id (e.g., if (chat && chat.id)) to
avoid throwing when findChat returns falsy, and remove the unused parameter
checkNumber from the function signature (export async function
getNewMessageId(chatId)) as it is never used; update any internal references
within getNewMessageId (e.g., newMsgId creation/logic) accordingly and run tests
to ensure callers remain compatible.

*/
export async function markUnseenMessage(id) {
const chat = await WAPI.sendExist(id);
const chat = await WAPI.findChat(id);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n src/lib/wapi/functions/mark-unseen-message.js

Repository: venomlib/venom

Length of output: 507


🏁 Script executed:

# Search for findChat implementation in WAPI
rg -A 10 "findChat\s*[:=]" src/lib/wapi

Repository: venomlib/venom

Length of output: 625


🏁 Script executed:

# Look for other files that use findChat to understand its return contract
rg "WAPI\.findChat|\.findChat" src/lib/wapi/functions -B 2 -A 5 | head -100

Repository: venomlib/venom

Length of output: 7248


🏁 Script executed:

# Find the findChat function definition
rg -B 5 -A 15 "function findChat|const findChat" src/lib/wapi --type js

Repository: venomlib/venom

Length of output: 1436


Guard against falsy values returned by findChat.

WAPI.findChat(id) returns undefined on failure (when chat is not found or an error occurs). Accessing chat.erro without a null check will throw a TypeError.

🛠️ Proposed fix
export async function markUnseenMessage(id) {
  const chat = await WAPI.findChat(id);
-  if (!chat.erro) {
-    await Store.ReadSeen.markUnread(chat, true);
-    return WAPI.scope(undefined, false, 'OK', null);
-  } else {
-    return WAPI.scope(undefined, true, 'Error', null);
-  }
+  if (!chat || chat.erro) {
+    return WAPI.scope(undefined, true, 'Error', null);
+  }
+  await Store.ReadSeen.markUnread(chat, true);
+  return WAPI.scope(undefined, false, 'OK', null);
}
🤖 Prompt for AI Agents
In `@src/lib/wapi/functions/mark-unseen-message.js` at line 7, WAPI.findChat(id)
can return undefined, so update the mark-unseen-message logic to guard against a
falsy chat before accessing chat.erro: after calling WAPI.findChat(id) check
that the returned chat is truthy (e.g., if (!chat) { handle/not-found path or
return false }) and only then read chat.erro and proceed with setting isUnseen;
reference the WAPI.findChat call and the chat.erro access in
mark-unseen-message.js and ensure the function returns or handles the
missing-chat case gracefully.

Comment on lines 10 to 14
if (chat && chat.status != 404 && chat.id) {
const chat = await WAPI.sendExist(chat);
const chatObj = await WAPI.findChat(chat);
try {
await Store.onlySendAdmin.sendSetGroupProperty(chat.id, `restrict`, type);
return WAPI.scope(chat, false, 200, 'successfully changed');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use the resolved chat object; current flow can pass undefined IDs.
chatObj is resolved but ignored; sendSetGroupProperty(chat.id, ...) can pass undefined when chat is a string. This is a functional regression.

🔧 Proposed fix
-  if (chat && chat.status != 404 && chat.id) {
-    const chatObj = await WAPI.findChat(chat);
+  const chatObj = await WAPI.findChat(chat);
+  if (chatObj && chatObj.status != 404 && chatObj.id) {
     try {
-      await Store.onlySendAdmin.sendSetGroupProperty(chat.id, `restrict`, type);
+      await Store.onlySendAdmin.sendSetGroupProperty(
+        chatObj.id,
+        `restrict`,
+        type
+      );
       return WAPI.scope(chat, false, 200, 'successfully changed');
🤖 Prompt for AI Agents
In `@src/lib/wapi/functions/only-send-data-admin.js` around lines 10 - 14, The
code calls WAPI.findChat(chat) but then uses the original chat variable for the
group ID, which can be a string and lead to undefined IDs; update the flow in
only-send-data-admin.js to use the resolved chatObj (from WAPI.findChat) for the
ID passed to Store.onlySendAdmin.sendSetGroupProperty (i.e., use chatObj.id),
and add a guard to handle when chatObj is falsy before calling
sendSetGroupProperty and before returning via WAPI.scope to avoid passing
undefined IDs.

test/index.js Outdated
.run();

.run(); */
await client.sendText('16036627490@c.us', 'Hi there');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Hardcoded phone number in test script poses privacy and operational risks.

This line will send a real WhatsApp message to what appears to be an actual phone number (16036627490) when the test runs. This raises concerns:

  1. PII in source code — The phone number should not be committed to the repository.
  2. Unintended messages — Running this test sends unsolicited messages to a real recipient.

Use an environment variable or a clearly documented test/mock number instead.

Suggested fix using environment variable
-  await client.sendText('16036627490@c.us', 'Hi there');
+  const testNumber = process.env.TEST_PHONE_NUMBER;
+  if (testNumber) {
+    await client.sendText(`${testNumber}@c.us`, 'Hi there');
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
await client.sendText('16036627490@c.us', 'Hi there');
const testNumber = process.env.TEST_PHONE_NUMBER;
if (testNumber) {
await client.sendText(`${testNumber}@c.us`, 'Hi there');
}
🤖 Prompt for AI Agents
In `@test/index.js` at line 48, Replace the hardcoded recipient in the test that
calls client.sendText(...) with a configurable value: stop committing PII by
reading the destination number from an environment variable (e.g.,
process.env.TEST_WHATSAPP_NUMBER) or a test-only constant/mock, and update the
test harness to validate the variable is set (or skip the integration send when
not present); locate the call to client.sendText in test/index.js and refactor
it to use the env variable or mock-number and document the required env var in
the test README.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
src/lib/wapi/functions/remove-participant.js (1)

8-13: Verify that findChat returns contact objects compatible with the filter and subsequent participant lookup.

The change from WAPI.sendExist to WAPI.findChat introduces a critical compatibility issue. The findChat function returns either:

  1. Error objects from WAPI.scope (with erro: true but no isUser property)
  2. Chat objects from Store.FindOrCreateChat.findOrCreateLatestChat (structure unclear)

However, line 10 filters on .filter((c) => !c.erro && c.isUser), which requires the isUser property on successfully returned objects. Error objects from WAPI.scope do not have this property.

More critically, line 11 assumes the filtered objects are contact/user references: .map((c) => chat.groupMetadata.participants.get(c.id)). This suggests the code expects contact objects with an id that corresponds to participant IDs, but findChat returns chat objects, creating a semantic mismatch.

Verify that:

  1. Chat objects returned by findChat have an isUser property or alternative way to identify users
  2. The id property on returned objects maps correctly to participant IDs in groupMetadata.participants
  3. This change was tested with actual participant operations (add, remove, promote, demote)

Note: This pattern is also used identically in promote-participant.js, demote-participant.js, and add-participant.js, so the fix must be consistent across all these files.

src/lib/wapi/functions/open-chat.js (1)

16-25: Guard against undefined chat before accessing chat.erro.

WAPI.findChat(chatId) can return undefined on failure. If the condition on line 17 is false and chat is undefined, accessing chat.erro on line 22 will throw a TypeError.

Also, the variable shadowing on line 18 (const chat = Store.Chat.get(chatId)) obscures the outer chat from findChat, which is confusing.

🛠️ Proposed fix
   const chat = await WAPI.findChat(chatId);
-  if (chat && chat.status != 404 && chat.id) {
-    const chat = Store.Chat.get(chatId);
-    const result = Store.Cmd.default.openChatBottom(chat);
+  if (chat && chat.status !== 404 && chat.id) {
+    const storeChat = Store.Chat.get(chatId);
+    const result = Store.Cmd.default.openChatBottom(storeChat);
     return WAPI.scope(undefined, false, result);
   }
-  if (!chat.erro) {
+  if (!chat || !chat.erro) {
     chat.erro = true;
   }
   return chat;
src/lib/wapi/functions/poll-creation.js (1)

37-50: Add null guard in the else block to prevent potential TypeError.

The refactor to WAPI.findChat is correct, and line 38 properly guards the success path. However, the else block at lines 45-49 accesses chat.error without checking if chat is truthy. If findChat returns null or undefined, accessing chat.error will throw a TypeError.

🐛 Proposed fix
   } else {
-    if (!chat.error) {
+    if (chat && !chat.error) {
       chat.error = true;
     }
     return chat;
   }
src/lib/wapi/functions/set-new-message.js (1)

1-1: Remove unused checkNumber parameter and update callers.

The checkNumber parameter is declared but never used in the function body. This requires updating the function signature and the two callers in send-file.js and send-ppt.js that pass this parameter.

♻️ Proposed changes

src/lib/wapi/functions/set-new-message.js:

-export async function setNewMessageId(info, checkNumber = true) {
+export async function setNewMessageId(info) {

src/lib/wapi/functions/send-file.js (line 92):

-      : await window.WAPI.setNewMessageId(passId, checkNumber);
+      : await window.WAPI.setNewMessageId(passId);

src/lib/wapi/functions/send-ppt.js (line 54):

-      : await window.WAPI.setNewMessageId(passId, checkNumber);
+      : await window.WAPI.setNewMessageId(passId);
🤖 Fix all issues with AI agents
In `@src/lib/wapi/functions/send-contact-vcard.js`:
- Around line 15-16: Replace the use of WAPI.findChat(contact) with
window.Store.Contact.get(contact) when retrieving the contact in
send-contact-vcard.js (currently using WAPI.findChat); ensure you pass the
actual contact model (with its __x_contact) into vcardFromContactModel, and add
a guard that validates the returned contact object has the __x_contact field
before dereferencing it (return or throw/log an error if missing) to mirror how
sendMessageOptions.js retrieves contacts.

In `@src/lib/wapi/functions/set-new-message.js`:
- Around line 9-11: The code calls WAPI.findChat(...) and directly checks
chat.id which can throw if chat is null/undefined; update the conditional in
set-new-message.js to guard the chat object (e.g., use if (chat && chat.id) or
if (chat?.id)) so you only access chat.id when chat is truthy; ensure you locate
the WAPI.findChat call and the subsequent if (chat.id) check and replace it with
the guarded form to match patterns used in poll-creation.js and
get-all-chats.js.
♻️ Duplicate comments (4)
src/lib/wapi/functions/mark-unseen-message.js (1)

7-8: Guard against falsy values returned by findChat.

WAPI.findChat(id) returns undefined on failure. Accessing chat.erro without a null check will throw a TypeError.

src/lib/wapi/functions/get-new-message-id.js (1)

1-13: Missing null guard and unused parameter still present.

The issues identified in the previous review remain unaddressed:

  1. Line 3 accesses chat.id without verifying chat exists—if findChat returns falsy, this throws a TypeError.
  2. The checkNumber parameter on line 1 is declared but never used after the refactor to always use findChat.
src/lib/wapi/functions/delete-messages.js (1)

10-79: Guard against falsy chat before dereferencing.
When findChat fails, the else branch can throw on chat.erro. Add a null/type guard and return a scoped error instead.

🛠️ Proposed fix
   } else {
-    if (!chat.erro) {
-      chat.erro = true;
-    }
-    return chat;
+    if (!chat || typeof chat !== 'object') {
+      return WAPI.scope(chatId, true, 404, 'Chat not found');
+    }
+    if (!chat.erro) {
+      chat.erro = true;
+    }
+    return chat;
   }
src/lib/wapi/functions/check-send-exist.js (1)

99-107: Await sendCheckType and createWid in findChat.
sendCheckType returns an async scope object and createWid is awaited in get-chat.js; without await, invalid IDs can bypass validation and findOrCreateLatestChat may receive a Promise.

🛠️ Proposed fix
 export async function findChat(chatId) {
-  const checkType = WAPI.sendCheckType(chatId);
+  const checkType = await WAPI.sendCheckType(chatId);
   if (checkType && checkType.status === 404) {
     return checkType;
   }

   try {
-    const wid = window.Store.WidFactory.createWid(chatId);
+    const wid = await window.Store.WidFactory.createWid(chatId);
     const { chat } = await window.Store.FindOrCreateChat.findOrCreateLatestChat(wid);
     if (chat) {
       return chat;
     }

Also applies to: 111-115

🧹 Nitpick comments (4)
test/index.js (2)

19-21: Unused variable f after commenting out the log.

The getHostDevice() result is assigned to f but now goes unused. Either remove the assignment entirely or keep the log for debugging purposes.

-  const f = await client.getHostDevice();
   console.log(await client.getWAVersion());
-  //console.log(f);
+  // const f = await client.getHostDevice();
+  // console.log(f);

2-2: Unused import and large commented code block.

With the FFmpeg pipeline commented out, the fluent-ffmpeg import at line 2 becomes dead code. Large commented blocks are generally discouraged—if this test path is deprecated in favor of the new Vitest unit tests, consider removing it entirely rather than leaving it commented.

If this code is intentionally preserved for future reference or occasional manual testing, consider:

  1. Moving it to a separate file (e.g., test/ffmpeg-manual-test.js)
  2. Adding a brief comment explaining why it's disabled
♻️ Suggested cleanup if FFmpeg test is no longer needed
 import venom from '../dist/index.mjs';
-import ffmpeg from 'fluent-ffmpeg';
 
 venom
   .create({

And remove lines 26-47 entirely.

Also applies to: 26-47

src/lib/wapi/functions/remove-participant.js (1)

28-29: Pre-existing: Callback receives false on success, inconsistent with return value.

This wasn't introduced by the current change, but the callback done(false) on line 28 contradicts the return true on line 29. Typically you'd expect done(true) for a successful operation to match the return value.

♻️ Optional fix for callback consistency
-  if (typeof done === 'function') done(false);
+  if (typeof done === 'function') done(true);
   return true;
src/lib/wapi/functions/send-seen.js (1)

3-14: Pre-existing issue: Return values from Promise handlers are discarded.

The .then() and .catch() handlers return WAPI.scope(...) values, but these are not captured. The function always returns true (line 11) regardless of whether markUnread succeeded or failed. Consider capturing and returning the result if the caller needs to distinguish success from failure.

This is a pre-existing issue, not introduced by this PR.

Suggested fix
 export async function sendSeen(id, done) {
   const chat = await WAPI.findChat(id);
   if (!chat.erro) {
-    await Store.ReadSeen.markUnread(chat, false)
+    return await Store.ReadSeen.markUnread(chat, false)
       .then(() => {
-        return WAPI.scope(undefined, false, 'OK', null);
+        return true;
       })
       .catch(() => {
-        return WAPI.scope(undefined, true, 'Error', null);
+        return false;
       });
-    return true;
   } else {
     return false;
   }
 }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c5ec758 and 01fe8ad.

⛔ Files ignored due to path filters (10)
  • dist/cjs/api/layers/group.layer.js is excluded by !**/dist/**
  • dist/cjs/api/layers/group.layer.js.map is excluded by !**/dist/**, !**/*.map
  • dist/cjs/api/layers/sender.layer.js is excluded by !**/dist/**
  • dist/cjs/api/layers/sender.layer.js.map is excluded by !**/dist/**, !**/*.map
  • dist/esm/api/layers/group.layer.js is excluded by !**/dist/**
  • dist/esm/api/layers/group.layer.js.map is excluded by !**/dist/**, !**/*.map
  • dist/esm/api/layers/sender.layer.js is excluded by !**/dist/**
  • dist/esm/api/layers/sender.layer.js.map is excluded by !**/dist/**, !**/*.map
  • dist/lib/wapi/wapi.js is excluded by !**/dist/**
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (58)
  • src/api/layers/group.layer.ts
  • src/api/layers/sender.layer.ts
  • src/lib/wapi/functions/add-participant.js
  • src/lib/wapi/functions/archive-chat.js
  • src/lib/wapi/functions/check-id-messagem.js
  • src/lib/wapi/functions/check-send-exist.js
  • src/lib/wapi/functions/create-group.js
  • src/lib/wapi/functions/delete-all-message.js
  • src/lib/wapi/functions/delete-messages.js
  • src/lib/wapi/functions/demote-participant.js
  • src/lib/wapi/functions/fix-chat.js
  • src/lib/wapi/functions/forward-messages.js
  • src/lib/wapi/functions/get-all-chats.js
  • src/lib/wapi/functions/get-all-messages-in-chat.js
  • src/lib/wapi/functions/get-data-messages.js
  • src/lib/wapi/functions/get-group-admins.js
  • src/lib/wapi/functions/get-host.js
  • src/lib/wapi/functions/get-new-message-id.js
  • src/lib/wapi/functions/get-number-profile.js
  • src/lib/wapi/functions/index.js
  • src/lib/wapi/functions/mark-markSeen-message.js
  • src/lib/wapi/functions/mark-unseen-message.js
  • src/lib/wapi/functions/only-send-admin.js
  • src/lib/wapi/functions/only-send-data-admin.js
  • src/lib/wapi/functions/open-chat.js
  • src/lib/wapi/functions/pin.chat.js
  • src/lib/wapi/functions/poll-creation.js
  • src/lib/wapi/functions/promote-participant.js
  • src/lib/wapi/functions/remove-participant.js
  • src/lib/wapi/functions/reply.js
  • src/lib/wapi/functions/send-buttons.js
  • src/lib/wapi/functions/send-contact-vcard-list.js
  • src/lib/wapi/functions/send-contact-vcard.js
  • src/lib/wapi/functions/send-file.js
  • src/lib/wapi/functions/send-link-preview.js
  • src/lib/wapi/functions/send-list-menu.js
  • src/lib/wapi/functions/send-location.js
  • src/lib/wapi/functions/send-message-scope.js
  • src/lib/wapi/functions/send-message.js
  • src/lib/wapi/functions/send-mute.js
  • src/lib/wapi/functions/send-ptt.js
  • src/lib/wapi/functions/send-seen.js
  • src/lib/wapi/functions/send-sticker.js
  • src/lib/wapi/functions/send-type-buttons.js
  • src/lib/wapi/functions/sendMessageOptions.js
  • src/lib/wapi/functions/set-group-description.js
  • src/lib/wapi/functions/set-group-image.js
  • src/lib/wapi/functions/set-group-settings.js
  • src/lib/wapi/functions/set-group-title.js
  • src/lib/wapi/functions/set-new-message.js
  • src/lib/wapi/functions/set-profile-pic.js
  • src/lib/wapi/functions/simulate-status-chat.js
  • src/lib/wapi/functions/test.js
  • src/lib/wapi/helper/filter-object.js
  • src/lib/wapi/helper/get-me-user.js
  • src/lib/wapi/helper/index.js
  • src/lib/wapi/wapi.js
  • test/index.js
🚧 Files skipped from review as they are similar to previous changes (34)
  • src/lib/wapi/functions/send-mute.js
  • src/api/layers/group.layer.ts
  • src/lib/wapi/functions/send-sticker.js
  • src/lib/wapi/functions/only-send-admin.js
  • src/lib/wapi/functions/set-profile-pic.js
  • src/lib/wapi/functions/forward-messages.js
  • src/lib/wapi/functions/delete-all-message.js
  • src/lib/wapi/functions/get-all-messages-in-chat.js
  • src/lib/wapi/functions/promote-participant.js
  • src/lib/wapi/functions/mark-markSeen-message.js
  • src/lib/wapi/functions/send-contact-vcard-list.js
  • src/lib/wapi/functions/reply.js
  • src/lib/wapi/functions/set-group-title.js
  • src/lib/wapi/helper/get-me-user.js
  • src/lib/wapi/functions/test.js
  • src/lib/wapi/functions/index.js
  • src/lib/wapi/functions/send-type-buttons.js
  • src/lib/wapi/functions/simulate-status-chat.js
  • src/lib/wapi/functions/create-group.js
  • src/api/layers/sender.layer.ts
  • src/lib/wapi/functions/fix-chat.js
  • src/lib/wapi/functions/only-send-data-admin.js
  • src/lib/wapi/helper/index.js
  • src/lib/wapi/functions/check-id-messagem.js
  • src/lib/wapi/functions/send-file.js
  • src/lib/wapi/functions/send-buttons.js
  • src/lib/wapi/functions/get-group-admins.js
  • src/lib/wapi/functions/add-participant.js
  • src/lib/wapi/functions/get-number-profile.js
  • src/lib/wapi/helper/filter-object.js
  • src/lib/wapi/functions/archive-chat.js
  • src/lib/wapi/functions/send-link-preview.js
  • src/lib/wapi/functions/pin.chat.js
  • src/lib/wapi/functions/demote-participant.js
🧰 Additional context used
📓 Path-based instructions (3)
src/lib/wapi/functions/**/*.js

📄 CodeRabbit inference engine (CLAUDE.md)

WAPI functions in src/lib/wapi/functions are JavaScript files injected into the browser; after changing them, run npm run build:wapi to rebuild

Files:

  • src/lib/wapi/functions/poll-creation.js
  • src/lib/wapi/functions/send-message.js
  • src/lib/wapi/functions/send-ptt.js
  • src/lib/wapi/functions/get-host.js
  • src/lib/wapi/functions/send-contact-vcard.js
  • src/lib/wapi/functions/remove-participant.js
  • src/lib/wapi/functions/send-location.js
  • src/lib/wapi/functions/send-message-scope.js
  • src/lib/wapi/functions/set-new-message.js
  • src/lib/wapi/functions/delete-messages.js
  • src/lib/wapi/functions/send-list-menu.js
  • src/lib/wapi/functions/get-data-messages.js
  • src/lib/wapi/functions/set-group-image.js
  • src/lib/wapi/functions/set-group-description.js
  • src/lib/wapi/functions/mark-unseen-message.js
  • src/lib/wapi/functions/check-send-exist.js
  • src/lib/wapi/functions/set-group-settings.js
  • src/lib/wapi/functions/get-new-message-id.js
  • src/lib/wapi/functions/get-all-chats.js
  • src/lib/wapi/functions/open-chat.js
  • src/lib/wapi/functions/sendMessageOptions.js
  • src/lib/wapi/functions/send-seen.js
src/lib/wapi/**/*.js

📄 CodeRabbit inference engine (CLAUDE.md)

WAPI layer code is built with webpack and injected into the Puppeteer browser context

Files:

  • src/lib/wapi/functions/poll-creation.js
  • src/lib/wapi/functions/send-message.js
  • src/lib/wapi/functions/send-ptt.js
  • src/lib/wapi/functions/get-host.js
  • src/lib/wapi/functions/send-contact-vcard.js
  • src/lib/wapi/functions/remove-participant.js
  • src/lib/wapi/functions/send-location.js
  • src/lib/wapi/functions/send-message-scope.js
  • src/lib/wapi/functions/set-new-message.js
  • src/lib/wapi/functions/delete-messages.js
  • src/lib/wapi/functions/send-list-menu.js
  • src/lib/wapi/functions/get-data-messages.js
  • src/lib/wapi/functions/set-group-image.js
  • src/lib/wapi/functions/set-group-description.js
  • src/lib/wapi/functions/mark-unseen-message.js
  • src/lib/wapi/functions/check-send-exist.js
  • src/lib/wapi/functions/set-group-settings.js
  • src/lib/wapi/functions/get-new-message-id.js
  • src/lib/wapi/functions/get-all-chats.js
  • src/lib/wapi/functions/open-chat.js
  • src/lib/wapi/wapi.js
  • src/lib/wapi/functions/sendMessageOptions.js
  • src/lib/wapi/functions/send-seen.js
test/index.js

📄 CodeRabbit inference engine (CLAUDE.md)

Use test/index.js as the main test script; tests are basic scripts without a formal framework

Files:

  • test/index.js
🧠 Learnings (1)
📚 Learning: 2025-09-08T17:49:03.345Z
Learnt from: CR
Repo: venomlib/venom PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T17:49:03.345Z
Learning: Applies to src/lib/wapi/functions/**/*.js : WAPI functions in src/lib/wapi/functions are JavaScript files injected into the browser; after changing them, run `npm run build:wapi` to rebuild

Applied to files:

  • src/lib/wapi/functions/delete-messages.js
  • src/lib/wapi/functions/send-list-menu.js
  • src/lib/wapi/functions/mark-unseen-message.js
  • src/lib/wapi/functions/set-group-settings.js
  • src/lib/wapi/wapi.js
🧬 Code graph analysis (19)
src/lib/wapi/functions/send-message.js (15)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/get-host.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/reply.js (1)
  • fromwWid (60-60)
src/lib/wapi/functions/send-buttons.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-contact-vcard-list.js (1)
  • fromwWid (52-52)
src/lib/wapi/functions/send-contact-vcard.js (1)
  • fromwWid (43-43)
src/lib/wapi/functions/send-link-preview.js (1)
  • fromwWid (31-31)
src/lib/wapi/functions/send-list-menu.js (1)
  • fromwWid (102-102)
src/lib/wapi/functions/send-location.js (1)
  • fromwWid (19-19)
src/lib/wapi/functions/send-message-scope.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-sticker.js (1)
  • fromwWid (6-6)
src/lib/wapi/functions/send-type-buttons.js (1)
  • fromwWid (122-122)
src/lib/wapi/functions/sendMessageOptions.js (1)
  • fromwWid (104-104)
src/lib/wapi/functions/test.js (1)
  • fromwWid (6-6)
src/api/whatsapp.ts (5)
  • WAPI (136-136)
  • WAPI (189-189)
  • messageId (223-223)
  • () => undefined (166-166)
  • getMessageById (221-226)
src/lib/wapi/functions/send-ptt.js (16)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/get-host.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/reply.js (1)
  • fromwWid (60-60)
src/lib/wapi/functions/send-buttons.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-contact-vcard-list.js (1)
  • fromwWid (52-52)
src/lib/wapi/functions/send-contact-vcard.js (1)
  • fromwWid (43-43)
src/lib/wapi/functions/send-link-preview.js (1)
  • fromwWid (31-31)
src/lib/wapi/functions/send-list-menu.js (1)
  • fromwWid (102-102)
src/lib/wapi/functions/send-location.js (1)
  • fromwWid (19-19)
src/lib/wapi/functions/send-message-scope.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-message.js (1)
  • fromwWid (46-46)
src/lib/wapi/functions/send-sticker.js (1)
  • fromwWid (6-6)
src/lib/wapi/functions/send-type-buttons.js (1)
  • fromwWid (122-122)
src/lib/wapi/functions/sendMessageOptions.js (1)
  • fromwWid (104-104)
src/lib/wapi/functions/test.js (1)
  • fromwWid (6-6)
src/api/model/message.ts (1)
  • Sender (83-101)
src/lib/wapi/functions/get-host.js (5)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/test.js (1)
  • fromwWid (6-6)
src/lib/wapi/functions/send-file.js (2)
  • wid (59-59)
  • chat (60-60)
src/lib/wapi/functions/send-ptt.js (2)
  • wid (20-20)
  • chat (21-21)
src/lib/wapi/functions/get-number-profile.js (1)
  • infoUser (7-7)
src/lib/wapi/functions/send-contact-vcard.js (8)
src/lib/wapi/functions/delete-messages.js (1)
  • chat (10-10)
src/lib/wapi/functions/send-contact-vcard-list.js (2)
  • chat (29-29)
  • fromwWid (52-52)
src/lib/wapi/functions/send-message.js (2)
  • chat (31-31)
  • fromwWid (46-46)
src/lib/wapi/wapi.js (3)
  • chat (443-443)
  • chat (502-502)
  • chat (511-511)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/get-host.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/send-link-preview.js (1)
  • fromwWid (31-31)
src/lib/wapi/functions/test.js (1)
  • fromwWid (6-6)
src/lib/wapi/functions/send-location.js (2)
src/lib/wapi/functions/get-new-message-id.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-chat.js (1)
  • getChat (1-49)
src/lib/wapi/functions/send-message-scope.js (3)
src/lib/wapi/functions/send-buttons.js (2)
  • chat (40-40)
  • fromwWid (44-44)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/get-host.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/set-new-message.js (5)
src/lib/wapi/functions/archive-chat.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-data-messages.js (1)
  • chat (42-42)
src/lib/wapi/functions/get-number-profile.js (1)
  • chat (5-5)
src/lib/wapi/wapi.js (3)
  • chat (443-443)
  • chat (502-502)
  • chat (511-511)
src/lib/wapi/functions/get-chat.js (1)
  • getChat (1-49)
src/lib/wapi/functions/delete-messages.js (10)
src/lib/wapi/functions/check-id-messagem.js (1)
  • chat (10-10)
src/lib/wapi/functions/get-number-profile.js (1)
  • chat (5-5)
src/lib/wapi/functions/reply.js (1)
  • chat (26-26)
src/lib/wapi/functions/send-buttons.js (1)
  • chat (40-40)
src/lib/wapi/functions/send-contact-vcard-list.js (1)
  • chat (29-29)
src/lib/wapi/functions/send-contact-vcard.js (1)
  • chat (15-15)
src/lib/wapi/functions/send-list-menu.js (1)
  • chat (98-98)
src/lib/wapi/functions/send-message-scope.js (1)
  • chat (39-39)
src/lib/wapi/functions/send-sticker.js (1)
  • chat (2-2)
src/lib/wapi/functions/send-type-buttons.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-data-messages.js (9)
src/lib/wapi/functions/archive-chat.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-all-messages-in-chat.js (1)
  • chat (7-7)
src/lib/wapi/functions/get-group-admins.js (1)
  • chat (5-5)
src/lib/wapi/functions/get-number-profile.js (1)
  • chat (5-5)
src/lib/wapi/functions/mark-markSeen-message.js (1)
  • chat (7-7)
src/lib/wapi/functions/mark-unseen-message.js (1)
  • chat (7-7)
src/lib/wapi/functions/send-message-scope.js (1)
  • chat (39-39)
src/lib/wapi/functions/set-group-description.js (1)
  • chat (15-15)
src/lib/wapi/functions/get-chat.js (1)
  • getChat (1-49)
src/lib/wapi/functions/set-group-image.js (13)
src/lib/wapi/functions/archive-chat.js (1)
  • chat (2-2)
src/lib/wapi/functions/check-id-messagem.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-all-message.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-messages.js (1)
  • chat (10-10)
src/lib/wapi/functions/get-data-messages.js (1)
  • chat (42-42)
src/lib/wapi/functions/get-group-admins.js (1)
  • chat (5-5)
src/lib/wapi/functions/get-new-message-id.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-number-profile.js (1)
  • chat (5-5)
src/lib/wapi/functions/mark-markSeen-message.js (1)
  • chat (7-7)
src/lib/wapi/functions/mark-unseen-message.js (1)
  • chat (7-7)
src/lib/wapi/functions/only-send-admin.js (1)
  • chat (9-9)
src/lib/wapi/functions/send-message-scope.js (1)
  • chat (39-39)
src/lib/wapi/functions/set-group-description.js (1)
  • chat (15-15)
src/lib/wapi/functions/set-group-description.js (4)
src/lib/wapi/functions/add-participant.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-data-messages.js (1)
  • chat (42-42)
src/lib/wapi/wapi.js (3)
  • chat (443-443)
  • chat (502-502)
  • chat (511-511)
src/lib/wapi/functions/get-chat.js (1)
  • getChat (1-49)
src/lib/wapi/functions/mark-unseen-message.js (13)
src/lib/wapi/functions/archive-chat.js (1)
  • chat (2-2)
src/lib/wapi/functions/check-id-messagem.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-all-message.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-messages.js (1)
  • chat (10-10)
src/lib/wapi/functions/get-all-messages-in-chat.js (1)
  • chat (7-7)
src/lib/wapi/functions/get-data-messages.js (1)
  • chat (42-42)
src/lib/wapi/functions/get-group-admins.js (1)
  • chat (5-5)
src/lib/wapi/functions/get-new-message-id.js (1)
  • chat (2-2)
src/lib/wapi/functions/get-number-profile.js (1)
  • chat (5-5)
src/lib/wapi/functions/mark-markSeen-message.js (1)
  • chat (7-7)
src/lib/wapi/functions/only-send-admin.js (1)
  • chat (9-9)
src/lib/wapi/functions/open-chat.js (2)
  • chat (7-7)
  • chat (16-16)
src/lib/wapi/functions/send-seen.js (1)
  • chat (2-2)
src/lib/wapi/functions/check-send-exist.js (2)
src/lib/wapi/functions/get-host.js (2)
  • wid (4-4)
  • window (6-6)
src/lib/wapi/functions/get-new-message-id.js (1)
  • chat (2-2)
src/lib/wapi/functions/set-group-settings.js (5)
src/lib/wapi/functions/get-group-admins.js (1)
  • chat (5-5)
src/lib/wapi/functions/send-buttons.js (1)
  • chat (40-40)
src/lib/wapi/functions/set-group-description.js (1)
  • chat (15-15)
src/lib/wapi/functions/set-group-title.js (1)
  • chat (15-15)
src/lib/wapi/wapi.js (3)
  • chat (443-443)
  • chat (502-502)
  • chat (511-511)
src/lib/wapi/functions/get-new-message-id.js (11)
src/lib/wapi/functions/archive-chat.js (1)
  • chat (2-2)
src/lib/wapi/functions/check-id-messagem.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-all-message.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-messages.js (1)
  • chat (10-10)
src/lib/wapi/functions/get-data-messages.js (1)
  • chat (42-42)
src/lib/wapi/functions/get-group-admins.js (1)
  • chat (5-5)
src/lib/wapi/functions/send-buttons.js (1)
  • chat (40-40)
src/lib/wapi/functions/send-contact-vcard-list.js (1)
  • chat (29-29)
src/lib/wapi/functions/send-contact-vcard.js (1)
  • chat (15-15)
src/lib/wapi/functions/send-list-menu.js (1)
  • chat (98-98)
src/lib/wapi/functions/send-location.js (1)
  • chat (7-7)
src/lib/wapi/functions/get-all-chats.js (14)
src/lib/wapi/functions/get-host.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/reply.js (1)
  • fromwWid (60-60)
src/lib/wapi/functions/send-buttons.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-contact-vcard-list.js (1)
  • fromwWid (52-52)
src/lib/wapi/functions/send-contact-vcard.js (1)
  • fromwWid (43-43)
src/lib/wapi/functions/send-link-preview.js (1)
  • fromwWid (31-31)
src/lib/wapi/functions/send-list-menu.js (1)
  • fromwWid (102-102)
src/lib/wapi/functions/send-location.js (1)
  • fromwWid (19-19)
src/lib/wapi/functions/send-message-scope.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-message.js (1)
  • fromwWid (46-46)
src/lib/wapi/functions/send-sticker.js (1)
  • fromwWid (6-6)
src/lib/wapi/functions/send-type-buttons.js (1)
  • fromwWid (122-122)
src/lib/wapi/functions/sendMessageOptions.js (1)
  • fromwWid (104-104)
src/lib/wapi/functions/test.js (1)
  • fromwWid (6-6)
src/lib/wapi/functions/open-chat.js (10)
src/lib/wapi/functions/archive-chat.js (1)
  • chat (2-2)
src/lib/wapi/functions/check-id-messagem.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-all-message.js (1)
  • chat (10-10)
src/lib/wapi/functions/delete-messages.js (1)
  • chat (10-10)
src/lib/wapi/functions/get-number-profile.js (1)
  • chat (5-5)
src/lib/wapi/functions/reply.js (1)
  • chat (26-26)
src/lib/wapi/functions/send-contact-vcard-list.js (1)
  • chat (29-29)
src/lib/wapi/functions/send-contact-vcard.js (1)
  • chat (15-15)
src/lib/wapi/functions/send-location.js (1)
  • chat (7-7)
src/lib/wapi/functions/send-sticker.js (1)
  • chat (2-2)
src/lib/wapi/wapi.js (3)
src/lib/wapi/functions/check-send-exist.js (2)
  • window (107-107)
  • findChat (99-116)
src/lib/wapi/functions/get-host.js (1)
  • window (6-6)
src/lib/wapi/helper/get-me-user.js (1)
  • getMeUser (5-11)
src/lib/wapi/functions/sendMessageOptions.js (14)
src/lib/wapi/functions/get-all-chats.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/get-host.js (1)
  • fromwWid (2-2)
src/lib/wapi/functions/reply.js (1)
  • fromwWid (60-60)
src/lib/wapi/functions/send-buttons.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-contact-vcard-list.js (1)
  • fromwWid (52-52)
src/lib/wapi/functions/send-contact-vcard.js (1)
  • fromwWid (43-43)
src/lib/wapi/functions/send-link-preview.js (1)
  • fromwWid (31-31)
src/lib/wapi/functions/send-list-menu.js (1)
  • fromwWid (102-102)
src/lib/wapi/functions/send-location.js (1)
  • fromwWid (19-19)
src/lib/wapi/functions/send-message-scope.js (1)
  • fromwWid (44-44)
src/lib/wapi/functions/send-message.js (1)
  • fromwWid (46-46)
src/lib/wapi/functions/send-sticker.js (1)
  • fromwWid (6-6)
src/lib/wapi/functions/send-type-buttons.js (1)
  • fromwWid (122-122)
src/lib/wapi/functions/test.js (1)
  • fromwWid (6-6)
🔇 Additional comments (19)
src/lib/wapi/functions/send-location.js (2)

7-7: LGTM on chat lookup migration.

The replacement of WAPI.sendExist(chatId) with WAPI.findChat(chatId) aligns with the PR-wide refactor. The subsequent check on chat.erro (line 16) is consistent with the expected return structure.


19-19: LGTM on user retrieval migration.

The migration from Store.MaybeMeUser.getMaybeMePnUser() to WAPI.getMeUser() is consistent with the standardized approach used across other functions in this PR (e.g., send-message.js, send-buttons.js, reply.js).

src/lib/wapi/functions/send-ptt.js (1)

86-86: LGTM on user retrieval migration.

The change from Store.MaybeMeUser.getMaybeMePnUser() to WAPI.getMeUser() is consistent with the standardized approach across the codebase.

src/lib/wapi/functions/send-seen.js (1)

2-2: LGTM on chat lookup migration.

The replacement of WAPI.sendExist(id) with WAPI.findChat(id) is consistent with the PR-wide refactor.

src/lib/wapi/functions/send-message-scope.js (2)

39-39: LGTM on chat lookup migration.

The replacement of WAPI.sendExist(to) with WAPI.findChat(to) aligns with the PR-wide refactor. The subsequent validation logic on chat.status and chat.id remains appropriate.


44-44: LGTM on user retrieval migration.

The migration to WAPI.getMeUser() is consistent with the standardized approach used across other functions in this PR.

src/lib/wapi/functions/get-host.js (1)

1-18: LGTM on the refactored implementation.

The changes appropriately:

  1. Use the standardized WAPI.getMeUser() for user retrieval
  2. Follow the same WidFactory.createWid + FindOrCreateChat.findOrCreateLatestChat pattern seen in other files (e.g., check-number-status.js)
  3. Add proper try-catch error handling with logging

The implicit undefined returns when conditions fail are acceptable for a getter function where callers can handle missing host info.

src/lib/wapi/wapi.js (2)

91-91: LGTM!

The import changes correctly add findChat from functions and getMeUser from helpers, aligning with the refactor to consolidate chat lookup and user retrieval APIs.

Also applies to: 130-131


270-270: LGTM!

Exposing getMeUser and findChat on the window.WAPI surface is consistent with the new helper-based approach and replaces the previous sendExist/returnChat mappings.

Also applies to: 280-280

src/lib/wapi/functions/send-message.js (1)

46-46: LGTM!

The switch to WAPI.getMeUser() aligns with the centralized helper approach used across other send functions in this PR.

src/lib/wapi/functions/sendMessageOptions.js (1)

104-104: LGTM!

The switch to WAPI.getMeUser() is consistent with the helper-based approach applied across all send functions in this PR.

src/lib/wapi/functions/get-data-messages.js (1)

42-43: LGTM!

The refactor from WAPI.sendExist to WAPI.findChat is consistent with the broader PR changes, and the null guard on line 43 (chat && chat.status != 404) properly handles cases where findChat may return a falsy value.

src/lib/wapi/functions/get-all-chats.js (1)

2-5: LGTM!

The refactor correctly replaces Store.MaybeMeUser.getMaybeMePnUser() with WAPI.getMeUser() and WAPI.sendExist with WAPI.findChat, consistent with the broader PR changes. Null guards are properly in place at lines 3 and 5.

src/lib/wapi/functions/set-group-description.js (1)

15-16: LGTM: findChat swap is consistent with existing guard.
Line 15 integrates cleanly with the existing chat && chat.status != 404 check.

src/lib/wapi/functions/set-group-image.js (1)

13-14: LGTM: findChat fits the existing existence check.
Line 13 keeps the same gating logic and error flow.

src/lib/wapi/functions/set-group-settings.js (1)

16-17: LGTM: findChat integration is straightforward.
Line 16 preserves the same error gating and downstream logic.

src/lib/wapi/functions/check-send-exist.js (1)

43-55: LGTM: allow @lid suffix in ID validation.
This aligns with the expanded identifier support.

src/lib/wapi/functions/send-contact-vcard.js (1)

43-43: The return type of WAPI.getMeUser() is correct for message.from. The function returns a WID object (or undefined), which matches the expected shape used consistently across all message-sending functions in the codebase. No type incompatibility exists.

Likely an incorrect or invalid review comment.

src/lib/wapi/functions/send-list-menu.js (1)

98-102: Confirm rebuild after WAPI bundle changes.

The changes maintain type compatibility: findChat() returns a chat object with id (Wid), and getMeUser() returns the expected Wid for the from field. The code properly guards against null values at line 100. Since this file matches src/lib/wapi/**/*.js, run npm run build:wapi to rebuild the webpack bundle after these changes.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +15 to +16
const chat = await WAPI.findChat(chatId);
const cont = await WAPI.findChat(contact);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, get the full context of send-contact-vcard.js to understand the code structure
cat -n src/lib/wapi/functions/send-contact-vcard.js

Repository: venomlib/venom

Length of output: 2728


🏁 Script executed:

# Search for findChat implementation
rg -n "^\s*findChat\s*[:=]|function\s+findChat|\.findChat\s*=" src/lib/wapi -g "*.js" -A 5

Repository: venomlib/venom

Length of output: 821


🏁 Script executed:

# Search for vcardFromContactModel implementation
rg -n "vcardFromContactModel" src/lib/wapi -g "*.js" -B 2 -A 10

Repository: venomlib/venom

Length of output: 4808


🏁 Script executed:

# Search for __x_contact usage to understand expectations
rg -n "__x_contact" src/lib/wapi -g "*.js" -B 2 -A 2

Repository: venomlib/venom

Length of output: 827


🏁 Script executed:

# Get the full findChat implementation
cat -n src/lib/wapi/functions/check-send-exist.js | head -150

Repository: venomlib/venom

Length of output: 4141


🏁 Script executed:

# Check for Store.Contact usage and patterns to understand the difference between findChat and Contact.get
rg -n "Store\.Contact\.get|findChat" src/lib/wapi/functions -g "*.js" -B 2 -A 8 | head -100

Repository: venomlib/venom

Length of output: 7420


Use Store.Contact.get(contact) instead of findChat(contact) to fetch the contact object.

findChat is designed to return chat objects via the FindOrCreateChat API, which may not have the __x_contact field required by vcardFromContactModel. Line 16 should use window.Store.Contact.get(contact) to fetch the contact object directly, consistent with how sendMessageOptions.js retrieves contacts before calling vcardFromContactModel. Additionally, validate that the returned contact object has the required __x_contact field before dereferencing it at line 45.

🤖 Prompt for AI Agents
In `@src/lib/wapi/functions/send-contact-vcard.js` around lines 15 - 16, Replace
the use of WAPI.findChat(contact) with window.Store.Contact.get(contact) when
retrieving the contact in send-contact-vcard.js (currently using WAPI.findChat);
ensure you pass the actual contact model (with its __x_contact) into
vcardFromContactModel, and add a guard that validates the returned contact
object has the __x_contact field before dereferencing it (return or throw/log an
error if missing) to mirror how sendMessageOptions.js retrieves contacts.

Comment on lines +9 to 11
const chat = await WAPI.findChat(info.number);
delete info.number;
if (chat.id) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add null guard to prevent potential TypeError.

Line 11 accesses chat.id without verifying that chat is truthy. If WAPI.findChat returns null or undefined, this will throw a TypeError. Other files in this PR (e.g., poll-creation.js line 38, get-all-chats.js line 5) correctly use chat && guards.

🐛 Proposed fix
     const chat = await WAPI.findChat(info.number);
     delete info.number;
-    if (chat.id) {
+    if (chat && chat.id) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const chat = await WAPI.findChat(info.number);
delete info.number;
if (chat.id) {
const chat = await WAPI.findChat(info.number);
delete info.number;
if (chat && chat.id) {
🤖 Prompt for AI Agents
In `@src/lib/wapi/functions/set-new-message.js` around lines 9 - 11, The code
calls WAPI.findChat(...) and directly checks chat.id which can throw if chat is
null/undefined; update the conditional in set-new-message.js to guard the chat
object (e.g., use if (chat && chat.id) or if (chat?.id)) so you only access
chat.id when chat is truthy; ensure you locate the WAPI.findChat call and the
subsequent if (chat.id) check and replace it with the guarded form to match
patterns used in poll-creation.js and get-all-chats.js.

@9cb14c1ec0 9cb14c1ec0 merged commit 125f1ad into master Jan 16, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant