zapo-js 1.0.1 → 1.1.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.
Files changed (341) hide show
  1. package/dist/client/coordinators/WaMessageCoordinator.js +2 -18
  2. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +2 -1
  3. package/dist/client/events/incoming.js +3 -1
  4. package/dist/client/events/receipt.d.ts +30 -0
  5. package/dist/client/events/receipt.js +32 -0
  6. package/dist/{types/client → client}/media.d.ts +59 -2
  7. package/dist/client/media.js +60 -0
  8. package/dist/{types/client → client}/types.d.ts +7 -0
  9. package/dist/esm/appstate-spec.js +2 -2
  10. package/dist/esm/client/coordinators/WaMessageCoordinator.js +2 -18
  11. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +2 -1
  12. package/dist/esm/client/events/incoming.js +3 -1
  13. package/dist/esm/client/events/receipt.js +31 -0
  14. package/dist/esm/client/media.js +59 -0
  15. package/dist/esm/index.js +2 -0
  16. package/dist/esm/message/context-info.js +16 -3
  17. package/dist/esm/message/encode/media-payload.js +18 -0
  18. package/dist/esm/mex.js +1 -1
  19. package/dist/esm/protocol/message.js +2 -1
  20. package/dist/esm/version-spec.js +1 -1
  21. package/dist/{types/index.d.ts → index.d.ts} +4 -1
  22. package/dist/index.js +6 -2
  23. package/dist/{types/message → message}/context-info.d.ts +9 -0
  24. package/dist/message/context-info.js +15 -2
  25. package/dist/message/encode/media-payload.d.ts +43 -0
  26. package/dist/message/encode/media-payload.js +18 -0
  27. package/dist/{types/protocol → protocol}/message.d.ts +1 -0
  28. package/dist/protocol/message.js +2 -1
  29. package/package.json +20 -16
  30. package/dist/types/client/events/receipt.d.ts +0 -14
  31. package/dist/types/message/encode/media-payload.d.ts +0 -12
  32. /package/dist/{types/appstate → appstate}/constants.d.ts +0 -0
  33. /package/dist/{types/appstate → appstate}/crypto/WaAppStateCrypto.d.ts +0 -0
  34. /package/dist/{types/appstate → appstate}/index.d.ts +0 -0
  35. /package/dist/{types/appstate → appstate}/parsers/encoding.d.ts +0 -0
  36. /package/dist/{types/appstate → appstate}/parsers/response-parser.d.ts +0 -0
  37. /package/dist/{types/appstate → appstate}/sync/WaAppStateSyncClient.d.ts +0 -0
  38. /package/dist/{types/appstate → appstate}/types.d.ts +0 -0
  39. /package/dist/{types/appstate → appstate}/utils.d.ts +0 -0
  40. /package/dist/{types/appstate-spec.d.ts → appstate-spec.d.ts} +0 -0
  41. /package/dist/{types/auth → auth}/WaAuthClient.d.ts +0 -0
  42. /package/dist/{types/auth → auth}/credentials-flow.d.ts +0 -0
  43. /package/dist/{types/auth → auth}/index.d.ts +0 -0
  44. /package/dist/{types/auth → auth}/pairing/WaPairingFlow.d.ts +0 -0
  45. /package/dist/{types/auth → auth}/pairing/WaQrFlow.d.ts +0 -0
  46. /package/dist/{types/auth → auth}/pairing/pairing-code-crypto.d.ts +0 -0
  47. /package/dist/{types/auth → auth}/types.d.ts +0 -0
  48. /package/dist/{types/client → client}/WaClient.d.ts +0 -0
  49. /package/dist/{types/client → client}/WaClientFactory.d.ts +0 -0
  50. /package/dist/{types/client → client}/connection/WaConnectionManager.d.ts +0 -0
  51. /package/dist/{types/client → client}/connection/WaReceiptQueue.d.ts +0 -0
  52. /package/dist/{types/client → client}/coordinators/WaAbPropsCoordinator.d.ts +0 -0
  53. /package/dist/{types/client → client}/coordinators/WaAppStateMutationCoordinator.d.ts +0 -0
  54. /package/dist/{types/client → client}/coordinators/WaBotCoordinator.d.ts +0 -0
  55. /package/dist/{types/client → client}/coordinators/WaBroadcastListCoordinator.d.ts +0 -0
  56. /package/dist/{types/client → client}/coordinators/WaBusinessCoordinator.d.ts +0 -0
  57. /package/dist/{types/client → client}/coordinators/WaEmailCoordinator.d.ts +0 -0
  58. /package/dist/{types/client → client}/coordinators/WaGroupCoordinator.d.ts +0 -0
  59. /package/dist/{types/client → client}/coordinators/WaIncomingNodeCoordinator.d.ts +0 -0
  60. /package/dist/{types/client → client}/coordinators/WaLowLevelCoordinator.d.ts +0 -0
  61. /package/dist/{types/client → client}/coordinators/WaMessageCoordinator.d.ts +0 -0
  62. /package/dist/{types/client → client}/coordinators/WaMessageDispatchCoordinator.d.ts +0 -0
  63. /package/dist/{types/client → client}/coordinators/WaNewsletterCoordinator.d.ts +0 -0
  64. /package/dist/{types/client → client}/coordinators/WaOfflineResumeCoordinator.d.ts +0 -0
  65. /package/dist/{types/client → client}/coordinators/WaPassiveTasksCoordinator.d.ts +0 -0
  66. /package/dist/{types/client → client}/coordinators/WaPresenceCoordinator.d.ts +0 -0
  67. /package/dist/{types/client → client}/coordinators/WaPrivacyCoordinator.d.ts +0 -0
  68. /package/dist/{types/client → client}/coordinators/WaProfileCoordinator.d.ts +0 -0
  69. /package/dist/{types/client → client}/coordinators/WaRetryCoordinator.d.ts +0 -0
  70. /package/dist/{types/client → client}/coordinators/WaStatusCoordinator.d.ts +0 -0
  71. /package/dist/{types/client → client}/coordinators/WaStreamControlCoordinator.d.ts +0 -0
  72. /package/dist/{types/client → client}/coordinators/WaTrustedContactTokenCoordinator.d.ts +0 -0
  73. /package/dist/{types/client → client}/events/abprops.d.ts +0 -0
  74. /package/dist/{types/client → client}/events/appstate-mutation.d.ts +0 -0
  75. /package/dist/{types/client → client}/events/business.d.ts +0 -0
  76. /package/dist/{types/client → client}/events/call.d.ts +0 -0
  77. /package/dist/{types/client → client}/events/chatstate.d.ts +0 -0
  78. /package/dist/{types/client → client}/events/devices.d.ts +0 -0
  79. /package/dist/{types/client → client}/events/dirty.d.ts +0 -0
  80. /package/dist/{types/client → client}/events/group.d.ts +0 -0
  81. /package/dist/{types/client → client}/events/identity.d.ts +0 -0
  82. /package/dist/{types/client → client}/events/incoming.d.ts +0 -0
  83. /package/dist/{types/client → client}/events/mex-notification.d.ts +0 -0
  84. /package/dist/{types/client → client}/events/picture.d.ts +0 -0
  85. /package/dist/{types/client → client}/events/presence.d.ts +0 -0
  86. /package/dist/{types/client → client}/events/privacy-token.d.ts +0 -0
  87. /package/dist/{types/client → client}/events/registration.d.ts +0 -0
  88. /package/dist/{types/client → client}/index.d.ts +0 -0
  89. /package/dist/{types/client → client}/messaging/fanout.d.ts +0 -0
  90. /package/dist/{types/client → client}/messaging/group-metadata.d.ts +0 -0
  91. /package/dist/{types/client → client}/messaging/ignore-key.d.ts +0 -0
  92. /package/dist/{types/client → client}/messaging/key-protocol.d.ts +0 -0
  93. /package/dist/{types/client → client}/messaging/link-preview.d.ts +0 -0
  94. /package/dist/{types/client → client}/messaging/messages.d.ts +0 -0
  95. /package/dist/{types/client → client}/newsletter/admin.d.ts +0 -0
  96. /package/dist/{types/client → client}/newsletter/content.d.ts +0 -0
  97. /package/dist/{types/client → client}/newsletter/discovery.d.ts +0 -0
  98. /package/dist/{types/client → client}/newsletter/messaging.d.ts +0 -0
  99. /package/dist/{types/client → client}/newsletter/mex.d.ts +0 -0
  100. /package/dist/{types/client → client}/newsletter/parse.d.ts +0 -0
  101. /package/dist/{types/client → client}/newsletter/types.d.ts +0 -0
  102. /package/dist/{types/client → client}/persistence/WriteBehindPersistence.d.ts +0 -0
  103. /package/dist/{types/client → client}/persistence/history-sync.d.ts +0 -0
  104. /package/dist/{types/client → client}/persistence/mailbox.d.ts +0 -0
  105. /package/dist/{types/client → client}/tokens/cs-token.d.ts +0 -0
  106. /package/dist/{types/client → client}/tokens/tc-token.d.ts +0 -0
  107. /package/dist/{types/crypto → crypto}/core/hkdf.d.ts +0 -0
  108. /package/dist/{types/crypto → crypto}/core/index.d.ts +0 -0
  109. /package/dist/{types/crypto → crypto}/core/keys.d.ts +0 -0
  110. /package/dist/{types/crypto → crypto}/core/nonce.d.ts +0 -0
  111. /package/dist/{types/crypto → crypto}/core/primitives.d.ts +0 -0
  112. /package/dist/{types/crypto → crypto}/core/random.d.ts +0 -0
  113. /package/dist/{types/crypto → crypto}/core/xeddsa.d.ts +0 -0
  114. /package/dist/{types/crypto → crypto}/curves/Ed25519.d.ts +0 -0
  115. /package/dist/{types/crypto → crypto}/curves/X25519.d.ts +0 -0
  116. /package/dist/{types/crypto → crypto}/curves/constants.d.ts +0 -0
  117. /package/dist/{types/crypto → crypto}/curves/types.d.ts +0 -0
  118. /package/dist/{types/crypto → crypto}/index.d.ts +0 -0
  119. /package/dist/{types/crypto → crypto}/math/constants.d.ts +0 -0
  120. /package/dist/{types/crypto → crypto}/math/edwards.d.ts +0 -0
  121. /package/dist/{types/crypto → crypto}/math/fe.d.ts +0 -0
  122. /package/dist/{types/crypto → crypto}/math/le.d.ts +0 -0
  123. /package/dist/{types/crypto → crypto}/math/mod.d.ts +0 -0
  124. /package/dist/{types/crypto → crypto}/math/types.d.ts +0 -0
  125. /package/dist/{types/infra → infra}/log/ConsoleLogger.d.ts +0 -0
  126. /package/dist/{types/infra → infra}/log/PinoLogger.d.ts +0 -0
  127. /package/dist/{types/infra → infra}/log/types.d.ts +0 -0
  128. /package/dist/{types/infra → infra}/perf/BackgroundQueue.d.ts +0 -0
  129. /package/dist/{types/infra → infra}/perf/BoundedTaskQueue.d.ts +0 -0
  130. /package/dist/{types/infra → infra}/perf/PromiseDedup.d.ts +0 -0
  131. /package/dist/{types/infra → infra}/perf/SharedExclusiveGate.d.ts +0 -0
  132. /package/dist/{types/infra → infra}/perf/StoreLock.d.ts +0 -0
  133. /package/dist/{types/media → media}/constants.d.ts +0 -0
  134. /package/dist/{types/media → media}/crypto/WaMediaCrypto.d.ts +0 -0
  135. /package/dist/{types/media → media}/index.d.ts +0 -0
  136. /package/dist/{types/media → media}/processor.d.ts +0 -0
  137. /package/dist/{types/media → media}/sticker/sticker-pack.d.ts +0 -0
  138. /package/dist/{types/media → media}/transfer/WaMediaTransferClient.d.ts +0 -0
  139. /package/dist/{types/media → media}/transfer/conn.d.ts +0 -0
  140. /package/dist/{types/media → media}/types.d.ts +0 -0
  141. /package/dist/{types/message → message}/WaMessageClient.d.ts +0 -0
  142. /package/dist/{types/message → message}/addons/link-preview/builder.d.ts +0 -0
  143. /package/dist/{types/message → message}/addons/link-preview/detect.d.ts +0 -0
  144. /package/dist/{types/message → message}/addons/link-preview/fetcher.d.ts +0 -0
  145. /package/dist/{types/message → message}/addons/link-preview/types.d.ts +0 -0
  146. /package/dist/{types/message → message}/crypto/addon-crypto.d.ts +0 -0
  147. /package/dist/{types/message → message}/crypto/icdc.d.ts +0 -0
  148. /package/dist/{types/message → message}/crypto/phash.d.ts +0 -0
  149. /package/dist/{types/message → message}/crypto/reporting-token.d.ts +0 -0
  150. /package/dist/{types/message → message}/crypto/use-case-secret.d.ts +0 -0
  151. /package/dist/{types/message → message}/encode/content.d.ts +0 -0
  152. /package/dist/{types/message → message}/encode/device-sent.d.ts +0 -0
  153. /package/dist/{types/message → message}/encode/padding.d.ts +0 -0
  154. /package/dist/{types/message → message}/index.d.ts +0 -0
  155. /package/dist/{types/message → message}/kinds/bot.d.ts +0 -0
  156. /package/dist/{types/message → message}/kinds/newsletter.d.ts +0 -0
  157. /package/dist/{types/message → message}/kinds/sticker-pack.d.ts +0 -0
  158. /package/dist/{types/message → message}/primitives/ack.d.ts +0 -0
  159. /package/dist/{types/message → message}/primitives/incoming.d.ts +0 -0
  160. /package/dist/{types/message → message}/primitives/peer-data-operation.d.ts +0 -0
  161. /package/dist/{types/message → message}/types.d.ts +0 -0
  162. /package/dist/{types/mex.d.ts → mex.d.ts} +0 -0
  163. /package/dist/{types/proto.d.ts → proto.d.ts} +0 -0
  164. /package/dist/{types/protocol → protocol}/abprops.d.ts +0 -0
  165. /package/dist/{types/protocol → protocol}/appstate.d.ts +0 -0
  166. /package/dist/{types/protocol → protocol}/auth.d.ts +0 -0
  167. /package/dist/{types/protocol → protocol}/bot.d.ts +0 -0
  168. /package/dist/{types/protocol → protocol}/browser.d.ts +0 -0
  169. /package/dist/{types/protocol → protocol}/business.d.ts +0 -0
  170. /package/dist/{types/protocol → protocol}/call.d.ts +0 -0
  171. /package/dist/{types/protocol → protocol}/constants.d.ts +0 -0
  172. /package/dist/{types/protocol → protocol}/defaults.d.ts +0 -0
  173. /package/dist/{types/protocol → protocol}/dirty.d.ts +0 -0
  174. /package/dist/{types/protocol → protocol}/email.d.ts +0 -0
  175. /package/dist/{types/protocol → protocol}/group.d.ts +0 -0
  176. /package/dist/{types/protocol → protocol}/index.d.ts +0 -0
  177. /package/dist/{types/protocol → protocol}/jid.d.ts +0 -0
  178. /package/dist/{types/protocol → protocol}/media.d.ts +0 -0
  179. /package/dist/{types/protocol → protocol}/newsletter.d.ts +0 -0
  180. /package/dist/{types/protocol → protocol}/nodes.d.ts +0 -0
  181. /package/dist/{types/protocol → protocol}/notification.d.ts +0 -0
  182. /package/dist/{types/protocol → protocol}/presence.d.ts +0 -0
  183. /package/dist/{types/protocol → protocol}/privacy-token.d.ts +0 -0
  184. /package/dist/{types/protocol → protocol}/privacy.d.ts +0 -0
  185. /package/dist/{types/protocol → protocol}/status.d.ts +0 -0
  186. /package/dist/{types/protocol → protocol}/stream.d.ts +0 -0
  187. /package/dist/{types/protocol → protocol}/usync.d.ts +0 -0
  188. /package/dist/{types/retry → retry}/codec.d.ts +0 -0
  189. /package/dist/{types/retry → retry}/constants.d.ts +0 -0
  190. /package/dist/{types/retry → retry}/index.d.ts +0 -0
  191. /package/dist/{types/retry → retry}/parse.d.ts +0 -0
  192. /package/dist/{types/retry → retry}/reason.d.ts +0 -0
  193. /package/dist/{types/retry → retry}/replay.d.ts +0 -0
  194. /package/dist/{types/retry → retry}/tracker.d.ts +0 -0
  195. /package/dist/{types/retry → retry}/types.d.ts +0 -0
  196. /package/dist/{types/signal → signal}/api/SignalDeviceSyncApi.d.ts +0 -0
  197. /package/dist/{types/signal → signal}/api/SignalDigestSyncApi.d.ts +0 -0
  198. /package/dist/{types/signal → signal}/api/SignalIdentitySyncApi.d.ts +0 -0
  199. /package/dist/{types/signal → signal}/api/SignalMissingPreKeysSyncApi.d.ts +0 -0
  200. /package/dist/{types/signal → signal}/api/SignalRotateKeyApi.d.ts +0 -0
  201. /package/dist/{types/signal → signal}/api/SignalSessionSyncApi.d.ts +0 -0
  202. /package/dist/{types/signal → signal}/api/codec.d.ts +0 -0
  203. /package/dist/{types/signal → signal}/api/constants.d.ts +0 -0
  204. /package/dist/{types/signal → signal}/api/prekeys.d.ts +0 -0
  205. /package/dist/{types/signal → signal}/api/result-map.d.ts +0 -0
  206. /package/dist/{types/signal → signal}/attestation/WaAdvSignature.d.ts +0 -0
  207. /package/dist/{types/signal → signal}/attestation/constants.d.ts +0 -0
  208. /package/dist/{types/signal → signal}/constants.d.ts +0 -0
  209. /package/dist/{types/signal → signal}/encoding.d.ts +0 -0
  210. /package/dist/{types/signal → signal}/group/SenderKeyChain.d.ts +0 -0
  211. /package/dist/{types/signal → signal}/group/SenderKeyCodec.d.ts +0 -0
  212. /package/dist/{types/signal → signal}/group/SenderKeyManager.d.ts +0 -0
  213. /package/dist/{types/signal → signal}/group/encoding.d.ts +0 -0
  214. /package/dist/{types/signal → signal}/index.d.ts +0 -0
  215. /package/dist/{types/signal → signal}/registration/encoding.d.ts +0 -0
  216. /package/dist/{types/signal → signal}/registration/keygen.d.ts +0 -0
  217. /package/dist/{types/signal → signal}/registration/utils.d.ts +0 -0
  218. /package/dist/{types/signal → signal}/session/SignalProtocol.d.ts +0 -0
  219. /package/dist/{types/signal → signal}/session/SignalRatchet.d.ts +0 -0
  220. /package/dist/{types/signal → signal}/session/SignalSerializer.d.ts +0 -0
  221. /package/dist/{types/signal → signal}/session/SignalSession.d.ts +0 -0
  222. /package/dist/{types/signal → signal}/session/encoding.d.ts +0 -0
  223. /package/dist/{types/signal → signal}/session/resolver.d.ts +0 -0
  224. /package/dist/{types/signal → signal}/types.d.ts +0 -0
  225. /package/dist/{types/store → store}/cache/identity.cache.d.ts +0 -0
  226. /package/dist/{types/store → store}/cache/privacy-token.cache.d.ts +0 -0
  227. /package/dist/{types/store → store}/cache/sender-key.cache.d.ts +0 -0
  228. /package/dist/{types/store → store}/cache/session.cache.d.ts +0 -0
  229. /package/dist/{types/store → store}/contracts/appstate.store.d.ts +0 -0
  230. /package/dist/{types/store → store}/contracts/auth.store.d.ts +0 -0
  231. /package/dist/{types/store → store}/contracts/contact.store.d.ts +0 -0
  232. /package/dist/{types/store → store}/contracts/device-list.store.d.ts +0 -0
  233. /package/dist/{types/store → store}/contracts/group-metadata.store.d.ts +0 -0
  234. /package/dist/{types/store → store}/contracts/identity.store.d.ts +0 -0
  235. /package/dist/{types/store → store}/contracts/message-secret.store.d.ts +0 -0
  236. /package/dist/{types/store → store}/contracts/message.store.d.ts +0 -0
  237. /package/dist/{types/store → store}/contracts/pre-key.store.d.ts +0 -0
  238. /package/dist/{types/store → store}/contracts/privacy-token.store.d.ts +0 -0
  239. /package/dist/{types/store → store}/contracts/retry.store.d.ts +0 -0
  240. /package/dist/{types/store → store}/contracts/sender-key.store.d.ts +0 -0
  241. /package/dist/{types/store → store}/contracts/session.store.d.ts +0 -0
  242. /package/dist/{types/store → store}/contracts/signal.store.d.ts +0 -0
  243. /package/dist/{types/store → store}/contracts/thread.store.d.ts +0 -0
  244. /package/dist/{types/store → store}/createStore.d.ts +0 -0
  245. /package/dist/{types/store → store}/index.d.ts +0 -0
  246. /package/dist/{types/store → store}/locks/appstate.lock.d.ts +0 -0
  247. /package/dist/{types/store → store}/locks/auth.lock.d.ts +0 -0
  248. /package/dist/{types/store → store}/locks/contact.lock.d.ts +0 -0
  249. /package/dist/{types/store → store}/locks/device-list.lock.d.ts +0 -0
  250. /package/dist/{types/store → store}/locks/group-metadata.lock.d.ts +0 -0
  251. /package/dist/{types/store → store}/locks/identity.lock.d.ts +0 -0
  252. /package/dist/{types/store → store}/locks/message-secret.lock.d.ts +0 -0
  253. /package/dist/{types/store → store}/locks/message.lock.d.ts +0 -0
  254. /package/dist/{types/store → store}/locks/pre-key.lock.d.ts +0 -0
  255. /package/dist/{types/store → store}/locks/privacy-token.lock.d.ts +0 -0
  256. /package/dist/{types/store → store}/locks/retry.lock.d.ts +0 -0
  257. /package/dist/{types/store → store}/locks/sender-key.lock.d.ts +0 -0
  258. /package/dist/{types/store → store}/locks/session.lock.d.ts +0 -0
  259. /package/dist/{types/store → store}/locks/signal.lock.d.ts +0 -0
  260. /package/dist/{types/store → store}/locks/thread.lock.d.ts +0 -0
  261. /package/dist/{types/store → store}/memory/appstate.store.d.ts +0 -0
  262. /package/dist/{types/store → store}/memory/auth.store.d.ts +0 -0
  263. /package/dist/{types/store → store}/memory/contact.store.d.ts +0 -0
  264. /package/dist/{types/store → store}/memory/device-list.store.d.ts +0 -0
  265. /package/dist/{types/store → store}/memory/group-metadata.store.d.ts +0 -0
  266. /package/dist/{types/store → store}/memory/identity.store.d.ts +0 -0
  267. /package/dist/{types/store → store}/memory/message-secret.store.d.ts +0 -0
  268. /package/dist/{types/store → store}/memory/message.store.d.ts +0 -0
  269. /package/dist/{types/store → store}/memory/pre-key.store.d.ts +0 -0
  270. /package/dist/{types/store → store}/memory/privacy-token.store.d.ts +0 -0
  271. /package/dist/{types/store → store}/memory/retry.store.d.ts +0 -0
  272. /package/dist/{types/store → store}/memory/sender-key.store.d.ts +0 -0
  273. /package/dist/{types/store → store}/memory/session.store.d.ts +0 -0
  274. /package/dist/{types/store → store}/memory/signal.store.d.ts +0 -0
  275. /package/dist/{types/store → store}/memory/thread.store.d.ts +0 -0
  276. /package/dist/{types/store → store}/noop.store.d.ts +0 -0
  277. /package/dist/{types/store → store}/types.d.ts +0 -0
  278. /package/dist/{types/transport → transport}/WaComms.d.ts +0 -0
  279. /package/dist/{types/transport → transport}/WaWebSocket.d.ts +0 -0
  280. /package/dist/{types/transport → transport}/binary/constants.d.ts +0 -0
  281. /package/dist/{types/transport → transport}/binary/decoder.d.ts +0 -0
  282. /package/dist/{types/transport → transport}/binary/encoder.d.ts +0 -0
  283. /package/dist/{types/transport → transport}/binary/index.d.ts +0 -0
  284. /package/dist/{types/transport → transport}/binary/tokens.d.ts +0 -0
  285. /package/dist/{types/transport → transport}/index.d.ts +0 -0
  286. /package/dist/{types/transport → transport}/keepalive/WaKeepAlive.d.ts +0 -0
  287. /package/dist/{types/transport → transport}/node/WaMobileTcpSocket.d.ts +0 -0
  288. /package/dist/{types/transport → transport}/node/WaNodeOrchestrator.d.ts +0 -0
  289. /package/dist/{types/transport → transport}/node/WaNodeTransport.d.ts +0 -0
  290. /package/dist/{types/transport → transport}/node/builders/abprops.d.ts +0 -0
  291. /package/dist/{types/transport → transport}/node/builders/account-sync.d.ts +0 -0
  292. /package/dist/{types/transport → transport}/node/builders/bot.d.ts +0 -0
  293. /package/dist/{types/transport → transport}/node/builders/business.d.ts +0 -0
  294. /package/dist/{types/transport → transport}/node/builders/chatstate.d.ts +0 -0
  295. /package/dist/{types/transport → transport}/node/builders/community.d.ts +0 -0
  296. /package/dist/{types/transport → transport}/node/builders/device.d.ts +0 -0
  297. /package/dist/{types/transport → transport}/node/builders/email.d.ts +0 -0
  298. /package/dist/{types/transport → transport}/node/builders/global.d.ts +0 -0
  299. /package/dist/{types/transport → transport}/node/builders/group.d.ts +0 -0
  300. /package/dist/{types/transport → transport}/node/builders/media.d.ts +0 -0
  301. /package/dist/{types/transport → transport}/node/builders/message.d.ts +0 -0
  302. /package/dist/{types/transport → transport}/node/builders/newsletter.d.ts +0 -0
  303. /package/dist/{types/transport → transport}/node/builders/offline.d.ts +0 -0
  304. /package/dist/{types/transport → transport}/node/builders/pairing.d.ts +0 -0
  305. /package/dist/{types/transport → transport}/node/builders/passive.d.ts +0 -0
  306. /package/dist/{types/transport → transport}/node/builders/prekeys.d.ts +0 -0
  307. /package/dist/{types/transport → transport}/node/builders/presence.d.ts +0 -0
  308. /package/dist/{types/transport → transport}/node/builders/privacy-token.d.ts +0 -0
  309. /package/dist/{types/transport → transport}/node/builders/privacy.d.ts +0 -0
  310. /package/dist/{types/transport → transport}/node/builders/profile.d.ts +0 -0
  311. /package/dist/{types/transport → transport}/node/builders/retry.d.ts +0 -0
  312. /package/dist/{types/transport → transport}/node/builders/tos.d.ts +0 -0
  313. /package/dist/{types/transport → transport}/node/builders/usync.d.ts +0 -0
  314. /package/dist/{types/transport → transport}/node/helpers.d.ts +0 -0
  315. /package/dist/{types/transport → transport}/node/mex/argo-decoder.d.ts +0 -0
  316. /package/dist/{types/transport → transport}/node/mex/client.d.ts +0 -0
  317. /package/dist/{types/transport → transport}/node/query.d.ts +0 -0
  318. /package/dist/{types/transport → transport}/node/usync.d.ts +0 -0
  319. /package/dist/{types/transport → transport}/node/xml.d.ts +0 -0
  320. /package/dist/{types/transport → transport}/noise/WaClientPayload.d.ts +0 -0
  321. /package/dist/{types/transport → transport}/noise/WaFrameCodec.d.ts +0 -0
  322. /package/dist/{types/transport → transport}/noise/WaMobileClientPayload.d.ts +0 -0
  323. /package/dist/{types/transport → transport}/noise/WaNoiseCert.d.ts +0 -0
  324. /package/dist/{types/transport → transport}/noise/WaNoiseHandshake.d.ts +0 -0
  325. /package/dist/{types/transport → transport}/noise/WaNoiseSession.d.ts +0 -0
  326. /package/dist/{types/transport → transport}/noise/WaNoiseSocket.d.ts +0 -0
  327. /package/dist/{types/transport → transport}/noise/constants.d.ts +0 -0
  328. /package/dist/{types/transport → transport}/noise/types.d.ts +0 -0
  329. /package/dist/{types/transport → transport}/proxy.d.ts +0 -0
  330. /package/dist/{types/transport → transport}/stream/parse.d.ts +0 -0
  331. /package/dist/{types/transport → transport}/types.d.ts +0 -0
  332. /package/dist/{types/transport → transport}/wa-web-version-fetcher.d.ts +0 -0
  333. /package/dist/{types/util → util}/async.d.ts +0 -0
  334. /package/dist/{types/util → util}/bytes.d.ts +0 -0
  335. /package/dist/{types/util → util}/clock.d.ts +0 -0
  336. /package/dist/{types/util → util}/coercion.d.ts +0 -0
  337. /package/dist/{types/util → util}/collections.d.ts +0 -0
  338. /package/dist/{types/util → util}/index.d.ts +0 -0
  339. /package/dist/{types/util → util}/primitives.d.ts +0 -0
  340. /package/dist/{types/util → util}/runtime.d.ts +0 -0
  341. /package/dist/{types/version-spec.d.ts → version-spec.d.ts} +0 -0
@@ -4,9 +4,9 @@ exports.WaMessageCoordinator = void 0;
4
4
  const node_fs_1 = require("node:fs");
5
5
  const promises_1 = require("node:stream/promises");
6
6
  const receipt_1 = require("../events/receipt");
7
+ const media_1 = require("../media");
7
8
  const addon_crypto_1 = require("../../message/crypto/addon-crypto");
8
9
  const content_1 = require("../../message/encode/content");
9
- const media_payload_1 = require("../../message/encode/media-payload");
10
10
  const _proto_1 = require("../../proto");
11
11
  const jid_1 = require("../../protocol/jid");
12
12
  const client_1 = require("../../transport/node/mex/client");
@@ -235,23 +235,7 @@ class WaMessageCoordinator {
235
235
  * for one-shot verified downloads.
236
236
  */
237
237
  async download(source, options = {}) {
238
- const message = 'rawNode' in source ? source.message : source;
239
- const payload = (0, media_payload_1.resolveMediaPayload)(message);
240
- if (!payload) {
241
- throw new Error('message has no downloadable media');
242
- }
243
- const { plaintext, metadata } = await this.mediaTransfer.downloadAndDecryptStream({
244
- directPath: payload.directPath,
245
- mediaType: payload.mediaType,
246
- mediaKey: payload.mediaKey,
247
- fileSha256: payload.fileSha256,
248
- fileEncSha256: payload.fileEncSha256,
249
- timeoutMs: options.timeoutMs,
250
- signal: options.signal,
251
- maxBytes: options.maxBytes
252
- });
253
- metadata.catch(() => undefined);
254
- return plaintext;
238
+ return (0, media_1.downloadMediaMessage)(source, { ...options, transfer: this.mediaTransfer });
255
239
  }
256
240
  /**
257
241
  * Convenience wrapper around {@link download} that streams the decrypted
@@ -164,7 +164,8 @@ class WaMessageDispatchCoordinator {
164
164
  quote: options.quote,
165
165
  forward: options.forward,
166
166
  mentions: options.mentions,
167
- meLid: this.deps.getCurrentCredentials()?.meLid
167
+ meLid: this.deps.getCurrentCredentials()?.meLid,
168
+ targetJid: recipientJid
168
169
  });
169
170
  const withCtx = ctx ? (0, context_info_1.applyContextInfo)(built.message, ctx) : built.message;
170
171
  const withViewOnce = options.viewOnce ? (0, content_1.wrapAsViewOnce)(withCtx) : withCtx;
@@ -18,6 +18,7 @@ const call_1 = require("../events/call");
18
18
  const group_1 = require("../events/group");
19
19
  const mex_notification_1 = require("../events/mex-notification");
20
20
  const picture_1 = require("../events/picture");
21
+ const receipt_1 = require("../events/receipt");
21
22
  const registration_1 = require("../events/registration");
22
23
  const constants_1 = require("../../protocol/constants");
23
24
  const jid_1 = require("../../protocol/jid");
@@ -188,7 +189,8 @@ function createIncomingReceiptHandler(options) {
188
189
  status: mapped.status,
189
190
  fromSelfDevice: mapped.fromSelfDevice,
190
191
  participantJid: node.attrs.participant,
191
- recipientJid: node.attrs.recipient
192
+ recipientJid: node.attrs.recipient,
193
+ messageIds: (0, receipt_1.extractReceiptIds)(node)
192
194
  });
193
195
  }
194
196
  else if (node.attrs.type && !INTERNAL_ONLY_RECEIPT_TYPES.has(node.attrs.type)) {
@@ -0,0 +1,30 @@
1
+ import type { BinaryNode } from '../../transport/types';
2
+ interface ReceiptTarget {
3
+ readonly chatJid: string;
4
+ readonly id: string;
5
+ readonly senderJid?: string;
6
+ readonly isGroupChat?: boolean;
7
+ readonly isBroadcastChat?: boolean;
8
+ }
9
+ interface AggregatedReceiptGroup {
10
+ readonly jid: string;
11
+ readonly ids: readonly string[];
12
+ readonly participant?: string;
13
+ }
14
+ export declare function aggregateReceiptTargets(targets: readonly ReceiptTarget[]): readonly AggregatedReceiptGroup[];
15
+ /**
16
+ * Resolves every message id a `<receipt>` acknowledges, mirroring WhatsApp
17
+ * Web's `externalIds`. A batch receipt carries the extra ids in a
18
+ * `<list><item id=.../>` block; the top-level `attrs.id` is just one of them.
19
+ *
20
+ * - `<list><item>` ids come first. For `type="view"` receipts the item key is
21
+ * `server_id` (not `id`), and the top-level id is NOT appended.
22
+ * - Otherwise the top-level `attrs.id` is appended last.
23
+ * - Aggregated receipts (carrying a `<participants>` child) are out of scope:
24
+ * their ids live in `<user>` children, so this falls back to the single
25
+ * top-level id for them.
26
+ *
27
+ * No dedup: matches wa-web, which pushes the top id without checking the list.
28
+ */
29
+ export declare function extractReceiptIds(node: BinaryNode): readonly string[];
30
+ export {};
@@ -1,7 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.aggregateReceiptTargets = aggregateReceiptTargets;
4
+ exports.extractReceiptIds = extractReceiptIds;
5
+ const constants_1 = require("../../protocol/constants");
4
6
  const jid_1 = require("../../protocol/jid");
7
+ const helpers_1 = require("../../transport/node/helpers");
5
8
  function needsParticipant(target) {
6
9
  if (target.isGroupChat !== undefined || target.isBroadcastChat !== undefined) {
7
10
  return target.isGroupChat === true || target.isBroadcastChat === true;
@@ -24,3 +27,32 @@ function aggregateReceiptTargets(targets) {
24
27
  }
25
28
  return [...groups.values()];
26
29
  }
30
+ /**
31
+ * Resolves every message id a `<receipt>` acknowledges, mirroring WhatsApp
32
+ * Web's `externalIds`. A batch receipt carries the extra ids in a
33
+ * `<list><item id=.../>` block; the top-level `attrs.id` is just one of them.
34
+ *
35
+ * - `<list><item>` ids come first. For `type="view"` receipts the item key is
36
+ * `server_id` (not `id`), and the top-level id is NOT appended.
37
+ * - Otherwise the top-level `attrs.id` is appended last.
38
+ * - Aggregated receipts (carrying a `<participants>` child) are out of scope:
39
+ * their ids live in `<user>` children, so this falls back to the single
40
+ * top-level id for them.
41
+ *
42
+ * No dedup: matches wa-web, which pushes the top id without checking the list.
43
+ */
44
+ function extractReceiptIds(node) {
45
+ const topId = node.attrs.id;
46
+ if ((0, helpers_1.hasNodeChild)(node, 'participants')) {
47
+ return topId ? [topId] : [];
48
+ }
49
+ const isView = node.attrs.type === constants_1.WA_MESSAGE_TYPES.RECEIPT_TYPE_VIEW;
50
+ const list = (0, helpers_1.findNodeChild)(node, 'list');
51
+ const ids = list
52
+ ? [...(0, helpers_1.getNodeChildrenNonEmptyAttrValuesByTag)(list, 'item', isView ? 'server_id' : 'id')]
53
+ : [];
54
+ if (!isView && topId) {
55
+ ids.push(topId);
56
+ }
57
+ return ids;
58
+ }
@@ -1,9 +1,11 @@
1
1
  import { type Readable } from 'node:stream';
2
- import type { WaMediaOptions } from './types';
2
+ import type { WaDownloadMediaOptions, WaIncomingMessageEvent, WaMediaOptions } from './types';
3
3
  import type { Logger } from '../infra/log/types';
4
- import type { WaMediaTransferClient } from '../media/transfer/WaMediaTransferClient';
4
+ import { WaMediaTransferClient } from '../media/transfer/WaMediaTransferClient';
5
5
  import type { WaMediaConn } from '../media/types';
6
6
  import type { WaSendMediaMessage } from '../message/types';
7
+ import type { Proto } from '../proto';
8
+ import type { WaProxyTransport } from '../transport/types';
7
9
  export interface ProcessedMediaFields {
8
10
  readonly jpegThumbnail?: Uint8Array;
9
11
  readonly pngThumbnail?: Uint8Array;
@@ -62,4 +64,59 @@ export declare function shouldNormalizeVoiceNote(media: WaMediaOptions | undefin
62
64
  export declare function hasMediaProcessingTasks(media: WaMediaOptions | undefined, content: WaSendMediaMessage): boolean;
63
65
  export declare function getScopedMediaLogger(parent: Logger): Logger;
64
66
  export declare function runMediaProcessor(media: WaMediaOptions | undefined, input: Uint8Array | string | undefined, content: WaSendMediaMessage, logger: Logger): Promise<ProcessedMediaFields>;
67
+ export interface WaDownloadMediaMessageOptions extends WaDownloadMediaOptions {
68
+ /**
69
+ * Reuse an existing transfer client instead of creating a fresh one. Lets
70
+ * the download inherit proxy agents, timeouts, and the MAC-verification
71
+ * toggle, and avoids spinning up a new HTTP client per call in a loop. A
72
+ * stateless {@link WaMediaTransferClient} is created when omitted - fine
73
+ * for one-off downloads.
74
+ */
75
+ readonly transfer?: WaMediaTransferClient;
76
+ /**
77
+ * Proxy for the CDN download leg, mirroring `proxy.mediaDownload` on the
78
+ * client. The fetch runs over `node:http`/`node:https`, so only the Node
79
+ * `http.Agent` form is used; an undici dispatcher is ignored (same as the
80
+ * client treats `mediaDownload`). Takes precedence over the default agent
81
+ * of a `transfer` you pass.
82
+ */
83
+ readonly proxy?: WaProxyTransport;
84
+ }
85
+ /**
86
+ * Streams and decrypts the media attached to a message without a connected
87
+ * `WaClient`. Resolves the encrypted payload (directPath, mediaKey, file
88
+ * hashes) from `source`, fetches the ciphertext from the WhatsApp media CDN,
89
+ * and decrypts it on the fly.
90
+ *
91
+ * The media keys come from the (already decrypted) message itself, so this is
92
+ * for re-downloading media you have persisted - not for fetching media you
93
+ * never received. The CDN download needs no session or auth token; only the
94
+ * upload path does.
95
+ *
96
+ * **The caller owns the returned stream** - pipe it somewhere or call
97
+ * `.destroy()` to release the socket; an unconsumed stream leaks the
98
+ * connection. MAC + SHA-256 verification runs as bytes are consumed, so
99
+ * aborting mid-read leaves you with unverified bytes. Pass `options.signal`
100
+ * to cancel cleanly.
101
+ *
102
+ * @throws when `source` carries no downloadable media.
103
+ * @example
104
+ * ```ts
105
+ * import { downloadMediaMessage } from '..'
106
+ * import { createWriteStream } from 'node:fs'
107
+ *
108
+ * const stream = await downloadMediaMessage(event)
109
+ * stream.pipe(createWriteStream('photo.jpg'))
110
+ * ```
111
+ * @example
112
+ * ```ts
113
+ * // Route the CDN download through an http.Agent-style proxy
114
+ * import { HttpsProxyAgent } from 'https-proxy-agent'
115
+ *
116
+ * const stream = await downloadMediaMessage(event, {
117
+ * proxy: new HttpsProxyAgent('http://127.0.0.1:8080')
118
+ * })
119
+ * ```
120
+ */
121
+ export declare function downloadMediaMessage(source: Proto.IMessage | WaIncomingMessageEvent, options?: WaDownloadMediaMessageOptions): Promise<Readable>;
65
122
  export {};
@@ -14,6 +14,7 @@ exports.shouldNormalizeVoiceNote = shouldNormalizeVoiceNote;
14
14
  exports.hasMediaProcessingTasks = hasMediaProcessingTasks;
15
15
  exports.getScopedMediaLogger = getScopedMediaLogger;
16
16
  exports.runMediaProcessor = runMediaProcessor;
17
+ exports.downloadMediaMessage = downloadMediaMessage;
17
18
  const node_crypto_1 = require("node:crypto");
18
19
  const node_fs_1 = require("node:fs");
19
20
  const promises_1 = require("node:fs/promises");
@@ -22,6 +23,9 @@ const node_path_1 = require("node:path");
22
23
  const node_stream_1 = require("node:stream");
23
24
  const promises_2 = require("node:stream/promises");
24
25
  const core_1 = require("../crypto/core");
26
+ const WaMediaTransferClient_1 = require("../media/transfer/WaMediaTransferClient");
27
+ const media_payload_1 = require("../message/encode/media-payload");
28
+ const proxy_1 = require("../transport/proxy");
25
29
  const bytes_1 = require("../util/bytes");
26
30
  const primitives_1 = require("../util/primitives");
27
31
  async function readFileHead(filePath, bytes) {
@@ -398,3 +402,59 @@ async function runMediaProcessor(media, input, content, logger) {
398
402
  }
399
403
  return result;
400
404
  }
405
+ /**
406
+ * Streams and decrypts the media attached to a message without a connected
407
+ * `WaClient`. Resolves the encrypted payload (directPath, mediaKey, file
408
+ * hashes) from `source`, fetches the ciphertext from the WhatsApp media CDN,
409
+ * and decrypts it on the fly.
410
+ *
411
+ * The media keys come from the (already decrypted) message itself, so this is
412
+ * for re-downloading media you have persisted - not for fetching media you
413
+ * never received. The CDN download needs no session or auth token; only the
414
+ * upload path does.
415
+ *
416
+ * **The caller owns the returned stream** - pipe it somewhere or call
417
+ * `.destroy()` to release the socket; an unconsumed stream leaks the
418
+ * connection. MAC + SHA-256 verification runs as bytes are consumed, so
419
+ * aborting mid-read leaves you with unverified bytes. Pass `options.signal`
420
+ * to cancel cleanly.
421
+ *
422
+ * @throws when `source` carries no downloadable media.
423
+ * @example
424
+ * ```ts
425
+ * import { downloadMediaMessage } from '..'
426
+ * import { createWriteStream } from 'node:fs'
427
+ *
428
+ * const stream = await downloadMediaMessage(event)
429
+ * stream.pipe(createWriteStream('photo.jpg'))
430
+ * ```
431
+ * @example
432
+ * ```ts
433
+ * // Route the CDN download through an http.Agent-style proxy
434
+ * import { HttpsProxyAgent } from 'https-proxy-agent'
435
+ *
436
+ * const stream = await downloadMediaMessage(event, {
437
+ * proxy: new HttpsProxyAgent('http://127.0.0.1:8080')
438
+ * })
439
+ * ```
440
+ */
441
+ async function downloadMediaMessage(source, options = {}) {
442
+ const message = 'rawNode' in source ? source.message : source;
443
+ const payload = (0, media_payload_1.resolveMediaPayload)(message);
444
+ if (!payload) {
445
+ throw new Error('message has no downloadable media');
446
+ }
447
+ const transfer = options.transfer ?? new WaMediaTransferClient_1.WaMediaTransferClient();
448
+ const { plaintext } = await transfer.downloadAndDecryptStream({
449
+ directPath: payload.directPath,
450
+ mediaType: payload.mediaType,
451
+ mediaKey: payload.mediaKey,
452
+ fileSha256: payload.fileSha256,
453
+ fileEncSha256: payload.fileEncSha256,
454
+ agent: (0, proxy_1.toProxyAgent)(options.proxy),
455
+ timeoutMs: options.timeoutMs,
456
+ signal: options.signal,
457
+ maxBytes: options.maxBytes
458
+ });
459
+ return plaintext;
460
+ }
@@ -512,6 +512,13 @@ export interface WaIncomingReceiptEvent extends WaIncomingBaseEvent {
512
512
  readonly fromSelfDevice: boolean;
513
513
  readonly participantJid?: string;
514
514
  readonly recipientJid?: string;
515
+ /**
516
+ * All message ids this receipt acknowledges. For batch read/delivery
517
+ * receipts this is the `<list><item>` ids plus the top-level `stanzaId`;
518
+ * for single receipts it is just `[stanzaId]`. Mirrors WhatsApp Web's
519
+ * `externalIds`.
520
+ */
521
+ readonly messageIds: readonly string[];
515
522
  }
516
523
  export interface WaIncomingPresenceEvent extends WaIncomingBaseEvent {
517
524
  readonly type: IncomingPresenceType;
@@ -1,6 +1,6 @@
1
1
  import { proto } from './proto.js';
2
- import { WA_APPSTATE_SCHEMAS as RAW_WA_APPSTATE_SCHEMAS } from '../spec/appstate';
3
- export { WA_APPSTATE_COLLECTIONS, WA_APPSTATE_SCHEMAS } from '../spec/appstate';
2
+ import { WA_APPSTATE_SCHEMAS as RAW_WA_APPSTATE_SCHEMAS } from '../../spec/appstate/index.js';
3
+ export { WA_APPSTATE_COLLECTIONS, WA_APPSTATE_SCHEMAS } from '../../spec/appstate/index.js';
4
4
  const SCHEMA_BY_ACTION_NAME_BUILDER = {};
5
5
  for (const key of Object.keys(RAW_WA_APPSTATE_SCHEMAS)) {
6
6
  SCHEMA_BY_ACTION_NAME_BUILDER[RAW_WA_APPSTATE_SCHEMAS[key].name] = key;
@@ -1,9 +1,9 @@
1
1
  import { createWriteStream } from 'node:fs';
2
2
  import { pipeline } from 'node:stream/promises';
3
3
  import { aggregateReceiptTargets } from '../events/receipt.js';
4
+ import { downloadMediaMessage } from '../media.js';
4
5
  import { buildAddonAdditionalData, decodeAddonPlaintext, decryptAddonPayload, identifyEncryptedAddon, resolveParentMessageSecret, resolvePollOptionNames, shouldUseAddonAdditionalData } from '../../message/crypto/addon-crypto.js';
5
6
  import { unwrapMessage } from '../../message/encode/content.js';
6
- import { resolveMediaPayload } from '../../message/encode/media-payload.js';
7
7
  import { proto } from '../../proto.js';
8
8
  import { applyDeviceToJid, normalizeRecipientJid } from '../../protocol/jid.js';
9
9
  import { runMexQuery } from '../../transport/node/mex/client.js';
@@ -232,23 +232,7 @@ export class WaMessageCoordinator {
232
232
  * for one-shot verified downloads.
233
233
  */
234
234
  async download(source, options = {}) {
235
- const message = 'rawNode' in source ? source.message : source;
236
- const payload = resolveMediaPayload(message);
237
- if (!payload) {
238
- throw new Error('message has no downloadable media');
239
- }
240
- const { plaintext, metadata } = await this.mediaTransfer.downloadAndDecryptStream({
241
- directPath: payload.directPath,
242
- mediaType: payload.mediaType,
243
- mediaKey: payload.mediaKey,
244
- fileSha256: payload.fileSha256,
245
- fileEncSha256: payload.fileEncSha256,
246
- timeoutMs: options.timeoutMs,
247
- signal: options.signal,
248
- maxBytes: options.maxBytes
249
- });
250
- metadata.catch(() => undefined);
251
- return plaintext;
235
+ return downloadMediaMessage(source, { ...options, transfer: this.mediaTransfer });
252
236
  }
253
237
  /**
254
238
  * Convenience wrapper around {@link download} that streams the decrypted
@@ -161,7 +161,8 @@ export class WaMessageDispatchCoordinator {
161
161
  quote: options.quote,
162
162
  forward: options.forward,
163
163
  mentions: options.mentions,
164
- meLid: this.deps.getCurrentCredentials()?.meLid
164
+ meLid: this.deps.getCurrentCredentials()?.meLid,
165
+ targetJid: recipientJid
165
166
  });
166
167
  const withCtx = ctx ? applyContextInfo(built.message, ctx) : built.message;
167
168
  const withViewOnce = options.viewOnce ? wrapAsViewOnce(withCtx) : withCtx;
@@ -3,6 +3,7 @@ import { parseCallNode } from '../events/call.js';
3
3
  import { parseGroupNotificationEvents } from '../events/group.js';
4
4
  import { parseMexNotification } from '../events/mex-notification.js';
5
5
  import { parsePictureNotificationEvents } from '../events/picture.js';
6
+ import { extractReceiptIds } from '../events/receipt.js';
6
7
  import { parseRegistrationNotification } from '../events/registration.js';
7
8
  import { WA_CALL_NODE_ATTRS, WA_CALL_RECEIPT_PAYLOAD_TAGS, WA_DISCONNECT_REASONS, WA_MESSAGE_TAGS, WA_MESSAGE_TYPES, WA_NODE_TAGS, WA_NOTIFICATION_TYPES } from '../../protocol/constants.js';
8
9
  import { isLidJid, normalizeDeviceJid, toUserJid } from '../../protocol/jid.js';
@@ -173,7 +174,8 @@ export function createIncomingReceiptHandler(options) {
173
174
  status: mapped.status,
174
175
  fromSelfDevice: mapped.fromSelfDevice,
175
176
  participantJid: node.attrs.participant,
176
- recipientJid: node.attrs.recipient
177
+ recipientJid: node.attrs.recipient,
178
+ messageIds: extractReceiptIds(node)
177
179
  });
178
180
  }
179
181
  else if (node.attrs.type && !INTERNAL_ONLY_RECEIPT_TYPES.has(node.attrs.type)) {
@@ -1,4 +1,6 @@
1
+ import { WA_MESSAGE_TYPES } from '../../protocol/constants.js';
1
2
  import { isGroupOrBroadcastJid } from '../../protocol/jid.js';
3
+ import { findNodeChild, getNodeChildrenNonEmptyAttrValuesByTag, hasNodeChild } from '../../transport/node/helpers.js';
2
4
  function needsParticipant(target) {
3
5
  if (target.isGroupChat !== undefined || target.isBroadcastChat !== undefined) {
4
6
  return target.isGroupChat === true || target.isBroadcastChat === true;
@@ -21,3 +23,32 @@ export function aggregateReceiptTargets(targets) {
21
23
  }
22
24
  return [...groups.values()];
23
25
  }
26
+ /**
27
+ * Resolves every message id a `<receipt>` acknowledges, mirroring WhatsApp
28
+ * Web's `externalIds`. A batch receipt carries the extra ids in a
29
+ * `<list><item id=.../>` block; the top-level `attrs.id` is just one of them.
30
+ *
31
+ * - `<list><item>` ids come first. For `type="view"` receipts the item key is
32
+ * `server_id` (not `id`), and the top-level id is NOT appended.
33
+ * - Otherwise the top-level `attrs.id` is appended last.
34
+ * - Aggregated receipts (carrying a `<participants>` child) are out of scope:
35
+ * their ids live in `<user>` children, so this falls back to the single
36
+ * top-level id for them.
37
+ *
38
+ * No dedup: matches wa-web, which pushes the top id without checking the list.
39
+ */
40
+ export function extractReceiptIds(node) {
41
+ const topId = node.attrs.id;
42
+ if (hasNodeChild(node, 'participants')) {
43
+ return topId ? [topId] : [];
44
+ }
45
+ const isView = node.attrs.type === WA_MESSAGE_TYPES.RECEIPT_TYPE_VIEW;
46
+ const list = findNodeChild(node, 'list');
47
+ const ids = list
48
+ ? [...getNodeChildrenNonEmptyAttrValuesByTag(list, 'item', isView ? 'server_id' : 'id')]
49
+ : [];
50
+ if (!isView && topId) {
51
+ ids.push(topId);
52
+ }
53
+ return ids;
54
+ }
@@ -6,6 +6,9 @@ import { join } from 'node:path';
6
6
  import { Transform } from 'node:stream';
7
7
  import { pipeline } from 'node:stream/promises';
8
8
  import { randomIntAsync, sha256 } from '../crypto/core/index.js';
9
+ import { WaMediaTransferClient } from '../media/transfer/WaMediaTransferClient.js';
10
+ import { resolveMediaPayload } from '../message/encode/media-payload.js';
11
+ import { toProxyAgent } from '../transport/proxy.js';
9
12
  import { bytesToBase64UrlSafe, TEXT_DECODER, toBytesView, toChunkBytes } from '../util/bytes.js';
10
13
  import { toError } from '../util/primitives.js';
11
14
  export async function readFileHead(filePath, bytes) {
@@ -382,3 +385,59 @@ export async function runMediaProcessor(media, input, content, logger) {
382
385
  }
383
386
  return result;
384
387
  }
388
+ /**
389
+ * Streams and decrypts the media attached to a message without a connected
390
+ * `WaClient`. Resolves the encrypted payload (directPath, mediaKey, file
391
+ * hashes) from `source`, fetches the ciphertext from the WhatsApp media CDN,
392
+ * and decrypts it on the fly.
393
+ *
394
+ * The media keys come from the (already decrypted) message itself, so this is
395
+ * for re-downloading media you have persisted - not for fetching media you
396
+ * never received. The CDN download needs no session or auth token; only the
397
+ * upload path does.
398
+ *
399
+ * **The caller owns the returned stream** - pipe it somewhere or call
400
+ * `.destroy()` to release the socket; an unconsumed stream leaks the
401
+ * connection. MAC + SHA-256 verification runs as bytes are consumed, so
402
+ * aborting mid-read leaves you with unverified bytes. Pass `options.signal`
403
+ * to cancel cleanly.
404
+ *
405
+ * @throws when `source` carries no downloadable media.
406
+ * @example
407
+ * ```ts
408
+ * import { downloadMediaMessage } from '..'
409
+ * import { createWriteStream } from 'node:fs'
410
+ *
411
+ * const stream = await downloadMediaMessage(event)
412
+ * stream.pipe(createWriteStream('photo.jpg'))
413
+ * ```
414
+ * @example
415
+ * ```ts
416
+ * // Route the CDN download through an http.Agent-style proxy
417
+ * import { HttpsProxyAgent } from 'https-proxy-agent'
418
+ *
419
+ * const stream = await downloadMediaMessage(event, {
420
+ * proxy: new HttpsProxyAgent('http://127.0.0.1:8080')
421
+ * })
422
+ * ```
423
+ */
424
+ export async function downloadMediaMessage(source, options = {}) {
425
+ const message = 'rawNode' in source ? source.message : source;
426
+ const payload = resolveMediaPayload(message);
427
+ if (!payload) {
428
+ throw new Error('message has no downloadable media');
429
+ }
430
+ const transfer = options.transfer ?? new WaMediaTransferClient();
431
+ const { plaintext } = await transfer.downloadAndDecryptStream({
432
+ directPath: payload.directPath,
433
+ mediaType: payload.mediaType,
434
+ mediaKey: payload.mediaKey,
435
+ fileSha256: payload.fileSha256,
436
+ fileEncSha256: payload.fileEncSha256,
437
+ agent: toProxyAgent(options.proxy),
438
+ timeoutMs: options.timeoutMs,
439
+ signal: options.signal,
440
+ maxBytes: options.maxBytes
441
+ });
442
+ return plaintext;
443
+ }
package/dist/esm/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  export { WaClient } from './client/index.js';
2
+ export { downloadMediaMessage } from './client/media.js';
2
3
  export { parseUsyncResultEnvelope } from './transport/node/builders/usync.js';
3
4
  export { getContentType, resolveMessageTarget } from './message/encode/content.js';
5
+ export { resolveMediaPayload } from './message/encode/media-payload.js';
4
6
  export { fetchLatestWaWebVersion } from './transport/wa-web-version-fetcher.js';
5
7
  export { ConsoleLogger } from './infra/log/ConsoleLogger.js';
6
8
  export { PinoLogger, createPinoLogger } from './infra/log/PinoLogger.js';
@@ -1,4 +1,4 @@
1
- import { isGroupOrBroadcastJid } from '../protocol/jid.js';
1
+ import { isGroupOrBroadcastJid, toUserJid } from '../protocol/jid.js';
2
2
  export function buildContextInfoProto(input) {
3
3
  const ctx = {};
4
4
  if (input.quotedMessageId !== undefined)
@@ -95,13 +95,23 @@ export function resolveSendContextInfo(input) {
95
95
  ctx.quotedMessageId = q.id ?? q.key?.id ?? ctx.quotedMessageId;
96
96
  const explicit = q.participant ?? q.key?.participant;
97
97
  const quotedRemote = q.remoteJid ?? q.key?.remoteJid;
98
+ const quotedFromMe = q.fromMe ?? q.key?.fromMe;
98
99
  const dmFallback = explicit === undefined && quotedRemote && !isGroupOrBroadcastJid(quotedRemote)
99
- ? q.key?.fromMe
100
+ ? quotedFromMe
100
101
  ? input.meLid
101
102
  : quotedRemote
102
103
  : undefined;
103
104
  ctx.quotedParticipant = explicit ?? dmFallback ?? ctx.quotedParticipant;
104
- ctx.quotedRemoteJid = quotedRemote ?? ctx.quotedRemoteJid;
105
+ const crossChat = quotedRemote !== undefined &&
106
+ (input.targetJid === undefined || !isSameChatJid(quotedRemote, input.targetJid));
107
+ if (quotedRemote !== undefined) {
108
+ if (crossChat) {
109
+ ctx.quotedRemoteJid = quotedRemote;
110
+ }
111
+ else {
112
+ delete ctx.quotedRemoteJid;
113
+ }
114
+ }
105
115
  ctx.quotedMessage = q.message ?? ctx.quotedMessage;
106
116
  }
107
117
  if (input.forward) {
@@ -121,3 +131,6 @@ function hasAnyKey(value) {
121
131
  }
122
132
  return false;
123
133
  }
134
+ function isSameChatJid(a, b) {
135
+ return toUserJid(a) === toUserJid(b);
136
+ }
@@ -20,6 +20,24 @@ function buildPayload(mediaType, fields) {
20
20
  fileLength: fields.fileLength ? longToNumber(fields.fileLength) : undefined
21
21
  };
22
22
  }
23
+ /**
24
+ * Extracts the downloadable media metadata from a message, unwrapping
25
+ * ephemeral / view-once / document-with-caption envelopes first.
26
+ *
27
+ * Returns `null` when `message` is absent, carries no media, or the media node
28
+ * lacks the `directPath` / `mediaKey` needed to fetch and decrypt the blob (a
29
+ * non-`Uint8Array` `mediaKey` also yields `null`). Supported kinds: image,
30
+ * video (gif when `gifPlayback`), audio (ptt when `ptt`), document, sticker,
31
+ * ptv.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * const payload = resolveMediaPayload(event.message)
36
+ * if (payload) {
37
+ * // payload.directPath, payload.mediaKey, payload.fileEncSha256, ...
38
+ * }
39
+ * ```
40
+ */
23
41
  export function resolveMediaPayload(message) {
24
42
  if (!message)
25
43
  return null;
package/dist/esm/mex.js CHANGED
@@ -1 +1 @@
1
- export { WA_MEX_PERSIST_IDS, WA_MEX_OPERATION_SCHEMAS } from '../spec/mex';
1
+ export { WA_MEX_PERSIST_IDS, WA_MEX_OPERATION_SCHEMAS } from '../../spec/mex/index.js';
@@ -23,7 +23,8 @@ export const WA_MESSAGE_TYPES = Object.freeze({
23
23
  RECEIPT_TYPE_PEER: 'peer_msg',
24
24
  RECEIPT_TYPE_SERVER_ERROR: 'server-error',
25
25
  RECEIPT_TYPE_RETRY: 'retry',
26
- RECEIPT_TYPE_ENC_REKEY_RETRY: 'enc_rekey_retry'
26
+ RECEIPT_TYPE_ENC_REKEY_RETRY: 'enc_rekey_retry',
27
+ RECEIPT_TYPE_VIEW: 'view'
27
28
  });
28
29
  export const WA_RETRYABLE_ACK_CODES = Object.freeze(['408', '429', '500', '503']);
29
30
  export const WA_STANZA_MSG_TYPES = Object.freeze({
@@ -1 +1 @@
1
- export { WA_VERSION } from '../spec/version';
1
+ export { WA_VERSION } from '../../spec/version/index.js';
@@ -6,7 +6,8 @@ export type { WaAppStateMutationCoordinator, WaBroadcastListParticipant, WaSetBr
6
6
  export type { WaBotCoordinator, WaBotInfo, WaBotPosingAsProfessional, WaBotProfileCommand, WaBotProfilePrompt, WaBotProfileResult, WaBotPromptOptions, WaGetBotProfileOptions } from './client/coordinators/WaBotCoordinator';
7
7
  export type { WaBroadcastListCoordinator, WaSendBroadcastListMessageInput } from './client/coordinators/WaBroadcastListCoordinator';
8
8
  export type { WaBusinessCoordinator, WaVerifiedNameBatchEntry } from './client/coordinators/WaBusinessCoordinator';
9
- export type { WaUploadMediaSource } from './client/media';
9
+ export { downloadMediaMessage } from './client/media';
10
+ export type { WaDownloadMediaMessageOptions, WaUploadMediaSource } from './client/media';
10
11
  export type { WaEditBusinessProfileInput } from './transport/node/builders/business';
11
12
  export type { WaEmailCoordinator, WaEmailStatus, WaEmailVerifyCodeResult } from './client/coordinators/WaEmailCoordinator';
12
13
  export type { WaCommunityCreateOptions, WaCommunitySubGroup, WaCommunitySubGroupResult, WaCommunitySubGroupsResult, WaGroupCoordinator, WaGroupCreateOptions, WaGroupMetadata, WaGroupParticipant, WaLinkSubGroupsResult, WaMembershipRequest, WaUnlinkSubGroupsResult } from './client/coordinators/WaGroupCoordinator';
@@ -19,6 +20,8 @@ export type { WaUsyncProtocolError, WaUsyncResultEnvelope } from './transport/no
19
20
  export type { WaSendStatusInput, WaStatusCoordinator } from './client/coordinators/WaStatusCoordinator';
20
21
  export type { WaEncryptedMessageInput, WaMessageAckMetadata, WaMessageKey, WaMessagePublishOptions, WaMessagePublishResult, WaMessageRef, WaMessageTargetInput, WaSendEditKey, WaSendEventLocation, WaSendEventMessage, WaSendEventParent, WaSendEventResponseMessage, WaSendEventResponseType, WaSendKeepMessage, WaSendMediaMessage, WaSendMessageContent, WaSendPinMessage, WaSendPollMessage, WaSendPollOptionInput, WaSendPollParent, WaSendPollVoteMessage, WaSendReactionMessage, WaSendReceiptEventOptions, WaSendReceiptInput, WaSendReceiptOptions, WaSendRevokeMessage, WaSendStickerPackMessage, WaSendStickerPackStickerInput, WaSendStickerPackTrayIcon, WaSendTextMessage } from './message/types';
21
22
  export { getContentType, resolveMessageTarget } from './message/encode/content';
23
+ export { resolveMediaPayload } from './message/encode/media-payload';
24
+ export type { WaResolvedMediaPayload } from './message/encode/media-payload';
22
25
  export type { WaSendContextInfo } from './message/context-info';
23
26
  export type { WaLinkPreviewFetcher, WaLinkPreviewOptions, WaLinkPreviewOverride, WaLinkPreviewResolved, WaLinkPreviewThumbnailBytes, WaLinkPreviewThumbnailInput, WaLinkPreviewThumbnailStream, WaLinkPreviewType } from './message/addons/link-preview/types';
24
27
  export type { SignalLidSyncResult } from './signal/api/SignalDeviceSyncApi';
package/dist/index.js CHANGED
@@ -1,14 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WA_DIRTY_PROTOCOLS = exports.WA_DEFAULTS = exports.WA_COMPANION_PLATFORM_IDS = exports.WA_BUSINESS_HOURS_MODES = exports.WA_BUSINESS_HOURS_DAYS = exports.WA_BROWSERS = exports.WA_APP_STATE_SYNC_DATA_TYPE = exports.WA_APP_STATE_KEY_TYPES = exports.WA_APP_STATE_KDF_INFO = exports.WA_APP_STATE_ERROR_CODES = exports.WA_APP_STATE_COLLECTION_STATES = exports.WA_APP_STATE_COLLECTIONS = exports.WA_ACCOUNT_SYNC_PROTOCOLS = exports.toUserJid = exports.splitJid = exports.signalAddressKey = exports.parseSignalAddressFromJid = exports.parsePhoneJid = exports.parseJidFull = exports.normalizeRecipientJid = exports.normalizeDeviceJid = exports.isUserJid = exports.isStatusBroadcastJid = exports.isNewsletterJid = exports.isLidJid = exports.isHostedServer = exports.isHostedDeviceJid = exports.isHostedDeviceId = exports.isGroupOrBroadcastJid = exports.isGroupJid = exports.isBroadcastJid = exports.isBotJid = exports.getWaMediaHkdfInfo = exports.getWaCompanionPlatformId = exports.getLoginIdentity = exports.canonicalizeSignalServer = exports.canonicalizeSignalJid = exports.buildDeviceJid = exports.delay = exports.WaAuthMemoryStore = exports.createStore = exports.createNoopLogger = exports.createPinoLogger = exports.PinoLogger = exports.ConsoleLogger = exports.fetchLatestWaWebVersion = exports.resolveMessageTarget = exports.getContentType = exports.parseUsyncResultEnvelope = exports.WaClient = void 0;
4
- exports.proto = exports.WA_XMLNS = exports.WA_PRIVACY_VALUES = exports.WA_PRIVACY_TAGS = exports.WA_PRIVACY_SETTING_TO_CATEGORY = exports.WA_PRIVACY_DISALLOWED_LIST_CATEGORIES = exports.WA_PRIVACY_CATEGORY_TO_SETTING = exports.WA_PRIVACY_CATEGORIES = exports.WA_SUPPORTED_DIRTY_TYPES = exports.WA_STREAM_SIGNALING = exports.WA_SIGNALING = exports.WA_RETRYABLE_ACK_CODES = exports.WA_READY_STATES = exports.WA_PREVIEW_MEDIA_HKDF_INFO = exports.WA_PAIRING_KDF_INFO = exports.WA_NODE_TAGS = exports.WA_MEDIA_HKDF_INFO = exports.WA_MESSAGE_TYPES = exports.WA_MESSAGE_TAGS = exports.WA_LOGOUT_REASONS = exports.WA_IQ_TYPES = exports.WA_DISCONNECT_REASONS = exports.WA_DIRTY_TYPES = void 0;
3
+ exports.WA_COMPANION_PLATFORM_IDS = exports.WA_BUSINESS_HOURS_MODES = exports.WA_BUSINESS_HOURS_DAYS = exports.WA_BROWSERS = exports.WA_APP_STATE_SYNC_DATA_TYPE = exports.WA_APP_STATE_KEY_TYPES = exports.WA_APP_STATE_KDF_INFO = exports.WA_APP_STATE_ERROR_CODES = exports.WA_APP_STATE_COLLECTION_STATES = exports.WA_APP_STATE_COLLECTIONS = exports.WA_ACCOUNT_SYNC_PROTOCOLS = exports.toUserJid = exports.splitJid = exports.signalAddressKey = exports.parseSignalAddressFromJid = exports.parsePhoneJid = exports.parseJidFull = exports.normalizeRecipientJid = exports.normalizeDeviceJid = exports.isUserJid = exports.isStatusBroadcastJid = exports.isNewsletterJid = exports.isLidJid = exports.isHostedServer = exports.isHostedDeviceJid = exports.isHostedDeviceId = exports.isGroupOrBroadcastJid = exports.isGroupJid = exports.isBroadcastJid = exports.isBotJid = exports.getWaMediaHkdfInfo = exports.getWaCompanionPlatformId = exports.getLoginIdentity = exports.canonicalizeSignalServer = exports.canonicalizeSignalJid = exports.buildDeviceJid = exports.delay = exports.WaAuthMemoryStore = exports.createStore = exports.createNoopLogger = exports.createPinoLogger = exports.PinoLogger = exports.ConsoleLogger = exports.fetchLatestWaWebVersion = exports.resolveMediaPayload = exports.resolveMessageTarget = exports.getContentType = exports.parseUsyncResultEnvelope = exports.downloadMediaMessage = exports.WaClient = void 0;
4
+ exports.proto = exports.WA_XMLNS = exports.WA_PRIVACY_VALUES = exports.WA_PRIVACY_TAGS = exports.WA_PRIVACY_SETTING_TO_CATEGORY = exports.WA_PRIVACY_DISALLOWED_LIST_CATEGORIES = exports.WA_PRIVACY_CATEGORY_TO_SETTING = exports.WA_PRIVACY_CATEGORIES = exports.WA_SUPPORTED_DIRTY_TYPES = exports.WA_STREAM_SIGNALING = exports.WA_SIGNALING = exports.WA_RETRYABLE_ACK_CODES = exports.WA_READY_STATES = exports.WA_PREVIEW_MEDIA_HKDF_INFO = exports.WA_PAIRING_KDF_INFO = exports.WA_NODE_TAGS = exports.WA_MEDIA_HKDF_INFO = exports.WA_MESSAGE_TYPES = exports.WA_MESSAGE_TAGS = exports.WA_LOGOUT_REASONS = exports.WA_IQ_TYPES = exports.WA_DISCONNECT_REASONS = exports.WA_DIRTY_TYPES = exports.WA_DIRTY_PROTOCOLS = exports.WA_DEFAULTS = void 0;
5
5
  var _client_1 = require("./client");
6
6
  Object.defineProperty(exports, "WaClient", { enumerable: true, get: function () { return _client_1.WaClient; } });
7
+ var media_1 = require("./client/media");
8
+ Object.defineProperty(exports, "downloadMediaMessage", { enumerable: true, get: function () { return media_1.downloadMediaMessage; } });
7
9
  var usync_1 = require("./transport/node/builders/usync");
8
10
  Object.defineProperty(exports, "parseUsyncResultEnvelope", { enumerable: true, get: function () { return usync_1.parseUsyncResultEnvelope; } });
9
11
  var content_1 = require("./message/encode/content");
10
12
  Object.defineProperty(exports, "getContentType", { enumerable: true, get: function () { return content_1.getContentType; } });
11
13
  Object.defineProperty(exports, "resolveMessageTarget", { enumerable: true, get: function () { return content_1.resolveMessageTarget; } });
14
+ var media_payload_1 = require("./message/encode/media-payload");
15
+ Object.defineProperty(exports, "resolveMediaPayload", { enumerable: true, get: function () { return media_payload_1.resolveMediaPayload; } });
12
16
  var wa_web_version_fetcher_1 = require("./transport/wa-web-version-fetcher");
13
17
  Object.defineProperty(exports, "fetchLatestWaWebVersion", { enumerable: true, get: function () { return wa_web_version_fetcher_1.fetchLatestWaWebVersion; } });
14
18
  var ConsoleLogger_1 = require("./infra/log/ConsoleLogger");