@zervonex/baileys 0.0.0-stage → 3.0.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.
Files changed (125) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3203 -2
  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 +590 -0
  9. package/lib/Builders/base.js +130 -0
  10. package/lib/Builders/builders.js +448 -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 +904 -0
  26. package/lib/Socket/messages-send.js +693 -0
  27. package/lib/Socket/mex.js +34 -0
  28. package/lib/Socket/newsletter.js +752 -0
  29. package/lib/Socket/nexus-handler.js +55 -0
  30. package/lib/Socket/registration.js +155 -0
  31. package/lib/Socket/socket.js +798 -0
  32. package/lib/Socket/spam-report.js +65 -0
  33. package/lib/Socket/username.js +82 -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 +316 -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 +39 -0
  74. package/lib/Utils/key-store.js +3 -0
  75. package/lib/Utils/link-preview.js +51 -0
  76. package/lib/Utils/logger.js +2 -0
  77. package/lib/Utils/lt-hash.js +3 -0
  78. package/lib/Utils/make-mutex.js +16 -0
  79. package/lib/Utils/message-composer.js +59 -0
  80. package/lib/Utils/message-retry-manager.js +48 -0
  81. package/lib/Utils/messages-media.js +520 -0
  82. package/lib/Utils/messages.js +742 -0
  83. package/lib/Utils/meta-ai-msmsg.js +122 -0
  84. package/lib/Utils/meta-compositing.js +75 -0
  85. package/lib/Utils/modern-messages.js +235 -0
  86. package/lib/Utils/native-flow.js +55 -0
  87. package/lib/Utils/noise-handler.js +161 -0
  88. package/lib/Utils/pre-key-manager.js +76 -0
  89. package/lib/Utils/process-message.js +399 -0
  90. package/lib/Utils/reporting-utils.js +171 -0
  91. package/lib/Utils/signal.js +167 -0
  92. package/lib/Utils/spam-report-utils.js +142 -0
  93. package/lib/Utils/sync-action-utils.js +33 -0
  94. package/lib/Utils/tc-token-utils.js +102 -0
  95. package/lib/Utils/use-multi-file-auth-state.js +307 -0
  96. package/lib/Utils/validate-connection.js +181 -0
  97. package/lib/WABinary/constants.js +1321 -0
  98. package/lib/WABinary/decode.js +152 -0
  99. package/lib/WABinary/encode.js +140 -0
  100. package/lib/WABinary/generic-utils.js +179 -0
  101. package/lib/WABinary/index.js +6 -0
  102. package/lib/WABinary/jid-utils.js +235 -0
  103. package/lib/WABinary/types.js +4 -0
  104. package/lib/WAM/BinaryInfo.js +10 -0
  105. package/lib/WAM/constants.js +22853 -0
  106. package/lib/WAM/encode.js +150 -0
  107. package/lib/WAM/index.js +3 -0
  108. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +30 -0
  109. package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +48 -0
  110. package/lib/WAUSync/Protocols/USyncContactProtocol.js +23 -0
  111. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +28 -0
  112. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +15 -0
  113. package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +24 -0
  114. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +9 -0
  115. package/lib/WAUSync/Protocols/USyncPictureProtocol.js +21 -0
  116. package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +19 -0
  117. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +19 -0
  118. package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +22 -0
  119. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +16 -0
  120. package/lib/WAUSync/Protocols/index.js +12 -0
  121. package/lib/WAUSync/USyncQuery.js +100 -0
  122. package/lib/WAUSync/USyncUser.js +20 -0
  123. package/lib/WAUSync/index.js +3 -0
  124. package/lib/index.js +68 -0
  125. package/package.json +216 -5
@@ -0,0 +1,291 @@
1
+ import { readFileSync, writeFileSync, existsSync } from 'fs'
2
+ import { fileURLToPath } from 'url'
3
+ import Long from 'long'
4
+
5
+ const MAXSAFE = 0x1fffffffffffff
6
+
7
+ const KIND = [
8
+ { k: 'varint', s: 'int' }, { k: 'varint', s: 'zigzag' }, { k: 'varint', s: 'bool' },
9
+ { k: 'i64', s: 'long' }, { k: 'i64', s: 'double' }, { k: 'i32', s: 'int' }, { k: 'i32', s: 'float' },
10
+ { k: 'string' }, { k: 'bytes' }, { k: 'varint', s: 'enum' }, { k: 'varint', s: 'long' }, { k: 'varint', s: 'zigzaglong' },
11
+ ]
12
+
13
+ const SCALAR_TC = {
14
+ int32: 0, uint32: 0, sint32: 1, bool: 2, fixed64: 3, sfixed64: 3, double: 4,
15
+ fixed32: 5, sfixed32: 5, float: 6, string: 7, bytes: 8, int64: 10, uint64: 10, sint64: 11,
16
+ }
17
+
18
+ const isLongLike = v => v !== null && typeof v === 'object' && 'low' in v && 'high' in v
19
+ const longToBigInt = v => (v.unsigned ? BigInt(v.high >>> 0) : BigInt(v.high | 0)) * 4294967296n + BigInt(v.low >>> 0)
20
+ const anyToBigInt = v => typeof v === 'bigint' ? v : isLongLike(v) ? longToBigInt(v) : BigInt(Math.trunc(Number(v)))
21
+ const zigzagEncode = v => BigInt.asUintN(64, anyToBigInt(v) << 1n ^ anyToBigInt(v) >> 63n)
22
+ const numOrBigInt = b => b <= 9007199254740991n && b >= -9007199254740991n ? Number(b) : b
23
+ const toLong = big => Long.fromString(BigInt.asIntN(64, big).toString())
24
+ const wireType = f => f.k === 'varint' ? 0 : f.k === 'i64' ? 1 : f.k === 'i32' ? 5 : 2
25
+
26
+ const toBuffer = v => {
27
+ if (v == null) return Buffer.alloc(0)
28
+ if (Buffer.isBuffer(v)) return v
29
+ if (typeof v === 'string') return Buffer.from(v, 'base64')
30
+ if (v?.type === 'Buffer' && Array.isArray(v.data)) return Buffer.from(v.data)
31
+ if (v instanceof Uint8Array) return Buffer.from(v)
32
+ if (typeof v === 'object') return Buffer.from(JSON.stringify(v))
33
+ return Buffer.alloc(0)
34
+ }
35
+
36
+ const B64_JSON = function () { return this.toString('base64') }
37
+ const tagBytes = b => (Object.defineProperty(b, 'toJSON', { value: B64_JSON, enumerable: false, configurable: true }), b)
38
+
39
+ class Writer {
40
+ constructor() { this.buf = new Uint8Array(256); this.len = 0 }
41
+ _grow(n) {
42
+ if (this.len + n <= this.buf.length) return
43
+ let cap = this.buf.length * 2
44
+ while (cap < this.len + n) cap *= 2
45
+ const next = new Uint8Array(cap)
46
+ next.set(this.buf.subarray(0, this.len))
47
+ this.buf = next
48
+ }
49
+ byte(b) { this._grow(1); this.buf[this.len++] = b }
50
+ raw(u) { this._grow(u.length); this.buf.set(u, this.len); this.len += u.length }
51
+ tag(f, wire) { this.varintNum(f * 8 + wire) }
52
+ varintNum(n) { this._grow(10); while (n > 0x7f) { this.buf[this.len++] = (n & 0x7f) | 0x80; n = Math.floor(n / 128) }; this.buf[this.len++] = n }
53
+ varintBig(v) { this._grow(10); let n = BigInt.asUintN(64, v); while (n > 0x7fn) { this.buf[this.len++] = Number((n & 0x7fn) | 0x80n); n >>= 7n }; this.buf[this.len++] = Number(n) }
54
+ vint(v) { typeof v === 'number' && v >= 0 && v <= MAXSAFE && Number.isInteger(v) ? this.varintNum(v) : this.varintBig(anyToBigInt(v)) }
55
+ fixed32(v) { this._grow(4); const n = Number(BigInt.asUintN(32, anyToBigInt(v))) >>> 0; this.buf[this.len++] = n & 0xff; this.buf[this.len++] = (n >>> 8) & 0xff; this.buf[this.len++] = (n >>> 16) & 0xff; this.buf[this.len++] = (n >>> 24) & 0xff }
56
+ fixed64(v) { this._grow(8); const b = Buffer.allocUnsafe(8); b.writeBigUInt64LE(BigInt.asUintN(64, anyToBigInt(v))); this.raw(b) }
57
+ float(v) { this._grow(4); const b = Buffer.allocUnsafe(4); b.writeFloatLE(v); this.raw(b) }
58
+ double(v) { this._grow(8); const b = Buffer.allocUnsafe(8); b.writeDoubleLE(v); this.raw(b) }
59
+ finish() { return Buffer.from(this.buf.buffer, this.buf.byteOffset, this.len) }
60
+ }
61
+
62
+ class Reader {
63
+ constructor(buf) { this.buf = Buffer.isBuffer(buf) ? buf : Buffer.from(buf); this.p = 0; this.len = this.buf.length }
64
+ _check(n) { if (this.p + n > this.len) throw new RangeError(`[WAProto] buffer overread: need ${n} bytes at ${this.p}, have ${this.len - this.p}`) }
65
+ varint() {
66
+ let r = 0, mult = 1, b, n = 0
67
+ do {
68
+ if (this.p >= this.len) throw new RangeError('[WAProto] varint: unexpected end of buffer')
69
+ b = this.buf[this.p++]; r += (b & 0x7f) * mult; mult *= 128; n++
70
+ if (n > 10) throw new RangeError('[WAProto] varint: too many bytes')
71
+ } while (b & 0x80)
72
+ return r > Number.MAX_SAFE_INTEGER ? Number(BigInt.asIntN(64, BigInt(Math.trunc(r)))) : r
73
+ }
74
+ varintBig() {
75
+ let r = 0n, s = 0n, b, n = 0
76
+ do {
77
+ if (this.p >= this.len) throw new RangeError('[WAProto] varintBig: unexpected end of buffer')
78
+ b = this.buf[this.p++]; r |= BigInt(b & 0x7f) << s; s += 7n; n++
79
+ if (n > 10) throw new RangeError('[WAProto] varintBig: too many bytes')
80
+ } while (b & 0x80)
81
+ return r
82
+ }
83
+ skipVarint() { let n = 0; while (this.p < this.len && this.buf[this.p++] & 0x80) { if (++n > 10) throw new RangeError('[WAProto] skipVarint overflow') } }
84
+ u32() { this._check(4); const p = this.p; this.p += 4; return (this.buf[p] | this.buf[p + 1] << 8 | this.buf[p + 2] << 16 | this.buf[p + 3] << 24) >>> 0 }
85
+ slice(len) { if (len < 0 || this.p + len > this.len) throw new RangeError(`[WAProto] slice: invalid length ${len} at ${this.p}`); const s = this.buf.subarray(this.p, this.p + len); this.p += len; return s }
86
+ read8() { this._check(8); const b = this.buf.subarray(this.p, this.p + 8); this.p += 8; return b }
87
+ read4() { this._check(4); const b = this.buf.subarray(this.p, this.p + 4); this.p += 4; return b }
88
+ }
89
+
90
+ function buildTable(rawTable, msgNames) {
91
+ const TABLE = {}
92
+ for (const [full, fields] of Object.entries(rawTable)) {
93
+ const order = fields.map(([name, id, tc, flags = 0, enumName]) => {
94
+ const base = tc >= 100 ? { k: 'msg', msg: msgNames[tc - 100] } : KIND[tc]
95
+ const f = { name, id, ...base, rep: !!(flags & 1), packed: !!(flags & 2) }
96
+ if (tc === 9 && enumName) f.enumName = enumName
97
+ return f
98
+ })
99
+ TABLE[full] = { order, byId: Object.fromEntries(order.map(f => [f.id, f])) }
100
+ }
101
+ return TABLE
102
+ }
103
+
104
+ function makeCodec(TABLE, enumIndex) {
105
+ function resolveEnum(f, v) {
106
+ if (typeof v !== 'string') return v
107
+ if (f.enumName && enumIndex[f.enumName]) { const n = enumIndex[f.enumName][v]; if (n !== undefined) return n }
108
+ const n = Number(v)
109
+ return Number.isFinite(n) ? n : undefined
110
+ }
111
+
112
+ function writeScalar(w, f, v) {
113
+ switch (f.k) {
114
+ case 'varint':
115
+ if (f.s === 'bool') w.byte(v ? 1 : 0)
116
+ else if (f.s === 'zigzag' || f.s === 'zigzaglong') w.varintBig(zigzagEncode(v))
117
+ else w.vint(v)
118
+ break
119
+ case 'i64': f.s === 'double' ? w.double(v) : w.fixed64(v); break
120
+ case 'i32': f.s === 'float' ? w.float(v) : w.fixed32(v); break
121
+ case 'string': { const b = Buffer.from(String(v), 'utf8'); w.varintNum(b.length); w.raw(b); break }
122
+ case 'bytes': { const b = toBuffer(v); w.varintNum(b.length); w.raw(b); break }
123
+ case 'msg': { const s = new Writer(); encodeMsg(s, TABLE[f.msg], v); const b = s.finish(); w.varintNum(b.length); w.raw(b); break }
124
+ }
125
+ }
126
+
127
+ function encodeMsg(w, T, obj) {
128
+ if (!T) throw new Error('[WAProto] Unknown message in table')
129
+ for (const f of T.order) {
130
+ let v = obj[f.name]
131
+ if (v == null) continue
132
+ if (f.s === 'enum') {
133
+ if (f.rep) { v = (Array.isArray(v) ? v : [v]).map(x => resolveEnum(f, x)).filter(x => x !== undefined); if (!v.length) continue }
134
+ else { v = resolveEnum(f, v); if (v === undefined) continue }
135
+ }
136
+ if (f.rep) {
137
+ if (!Array.isArray(v)) v = [v]
138
+ if (f.packed && (f.k === 'varint' || f.k === 'i64' || f.k === 'i32')) {
139
+ const s = new Writer()
140
+ for (const item of v) writeScalar(s, f, item)
141
+ const b = s.finish()
142
+ w.tag(f.id, 2); w.varintNum(b.length); w.raw(b)
143
+ } else { const wt = wireType(f); for (const item of v) { w.tag(f.id, wt); writeScalar(w, f, item) } }
144
+ } else { w.tag(f.id, wireType(f)); writeScalar(w, f, v) }
145
+ }
146
+ }
147
+
148
+ function readScalar(r, f) {
149
+ switch (f.k) {
150
+ case 'varint': {
151
+ if (f.s === 'bool') return !!r.varint()
152
+ if (f.s === 'zigzag') { const u = r.varintBig(); return numOrBigInt(u >> 1n ^ -(u & 1n)) }
153
+ if (f.s === 'zigzaglong') { const u = r.varintBig(); return toLong(u >> 1n ^ -(u & 1n)) }
154
+ if (f.s === 'enum') return r.varint() | 0
155
+ if (f.s === 'long') return toLong(BigInt(r.varint()))
156
+ return r.varint()
157
+ }
158
+ case 'i64': { const b = Buffer.from(r.read8()); return f.s === 'double' ? b.readDoubleLE(0) : toLong(b.readBigUInt64LE(0)) }
159
+ case 'i32': { if (f.s === 'float') { const b = Buffer.from(r.read4()); return b.readFloatLE(0) }; return r.u32() }
160
+ case 'string': { const len = r.varint(); return Buffer.from(r.slice(len)).toString('utf8') }
161
+ case 'bytes': return tagBytes(Buffer.from(r.slice(r.varint())))
162
+ case 'msg': return decodeMsg(f.msg, r.slice(r.varint()))
163
+ }
164
+ }
165
+
166
+ function skip(r, wire) {
167
+ if (wire === 0) r.skipVarint()
168
+ else if (wire === 2) { const n = r.varint(); r.slice(n) }
169
+ else if (wire === 1) r.read8()
170
+ else if (wire === 5) r.read4()
171
+ }
172
+
173
+ function decodeMsg(msgName, buf) {
174
+ const T = TABLE[msgName]
175
+ if (!T) throw new Error(`[WAProto] Unknown message: ${msgName}`)
176
+ const obj = {}, r = new Reader(buf)
177
+ while (r.p < r.len) {
178
+ let tag, id, wire
179
+ try { tag = r.varint(); id = tag >>> 3; wire = tag & 7 } catch { break }
180
+ const f = T.byId[id]
181
+ if (!f) { try { skip(r, wire) } catch { break }; continue }
182
+ try {
183
+ if (f.rep && wire === 2 && (f.k === 'varint' || f.k === 'i64' || f.k === 'i32')) {
184
+ const len = r.varint(), end = r.p + len
185
+ const arr = obj[f.name] || (obj[f.name] = [])
186
+ while (r.p < end) arr.push(readScalar(r, f))
187
+ } else {
188
+ const val = readScalar(r, f)
189
+ if (f.rep) (obj[f.name] || (obj[f.name] = [])).push(val)
190
+ else obj[f.name] = val
191
+ }
192
+ } catch { break }
193
+ }
194
+ return obj
195
+ }
196
+
197
+ return {
198
+ encode: (msgName, obj) => { const w = new Writer(); encodeMsg(w, TABLE[msgName], obj ?? {}); return w.finish() },
199
+ decode: (msgName, buf) => decodeMsg(msgName, buf),
200
+ }
201
+ }
202
+
203
+ export async function generateTable(protoPath, outPath) {
204
+ const pb = await import('protobufjs')
205
+ const protobuf = pb.default || pb
206
+ const root = await protobuf.load(protoPath)
207
+ const msgNames = []
208
+ const msgIndex = n => { let i = msgNames.indexOf(n); return i < 0 ? msgNames.push(n) - 1 : i }
209
+ const t = {}, e = {}
210
+ const build = ns => {
211
+ for (const o of Object.values(ns.nested ?? {})) {
212
+ const full = o.fullName.replace(/^\./, '')
213
+ if (o.values) e[full] = o.values
214
+ if (o.fieldsArray) {
215
+ const fs = []
216
+ for (const f of o.fieldsArray) {
217
+ if (f.map) continue
218
+ const rt = f.resolvedType
219
+ let tc, enumName
220
+ if (rt?.fieldsArray !== undefined && rt?.values === undefined) tc = 100 + msgIndex(rt.fullName.replace(/^\./, ''))
221
+ else if (rt?.values) { tc = 9; enumName = rt.fullName.replace(/^\./, '') }
222
+ else tc = SCALAR_TC[f.type]
223
+ const numeric = tc < 100 && tc !== 7 && tc !== 8
224
+ const flags = (f.repeated ? 1 : 0) | (f.repeated && numeric && f.packed !== false ? 2 : 0)
225
+ if (tc === 9) fs.push([f.name, f.id, 9, flags, enumName])
226
+ else if (flags) fs.push([f.name, f.id, tc, flags])
227
+ else fs.push([f.name, f.id, tc])
228
+ }
229
+ fs.sort((a, b) => a[1] - b[1])
230
+ t[full] = fs
231
+ }
232
+ if (o.nested) build(o)
233
+ }
234
+ }
235
+ build(root)
236
+ const tmp = outPath + '.tmp'
237
+ writeFileSync(tmp, JSON.stringify({ m: msgNames, t, e }))
238
+ const { renameSync } = await import('fs')
239
+ renameSync(tmp, outPath)
240
+ return { types: Object.keys(t).length, enums: Object.keys(e).length }
241
+ }
242
+
243
+ function makeProto(tablePath) {
244
+ const { m, t, e } = JSON.parse(readFileSync(tablePath, 'utf8'))
245
+ const TABLE = buildTable(t, m)
246
+ const codec = makeCodec(TABLE, e)
247
+ const proto = {}
248
+ const nodeFor = path => { let c = proto; for (const p of path) c = c[p] ?? (c[p] = {}); return c }
249
+ for (const full of Object.keys(t)) {
250
+ const node = nodeFor(full.replace(/^proto\./, '').split('.'))
251
+ node.encode = o => ({ finish: () => codec.encode(full, o ?? {}) })
252
+ node.decode = b => codec.decode(full, b)
253
+ node.create = o => o ?? {}
254
+ node.fromObject = o => o ?? {}
255
+ node.toObject = o => o ?? {}
256
+ node.verify = () => null
257
+ node.name = full.split('.').pop()
258
+ }
259
+ for (const [full, values] of Object.entries(e)) {
260
+ const node = nodeFor(full.replace(/^proto\./, '').split('.'))
261
+ for (const [k, v] of Object.entries(values)) { node[k] = v; node[v] = k }
262
+ }
263
+ return { proto, codec }
264
+ }
265
+
266
+ const isGeneratorRun = process.argv[1] && (process.argv[1] === fileURLToPath(import.meta.url) || process.argv.includes('--generate'))
267
+
268
+ if (isGeneratorRun) {
269
+ const protoPath = fileURLToPath(new URL('./WAProto.proto', import.meta.url))
270
+ const outPath = fileURLToPath(new URL('./WAProto.json', import.meta.url))
271
+ generateTable(protoPath, outPath)
272
+ .then(r => { process.stdout.write(`[WAProto] Generated: ${r.types} types, ${r.enums} enums\n`); process.exit(0) })
273
+ .catch(err => { process.stderr.write(err.message + '\n'); process.exit(1) })
274
+ }
275
+
276
+ const tablePath = fileURLToPath(new URL('./WAProto.json', import.meta.url))
277
+ const built = { proto: {}, codec: null }
278
+
279
+ export function _reloadProto() {
280
+ if (!existsSync(tablePath)) return
281
+ const loaded = makeProto(tablePath)
282
+ for (const key of Object.keys(built.proto)) delete built.proto[key]
283
+ Object.assign(built.proto, loaded.proto)
284
+ built.codec = loaded.codec
285
+ }
286
+
287
+ if (!isGeneratorRun && existsSync(tablePath)) _reloadProto()
288
+
289
+ export const proto = built.proto
290
+ export const codec = built.codec
291
+ export default built
@@ -0,0 +1,69 @@
1
+ import { fetch, Agent } from 'undici'
2
+ import { createHash } from 'crypto'
3
+ import { readFileSync, writeFileSync, existsSync } from 'fs'
4
+ import { join, dirname } from 'path'
5
+ import { fileURLToPath } from 'url'
6
+
7
+ const __dirname = dirname(fileURLToPath(import.meta.url))
8
+ const CACHE_FILE = join(__dirname, '.cache.json')
9
+ const PROTO_FILE = join(__dirname, 'WAProto.proto')
10
+
11
+ const GITHUB_RAW = 'https://raw.githubusercontent.com/nexustechpro2/baileys/main/.wa-cache'
12
+ const CACHE_TTL = 24 * 60 * 60 * 1000
13
+
14
+ const agent = new Agent({ connect: { family: 4 } })
15
+
16
+ const isCacheValid = (cache) => cache.version && cache.timestamp && (Date.now() - cache.timestamp) < CACHE_TTL
17
+ const readCache = () => { try { return existsSync(CACHE_FILE) ? JSON.parse(readFileSync(CACHE_FILE, 'utf8')) : {} } catch { return {} } }
18
+ const writeCache = (data) => writeFileSync(CACHE_FILE, JSON.stringify({ ...data, timestamp: Date.now() }, null, 2), 'utf8')
19
+
20
+ async function fetchFromGitHub(file) {
21
+ const res = await fetch(`${GITHUB_RAW}/${file}`, { method: 'GET', dispatcher: agent })
22
+ if (!res.ok) throw new Error(`[WAProto] GitHub fetch failed: ${res.status} for ${file}`)
23
+ return file.endsWith('.json') ? res.json() : res.text()
24
+ }
25
+
26
+ async function fetchClientRevision() {
27
+ const data = await fetchFromGitHub('wa-version.json')
28
+ if (!data?.version) throw new Error('[WAProto] GitHub wa-version.json missing version field')
29
+ return String(data.version)
30
+ }
31
+
32
+ async function fetchCombinedBundle() {
33
+ return fetchFromGitHub('WAProto.bundle.js')
34
+ }
35
+
36
+ export async function fetchProtoBundle() {
37
+ const cache = readCache()
38
+ if (isCacheValid(cache) && existsSync(PROTO_FILE)) return { changed: false, bundle: null, version: cache.version }
39
+
40
+ const version = await fetchClientRevision()
41
+
42
+ if (cache.version === version && existsSync(PROTO_FILE)) {
43
+ writeCache({ ...cache, version })
44
+ return { changed: false, bundle: null, version }
45
+ }
46
+
47
+ let bundle = await fetchCombinedBundle()
48
+ const hash = createHash('sha256').update(bundle).digest('hex')
49
+
50
+ if (cache.hash === hash) {
51
+ writeCache({ version, hash })
52
+ return { changed: false, bundle: null, version }
53
+ }
54
+
55
+ writeCache({ version, hash })
56
+ const result = { changed: true, bundle, version }
57
+ bundle = null
58
+ return result
59
+ }
60
+
61
+ export async function getWAVersion() {
62
+ const cache = readCache()
63
+ if (isCacheValid(cache) && cache.version) return [2, 3000, parseInt(cache.version)]
64
+
65
+ const data = await fetchFromGitHub('wa-version.json')
66
+ if (!data?.version) throw new Error('[WAProto] GitHub wa-version.json missing version field')
67
+
68
+ return [2, 3000, parseInt(data.version)]
69
+ }
@@ -0,0 +1,88 @@
1
+ import { existsSync, unlinkSync, readFileSync } from 'fs'
2
+ import { join, dirname } from 'path'
3
+ import { fileURLToPath } from 'url'
4
+ import logger from '../lib/Utils/logger.js'
5
+ import { fetchProtoBundle } from './fetcher.js'
6
+ import { generateTable, _reloadProto } from './WAProtoCompile.js'
7
+ import { parseBundle } from './parser.js'
8
+
9
+ const __dirname = dirname(fileURLToPath(import.meta.url))
10
+ const PROTO_FILE = join(__dirname, 'WAProto.proto')
11
+ const TABLE_FILE = join(__dirname, 'WAProto.json')
12
+
13
+ const log = msg => logger.info(msg)
14
+ const err = msg => logger.error(msg)
15
+
16
+ const isJsonValid = () => {
17
+ try {
18
+ const { m, t } = JSON.parse(readFileSync(TABLE_FILE, 'utf8'))
19
+ return Array.isArray(m) && m.length > 0 && typeof t === 'object' && Object.keys(t).length > 0
20
+ } catch { return false }
21
+ }
22
+
23
+ const del = (...files) => { for (const f of files) { try { if (existsSync(f)) unlinkSync(f) } catch { } } }
24
+
25
+ async function regenerateFromProto() {
26
+ log('Regenerating WAProto.json from existing WAProto.proto...')
27
+ await generateTable(PROTO_FILE, TABLE_FILE)
28
+ _reloadProto()
29
+ log('Regenerated successfully')
30
+ }
31
+
32
+ async function refetch() {
33
+ log('Fetching proto bundle from WhatsApp Web...')
34
+ const { bundle, version } = await fetchProtoBundle()
35
+ if (!bundle) throw new Error('fetchProtoBundle returned no bundle')
36
+ const protoText = parseBundle(bundle, version)
37
+ const { writeFileSync } = await import('fs')
38
+ const tmp = PROTO_FILE + '.tmp'
39
+ writeFileSync(tmp, protoText, 'utf8')
40
+ const { renameSync } = await import('fs')
41
+ renameSync(tmp, PROTO_FILE)
42
+ await generateTable(PROTO_FILE, TABLE_FILE)
43
+ _reloadProto()
44
+ log(`Fetched and compiled — WA version ${version}`)
45
+ }
46
+
47
+ async function boot() {
48
+ const hasProto = existsSync(PROTO_FILE)
49
+ const hasJson = existsSync(TABLE_FILE)
50
+
51
+ if (hasProto && hasJson) {
52
+ if (isJsonValid()) { _reloadProto(); return }
53
+ err('WAProto.json is invalid or corrupt — regenerating from proto...')
54
+ del(TABLE_FILE)
55
+ try { await regenerateFromProto(); return } catch (e) {
56
+ err(`Regeneration failed: ${e.message} — refetching from WA Web...`)
57
+ del(PROTO_FILE, TABLE_FILE)
58
+ await refetch()
59
+ }
60
+ return
61
+ }
62
+
63
+ if (hasProto && !hasJson) {
64
+ log('WAProto.json missing — generating from existing proto...')
65
+ try { await regenerateFromProto(); return } catch (e) {
66
+ err(`Generation failed: ${e.message} — refetching from WA Web...`)
67
+ del(PROTO_FILE, TABLE_FILE)
68
+ await refetch()
69
+ }
70
+ return
71
+ }
72
+
73
+ if (hasJson && !hasProto) {
74
+ err('WAProto.proto missing but WAProto.json exists — cannot trust JSON, refetching...')
75
+ del(TABLE_FILE)
76
+ await refetch()
77
+ return
78
+ }
79
+
80
+ log('No proto files found — fetching from WA Web...')
81
+ await refetch()
82
+ }
83
+
84
+ await boot()
85
+
86
+ export { proto, codec, generateTable, _reloadProto } from './WAProtoCompile.js'
87
+ export { getWAVersion, fetchProtoBundle } from './fetcher.js'
88
+ export { default } from './WAProtoCompile.js'