@badzz88/baileys 8.4.9 → 8.5.1
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.
- package/README.md +1 -1
- package/WAProto/WAProto.proto +6 -347
- package/WAProto/fix-imports.js +85 -86
- package/WAProto/index.d.ts +25 -4913
- package/WAProto/index.js +93 -14069
- package/{src → lib}/Defaults/index.js +2 -13
- package/{src → lib}/Signal/Group/group_cipher.js +5 -5
- package/{src → lib}/Signal/Group/keyhelper.js +4 -4
- package/{src → lib}/Signal/Group/sender-chain-key.js +2 -2
- package/{src → lib}/Signal/Group/sender-key-distribution-message.js +1 -1
- package/{src → lib}/Signal/Group/sender-key-message.js +3 -3
- package/{src → lib}/Signal/Group/sender-key-record.js +1 -1
- package/{src → lib}/Signal/Group/sender-message-key.js +2 -2
- package/{src → lib}/Signal/libsignal.js +26 -6
- package/{src → lib}/Socket/chats.js +58 -616
- package/{src → lib}/Socket/communities.js +28 -59
- package/{src → lib}/Socket/graphql.js +103 -362
- package/{src → lib}/Socket/groups.js +29 -77
- package/{src → lib}/Socket/index.js +5 -3
- package/{src → lib}/Socket/interactive-handler.js +60 -117
- package/{src → lib}/Socket/interop.js +19 -36
- package/lib/Socket/luxu.js +387 -0
- package/{src → lib}/Socket/managed-account.js +27 -58
- package/{src → lib}/Socket/messages-recv.js +144 -715
- package/{src → lib}/Socket/messages-send.js +102 -412
- package/lib/Socket/mex.js +60 -0
- package/{src → lib}/Socket/newsletter.js +23 -266
- package/{src → lib}/Socket/privacy.js +38 -41
- package/{src → lib}/Socket/registration.js +106 -113
- package/{src → lib}/Socket/socket.js +101 -88
- package/{src → lib}/Socket/text-router.js +17 -1
- package/lib/Socket/username.js +243 -0
- package/lib/Store/keyed-db.js +108 -0
- package/{src → lib}/Store/make-in-memory-store.js +104 -6
- package/lib/Types/Mex.js +112 -0
- package/{src → lib}/Types/Newsletter.js +41 -72
- package/{src → lib}/Types/index.js +1 -0
- package/{src → lib}/Utils/chat-utils.js +9 -73
- package/lib/Utils/command-loader.d.ts +31 -0
- package/lib/Utils/command-loader.js +100 -0
- package/lib/Utils/companion-reg-client-utils.js +42 -0
- package/lib/Utils/crypto.js +155 -0
- package/lib/Utils/curve25519-js.js +275 -0
- package/{src → lib}/Utils/decode-wa-message.js +36 -284
- package/{src → lib}/Utils/event-buffer.js +27 -6
- package/{src → lib}/Utils/generics.js +37 -114
- package/{src → lib}/Utils/index.js +5 -1
- package/lib/Utils/lt-hash.js +39 -0
- package/{src → lib}/Utils/message-retry-manager.js +39 -0
- package/{src → lib}/Utils/messages-media.js +58 -105
- package/{src → lib}/Utils/messages.js +529 -115
- package/lib/Utils/meta-ai-msmsg.js +262 -0
- package/lib/Utils/native-bridge.js +82 -0
- package/{src → lib}/Utils/noise-handler.js +15 -13
- package/{src → lib}/Utils/process-message.js +55 -54
- package/{src → lib}/Utils/reporting-utils.js +2 -2
- package/lib/Utils/session-pool.d.ts +16 -0
- package/lib/Utils/session-pool.js +94 -0
- package/{src → lib}/Utils/signal.js +51 -19
- package/{src → lib}/Utils/stanza-ack.js +2 -36
- package/lib/Utils/sticker.d.ts +17 -0
- package/lib/Utils/sticker.js +145 -0
- package/{src → lib}/Utils/tc-token-utils.js +1 -1
- package/{src → lib}/Utils/validate-connection.js +11 -40
- package/lib/Utils/view-once-cache.d.ts +9 -0
- package/lib/Utils/view-once-cache.js +79 -0
- package/{src → lib}/WABinary/decode.js +4 -38
- package/lib/WABinary/encode.js +228 -0
- package/{src → lib}/WABinary/generic-utils.js +93 -1
- package/{src → lib}/WABinary/jid-utils.js +3 -16
- package/{src → lib}/WAM/encode.js +1 -1
- package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +43 -0
- package/{src → lib}/WAUSync/Protocols/USyncContactProtocol.js +1 -7
- package/{src → lib}/WAUSync/Protocols/USyncDeviceProtocol.js +5 -13
- package/{src → lib}/WAUSync/Protocols/USyncDisappearingModeProtocol.js +4 -1
- package/{src → lib}/WAUSync/Protocols/USyncFeatureProtocol.js +2 -17
- package/{src → lib}/WAUSync/Protocols/USyncStatusProtocol.js +2 -7
- package/{src → lib}/WAUSync/Protocols/USyncUsernameProtocol.js +1 -2
- package/{src → lib}/WAUSync/Protocols/index.js +0 -1
- package/{src → lib}/WAUSync/USyncQuery.js +6 -77
- package/{src → lib}/WAUSync/USyncUser.js +8 -16
- package/{src → lib}/WAUSync/index.js +0 -1
- package/{src → lib}/antiban.js +266 -355
- package/{src → lib}/index.js +2 -2
- package/package.json +19 -16
- package/WAProto/fix-import.js +0 -38
- package/src/Socket/mex.js +0 -47
- package/src/Socket/username.js +0 -234
- package/src/Utils/crypto.js +0 -125
- package/src/Utils/lt-hash.js +0 -10
- package/src/Utils/message-inspect.js +0 -400
- package/src/Utils/meta-ai-msmsg.js +0 -133
- package/src/WABinary/encode.js +0 -58
- package/src/WAUSync/Protocols/USyncBusinessProtocol.js +0 -100
- package/src/WAUSync/USyncBackoff.js +0 -31
- /package/{src → lib}/Defaults/phonenumber-mcc.json +0 -0
- /package/{src → lib}/Signal/Group/ciphertext-message.js +0 -0
- /package/{src → lib}/Signal/Group/group-session-builder.js +0 -0
- /package/{src → lib}/Signal/Group/index.js +0 -0
- /package/{src → lib}/Signal/Group/sender-key-name.js +0 -0
- /package/{src → lib}/Signal/Group/sender-key-state.js +0 -0
- /package/{src → lib}/Signal/lid-mapping.js +0 -0
- /package/{src → lib}/Socket/Client/index.js +0 -0
- /package/{src → lib}/Socket/Client/types.js +0 -0
- /package/{src → lib}/Socket/Client/websocket.js +0 -0
- /package/{src → lib}/Socket/aigroups.js +0 -0
- /package/{src → lib}/Socket/business.js +0 -0
- /package/{src → lib}/Store/index.js +0 -0
- /package/{src → lib}/Store/make-cache-manager-store.js +0 -0
- /package/{src → lib}/Store/make-ordered-dictionary.js +0 -0
- /package/{src → lib}/Store/object-repository.js +0 -0
- /package/{src → lib}/Types/Auth.js +0 -0
- /package/{src → lib}/Types/Bussines.js +0 -0
- /package/{src → lib}/Types/Call.js +0 -0
- /package/{src → lib}/Types/Chat.js +0 -0
- /package/{src → lib}/Types/Contact.js +0 -0
- /package/{src → lib}/Types/Events.js +0 -0
- /package/{src → lib}/Types/GroupMetadata.js +0 -0
- /package/{src → lib}/Types/Label.js +0 -0
- /package/{src → lib}/Types/LabelAssociation.js +0 -0
- /package/{src → lib}/Types/Message.js +0 -0
- /package/{src → lib}/Types/Product.js +0 -0
- /package/{src → lib}/Types/Signal.js +0 -0
- /package/{src → lib}/Types/Socket.js +0 -0
- /package/{src → lib}/Types/State.js +0 -0
- /package/{src → lib}/Types/USync.js +0 -0
- /package/{src → lib}/Utils/auth-utils.js +0 -0
- /package/{src → lib}/Utils/browser-utils.js +0 -0
- /package/{src → lib}/Utils/business.js +0 -0
- /package/{src → lib}/Utils/consumer-application.js +0 -0
- /package/{src → lib}/Utils/group-history.js +0 -0
- /package/{src → lib}/Utils/history.js +0 -0
- /package/{src → lib}/Utils/identity-change-handler.js +0 -0
- /package/{src → lib}/Utils/jid-display-normalization.js +0 -0
- /package/{src → lib}/Utils/link-preview.js +0 -0
- /package/{src → lib}/Utils/logger.js +0 -0
- /package/{src → lib}/Utils/make-mutex.js +0 -0
- /package/{src → lib}/Utils/message-composer.js +0 -0
- /package/{src → lib}/Utils/offline-node-processor.js +0 -0
- /package/{src → lib}/Utils/pre-key-manager.js +0 -0
- /package/{src → lib}/Utils/sync-action-utils.js +0 -0
- /package/{src → lib}/Utils/use-multi-file-auth-state.js +0 -0
- /package/{src → lib}/Utils/voip-rekey.js +0 -0
- /package/{src → lib}/WABinary/constants.js +0 -0
- /package/{src → lib}/WABinary/index.js +0 -0
- /package/{src → lib}/WABinary/types.js +0 -0
- /package/{src → lib}/WAM/BinaryInfo.js +0 -0
- /package/{src → lib}/WAM/constants.js +0 -0
- /package/{src → lib}/WAM/index.js +0 -0
- /package/{src → lib}/WAUSync/Protocols/USyncBotProfileProtocol.js +0 -0
- /package/{src → lib}/WAUSync/Protocols/USyncLIDProtocol.js +0 -0
- /package/{src → lib}/WAUSync/Protocols/USyncPictureProtocol.js +0 -0
- /package/{src → lib}/WAUSync/Protocols/USyncSidelistProtocol.js +0 -0
- /package/{src → lib}/WAUSync/Protocols/USyncTextStatusProtocol.js +0 -0
|
@@ -4,6 +4,7 @@ exports.getNextPreKeysNode =
|
|
|
4
4
|
exports.getNextPreKeys =
|
|
5
5
|
exports.extractDeviceJids =
|
|
6
6
|
exports.parseAndInjectE2ESessions =
|
|
7
|
+
exports.extractE2ESessionFromRetryReceipt =
|
|
7
8
|
exports.xmppPreKey =
|
|
8
9
|
exports.xmppSignedPreKey =
|
|
9
10
|
exports.generateOrGetPreKeys =
|
|
@@ -53,11 +54,9 @@ const generateOrGetPreKeys = (creds, range) => {
|
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
56
|
exports.generateOrGetPreKeys = generateOrGetPreKeys
|
|
56
|
-
|
|
57
|
-
// only pass it when mixing in a non-default cipher; omit for plain Curve25519 uploads.
|
|
58
|
-
const xmppSignedPreKey = (key, cipherSuite) => ({
|
|
57
|
+
const xmppSignedPreKey = key => ({
|
|
59
58
|
tag: 'skey',
|
|
60
|
-
attrs:
|
|
59
|
+
attrs: {},
|
|
61
60
|
content: [
|
|
62
61
|
{ tag: 'id', attrs: {}, content: (0, generics_1.encodeBigEndian)(key.keyId, 3) },
|
|
63
62
|
{ tag: 'value', attrs: {}, content: key.keyPair.public },
|
|
@@ -65,27 +64,63 @@ const xmppSignedPreKey = (key, cipherSuite) => ({
|
|
|
65
64
|
]
|
|
66
65
|
})
|
|
67
66
|
exports.xmppSignedPreKey = xmppSignedPreKey
|
|
68
|
-
const xmppPreKey = (pair, id
|
|
67
|
+
const xmppPreKey = (pair, id) => ({
|
|
69
68
|
tag: 'key',
|
|
70
|
-
attrs:
|
|
69
|
+
attrs: {},
|
|
71
70
|
content: [
|
|
72
71
|
{ tag: 'id', attrs: {}, content: (0, generics_1.encodeBigEndian)(id, 3) },
|
|
73
72
|
{ tag: 'value', attrs: {}, content: pair.public }
|
|
74
73
|
]
|
|
75
74
|
})
|
|
76
75
|
exports.xmppPreKey = xmppPreKey
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
76
|
+
const isValidUInt = n => typeof n === 'number' && Number.isInteger(n)
|
|
77
|
+
const extractE2ESessionFromRetryReceipt = receipt => {
|
|
78
|
+
const keysNode = (0, WABinary_1.getBinaryNodeChild)(receipt, 'keys')
|
|
79
|
+
if (!keysNode) return null
|
|
80
|
+
const typeBuf = (0, WABinary_1.getBinaryNodeChildBuffer)(keysNode, 'type')
|
|
81
|
+
if (!typeBuf || typeBuf.length !== 1 || typeBuf[0] !== Defaults_1.KEY_BUNDLE_TYPE[0]) return null
|
|
82
|
+
const identity = (0, WABinary_1.getBinaryNodeChildBuffer)(keysNode, 'identity')
|
|
83
|
+
const skey = (0, WABinary_1.getBinaryNodeChild)(keysNode, 'skey')
|
|
84
|
+
if (!identity || identity.length !== 32 || !skey) return null
|
|
85
|
+
const registrationId = (0, WABinary_1.getBinaryNodeChildUInt)(receipt, 'registration', 4)
|
|
86
|
+
if (!isValidUInt(registrationId)) return null
|
|
87
|
+
const signedPubKey = (0, WABinary_1.getBinaryNodeChildBuffer)(skey, 'value')
|
|
88
|
+
const signedSig = (0, WABinary_1.getBinaryNodeChildBuffer)(skey, 'signature')
|
|
89
|
+
const signedKeyId = (0, WABinary_1.getBinaryNodeChildUInt)(skey, 'id', 3)
|
|
90
|
+
if (!signedPubKey || signedPubKey.length !== 32 || !signedSig || !isValidUInt(signedKeyId)) {
|
|
91
|
+
return null
|
|
92
|
+
}
|
|
93
|
+
const preKeyNode = (0, WABinary_1.getBinaryNodeChild)(keysNode, 'key')
|
|
94
|
+
let preKey
|
|
95
|
+
if (preKeyNode) {
|
|
96
|
+
const preKeyPub = (0, WABinary_1.getBinaryNodeChildBuffer)(preKeyNode, 'value')
|
|
97
|
+
const preKeyId = (0, WABinary_1.getBinaryNodeChildUInt)(preKeyNode, 'id', 3)
|
|
98
|
+
if (!preKeyPub || preKeyPub.length !== 32 || !isValidUInt(preKeyId)) {
|
|
99
|
+
return null
|
|
87
100
|
}
|
|
101
|
+
preKey = { keyId: preKeyId, publicKey: (0, crypto_1.generateSignalPubKey)(preKeyPub) }
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
registrationId,
|
|
105
|
+
identityKey: (0, crypto_1.generateSignalPubKey)(identity),
|
|
106
|
+
signedPreKey: {
|
|
107
|
+
keyId: signedKeyId,
|
|
108
|
+
publicKey: (0, crypto_1.generateSignalPubKey)(signedPubKey),
|
|
109
|
+
signature: signedSig
|
|
110
|
+
},
|
|
111
|
+
preKey
|
|
88
112
|
}
|
|
113
|
+
}
|
|
114
|
+
exports.extractE2ESessionFromRetryReceipt = extractE2ESessionFromRetryReceipt
|
|
115
|
+
const parseAndInjectE2ESessions = async (node, repository) => {
|
|
116
|
+
const extractKey = key =>
|
|
117
|
+
key
|
|
118
|
+
? {
|
|
119
|
+
keyId: (0, WABinary_1.getBinaryNodeChildUInt)(key, 'id', 3),
|
|
120
|
+
publicKey: (0, crypto_1.generateSignalPubKey)((0, WABinary_1.getBinaryNodeChildBuffer)(key, 'value')),
|
|
121
|
+
signature: (0, WABinary_1.getBinaryNodeChildBuffer)(key, 'signature')
|
|
122
|
+
}
|
|
123
|
+
: undefined
|
|
89
124
|
const nodes = (0, WABinary_1.getBinaryNodeChildren)((0, WABinary_1.getBinaryNodeChild)(node, 'list'), 'user')
|
|
90
125
|
for (const node of nodes) {
|
|
91
126
|
;(0, WABinary_1.assertNodeErrorFree)(node)
|
|
@@ -180,9 +215,6 @@ const getNextPreKeysNode = async (state, count) => {
|
|
|
180
215
|
{ tag: 'registration', attrs: {}, content: (0, generics_1.encodeBigEndian)(creds.registrationId) },
|
|
181
216
|
{ tag: 'type', attrs: {}, content: Defaults_1.KEY_BUNDLE_TYPE },
|
|
182
217
|
{ tag: 'identity', attrs: {}, content: creds.signedIdentityKey.public },
|
|
183
|
-
// key_cipher_suite is only sent when the bundle mixes in a non-default cipher
|
|
184
|
-
// (e.g. Kyber/PQXDH alongside Curve25519) — a plain Curve25519-only upload
|
|
185
|
-
// omits it entirely on real clients, confirmed against live capture.
|
|
186
218
|
{ tag: 'list', attrs: {}, content: Object.keys(preKeys).map(k => (0, exports.xmppPreKey)(preKeys[+k], +k)) },
|
|
187
219
|
(0, exports.xmppSignedPreKey)(creds.signedPreKey)
|
|
188
220
|
]
|
|
@@ -1,34 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
Object.defineProperty(exports, '__esModule', { value: true })
|
|
3
3
|
exports.buildAckStanza = buildAckStanza
|
|
4
|
-
// Standalone call stanzas use class="call" + type=<tag>, not class=<tag>.
|
|
5
|
-
// Kept in sync with messages-recv.js's CALL_STATE_TAGS + CB: registration loop.
|
|
6
|
-
const CALL_STANZA_TAGS = new Set([
|
|
7
|
-
'offer',
|
|
8
|
-
'offer_notice',
|
|
9
|
-
'terminate',
|
|
10
|
-
'accept',
|
|
11
|
-
'reject',
|
|
12
|
-
'preaccept',
|
|
13
|
-
'transport',
|
|
14
|
-
'video',
|
|
15
|
-
'duration',
|
|
16
|
-
'mute_v2',
|
|
17
|
-
'lobby',
|
|
18
|
-
'heartbeat',
|
|
19
|
-
'relaylatency',
|
|
20
|
-
'link_query',
|
|
21
|
-
'group_update',
|
|
22
|
-
'accept_ack',
|
|
23
|
-
'enc-rekey',
|
|
24
|
-
'enc_rekey',
|
|
25
|
-
'peer_state',
|
|
26
|
-
'group_info',
|
|
27
|
-
'video_state',
|
|
28
|
-
'video_state_ack',
|
|
29
|
-
'flow_control',
|
|
30
|
-
'waiting_room_request'
|
|
31
|
-
])
|
|
32
4
|
/**
|
|
33
5
|
* Builds an ACK stanza for a received node.
|
|
34
6
|
* Pure function -- no I/O, no side effects.
|
|
@@ -39,19 +11,14 @@ const CALL_STANZA_TAGS = new Set([
|
|
|
39
11
|
*/
|
|
40
12
|
function buildAckStanza(node, errorCode, meId) {
|
|
41
13
|
const { tag, attrs } = node
|
|
42
|
-
const isCallStanza = CALL_STANZA_TAGS.has(tag)
|
|
43
14
|
const stanza = {
|
|
44
15
|
tag: 'ack',
|
|
45
16
|
attrs: {
|
|
46
17
|
id: attrs.id,
|
|
47
18
|
to: attrs.from,
|
|
48
|
-
class:
|
|
19
|
+
class: tag
|
|
49
20
|
}
|
|
50
21
|
}
|
|
51
|
-
// For standalone call stanzas, WA Web puts the original tag into `type`
|
|
52
|
-
if (isCallStanza) {
|
|
53
|
-
stanza.attrs.type = tag
|
|
54
|
-
}
|
|
55
22
|
if (errorCode) {
|
|
56
23
|
stanza.attrs.error = errorCode.toString()
|
|
57
24
|
}
|
|
@@ -62,8 +29,7 @@ function buildAckStanza(node, errorCode, meId) {
|
|
|
62
29
|
stanza.attrs.recipient = attrs.recipient
|
|
63
30
|
}
|
|
64
31
|
// WA Web always includes type when present: `n.type || DROP_ATTR`
|
|
65
|
-
|
|
66
|
-
if (attrs.type && !isCallStanza) {
|
|
32
|
+
if (attrs.type) {
|
|
67
33
|
stanza.attrs.type = attrs.type
|
|
68
34
|
}
|
|
69
35
|
// WA Web WAWebHandleMsgSendAck.sendAck/sendNack always include `from` for message-class ACKs
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface StickerMetaOptions {
|
|
2
|
+
packName?: string
|
|
3
|
+
packPublisher?: string
|
|
4
|
+
categories?: string[]
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function addExifToWebp(webpBuffer: Buffer, options?: StickerMetaOptions): Promise<Buffer>
|
|
8
|
+
|
|
9
|
+
export function imageToWebpSticker(
|
|
10
|
+
imageBuffer: Buffer,
|
|
11
|
+
options?: StickerMetaOptions & { quality?: number }
|
|
12
|
+
): Promise<Buffer>
|
|
13
|
+
|
|
14
|
+
export function videoToWebpSticker(
|
|
15
|
+
videoBuffer: Buffer,
|
|
16
|
+
options?: StickerMetaOptions & { fps?: number; seconds?: number }
|
|
17
|
+
): Promise<Buffer>
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
Object.defineProperty(exports, '__esModule', { value: true })
|
|
3
|
+
exports.imageToWebpSticker = exports.videoToWebpSticker = exports.addExifToWebp = void 0
|
|
4
|
+
const os = require('os')
|
|
5
|
+
const path = require('path')
|
|
6
|
+
const fs = require('fs')
|
|
7
|
+
const crypto = require('crypto')
|
|
8
|
+
const { exec } = require('child_process')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Builds and writes the EXIF metadata WhatsApp expects on sticker webp files
|
|
12
|
+
* (pack name / author, shown when a user long-presses a sticker).
|
|
13
|
+
* Converts the file to the "extended" (VP8X) WebP container if it isn't already,
|
|
14
|
+
* since that's the container format that actually carries an EXIF chunk.
|
|
15
|
+
* Returns the new buffer with EXIF attached.
|
|
16
|
+
*/
|
|
17
|
+
const addExifToWebp = async (webpBuffer, { packName = '', packPublisher = '', categories = [] } = {}) => {
|
|
18
|
+
const json = {
|
|
19
|
+
'sticker-pack-id': crypto.randomBytes(16).toString('hex'),
|
|
20
|
+
'sticker-pack-name': packName,
|
|
21
|
+
'sticker-pack-publisher': packPublisher,
|
|
22
|
+
emojis: categories.length ? categories : ['😀']
|
|
23
|
+
}
|
|
24
|
+
const jsonBuffer = Buffer.from(JSON.stringify(json), 'utf-8')
|
|
25
|
+
// TIFF header + IFD entry pointing at a single custom tag (0x5741 "AW") holding
|
|
26
|
+
// the JSON payload -- this is the exact structure WhatsApp's client parses.
|
|
27
|
+
const exifAttr = Buffer.from([
|
|
28
|
+
0x49, 0x49, 0x2a, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
|
|
29
|
+
0x00, 0x00, 0x00
|
|
30
|
+
])
|
|
31
|
+
exifAttr.writeUIntLE(jsonBuffer.length, 14, 4)
|
|
32
|
+
const exifPayload = Buffer.concat([exifAttr, jsonBuffer])
|
|
33
|
+
const pad = buf => (buf.length % 2 === 1 ? Buffer.concat([buf, Buffer.from([0x00])]) : buf)
|
|
34
|
+
const makeChunk = (tag, data) => {
|
|
35
|
+
const sizeField = Buffer.alloc(4)
|
|
36
|
+
sizeField.writeUInt32LE(data.length, 0)
|
|
37
|
+
return Buffer.concat([Buffer.from(tag, 'ascii'), sizeField, pad(data)])
|
|
38
|
+
}
|
|
39
|
+
const exifChunk = makeChunk('EXIF', exifPayload)
|
|
40
|
+
if (webpBuffer.slice(0, 4).toString('ascii') !== 'RIFF' || webpBuffer.slice(8, 12).toString('ascii') !== 'WEBP') {
|
|
41
|
+
throw new Error('addExifToWebp expects a valid WebP buffer')
|
|
42
|
+
}
|
|
43
|
+
let offset = 12
|
|
44
|
+
let vp8xChunk = null
|
|
45
|
+
let vp8xOffset = -1
|
|
46
|
+
const otherChunks = []
|
|
47
|
+
while (offset < webpBuffer.length) {
|
|
48
|
+
const tag = webpBuffer.slice(offset, offset + 4).toString('ascii')
|
|
49
|
+
const size = webpBuffer.readUInt32LE(offset + 4)
|
|
50
|
+
const dataStart = offset + 8
|
|
51
|
+
const dataEnd = dataStart + size
|
|
52
|
+
const chunkTotal = 8 + size + (size % 2)
|
|
53
|
+
if (tag === 'VP8X') {
|
|
54
|
+
vp8xChunk = webpBuffer.slice(offset, offset + chunkTotal)
|
|
55
|
+
vp8xOffset = offset
|
|
56
|
+
} else if (tag !== 'EXIF') {
|
|
57
|
+
// drop any pre-existing EXIF chunk, keep everything else (VP8/VP8L/ANIM/ANMF/ICCP/...)
|
|
58
|
+
otherChunks.push(webpBuffer.slice(offset, offset + chunkTotal))
|
|
59
|
+
}
|
|
60
|
+
offset += chunkTotal
|
|
61
|
+
}
|
|
62
|
+
let flags
|
|
63
|
+
let canvasWidth
|
|
64
|
+
let canvasHeight
|
|
65
|
+
if (vp8xChunk) {
|
|
66
|
+
flags = vp8xChunk.readUInt8(8)
|
|
67
|
+
canvasWidth = vp8xChunk.readUIntLE(12, 3) + 1
|
|
68
|
+
canvasHeight = vp8xChunk.readUIntLE(15, 3) + 1
|
|
69
|
+
} else {
|
|
70
|
+
flags = 0
|
|
71
|
+
let sharp
|
|
72
|
+
try {
|
|
73
|
+
sharp = require('sharp')
|
|
74
|
+
} catch (error) {
|
|
75
|
+
throw new Error('addExifToWebp needs the optional "sharp" dependency to read image dimensions')
|
|
76
|
+
}
|
|
77
|
+
const meta = await sharp(webpBuffer).metadata()
|
|
78
|
+
canvasWidth = meta.width
|
|
79
|
+
canvasHeight = meta.height
|
|
80
|
+
}
|
|
81
|
+
flags |= 0x08 // set the "has EXIF metadata" bit
|
|
82
|
+
const vp8xData = Buffer.alloc(10)
|
|
83
|
+
vp8xData.writeUInt8(flags, 0)
|
|
84
|
+
vp8xData.writeUIntLE(canvasWidth - 1, 4, 3)
|
|
85
|
+
vp8xData.writeUIntLE(canvasHeight - 1, 7, 3)
|
|
86
|
+
const newVp8xChunk = makeChunk('VP8X', vp8xData)
|
|
87
|
+
const body = Buffer.concat([newVp8xChunk, ...otherChunks, exifChunk])
|
|
88
|
+
const fileSize = Buffer.alloc(4)
|
|
89
|
+
fileSize.writeUInt32LE(4 + body.length, 0) // 4 = 'WEBP'
|
|
90
|
+
return Buffer.concat([Buffer.from('RIFF', 'ascii'), fileSize, Buffer.from('WEBP', 'ascii'), body])
|
|
91
|
+
}
|
|
92
|
+
exports.addExifToWebp = addExifToWebp
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Converts a static image buffer to a WhatsApp sticker-ready webp buffer using `sharp`.
|
|
96
|
+
* @param {Buffer} imageBuffer
|
|
97
|
+
* @param {{ packName?: string, packPublisher?: string, categories?: string[], quality?: number }} [options]
|
|
98
|
+
* @returns {Promise<Buffer>}
|
|
99
|
+
*/
|
|
100
|
+
const imageToWebpSticker = async (imageBuffer, options = {}) => {
|
|
101
|
+
let sharp
|
|
102
|
+
try {
|
|
103
|
+
sharp = require('sharp')
|
|
104
|
+
} catch (error) {
|
|
105
|
+
throw new Error('imageToWebpSticker requires the optional "sharp" dependency to be installed')
|
|
106
|
+
}
|
|
107
|
+
const webp = await sharp(imageBuffer)
|
|
108
|
+
.resize(512, 512, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } })
|
|
109
|
+
.webp({ quality: options.quality ?? 80 })
|
|
110
|
+
.toBuffer()
|
|
111
|
+
return addExifToWebp(webp, options)
|
|
112
|
+
}
|
|
113
|
+
exports.imageToWebpSticker = imageToWebpSticker
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Converts a video buffer to an animated WhatsApp sticker-ready webp buffer.
|
|
117
|
+
* Requires the `ffmpeg` binary to be available on PATH.
|
|
118
|
+
* @param {Buffer} videoBuffer
|
|
119
|
+
* @param {{ packName?: string, packPublisher?: string, categories?: string[], fps?: number, seconds?: number }} [options]
|
|
120
|
+
* @returns {Promise<Buffer>}
|
|
121
|
+
*/
|
|
122
|
+
const videoToWebpSticker = async (videoBuffer, options = {}) => {
|
|
123
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'xazbails-sticker-'))
|
|
124
|
+
const inputPath = path.join(tmpDir, 'input.mp4')
|
|
125
|
+
const outputPath = path.join(tmpDir, 'output.webp')
|
|
126
|
+
fs.writeFileSync(inputPath, videoBuffer)
|
|
127
|
+
const fps = options.fps ?? 10
|
|
128
|
+
const seconds = options.seconds ?? 5
|
|
129
|
+
const cmd =
|
|
130
|
+
`ffmpeg -y -i ${inputPath} -t ${seconds} -vf ` +
|
|
131
|
+
`"fps=${fps},scale=512:512:force_original_aspect_ratio=decrease,` +
|
|
132
|
+
`pad=512:512:(ow-iw)/2:(oh-ih)/2:color=0x00000000,split[a][b];` +
|
|
133
|
+
`[a]palettegen=reserve_transparent=1[p];[b][p]paletteuse" ` +
|
|
134
|
+
`-loop 0 -preset default -an -vsync 0 ${outputPath}`
|
|
135
|
+
try {
|
|
136
|
+
await new Promise((resolve, reject) => {
|
|
137
|
+
exec(cmd, err => (err ? reject(err) : resolve()))
|
|
138
|
+
})
|
|
139
|
+
const webp = fs.readFileSync(outputPath)
|
|
140
|
+
return await addExifToWebp(webp, options)
|
|
141
|
+
} finally {
|
|
142
|
+
fs.rmSync(tmpDir, { recursive: true, force: true })
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
exports.videoToWebpSticker = videoToWebpSticker
|
|
@@ -64,7 +64,7 @@ async function buildMergedTcTokenIndexWrite(keys, addedJids) {
|
|
|
64
64
|
// WA Web has separate sender/receiver AB props for these but they're identical today
|
|
65
65
|
function isTcTokenExpired(timestamp) {
|
|
66
66
|
if (timestamp === null || timestamp === undefined) return true
|
|
67
|
-
const ts = typeof timestamp === 'string' ? parseInt(timestamp
|
|
67
|
+
const ts = typeof timestamp === 'string' ? parseInt(timestamp) : timestamp
|
|
68
68
|
if (isNaN(ts)) return true
|
|
69
69
|
const now = Math.floor(Date.now() / 1000)
|
|
70
70
|
const currentBucket = Math.floor(now / TC_TOKEN_BUCKET_DURATION)
|
|
@@ -7,40 +7,24 @@ exports.encodeSignedDeviceIdentity =
|
|
|
7
7
|
void 0
|
|
8
8
|
const boom_1 = require('@hapi/boom')
|
|
9
9
|
const crypto_1 = require('crypto')
|
|
10
|
-
const
|
|
10
|
+
const Crypto_1 = require('./crypto')
|
|
11
11
|
const index_js_1 = require('../../WAProto/index.js')
|
|
12
12
|
const Defaults_1 = require('../Defaults')
|
|
13
13
|
const WABinary_1 = require('../WABinary')
|
|
14
14
|
const crypto_2 = require('./crypto')
|
|
15
15
|
const generics_1 = require('./generics')
|
|
16
16
|
const signal_1 = require('./signal')
|
|
17
|
-
const MOBILE_PLATFORMS = new Set(['Android', 'iOS'])
|
|
18
17
|
const getUserAgent = config => {
|
|
19
|
-
const os = config.browser[0]
|
|
20
|
-
let platform, device, osVersion
|
|
21
|
-
if (os === 'Android') {
|
|
22
|
-
platform = index_js_1.proto.ClientPayload.UserAgent.Platform.ANDROID
|
|
23
|
-
device = 'Android'
|
|
24
|
-
osVersion = config.browser[2] || '15.0.0'
|
|
25
|
-
} else if (os === 'iOS') {
|
|
26
|
-
platform = index_js_1.proto.ClientPayload.UserAgent.Platform.IOS
|
|
27
|
-
device = 'iPhone'
|
|
28
|
-
osVersion = config.browser[2] || '18.0'
|
|
29
|
-
} else {
|
|
30
|
-
platform = index_js_1.proto.ClientPayload.UserAgent.Platform.WEB
|
|
31
|
-
device = 'Desktop'
|
|
32
|
-
osVersion = '0.1'
|
|
33
|
-
}
|
|
34
18
|
return {
|
|
35
19
|
appVersion: {
|
|
36
20
|
primary: config.version[0],
|
|
37
21
|
secondary: config.version[1],
|
|
38
22
|
tertiary: config.version[2]
|
|
39
23
|
},
|
|
40
|
-
platform,
|
|
41
|
-
releaseChannel: index_js_1.proto.ClientPayload.UserAgent.ReleaseChannel.
|
|
42
|
-
osVersion,
|
|
43
|
-
device,
|
|
24
|
+
platform: index_js_1.proto.ClientPayload.UserAgent.Platform.WEB,
|
|
25
|
+
releaseChannel: index_js_1.proto.ClientPayload.UserAgent.ReleaseChannel.RELEASE,
|
|
26
|
+
osVersion: '0.1',
|
|
27
|
+
device: 'Desktop',
|
|
44
28
|
osBuildNumber: '0.1',
|
|
45
29
|
localeLanguageIso6391: 'en',
|
|
46
30
|
mnc: '000',
|
|
@@ -50,9 +34,7 @@ const getUserAgent = config => {
|
|
|
50
34
|
}
|
|
51
35
|
const PLATFORM_MAP = {
|
|
52
36
|
'Mac OS': index_js_1.proto.ClientPayload.WebInfo.WebSubPlatform.DARWIN,
|
|
53
|
-
Windows: index_js_1.proto.ClientPayload.WebInfo.WebSubPlatform.WIN32
|
|
54
|
-
Android: index_js_1.proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER,
|
|
55
|
-
iOS: index_js_1.proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER
|
|
37
|
+
Windows: index_js_1.proto.ClientPayload.WebInfo.WebSubPlatform.WIN32
|
|
56
38
|
}
|
|
57
39
|
const getWebInfo = config => {
|
|
58
40
|
let webSubPlatform = index_js_1.proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER
|
|
@@ -67,9 +49,7 @@ const getClientPayload = config => {
|
|
|
67
49
|
connectReason: index_js_1.proto.ClientPayload.ConnectReason.USER_ACTIVATED,
|
|
68
50
|
userAgent: getUserAgent(config)
|
|
69
51
|
}
|
|
70
|
-
|
|
71
|
-
payload.webInfo = getWebInfo(config)
|
|
72
|
-
}
|
|
52
|
+
payload.webInfo = getWebInfo(config)
|
|
73
53
|
return payload
|
|
74
54
|
}
|
|
75
55
|
const generateLoginNode = (userJid, config, creds) => {
|
|
@@ -105,18 +85,16 @@ const getPlatformType = platform => {
|
|
|
105
85
|
const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentityKey }, config) => {
|
|
106
86
|
// the app version needs to be md5 hashed
|
|
107
87
|
// and passed in
|
|
108
|
-
const appVersionBuf = Buffer.from(
|
|
88
|
+
const appVersionBuf = Buffer.from(Crypto_1.md5(Buffer.from(config.version.join('.'))))
|
|
109
89
|
const companion = {
|
|
110
90
|
os: config.browser[0],
|
|
111
91
|
platformType: getPlatformType(config.browser[1]),
|
|
112
92
|
requireFullSync: config.syncFullHistory,
|
|
113
93
|
historySyncConfig: {
|
|
114
|
-
fullSyncDaysLimit: undefined,
|
|
115
|
-
fullSyncSizeMbLimit: undefined,
|
|
116
94
|
storageQuotaMb: 10240,
|
|
117
95
|
inlineInitialPayloadInE2EeMsg: true,
|
|
118
96
|
recentSyncDaysLimit: undefined,
|
|
119
|
-
supportCallLogHistory:
|
|
97
|
+
supportCallLogHistory: false,
|
|
120
98
|
supportBotUserAgentChatHistory: true,
|
|
121
99
|
supportCagReactionsAndPolls: true,
|
|
122
100
|
supportBizHostedMsg: true,
|
|
@@ -125,16 +103,9 @@ const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentity
|
|
|
125
103
|
supportFbidBotChatHistory: true,
|
|
126
104
|
supportAddOnHistorySyncMigration: undefined,
|
|
127
105
|
supportMessageAssociation: true,
|
|
128
|
-
supportGroupHistory:
|
|
106
|
+
supportGroupHistory: false,
|
|
129
107
|
onDemandReady: undefined,
|
|
130
|
-
supportGuestChat:
|
|
131
|
-
completeOnDemandReady: undefined,
|
|
132
|
-
thumbnailSyncDaysLimit: undefined,
|
|
133
|
-
initialSyncMaxMessagesPerChat: undefined,
|
|
134
|
-
supportManusHistory: true,
|
|
135
|
-
supportHatchHistory: true,
|
|
136
|
-
supportedBotChannelFbids: undefined,
|
|
137
|
-
supportInlineContacts: true
|
|
108
|
+
supportGuestChat: undefined
|
|
138
109
|
},
|
|
139
110
|
version: {
|
|
140
111
|
primary: 10,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface AutoCacheViewOnceOptions {
|
|
2
|
+
cacheDir?: string
|
|
3
|
+
logger?: any
|
|
4
|
+
onCached?: (info: { id: string; jid: string; filePath: string; type: string }) => void
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function getViewOnceContent(message: any): Record<string, any> | null
|
|
8
|
+
|
|
9
|
+
export function autoCacheViewOnceMedia(sock: any, options?: AutoCacheViewOnceOptions): () => void
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
Object.defineProperty(exports, '__esModule', { value: true })
|
|
3
|
+
exports.autoCacheViewOnceMedia = void 0
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const fs = require('fs')
|
|
6
|
+
const Messages_1 = require('./messages')
|
|
7
|
+
const MessagesMedia_1 = require('./messages-media')
|
|
8
|
+
|
|
9
|
+
const VIEW_ONCE_WRAPPER_KEYS = ['viewOnceMessage', 'viewOnceMessageV2', 'viewOnceMessageV2Extension']
|
|
10
|
+
const VIEW_ONCE_INNER_KEYS = ['imageMessage', 'videoMessage', 'audioMessage']
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Unwraps a message and returns the inner view-once media content if present, otherwise null.
|
|
14
|
+
* Handles both the wrapper style (viewOnceMessage[V2/V2Extension] -> message -> ...)
|
|
15
|
+
* and the inline style (imageMessage/videoMessage with viewOnce: true set directly).
|
|
16
|
+
*/
|
|
17
|
+
const getViewOnceContent = message => {
|
|
18
|
+
if (!message) return null
|
|
19
|
+
const content = (0, Messages_1.extractMessageContent)(message)
|
|
20
|
+
if (!content) return null
|
|
21
|
+
for (const wrapperKey of VIEW_ONCE_WRAPPER_KEYS) {
|
|
22
|
+
const wrapper = content[wrapperKey]
|
|
23
|
+
if (wrapper?.message) {
|
|
24
|
+
const inner = (0, Messages_1.extractMessageContent)(wrapper.message)
|
|
25
|
+
if (inner) return inner
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
for (const key of VIEW_ONCE_INNER_KEYS) {
|
|
29
|
+
if (content[key]?.viewOnce) {
|
|
30
|
+
return { [key]: content[key] }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return null
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Registers a `messages.upsert` listener on the given socket that automatically
|
|
38
|
+
* downloads and saves view-once media (image/video/audio) to `cacheDir` as soon
|
|
39
|
+
* as it arrives, before the sender's app can mark it as opened/consumed.
|
|
40
|
+
*
|
|
41
|
+
* @param {ReturnType<typeof import('../Socket').default>} sock - an active Baileys socket
|
|
42
|
+
* @param {{ cacheDir?: string, logger?: any, onCached?: (info: { id: string, jid: string, filePath: string, type: string }) => void }} [options]
|
|
43
|
+
* @returns {() => void} a function that removes the listener
|
|
44
|
+
*/
|
|
45
|
+
const autoCacheViewOnceMedia = (sock, options = {}) => {
|
|
46
|
+
const cacheDir = options.cacheDir || './viewonce-cache'
|
|
47
|
+
const logger = options.logger || sock.logger
|
|
48
|
+
if (!fs.existsSync(cacheDir)) {
|
|
49
|
+
fs.mkdirSync(cacheDir, { recursive: true })
|
|
50
|
+
}
|
|
51
|
+
const handler = async ({ messages, type }) => {
|
|
52
|
+
if (type !== 'notify' && type !== 'append') return
|
|
53
|
+
for (const msg of messages) {
|
|
54
|
+
try {
|
|
55
|
+
const viewOnceContent = getViewOnceContent(msg.message)
|
|
56
|
+
if (!viewOnceContent) continue
|
|
57
|
+
const mediaType = Object.keys(viewOnceContent)[0]
|
|
58
|
+
const buffer = await (0, Messages_1.downloadMediaMessage)(
|
|
59
|
+
msg,
|
|
60
|
+
'buffer',
|
|
61
|
+
{},
|
|
62
|
+
{ logger, reuploadRequest: sock.updateMediaMessage }
|
|
63
|
+
)
|
|
64
|
+
const extension = (0, MessagesMedia_1.extensionForMediaMessage)(viewOnceContent) || 'bin'
|
|
65
|
+
const fileName = `${msg.key.id}.${extension}`
|
|
66
|
+
const filePath = path.join(cacheDir, fileName)
|
|
67
|
+
fs.writeFileSync(filePath, buffer)
|
|
68
|
+
logger?.debug?.({ id: msg.key.id, filePath, mediaType }, 'cached view-once media')
|
|
69
|
+
options.onCached?.({ id: msg.key.id, jid: msg.key.remoteJid, filePath, type: mediaType })
|
|
70
|
+
} catch (error) {
|
|
71
|
+
logger?.warn?.({ error, id: msg.key?.id }, 'failed to cache view-once media')
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
sock.ev.on('messages.upsert', handler)
|
|
76
|
+
return () => sock.ev.off('messages.upsert', handler)
|
|
77
|
+
}
|
|
78
|
+
exports.autoCacheViewOnceMedia = autoCacheViewOnceMedia
|
|
79
|
+
exports.getViewOnceContent = getViewOnceContent
|
|
@@ -56,7 +56,6 @@ const util_1 = require('util')
|
|
|
56
56
|
const zlib_1 = require('zlib')
|
|
57
57
|
const constants = __importStar(require('./constants'))
|
|
58
58
|
const jid_utils_1 = require('./jid-utils')
|
|
59
|
-
const rb = require('whatsapp-rust-bridge-baron')
|
|
60
59
|
const inflatePromise = (0, util_1.promisify)(zlib_1.inflate)
|
|
61
60
|
const decompressingIfRequired = async buffer => {
|
|
62
61
|
if (2 & buffer.readUInt8()) {
|
|
@@ -68,25 +67,6 @@ const decompressingIfRequired = async buffer => {
|
|
|
68
67
|
return buffer
|
|
69
68
|
}
|
|
70
69
|
exports.decompressingIfRequired = decompressingIfRequired
|
|
71
|
-
|
|
72
|
-
// Converts InternalBinaryNode.toJSON() output to a plain JS object with Buffer content
|
|
73
|
-
const rustNodeToJs = node => {
|
|
74
|
-
if (!node || typeof node !== 'object') return node
|
|
75
|
-
const result = { tag: node.tag, attrs: node.attrs || {} }
|
|
76
|
-
const content = node.content
|
|
77
|
-
if (content === undefined || content === null) {
|
|
78
|
-
// no content
|
|
79
|
-
} else if (content instanceof Uint8Array) {
|
|
80
|
-
result.content = Buffer.from(content)
|
|
81
|
-
} else if (typeof content === 'string') {
|
|
82
|
-
result.content = content
|
|
83
|
-
} else if (Array.isArray(content)) {
|
|
84
|
-
result.content = content.map(rustNodeToJs)
|
|
85
|
-
} else {
|
|
86
|
-
result.content = content
|
|
87
|
-
}
|
|
88
|
-
return result
|
|
89
|
-
}
|
|
90
70
|
const decodeDecompressedBinaryNode = (buffer, opts, indexRef = { index: 0 }) => {
|
|
91
71
|
const { DOUBLE_BYTE_TOKENS, SINGLE_BYTE_TOKENS, TAGS } = opts
|
|
92
72
|
const checkEOS = length => {
|
|
@@ -110,7 +90,7 @@ const decodeDecompressedBinaryNode = (buffer, opts, indexRef = { index: 0 }) =>
|
|
|
110
90
|
return value
|
|
111
91
|
}
|
|
112
92
|
const readStringFromChars = length => {
|
|
113
|
-
return readBytes(length).toString('
|
|
93
|
+
return readBytes(length).toString('utf-8')
|
|
114
94
|
}
|
|
115
95
|
const readInt = (n, littleEndian = false) => {
|
|
116
96
|
checkEOS(n)
|
|
@@ -304,9 +284,7 @@ const decodeDecompressedBinaryNode = (buffer, opts, indexRef = { index: 0 }) =>
|
|
|
304
284
|
const value = dict[index2]
|
|
305
285
|
if (typeof value === 'undefined') {
|
|
306
286
|
// Unknown token in known dictionary — token table may be outdated
|
|
307
|
-
process.stderr.write(
|
|
308
|
-
`[WABinary] unknown double-byte token dict=${index1} idx=${index2} — token table outdated?\n`
|
|
309
|
-
)
|
|
287
|
+
process.stderr.write(`[WABinary] unknown double-byte token dict=${index1} idx=${index2} — token table outdated?\n`)
|
|
310
288
|
return ''
|
|
311
289
|
}
|
|
312
290
|
return value
|
|
@@ -358,20 +336,8 @@ const decodeDecompressedBinaryNode = (buffer, opts, indexRef = { index: 0 }) =>
|
|
|
358
336
|
}
|
|
359
337
|
}
|
|
360
338
|
exports.decodeDecompressedBinaryNode = decodeDecompressedBinaryNode
|
|
361
|
-
const JS_DECODE_OPTS = {
|
|
362
|
-
TAGS: constants.TAGS,
|
|
363
|
-
SINGLE_BYTE_TOKENS: constants.SINGLE_BYTE_TOKENS,
|
|
364
|
-
DOUBLE_BYTE_TOKENS: constants.DOUBLE_BYTE_TOKENS,
|
|
365
|
-
}
|
|
366
339
|
const decodeBinaryNode = buff => {
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
const internal = rb.decodeNode(u8)
|
|
370
|
-
return rustNodeToJs(internal.toJSON())
|
|
371
|
-
} catch (_) {
|
|
372
|
-
// WASM token table is outdated (e.g. INTEROP_JID_TUPLE=244, INTEROP_JID=245).
|
|
373
|
-
// Fall back to the JS decoder which knows all current tags.
|
|
374
|
-
return (0, exports.decodeDecompressedBinaryNode)(buff, JS_DECODE_OPTS)
|
|
375
|
-
}
|
|
340
|
+
const buffer = Buffer.isBuffer(buff) ? buff : Buffer.from(buff)
|
|
341
|
+
return decodeDecompressedBinaryNode(buffer, constants)
|
|
376
342
|
}
|
|
377
343
|
exports.decodeBinaryNode = decodeBinaryNode
|