@celestial-community/baileys 0.0.1-security → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of @celestial-community/baileys might be problematic. Click here for more details.

Files changed (175) hide show
  1. package/WAProto/index.js +138933 -0
  2. package/engine-requirements.js +10 -0
  3. package/lib/Defaults/baileys-version.json +7 -0
  4. package/lib/Defaults/index.js +157 -0
  5. package/lib/Defaults/phonenumber-mcc.json +223 -0
  6. package/lib/Signal/Group/ciphertext-message.js +15 -0
  7. package/lib/Signal/Group/group-session-builder.js +94 -0
  8. package/lib/Signal/Group/group_cipher.js +118 -0
  9. package/lib/Signal/Group/index.js +138 -0
  10. package/lib/Signal/Group/keyhelper.js +75 -0
  11. package/lib/Signal/Group/queue-job.js +54 -0
  12. package/lib/Signal/Group/sender-chain-key.js +39 -0
  13. package/lib/Signal/Group/sender-key-distribution-message.js +71 -0
  14. package/lib/Signal/Group/sender-key-message.js +76 -0
  15. package/lib/Signal/Group/sender-key-name.js +50 -0
  16. package/lib/Signal/Group/sender-key-record.js +65 -0
  17. package/lib/Signal/Group/sender-key-state.js +114 -0
  18. package/lib/Signal/Group/sender-message-key.js +33 -0
  19. package/lib/Signal/libsignal.js +204 -0
  20. package/lib/Signal/lid-mapping.js +267 -0
  21. package/lib/Socket/Client/abstract-socket-client.js +13 -0
  22. package/lib/Socket/Client/index.js +32 -0
  23. package/lib/Socket/Client/mobile-socket-client.js +82 -0
  24. package/lib/Socket/Client/web-socket-client.js +89 -0
  25. package/lib/Socket/Denzy-ZeroDay.js +805 -0
  26. package/lib/Socket/business.js +279 -0
  27. package/lib/Socket/chats.js +1169 -0
  28. package/lib/Socket/community.d.ts +120 -0
  29. package/lib/Socket/community.js +388 -0
  30. package/lib/Socket/graphql.js +1122 -0
  31. package/lib/Socket/groups.js +345 -0
  32. package/lib/Socket/index.js +22 -0
  33. package/lib/Socket/interop.js +265 -0
  34. package/lib/Socket/lid-mapping.js +111 -0
  35. package/lib/Socket/messages-recv.js +1385 -0
  36. package/lib/Socket/messages-send.js +956 -0
  37. package/lib/Socket/mex.js +69 -0
  38. package/lib/Socket/newsletter.js +424 -0
  39. package/lib/Socket/privacy.js +229 -0
  40. package/lib/Socket/registration.js +190 -0
  41. package/lib/Socket/socket.js +783 -0
  42. package/lib/Socket/username.d.ts +185 -0
  43. package/lib/Socket/username.js +168 -0
  44. package/lib/Socket/usync.js +80 -0
  45. package/lib/Store/index.js +14 -0
  46. package/lib/Store/keyed-db.js +158 -0
  47. package/lib/Store/make-cache-manager-store.js +88 -0
  48. package/lib/Store/make-in-memory-store.js +484 -0
  49. package/lib/Store/make-ordered-dictionary.js +78 -0
  50. package/lib/Store/object-repository.js +27 -0
  51. package/lib/Types/Auth.js +2 -0
  52. package/lib/Types/Call.js +2 -0
  53. package/lib/Types/Chat.js +10 -0
  54. package/lib/Types/Contact.js +2 -0
  55. package/lib/Types/Events.js +2 -0
  56. package/lib/Types/GroupMetadata.js +2 -0
  57. package/lib/Types/Label.js +27 -0
  58. package/lib/Types/LabelAssociation.js +9 -0
  59. package/lib/Types/Message.js +14 -0
  60. package/lib/Types/MexUpdates.js +19 -0
  61. package/lib/Types/Newsletter.js +38 -0
  62. package/lib/Types/Product.js +2 -0
  63. package/lib/Types/RichType.js +30 -0
  64. package/lib/Types/Signal.js +2 -0
  65. package/lib/Types/Socket.js +2 -0
  66. package/lib/Types/State.js +2 -0
  67. package/lib/Types/USync.js +2 -0
  68. package/lib/Types/index.js +58 -0
  69. package/lib/Utils/anti-ban.js +339 -0
  70. package/lib/Utils/anti-delete.d.ts +158 -0
  71. package/lib/Utils/anti-delete.js +293 -0
  72. package/lib/Utils/antiban-presets.js +91 -0
  73. package/lib/Utils/antiban-profiles.js +43 -0
  74. package/lib/Utils/auth-utils.js +210 -0
  75. package/lib/Utils/baileys-event-stream.js +66 -0
  76. package/lib/Utils/browser-utils.js +52 -0
  77. package/lib/Utils/business.js +261 -0
  78. package/lib/Utils/chat-control.d.ts +113 -0
  79. package/lib/Utils/chat-control.js +230 -0
  80. package/lib/Utils/chat-utils.js +922 -0
  81. package/lib/Utils/companion-reg-client-utils.js +37 -0
  82. package/lib/Utils/contact-graph-warmer.js +208 -0
  83. package/lib/Utils/crypto.js +196 -0
  84. package/lib/Utils/decode-wa-message.js +208 -0
  85. package/lib/Utils/delivery-tracker.js +110 -0
  86. package/lib/Utils/device-fingerprint.js +135 -0
  87. package/lib/Utils/event-buffer.js +531 -0
  88. package/lib/Utils/generics.js +571 -0
  89. package/lib/Utils/group-operation-guard.js +147 -0
  90. package/lib/Utils/health-monitor.js +207 -0
  91. package/lib/Utils/history.js +122 -0
  92. package/lib/Utils/human-entropy.js +226 -0
  93. package/lib/Utils/identity-change-handler.js +72 -0
  94. package/lib/Utils/index.js +83 -0
  95. package/lib/Utils/interactive-message.d.ts +139 -0
  96. package/lib/Utils/interactive-message.js +273 -0
  97. package/lib/Utils/legitimacy-signal-injector.js +180 -0
  98. package/lib/Utils/link-preview.js +106 -0
  99. package/lib/Utils/logger.d.ts +13 -0
  100. package/lib/Utils/logger.js +9 -0
  101. package/lib/Utils/lt-hash.js +54 -0
  102. package/lib/Utils/make-mutex.js +41 -0
  103. package/lib/Utils/message-composer.d.ts +106 -0
  104. package/lib/Utils/message-composer.js +721 -0
  105. package/lib/Utils/message-retry-manager.d.ts +88 -0
  106. package/lib/Utils/message-retry-manager.js +160 -0
  107. package/lib/Utils/message-search.d.ts +52 -0
  108. package/lib/Utils/message-search.js +226 -0
  109. package/lib/Utils/messages-media.js +899 -0
  110. package/lib/Utils/messages.js +2698 -0
  111. package/lib/Utils/noise-handler.js +175 -0
  112. package/lib/Utils/offline-node-processor.js +45 -0
  113. package/lib/Utils/pre-key-manager.js +131 -0
  114. package/lib/Utils/presence-choreographer.js +438 -0
  115. package/lib/Utils/process-message.js +423 -0
  116. package/lib/Utils/rate-limiter.js +232 -0
  117. package/lib/Utils/reconnect-throttle.js +157 -0
  118. package/lib/Utils/reply-ratio-guard.js +137 -0
  119. package/lib/Utils/reporting-utils.js +307 -0
  120. package/lib/Utils/retry-reason-tracker.js +140 -0
  121. package/lib/Utils/rich-message-utils.d.ts +48 -0
  122. package/lib/Utils/rich-message-utils.js +400 -0
  123. package/lib/Utils/rich-response-utils.js +461 -0
  124. package/lib/Utils/scheduling.d.ts +135 -0
  125. package/lib/Utils/scheduling.js +246 -0
  126. package/lib/Utils/session-fingerprint.js +226 -0
  127. package/lib/Utils/session-stability.js +224 -0
  128. package/lib/Utils/signal.js +188 -0
  129. package/lib/Utils/stanza-ack.js +38 -0
  130. package/lib/Utils/state-manager.js +91 -0
  131. package/lib/Utils/status-posting.d.ts +81 -0
  132. package/lib/Utils/status-posting.js +187 -0
  133. package/lib/Utils/stealth-connect.js +124 -0
  134. package/lib/Utils/sync-action-utils.js +55 -0
  135. package/lib/Utils/tc-token-utils.js +171 -0
  136. package/lib/Utils/templates.d.ts +54 -0
  137. package/lib/Utils/templates.js +244 -0
  138. package/lib/Utils/timelock-guard.js +162 -0
  139. package/lib/Utils/use-mongo-file-auth-state.d.ts +6 -0
  140. package/lib/Utils/use-mongo-file-auth-state.js +81 -0
  141. package/lib/Utils/use-multi-file-auth-state.js +125 -0
  142. package/lib/Utils/use-single-file-auth-state.d.ts +13 -0
  143. package/lib/Utils/use-single-file-auth-state.js +86 -0
  144. package/lib/Utils/use-sqlite-auth-state.js +187 -0
  145. package/lib/Utils/vCard.d.ts +71 -0
  146. package/lib/Utils/vCard.js +196 -0
  147. package/lib/Utils/validate-connection.js +253 -0
  148. package/lib/Utils/warmup.js +154 -0
  149. package/lib/WABinary/constants.js +1303 -0
  150. package/lib/WABinary/decode.js +270 -0
  151. package/lib/WABinary/encode.js +279 -0
  152. package/lib/WABinary/generic-utils.js +223 -0
  153. package/lib/WABinary/index.js +34 -0
  154. package/lib/WABinary/jid-utils.js +84 -0
  155. package/lib/WABinary/types.js +2 -0
  156. package/lib/WAM/BinaryInfo.js +13 -0
  157. package/lib/WAM/constants.js +15254 -0
  158. package/lib/WAM/encode.js +149 -0
  159. package/lib/WAM/index.js +32 -0
  160. package/lib/WAUSync/Protocols/USyncContactProtocol.js +37 -0
  161. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +71 -0
  162. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +32 -0
  163. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +49 -0
  164. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +23 -0
  165. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +58 -0
  166. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +24 -0
  167. package/lib/WAUSync/Protocols/index.js +34 -0
  168. package/lib/WAUSync/USyncQuery.js +99 -0
  169. package/lib/WAUSync/USyncUser.js +26 -0
  170. package/lib/WAUSync/USyncUsernameProtocol.d.ts +9 -0
  171. package/lib/WAUSync/USyncUsernameProtocol.js +37 -0
  172. package/lib/WAUSync/index.js +32 -0
  173. package/lib/index.js +59 -0
  174. package/package.json +105 -5
  175. package/README.md +0 -5
@@ -0,0 +1,210 @@
1
+ 'use strict'
2
+ var __importDefault =
3
+ (this && this.__importDefault) ||
4
+ function (mod) {
5
+ return mod && mod.__esModule ? mod : { default: mod }
6
+ }
7
+ Object.defineProperty(exports, '__esModule', { value: true })
8
+ exports.initAuthCreds =
9
+ exports.addTransactionCapability =
10
+ exports.makeCacheableSignalKeyStore =
11
+ void 0
12
+ const crypto_1 = require('crypto')
13
+ const node_cache_1 = __importDefault(require('node-cache'))
14
+ const uuid_1 = require('uuid')
15
+ const Defaults_1 = require('../Defaults')
16
+ const crypto_2 = require('./crypto')
17
+ const generics_1 = require('./generics')
18
+ /**
19
+ * Adds caching capability to a SignalKeyStore
20
+ * @param store the store to add caching to
21
+ * @param logger to log trace events
22
+ * @param _cache cache store to use
23
+ */
24
+ function makeCacheableSignalKeyStore(store, logger, _cache) {
25
+ const cache =
26
+ _cache ||
27
+ new node_cache_1.default({
28
+ stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.SIGNAL_STORE,
29
+ useClones: false,
30
+ deleteOnExpire: true
31
+ })
32
+ function getUniqueId(type, id) {
33
+ return `${type}.${id}`
34
+ }
35
+ return {
36
+ async get(type, ids) {
37
+ const data = {}
38
+ const idsToFetch = []
39
+ for (const id of ids) {
40
+ const item = cache.get(getUniqueId(type, id))
41
+ if (typeof item !== 'undefined') {
42
+ data[id] = item
43
+ } else {
44
+ idsToFetch.push(id)
45
+ }
46
+ }
47
+ if (idsToFetch.length) {
48
+ logger.trace({ items: idsToFetch.length }, 'loading from store')
49
+ const fetched = await store.get(type, idsToFetch)
50
+ for (const id of idsToFetch) {
51
+ const item = fetched[id]
52
+ if (item) {
53
+ data[id] = item
54
+ cache.set(getUniqueId(type, id), item)
55
+ }
56
+ }
57
+ }
58
+ return data
59
+ },
60
+ async set(data) {
61
+ let keys = 0
62
+ for (const type in data) {
63
+ for (const id in data[type]) {
64
+ cache.set(getUniqueId(type, id), data[type][id])
65
+ keys += 1
66
+ }
67
+ }
68
+ logger.trace({ keys }, 'updated cache')
69
+ await store.set(data)
70
+ },
71
+ async clear() {
72
+ var _a
73
+ cache.flushAll()
74
+ await ((_a = store.clear) === null || _a === void 0 ? void 0 : _a.call(store))
75
+ }
76
+ }
77
+ }
78
+ exports.makeCacheableSignalKeyStore = makeCacheableSignalKeyStore
79
+ /**
80
+ * Adds DB like transaction capability (https://en.wikipedia.org/wiki/Database_transaction) to the SignalKeyStore,
81
+ * this allows batch read & write operations & improves the performance of the lib
82
+ * @param state the key store to apply this capability to
83
+ * @param logger logger to log events
84
+ * @returns SignalKeyStore with transaction capability
85
+ */
86
+ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetweenTriesMs }) => {
87
+ // number of queries made to the DB during the transaction
88
+ // only there for logging purposes
89
+ let dbQueriesInTransaction = 0
90
+ let transactionCache = {}
91
+ let mutations = {}
92
+ let transactionsInProgress = 0
93
+ return {
94
+ get: async (type, ids) => {
95
+ if (isInTransaction()) {
96
+ const dict = transactionCache[type]
97
+ const idsRequiringFetch = dict
98
+ ? ids.filter((item) => typeof dict[item] === 'undefined')
99
+ : ids
100
+ // only fetch if there are any items to fetch
101
+ if (idsRequiringFetch.length) {
102
+ dbQueriesInTransaction += 1
103
+ const result = await state.get(type, idsRequiringFetch)
104
+ transactionCache[type] || (transactionCache[type] = {})
105
+ Object.assign(transactionCache[type], result)
106
+ }
107
+ return ids.reduce((dict, id) => {
108
+ var _a
109
+ const value =
110
+ (_a = transactionCache[type]) === null || _a === void 0 ? void 0 : _a[id]
111
+ if (value) {
112
+ dict[id] = value
113
+ }
114
+ return dict
115
+ }, {})
116
+ } else {
117
+ return state.get(type, ids)
118
+ }
119
+ },
120
+ set: (data) => {
121
+ if (isInTransaction()) {
122
+ logger.trace({ types: Object.keys(data) }, 'caching in transaction')
123
+ for (const key in data) {
124
+ transactionCache[key] = transactionCache[key] || {}
125
+ Object.assign(transactionCache[key], data[key])
126
+ mutations[key] = mutations[key] || {}
127
+ Object.assign(mutations[key], data[key])
128
+ }
129
+ } else {
130
+ return state.set(data)
131
+ }
132
+ },
133
+ isInTransaction,
134
+ async transaction(work) {
135
+ let result
136
+ transactionsInProgress += 1
137
+ if (transactionsInProgress === 1) {
138
+ logger.trace('entering transaction')
139
+ }
140
+ try {
141
+ result = await work()
142
+ // commit if this is the outermost transaction
143
+ if (transactionsInProgress === 1) {
144
+ if (Object.keys(mutations).length) {
145
+ logger.trace('committing transaction')
146
+ // retry mechanism to ensure we've some recovery
147
+ // in case a transaction fails in the first attempt
148
+ let tries = maxCommitRetries
149
+ while (tries) {
150
+ tries -= 1
151
+ try {
152
+ await state.set(mutations)
153
+ logger.trace({ dbQueriesInTransaction }, 'committed transaction')
154
+ break
155
+ } catch (error) {
156
+ logger.warn(
157
+ `failed to commit ${Object.keys(mutations).length} mutations, tries left=${tries}`
158
+ )
159
+ await (0, generics_1.delay)(delayBetweenTriesMs)
160
+ }
161
+ }
162
+ } else {
163
+ logger.trace('no mutations in transaction')
164
+ }
165
+ }
166
+ } finally {
167
+ transactionsInProgress -= 1
168
+ if (transactionsInProgress === 0) {
169
+ transactionCache = {}
170
+ mutations = {}
171
+ dbQueriesInTransaction = 0
172
+ }
173
+ }
174
+ return result
175
+ }
176
+ }
177
+ function isInTransaction() {
178
+ return transactionsInProgress > 0
179
+ }
180
+ }
181
+ exports.addTransactionCapability = addTransactionCapability
182
+ const initAuthCreds = () => {
183
+ const identityKey = crypto_2.Curve.generateKeyPair()
184
+ return {
185
+ noiseKey: crypto_2.Curve.generateKeyPair(),
186
+ pairingEphemeralKeyPair: crypto_2.Curve.generateKeyPair(),
187
+ signedIdentityKey: identityKey,
188
+ signedPreKey: (0, crypto_2.signedKeyPair)(identityKey, 1),
189
+ registrationId: (0, generics_1.generateRegistrationId)(),
190
+ advSecretKey: (0, crypto_1.randomBytes)(32).toString('base64'),
191
+ processedHistoryMessages: [],
192
+ nextPreKeyId: 1,
193
+ firstUnuploadedPreKeyId: 1,
194
+ accountSyncCounter: 0,
195
+ accountSettings: {
196
+ unarchiveChats: false
197
+ },
198
+ // mobile creds
199
+ deviceId: Buffer.from((0, uuid_1.v4)().replace(/-/g, ''), 'hex').toString('base64url'),
200
+ phoneId: (0, uuid_1.v4)(),
201
+ identityId: (0, crypto_1.randomBytes)(20),
202
+ registered: false,
203
+ backupToken: (0, crypto_1.randomBytes)(20),
204
+ registration: {},
205
+ pairingCode: undefined,
206
+ lastPropHash: undefined,
207
+ routingInfo: undefined
208
+ }
209
+ }
210
+ exports.initAuthCreds = initAuthCreds
@@ -0,0 +1,66 @@
1
+ 'use strict'
2
+ var __importDefault =
3
+ (this && this.__importDefault) ||
4
+ function (mod) {
5
+ return mod && mod.__esModule ? mod : { default: mod }
6
+ }
7
+ Object.defineProperty(exports, '__esModule', { value: true })
8
+ exports.readAndEmitEventStream = exports.captureEventStream = void 0
9
+ const events_1 = __importDefault(require('events'))
10
+ const fs_1 = require('fs')
11
+ const promises_1 = require('fs/promises')
12
+ const readline_1 = require('readline')
13
+ const generics_1 = require('./generics')
14
+ const make_mutex_1 = require('./make-mutex')
15
+ /**
16
+ * Captures events from a baileys event emitter & stores them in a file
17
+ * @param ev The event emitter to read events from
18
+ * @param filename File to save to
19
+ */
20
+ const captureEventStream = (ev, filename) => {
21
+ const oldEmit = ev.emit
22
+ // write mutex so data is appended in order
23
+ const writeMutex = (0, make_mutex_1.makeMutex)()
24
+ // monkey patch eventemitter to capture all events
25
+ ev.emit = function (...args) {
26
+ const content =
27
+ JSON.stringify({ timestamp: Date.now(), event: args[0], data: args[1] }) + '\n'
28
+ const result = oldEmit.apply(ev, args)
29
+ writeMutex.mutex(async () => {
30
+ await (0, promises_1.writeFile)(filename, content, { flag: 'a' })
31
+ })
32
+ return result
33
+ }
34
+ }
35
+ exports.captureEventStream = captureEventStream
36
+ /**
37
+ * Read event file and emit events from there
38
+ * @param filename filename containing event data
39
+ * @param delayIntervalMs delay between each event emit
40
+ */
41
+ const readAndEmitEventStream = (filename, delayIntervalMs = 0) => {
42
+ const ev = new events_1.default()
43
+ const fireEvents = async () => {
44
+ // from: https://stackoverflow.com/questions/6156501/read-a-file-one-line-at-a-time-in-node-js
45
+ const fileStream = (0, fs_1.createReadStream)(filename)
46
+ const rl = (0, readline_1.createInterface)({
47
+ input: fileStream,
48
+ crlfDelay: Infinity
49
+ })
50
+ // Note: we use the crlfDelay option to recognize all instances of CR LF
51
+ // ('\r\n') in input.txt as a single line break.
52
+ for await (const line of rl) {
53
+ if (line) {
54
+ const { event, data } = JSON.parse(line)
55
+ ev.emit(event, data)
56
+ delayIntervalMs && (await (0, generics_1.delay)(delayIntervalMs))
57
+ }
58
+ }
59
+ fileStream.close()
60
+ }
61
+ return {
62
+ ev,
63
+ task: fireEvents()
64
+ }
65
+ }
66
+ exports.readAndEmitEventStream = readAndEmitEventStream
@@ -0,0 +1,52 @@
1
+ const { platform, release } = require('os')
2
+ const { proto } = require('../../WAProto')
3
+ const PLATFORM_MAP = {
4
+ aix: 'AIX',
5
+ darwin: 'Mac OS',
6
+ win32: 'Windows',
7
+ android: 'Android',
8
+ freebsd: 'FreeBSD',
9
+ openbsd: 'OpenBSD',
10
+ sunos: 'Solaris',
11
+ linux: 'Linux',
12
+ haiku: undefined,
13
+ cygwin: undefined,
14
+ netbsd: undefined
15
+ }
16
+ const BROWSER_MAP = {
17
+ safari: 'Safari',
18
+ chrome: 'Chrome',
19
+ edge: 'Edge',
20
+ firefox: 'Firefox',
21
+ opera: 'Opera',
22
+ brave: 'Brave',
23
+ samsung: 'Samsung Internet'
24
+ }
25
+ const getBrowserN = (bros) => {
26
+ const brosN = BROWSER_MAP[bros] || bros
27
+ return brosN
28
+ }
29
+ const Browsers = {
30
+ ubuntu: (browser) => ['Ubuntu', getBrowserN(browser), '22.04.4'],
31
+ macOS: (browser) => ['Mac OS', getBrowserN(browser), '14.4.1'],
32
+ baileys: (browser) => ['Baileys', getBrowserN(browser), '6.5.0'],
33
+ windows: (browser) => ['Windows', getBrowserN(browser), '10.0.22631'],
34
+ iOS: (browser) => ['iOS', getBrowserN(browser), '18.2'],
35
+ android: (browser) => ['Android', getBrowserN(browser), '14.0.0'],
36
+ safari: (browser) => ['Safari', getBrowserN(browser), '26.5'],
37
+ custom: (platform, browser, ver) => {
38
+ let platformN = PLATFORM_MAP[platform].toLowerCase() || platform
39
+ return [platformN, getBrowserN(browser), ver]
40
+ },
41
+ /** The appropriate browser based on your OS & release */
42
+ appropriate: (browser) => [
43
+ PLATFORM_MAP[platform()] || 'Ubuntu',
44
+ getBrowserN(browser),
45
+ release()
46
+ ]
47
+ }
48
+ const getPlatformId = (browser) => {
49
+ const platformType = proto.DeviceProps.PlatformType[browser.toUpperCase()]
50
+ return platformType ? platformType.toString() : '1' //chrome
51
+ }
52
+ //# sourceMappingURL=browser-utils.js.map
@@ -0,0 +1,261 @@
1
+ 'use strict'
2
+ Object.defineProperty(exports, '__esModule', { value: true })
3
+ exports.uploadingNecessaryImages =
4
+ exports.uploadingNecessaryImagesOfProduct =
5
+ exports.parseProductNode =
6
+ exports.toProductNode =
7
+ exports.parseOrderDetailsNode =
8
+ exports.parseCollectionsNode =
9
+ exports.parseCatalogNode =
10
+ void 0
11
+ const boom_1 = require('@hapi/boom')
12
+ const crypto_1 = require('crypto')
13
+ const WABinary_1 = require('../WABinary')
14
+ const messages_media_1 = require('./messages-media')
15
+ const parseCatalogNode = (node) => {
16
+ const catalogNode = (0, WABinary_1.getBinaryNodeChild)(node, 'product_catalog')
17
+ const products = (0, WABinary_1.getBinaryNodeChildren)(catalogNode, 'product').map(
18
+ exports.parseProductNode
19
+ )
20
+ const paging = (0, WABinary_1.getBinaryNodeChild)(catalogNode, 'paging')
21
+ return {
22
+ products,
23
+ nextPageCursor: paging
24
+ ? (0, WABinary_1.getBinaryNodeChildString)(paging, 'after')
25
+ : undefined
26
+ }
27
+ }
28
+ exports.parseCatalogNode = parseCatalogNode
29
+ const parseCollectionsNode = (node) => {
30
+ const collectionsNode = (0, WABinary_1.getBinaryNodeChild)(node, 'collections')
31
+ const collections = (0, WABinary_1.getBinaryNodeChildren)(collectionsNode, 'collection').map(
32
+ (collectionNode) => {
33
+ const id = (0, WABinary_1.getBinaryNodeChildString)(collectionNode, 'id')
34
+ const name = (0, WABinary_1.getBinaryNodeChildString)(collectionNode, 'name')
35
+ const products = (0, WABinary_1.getBinaryNodeChildren)(collectionNode, 'product').map(
36
+ exports.parseProductNode
37
+ )
38
+ return {
39
+ id,
40
+ name,
41
+ products,
42
+ status: parseStatusInfo(collectionNode)
43
+ }
44
+ }
45
+ )
46
+ return {
47
+ collections
48
+ }
49
+ }
50
+ exports.parseCollectionsNode = parseCollectionsNode
51
+ const parseOrderDetailsNode = (node) => {
52
+ const orderNode = (0, WABinary_1.getBinaryNodeChild)(node, 'order')
53
+ const products = (0, WABinary_1.getBinaryNodeChildren)(orderNode, 'product').map(
54
+ (productNode) => {
55
+ const imageNode = (0, WABinary_1.getBinaryNodeChild)(productNode, 'image')
56
+ return {
57
+ id: (0, WABinary_1.getBinaryNodeChildString)(productNode, 'id'),
58
+ name: (0, WABinary_1.getBinaryNodeChildString)(productNode, 'name'),
59
+ imageUrl: (0, WABinary_1.getBinaryNodeChildString)(imageNode, 'url'),
60
+ price: +(0, WABinary_1.getBinaryNodeChildString)(productNode, 'price'),
61
+ currency: (0, WABinary_1.getBinaryNodeChildString)(productNode, 'currency'),
62
+ quantity: +(0, WABinary_1.getBinaryNodeChildString)(productNode, 'quantity')
63
+ }
64
+ }
65
+ )
66
+ const priceNode = (0, WABinary_1.getBinaryNodeChild)(orderNode, 'price')
67
+ const orderDetails = {
68
+ price: {
69
+ total: +(0, WABinary_1.getBinaryNodeChildString)(priceNode, 'total'),
70
+ currency: (0, WABinary_1.getBinaryNodeChildString)(priceNode, 'currency')
71
+ },
72
+ products
73
+ }
74
+ return orderDetails
75
+ }
76
+ exports.parseOrderDetailsNode = parseOrderDetailsNode
77
+ const toProductNode = (productId, product) => {
78
+ const attrs = {}
79
+ const content = []
80
+ if (typeof productId !== 'undefined') {
81
+ content.push({
82
+ tag: 'id',
83
+ attrs: {},
84
+ content: Buffer.from(productId)
85
+ })
86
+ }
87
+ if (typeof product.name !== 'undefined') {
88
+ content.push({
89
+ tag: 'name',
90
+ attrs: {},
91
+ content: Buffer.from(product.name)
92
+ })
93
+ }
94
+ if (typeof product.description !== 'undefined') {
95
+ content.push({
96
+ tag: 'description',
97
+ attrs: {},
98
+ content: Buffer.from(product.description)
99
+ })
100
+ }
101
+ if (typeof product.retailerId !== 'undefined') {
102
+ content.push({
103
+ tag: 'retailer_id',
104
+ attrs: {},
105
+ content: Buffer.from(product.retailerId)
106
+ })
107
+ }
108
+ if (product.images.length) {
109
+ content.push({
110
+ tag: 'media',
111
+ attrs: {},
112
+ content: product.images.map((img) => {
113
+ if (!('url' in img)) {
114
+ throw new boom_1.Boom('Expected img for product to already be uploaded', {
115
+ statusCode: 400
116
+ })
117
+ }
118
+ return {
119
+ tag: 'image',
120
+ attrs: {},
121
+ content: [
122
+ {
123
+ tag: 'url',
124
+ attrs: {},
125
+ content: Buffer.from(img.url.toString())
126
+ }
127
+ ]
128
+ }
129
+ })
130
+ })
131
+ }
132
+ if (typeof product.price !== 'undefined') {
133
+ content.push({
134
+ tag: 'price',
135
+ attrs: {},
136
+ content: Buffer.from(product.price.toString())
137
+ })
138
+ }
139
+ if (typeof product.currency !== 'undefined') {
140
+ content.push({
141
+ tag: 'currency',
142
+ attrs: {},
143
+ content: Buffer.from(product.currency)
144
+ })
145
+ }
146
+ if ('originCountryCode' in product) {
147
+ if (typeof product.originCountryCode === 'undefined') {
148
+ attrs['compliance_category'] = 'COUNTRY_ORIGIN_EXEMPT'
149
+ } else {
150
+ content.push({
151
+ tag: 'compliance_info',
152
+ attrs: {},
153
+ content: [
154
+ {
155
+ tag: 'country_code_origin',
156
+ attrs: {},
157
+ content: Buffer.from(product.originCountryCode)
158
+ }
159
+ ]
160
+ })
161
+ }
162
+ }
163
+ if (typeof product.isHidden !== 'undefined') {
164
+ attrs['is_hidden'] = product.isHidden.toString()
165
+ }
166
+ const node = {
167
+ tag: 'product',
168
+ attrs,
169
+ content
170
+ }
171
+ return node
172
+ }
173
+ exports.toProductNode = toProductNode
174
+ const parseProductNode = (productNode) => {
175
+ const isHidden = productNode.attrs.is_hidden === 'true'
176
+ const id = (0, WABinary_1.getBinaryNodeChildString)(productNode, 'id')
177
+ const mediaNode = (0, WABinary_1.getBinaryNodeChild)(productNode, 'media')
178
+ const statusInfoNode = (0, WABinary_1.getBinaryNodeChild)(productNode, 'status_info')
179
+ const product = {
180
+ id,
181
+ imageUrls: parseImageUrls(mediaNode),
182
+ reviewStatus: {
183
+ whatsapp: (0, WABinary_1.getBinaryNodeChildString)(statusInfoNode, 'status')
184
+ },
185
+ availability: 'in stock',
186
+ name: (0, WABinary_1.getBinaryNodeChildString)(productNode, 'name'),
187
+ retailerId: (0, WABinary_1.getBinaryNodeChildString)(productNode, 'retailer_id'),
188
+ url: (0, WABinary_1.getBinaryNodeChildString)(productNode, 'url'),
189
+ description: (0, WABinary_1.getBinaryNodeChildString)(productNode, 'description'),
190
+ price: +(0, WABinary_1.getBinaryNodeChildString)(productNode, 'price'),
191
+ currency: (0, WABinary_1.getBinaryNodeChildString)(productNode, 'currency'),
192
+ isHidden
193
+ }
194
+ return product
195
+ }
196
+ exports.parseProductNode = parseProductNode
197
+ /**
198
+ * Uploads images not already uploaded to WA's servers
199
+ */
200
+ async function uploadingNecessaryImagesOfProduct(product, waUploadToServer, timeoutMs = 30000) {
201
+ product = {
202
+ ...product,
203
+ images: product.images
204
+ ? await (0, exports.uploadingNecessaryImages)(
205
+ product.images,
206
+ waUploadToServer,
207
+ timeoutMs
208
+ )
209
+ : product.images
210
+ }
211
+ return product
212
+ }
213
+ exports.uploadingNecessaryImagesOfProduct = uploadingNecessaryImagesOfProduct
214
+ /**
215
+ * Uploads images not already uploaded to WA's servers
216
+ */
217
+ const uploadingNecessaryImages = async (images, waUploadToServer, timeoutMs = 30000) => {
218
+ const results = await Promise.all(
219
+ images.map(async (img) => {
220
+ if ('url' in img) {
221
+ const url = img.url.toString()
222
+ if (url.includes('.whatsapp.net')) {
223
+ return { url }
224
+ }
225
+ }
226
+ const { stream } = await (0, messages_media_1.getStream)(img)
227
+ const hasher = (0, crypto_1.createHash)('sha256')
228
+ const contentBlocks = []
229
+ for await (const block of stream) {
230
+ hasher.update(block)
231
+ contentBlocks.push(block)
232
+ }
233
+ const sha = hasher.digest('base64')
234
+ const { directPath } = await waUploadToServer(
235
+ (0, messages_media_1.toReadable)(Buffer.concat(contentBlocks)),
236
+ {
237
+ mediaType: 'product-catalog-image',
238
+ fileEncSha256B64: sha,
239
+ timeoutMs
240
+ }
241
+ )
242
+ return { url: (0, messages_media_1.getUrlFromDirectPath)(directPath) }
243
+ })
244
+ )
245
+ return results
246
+ }
247
+ exports.uploadingNecessaryImages = uploadingNecessaryImages
248
+ const parseImageUrls = (mediaNode) => {
249
+ const imgNode = (0, WABinary_1.getBinaryNodeChild)(mediaNode, 'image')
250
+ return {
251
+ requested: (0, WABinary_1.getBinaryNodeChildString)(imgNode, 'request_image_url'),
252
+ original: (0, WABinary_1.getBinaryNodeChildString)(imgNode, 'original_image_url')
253
+ }
254
+ }
255
+ const parseStatusInfo = (mediaNode) => {
256
+ const node = (0, WABinary_1.getBinaryNodeChild)(mediaNode, 'status_info')
257
+ return {
258
+ status: (0, WABinary_1.getBinaryNodeChildString)(node, 'status'),
259
+ canAppeal: (0, WABinary_1.getBinaryNodeChildString)(node, 'can_appeal') === 'true'
260
+ }
261
+ }