@zervonex/baileys 0.0.0-stage → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3206 -3
  3. package/WAProto/WAProtoCompile.js +291 -0
  4. package/WAProto/fetcher.js +69 -0
  5. package/WAProto/index.js +88 -0
  6. package/WAProto/parser.js +313 -0
  7. package/engine-requirements.js +10 -0
  8. package/lib/Builders/AIRich.js +643 -0
  9. package/lib/Builders/base.js +130 -0
  10. package/lib/Builders/builders.js +449 -0
  11. package/lib/Builders/index.js +3 -0
  12. package/lib/Defaults/index.js +225 -0
  13. package/lib/Defaults/phonenumber-mcc.json +223 -0
  14. package/lib/Signal/index.js +2 -0
  15. package/lib/Signal/libsignal.js +523 -0
  16. package/lib/Signal/lid-mapping.js +283 -0
  17. package/lib/Socket/Client/index.js +2 -0
  18. package/lib/Socket/Client/types.js +10 -0
  19. package/lib/Socket/Client/websocket.js +84 -0
  20. package/lib/Socket/business.js +152 -0
  21. package/lib/Socket/chats.js +855 -0
  22. package/lib/Socket/communities.js +147 -0
  23. package/lib/Socket/groups.js +294 -0
  24. package/lib/Socket/index.js +15 -0
  25. package/lib/Socket/messages-recv.js +981 -0
  26. package/lib/Socket/messages-send.js +708 -0
  27. package/lib/Socket/mex.js +34 -0
  28. package/lib/Socket/newsletter.js +781 -0
  29. package/lib/Socket/registration.js +155 -0
  30. package/lib/Socket/socket.js +797 -0
  31. package/lib/Socket/spam-report.js +65 -0
  32. package/lib/Socket/username.js +82 -0
  33. package/lib/Socket/zervonex-handler.js +55 -0
  34. package/lib/Store/index.js +6 -0
  35. package/lib/Store/make-cache-manager-store.js +81 -0
  36. package/lib/Store/make-in-memory-store.js +425 -0
  37. package/lib/Store/make-ordered-dictionary.js +82 -0
  38. package/lib/Store/object-repository.js +31 -0
  39. package/lib/Store/reporting-info-store.js +38 -0
  40. package/lib/Types/Auth.js +2 -0
  41. package/lib/Types/Bussines.js +2 -0
  42. package/lib/Types/Call.js +2 -0
  43. package/lib/Types/Chat.js +8 -0
  44. package/lib/Types/Contact.js +2 -0
  45. package/lib/Types/Events.js +2 -0
  46. package/lib/Types/GroupMetadata.js +2 -0
  47. package/lib/Types/Label.js +25 -0
  48. package/lib/Types/LabelAssociation.js +7 -0
  49. package/lib/Types/Message.js +15 -0
  50. package/lib/Types/Newsletter.js +100 -0
  51. package/lib/Types/Product.js +2 -0
  52. package/lib/Types/Signal.js +2 -0
  53. package/lib/Types/Socket.js +14 -0
  54. package/lib/Types/State.js +26 -0
  55. package/lib/Types/USync.js +2 -0
  56. package/lib/Types/index.js +30 -0
  57. package/lib/Utils/auth-utils.js +142 -0
  58. package/lib/Utils/baileys-event-stream.js +33 -0
  59. package/lib/Utils/bot-capabilities.js +40 -0
  60. package/lib/Utils/bot-planning-replay.js +44 -0
  61. package/lib/Utils/browser-utils.js +26 -0
  62. package/lib/Utils/business.js +75 -0
  63. package/lib/Utils/chat-utils.js +317 -0
  64. package/lib/Utils/companion-reg-client-utils.js +20 -0
  65. package/lib/Utils/consumer-application.js +38 -0
  66. package/lib/Utils/crypto.js +52 -0
  67. package/lib/Utils/decode-wa-message.js +197 -0
  68. package/lib/Utils/event-buffer.js +273 -0
  69. package/lib/Utils/extras.js +186 -0
  70. package/lib/Utils/generics.js +195 -0
  71. package/lib/Utils/history.js +51 -0
  72. package/lib/Utils/identity-change-handler.js +19 -0
  73. package/lib/Utils/index.js +38 -0
  74. package/lib/Utils/link-preview.js +51 -0
  75. package/lib/Utils/logger.js +2 -0
  76. package/lib/Utils/lt-hash.js +3 -0
  77. package/lib/Utils/make-mutex.js +16 -0
  78. package/lib/Utils/message-composer.js +59 -0
  79. package/lib/Utils/message-retry-manager.js +48 -0
  80. package/lib/Utils/messages-media.js +520 -0
  81. package/lib/Utils/messages.js +752 -0
  82. package/lib/Utils/meta-ai-msmsg.js +122 -0
  83. package/lib/Utils/meta-compositing.js +75 -0
  84. package/lib/Utils/modern-messages.js +235 -0
  85. package/lib/Utils/native-flow.js +55 -0
  86. package/lib/Utils/noise-handler.js +161 -0
  87. package/lib/Utils/pre-key-manager.js +76 -0
  88. package/lib/Utils/process-message.js +399 -0
  89. package/lib/Utils/reporting-utils.js +171 -0
  90. package/lib/Utils/signal.js +167 -0
  91. package/lib/Utils/spam-report-utils.js +135 -0
  92. package/lib/Utils/sync-action-utils.js +33 -0
  93. package/lib/Utils/tc-token-utils.js +154 -0
  94. package/lib/Utils/use-multi-file-auth-state.js +307 -0
  95. package/lib/Utils/validate-connection.js +181 -0
  96. package/lib/WABinary/constants.js +1321 -0
  97. package/lib/WABinary/decode.js +152 -0
  98. package/lib/WABinary/encode.js +140 -0
  99. package/lib/WABinary/generic-utils.js +179 -0
  100. package/lib/WABinary/index.js +6 -0
  101. package/lib/WABinary/jid-utils.js +235 -0
  102. package/lib/WABinary/types.js +4 -0
  103. package/lib/WAM/BinaryInfo.js +10 -0
  104. package/lib/WAM/constants.js +22853 -0
  105. package/lib/WAM/encode.js +150 -0
  106. package/lib/WAM/index.js +3 -0
  107. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +30 -0
  108. package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +48 -0
  109. package/lib/WAUSync/Protocols/USyncContactProtocol.js +23 -0
  110. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +28 -0
  111. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +15 -0
  112. package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +24 -0
  113. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +9 -0
  114. package/lib/WAUSync/Protocols/USyncPictureProtocol.js +21 -0
  115. package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +19 -0
  116. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +19 -0
  117. package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +22 -0
  118. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +16 -0
  119. package/lib/WAUSync/Protocols/index.js +12 -0
  120. package/lib/WAUSync/USyncQuery.js +100 -0
  121. package/lib/WAUSync/USyncUser.js +20 -0
  122. package/lib/WAUSync/index.js +3 -0
  123. package/lib/index.js +67 -0
  124. package/package.json +220 -5
@@ -0,0 +1,313 @@
1
+ import { createRequire } from 'module'
2
+ import { writeFileSync, renameSync } from 'fs'
3
+ import { join, dirname } from 'path'
4
+ import { fileURLToPath } from 'url'
5
+ import logger from '../lib/Utils/logger.js'
6
+
7
+ const require = createRequire(import.meta.url)
8
+ const acorn = require('acorn')
9
+ const walk = require('acorn-walk')
10
+
11
+ const __dirname = dirname(fileURLToPath(import.meta.url))
12
+ const addPrefix = (lines, prefix) => lines.map(l => prefix + l)
13
+
14
+ function extractAllExpressions(node) {
15
+ const out = [node]
16
+ const exp = node.expression
17
+ if (exp) out.push(exp)
18
+ if (node?.expression?.arguments?.length)
19
+ for (const arg of node.expression.arguments)
20
+ if (arg?.body?.body?.length)
21
+ for (const e of arg.body.body) out.push(...extractAllExpressions(e))
22
+ if (node?.body?.body?.length)
23
+ for (const e of node.body.body)
24
+ if (e.expression) out.push(...extractAllExpressions(e.expression))
25
+ if (node.expression?.expressions?.length)
26
+ for (const e of node.expression.expressions) out.push(...extractAllExpressions(e))
27
+ return out
28
+ }
29
+
30
+ function getNumericEnumValue(node) {
31
+ if (node?.type === 'Literal' && typeof node.value === 'number') return node.value
32
+ if (node?.type === 'UnaryExpression' && (node.operator === '-' || node.operator === '+') &&
33
+ node.argument?.type === 'Literal' && typeof node.argument.value === 'number')
34
+ return node.operator === '-' ? -node.argument.value : node.argument.value
35
+ return undefined
36
+ }
37
+
38
+ function parseBundleSources(sources) {
39
+ const nodes = []
40
+ const opts = { ecmaVersion: 'latest', allowHashBang: true }
41
+ for (let i = 0; i < sources.length; i++) {
42
+ const patched = sources[i].replaceAll('LimitSharing$Trigger', 'LimitSharing$TriggerType')
43
+ sources[i] = null
44
+ try { nodes.push(...acorn.parse(patched, { ...opts, sourceType: 'script' }).body) }
45
+ catch {
46
+ try { nodes.push(...acorn.parse(patched, { ...opts, sourceType: 'module' }).body) }
47
+ catch (e) { logger.warn(`[WAProto] Skipping bundle ${i + 1}: ${e.message}`) }
48
+ }
49
+ }
50
+ return nodes
51
+ }
52
+
53
+ function filterProtoModules(allNodes) {
54
+ return allNodes.filter(m => extractAllExpressions(m).find(e => e?.left?.property?.name === 'internalSpec'))
55
+ }
56
+
57
+ export function extractSchema(bundleSources) {
58
+ const allNodes = parseBundleSources(Array.isArray(bundleSources) ? bundleSources : [bundleSources])
59
+ const modules = filterProtoModules(allNodes)
60
+
61
+ const unspecName = n => n.endsWith('Spec') ? n.slice(0, -4) : n
62
+ const getNesting = n => n.split('$').slice(0, -1).join('$')
63
+ const rename = n => unspecName(n)
64
+
65
+ const modulesInfo = {}
66
+ const moduleIndentationMap = {}
67
+
68
+ modules.forEach(module => {
69
+ const modName = module?.expression?.arguments?.[0]?.value ?? `__anon_${Math.random()}`
70
+ modulesInfo[modName] = { crossRefs: [] }
71
+ walk.simple(module, {
72
+ AssignmentExpression(node) {
73
+ if (node?.right?.type === 'CallExpression' &&
74
+ node?.right?.arguments?.length === 1 &&
75
+ node?.right?.arguments[0]?.type !== 'ObjectExpression')
76
+ modulesInfo[modName].crossRefs.push({ alias: node.left?.name, module: node.right.arguments[0].value })
77
+ },
78
+ })
79
+ })
80
+
81
+ for (const mod of modules) {
82
+ const modName = mod?.expression?.arguments?.[0]?.value
83
+ const modInfo = modulesInfo[modName]
84
+ const assignments = []
85
+
86
+ walk.simple(mod, {
87
+ AssignmentExpression(node) {
88
+ const left = node.left
89
+ if (left?.property?.name &&
90
+ left.property.name !== 'internalSpec' &&
91
+ left.property.name !== 'internalDefaults' &&
92
+ left.property.name !== 'name') assignments.push(left)
93
+ },
94
+ })
95
+
96
+ const makeBlankIdent = a => {
97
+ const key = rename(a?.property?.name)
98
+ const indentation = getNesting(key)
99
+ moduleIndentationMap[key] = moduleIndentationMap[key] || {}
100
+ moduleIndentationMap[key].indentation = indentation
101
+ if (indentation.length) {
102
+ moduleIndentationMap[indentation] = moduleIndentationMap[indentation] || {}
103
+ moduleIndentationMap[indentation].members = moduleIndentationMap[indentation].members || new Set()
104
+ moduleIndentationMap[indentation].members.add(key)
105
+ }
106
+ return [key, { name: key }]
107
+ }
108
+
109
+ modInfo.identifiers = Object.fromEntries(assignments.map(makeBlankIdent).reverse())
110
+
111
+ const enumAliases = {}
112
+ walk.ancestor(mod, {
113
+ Property(node, anc) {
114
+ const fatherNode = anc[anc.length - 3]
115
+ const fatherFather = anc[anc.length - 4]
116
+ if (fatherNode?.type === 'AssignmentExpression' &&
117
+ fatherNode?.left?.property?.name === 'internalSpec' &&
118
+ fatherNode?.right?.properties?.length) {
119
+ const values = fatherNode.right.properties.map(p => ({ name: p.key.name, id: p.value.value }))
120
+ enumAliases[fatherNode?.left?.name] = values
121
+ } else if (fatherNode?.type === 'VariableDeclarator' &&
122
+ fatherNode?.init?.type === 'ObjectExpression' &&
123
+ fatherNode.init.properties.length &&
124
+ fatherNode.init.properties.every(p => getNumericEnumValue(p.value) !== undefined)) {
125
+ const values = fatherNode.init.properties.map(p => ({ name: p.key.name || p.key.value, id: getNumericEnumValue(p.value) }))
126
+ enumAliases[fatherNode.id?.name] = values
127
+ } else if (node?.key?.name && fatherNode?.arguments?.length > 0) {
128
+ const values = fatherNode.arguments?.[0]?.properties?.map(p => ({ name: p.key.name, id: p.value.value }))
129
+ const nameAlias = fatherFather?.left?.name || fatherFather?.id?.name
130
+ if (nameAlias) enumAliases[nameAlias] = values
131
+ }
132
+ },
133
+ })
134
+
135
+ walk.simple(mod, {
136
+ AssignmentExpression(node) {
137
+ if (node.left?.type === 'MemberExpression' && modInfo.identifiers?.[rename(node.left.property?.name)]) {
138
+ const ident = modInfo.identifiers[rename(node.left.property.name)]
139
+ ident.alias = node.right?.name
140
+ ident.enumValues = enumAliases[ident.alias]
141
+ }
142
+ },
143
+ })
144
+ }
145
+
146
+ const findByAlias = (identifiers, alias) => Object.values(identifiers).find(item => item.alias === alias)
147
+
148
+ for (const mod of modules) {
149
+ const modName = mod?.expression?.arguments?.[0]?.value
150
+ const modInfo = modulesInfo[modName]
151
+
152
+ walk.simple(mod, {
153
+ AssignmentExpression(node) {
154
+ if (node.left?.type !== 'MemberExpression' ||
155
+ node.left.property?.name !== 'internalSpec' ||
156
+ node.right?.type !== 'ObjectExpression') return
157
+
158
+ const targetIdent = Object.values(modInfo.identifiers).find(v => v.alias === node.left.object?.name)
159
+ if (!targetIdent) return
160
+
161
+ const constraints = [], rawMembers = []
162
+ for (const p of node.right.properties) {
163
+ p.key.name = p.key.type === 'Identifier' ? p.key.name : p.key.value
164
+ ; (p.key.name.substring(0, 2) === '__' ? constraints : rawMembers).push(p)
165
+ }
166
+
167
+ let members = rawMembers.map(({ key: { name }, value: { elements } }) => {
168
+ let type
169
+ const flags = []
170
+ const unwrapBinaryOr = n =>
171
+ n.type === 'BinaryExpression' && n.operator === '|'
172
+ ? [].concat(unwrapBinaryOr(n.left), unwrapBinaryOr(n.right))
173
+ : [n]
174
+
175
+ unwrapBinaryOr(elements[1]).forEach(m => {
176
+ if (m.type !== 'MemberExpression' || m.object?.type !== 'MemberExpression') return
177
+ if (m.object.property?.name === 'TYPES') {
178
+ type = m.property.name.toLowerCase()
179
+ if (type === 'map' && elements[2]?.type === 'ArrayExpression') {
180
+ let typeStr = 'map<'
181
+ elements[2].elements.forEach((el, i) => {
182
+ typeStr += el?.property?.name ? el.property.name.toLowerCase()
183
+ : (findByAlias(modInfo.identifiers, el.name)?.name ?? el.name)
184
+ if (i < elements[2].elements.length - 1) typeStr += ', '
185
+ })
186
+ type = typeStr + '>'
187
+ }
188
+ } else if (m.object.property?.name === 'FLAGS') {
189
+ flags.push(m.property.name.toLowerCase())
190
+ }
191
+ })
192
+
193
+ if (type === 'message' || type === 'enum') {
194
+ if (elements[2]?.type === 'Identifier') {
195
+ const found = Object.values(modInfo.identifiers).find(v => v.alias === elements[2].name)
196
+ type = found?.name
197
+ } else if (elements[2]?.type === 'MemberExpression') {
198
+ const targetAlias = elements[2]?.object?.name || elements[2]?.object?.left?.name || elements[2]?.object?.callee?.name
199
+ const crossRef = modInfo.crossRefs.find(r => r.alias === targetAlias)
200
+ if (elements[1]?.property?.name === 'ENUM' && elements[2]?.property?.name?.includes('Type'))
201
+ type = rename(elements[2].property.name)
202
+ else if (elements[2]?.property?.name?.includes('Spec'))
203
+ type = rename(elements[2].property.name)
204
+ else if (crossRef && crossRef.module !== '$InternalEnum' && modulesInfo[crossRef.module]?.identifiers?.[rename(elements[2].property.name)])
205
+ type = rename(elements[2].property.name)
206
+ }
207
+ }
208
+
209
+ return { name, id: elements[0].value, type, flags }
210
+ })
211
+
212
+ constraints.forEach(c => {
213
+ if (c.key.name === '__oneofs__' && c.value.type === 'ObjectExpression') {
214
+ const oneofs = c.value.properties.map(p => ({
215
+ name: p.key.name, type: '__oneof__',
216
+ members: p.value.elements.map(e => {
217
+ const idx = members.findIndex(m => m.name === e.value)
218
+ const member = members[idx]
219
+ members.splice(idx, 1)
220
+ return member
221
+ }),
222
+ }))
223
+ members.push(...oneofs)
224
+ }
225
+ })
226
+
227
+ targetIdent.members = members
228
+ },
229
+ })
230
+ }
231
+
232
+ return { modulesInfo, moduleIndentationMap }
233
+ }
234
+
235
+ export function generateProto3(modulesInfo, moduleIndentationMap, version) {
236
+ const indent = ' '
237
+ const unnest = n => n.split('$').slice(-1)[0]
238
+
239
+ const stringifyMember = (info, completeFlags, parentName) => {
240
+ if (info.type === '__oneof__')
241
+ return [`oneof ${info.name} {`, ...addPrefix([].concat(...info.members.map(m => stringifyMember(m, false))), indent), '}']
242
+ if (info.flags.includes('packed')) { info.flags.splice(info.flags.indexOf('packed'), 1); info.packed = ' [packed=true]' }
243
+ const reqIdx = info.flags.indexOf('required'); if (reqIdx !== -1) info.flags[reqIdx] = 'optional'
244
+ if (completeFlags && !info.flags.length && info.type && !info.type.includes('map')) info.flags.push('optional')
245
+ const indentation = moduleIndentationMap[info.type]?.indentation
246
+ let typeName = unnest(info.type || 'bytes')
247
+ if (indentation !== parentName && indentation) typeName = `${indentation.replaceAll('$', '.')}.${typeName}`
248
+ return [`${info.flags.join(' ')}${info.flags.length ? ' ' : ''}${typeName} ${info.name} = ${info.id}${info.packed || ''};`]
249
+ }
250
+
251
+ const decodedProtoMap = {}
252
+
253
+ for (const [, modInfo] of Object.entries(modulesInfo)) {
254
+ if (!modInfo.identifiers) continue
255
+
256
+ const stringifyEnum = (ident, overrideName = null) => [
257
+ `enum ${overrideName || ident.displayName || ident.name} {`,
258
+ ...addPrefix(ident.enumValues.map(v => `${v.name} = ${v.id};`), indent),
259
+ '}',
260
+ ]
261
+
262
+ function stringifyMessage(ident) {
263
+ const nestedKeys = moduleIndentationMap[ident.name]?.members
264
+ const result = [
265
+ `message ${ident.displayName || ident.name} {`,
266
+ ...addPrefix([].concat(...ident.members.map(m => stringifyMember(m, true, ident.name))), indent),
267
+ ]
268
+ if (nestedKeys?.size) {
269
+ for (const memberName of Array.from(nestedKeys).sort()) {
270
+ let entity = modInfo.identifiers[memberName]
271
+ if (entity) {
272
+ entity = { ...entity, displayName: entity.name.slice(ident.name.length + 1) }
273
+ result.push(...addPrefix(getEntity(entity), indent))
274
+ }
275
+ }
276
+ }
277
+ result.push('}', '')
278
+ return result
279
+ }
280
+
281
+ const getEntity = v => {
282
+ if (v.members) return stringifyMessage(v)
283
+ if (v.enumValues?.length) return stringifyEnum(v)
284
+ return [`// Unknown entity ${v.name}`]
285
+ }
286
+
287
+ for (const v of Object.values(modInfo.identifiers))
288
+ if (!moduleIndentationMap[v.name]?.indentation?.length)
289
+ decodedProtoMap[v.name] = getEntity(v).join('\n')
290
+ }
291
+
292
+ const body = Object.keys(decodedProtoMap).sort().map(k => decodedProtoMap[k]).join('\n')
293
+ return `syntax = "proto3";\npackage proto;\n${version ? `\n/// WhatsApp Version: ${version}\n` : ''}\n${body}`
294
+ }
295
+
296
+ export function parseBundle(bundle, version) {
297
+ const sources = Array.isArray(bundle) ? bundle : [bundle]
298
+ const { modulesInfo, moduleIndentationMap } = extractSchema(sources)
299
+ return generateProto3(modulesInfo, moduleIndentationMap, version)
300
+ }
301
+
302
+ export async function parseAndWriteProto(bundle, version, outPath = PROTO_FILE) {
303
+ const protoText = parseBundle(bundle, version)
304
+ const tmp = outPath + '.tmp'
305
+ writeFileSync(tmp, protoText, 'utf8')
306
+ renameSync(tmp, outPath)
307
+ const unknown = [...protoText.matchAll(/\/\/ Unknown entity (.+)/g)].map(m => m[1])
308
+ if (unknown.length) logger.warn(`[WAProto] ${unknown.length} unknown entities: ${unknown.join(', ')}`)
309
+ return {
310
+ messageCount: Object.values(modulesInfo).reduce((s, m) => s + Object.keys(m.identifiers || {}).length, 0),
311
+ unknownCount: unknown.length,
312
+ }
313
+ }
@@ -0,0 +1,10 @@
1
+ const major = parseInt(process.versions.node.split('.')[0], 10);
2
+
3
+ if (major < 20) {
4
+ console.error(
5
+ `\n❌ This package requires Node.js 20+ to run reliably.\n` +
6
+ ` You are using Node.js ${process.versions.node}.\n` +
7
+ ` Please upgrade to Node.js 20+ to proceed.\n`
8
+ );
9
+ process.exit(1);
10
+ }