@oxidezap/baileyrs 0.2.12 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,16 +16,16 @@ const rejectUnsupportedFields = (where, value, fields) => {
16
16
  export const makeChatActionMethods = (ctx) => {
17
17
  const methods = {
18
18
  pinChat: async (jid, pin) => {
19
- await (await ctx.getClient()).pinChat(jid, pin);
19
+ await ctx.withClient(client => client.pinChat(jid, pin));
20
20
  },
21
21
  muteChat: async (jid, muteUntil) => {
22
- await (await ctx.getClient()).muteChat(jid, muteUntil);
22
+ await ctx.withClient(client => client.muteChat(jid, muteUntil));
23
23
  },
24
24
  archiveChat: async (jid, archive) => {
25
- await (await ctx.getClient()).archiveChat(jid, archive);
25
+ await ctx.withClient(client => client.archiveChat(jid, archive));
26
26
  },
27
27
  starMessage: async (jid, messageId, star) => {
28
- await (await ctx.getClient()).starMessage(jid, messageId, star);
28
+ await ctx.withClient(client => client.starMessage(jid, messageId, star));
29
29
  },
30
30
  /**
31
31
  * Compatibility wrapper for original Baileys chatModify API.
@@ -36,106 +36,110 @@ export const makeChatActionMethods = (ctx) => {
36
36
  * synced, and no signature or type catches that.
37
37
  */
38
38
  chatModify: async (mod, jid) => {
39
- const client = await ctx.getClient();
40
- if ('archive' in mod) {
41
- await client.archiveChat(jid, mod.archive);
42
- }
43
- else if ('pin' in mod) {
44
- await client.pinChat(jid, mod.pin);
45
- }
46
- else if ('mute' in mod) {
47
- await client.muteChat(jid, mod.mute);
48
- }
49
- else if ('star' in mod) {
50
- for (const msg of mod.star.messages) {
51
- await client.starMessage(jid, msg.id, mod.star.star);
52
- }
53
- }
54
- else if ('markRead' in mod) {
55
- await client.markChatAsRead(jid, mod.markRead);
56
- }
57
- else if ('delete' in mod) {
58
- await client.deleteChat(jid);
59
- }
60
- else if ('deleteForMe' in mod) {
61
- await client.deleteMessageForMe(jid, mod.deleteForMe.key.id, !!mod.deleteForMe.key.fromMe);
62
- }
63
- else if ('pushNameSetting' in mod) {
64
- await client.setPushName(mod.pushNameSetting);
65
- }
66
- else if ('contact' in mod) {
67
- // Save/rename a contact (syncs the name to linked devices). `jid` is the
68
- // contact's bare PN jid.
69
- if (mod.contact) {
70
- rejectUnsupportedFields('chatModify contact', mod.contact, ['lidJid', 'pnJid', 'username']);
71
- await client.saveContact(jid, mod.contact.fullName ?? undefined, mod.contact.firstName ?? undefined, mod.contact.saveOnPrimaryAddressbook ?? true);
39
+ return ctx.withClient(async (client) => {
40
+ if ('archive' in mod) {
41
+ await client.archiveChat(jid, mod.archive);
72
42
  }
73
- else {
74
- // Its own method, not `saveContact` with empty fields: removal is
75
- // the one contact mutation the wire models as a `Remove`, and a
76
- // `Set` carrying empty values renames the contact to "".
77
- await client.removeContact(jid);
78
- }
79
- }
80
- else if ('clear' in mod) {
81
- // Clear a chat's messages while keeping the chat. `lastMessages` (the
82
- // message range) is ignored, same as the `delete` branch — the bridge
83
- // clears the whole chat. deleteStarred/deleteMedia aren't part of the
84
- // Baileys `clear` shape, so default both to false (keep starred + media).
85
- if (mod.clear) {
86
- await client.clearChat(jid, false, false);
87
- }
88
- }
89
- else if ('disableLinkPreviews' in mod) {
90
- await client.setLinkPreviewsDisabled(mod.disableLinkPreviews.isPreviewsDisabled ?? false);
91
- }
92
- else if ('addLabel' in mod) {
93
- // One upstream variant, two wire actions: an edit carrying
94
- // `deleted` is the delete, not a separate modification.
95
- if (mod.addLabel.deleted) {
96
- await client.deleteLabel(mod.addLabel.id);
43
+ else if ('pin' in mod) {
44
+ await client.pinChat(jid, mod.pin);
97
45
  }
98
- else {
99
- rejectUnsupportedFields('chatModify addLabel', mod.addLabel, ['predefinedId']);
100
- // The mutation replaces the whole label, so a missing field is
101
- // not "leave it alone", it is "set it to nothing". Upstream can
102
- // omit one because it builds the proto directly; this call
103
- // cannot, so both are required rather than defaulted.
104
- if (mod.addLabel.name === undefined || mod.addLabel.color === undefined) {
105
- throw new Boom('chatModify addLabel: name and color are both required, because the label mutation is a full replace and an omitted field would reset it', { statusCode: 400 });
46
+ else if ('mute' in mod) {
47
+ await client.muteChat(jid, mod.mute);
48
+ }
49
+ else if ('star' in mod) {
50
+ for (const msg of mod.star.messages) {
51
+ await client.starMessage(jid, msg.id, mod.star.star);
52
+ }
53
+ }
54
+ else if ('markRead' in mod) {
55
+ await client.markChatAsRead(jid, mod.markRead);
56
+ }
57
+ else if ('delete' in mod) {
58
+ await client.deleteChat(jid);
59
+ }
60
+ else if ('deleteForMe' in mod) {
61
+ await client.deleteMessageForMe(jid, mod.deleteForMe.key.id, !!mod.deleteForMe.key.fromMe);
62
+ }
63
+ else if ('pushNameSetting' in mod) {
64
+ await client.setPushName(mod.pushNameSetting);
65
+ }
66
+ else if ('contact' in mod) {
67
+ // Save/rename a contact (syncs the name to linked devices). `jid` is the
68
+ // contact's bare PN jid.
69
+ if (mod.contact) {
70
+ rejectUnsupportedFields('chatModify contact', mod.contact, ['lidJid', 'pnJid', 'username']);
71
+ await client.saveContact(jid, mod.contact.fullName ?? undefined, mod.contact.firstName ?? undefined, mod.contact.saveOnPrimaryAddressbook ?? true);
72
+ }
73
+ else {
74
+ // Its own method, not `saveContact` with empty fields: removal is
75
+ // the one contact mutation the wire models as a `Remove`, and a
76
+ // `Set` carrying empty values renames the contact to "".
77
+ await client.removeContact(jid);
78
+ }
79
+ }
80
+ else if ('clear' in mod) {
81
+ // Clear a chat's messages while keeping the chat. `lastMessages` (the
82
+ // message range) is ignored, same as the `delete` branch — the bridge
83
+ // clears the whole chat. deleteStarred/deleteMedia aren't part of the
84
+ // Baileys `clear` shape, so default both to false (keep starred + media).
85
+ if (mod.clear) {
86
+ await client.clearChat(jid, false, false);
87
+ }
88
+ }
89
+ else if ('disableLinkPreviews' in mod) {
90
+ await client.setLinkPreviewsDisabled(mod.disableLinkPreviews.isPreviewsDisabled ?? false);
91
+ }
92
+ else if ('addLabel' in mod) {
93
+ // One upstream variant, two wire actions: an edit carrying
94
+ // `deleted` is the delete, not a separate modification.
95
+ if (mod.addLabel.deleted) {
96
+ await client.deleteLabel(mod.addLabel.id);
97
+ }
98
+ else {
99
+ rejectUnsupportedFields('chatModify addLabel', mod.addLabel, ['predefinedId']);
100
+ // The mutation replaces the whole label, so a missing field is
101
+ // not "leave it alone", it is "set it to nothing". Upstream can
102
+ // omit one because it builds the proto directly; this call
103
+ // cannot, so both are required rather than defaulted.
104
+ if (mod.addLabel.name === undefined || mod.addLabel.color === undefined) {
105
+ throw new Boom('chatModify addLabel: name and color are both required, because the label mutation is a full replace and an omitted field would reset it', { statusCode: 400 });
106
+ }
107
+ await client.createLabel(mod.addLabel.id, mod.addLabel.name, mod.addLabel.color);
108
+ }
109
+ }
110
+ else if ('addChatLabel' in mod) {
111
+ await client.addChatLabel(mod.addChatLabel.labelId, jid);
112
+ }
113
+ else if ('removeChatLabel' in mod) {
114
+ await client.removeChatLabel(mod.removeChatLabel.labelId, jid);
115
+ }
116
+ else if ('addMessageLabel' in mod) {
117
+ await client.addMessageLabel(mod.addMessageLabel.labelId, jid, mod.addMessageLabel.messageId);
118
+ }
119
+ else if ('removeMessageLabel' in mod) {
120
+ await client.removeMessageLabel(mod.removeMessageLabel.labelId, jid, mod.removeMessageLabel.messageId);
121
+ }
122
+ else if ('quickReply' in mod) {
123
+ // Upstream's `timestamp` is the app-state index key, the same slot
124
+ // the core calls `id`. Deleting is the same upsert with `deleted`.
125
+ // `||`, not `??`: upstream treats an empty timestamp as absent and
126
+ // mints a key, and the core rejects an empty index outright.
127
+ const id = mod.quickReply.timestamp || String(Math.floor(Date.now() / 1000));
128
+ if (mod.quickReply.deleted) {
129
+ await client.deleteQuickReply(id);
130
+ }
131
+ else {
132
+ await client.setQuickReply(id, mod.quickReply.shortcut ?? '', mod.quickReply.message ?? '', mod.quickReply.keywords ?? [], mod.quickReply.count ?? 0);
106
133
  }
107
- await client.createLabel(mod.addLabel.id, mod.addLabel.name, mod.addLabel.color);
108
- }
109
- }
110
- else if ('addChatLabel' in mod) {
111
- await client.addChatLabel(mod.addChatLabel.labelId, jid);
112
- }
113
- else if ('removeChatLabel' in mod) {
114
- await client.removeChatLabel(mod.removeChatLabel.labelId, jid);
115
- }
116
- else if ('addMessageLabel' in mod) {
117
- await client.addMessageLabel(mod.addMessageLabel.labelId, jid, mod.addMessageLabel.messageId);
118
- }
119
- else if ('removeMessageLabel' in mod) {
120
- await client.removeMessageLabel(mod.removeMessageLabel.labelId, jid, mod.removeMessageLabel.messageId);
121
- }
122
- else if ('quickReply' in mod) {
123
- // Upstream's `timestamp` is the app-state index key, the same slot
124
- // the core calls `id`. Deleting is the same upsert with `deleted`.
125
- // `||`, not `??`: upstream treats an empty timestamp as absent and
126
- // mints a key, and the core rejects an empty index outright.
127
- const id = mod.quickReply.timestamp || String(Math.floor(Date.now() / 1000));
128
- if (mod.quickReply.deleted) {
129
- await client.deleteQuickReply(id);
130
134
  }
131
135
  else {
132
- await client.setQuickReply(id, mod.quickReply.shortcut ?? '', mod.quickReply.message ?? '', mod.quickReply.keywords ?? [], mod.quickReply.count ?? 0);
136
+ const variant = Object.keys(mod)[0] ?? '(empty)';
137
+ throw new Boom(`chatModify: unsupported modification '${variant}'`, {
138
+ statusCode: 400,
139
+ data: { variant, jid }
140
+ });
133
141
  }
134
- }
135
- else {
136
- const variant = Object.keys(mod)[0] ?? '(empty)';
137
- throw new Boom(`chatModify: unsupported modification '${variant}'`, { statusCode: 400, data: { variant, jid } });
138
- }
142
+ });
139
143
  },
140
144
  // Upstream models all of these as sugar over `chatModify`, and so do we:
141
145
  // one place decides which bridge call a modification becomes, so the
@@ -0,0 +1,6 @@
1
+ import type { WasmWhatsAppClient } from '@oxidezap/whatsapp-rust-bridge';
2
+ export interface ClientOperations<Client = WasmWhatsAppClient> {
3
+ withClient<T>(operation: (client: Client) => T | Promise<T>): Promise<T>;
4
+ }
5
+ export declare const makeWithClient: <Client>(getClient: () => Promise<Client>) => ClientOperations<Client>['withClient'];
6
+ //# sourceMappingURL=client-operations.d.ts.map
@@ -0,0 +1,2 @@
1
+ export const makeWithClient = (getClient) => async (operation) => operation(await getClient());
2
+ //# sourceMappingURL=client-operations.js.map
@@ -6,7 +6,7 @@ import { GROUP_REQUEST_ACTIONS, GROUP_SETTINGS, JOIN_APPROVAL_MODES, makeGroupMe
6
6
  export const makeCommunityMethods = (ctx, groups = makeGroupMethods(ctx)) => {
7
7
  const communityMetadata = async (jid) => groups.groupMetadata(jid);
8
8
  const communityFetchAllParticipating = async () => {
9
- const bridgeCommunities = await (await ctx.getClient()).communityFetchAllParticipating();
9
+ const bridgeCommunities = await ctx.withClient(client => client.communityFetchAllParticipating());
10
10
  const result = {};
11
11
  for (const [communityJid, metadata] of Object.entries(bridgeCommunities)) {
12
12
  result[communityJid] = bridgeGroupMetadataToBaileys(metadata);
@@ -17,30 +17,30 @@ export const makeCommunityMethods = (ctx, groups = makeGroupMethods(ctx)) => {
17
17
  return {
18
18
  communityMetadata,
19
19
  communityCreate: async (subject, body) => {
20
- const metadata = await (await ctx.getClient()).createCommunity(subject, body || undefined, true, true, true);
20
+ const metadata = await ctx.withClient(client => client.createCommunity(subject, body || undefined, true, true, true));
21
21
  return bridgeGroupMetadataToBaileys(metadata);
22
22
  },
23
23
  communityCreateGroup: async (subject, participants, parentCommunityJid) => {
24
- const metadata = await (await ctx.getClient()).createCommunitySubgroup(subject, participants, parentCommunityJid);
24
+ const metadata = await ctx.withClient(client => client.createCommunitySubgroup(subject, participants, parentCommunityJid));
25
25
  return bridgeGroupMetadataToBaileys(metadata);
26
26
  },
27
27
  communityLeave: async (id) => {
28
- await (await ctx.getClient()).deactivateCommunity(id);
28
+ await ctx.withClient(client => client.deactivateCommunity(id));
29
29
  },
30
30
  communityUpdateSubject: async (jid, subject) => {
31
31
  await groups.groupUpdateSubject(jid, subject);
32
32
  },
33
33
  communityLinkGroup: async (groupJid, parentCommunityJid) => {
34
- await (await ctx.getClient()).linkCommunitySubgroups(parentCommunityJid, [groupJid]);
34
+ await ctx.withClient(client => client.linkCommunitySubgroups(parentCommunityJid, [groupJid]));
35
35
  },
36
36
  communityUnlinkGroup: async (groupJid, parentCommunityJid) => {
37
- await (await ctx.getClient()).unlinkCommunitySubgroups(parentCommunityJid, [groupJid], false);
37
+ await ctx.withClient(client => client.unlinkCommunitySubgroups(parentCommunityJid, [groupJid], false));
38
38
  },
39
39
  communityFetchLinkedGroups: async (jid) => {
40
40
  const metadata = await groups.groupMetadata(jid);
41
41
  const communityJid = metadata.linkedParent || jid;
42
42
  const isCommunity = !metadata.linkedParent;
43
- const subgroups = await (await ctx.getClient()).getCommunitySubgroups(communityJid);
43
+ const subgroups = await ctx.withClient(client => client.getCommunitySubgroups(communityJid));
44
44
  const linkedGroups = subgroups.map(group => ({
45
45
  id: group.id,
46
46
  subject: group.subject,
@@ -61,7 +61,7 @@ export const makeCommunityMethods = (ctx, groups = makeGroupMethods(ctx)) => {
61
61
  },
62
62
  communityParticipantsUpdate: async (jid, participants, action) => {
63
63
  assertArgumentDomain('communityParticipantsUpdate', 'action', action, PARTICIPANT_ACTIONS);
64
- return bridgeParticipantChangesToBaileys(await (await ctx.getClient()).communityParticipantsUpdate(jid, participants, action));
64
+ return bridgeParticipantChangesToBaileys(await ctx.withClient(client => client.communityParticipantsUpdate(jid, participants, action)));
65
65
  },
66
66
  communityUpdateDescription: groups.groupUpdateDescription,
67
67
  communityInviteCode: groups.groupInviteCode,
@@ -1,29 +1,32 @@
1
1
  import { assertArgumentDomain } from '../Utils/argument-domain.js';
2
2
  export const PROFILE_PICTURE_TYPES = ['preview', 'image'];
3
- export const makeContactMethods = (ctx) => ({
4
- onWhatsApp: async (...phoneNumber) => {
5
- const client = await ctx.getClient();
6
- // Single batched usync — the bridge splits PN/LID inputs internally and
7
- // returns lid/pnJid/isBusiness in the same payload, so no secondary IQ.
8
- const results = await client.isOnWhatsApp(phoneNumber);
9
- return results.map(r => {
10
- const out = { exists: r.isRegistered, jid: r.jid, isBusiness: r.isBusiness };
11
- if (r.lid)
12
- out.lid = r.lid;
13
- if (r.pnJid)
14
- out.pnJid = r.pnJid;
15
- if (r.verifiedName)
16
- out.verifiedName = r.verifiedName;
17
- return out;
18
- });
19
- },
20
- profilePictureUrl: async (jid, type = 'preview', timeoutMs) => {
21
- assertArgumentDomain('profilePictureUrl', 'type', type, PROFILE_PICTURE_TYPES);
22
- const result = await (await ctx.getClient()).profilePictureUrl(jid, type, timeoutMs);
23
- return result?.url;
24
- },
25
- fetchUserInfo: async (...jids) => {
26
- return await (await ctx.getClient()).fetchUserInfo(jids);
27
- }
28
- });
3
+ export const makeContactMethods = (ctx) => {
4
+ return {
5
+ onWhatsApp: async (...phoneNumber) => {
6
+ return ctx.withClient(async (client) => {
7
+ // Single batched usync the bridge splits PN/LID inputs internally and
8
+ // returns lid/pnJid/isBusiness in the same payload, so no secondary IQ.
9
+ const results = await client.isOnWhatsApp(phoneNumber);
10
+ return results.map(r => {
11
+ const out = { exists: r.isRegistered, jid: r.jid, isBusiness: r.isBusiness };
12
+ if (r.lid)
13
+ out.lid = r.lid;
14
+ if (r.pnJid)
15
+ out.pnJid = r.pnJid;
16
+ if (r.verifiedName)
17
+ out.verifiedName = r.verifiedName;
18
+ return out;
19
+ });
20
+ });
21
+ },
22
+ profilePictureUrl: async (jid, type = 'preview', timeoutMs) => {
23
+ assertArgumentDomain('profilePictureUrl', 'type', type, PROFILE_PICTURE_TYPES);
24
+ const result = await ctx.withClient(client => client.profilePictureUrl(jid, type, timeoutMs));
25
+ return result?.url;
26
+ },
27
+ fetchUserInfo: async (...jids) => {
28
+ return await ctx.withClient(client => client.fetchUserInfo(jids));
29
+ }
30
+ };
31
+ };
29
32
  //# sourceMappingURL=contacts.js.map
@@ -22,7 +22,7 @@ import { buildGroupCreateStubMessage, buildGroupJoinRequestEvents, buildGroupNot
22
22
  import { emitMessageUpsert } from '../Compatibility/message-upsert.js';
23
23
  import { extractMessageCappingPayload } from './message-capping.js';
24
24
  import { mapReachoutTimelock } from './reachout.js';
25
- import { isReconnectableConnectFailure } from './terminal-close.js';
25
+ import { isReconnectableConnectFailure, mapConnectFailureToDisconnect } from './terminal-close.js';
26
26
  const CANONICAL_MESSAGE_EVENT = 'message';
27
27
  const MESSAGE_UPSERT_APPEND = 'append';
28
28
  const MESSAGE_UPSERT_NOTIFY = 'notify';
@@ -191,41 +191,6 @@ const emitRetrying = (ctx) => ctx.ev.emit('connection.update', {
191
191
  * dispatcher for why `badSession` was the wrong home.
192
192
  */
193
193
  const CLIENT_OUTDATED_STATUS = 405;
194
- /**
195
- * Map bridge `ConnectFailureReason` wire codes (per the bridge's
196
- * `.d.ts` annotation) onto upstream Baileys' `DisconnectReason`.
197
- * Unknown codes fall through to `connectionClosed` so existing
198
- * reconnect heuristics keep working.
199
- *
200
- * Several cases here are belt-and-braces: the engine dispatches its own event
201
- * for `is_logged_out()` reasons (401/403/406) and for 405, so those never
202
- * reach `connectFailure` in practice. Kept because they cost nothing and the
203
- * engine's routing is not ours to depend on.
204
- */
205
- const mapConnectFailureToDisconnect = (reason) => {
206
- switch (reason) {
207
- case 401: // LoggedOut
208
- case 403: // MainDeviceGone
209
- case 406: // UnknownLogout
210
- return DisconnectReason.loggedOut;
211
- case 402: // TempBanned
212
- return DisconnectReason.forbidden;
213
- case 405: // ClientOutdated
214
- return CLIENT_OUTDATED_STATUS;
215
- case 411: // MultideviceMismatch (legacy alias)
216
- return DisconnectReason.multideviceMismatch;
217
- case 503: // ServiceUnavailable
218
- case 501: // Experimental
219
- return DisconnectReason.unavailableService;
220
- case 408: // Timed out
221
- return DisconnectReason.timedOut;
222
- case 515: // RestartRequired
223
- return DisconnectReason.restartRequired;
224
- // 400, 409, 413, 414, 415, 418, 500, undefined → generic close
225
- default:
226
- return DisconnectReason.connectionClosed;
227
- }
228
- };
229
194
  const describeTempBan = (code) => {
230
195
  switch (code) {
231
196
  case 101:
@@ -581,7 +546,7 @@ const DISPATCHERS = {
581
546
  // the same complete lifecycle and ordering as upstream.
582
547
  void (async () => {
583
548
  try {
584
- const bridgeMetadata = await (await ctx.getClient()).getGroupMetadata(evt.groupJid);
549
+ const bridgeMetadata = await ctx.withClient(client => client.getGroupMetadata(evt.groupJid));
585
550
  const metadata = bridgeGroupMetadataToBaileys(bridgeMetadata);
586
551
  ctx.ev.emit('chats.upsert', [
587
552
  { id: metadata.id, name: metadata.subject, conversationTimestamp: metadata.creation }
@@ -22,22 +22,23 @@ export const JOIN_APPROVAL_MODES = ['on', 'off'];
22
22
  const inviteExpirationNumber = (value) => toNumber(value);
23
23
  export const makeGroupMethods = (ctx) => {
24
24
  const groupMetadata = async (jid) => {
25
- const metadata = await (await ctx.getClient()).getGroupMetadata(jid);
25
+ const metadata = await ctx.withClient(client => client.getGroupMetadata(jid));
26
26
  return bridgeGroupMetadataToBaileys(metadata);
27
27
  };
28
28
  const groupSettingUpdate = async (jid, setting) => {
29
29
  const checked = assertArgumentDomain('groupSettingUpdate', 'setting', setting, GROUP_SETTINGS);
30
30
  const mapped = GROUP_SETTING_ALIASES[checked];
31
- await (await ctx.getClient()).groupSettingUpdate(jid, mapped.setting, mapped.value);
31
+ await ctx.withClient(client => client.groupSettingUpdate(jid, mapped.setting, mapped.value));
32
32
  };
33
33
  const groupAcceptInviteV4 = ctx.ev.createBufferedFunction(async (key, inviteMessage
34
34
  // oxlint-disable-next-line typescript/no-explicit-any -- the established public contract returns Promise<any>.
35
35
  ) => {
36
36
  const messageKey = typeof key === 'string' ? { remoteJid: key } : key;
37
- if (!inviteMessage.groupJid || !inviteMessage.inviteCode || !messageKey.remoteJid) {
37
+ const groupJid = inviteMessage.groupJid;
38
+ if (!groupJid || !inviteMessage.inviteCode || !messageKey.remoteJid) {
38
39
  throw new TypeError('groupAcceptInviteV4 requires groupJid, inviteCode and inviter JID');
39
40
  }
40
- const joinedJid = await (await ctx.getClient()).groupAcceptInviteV4(inviteMessage.groupJid, inviteMessage.inviteCode, inviteExpirationNumber(inviteMessage.inviteExpiration), messageKey.remoteJid);
41
+ const joinedJid = await ctx.withClient(client => client.groupAcceptInviteV4(groupJid, inviteMessage.inviteCode, inviteExpirationNumber(inviteMessage.inviteExpiration), messageKey.remoteJid));
41
42
  if (messageKey.id) {
42
43
  const expiredInvite = proto.Message.GroupInviteMessage.fromObject(inviteMessage);
43
44
  expiredInvite.inviteExpiration = 0;
@@ -68,61 +69,61 @@ export const makeGroupMethods = (ctx) => {
68
69
  return {
69
70
  groupMetadata,
70
71
  groupCreate: async (subject, participants) => {
71
- const metadata = await (await ctx.getClient()).createGroup(subject, participants);
72
+ const metadata = await ctx.withClient(client => client.createGroup(subject, participants));
72
73
  return bridgeGroupMetadataToBaileys(metadata);
73
74
  },
74
75
  groupLeave: async (id) => {
75
- await (await ctx.getClient()).groupLeave(id);
76
+ await ctx.withClient(client => client.groupLeave(id));
76
77
  },
77
78
  groupUpdateSubject: async (jid, subject) => {
78
- await (await ctx.getClient()).groupUpdateSubject(jid, subject);
79
+ await ctx.withClient(client => client.groupUpdateSubject(jid, subject));
79
80
  },
80
81
  groupRequestParticipantsList: async (jid) => {
81
- return bridgeMembershipRequestsToBaileys(await (await ctx.getClient()).groupRequestParticipantsList(jid));
82
+ return bridgeMembershipRequestsToBaileys(await ctx.withClient(client => client.groupRequestParticipantsList(jid)));
82
83
  },
83
84
  groupRequestParticipantsUpdate: async (jid, participants, action) => {
84
85
  assertArgumentDomain('groupRequestParticipantsUpdate', 'action', action, GROUP_REQUEST_ACTIONS);
85
- return bridgeMembershipRequestUpdatesToBaileys(await (await ctx.getClient()).groupRequestParticipantsUpdate(jid, participants, action));
86
+ return bridgeMembershipRequestUpdatesToBaileys(await ctx.withClient(client => client.groupRequestParticipantsUpdate(jid, participants, action)));
86
87
  },
87
88
  groupParticipantsUpdate: async (jid, participants, action) => {
88
89
  assertArgumentDomain('groupParticipantsUpdate', 'action', action, PARTICIPANT_ACTIONS);
89
- return bridgeParticipantChangesToBaileys(await (await ctx.getClient()).groupParticipantsUpdate(jid, participants, action));
90
+ return bridgeParticipantChangesToBaileys(await ctx.withClient(client => client.groupParticipantsUpdate(jid, participants, action)));
90
91
  },
91
92
  groupUpdateDescription: async (jid, description) => {
92
- await (await ctx.getClient()).groupUpdateDescription(jid, description);
93
+ await ctx.withClient(client => client.groupUpdateDescription(jid, description));
93
94
  },
94
95
  groupInviteCode: async (jid) => {
95
- return bridgeInviteLinkToCode(await (await ctx.getClient()).groupInviteCode(jid));
96
+ return bridgeInviteLinkToCode(await ctx.withClient(client => client.groupInviteCode(jid)));
96
97
  },
97
98
  groupRevokeInvite: async (jid) => {
98
- return bridgeInviteLinkToCode(await (await ctx.getClient()).groupRevokeInvite(jid));
99
+ return bridgeInviteLinkToCode(await ctx.withClient(client => client.groupRevokeInvite(jid)));
99
100
  },
100
101
  groupAcceptInvite: async (code) => {
101
- return (await ctx.getClient()).groupAcceptInvite(code);
102
+ return ctx.withClient(client => client.groupAcceptInvite(code));
102
103
  },
103
104
  groupRevokeInviteV4: async (groupJid, invitedJid) => {
104
- return (await ctx.getClient()).groupRevokeInviteV4(groupJid, invitedJid);
105
+ return ctx.withClient(client => client.groupRevokeInviteV4(groupJid, invitedJid));
105
106
  },
106
107
  groupAcceptInviteV4,
107
108
  groupGetInviteInfo: async (code) => {
108
- return bridgeGroupMetadataToBaileys(await (await ctx.getClient()).groupGetInviteInfo(code));
109
+ return bridgeGroupMetadataToBaileys(await ctx.withClient(client => client.groupGetInviteInfo(code)));
109
110
  },
110
111
  groupToggleEphemeral: async (jid, ephemeralExpiration) => {
111
- await (await ctx.getClient()).groupToggleEphemeral(jid, ephemeralExpiration);
112
+ await ctx.withClient(client => client.groupToggleEphemeral(jid, ephemeralExpiration));
112
113
  },
113
114
  groupSettingUpdate,
114
115
  groupMemberAddMode: async (jid, mode) => {
115
116
  assertArgumentDomain('groupMemberAddMode', 'mode', mode, MEMBER_ADD_MODES);
116
- await (await ctx.getClient()).groupMemberAddMode(jid, mode);
117
+ await ctx.withClient(client => client.groupMemberAddMode(jid, mode));
117
118
  },
118
119
  groupJoinApprovalMode: async (jid, mode) => {
119
120
  // Anything but 'on' used to mean off, so a typo turned approvals off
120
121
  // and reported success.
121
122
  assertArgumentDomain('groupJoinApprovalMode', 'mode', mode, JOIN_APPROVAL_MODES);
122
- await (await ctx.getClient()).groupSettingUpdate(jid, 'membership_approval', mode === 'on');
123
+ await ctx.withClient(client => client.groupSettingUpdate(jid, 'membership_approval', mode === 'on'));
123
124
  },
124
125
  groupFetchAllParticipating: async () => {
125
- const bridgeGroups = await (await ctx.getClient()).groupFetchAllParticipating();
126
+ const bridgeGroups = await ctx.withClient(client => client.groupFetchAllParticipating());
126
127
  const result = {};
127
128
  for (const [groupJid, metadata] of Object.entries(bridgeGroups)) {
128
129
  result[groupJid] = bridgeGroupMetadataToBaileys(metadata);
@@ -131,7 +132,7 @@ export const makeGroupMethods = (ctx) => {
131
132
  return result;
132
133
  },
133
134
  updateMemberLabel: async (jid, memberLabel) => {
134
- return (await ctx.getClient()).updateMemberLabel(jid, memberLabel.slice(0, 30));
135
+ return ctx.withClient(client => client.updateMemberLabel(jid, memberLabel.slice(0, 30)));
135
136
  }
136
137
  };
137
138
  };
@@ -1,5 +1,5 @@
1
1
  import { Buffer } from 'node:buffer';
2
- import { type UploadMediaResult } from '@oxidezap/whatsapp-rust-bridge';
2
+ import { type WasmWhatsAppClient, type UploadMediaResult } from '@oxidezap/whatsapp-rust-bridge';
3
3
  import { WebSocketClient } from '../Compatibility/websocket-client.js';
4
4
  import { type MediaType } from '../Defaults/index.js';
5
5
  import type { BinaryNode, AuthenticationCreds, ConnectionState, Contact, ReachoutTimelockState, SignalKeyStoreWithTransaction, UserFacingSocketConfig, WABusinessProfile, WAMessage, WAMessageKey, WAPresence } from '../Types/index.js';
@@ -220,7 +220,7 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
220
220
  */
221
221
  [Symbol.asyncDispose](): Promise<void>;
222
222
  user: Contact | undefined;
223
- waClient: import("@oxidezap/whatsapp-rust-bridge").WasmWhatsAppClient | undefined;
223
+ waClient: WasmWhatsAppClient | undefined;
224
224
  isConnected: boolean;
225
225
  isLoggedIn: boolean;
226
226
  authState: {