@oxidezap/baileyrs 0.1.0 → 0.1.2

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.
@@ -1,89 +1,177 @@
1
- export const makeChatActionMethods = (ctx) => ({
2
- pinChat: async (jid, pin) => {
3
- await (await ctx.getClient()).pinChat(jid, pin);
4
- },
5
- muteChat: async (jid, muteUntil) => {
6
- await (await ctx.getClient()).muteChat(jid, muteUntil);
7
- },
8
- archiveChat: async (jid, archive) => {
9
- await (await ctx.getClient()).archiveChat(jid, archive);
10
- },
11
- starMessage: async (jid, messageId, star) => {
12
- await (await ctx.getClient()).starMessage(jid, messageId, star);
13
- },
14
- /**
15
- * Compatibility wrapper for original Baileys chatModify API.
16
- * Routes to the appropriate bridge method based on the modification type.
17
- *
18
- * Fully supported: archive, pin, mute, star, markRead, delete, deleteForMe, pushNameSetting, contact, clear
19
- * Not yet in bridge (app-state patches): disableLinkPreviews, labels, quickReply
20
- */
21
- chatModify: async (mod, jid) => {
22
- const client = await ctx.getClient();
23
- if ('archive' in mod) {
24
- await client.archiveChat(jid, mod.archive);
25
- }
26
- else if ('pin' in mod) {
27
- await client.pinChat(jid, mod.pin);
28
- }
29
- else if ('mute' in mod) {
30
- await client.muteChat(jid, mod.mute);
31
- }
32
- else if ('star' in mod) {
33
- for (const msg of mod.star.messages) {
34
- await client.starMessage(jid, msg.id, mod.star.star);
1
+ import { Boom } from '../Utils/boom.js';
2
+ /**
3
+ * Refuse a field the mutation carries but the wire call cannot. Dropping it
4
+ * would report success for a change that never happened, which is the failure
5
+ * this whole path exists to stop.
6
+ */
7
+ const rejectUnsupportedFields = (where, value, fields) => {
8
+ const present = fields.filter(field => value[field] != null);
9
+ if (present.length) {
10
+ throw new Boom(`${where}: ${present.join(', ')} cannot be set through this client`, {
11
+ statusCode: 400,
12
+ data: { fields: present }
13
+ });
14
+ }
15
+ };
16
+ export const makeChatActionMethods = (ctx) => {
17
+ const methods = {
18
+ pinChat: async (jid, pin) => {
19
+ await (await ctx.getClient()).pinChat(jid, pin);
20
+ },
21
+ muteChat: async (jid, muteUntil) => {
22
+ await (await ctx.getClient()).muteChat(jid, muteUntil);
23
+ },
24
+ archiveChat: async (jid, archive) => {
25
+ await (await ctx.getClient()).archiveChat(jid, archive);
26
+ },
27
+ starMessage: async (jid, messageId, star) => {
28
+ await (await ctx.getClient()).starMessage(jid, messageId, star);
29
+ },
30
+ /**
31
+ * Compatibility wrapper for original Baileys chatModify API.
32
+ * Routes to the appropriate bridge method based on the modification type.
33
+ *
34
+ * Every variant either runs or throws. A variant that resolved without
35
+ * doing anything told the caller their chat was labelled when nothing was
36
+ * synced, and no signature or type catches that.
37
+ */
38
+ chatModify: async (mod, jid) => {
39
+ const client = await ctx.getClient();
40
+ if ('archive' in mod) {
41
+ await client.archiveChat(jid, mod.archive);
35
42
  }
36
- }
37
- else if ('markRead' in mod) {
38
- await client.markChatAsRead(jid, mod.markRead);
39
- }
40
- else if ('delete' in mod) {
41
- await client.deleteChat(jid);
42
- }
43
- else if ('deleteForMe' in mod) {
44
- await client.deleteMessageForMe(jid, mod.deleteForMe.key.id, !!mod.deleteForMe.key.fromMe);
45
- }
46
- else if ('pushNameSetting' in mod) {
47
- await client.setPushName(mod.pushNameSetting);
48
- }
49
- else if ('contact' in mod) {
50
- // Save/rename a contact (syncs the name to linked devices). `jid` is the
51
- // contact's bare PN jid.
52
- if (mod.contact) {
53
- await client.saveContact(jid, mod.contact.fullName ?? undefined, mod.contact.firstName ?? undefined, mod.contact.saveOnPrimaryAddressbook ?? true);
43
+ else if ('pin' in mod) {
44
+ await client.pinChat(jid, mod.pin);
54
45
  }
55
- else {
56
- // `contact: null` = remove-contact in upstream Baileys; no
57
- // bridge/core path yet — warn instead of silently dropping.
58
- ctx.logger.warn({ jid }, 'chatModify: contact removal (contact: null) not yet supported by bridge');
46
+ else if ('mute' in mod) {
47
+ await client.muteChat(jid, mod.mute);
59
48
  }
60
- }
61
- else if ('clear' in mod) {
62
- // Clear a chat's messages while keeping the chat. `lastMessages` (the
63
- // message range) is ignored, same as the `delete` branch — the bridge
64
- // clears the whole chat. deleteStarred/deleteMedia aren't part of the
65
- // Baileys `clear` shape, so default both to false (keep starred + media).
66
- if (mod.clear) {
67
- await client.clearChat(jid, false, false);
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
+ }
68
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);
133
+ }
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
+ }
139
+ },
140
+ // Upstream models all of these as sugar over `chatModify`, and so do we:
141
+ // one place decides which bridge call a modification becomes, so the
142
+ // method and the modification can never disagree.
143
+ addOrEditContact: async (jid, contact) => {
144
+ await methods.chatModify({ contact }, jid);
145
+ },
146
+ removeContact: async (jid) => {
147
+ await methods.chatModify({ contact: null }, jid);
148
+ },
149
+ addLabel: async (jid, labels) => {
150
+ await methods.chatModify({ addLabel: { ...labels } }, jid);
151
+ },
152
+ addChatLabel: async (jid, labelId) => {
153
+ await methods.chatModify({ addChatLabel: { labelId } }, jid);
154
+ },
155
+ removeChatLabel: async (jid, labelId) => {
156
+ await methods.chatModify({ removeChatLabel: { labelId } }, jid);
157
+ },
158
+ addMessageLabel: async (jid, messageId, labelId) => {
159
+ await methods.chatModify({ addMessageLabel: { labelId, messageId } }, jid);
160
+ },
161
+ removeMessageLabel: async (jid, messageId, labelId) => {
162
+ await methods.chatModify({ removeMessageLabel: { labelId, messageId } }, jid);
163
+ },
164
+ star: async (jid, messages, star) => {
165
+ await methods.chatModify({ star: { messages, star } }, jid);
166
+ },
167
+ // No jid: a quick reply is account-wide, keyed only by its index.
168
+ addOrEditQuickReply: async (quickReply) => {
169
+ await methods.chatModify({ quickReply }, '');
170
+ },
171
+ removeQuickReply: async (timestamp) => {
172
+ await methods.chatModify({ quickReply: { timestamp, deleted: true } }, '');
69
173
  }
70
- else {
71
- // App-state-patch variants not yet exposed by bridge:
72
- // disableLinkPreviews, addLabel, addChatLabel,
73
- // removeChatLabel, addMessageLabel, removeMessageLabel, quickReply
74
- const variant = Object.keys(mod)[0];
75
- ctx.logger.warn({ variant, jid }, 'chatModify: variant requires app-state patch support not yet available in bridge');
76
- }
77
- },
78
- /**
79
- * Force re-sync of app state collections.
80
- *
81
- * In the Rust bridge architecture, app state is managed internally by the engine
82
- * and synced automatically on connect. This method is a no-op provided for API
83
- * compatibility with upstream Baileys.
84
- */
85
- resyncAppState: async (_collections, _isInitialSync) => {
86
- ctx.logger.info('resyncAppState: app state is synced automatically by the Rust bridge');
87
- }
88
- });
174
+ };
175
+ return methods;
176
+ };
89
177
  //# sourceMappingURL=chat-actions.js.map
@@ -813,7 +813,7 @@ const dispatchCanonicalEvent = (canonical, dispatchCtx) => {
813
813
  }
814
814
  catch (err) {
815
815
  // One bad event must not poison the rest of the pipeline.
816
- dispatchCtx.ctx.logger.error({ err, type: canonical.type }, 'dispatcher threw — dropping event');
816
+ dispatchCtx.ctx.reportUnexpectedError(err, `dispatching a '${canonical.type}' event`);
817
817
  }
818
818
  };
819
819
  /** Aggregate adjacent ordinary messages while preserving every side-effecting
@@ -852,7 +852,7 @@ const dispatchCanonicalBatch = (ctx, dispatchCtx, count, canonicalAt) => {
852
852
  }
853
853
  }
854
854
  catch (err) {
855
- ctx.logger.error({ err, type: CANONICAL_MESSAGE_EVENT }, 'dispatcher threw — dropping event');
855
+ ctx.reportUnexpectedError(err, `dispatching a '${CANONICAL_MESSAGE_EVENT}' event`);
856
856
  }
857
857
  }
858
858
  if (pending)
@@ -884,7 +884,7 @@ export const makeEventHandlers = (ctx, callbacks) => {
884
884
  view = decodeMessageWireBatch(batch);
885
885
  }
886
886
  catch (err) {
887
- ctx.logger.error({ err }, 'failed to decode the message wire batch');
887
+ ctx.reportUnexpectedError(err, 'decoding the message wire batch');
888
888
  return;
889
889
  }
890
890
  const { messageData, messageOffsets, infos } = view;
@@ -923,7 +923,7 @@ export const makeEventHandlers = (ctx, callbacks) => {
923
923
  receipts = decodeReceiptWireBatch(batch);
924
924
  }
925
925
  catch (err) {
926
- ctx.logger.error({ err }, 'failed to decode receipt wire batch');
926
+ ctx.reportUnexpectedError(err, 'decoding the receipt wire batch');
927
927
  return;
928
928
  }
929
929
  // The decoded payload matches the single-event wire shape; the union's
@@ -937,7 +937,7 @@ export const makeEventHandlers = (ctx, callbacks) => {
937
937
  acks = decodeServerAckWireBatch(batch);
938
938
  }
939
939
  catch (err) {
940
- ctx.logger.error({ err }, 'failed to decode server-ack wire batch');
940
+ ctx.reportUnexpectedError(err, 'decoding the server-ack wire batch');
941
941
  return;
942
942
  }
943
943
  for (const data of acks)
@@ -2,7 +2,7 @@ import { Buffer } from 'node:buffer';
2
2
  import { 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
- import type { BinaryNode, AuthenticationCreds, ConnectionState, Contact, ReachoutTimelockState, SignalKeyStoreWithTransaction, UserFacingSocketConfig, WAPrivacyGroupAddValue, WAPrivacyOnlineValue, WAPrivacyValue, WABusinessProfile, WAReadReceiptsValue, WAMessage, WAMessageKey } from '../Types/index.js';
5
+ import type { BinaryNode, AuthenticationCreds, ConnectionState, Contact, ReachoutTimelockState, SignalKeyStoreWithTransaction, UserFacingSocketConfig, WABusinessProfile, WAMessage, WAMessageKey } from '../Types/index.js';
6
6
  import type Long from 'long';
7
7
  import type { MediaDownloadOptions } from '../Utils/messages-media.js';
8
8
  import type { proto } from '../WAProto/runtime.js';
@@ -12,12 +12,33 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
12
12
  sendRetryRequest: (node: BinaryNode, forceIncludeKeys?: boolean) => Promise<void>;
13
13
  updateBlockStatus: (jid: string, action: 'block' | 'unblock') => Promise<void>;
14
14
  fetchBlocklist: () => Promise<Array<string | undefined>>;
15
+ getCatalog: ({ jid, limit, cursor }: import("../index.js").GetCatalogOptions) => Promise<import("../index.js").CatalogPage>;
16
+ getCollections: (jid?: string, limit?: number) => Promise<import("../index.js").CollectionsPage>;
17
+ getOrderDetails: (orderId: string, tokenBase64: string, sellerJid?: string) => Promise<import("@oxidezap/whatsapp-rust-bridge").OrderResult>;
18
+ updateBussinesProfile: (args: import("../Types/Bussines.js").UpdateBussinesProfileProps) => Promise<void>;
19
+ updateCoverPhoto: (photo: import("../index.js").WAMediaUpload) => Promise<never>;
20
+ removeCoverPhoto: (id: string) => Promise<void>;
21
+ productCreate: (create: import("../index.js").ProductCreate) => Promise<never>;
22
+ productUpdate: (productId: string, update: import("../index.js").ProductUpdate) => Promise<never>;
23
+ productDelete: (productIds: string[]) => Promise<never>;
15
24
  pinChat: (jid: string, pin: boolean) => Promise<void>;
16
25
  muteChat: (jid: string, muteUntil?: number | null) => Promise<void>;
17
26
  archiveChat: (jid: string, archive: boolean) => Promise<void>;
18
27
  starMessage: (jid: string, messageId: string, star: boolean) => Promise<void>;
19
28
  chatModify: (mod: import("../index.js").ChatModification, jid: string) => Promise<void>;
20
- resyncAppState: (_collections?: readonly import("../index.js").WAPatchName[], _isInitialSync?: boolean) => Promise<void>;
29
+ addOrEditContact: (jid: string, contact: proto.SyncActionValue.IContactAction) => Promise<void>;
30
+ removeContact: (jid: string) => Promise<void>;
31
+ addLabel: (jid: string, labels: import("../Types/Label.js").LabelActionBody) => Promise<void>;
32
+ addChatLabel: (jid: string, labelId: string) => Promise<void>;
33
+ removeChatLabel: (jid: string, labelId: string) => Promise<void>;
34
+ addMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
35
+ removeMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
36
+ star: (jid: string, messages: {
37
+ id: string;
38
+ fromMe?: boolean;
39
+ }[], star: boolean) => Promise<void>;
40
+ addOrEditQuickReply: (quickReply: import("../Types/Bussines.js").QuickReplyAction) => Promise<void>;
41
+ removeQuickReply: (timestamp: string) => Promise<void>;
21
42
  onWhatsApp: (...phoneNumber: string[]) => Promise<import("./contacts.js").OnWhatsAppResult[] | undefined>;
22
43
  profilePictureUrl: (jid: string, type?: 'preview' | 'image', timeoutMs?: number) => Promise<string | undefined>;
23
44
  fetchUserInfo: (...jids: string[]) => Promise<Record<string, import("@oxidezap/whatsapp-rust-bridge").UserInfoResult>>;
@@ -74,6 +95,14 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
74
95
  communityMemberAddMode: (jid: string, mode: 'admin_add' | 'all_member_add') => Promise<void>;
75
96
  communityJoinApprovalMode: (jid: string, mode: 'on' | 'off') => Promise<void>;
76
97
  communityFetchAllParticipating: () => Promise<Record<string, import("../index.js").GroupMetadata>>;
98
+ waitForSocketOpen: () => Promise<void>;
99
+ upsertMessage: (msg: WAMessage, type: import("../index.js").MessageUpsertType) => Promise<void>;
100
+ onUnexpectedError: (err: Error, msg: string) => void;
101
+ resyncAppState: (collections?: readonly ('critical_block' | 'critical_unblock_low' | 'regular_high' | 'regular_low' | 'regular')[], isInitialSync?: boolean) => Promise<void>;
102
+ updateServerTimeOffset: (node: BinaryNode) => never;
103
+ sendUnifiedSession: () => Promise<never>;
104
+ appPatch: (patchCreate: import("../index.js").WAPatchCreate) => Promise<never>;
105
+ messageRetryManager: null;
77
106
  sendMessage: (jid: string, content: import("../index.js").AnyMessageContent, options?: Omit<import("../index.js").MessageGenerationOptions, 'waClient' | 'logger' | 'userJid' | 'mediaInNote'>) => Promise<WAMessage>;
78
107
  updateMediaMessage: (message: WAMessage) => Promise<WAMessage>;
79
108
  relayMessage: (jid: string, message: proto.IMessage, options: import("../index.js").MessageRelayOptions) => Promise<string>;
@@ -81,12 +110,31 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
81
110
  sendReceipt: (jid: string, participant: string | undefined, messageIds: string[], type: import("../index.js").MessageReceiptType) => Promise<void>;
82
111
  sendReceipts: (keys: WAMessageKey[], type: import("../index.js").MessageReceiptType) => Promise<void>;
83
112
  requestPlaceholderResend: (messageKey: WAMessageKey, msgData?: Partial<WAMessage>) => Promise<string | undefined>;
84
- newsletterCreate: (name: string, description?: string) => Promise<import("@oxidezap/whatsapp-rust-bridge").NewsletterMetadataResult>;
85
- newsletterMetadata: (jid: string) => Promise<import("@oxidezap/whatsapp-rust-bridge").NewsletterMetadataResult>;
113
+ newsletterCreate: (name: string, description?: string) => Promise<import("../index.js").NewsletterMetadata>;
114
+ newsletterMetadata: (type: 'invite' | 'jid', key: string) => Promise<import("../index.js").NewsletterMetadata | null>;
115
+ newsletterUpdate: (jid: string, updates: import("../index.js").NewsletterUpdate) => Promise<import("../index.js").NewsletterMetadata>;
116
+ newsletterUpdateName: (jid: string, name: string) => Promise<import("../index.js").NewsletterMetadata>;
117
+ newsletterUpdateDescription: (jid: string, description: string) => Promise<import("../index.js").NewsletterMetadata>;
118
+ newsletterUpdatePicture: (jid: string, content: import("../index.js").WAMediaUpload) => Promise<import("../index.js").NewsletterMetadata>;
119
+ newsletterRemovePicture: (jid: string) => Promise<import("../index.js").NewsletterMetadata>;
120
+ newsletterFollow: (jid: string) => Promise<import("../index.js").NewsletterMetadata>;
121
+ newsletterUnfollow: (jid: string) => Promise<void>;
86
122
  newsletterSubscribe: (jid: string) => Promise<import("@oxidezap/whatsapp-rust-bridge").NewsletterMetadataResult>;
87
123
  newsletterUnsubscribe: (jid: string) => Promise<void>;
124
+ newsletterMute: (jid: string) => Promise<void>;
125
+ newsletterUnmute: (jid: string) => Promise<void>;
126
+ newsletterSubscribers: (jid: string) => Promise<{
127
+ subscribers: number;
128
+ }>;
88
129
  newsletterReactMessage: (jid: string, serverId: string, reaction?: string) => Promise<void>;
89
- newsletterMute: (jid: string, mute: boolean) => Promise<void>;
130
+ newsletterFetchMessages: (jid: string, count: number, since?: number, after?: number) => Promise<import("@oxidezap/whatsapp-rust-bridge").NewsletterMessageResult[]>;
131
+ subscribeNewsletterUpdates: (jid: string) => Promise<{
132
+ duration: string;
133
+ }>;
134
+ newsletterAdminCount: (jid: string) => Promise<number>;
135
+ newsletterChangeOwner: (jid: string, newOwnerJid: string) => Promise<void>;
136
+ newsletterDemote: (jid: string, userJid: string) => Promise<void>;
137
+ newsletterDelete: (jid: string) => Promise<void>;
90
138
  uploadPreKeys: (count?: number) => Promise<void>;
91
139
  uploadPreKeysToServerIfRequired: () => Promise<void>;
92
140
  digestKeyBundle: () => Promise<void>;
@@ -94,6 +142,30 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
94
142
  sendPresence: (status: 'available' | 'unavailable') => Promise<void>;
95
143
  presenceSubscribe: (toJid: string) => Promise<void>;
96
144
  sendChatState: (jid: string, state: 'composing' | 'recording' | 'paused') => Promise<void>;
145
+ fetchPrivacySettings: (force?: boolean) => Promise<any>;
146
+ updatePrivacySetting: (category: string, value: string) => Promise<void>;
147
+ updateLastSeenPrivacy: (value: import("../index.js").WAPrivacyValue) => Promise<void>;
148
+ updateOnlinePrivacy: (value: import("../index.js").WAPrivacyOnlineValue) => Promise<void>;
149
+ updateProfilePicturePrivacy: (value: import("../index.js").WAPrivacyValue) => Promise<void>;
150
+ updateStatusPrivacy: (value: import("../index.js").WAPrivacyValue) => Promise<void>;
151
+ updateReadReceiptsPrivacy: (value: import("../index.js").WAReadReceiptsValue) => Promise<void>;
152
+ updateGroupsAddPrivacy: (value: import("../index.js").WAPrivacyGroupAddValue) => Promise<void>;
153
+ updateCallPrivacy: (value: import("../index.js").WAPrivacyCallValue) => Promise<void>;
154
+ updateMessagesPrivacy: (value: import("../index.js").WAPrivacyMessagesValue) => Promise<void>;
155
+ issuePrivacyTokens: (jids: string[], timestamp?: number) => Promise<void>;
156
+ refreshMediaConn: (forceGet?: boolean) => Promise<Omit<import("../index.js").MediaConnInfo, 'hosts'> & {
157
+ hosts: {
158
+ hostname: string;
159
+ }[];
160
+ }>;
161
+ getMediaHost: () => string;
162
+ getBotListV2: () => Promise<import("../index.js").BotListInfo[]>;
163
+ fetchNewChatMessageCap: () => Promise<import("../index.js").NewChatMessageCapInfo & {
164
+ remaining_quota?: number;
165
+ }>;
166
+ cleanDirtyBits: (type: 'account_sync' | 'groups', fromTimestamp?: number | string) => Promise<void>;
167
+ sendPeerDataOperationMessage: (_pdoMessage: unknown) => Promise<never>;
168
+ createCallLink: (_type: 'audio' | 'video', _event?: unknown, _timeoutMs?: number) => Promise<never>;
97
169
  requestPairingCode: (phoneNumber: string, customPairingCode?: string) => Promise<string>;
98
170
  setPushName: (name: string) => Promise<void>;
99
171
  updateProfileName: (name: string) => Promise<void>;
@@ -176,7 +248,14 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
176
248
  waitForMessage: <T>(msgId: string, timeoutMs?: number | undefined) => Promise<T | undefined>;
177
249
  query: (node: BinaryNode, timeoutMs?: number) => Promise<BinaryNode>;
178
250
  sendRawMessage: (data: Uint8Array | Buffer) => Promise<void>;
179
- createParticipantNodes: (jids: string[], message: proto.IMessage, extraAttrs?: BinaryNode['attrs']) => Promise<{
251
+ /**
252
+ * `dsmMessage` is accepted so the signature matches upstream, and
253
+ * refused rather than ignored. Upstream uses it to encrypt a different
254
+ * plaintext for the caller's own other devices; the engine encrypts one
255
+ * payload for every recipient, so honouring it is not possible here and
256
+ * dropping it would send those devices the wrong message.
257
+ */
258
+ createParticipantNodes: (jids: string[], message: proto.IMessage, extraAttrs?: BinaryNode['attrs'], dsmMessage?: proto.IMessage) => Promise<{
180
259
  nodes: BinaryNode[];
181
260
  shouldIncludeDeviceIdentity: boolean;
182
261
  }>;
@@ -203,14 +282,6 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
203
282
  waUploadToServer: (data: Uint8Array | Buffer, opts: {
204
283
  mediaType: MediaType;
205
284
  }) => Promise<UploadMediaResult>;
206
- fetchPrivacySettings: (force?: boolean) => Promise<any>;
207
- updatePrivacySetting: (category: string, value: string) => Promise<void>;
208
- updateLastSeenPrivacy: (value: WAPrivacyValue) => Promise<void>;
209
- updateOnlinePrivacy: (value: WAPrivacyOnlineValue) => Promise<void>;
210
- updateProfilePicturePrivacy: (value: WAPrivacyValue) => Promise<void>;
211
- updateStatusPrivacy: (value: WAPrivacyValue) => Promise<void>;
212
- updateReadReceiptsPrivacy: (value: WAReadReceiptsValue) => Promise<void>;
213
- updateGroupsAddPrivacy: (value: WAPrivacyGroupAddValue) => Promise<void>;
214
285
  updateDefaultDisappearingMode: (duration: number) => Promise<void>;
215
286
  rejectCall: (callId: string, callFrom: string) => Promise<void>;
216
287
  /**
@@ -21,6 +21,7 @@ import { makeNativeCryptoProvider } from '../Utils/native-crypto-provider.js';
21
21
  import { wrapLegacyStore } from '../Utils/wrap-legacy-store.js';
22
22
  import { assertNodeErrorFree } from '../WABinary/generic-utils.js';
23
23
  import { makeBlockingMethods } from './blocking.js';
24
+ import { makeBusinessMethods } from './business.js';
24
25
  import { makeChatActionMethods } from './chat-actions.js';
25
26
  import { makeContactMethods } from './contacts.js';
26
27
  import { makeCommunityMethods } from './communities.js';
@@ -28,10 +29,13 @@ import { makeBridgeClientOwner } from './bridge-client-owner.js';
28
29
  import { makeTerminalCloseReporter } from './terminal-close-reporter.js';
29
30
  import { makeEventHandlers } from './events.js';
30
31
  import { makeGroupMethods } from './groups.js';
32
+ import { makeInternalMethods, makeUnexpectedErrorReporter } from './internals.js';
31
33
  import { makeMessageMethods } from './messages.js';
32
34
  import { makeNewsletterMethods } from './newsletter.js';
33
35
  import { makePreKeyMethods } from './prekeys.js';
34
36
  import { makePresenceMethods } from './presence.js';
37
+ import { makePrivacyMethods } from './privacy.js';
38
+ import { makeServerQueryMethods } from './server-queries.js';
35
39
  import { makeProfileMethods } from './profile.js';
36
40
  import { mapReachoutTimelock } from './reachout.js';
37
41
  import { makeHttpClient, makeTransport } from './transport.js';
@@ -249,11 +253,18 @@ const makeWASocket = (config) => {
249
253
  let autoReconnectEnabled = true;
250
254
  /** Owns reporting the terminal close: once, after teardown, never not at all. */
251
255
  const terminalClose = makeTerminalCloseReporter({ logger });
256
+ /**
257
+ * Held in a reporter rather than captured, because `sock.onUnexpectedError`
258
+ * is an assignable property: a consumer that replaces it has to be the one
259
+ * the socket's own failure paths reach afterwards.
260
+ */
261
+ const unexpectedErrors = makeUnexpectedErrorReporter(logger);
252
262
  const ctx = {
253
263
  ev,
254
264
  logger,
255
265
  fullConfig,
256
266
  ws,
267
+ reportUnexpectedError: unexpectedErrors.report,
257
268
  getUser: () => user,
258
269
  getMe: () => {
259
270
  const me = auth.creds.me;
@@ -783,7 +794,17 @@ const makeWASocket = (config) => {
783
794
  sendRawMessage: async (data) => {
784
795
  return (await ctx.getClient()).sendRawMessage(data instanceof Uint8Array ? data : new Uint8Array(data));
785
796
  },
786
- createParticipantNodes: async (jids, message, extraAttrs) => {
797
+ /**
798
+ * `dsmMessage` is accepted so the signature matches upstream, and
799
+ * refused rather than ignored. Upstream uses it to encrypt a different
800
+ * plaintext for the caller's own other devices; the engine encrypts one
801
+ * payload for every recipient, so honouring it is not possible here and
802
+ * dropping it would send those devices the wrong message.
803
+ */
804
+ createParticipantNodes: async (jids, message, extraAttrs, dsmMessage) => {
805
+ if (dsmMessage) {
806
+ throw new Boom('createParticipantNodes: dsmMessage is not supported, the engine encrypts one payload for every recipient and cannot substitute a different one for your own devices', { statusCode: 501 });
807
+ }
787
808
  const bytes = encodeProto('Message', message);
788
809
  return (await ctx.getClient()).createParticipantNodesBytes(jids, bytes, extraAttrs ?? {});
789
810
  },
@@ -826,31 +847,7 @@ const makeWASocket = (config) => {
826
847
  const bytes = data instanceof Uint8Array && !Buffer.isBuffer(data) ? data : new Uint8Array(data);
827
848
  return (await ctx.getClient()).uploadMedia(bytes, toBridgeMediaType(opts.mediaType));
828
849
  },
829
- fetchPrivacySettings: async (force) => {
830
- void force;
831
- return (await ctx.getClient()).fetchPrivacySettings();
832
- },
833
- updatePrivacySetting: async (category, value) => {
834
- await (await ctx.getClient()).updatePrivacySetting(category, value);
835
- },
836
- updateLastSeenPrivacy: async (value) => {
837
- await (await ctx.getClient()).updatePrivacySetting('last', value);
838
- },
839
- updateOnlinePrivacy: async (value) => {
840
- await (await ctx.getClient()).updatePrivacySetting('online', value);
841
- },
842
- updateProfilePicturePrivacy: async (value) => {
843
- await (await ctx.getClient()).updatePrivacySetting('profile', value);
844
- },
845
- updateStatusPrivacy: async (value) => {
846
- await (await ctx.getClient()).updatePrivacySetting('status', value);
847
- },
848
- updateReadReceiptsPrivacy: async (value) => {
849
- await (await ctx.getClient()).updatePrivacySetting('readreceipts', value);
850
- },
851
- updateGroupsAddPrivacy: async (value) => {
852
- await (await ctx.getClient()).updatePrivacySetting('groupadd', value);
853
- },
850
+ ...makePrivacyMethods(ctx),
854
851
  updateDefaultDisappearingMode: async (duration) => {
855
852
  await (await ctx.getClient()).updateDefaultDisappearingMode(duration);
856
853
  },
@@ -891,11 +888,14 @@ const makeWASocket = (config) => {
891
888
  ...makeContactMethods(ctx),
892
889
  ...makeProfileMethods(ctx),
893
890
  ...makeChatActionMethods(ctx),
891
+ ...makeInternalMethods(ctx),
894
892
  ...usyncMethods,
895
893
  ...makeStanzaResponseMethods(ctx),
896
894
  ...makePresenceMethods(ctx),
897
895
  ...makeBlockingMethods(ctx),
898
896
  ...makeNewsletterMethods(ctx),
897
+ ...makeBusinessMethods(ctx),
898
+ ...makeServerQueryMethods(ctx),
899
899
  downloadMedia: async (message, type, options = {}) => {
900
900
  return downloadMediaMessage(message, type, options, {
901
901
  logger,
@@ -904,6 +904,16 @@ const makeWASocket = (config) => {
904
904
  });
905
905
  }
906
906
  };
907
+ // Assigning replaces the handler the socket itself reports through, rather
908
+ // than shadowing it with a second one only a consumer could reach.
909
+ Object.defineProperty(sock, 'onUnexpectedError', {
910
+ get: () => unexpectedErrors.handler,
911
+ set: (handler) => {
912
+ unexpectedErrors.handler = handler;
913
+ },
914
+ enumerable: true,
915
+ configurable: true
916
+ });
907
917
  return sock;
908
918
  };
909
919
  export default makeWASocket;