@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.
- package/LICENSE +21 -0
- package/README.md +3206 -3
- package/WAProto/WAProtoCompile.js +291 -0
- package/WAProto/fetcher.js +69 -0
- package/WAProto/index.js +88 -0
- package/WAProto/parser.js +313 -0
- package/engine-requirements.js +10 -0
- package/lib/Builders/AIRich.js +643 -0
- package/lib/Builders/base.js +130 -0
- package/lib/Builders/builders.js +449 -0
- package/lib/Builders/index.js +3 -0
- package/lib/Defaults/index.js +225 -0
- package/lib/Defaults/phonenumber-mcc.json +223 -0
- package/lib/Signal/index.js +2 -0
- package/lib/Signal/libsignal.js +523 -0
- package/lib/Signal/lid-mapping.js +283 -0
- package/lib/Socket/Client/index.js +2 -0
- package/lib/Socket/Client/types.js +10 -0
- package/lib/Socket/Client/websocket.js +84 -0
- package/lib/Socket/business.js +152 -0
- package/lib/Socket/chats.js +855 -0
- package/lib/Socket/communities.js +147 -0
- package/lib/Socket/groups.js +294 -0
- package/lib/Socket/index.js +15 -0
- package/lib/Socket/messages-recv.js +981 -0
- package/lib/Socket/messages-send.js +708 -0
- package/lib/Socket/mex.js +34 -0
- package/lib/Socket/newsletter.js +781 -0
- package/lib/Socket/registration.js +155 -0
- package/lib/Socket/socket.js +797 -0
- package/lib/Socket/spam-report.js +65 -0
- package/lib/Socket/username.js +82 -0
- package/lib/Socket/zervonex-handler.js +55 -0
- package/lib/Store/index.js +6 -0
- package/lib/Store/make-cache-manager-store.js +81 -0
- package/lib/Store/make-in-memory-store.js +425 -0
- package/lib/Store/make-ordered-dictionary.js +82 -0
- package/lib/Store/object-repository.js +31 -0
- package/lib/Store/reporting-info-store.js +38 -0
- package/lib/Types/Auth.js +2 -0
- package/lib/Types/Bussines.js +2 -0
- package/lib/Types/Call.js +2 -0
- package/lib/Types/Chat.js +8 -0
- package/lib/Types/Contact.js +2 -0
- package/lib/Types/Events.js +2 -0
- package/lib/Types/GroupMetadata.js +2 -0
- package/lib/Types/Label.js +25 -0
- package/lib/Types/LabelAssociation.js +7 -0
- package/lib/Types/Message.js +15 -0
- package/lib/Types/Newsletter.js +100 -0
- package/lib/Types/Product.js +2 -0
- package/lib/Types/Signal.js +2 -0
- package/lib/Types/Socket.js +14 -0
- package/lib/Types/State.js +26 -0
- package/lib/Types/USync.js +2 -0
- package/lib/Types/index.js +30 -0
- package/lib/Utils/auth-utils.js +142 -0
- package/lib/Utils/baileys-event-stream.js +33 -0
- package/lib/Utils/bot-capabilities.js +40 -0
- package/lib/Utils/bot-planning-replay.js +44 -0
- package/lib/Utils/browser-utils.js +26 -0
- package/lib/Utils/business.js +75 -0
- package/lib/Utils/chat-utils.js +317 -0
- package/lib/Utils/companion-reg-client-utils.js +20 -0
- package/lib/Utils/consumer-application.js +38 -0
- package/lib/Utils/crypto.js +52 -0
- package/lib/Utils/decode-wa-message.js +197 -0
- package/lib/Utils/event-buffer.js +273 -0
- package/lib/Utils/extras.js +186 -0
- package/lib/Utils/generics.js +195 -0
- package/lib/Utils/history.js +51 -0
- package/lib/Utils/identity-change-handler.js +19 -0
- package/lib/Utils/index.js +38 -0
- package/lib/Utils/link-preview.js +51 -0
- package/lib/Utils/logger.js +2 -0
- package/lib/Utils/lt-hash.js +3 -0
- package/lib/Utils/make-mutex.js +16 -0
- package/lib/Utils/message-composer.js +59 -0
- package/lib/Utils/message-retry-manager.js +48 -0
- package/lib/Utils/messages-media.js +520 -0
- package/lib/Utils/messages.js +752 -0
- package/lib/Utils/meta-ai-msmsg.js +122 -0
- package/lib/Utils/meta-compositing.js +75 -0
- package/lib/Utils/modern-messages.js +235 -0
- package/lib/Utils/native-flow.js +55 -0
- package/lib/Utils/noise-handler.js +161 -0
- package/lib/Utils/pre-key-manager.js +76 -0
- package/lib/Utils/process-message.js +399 -0
- package/lib/Utils/reporting-utils.js +171 -0
- package/lib/Utils/signal.js +167 -0
- package/lib/Utils/spam-report-utils.js +135 -0
- package/lib/Utils/sync-action-utils.js +33 -0
- package/lib/Utils/tc-token-utils.js +154 -0
- package/lib/Utils/use-multi-file-auth-state.js +307 -0
- package/lib/Utils/validate-connection.js +181 -0
- package/lib/WABinary/constants.js +1321 -0
- package/lib/WABinary/decode.js +152 -0
- package/lib/WABinary/encode.js +140 -0
- package/lib/WABinary/generic-utils.js +179 -0
- package/lib/WABinary/index.js +6 -0
- package/lib/WABinary/jid-utils.js +235 -0
- package/lib/WABinary/types.js +4 -0
- package/lib/WAM/BinaryInfo.js +10 -0
- package/lib/WAM/constants.js +22853 -0
- package/lib/WAM/encode.js +150 -0
- package/lib/WAM/index.js +3 -0
- package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +30 -0
- package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +48 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +23 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +28 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +15 -0
- package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +24 -0
- package/lib/WAUSync/Protocols/USyncLIDProtocol.js +9 -0
- package/lib/WAUSync/Protocols/USyncPictureProtocol.js +21 -0
- package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +19 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +19 -0
- package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +22 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +16 -0
- package/lib/WAUSync/Protocols/index.js +12 -0
- package/lib/WAUSync/USyncQuery.js +100 -0
- package/lib/WAUSync/USyncUser.js +20 -0
- package/lib/WAUSync/index.js +3 -0
- package/lib/index.js +67 -0
- package/package.json +220 -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/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
|
+
}
|
package/WAProto/index.js
ADDED
|
@@ -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 GitHub...')
|
|
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 GitHub...')
|
|
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'
|