@ardennguyen/zalo-agent-cli 1.0.7 → 2.1.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.
Files changed (1275) hide show
  1. package/DISCLAIMER.md +2 -2
  2. package/LICENSE +456 -21
  3. package/NOTICE +127 -0
  4. package/README.md +169 -70
  5. package/node_modules/asynckit/LICENSE +21 -0
  6. package/node_modules/asynckit/README.md +233 -0
  7. package/node_modules/asynckit/bench.js +76 -0
  8. package/node_modules/asynckit/index.js +6 -0
  9. package/node_modules/asynckit/lib/abort.js +29 -0
  10. package/node_modules/asynckit/lib/async.js +34 -0
  11. package/node_modules/asynckit/lib/defer.js +26 -0
  12. package/node_modules/asynckit/lib/iterate.js +75 -0
  13. package/node_modules/asynckit/lib/readable_asynckit.js +91 -0
  14. package/node_modules/asynckit/lib/readable_parallel.js +25 -0
  15. package/node_modules/asynckit/lib/readable_serial.js +25 -0
  16. package/node_modules/asynckit/lib/readable_serial_ordered.js +29 -0
  17. package/node_modules/asynckit/lib/state.js +37 -0
  18. package/node_modules/asynckit/lib/streamify.js +141 -0
  19. package/node_modules/asynckit/lib/terminator.js +29 -0
  20. package/node_modules/asynckit/package.json +63 -0
  21. package/node_modules/asynckit/parallel.js +43 -0
  22. package/node_modules/asynckit/serial.js +17 -0
  23. package/node_modules/asynckit/serialOrdered.js +75 -0
  24. package/node_modules/asynckit/stream.js +21 -0
  25. package/node_modules/bignumber.js/CHANGELOG.md +381 -0
  26. package/node_modules/bignumber.js/LICENCE.md +26 -0
  27. package/node_modules/bignumber.js/README.md +289 -0
  28. package/node_modules/bignumber.js/bignumber.d.mts +6 -0
  29. package/node_modules/bignumber.js/bignumber.d.ts +5 -0
  30. package/node_modules/bignumber.js/bignumber.js +2922 -0
  31. package/node_modules/bignumber.js/bignumber.mjs +2907 -0
  32. package/node_modules/bignumber.js/doc/API.html +2249 -0
  33. package/node_modules/bignumber.js/package.json +60 -0
  34. package/node_modules/bignumber.js/types.d.ts +1821 -0
  35. package/node_modules/call-bind-apply-helpers/.eslintrc +17 -0
  36. package/node_modules/call-bind-apply-helpers/.github/FUNDING.yml +12 -0
  37. package/node_modules/call-bind-apply-helpers/.nycrc +9 -0
  38. package/node_modules/call-bind-apply-helpers/CHANGELOG.md +30 -0
  39. package/node_modules/call-bind-apply-helpers/LICENSE +21 -0
  40. package/node_modules/call-bind-apply-helpers/README.md +62 -0
  41. package/node_modules/call-bind-apply-helpers/actualApply.d.ts +1 -0
  42. package/node_modules/call-bind-apply-helpers/actualApply.js +10 -0
  43. package/node_modules/call-bind-apply-helpers/applyBind.d.ts +19 -0
  44. package/node_modules/call-bind-apply-helpers/applyBind.js +10 -0
  45. package/node_modules/call-bind-apply-helpers/functionApply.d.ts +1 -0
  46. package/node_modules/call-bind-apply-helpers/functionApply.js +4 -0
  47. package/node_modules/call-bind-apply-helpers/functionCall.d.ts +1 -0
  48. package/node_modules/call-bind-apply-helpers/functionCall.js +4 -0
  49. package/node_modules/call-bind-apply-helpers/index.d.ts +64 -0
  50. package/node_modules/call-bind-apply-helpers/index.js +15 -0
  51. package/node_modules/call-bind-apply-helpers/package.json +85 -0
  52. package/node_modules/call-bind-apply-helpers/reflectApply.d.ts +3 -0
  53. package/node_modules/call-bind-apply-helpers/reflectApply.js +4 -0
  54. package/node_modules/call-bind-apply-helpers/test/index.js +63 -0
  55. package/node_modules/call-bind-apply-helpers/tsconfig.json +9 -0
  56. package/node_modules/combined-stream/License +19 -0
  57. package/node_modules/combined-stream/Readme.md +138 -0
  58. package/node_modules/combined-stream/lib/combined_stream.js +208 -0
  59. package/node_modules/combined-stream/package.json +25 -0
  60. package/node_modules/crypto-js/CONTRIBUTING.md +28 -0
  61. package/node_modules/crypto-js/LICENSE +24 -0
  62. package/node_modules/crypto-js/README.md +275 -0
  63. package/node_modules/crypto-js/aes.js +234 -0
  64. package/node_modules/crypto-js/blowfish.js +471 -0
  65. package/node_modules/crypto-js/bower.json +39 -0
  66. package/node_modules/crypto-js/cipher-core.js +895 -0
  67. package/node_modules/crypto-js/core.js +807 -0
  68. package/node_modules/crypto-js/crypto-js.js +6657 -0
  69. package/node_modules/crypto-js/docs/QuickStartGuide.wiki +470 -0
  70. package/node_modules/crypto-js/enc-base64.js +136 -0
  71. package/node_modules/crypto-js/enc-base64url.js +148 -0
  72. package/node_modules/crypto-js/enc-hex.js +18 -0
  73. package/node_modules/crypto-js/enc-latin1.js +18 -0
  74. package/node_modules/crypto-js/enc-utf16.js +149 -0
  75. package/node_modules/crypto-js/enc-utf8.js +18 -0
  76. package/node_modules/crypto-js/evpkdf.js +134 -0
  77. package/node_modules/crypto-js/format-hex.js +66 -0
  78. package/node_modules/crypto-js/format-openssl.js +18 -0
  79. package/node_modules/crypto-js/hmac-md5.js +18 -0
  80. package/node_modules/crypto-js/hmac-ripemd160.js +18 -0
  81. package/node_modules/crypto-js/hmac-sha1.js +18 -0
  82. package/node_modules/crypto-js/hmac-sha224.js +18 -0
  83. package/node_modules/crypto-js/hmac-sha256.js +18 -0
  84. package/node_modules/crypto-js/hmac-sha3.js +18 -0
  85. package/node_modules/crypto-js/hmac-sha384.js +18 -0
  86. package/node_modules/crypto-js/hmac-sha512.js +18 -0
  87. package/node_modules/crypto-js/hmac.js +143 -0
  88. package/node_modules/crypto-js/index.js +18 -0
  89. package/node_modules/crypto-js/lib-typedarrays.js +76 -0
  90. package/node_modules/crypto-js/md5.js +268 -0
  91. package/node_modules/crypto-js/mode-cfb.js +80 -0
  92. package/node_modules/crypto-js/mode-ctr-gladman.js +116 -0
  93. package/node_modules/crypto-js/mode-ctr.js +58 -0
  94. package/node_modules/crypto-js/mode-ecb.js +40 -0
  95. package/node_modules/crypto-js/mode-ofb.js +54 -0
  96. package/node_modules/crypto-js/package.json +42 -0
  97. package/node_modules/crypto-js/pad-ansix923.js +49 -0
  98. package/node_modules/crypto-js/pad-iso10126.js +44 -0
  99. package/node_modules/crypto-js/pad-iso97971.js +40 -0
  100. package/node_modules/crypto-js/pad-nopadding.js +30 -0
  101. package/node_modules/crypto-js/pad-pkcs7.js +18 -0
  102. package/node_modules/crypto-js/pad-zeropadding.js +47 -0
  103. package/node_modules/crypto-js/pbkdf2.js +145 -0
  104. package/node_modules/crypto-js/rabbit-legacy.js +190 -0
  105. package/node_modules/crypto-js/rabbit.js +192 -0
  106. package/node_modules/crypto-js/rc4.js +139 -0
  107. package/node_modules/crypto-js/ripemd160.js +267 -0
  108. package/node_modules/crypto-js/sha1.js +150 -0
  109. package/node_modules/crypto-js/sha224.js +80 -0
  110. package/node_modules/crypto-js/sha256.js +199 -0
  111. package/node_modules/crypto-js/sha3.js +326 -0
  112. package/node_modules/crypto-js/sha384.js +83 -0
  113. package/node_modules/crypto-js/sha512.js +326 -0
  114. package/node_modules/crypto-js/tripledes.js +779 -0
  115. package/node_modules/crypto-js/x64-core.js +304 -0
  116. package/node_modules/delayed-stream/.npmignore +1 -0
  117. package/node_modules/delayed-stream/License +19 -0
  118. package/node_modules/delayed-stream/Makefile +7 -0
  119. package/node_modules/delayed-stream/Readme.md +141 -0
  120. package/node_modules/delayed-stream/lib/delayed_stream.js +107 -0
  121. package/node_modules/delayed-stream/package.json +27 -0
  122. package/node_modules/dunder-proto/.eslintrc +5 -0
  123. package/node_modules/dunder-proto/.github/FUNDING.yml +12 -0
  124. package/node_modules/dunder-proto/.nycrc +13 -0
  125. package/node_modules/dunder-proto/CHANGELOG.md +24 -0
  126. package/node_modules/dunder-proto/LICENSE +21 -0
  127. package/node_modules/dunder-proto/README.md +54 -0
  128. package/node_modules/dunder-proto/get.d.ts +5 -0
  129. package/node_modules/dunder-proto/get.js +30 -0
  130. package/node_modules/dunder-proto/package.json +76 -0
  131. package/node_modules/dunder-proto/set.d.ts +5 -0
  132. package/node_modules/dunder-proto/set.js +35 -0
  133. package/node_modules/dunder-proto/test/get.js +34 -0
  134. package/node_modules/dunder-proto/test/index.js +4 -0
  135. package/node_modules/dunder-proto/test/set.js +50 -0
  136. package/node_modules/dunder-proto/tsconfig.json +9 -0
  137. package/node_modules/es-define-property/.eslintrc +13 -0
  138. package/node_modules/es-define-property/.github/FUNDING.yml +12 -0
  139. package/node_modules/es-define-property/.nycrc +9 -0
  140. package/node_modules/es-define-property/CHANGELOG.md +29 -0
  141. package/node_modules/es-define-property/LICENSE +21 -0
  142. package/node_modules/es-define-property/README.md +49 -0
  143. package/node_modules/es-define-property/index.d.ts +3 -0
  144. package/node_modules/es-define-property/index.js +14 -0
  145. package/node_modules/es-define-property/package.json +81 -0
  146. package/node_modules/es-define-property/test/index.js +56 -0
  147. package/node_modules/es-define-property/tsconfig.json +10 -0
  148. package/node_modules/es-errors/.eslintrc +5 -0
  149. package/node_modules/es-errors/.github/FUNDING.yml +12 -0
  150. package/node_modules/es-errors/CHANGELOG.md +40 -0
  151. package/node_modules/es-errors/LICENSE +21 -0
  152. package/node_modules/es-errors/README.md +55 -0
  153. package/node_modules/es-errors/eval.d.ts +3 -0
  154. package/node_modules/es-errors/eval.js +4 -0
  155. package/node_modules/es-errors/index.d.ts +3 -0
  156. package/node_modules/es-errors/index.js +4 -0
  157. package/node_modules/es-errors/package.json +80 -0
  158. package/node_modules/es-errors/range.d.ts +3 -0
  159. package/node_modules/es-errors/range.js +4 -0
  160. package/node_modules/es-errors/ref.d.ts +3 -0
  161. package/node_modules/es-errors/ref.js +4 -0
  162. package/node_modules/es-errors/syntax.d.ts +3 -0
  163. package/node_modules/es-errors/syntax.js +4 -0
  164. package/node_modules/es-errors/test/index.js +19 -0
  165. package/node_modules/es-errors/tsconfig.json +49 -0
  166. package/node_modules/es-errors/type.d.ts +3 -0
  167. package/node_modules/es-errors/type.js +4 -0
  168. package/node_modules/es-errors/uri.d.ts +3 -0
  169. package/node_modules/es-errors/uri.js +4 -0
  170. package/node_modules/es-object-atoms/.eslintrc +16 -0
  171. package/node_modules/es-object-atoms/.github/FUNDING.yml +12 -0
  172. package/node_modules/es-object-atoms/CHANGELOG.md +44 -0
  173. package/node_modules/es-object-atoms/LICENSE +21 -0
  174. package/node_modules/es-object-atoms/README.md +63 -0
  175. package/node_modules/es-object-atoms/RequireObjectCoercible.d.ts +3 -0
  176. package/node_modules/es-object-atoms/RequireObjectCoercible.js +11 -0
  177. package/node_modules/es-object-atoms/ToObject.d.ts +7 -0
  178. package/node_modules/es-object-atoms/ToObject.js +10 -0
  179. package/node_modules/es-object-atoms/index.d.ts +3 -0
  180. package/node_modules/es-object-atoms/index.js +4 -0
  181. package/node_modules/es-object-atoms/isObject.d.ts +3 -0
  182. package/node_modules/es-object-atoms/isObject.js +6 -0
  183. package/node_modules/es-object-atoms/package.json +79 -0
  184. package/node_modules/es-object-atoms/test/index.js +38 -0
  185. package/node_modules/es-object-atoms/tsconfig.json +7 -0
  186. package/node_modules/es-set-tostringtag/.eslintrc +13 -0
  187. package/node_modules/es-set-tostringtag/.nycrc +9 -0
  188. package/node_modules/es-set-tostringtag/CHANGELOG.md +67 -0
  189. package/node_modules/es-set-tostringtag/LICENSE +21 -0
  190. package/node_modules/es-set-tostringtag/README.md +53 -0
  191. package/node_modules/es-set-tostringtag/index.d.ts +10 -0
  192. package/node_modules/es-set-tostringtag/index.js +35 -0
  193. package/node_modules/es-set-tostringtag/package.json +78 -0
  194. package/node_modules/es-set-tostringtag/test/index.js +85 -0
  195. package/node_modules/es-set-tostringtag/tsconfig.json +9 -0
  196. package/node_modules/form-data/CHANGELOG.md +686 -0
  197. package/node_modules/form-data/License +19 -0
  198. package/node_modules/form-data/README.md +355 -0
  199. package/node_modules/form-data/index.d.ts +62 -0
  200. package/node_modules/form-data/lib/browser.js +4 -0
  201. package/node_modules/form-data/lib/form_data.js +506 -0
  202. package/node_modules/form-data/lib/populate.js +10 -0
  203. package/node_modules/form-data/node_modules/mime-db/HISTORY.md +507 -0
  204. package/node_modules/form-data/node_modules/mime-db/LICENSE +23 -0
  205. package/node_modules/form-data/node_modules/mime-db/README.md +100 -0
  206. package/node_modules/form-data/node_modules/mime-db/db.json +8519 -0
  207. package/node_modules/form-data/node_modules/mime-db/index.js +12 -0
  208. package/node_modules/form-data/node_modules/mime-db/package.json +60 -0
  209. package/node_modules/form-data/node_modules/mime-types/HISTORY.md +397 -0
  210. package/node_modules/form-data/node_modules/mime-types/LICENSE +23 -0
  211. package/node_modules/form-data/node_modules/mime-types/README.md +113 -0
  212. package/node_modules/form-data/node_modules/mime-types/index.js +188 -0
  213. package/node_modules/form-data/node_modules/mime-types/package.json +44 -0
  214. package/node_modules/form-data/package.json +82 -0
  215. package/node_modules/function-bind/.eslintrc +21 -0
  216. package/node_modules/function-bind/.github/FUNDING.yml +12 -0
  217. package/node_modules/function-bind/.github/SECURITY.md +3 -0
  218. package/node_modules/function-bind/.nycrc +13 -0
  219. package/node_modules/function-bind/CHANGELOG.md +136 -0
  220. package/node_modules/function-bind/LICENSE +20 -0
  221. package/node_modules/function-bind/README.md +46 -0
  222. package/node_modules/function-bind/implementation.js +84 -0
  223. package/node_modules/function-bind/index.js +5 -0
  224. package/node_modules/function-bind/package.json +87 -0
  225. package/node_modules/function-bind/test/.eslintrc +9 -0
  226. package/node_modules/function-bind/test/index.js +252 -0
  227. package/node_modules/get-intrinsic/.eslintrc +42 -0
  228. package/node_modules/get-intrinsic/.github/FUNDING.yml +12 -0
  229. package/node_modules/get-intrinsic/.nycrc +9 -0
  230. package/node_modules/get-intrinsic/CHANGELOG.md +186 -0
  231. package/node_modules/get-intrinsic/LICENSE +21 -0
  232. package/node_modules/get-intrinsic/README.md +71 -0
  233. package/node_modules/get-intrinsic/index.js +378 -0
  234. package/node_modules/get-intrinsic/package.json +97 -0
  235. package/node_modules/get-intrinsic/test/GetIntrinsic.js +274 -0
  236. package/node_modules/get-proto/.eslintrc +10 -0
  237. package/node_modules/get-proto/.github/FUNDING.yml +12 -0
  238. package/node_modules/get-proto/.nycrc +9 -0
  239. package/node_modules/get-proto/CHANGELOG.md +21 -0
  240. package/node_modules/get-proto/LICENSE +21 -0
  241. package/node_modules/get-proto/Object.getPrototypeOf.d.ts +5 -0
  242. package/node_modules/get-proto/Object.getPrototypeOf.js +6 -0
  243. package/node_modules/get-proto/README.md +50 -0
  244. package/node_modules/get-proto/Reflect.getPrototypeOf.d.ts +3 -0
  245. package/node_modules/get-proto/Reflect.getPrototypeOf.js +4 -0
  246. package/node_modules/get-proto/index.d.ts +5 -0
  247. package/node_modules/get-proto/index.js +27 -0
  248. package/node_modules/get-proto/package.json +81 -0
  249. package/node_modules/get-proto/test/index.js +68 -0
  250. package/node_modules/get-proto/tsconfig.json +9 -0
  251. package/node_modules/gopd/.eslintrc +16 -0
  252. package/node_modules/gopd/.github/FUNDING.yml +12 -0
  253. package/node_modules/gopd/CHANGELOG.md +45 -0
  254. package/node_modules/gopd/LICENSE +21 -0
  255. package/node_modules/gopd/README.md +40 -0
  256. package/node_modules/gopd/gOPD.d.ts +1 -0
  257. package/node_modules/gopd/gOPD.js +4 -0
  258. package/node_modules/gopd/index.d.ts +5 -0
  259. package/node_modules/gopd/index.js +15 -0
  260. package/node_modules/gopd/package.json +77 -0
  261. package/node_modules/gopd/test/index.js +36 -0
  262. package/node_modules/gopd/tsconfig.json +9 -0
  263. package/node_modules/has-symbols/.eslintrc +11 -0
  264. package/node_modules/has-symbols/.github/FUNDING.yml +12 -0
  265. package/node_modules/has-symbols/.nycrc +9 -0
  266. package/node_modules/has-symbols/CHANGELOG.md +91 -0
  267. package/node_modules/has-symbols/LICENSE +21 -0
  268. package/node_modules/has-symbols/README.md +46 -0
  269. package/node_modules/has-symbols/index.d.ts +3 -0
  270. package/node_modules/has-symbols/index.js +14 -0
  271. package/node_modules/has-symbols/package.json +111 -0
  272. package/node_modules/has-symbols/shams.d.ts +3 -0
  273. package/node_modules/has-symbols/shams.js +45 -0
  274. package/node_modules/has-symbols/test/index.js +22 -0
  275. package/node_modules/has-symbols/test/shams/core-js.js +29 -0
  276. package/node_modules/has-symbols/test/shams/get-own-property-symbols.js +29 -0
  277. package/node_modules/has-symbols/test/tests.js +58 -0
  278. package/node_modules/has-symbols/tsconfig.json +10 -0
  279. package/node_modules/has-tostringtag/.eslintrc +5 -0
  280. package/node_modules/has-tostringtag/.github/FUNDING.yml +12 -0
  281. package/node_modules/has-tostringtag/.nycrc +13 -0
  282. package/node_modules/has-tostringtag/CHANGELOG.md +42 -0
  283. package/node_modules/has-tostringtag/LICENSE +21 -0
  284. package/node_modules/has-tostringtag/README.md +46 -0
  285. package/node_modules/has-tostringtag/index.d.ts +3 -0
  286. package/node_modules/has-tostringtag/index.js +8 -0
  287. package/node_modules/has-tostringtag/package.json +108 -0
  288. package/node_modules/has-tostringtag/shams.d.ts +3 -0
  289. package/node_modules/has-tostringtag/shams.js +8 -0
  290. package/node_modules/has-tostringtag/test/index.js +21 -0
  291. package/node_modules/has-tostringtag/test/shams/core-js.js +31 -0
  292. package/node_modules/has-tostringtag/test/shams/get-own-property-symbols.js +30 -0
  293. package/node_modules/has-tostringtag/test/tests.js +15 -0
  294. package/node_modules/has-tostringtag/tsconfig.json +49 -0
  295. package/node_modules/hasown/.github/FUNDING.yml +12 -0
  296. package/node_modules/hasown/.nycrc +13 -0
  297. package/node_modules/hasown/CHANGELOG.md +58 -0
  298. package/node_modules/hasown/LICENSE +21 -0
  299. package/node_modules/hasown/README.md +40 -0
  300. package/node_modules/hasown/eslint.config.mjs +6 -0
  301. package/node_modules/hasown/index.d.ts +3 -0
  302. package/node_modules/hasown/index.js +8 -0
  303. package/node_modules/hasown/package.json +91 -0
  304. package/node_modules/hasown/tsconfig.json +6 -0
  305. package/node_modules/json-bigint/LICENSE +20 -0
  306. package/node_modules/json-bigint/README.md +240 -0
  307. package/node_modules/json-bigint/index.js +12 -0
  308. package/node_modules/json-bigint/lib/parse.js +443 -0
  309. package/node_modules/json-bigint/lib/stringify.js +384 -0
  310. package/node_modules/json-bigint/package.json +34 -0
  311. package/node_modules/math-intrinsics/.eslintrc +16 -0
  312. package/node_modules/math-intrinsics/.github/FUNDING.yml +12 -0
  313. package/node_modules/math-intrinsics/CHANGELOG.md +24 -0
  314. package/node_modules/math-intrinsics/LICENSE +21 -0
  315. package/node_modules/math-intrinsics/README.md +50 -0
  316. package/node_modules/math-intrinsics/abs.d.ts +1 -0
  317. package/node_modules/math-intrinsics/abs.js +4 -0
  318. package/node_modules/math-intrinsics/constants/maxArrayLength.d.ts +3 -0
  319. package/node_modules/math-intrinsics/constants/maxArrayLength.js +4 -0
  320. package/node_modules/math-intrinsics/constants/maxSafeInteger.d.ts +3 -0
  321. package/node_modules/math-intrinsics/constants/maxSafeInteger.js +5 -0
  322. package/node_modules/math-intrinsics/constants/maxValue.d.ts +3 -0
  323. package/node_modules/math-intrinsics/constants/maxValue.js +5 -0
  324. package/node_modules/math-intrinsics/floor.d.ts +1 -0
  325. package/node_modules/math-intrinsics/floor.js +4 -0
  326. package/node_modules/math-intrinsics/isFinite.d.ts +3 -0
  327. package/node_modules/math-intrinsics/isFinite.js +12 -0
  328. package/node_modules/math-intrinsics/isInteger.d.ts +3 -0
  329. package/node_modules/math-intrinsics/isInteger.js +16 -0
  330. package/node_modules/math-intrinsics/isNaN.d.ts +1 -0
  331. package/node_modules/math-intrinsics/isNaN.js +6 -0
  332. package/node_modules/math-intrinsics/isNegativeZero.d.ts +3 -0
  333. package/node_modules/math-intrinsics/isNegativeZero.js +6 -0
  334. package/node_modules/math-intrinsics/max.d.ts +1 -0
  335. package/node_modules/math-intrinsics/max.js +4 -0
  336. package/node_modules/math-intrinsics/min.d.ts +1 -0
  337. package/node_modules/math-intrinsics/min.js +4 -0
  338. package/node_modules/math-intrinsics/mod.d.ts +3 -0
  339. package/node_modules/math-intrinsics/mod.js +9 -0
  340. package/node_modules/math-intrinsics/package.json +86 -0
  341. package/node_modules/math-intrinsics/pow.d.ts +1 -0
  342. package/node_modules/math-intrinsics/pow.js +4 -0
  343. package/node_modules/math-intrinsics/round.d.ts +1 -0
  344. package/node_modules/math-intrinsics/round.js +4 -0
  345. package/node_modules/math-intrinsics/sign.d.ts +3 -0
  346. package/node_modules/math-intrinsics/sign.js +11 -0
  347. package/node_modules/math-intrinsics/test/index.js +192 -0
  348. package/node_modules/math-intrinsics/tsconfig.json +3 -0
  349. package/node_modules/pako/LICENSE +21 -0
  350. package/node_modules/pako/README.md +155 -0
  351. package/node_modules/pako/dist/pako.es5.js +6760 -0
  352. package/node_modules/pako/dist/pako.es5.min.js +2 -0
  353. package/node_modules/pako/dist/pako.esm.mjs +6945 -0
  354. package/node_modules/pako/dist/pako.js +6964 -0
  355. package/node_modules/pako/dist/pako.min.js +2 -0
  356. package/node_modules/pako/dist/pako_deflate.es5.js +3953 -0
  357. package/node_modules/pako/dist/pako_deflate.es5.min.js +2 -0
  358. package/node_modules/pako/dist/pako_deflate.js +4154 -0
  359. package/node_modules/pako/dist/pako_deflate.min.js +2 -0
  360. package/node_modules/pako/dist/pako_inflate.es5.js +3272 -0
  361. package/node_modules/pako/dist/pako_inflate.es5.min.js +2 -0
  362. package/node_modules/pako/dist/pako_inflate.js +3279 -0
  363. package/node_modules/pako/dist/pako_inflate.min.js +2 -0
  364. package/node_modules/pako/index.js +18 -0
  365. package/node_modules/pako/lib/deflate.js +387 -0
  366. package/node_modules/pako/lib/inflate.js +456 -0
  367. package/node_modules/pako/lib/utils/common.js +48 -0
  368. package/node_modules/pako/lib/utils/strings.js +174 -0
  369. package/node_modules/pako/lib/zlib/README +59 -0
  370. package/node_modules/pako/lib/zlib/adler32.js +51 -0
  371. package/node_modules/pako/lib/zlib/constants.js +68 -0
  372. package/node_modules/pako/lib/zlib/crc32.js +59 -0
  373. package/node_modules/pako/lib/zlib/deflate.js +2069 -0
  374. package/node_modules/pako/lib/zlib/gzheader.js +58 -0
  375. package/node_modules/pako/lib/zlib/inffast.js +344 -0
  376. package/node_modules/pako/lib/zlib/inflate.js +1575 -0
  377. package/node_modules/pako/lib/zlib/inftrees.js +340 -0
  378. package/node_modules/pako/lib/zlib/messages.js +32 -0
  379. package/node_modules/pako/lib/zlib/trees.js +1179 -0
  380. package/node_modules/pako/lib/zlib/zstream.js +47 -0
  381. package/node_modules/pako/package.json +73 -0
  382. package/node_modules/semver/LICENSE +15 -0
  383. package/node_modules/semver/README.md +680 -0
  384. package/node_modules/semver/bin/semver.js +195 -0
  385. package/node_modules/semver/classes/comparator.js +143 -0
  386. package/node_modules/semver/classes/index.js +7 -0
  387. package/node_modules/semver/classes/range.js +577 -0
  388. package/node_modules/semver/classes/semver.js +350 -0
  389. package/node_modules/semver/functions/clean.js +8 -0
  390. package/node_modules/semver/functions/cmp.js +54 -0
  391. package/node_modules/semver/functions/coerce.js +62 -0
  392. package/node_modules/semver/functions/compare-build.js +9 -0
  393. package/node_modules/semver/functions/compare-loose.js +5 -0
  394. package/node_modules/semver/functions/compare.js +7 -0
  395. package/node_modules/semver/functions/diff.js +60 -0
  396. package/node_modules/semver/functions/eq.js +5 -0
  397. package/node_modules/semver/functions/gt.js +5 -0
  398. package/node_modules/semver/functions/gte.js +5 -0
  399. package/node_modules/semver/functions/inc.js +21 -0
  400. package/node_modules/semver/functions/lt.js +5 -0
  401. package/node_modules/semver/functions/lte.js +5 -0
  402. package/node_modules/semver/functions/major.js +5 -0
  403. package/node_modules/semver/functions/minor.js +5 -0
  404. package/node_modules/semver/functions/neq.js +5 -0
  405. package/node_modules/semver/functions/parse.js +18 -0
  406. package/node_modules/semver/functions/patch.js +5 -0
  407. package/node_modules/semver/functions/prerelease.js +8 -0
  408. package/node_modules/semver/functions/rcompare.js +5 -0
  409. package/node_modules/semver/functions/rsort.js +5 -0
  410. package/node_modules/semver/functions/satisfies.js +12 -0
  411. package/node_modules/semver/functions/sort.js +5 -0
  412. package/node_modules/semver/functions/truncate.js +48 -0
  413. package/node_modules/semver/functions/valid.js +8 -0
  414. package/node_modules/semver/index.js +93 -0
  415. package/node_modules/semver/internal/constants.js +37 -0
  416. package/node_modules/semver/internal/debug.js +11 -0
  417. package/node_modules/semver/internal/identifiers.js +29 -0
  418. package/node_modules/semver/internal/lrucache.js +42 -0
  419. package/node_modules/semver/internal/parse-options.js +17 -0
  420. package/node_modules/semver/internal/re.js +223 -0
  421. package/node_modules/semver/package.json +78 -0
  422. package/node_modules/semver/preload.js +4 -0
  423. package/node_modules/semver/range.bnf +17 -0
  424. package/node_modules/semver/ranges/gtr.js +6 -0
  425. package/node_modules/semver/ranges/intersects.js +9 -0
  426. package/node_modules/semver/ranges/ltr.js +6 -0
  427. package/node_modules/semver/ranges/max-satisfying.js +27 -0
  428. package/node_modules/semver/ranges/min-satisfying.js +26 -0
  429. package/node_modules/semver/ranges/min-version.js +63 -0
  430. package/node_modules/semver/ranges/outside.js +82 -0
  431. package/node_modules/semver/ranges/simplify.js +49 -0
  432. package/node_modules/semver/ranges/subset.js +249 -0
  433. package/node_modules/semver/ranges/to-comparators.js +10 -0
  434. package/node_modules/semver/ranges/valid.js +13 -0
  435. package/node_modules/spark-md5/LICENSE +13 -0
  436. package/node_modules/spark-md5/README.md +191 -0
  437. package/node_modules/spark-md5/package.json +35 -0
  438. package/node_modules/spark-md5/spark-md5.js +751 -0
  439. package/node_modules/spark-md5/spark-md5.min.js +1 -0
  440. package/node_modules/tldts/LICENSE +13 -0
  441. package/node_modules/tldts/README.md +327 -0
  442. package/node_modules/tldts/bin/cli.js +21 -0
  443. package/node_modules/tldts/dist/cjs/index.js +666 -0
  444. package/node_modules/tldts/dist/cjs/index.js.map +1 -0
  445. package/node_modules/tldts/dist/cjs/src/data/trie.js +14 -0
  446. package/node_modules/tldts/dist/cjs/src/data/trie.js.map +1 -0
  447. package/node_modules/tldts/dist/cjs/src/suffix-trie.js +67 -0
  448. package/node_modules/tldts/dist/cjs/src/suffix-trie.js.map +1 -0
  449. package/node_modules/tldts/dist/cjs/tsconfig.tsbuildinfo +1 -0
  450. package/node_modules/tldts/dist/es6/index.js +33 -0
  451. package/node_modules/tldts/dist/es6/index.js.map +1 -0
  452. package/node_modules/tldts/dist/es6/src/data/trie.js +11 -0
  453. package/node_modules/tldts/dist/es6/src/data/trie.js.map +1 -0
  454. package/node_modules/tldts/dist/es6/src/suffix-trie.js +64 -0
  455. package/node_modules/tldts/dist/es6/src/suffix-trie.js.map +1 -0
  456. package/node_modules/tldts/dist/es6/tsconfig.bundle.tsbuildinfo +1 -0
  457. package/node_modules/tldts/dist/index.cjs.min.js +2 -0
  458. package/node_modules/tldts/dist/index.cjs.min.js.map +1 -0
  459. package/node_modules/tldts/dist/index.esm.min.js +2 -0
  460. package/node_modules/tldts/dist/index.esm.min.js.map +1 -0
  461. package/node_modules/tldts/dist/index.umd.min.js +2 -0
  462. package/node_modules/tldts/dist/index.umd.min.js.map +1 -0
  463. package/node_modules/tldts/dist/types/index.d.ts +7 -0
  464. package/node_modules/tldts/dist/types/src/data/trie.d.ts +5 -0
  465. package/node_modules/tldts/dist/types/src/suffix-trie.d.ts +5 -0
  466. package/node_modules/tldts/index.ts +62 -0
  467. package/node_modules/tldts/package.json +91 -0
  468. package/node_modules/tldts/src/data/trie.ts +14 -0
  469. package/node_modules/tldts/src/suffix-trie.ts +110 -0
  470. package/node_modules/tldts-core/LICENSE +13 -0
  471. package/node_modules/tldts-core/README.md +3 -0
  472. package/node_modules/tldts-core/dist/cjs/index.js +561 -0
  473. package/node_modules/tldts-core/dist/cjs/index.js.map +1 -0
  474. package/node_modules/tldts-core/dist/cjs/src/domain-without-suffix.js +15 -0
  475. package/node_modules/tldts-core/dist/cjs/src/domain-without-suffix.js.map +1 -0
  476. package/node_modules/tldts-core/dist/cjs/src/domain.js +83 -0
  477. package/node_modules/tldts-core/dist/cjs/src/domain.js.map +1 -0
  478. package/node_modules/tldts-core/dist/cjs/src/extract-hostname.js +149 -0
  479. package/node_modules/tldts-core/dist/cjs/src/extract-hostname.js.map +1 -0
  480. package/node_modules/tldts-core/dist/cjs/src/factory.js +104 -0
  481. package/node_modules/tldts-core/dist/cjs/src/factory.js.map +1 -0
  482. package/node_modules/tldts-core/dist/cjs/src/is-ip.js +72 -0
  483. package/node_modules/tldts-core/dist/cjs/src/is-ip.js.map +1 -0
  484. package/node_modules/tldts-core/dist/cjs/src/is-valid.js +69 -0
  485. package/node_modules/tldts-core/dist/cjs/src/is-valid.js.map +1 -0
  486. package/node_modules/tldts-core/dist/cjs/src/lookup/fast-path.js +69 -0
  487. package/node_modules/tldts-core/dist/cjs/src/lookup/fast-path.js.map +1 -0
  488. package/node_modules/tldts-core/dist/cjs/src/lookup/interface.js +3 -0
  489. package/node_modules/tldts-core/dist/cjs/src/lookup/interface.js.map +1 -0
  490. package/node_modules/tldts-core/dist/cjs/src/options.js +22 -0
  491. package/node_modules/tldts-core/dist/cjs/src/options.js.map +1 -0
  492. package/node_modules/tldts-core/dist/cjs/src/subdomain.js +14 -0
  493. package/node_modules/tldts-core/dist/cjs/src/subdomain.js.map +1 -0
  494. package/node_modules/tldts-core/dist/cjs/tsconfig.tsbuildinfo +1 -0
  495. package/node_modules/tldts-core/dist/es6/index.js +4 -0
  496. package/node_modules/tldts-core/dist/es6/index.js.map +1 -0
  497. package/node_modules/tldts-core/dist/es6/src/domain-without-suffix.js +12 -0
  498. package/node_modules/tldts-core/dist/es6/src/domain-without-suffix.js.map +1 -0
  499. package/node_modules/tldts-core/dist/es6/src/domain.js +80 -0
  500. package/node_modules/tldts-core/dist/es6/src/domain.js.map +1 -0
  501. package/node_modules/tldts-core/dist/es6/src/extract-hostname.js +146 -0
  502. package/node_modules/tldts-core/dist/es6/src/extract-hostname.js.map +1 -0
  503. package/node_modules/tldts-core/dist/es6/src/factory.js +99 -0
  504. package/node_modules/tldts-core/dist/es6/src/factory.js.map +1 -0
  505. package/node_modules/tldts-core/dist/es6/src/is-ip.js +69 -0
  506. package/node_modules/tldts-core/dist/es6/src/is-ip.js.map +1 -0
  507. package/node_modules/tldts-core/dist/es6/src/is-valid.js +66 -0
  508. package/node_modules/tldts-core/dist/es6/src/is-valid.js.map +1 -0
  509. package/node_modules/tldts-core/dist/es6/src/lookup/fast-path.js +66 -0
  510. package/node_modules/tldts-core/dist/es6/src/lookup/fast-path.js.map +1 -0
  511. package/node_modules/tldts-core/dist/es6/src/lookup/interface.js +2 -0
  512. package/node_modules/tldts-core/dist/es6/src/lookup/interface.js.map +1 -0
  513. package/node_modules/tldts-core/dist/es6/src/options.js +19 -0
  514. package/node_modules/tldts-core/dist/es6/src/options.js.map +1 -0
  515. package/node_modules/tldts-core/dist/es6/src/subdomain.js +11 -0
  516. package/node_modules/tldts-core/dist/es6/src/subdomain.js.map +1 -0
  517. package/node_modules/tldts-core/dist/es6/tsconfig.bundle.tsbuildinfo +1 -0
  518. package/node_modules/tldts-core/dist/types/index.d.ts +4 -0
  519. package/node_modules/tldts-core/dist/types/src/domain-without-suffix.d.ts +6 -0
  520. package/node_modules/tldts-core/dist/types/src/domain.d.ts +5 -0
  521. package/node_modules/tldts-core/dist/types/src/extract-hostname.d.ts +5 -0
  522. package/node_modules/tldts-core/dist/types/src/factory.d.ts +28 -0
  523. package/node_modules/tldts-core/dist/types/src/is-ip.d.ts +6 -0
  524. package/node_modules/tldts-core/dist/types/src/is-valid.d.ts +15 -0
  525. package/node_modules/tldts-core/dist/types/src/lookup/fast-path.d.ts +2 -0
  526. package/node_modules/tldts-core/dist/types/src/lookup/interface.d.ts +9 -0
  527. package/node_modules/tldts-core/dist/types/src/options.d.ts +10 -0
  528. package/node_modules/tldts-core/dist/types/src/subdomain.d.ts +4 -0
  529. package/node_modules/tldts-core/index.ts +10 -0
  530. package/node_modules/tldts-core/package.json +68 -0
  531. package/node_modules/tldts-core/src/domain-without-suffix.ts +14 -0
  532. package/node_modules/tldts-core/src/domain.ts +100 -0
  533. package/node_modules/tldts-core/src/extract-hostname.ts +170 -0
  534. package/node_modules/tldts-core/src/factory.ts +160 -0
  535. package/node_modules/tldts-core/src/is-ip.ts +87 -0
  536. package/node_modules/tldts-core/src/is-valid.ts +79 -0
  537. package/node_modules/tldts-core/src/lookup/fast-path.ts +80 -0
  538. package/node_modules/tldts-core/src/lookup/interface.ts +10 -0
  539. package/node_modules/tldts-core/src/options.ts +39 -0
  540. package/node_modules/tldts-core/src/subdomain.ts +11 -0
  541. package/node_modules/tough-cookie/LICENSE +12 -0
  542. package/node_modules/tough-cookie/README.md +154 -0
  543. package/node_modules/tough-cookie/dist/cookie/canonicalDomain.d.ts +33 -0
  544. package/node_modules/tough-cookie/dist/cookie/canonicalDomain.js +65 -0
  545. package/node_modules/tough-cookie/dist/cookie/constants.d.ts +54 -0
  546. package/node_modules/tough-cookie/dist/cookie/constants.js +38 -0
  547. package/node_modules/tough-cookie/dist/cookie/cookie.d.ts +326 -0
  548. package/node_modules/tough-cookie/dist/cookie/cookie.js +831 -0
  549. package/node_modules/tough-cookie/dist/cookie/cookieCompare.d.ts +58 -0
  550. package/node_modules/tough-cookie/dist/cookie/cookieCompare.js +84 -0
  551. package/node_modules/tough-cookie/dist/cookie/cookieJar.d.ts +621 -0
  552. package/node_modules/tough-cookie/dist/cookie/cookieJar.js +1000 -0
  553. package/node_modules/tough-cookie/dist/cookie/defaultPath.d.ts +40 -0
  554. package/node_modules/tough-cookie/dist/cookie/defaultPath.js +60 -0
  555. package/node_modules/tough-cookie/dist/cookie/domainMatch.d.ts +38 -0
  556. package/node_modules/tough-cookie/dist/cookie/domainMatch.js +94 -0
  557. package/node_modules/tough-cookie/dist/cookie/formatDate.d.ts +15 -0
  558. package/node_modules/tough-cookie/dist/cookie/formatDate.js +20 -0
  559. package/node_modules/tough-cookie/dist/cookie/index.d.ts +29 -0
  560. package/node_modules/tough-cookie/dist/cookie/index.js +54 -0
  561. package/node_modules/tough-cookie/dist/cookie/parseDate.d.ts +103 -0
  562. package/node_modules/tough-cookie/dist/cookie/parseDate.js +323 -0
  563. package/node_modules/tough-cookie/dist/cookie/permutePath.d.ts +14 -0
  564. package/node_modules/tough-cookie/dist/cookie/permutePath.js +32 -0
  565. package/node_modules/tough-cookie/dist/getPublicSuffix.d.ts +55 -0
  566. package/node_modules/tough-cookie/dist/getPublicSuffix.js +71 -0
  567. package/node_modules/tough-cookie/dist/memstore.d.ts +220 -0
  568. package/node_modules/tough-cookie/dist/memstore.js +187 -0
  569. package/node_modules/tough-cookie/dist/pathMatch.d.ts +17 -0
  570. package/node_modules/tough-cookie/dist/pathMatch.js +40 -0
  571. package/node_modules/tough-cookie/dist/permuteDomain.d.ts +15 -0
  572. package/node_modules/tough-cookie/dist/permuteDomain.js +44 -0
  573. package/node_modules/tough-cookie/dist/store.d.ts +211 -0
  574. package/node_modules/tough-cookie/dist/store.js +76 -0
  575. package/node_modules/tough-cookie/dist/utils.d.ts +34 -0
  576. package/node_modules/tough-cookie/dist/utils.js +99 -0
  577. package/node_modules/tough-cookie/dist/validators.d.ts +24 -0
  578. package/node_modules/tough-cookie/dist/validators.js +90 -0
  579. package/node_modules/tough-cookie/dist/version.d.ts +5 -0
  580. package/node_modules/tough-cookie/dist/version.js +8 -0
  581. package/node_modules/tough-cookie/package.json +144 -0
  582. package/node_modules/ws/LICENSE +20 -0
  583. package/node_modules/ws/README.md +548 -0
  584. package/node_modules/ws/browser.js +8 -0
  585. package/node_modules/ws/index.js +22 -0
  586. package/node_modules/ws/lib/buffer-util.js +131 -0
  587. package/node_modules/ws/lib/constants.js +19 -0
  588. package/node_modules/ws/lib/event-target.js +292 -0
  589. package/node_modules/ws/lib/extension.js +203 -0
  590. package/node_modules/ws/lib/limiter.js +55 -0
  591. package/node_modules/ws/lib/permessage-deflate.js +530 -0
  592. package/node_modules/ws/lib/receiver.js +743 -0
  593. package/node_modules/ws/lib/sender.js +607 -0
  594. package/node_modules/ws/lib/stream.js +161 -0
  595. package/node_modules/ws/lib/subprotocol.js +62 -0
  596. package/node_modules/ws/lib/validation.js +152 -0
  597. package/node_modules/ws/lib/websocket-server.js +562 -0
  598. package/node_modules/ws/lib/websocket.js +1407 -0
  599. package/node_modules/ws/package.json +74 -0
  600. package/node_modules/ws/wrapper.mjs +21 -0
  601. package/node_modules/zca-js/.prettierrc +5 -0
  602. package/node_modules/zca-js/CODE_OF_CONDUCT.md +163 -0
  603. package/node_modules/zca-js/CONTRIBUTING.md +470 -0
  604. package/node_modules/zca-js/LICENSE +21 -0
  605. package/node_modules/zca-js/README.md +225 -0
  606. package/node_modules/zca-js/SECURITY.md +83 -0
  607. package/node_modules/zca-js/dist/Errors/ZaloApiError.d.ts +4 -0
  608. package/node_modules/zca-js/dist/Errors/ZaloApiError.js +7 -0
  609. package/node_modules/zca-js/dist/Errors/ZaloApiLoginQRAborted.d.ts +4 -0
  610. package/node_modules/zca-js/dist/Errors/ZaloApiLoginQRAborted.js +7 -0
  611. package/node_modules/zca-js/dist/Errors/ZaloApiLoginQRDeclined.d.ts +4 -0
  612. package/node_modules/zca-js/dist/Errors/ZaloApiLoginQRDeclined.js +7 -0
  613. package/node_modules/zca-js/dist/Errors/ZaloApiMissingImageMetadataGetter.d.ts +4 -0
  614. package/node_modules/zca-js/dist/Errors/ZaloApiMissingImageMetadataGetter.js +7 -0
  615. package/node_modules/zca-js/dist/Errors/index.d.ts +4 -0
  616. package/node_modules/zca-js/dist/Errors/index.js +4 -0
  617. package/node_modules/zca-js/dist/apis/acceptFriendRequest.d.ts +2 -0
  618. package/node_modules/zca-js/dist/apis/acceptFriendRequest.js +28 -0
  619. package/node_modules/zca-js/dist/apis/addGroupBlockedMember.d.ts +2 -0
  620. package/node_modules/zca-js/dist/apis/addGroupBlockedMember.js +28 -0
  621. package/node_modules/zca-js/dist/apis/addGroupDeputy.d.ts +2 -0
  622. package/node_modules/zca-js/dist/apis/addGroupDeputy.js +30 -0
  623. package/node_modules/zca-js/dist/apis/addPollOptions.d.ts +14 -0
  624. package/node_modules/zca-js/dist/apis/addPollOptions.js +26 -0
  625. package/node_modules/zca-js/dist/apis/addQuickMessage.d.ts +11 -0
  626. package/node_modules/zca-js/dist/apis/addQuickMessage.js +60 -0
  627. package/node_modules/zca-js/dist/apis/addReaction.d.ts +18 -0
  628. package/node_modules/zca-js/dist/apis/addReaction.js +294 -0
  629. package/node_modules/zca-js/dist/apis/addUnreadMark.d.ts +8 -0
  630. package/node_modules/zca-js/dist/apis/addUnreadMark.js +52 -0
  631. package/node_modules/zca-js/dist/apis/addUserToGroup.d.ts +5 -0
  632. package/node_modules/zca-js/dist/apis/addUserToGroup.js +34 -0
  633. package/node_modules/zca-js/dist/apis/blockUser.d.ts +2 -0
  634. package/node_modules/zca-js/dist/apis/blockUser.js +28 -0
  635. package/node_modules/zca-js/dist/apis/blockViewFeed.d.ts +2 -0
  636. package/node_modules/zca-js/dist/apis/blockViewFeed.js +30 -0
  637. package/node_modules/zca-js/dist/apis/changeAccountAvatar.d.ts +3 -0
  638. package/node_modules/zca-js/dist/apis/changeAccountAvatar.js +52 -0
  639. package/node_modules/zca-js/dist/apis/changeFriendAlias.d.ts +2 -0
  640. package/node_modules/zca-js/dist/apis/changeFriendAlias.js +27 -0
  641. package/node_modules/zca-js/dist/apis/changeGroupAvatar.d.ts +3 -0
  642. package/node_modules/zca-js/dist/apis/changeGroupAvatar.js +44 -0
  643. package/node_modules/zca-js/dist/apis/changeGroupName.d.ts +4 -0
  644. package/node_modules/zca-js/dist/apis/changeGroupName.js +32 -0
  645. package/node_modules/zca-js/dist/apis/changeGroupOwner.d.ts +4 -0
  646. package/node_modules/zca-js/dist/apis/changeGroupOwner.js +30 -0
  647. package/node_modules/zca-js/dist/apis/createAutoReply.d.ts +14 -0
  648. package/node_modules/zca-js/dist/apis/createAutoReply.js +37 -0
  649. package/node_modules/zca-js/dist/apis/createBankAccount.d.ts +8 -0
  650. package/node_modules/zca-js/dist/apis/createBankAccount.js +32 -0
  651. package/node_modules/zca-js/dist/apis/createCatalog.d.ts +7 -0
  652. package/node_modules/zca-js/dist/apis/createCatalog.js +29 -0
  653. package/node_modules/zca-js/dist/apis/createGroup.d.ts +28 -0
  654. package/node_modules/zca-js/dist/apis/createGroup.js +43 -0
  655. package/node_modules/zca-js/dist/apis/createNote.d.ts +7 -0
  656. package/node_modules/zca-js/dist/apis/createNote.js +47 -0
  657. package/node_modules/zca-js/dist/apis/createPoll.d.ts +36 -0
  658. package/node_modules/zca-js/dist/apis/createPoll.js +40 -0
  659. package/node_modules/zca-js/dist/apis/createProductCatalog.d.ts +23 -0
  660. package/node_modules/zca-js/dist/apis/createProductCatalog.js +50 -0
  661. package/node_modules/zca-js/dist/apis/createReminder.d.ts +12 -0
  662. package/node_modules/zca-js/dist/apis/createReminder.js +63 -0
  663. package/node_modules/zca-js/dist/apis/custom.d.ts +9 -0
  664. package/node_modules/zca-js/dist/apis/custom.js +15 -0
  665. package/node_modules/zca-js/dist/apis/deleteAutoReply.d.ts +5 -0
  666. package/node_modules/zca-js/dist/apis/deleteAutoReply.js +29 -0
  667. package/node_modules/zca-js/dist/apis/deleteAvatar.d.ts +9 -0
  668. package/node_modules/zca-js/dist/apis/deleteAvatar.js +27 -0
  669. package/node_modules/zca-js/dist/apis/deleteBankAccount.d.ts +11 -0
  670. package/node_modules/zca-js/dist/apis/deleteBankAccount.js +32 -0
  671. package/node_modules/zca-js/dist/apis/deleteCatalog.d.ts +2 -0
  672. package/node_modules/zca-js/dist/apis/deleteCatalog.js +28 -0
  673. package/node_modules/zca-js/dist/apis/deleteChat.d.ts +19 -0
  674. package/node_modules/zca-js/dist/apis/deleteChat.js +50 -0
  675. package/node_modules/zca-js/dist/apis/deleteGroupInviteBox.d.ts +9 -0
  676. package/node_modules/zca-js/dist/apis/deleteGroupInviteBox.js +27 -0
  677. package/node_modules/zca-js/dist/apis/deleteMessage.d.ts +14 -0
  678. package/node_modules/zca-js/dist/apis/deleteMessage.js +52 -0
  679. package/node_modules/zca-js/dist/apis/deleteProductCatalog.d.ts +10 -0
  680. package/node_modules/zca-js/dist/apis/deleteProductCatalog.js +31 -0
  681. package/node_modules/zca-js/dist/apis/deleteSnapshotMobileMsg.js +18 -0
  682. package/node_modules/zca-js/dist/apis/disableGroupLink.d.ts +2 -0
  683. package/node_modules/zca-js/dist/apis/disableGroupLink.js +24 -0
  684. package/node_modules/zca-js/dist/apis/disperseGroup.d.ts +2 -0
  685. package/node_modules/zca-js/dist/apis/disperseGroup.js +28 -0
  686. package/node_modules/zca-js/dist/apis/editNote.d.ts +17 -0
  687. package/node_modules/zca-js/dist/apis/editNote.js +46 -0
  688. package/node_modules/zca-js/dist/apis/editReminder.d.ts +13 -0
  689. package/node_modules/zca-js/dist/apis/editReminder.js +61 -0
  690. package/node_modules/zca-js/dist/apis/enableGroupLink.d.ts +6 -0
  691. package/node_modules/zca-js/dist/apis/enableGroupLink.js +25 -0
  692. package/node_modules/zca-js/dist/apis/fetchAccountInfo.d.ts +5 -0
  693. package/node_modules/zca-js/dist/apis/fetchAccountInfo.js +10 -0
  694. package/node_modules/zca-js/dist/apis/findUser.d.ts +3 -0
  695. package/node_modules/zca-js/dist/apis/findUser.js +42 -0
  696. package/node_modules/zca-js/dist/apis/findUserByUsername.d.ts +3 -0
  697. package/node_modules/zca-js/dist/apis/findUserByUsername.js +27 -0
  698. package/node_modules/zca-js/dist/apis/forwardMessage.d.ts +24 -0
  699. package/node_modules/zca-js/dist/apis/forwardMessage.js +114 -0
  700. package/node_modules/zca-js/dist/apis/getAliasList.d.ts +8 -0
  701. package/node_modules/zca-js/dist/apis/getAliasList.js +27 -0
  702. package/node_modules/zca-js/dist/apis/getAllFriends.d.ts +3 -0
  703. package/node_modules/zca-js/dist/apis/getAllFriends.js +34 -0
  704. package/node_modules/zca-js/dist/apis/getAllGroups.d.ts +7 -0
  705. package/node_modules/zca-js/dist/apis/getAllGroups.js +10 -0
  706. package/node_modules/zca-js/dist/apis/getArchivedChatList.d.ts +5 -0
  707. package/node_modules/zca-js/dist/apis/getArchivedChatList.js +23 -0
  708. package/node_modules/zca-js/dist/apis/getAutoDeleteChat.d.ts +9 -0
  709. package/node_modules/zca-js/dist/apis/getAutoDeleteChat.js +21 -0
  710. package/node_modules/zca-js/dist/apis/getAutoReplyList.d.ts +6 -0
  711. package/node_modules/zca-js/dist/apis/getAutoReplyList.js +24 -0
  712. package/node_modules/zca-js/dist/apis/getAvatarList.d.ts +12 -0
  713. package/node_modules/zca-js/dist/apis/getAvatarList.js +28 -0
  714. package/node_modules/zca-js/dist/apis/getAvatarUrlProfile.d.ts +7 -0
  715. package/node_modules/zca-js/dist/apis/getAvatarUrlProfile.js +30 -0
  716. package/node_modules/zca-js/dist/apis/getBizAccount.d.ts +24 -0
  717. package/node_modules/zca-js/dist/apis/getBizAccount.js +27 -0
  718. package/node_modules/zca-js/dist/apis/getCatalogList.d.ts +18 -0
  719. package/node_modules/zca-js/dist/apis/getCatalogList.js +32 -0
  720. package/node_modules/zca-js/dist/apis/getCloseFriends.d.ts +3 -0
  721. package/node_modules/zca-js/dist/apis/getCloseFriends.js +20 -0
  722. package/node_modules/zca-js/dist/apis/getContext.d.ts +1 -0
  723. package/node_modules/zca-js/dist/apis/getContext.js +4 -0
  724. package/node_modules/zca-js/dist/apis/getCookie.d.ts +1 -0
  725. package/node_modules/zca-js/dist/apis/getCookie.js +9 -0
  726. package/node_modules/zca-js/dist/apis/getCrossDB.js +18 -0
  727. package/node_modules/zca-js/dist/apis/getFriendBoardList.d.ts +5 -0
  728. package/node_modules/zca-js/dist/apis/getFriendBoardList.js +26 -0
  729. package/node_modules/zca-js/dist/apis/getFriendOnlines.d.ts +10 -0
  730. package/node_modules/zca-js/dist/apis/getFriendOnlines.js +35 -0
  731. package/node_modules/zca-js/dist/apis/getFriendRecommendations.d.ts +42 -0
  732. package/node_modules/zca-js/dist/apis/getFriendRecommendations.js +27 -0
  733. package/node_modules/zca-js/dist/apis/getFriendRequestStatus.d.ts +8 -0
  734. package/node_modules/zca-js/dist/apis/getFriendRequestStatus.js +25 -0
  735. package/node_modules/zca-js/dist/apis/getFullAvatar.d.ts +5 -0
  736. package/node_modules/zca-js/dist/apis/getFullAvatar.js +25 -0
  737. package/node_modules/zca-js/dist/apis/getGroupBlockedMember.d.ts +23 -0
  738. package/node_modules/zca-js/dist/apis/getGroupBlockedMember.js +29 -0
  739. package/node_modules/zca-js/dist/apis/getGroupChatHistory.d.ts +8 -0
  740. package/node_modules/zca-js/dist/apis/getGroupChatHistory.js +36 -0
  741. package/node_modules/zca-js/dist/apis/getGroupInfo.d.ts +16 -0
  742. package/node_modules/zca-js/dist/apis/getGroupInfo.js +32 -0
  743. package/node_modules/zca-js/dist/apis/getGroupInviteBoxInfo.d.ts +32 -0
  744. package/node_modules/zca-js/dist/apis/getGroupInviteBoxInfo.js +38 -0
  745. package/node_modules/zca-js/dist/apis/getGroupInviteBoxList.d.ts +38 -0
  746. package/node_modules/zca-js/dist/apis/getGroupInviteBoxList.js +31 -0
  747. package/node_modules/zca-js/dist/apis/getGroupLinkDetail.d.ts +9 -0
  748. package/node_modules/zca-js/dist/apis/getGroupLinkDetail.js +25 -0
  749. package/node_modules/zca-js/dist/apis/getGroupLinkInfo.d.ts +34 -0
  750. package/node_modules/zca-js/dist/apis/getGroupLinkInfo.js +28 -0
  751. package/node_modules/zca-js/dist/apis/getGroupMembersInfo.d.ts +17 -0
  752. package/node_modules/zca-js/dist/apis/getGroupMembersInfo.js +24 -0
  753. package/node_modules/zca-js/dist/apis/getHiddenConversations.d.ts +11 -0
  754. package/node_modules/zca-js/dist/apis/getHiddenConversations.js +23 -0
  755. package/node_modules/zca-js/dist/apis/getLabels.d.ts +7 -0
  756. package/node_modules/zca-js/dist/apis/getLabels.js +28 -0
  757. package/node_modules/zca-js/dist/apis/getListBank.d.ts +5 -0
  758. package/node_modules/zca-js/dist/apis/getListBank.js +20 -0
  759. package/node_modules/zca-js/dist/apis/getListBankAccount.d.ts +7 -0
  760. package/node_modules/zca-js/dist/apis/getListBankAccount.js +27 -0
  761. package/node_modules/zca-js/dist/apis/getListBoard.d.ts +21 -0
  762. package/node_modules/zca-js/dist/apis/getListBoard.js +45 -0
  763. package/node_modules/zca-js/dist/apis/getListDevice.d.ts +10 -0
  764. package/node_modules/zca-js/dist/apis/getListDevice.js +22 -0
  765. package/node_modules/zca-js/dist/apis/getListReminder.d.ts +28 -0
  766. package/node_modules/zca-js/dist/apis/getListReminder.js +47 -0
  767. package/node_modules/zca-js/dist/apis/getMultiUsersByPhones.d.ts +5 -0
  768. package/node_modules/zca-js/dist/apis/getMultiUsersByPhones.js +39 -0
  769. package/node_modules/zca-js/dist/apis/getMute.d.ts +13 -0
  770. package/node_modules/zca-js/dist/apis/getMute.js +22 -0
  771. package/node_modules/zca-js/dist/apis/getOwnId.d.ts +1 -0
  772. package/node_modules/zca-js/dist/apis/getOwnId.js +4 -0
  773. package/node_modules/zca-js/dist/apis/getPendingGroupMembers.d.ts +11 -0
  774. package/node_modules/zca-js/dist/apis/getPendingGroupMembers.js +27 -0
  775. package/node_modules/zca-js/dist/apis/getPinConversations.d.ts +5 -0
  776. package/node_modules/zca-js/dist/apis/getPinConversations.js +22 -0
  777. package/node_modules/zca-js/dist/apis/getPollDetail.d.ts +3 -0
  778. package/node_modules/zca-js/dist/apis/getPollDetail.js +30 -0
  779. package/node_modules/zca-js/dist/apis/getProductCatalogList.d.ts +20 -0
  780. package/node_modules/zca-js/dist/apis/getProductCatalogList.js +33 -0
  781. package/node_modules/zca-js/dist/apis/getQR.d.ts +4 -0
  782. package/node_modules/zca-js/dist/apis/getQR.js +29 -0
  783. package/node_modules/zca-js/dist/apis/getQuickMessageList.d.ts +7 -0
  784. package/node_modules/zca-js/dist/apis/getQuickMessageList.js +24 -0
  785. package/node_modules/zca-js/dist/apis/getRelatedFriendGroup.d.ts +6 -0
  786. package/node_modules/zca-js/dist/apis/getRelatedFriendGroup.js +30 -0
  787. package/node_modules/zca-js/dist/apis/getReminder.d.ts +3 -0
  788. package/node_modules/zca-js/dist/apis/getReminder.js +25 -0
  789. package/node_modules/zca-js/dist/apis/getReminderResponses.d.ts +5 -0
  790. package/node_modules/zca-js/dist/apis/getReminderResponses.js +24 -0
  791. package/node_modules/zca-js/dist/apis/getSentFriendRequest.d.ts +18 -0
  792. package/node_modules/zca-js/dist/apis/getSentFriendRequest.js +24 -0
  793. package/node_modules/zca-js/dist/apis/getSettings.d.ts +3 -0
  794. package/node_modules/zca-js/dist/apis/getSettings.js +20 -0
  795. package/node_modules/zca-js/dist/apis/getStickerCategoryDetail.d.ts +3 -0
  796. package/node_modules/zca-js/dist/apis/getStickerCategoryDetail.js +24 -0
  797. package/node_modules/zca-js/dist/apis/getStickers.d.ts +1 -0
  798. package/node_modules/zca-js/dist/apis/getStickers.js +40 -0
  799. package/node_modules/zca-js/dist/apis/getStickersDetail.d.ts +3 -0
  800. package/node_modules/zca-js/dist/apis/getStickersDetail.js +40 -0
  801. package/node_modules/zca-js/dist/apis/getUnreadMark.d.ts +14 -0
  802. package/node_modules/zca-js/dist/apis/getUnreadMark.js +30 -0
  803. package/node_modules/zca-js/dist/apis/getUserInfo.d.ts +8 -0
  804. package/node_modules/zca-js/dist/apis/getUserInfo.js +44 -0
  805. package/node_modules/zca-js/dist/apis/inviteUserToGroups.d.ts +10 -0
  806. package/node_modules/zca-js/dist/apis/inviteUserToGroups.js +30 -0
  807. package/node_modules/zca-js/dist/apis/joinGroupInviteBox.d.ts +2 -0
  808. package/node_modules/zca-js/dist/apis/joinGroupInviteBox.js +25 -0
  809. package/node_modules/zca-js/dist/apis/joinGroupLink.d.ts +2 -0
  810. package/node_modules/zca-js/dist/apis/joinGroupLink.js +27 -0
  811. package/node_modules/zca-js/dist/apis/keepAlive.d.ts +4 -0
  812. package/node_modules/zca-js/dist/apis/keepAlive.js +22 -0
  813. package/node_modules/zca-js/dist/apis/lastOnline.d.ts +7 -0
  814. package/node_modules/zca-js/dist/apis/lastOnline.js +26 -0
  815. package/node_modules/zca-js/dist/apis/leaveGroup.d.ts +4 -0
  816. package/node_modules/zca-js/dist/apis/leaveGroup.js +33 -0
  817. package/node_modules/zca-js/dist/apis/listen.d.ts +102 -0
  818. package/node_modules/zca-js/dist/apis/listen.js +425 -0
  819. package/node_modules/zca-js/dist/apis/lockPoll.d.ts +2 -0
  820. package/node_modules/zca-js/dist/apis/lockPoll.js +28 -0
  821. package/node_modules/zca-js/dist/apis/login.d.ts +3 -0
  822. package/node_modules/zca-js/dist/apis/login.js +96 -0
  823. package/node_modules/zca-js/dist/apis/loginQR.d.ts +71 -0
  824. package/node_modules/zca-js/dist/apis/loginQR.js +376 -0
  825. package/node_modules/zca-js/dist/apis/logoutV2.js +79 -0
  826. package/node_modules/zca-js/dist/apis/lostFocus.d.ts +4 -0
  827. package/node_modules/zca-js/dist/apis/lostFocus.js +23 -0
  828. package/node_modules/zca-js/dist/apis/parseLink.d.ts +21 -0
  829. package/node_modules/zca-js/dist/apis/parseLink.js +27 -0
  830. package/node_modules/zca-js/dist/apis/pullMobileMsg.js +22 -0
  831. package/node_modules/zca-js/dist/apis/registerCatalog.d.ts +2 -0
  832. package/node_modules/zca-js/dist/apis/registerCatalog.js +27 -0
  833. package/node_modules/zca-js/dist/apis/rejectFriendRequest.d.ts +2 -0
  834. package/node_modules/zca-js/dist/apis/rejectFriendRequest.js +27 -0
  835. package/node_modules/zca-js/dist/apis/removeFriend.d.ts +2 -0
  836. package/node_modules/zca-js/dist/apis/removeFriend.js +28 -0
  837. package/node_modules/zca-js/dist/apis/removeFriendAlias.d.ts +2 -0
  838. package/node_modules/zca-js/dist/apis/removeFriendAlias.js +24 -0
  839. package/node_modules/zca-js/dist/apis/removeGroupBlockedMember.d.ts +2 -0
  840. package/node_modules/zca-js/dist/apis/removeGroupBlockedMember.js +28 -0
  841. package/node_modules/zca-js/dist/apis/removeGroupDeputy.d.ts +2 -0
  842. package/node_modules/zca-js/dist/apis/removeGroupDeputy.js +30 -0
  843. package/node_modules/zca-js/dist/apis/removeQuickMessage.d.ts +5 -0
  844. package/node_modules/zca-js/dist/apis/removeQuickMessage.js +27 -0
  845. package/node_modules/zca-js/dist/apis/removeReminder.d.ts +3 -0
  846. package/node_modules/zca-js/dist/apis/removeReminder.js +40 -0
  847. package/node_modules/zca-js/dist/apis/removeUnreadMark.d.ts +8 -0
  848. package/node_modules/zca-js/dist/apis/removeUnreadMark.js +50 -0
  849. package/node_modules/zca-js/dist/apis/removeUserFromGroup.d.ts +4 -0
  850. package/node_modules/zca-js/dist/apis/removeUserFromGroup.js +34 -0
  851. package/node_modules/zca-js/dist/apis/requestSyncMessage.js +18 -0
  852. package/node_modules/zca-js/dist/apis/resetHiddenConversPin.d.ts +2 -0
  853. package/node_modules/zca-js/dist/apis/resetHiddenConversPin.js +20 -0
  854. package/node_modules/zca-js/dist/apis/reuseAvatar.d.ts +2 -0
  855. package/node_modules/zca-js/dist/apis/reuseAvatar.js +26 -0
  856. package/node_modules/zca-js/dist/apis/reviewPendingMemberRequest.d.ts +14 -0
  857. package/node_modules/zca-js/dist/apis/reviewPendingMemberRequest.js +38 -0
  858. package/node_modules/zca-js/dist/apis/scanURL.d.ts +4 -0
  859. package/node_modules/zca-js/dist/apis/scanURL.js +28 -0
  860. package/node_modules/zca-js/dist/apis/searchSticker.d.ts +3 -0
  861. package/node_modules/zca-js/dist/apis/searchSticker.js +28 -0
  862. package/node_modules/zca-js/dist/apis/sendBankCard.d.ts +9 -0
  863. package/node_modules/zca-js/dist/apis/sendBankCard.js +53 -0
  864. package/node_modules/zca-js/dist/apis/sendCard.d.ts +10 -0
  865. package/node_modules/zca-js/dist/apis/sendCard.js +75 -0
  866. package/node_modules/zca-js/dist/apis/sendDeliveredEvent.d.ts +16 -0
  867. package/node_modules/zca-js/dist/apis/sendDeliveredEvent.js +55 -0
  868. package/node_modules/zca-js/dist/apis/sendFriendRequest.d.ts +2 -0
  869. package/node_modules/zca-js/dist/apis/sendFriendRequest.js +39 -0
  870. package/node_modules/zca-js/dist/apis/sendLink.d.ts +10 -0
  871. package/node_modules/zca-js/dist/apis/sendLink.js +78 -0
  872. package/node_modules/zca-js/dist/apis/sendMessage.d.ts +105 -0
  873. package/node_modules/zca-js/dist/apis/sendMessage.js +486 -0
  874. package/node_modules/zca-js/dist/apis/sendReport.d.ts +17 -0
  875. package/node_modules/zca-js/dist/apis/sendReport.js +53 -0
  876. package/node_modules/zca-js/dist/apis/sendSeenEvent.d.ts +16 -0
  877. package/node_modules/zca-js/dist/apis/sendSeenEvent.js +63 -0
  878. package/node_modules/zca-js/dist/apis/sendSticker.d.ts +10 -0
  879. package/node_modules/zca-js/dist/apis/sendSticker.js +74 -0
  880. package/node_modules/zca-js/dist/apis/sendTypingEvent.d.ts +5 -0
  881. package/node_modules/zca-js/dist/apis/sendTypingEvent.js +33 -0
  882. package/node_modules/zca-js/dist/apis/sendVideo.d.ts +35 -0
  883. package/node_modules/zca-js/dist/apis/sendVideo.js +134 -0
  884. package/node_modules/zca-js/dist/apis/sendVoice.d.ts +12 -0
  885. package/node_modules/zca-js/dist/apis/sendVoice.js +89 -0
  886. package/node_modules/zca-js/dist/apis/setHiddenConversations.d.ts +3 -0
  887. package/node_modules/zca-js/dist/apis/setHiddenConversations.js +39 -0
  888. package/node_modules/zca-js/dist/apis/setMute.d.ts +20 -0
  889. package/node_modules/zca-js/dist/apis/setMute.js +67 -0
  890. package/node_modules/zca-js/dist/apis/setPinnedConversations.d.ts +3 -0
  891. package/node_modules/zca-js/dist/apis/setPinnedConversations.js +34 -0
  892. package/node_modules/zca-js/dist/apis/sharePoll.d.ts +2 -0
  893. package/node_modules/zca-js/dist/apis/sharePoll.js +28 -0
  894. package/node_modules/zca-js/dist/apis/unblockUser.d.ts +2 -0
  895. package/node_modules/zca-js/dist/apis/unblockUser.js +28 -0
  896. package/node_modules/zca-js/dist/apis/undo.d.ts +9 -0
  897. package/node_modules/zca-js/dist/apis/undo.js +42 -0
  898. package/node_modules/zca-js/dist/apis/undoFriendRequest.d.ts +2 -0
  899. package/node_modules/zca-js/dist/apis/undoFriendRequest.js +27 -0
  900. package/node_modules/zca-js/dist/apis/updateActiveStatus.d.ts +4 -0
  901. package/node_modules/zca-js/dist/apis/updateActiveStatus.js +27 -0
  902. package/node_modules/zca-js/dist/apis/updateArchivedChatList.d.ts +10 -0
  903. package/node_modules/zca-js/dist/apis/updateArchivedChatList.js +34 -0
  904. package/node_modules/zca-js/dist/apis/updateAutoDeleteChat.d.ts +9 -0
  905. package/node_modules/zca-js/dist/apis/updateAutoDeleteChat.js +40 -0
  906. package/node_modules/zca-js/dist/apis/updateAutoReply.d.ts +15 -0
  907. package/node_modules/zca-js/dist/apis/updateAutoReply.js +38 -0
  908. package/node_modules/zca-js/dist/apis/updateBankAccount.d.ts +9 -0
  909. package/node_modules/zca-js/dist/apis/updateBankAccount.js +31 -0
  910. package/node_modules/zca-js/dist/apis/updateCatalog.d.ts +11 -0
  911. package/node_modules/zca-js/dist/apis/updateCatalog.js +30 -0
  912. package/node_modules/zca-js/dist/apis/updateGroupSettings.d.ts +40 -0
  913. package/node_modules/zca-js/dist/apis/updateGroupSettings.js +43 -0
  914. package/node_modules/zca-js/dist/apis/updateHiddenConversPin.d.ts +2 -0
  915. package/node_modules/zca-js/dist/apis/updateHiddenConversPin.js +30 -0
  916. package/node_modules/zca-js/dist/apis/updateLabels.d.ts +15 -0
  917. package/node_modules/zca-js/dist/apis/updateLabels.js +34 -0
  918. package/node_modules/zca-js/dist/apis/updateLang.d.ts +6 -0
  919. package/node_modules/zca-js/dist/apis/updateLang.js +30 -0
  920. package/node_modules/zca-js/dist/apis/updateProductCatalog.d.ts +25 -0
  921. package/node_modules/zca-js/dist/apis/updateProductCatalog.js +51 -0
  922. package/node_modules/zca-js/dist/apis/updateProfile.d.ts +20 -0
  923. package/node_modules/zca-js/dist/apis/updateProfile.js +43 -0
  924. package/node_modules/zca-js/dist/apis/updateProfileBio.d.ts +2 -0
  925. package/node_modules/zca-js/dist/apis/updateProfileBio.js +27 -0
  926. package/node_modules/zca-js/dist/apis/updateQuickMessage.d.ts +11 -0
  927. package/node_modules/zca-js/dist/apis/updateQuickMessage.js +61 -0
  928. package/node_modules/zca-js/dist/apis/updateSettings.d.ts +16 -0
  929. package/node_modules/zca-js/dist/apis/updateSettings.js +90 -0
  930. package/node_modules/zca-js/dist/apis/upgradeGroupToCommunity.d.ts +2 -0
  931. package/node_modules/zca-js/dist/apis/upgradeGroupToCommunity.js +27 -0
  932. package/node_modules/zca-js/dist/apis/uploadAttachment.d.ts +50 -0
  933. package/node_modules/zca-js/dist/apis/uploadAttachment.js +197 -0
  934. package/node_modules/zca-js/dist/apis/uploadProductPhoto.d.ts +14 -0
  935. package/node_modules/zca-js/dist/apis/uploadProductPhoto.js +50 -0
  936. package/node_modules/zca-js/dist/apis/votePoll.d.ts +5 -0
  937. package/node_modules/zca-js/dist/apis/votePoll.js +29 -0
  938. package/node_modules/zca-js/dist/apis.d.ts +317 -0
  939. package/node_modules/zca-js/dist/apis.js +327 -0
  940. package/node_modules/zca-js/dist/cjs/Errors/ZaloApiError.cjs +11 -0
  941. package/node_modules/zca-js/dist/cjs/Errors/ZaloApiLoginQRAborted.cjs +12 -0
  942. package/node_modules/zca-js/dist/cjs/Errors/ZaloApiLoginQRDeclined.cjs +12 -0
  943. package/node_modules/zca-js/dist/cjs/Errors/ZaloApiMissingImageMetadataGetter.cjs +12 -0
  944. package/node_modules/zca-js/dist/cjs/apis/acceptFriendRequest.cjs +33 -0
  945. package/node_modules/zca-js/dist/cjs/apis/addGroupBlockedMember.cjs +33 -0
  946. package/node_modules/zca-js/dist/cjs/apis/addGroupDeputy.cjs +35 -0
  947. package/node_modules/zca-js/dist/cjs/apis/addPollOptions.cjs +31 -0
  948. package/node_modules/zca-js/dist/cjs/apis/addQuickMessage.cjs +65 -0
  949. package/node_modules/zca-js/dist/cjs/apis/addReaction.cjs +308 -0
  950. package/node_modules/zca-js/dist/cjs/apis/addUnreadMark.cjs +66 -0
  951. package/node_modules/zca-js/dist/cjs/apis/addUserToGroup.cjs +39 -0
  952. package/node_modules/zca-js/dist/cjs/apis/blockUser.cjs +33 -0
  953. package/node_modules/zca-js/dist/cjs/apis/blockViewFeed.cjs +35 -0
  954. package/node_modules/zca-js/dist/cjs/apis/changeAccountAvatar.cjs +57 -0
  955. package/node_modules/zca-js/dist/cjs/apis/changeFriendAlias.cjs +32 -0
  956. package/node_modules/zca-js/dist/cjs/apis/changeGroupAvatar.cjs +49 -0
  957. package/node_modules/zca-js/dist/cjs/apis/changeGroupName.cjs +37 -0
  958. package/node_modules/zca-js/dist/cjs/apis/changeGroupOwner.cjs +35 -0
  959. package/node_modules/zca-js/dist/cjs/apis/createAutoReply.cjs +42 -0
  960. package/node_modules/zca-js/dist/cjs/apis/createBankAccount.cjs +37 -0
  961. package/node_modules/zca-js/dist/cjs/apis/createCatalog.cjs +34 -0
  962. package/node_modules/zca-js/dist/cjs/apis/createGroup.cjs +48 -0
  963. package/node_modules/zca-js/dist/cjs/apis/createNote.cjs +52 -0
  964. package/node_modules/zca-js/dist/cjs/apis/createPoll.cjs +45 -0
  965. package/node_modules/zca-js/dist/cjs/apis/createProductCatalog.cjs +55 -0
  966. package/node_modules/zca-js/dist/cjs/apis/createReminder.cjs +77 -0
  967. package/node_modules/zca-js/dist/cjs/apis/custom.cjs +19 -0
  968. package/node_modules/zca-js/dist/cjs/apis/deleteAutoReply.cjs +34 -0
  969. package/node_modules/zca-js/dist/cjs/apis/deleteAvatar.cjs +32 -0
  970. package/node_modules/zca-js/dist/cjs/apis/deleteBankAccount.cjs +37 -0
  971. package/node_modules/zca-js/dist/cjs/apis/deleteCatalog.cjs +33 -0
  972. package/node_modules/zca-js/dist/cjs/apis/deleteChat.cjs +64 -0
  973. package/node_modules/zca-js/dist/cjs/apis/deleteGroupInviteBox.cjs +32 -0
  974. package/node_modules/zca-js/dist/cjs/apis/deleteMessage.cjs +66 -0
  975. package/node_modules/zca-js/dist/cjs/apis/deleteProductCatalog.cjs +36 -0
  976. package/node_modules/zca-js/dist/cjs/apis/deleteSnapshotMobileMsg.cjs +22 -0
  977. package/node_modules/zca-js/dist/cjs/apis/disableGroupLink.cjs +29 -0
  978. package/node_modules/zca-js/dist/cjs/apis/disperseGroup.cjs +33 -0
  979. package/node_modules/zca-js/dist/cjs/apis/editNote.cjs +51 -0
  980. package/node_modules/zca-js/dist/cjs/apis/editReminder.cjs +75 -0
  981. package/node_modules/zca-js/dist/cjs/apis/enableGroupLink.cjs +30 -0
  982. package/node_modules/zca-js/dist/cjs/apis/fetchAccountInfo.cjs +15 -0
  983. package/node_modules/zca-js/dist/cjs/apis/findUser.cjs +56 -0
  984. package/node_modules/zca-js/dist/cjs/apis/findUserByUsername.cjs +41 -0
  985. package/node_modules/zca-js/dist/cjs/apis/forwardMessage.cjs +129 -0
  986. package/node_modules/zca-js/dist/cjs/apis/getAliasList.cjs +32 -0
  987. package/node_modules/zca-js/dist/cjs/apis/getAllFriends.cjs +48 -0
  988. package/node_modules/zca-js/dist/cjs/apis/getAllGroups.cjs +15 -0
  989. package/node_modules/zca-js/dist/cjs/apis/getArchivedChatList.cjs +28 -0
  990. package/node_modules/zca-js/dist/cjs/apis/getAutoDeleteChat.cjs +26 -0
  991. package/node_modules/zca-js/dist/cjs/apis/getAutoReplyList.cjs +29 -0
  992. package/node_modules/zca-js/dist/cjs/apis/getAvatarList.cjs +33 -0
  993. package/node_modules/zca-js/dist/cjs/apis/getAvatarUrlProfile.cjs +44 -0
  994. package/node_modules/zca-js/dist/cjs/apis/getBizAccount.cjs +32 -0
  995. package/node_modules/zca-js/dist/cjs/apis/getCatalogList.cjs +37 -0
  996. package/node_modules/zca-js/dist/cjs/apis/getCloseFriends.cjs +25 -0
  997. package/node_modules/zca-js/dist/cjs/apis/getContext.cjs +9 -0
  998. package/node_modules/zca-js/dist/cjs/apis/getCookie.cjs +14 -0
  999. package/node_modules/zca-js/dist/cjs/apis/getCrossDB.cjs +22 -0
  1000. package/node_modules/zca-js/dist/cjs/apis/getFriendBoardList.cjs +31 -0
  1001. package/node_modules/zca-js/dist/cjs/apis/getFriendOnlines.cjs +40 -0
  1002. package/node_modules/zca-js/dist/cjs/apis/getFriendRecommendations.cjs +32 -0
  1003. package/node_modules/zca-js/dist/cjs/apis/getFriendRequestStatus.cjs +30 -0
  1004. package/node_modules/zca-js/dist/cjs/apis/getFullAvatar.cjs +30 -0
  1005. package/node_modules/zca-js/dist/cjs/apis/getGroupBlockedMember.cjs +34 -0
  1006. package/node_modules/zca-js/dist/cjs/apis/getGroupChatHistory.cjs +51 -0
  1007. package/node_modules/zca-js/dist/cjs/apis/getGroupInfo.cjs +37 -0
  1008. package/node_modules/zca-js/dist/cjs/apis/getGroupInviteBoxInfo.cjs +43 -0
  1009. package/node_modules/zca-js/dist/cjs/apis/getGroupInviteBoxList.cjs +36 -0
  1010. package/node_modules/zca-js/dist/cjs/apis/getGroupLinkDetail.cjs +30 -0
  1011. package/node_modules/zca-js/dist/cjs/apis/getGroupLinkInfo.cjs +33 -0
  1012. package/node_modules/zca-js/dist/cjs/apis/getGroupMembersInfo.cjs +29 -0
  1013. package/node_modules/zca-js/dist/cjs/apis/getHiddenConversations.cjs +28 -0
  1014. package/node_modules/zca-js/dist/cjs/apis/getLabels.cjs +33 -0
  1015. package/node_modules/zca-js/dist/cjs/apis/getListBank.cjs +25 -0
  1016. package/node_modules/zca-js/dist/cjs/apis/getListBankAccount.cjs +32 -0
  1017. package/node_modules/zca-js/dist/cjs/apis/getListBoard.cjs +59 -0
  1018. package/node_modules/zca-js/dist/cjs/apis/getListDevice.cjs +27 -0
  1019. package/node_modules/zca-js/dist/cjs/apis/getListReminder.cjs +61 -0
  1020. package/node_modules/zca-js/dist/cjs/apis/getMultiUsersByPhones.cjs +53 -0
  1021. package/node_modules/zca-js/dist/cjs/apis/getMute.cjs +27 -0
  1022. package/node_modules/zca-js/dist/cjs/apis/getOwnId.cjs +9 -0
  1023. package/node_modules/zca-js/dist/cjs/apis/getPendingGroupMembers.cjs +32 -0
  1024. package/node_modules/zca-js/dist/cjs/apis/getPinConversations.cjs +27 -0
  1025. package/node_modules/zca-js/dist/cjs/apis/getPollDetail.cjs +35 -0
  1026. package/node_modules/zca-js/dist/cjs/apis/getProductCatalogList.cjs +38 -0
  1027. package/node_modules/zca-js/dist/cjs/apis/getQR.cjs +34 -0
  1028. package/node_modules/zca-js/dist/cjs/apis/getQuickMessageList.cjs +29 -0
  1029. package/node_modules/zca-js/dist/cjs/apis/getRelatedFriendGroup.cjs +35 -0
  1030. package/node_modules/zca-js/dist/cjs/apis/getReminder.cjs +30 -0
  1031. package/node_modules/zca-js/dist/cjs/apis/getReminderResponses.cjs +29 -0
  1032. package/node_modules/zca-js/dist/cjs/apis/getSentFriendRequest.cjs +29 -0
  1033. package/node_modules/zca-js/dist/cjs/apis/getSettings.cjs +25 -0
  1034. package/node_modules/zca-js/dist/cjs/apis/getStickerCategoryDetail.cjs +29 -0
  1035. package/node_modules/zca-js/dist/cjs/apis/getStickers.cjs +45 -0
  1036. package/node_modules/zca-js/dist/cjs/apis/getStickersDetail.cjs +45 -0
  1037. package/node_modules/zca-js/dist/cjs/apis/getUnreadMark.cjs +35 -0
  1038. package/node_modules/zca-js/dist/cjs/apis/getUserInfo.cjs +58 -0
  1039. package/node_modules/zca-js/dist/cjs/apis/inviteUserToGroups.cjs +35 -0
  1040. package/node_modules/zca-js/dist/cjs/apis/joinGroupInviteBox.cjs +30 -0
  1041. package/node_modules/zca-js/dist/cjs/apis/joinGroupLink.cjs +32 -0
  1042. package/node_modules/zca-js/dist/cjs/apis/keepAlive.cjs +27 -0
  1043. package/node_modules/zca-js/dist/cjs/apis/lastOnline.cjs +31 -0
  1044. package/node_modules/zca-js/dist/cjs/apis/leaveGroup.cjs +38 -0
  1045. package/node_modules/zca-js/dist/cjs/apis/listen.cjs +440 -0
  1046. package/node_modules/zca-js/dist/cjs/apis/lockPoll.cjs +33 -0
  1047. package/node_modules/zca-js/dist/cjs/apis/login.cjs +102 -0
  1048. package/node_modules/zca-js/dist/cjs/apis/loginQR.cjs +368 -0
  1049. package/node_modules/zca-js/dist/cjs/apis/logoutV2.cjs +83 -0
  1050. package/node_modules/zca-js/dist/cjs/apis/lostFocus.cjs +28 -0
  1051. package/node_modules/zca-js/dist/cjs/apis/parseLink.cjs +32 -0
  1052. package/node_modules/zca-js/dist/cjs/apis/pullMobileMsg.cjs +26 -0
  1053. package/node_modules/zca-js/dist/cjs/apis/registerCatalog.cjs +32 -0
  1054. package/node_modules/zca-js/dist/cjs/apis/rejectFriendRequest.cjs +32 -0
  1055. package/node_modules/zca-js/dist/cjs/apis/removeFriend.cjs +33 -0
  1056. package/node_modules/zca-js/dist/cjs/apis/removeFriendAlias.cjs +29 -0
  1057. package/node_modules/zca-js/dist/cjs/apis/removeGroupBlockedMember.cjs +33 -0
  1058. package/node_modules/zca-js/dist/cjs/apis/removeGroupDeputy.cjs +35 -0
  1059. package/node_modules/zca-js/dist/cjs/apis/removeQuickMessage.cjs +32 -0
  1060. package/node_modules/zca-js/dist/cjs/apis/removeReminder.cjs +54 -0
  1061. package/node_modules/zca-js/dist/cjs/apis/removeUnreadMark.cjs +64 -0
  1062. package/node_modules/zca-js/dist/cjs/apis/removeUserFromGroup.cjs +39 -0
  1063. package/node_modules/zca-js/dist/cjs/apis/requestSyncMessage.cjs +22 -0
  1064. package/node_modules/zca-js/dist/cjs/apis/resetHiddenConversPin.cjs +25 -0
  1065. package/node_modules/zca-js/dist/cjs/apis/reuseAvatar.cjs +31 -0
  1066. package/node_modules/zca-js/dist/cjs/apis/reviewPendingMemberRequest.cjs +43 -0
  1067. package/node_modules/zca-js/dist/cjs/apis/scanURL.cjs +33 -0
  1068. package/node_modules/zca-js/dist/cjs/apis/searchSticker.cjs +33 -0
  1069. package/node_modules/zca-js/dist/cjs/apis/sendBankCard.cjs +68 -0
  1070. package/node_modules/zca-js/dist/cjs/apis/sendCard.cjs +89 -0
  1071. package/node_modules/zca-js/dist/cjs/apis/sendDeliveredEvent.cjs +69 -0
  1072. package/node_modules/zca-js/dist/cjs/apis/sendFriendRequest.cjs +44 -0
  1073. package/node_modules/zca-js/dist/cjs/apis/sendLink.cjs +92 -0
  1074. package/node_modules/zca-js/dist/cjs/apis/sendMessage.cjs +500 -0
  1075. package/node_modules/zca-js/dist/cjs/apis/sendReport.cjs +67 -0
  1076. package/node_modules/zca-js/dist/cjs/apis/sendSeenEvent.cjs +77 -0
  1077. package/node_modules/zca-js/dist/cjs/apis/sendSticker.cjs +88 -0
  1078. package/node_modules/zca-js/dist/cjs/apis/sendTypingEvent.cjs +47 -0
  1079. package/node_modules/zca-js/dist/cjs/apis/sendVideo.cjs +148 -0
  1080. package/node_modules/zca-js/dist/cjs/apis/sendVoice.cjs +103 -0
  1081. package/node_modules/zca-js/dist/cjs/apis/setHiddenConversations.cjs +53 -0
  1082. package/node_modules/zca-js/dist/cjs/apis/setMute.cjs +81 -0
  1083. package/node_modules/zca-js/dist/cjs/apis/setPinnedConversations.cjs +48 -0
  1084. package/node_modules/zca-js/dist/cjs/apis/sharePoll.cjs +33 -0
  1085. package/node_modules/zca-js/dist/cjs/apis/unblockUser.cjs +33 -0
  1086. package/node_modules/zca-js/dist/cjs/apis/undo.cjs +56 -0
  1087. package/node_modules/zca-js/dist/cjs/apis/undoFriendRequest.cjs +32 -0
  1088. package/node_modules/zca-js/dist/cjs/apis/updateActiveStatus.cjs +32 -0
  1089. package/node_modules/zca-js/dist/cjs/apis/updateArchivedChatList.cjs +39 -0
  1090. package/node_modules/zca-js/dist/cjs/apis/updateAutoDeleteChat.cjs +54 -0
  1091. package/node_modules/zca-js/dist/cjs/apis/updateAutoReply.cjs +43 -0
  1092. package/node_modules/zca-js/dist/cjs/apis/updateBankAccount.cjs +36 -0
  1093. package/node_modules/zca-js/dist/cjs/apis/updateCatalog.cjs +35 -0
  1094. package/node_modules/zca-js/dist/cjs/apis/updateGroupSettings.cjs +48 -0
  1095. package/node_modules/zca-js/dist/cjs/apis/updateHiddenConversPin.cjs +35 -0
  1096. package/node_modules/zca-js/dist/cjs/apis/updateLabels.cjs +39 -0
  1097. package/node_modules/zca-js/dist/cjs/apis/updateLang.cjs +35 -0
  1098. package/node_modules/zca-js/dist/cjs/apis/updateProductCatalog.cjs +56 -0
  1099. package/node_modules/zca-js/dist/cjs/apis/updateProfile.cjs +48 -0
  1100. package/node_modules/zca-js/dist/cjs/apis/updateProfileBio.cjs +32 -0
  1101. package/node_modules/zca-js/dist/cjs/apis/updateQuickMessage.cjs +66 -0
  1102. package/node_modules/zca-js/dist/cjs/apis/updateSettings.cjs +95 -0
  1103. package/node_modules/zca-js/dist/cjs/apis/upgradeGroupToCommunity.cjs +32 -0
  1104. package/node_modules/zca-js/dist/cjs/apis/uploadAttachment.cjs +211 -0
  1105. package/node_modules/zca-js/dist/cjs/apis/uploadProductPhoto.cjs +55 -0
  1106. package/node_modules/zca-js/dist/cjs/apis/votePoll.cjs +34 -0
  1107. package/node_modules/zca-js/dist/cjs/apis.cjs +332 -0
  1108. package/node_modules/zca-js/dist/cjs/context.cjs +34 -0
  1109. package/node_modules/zca-js/dist/cjs/index.cjs +159 -0
  1110. package/node_modules/zca-js/dist/cjs/models/AutoReply.cjs +9 -0
  1111. package/node_modules/zca-js/dist/cjs/models/Bank.cjs +263 -0
  1112. package/node_modules/zca-js/dist/cjs/models/Board.cjs +8 -0
  1113. package/node_modules/zca-js/dist/cjs/models/DeliveredMessage.cjs +23 -0
  1114. package/node_modules/zca-js/dist/cjs/models/Enum.cjs +27 -0
  1115. package/node_modules/zca-js/dist/cjs/models/FriendEvent.cjs +87 -0
  1116. package/node_modules/zca-js/dist/cjs/models/Group.cjs +13 -0
  1117. package/node_modules/zca-js/dist/cjs/models/GroupEvent.cjs +94 -0
  1118. package/node_modules/zca-js/dist/cjs/models/Message.cjs +35 -0
  1119. package/node_modules/zca-js/dist/cjs/models/Reaction.cjs +74 -0
  1120. package/node_modules/zca-js/dist/cjs/models/Reminder.cjs +9 -0
  1121. package/node_modules/zca-js/dist/cjs/models/SeenMessage.cjs +23 -0
  1122. package/node_modules/zca-js/dist/cjs/models/Typing.cjs +23 -0
  1123. package/node_modules/zca-js/dist/cjs/models/Undo.cjs +16 -0
  1124. package/node_modules/zca-js/dist/cjs/models/ZBusiness.cjs +39 -0
  1125. package/node_modules/zca-js/dist/cjs/update.cjs +34 -0
  1126. package/node_modules/zca-js/dist/cjs/utils.cjs +703 -0
  1127. package/node_modules/zca-js/dist/cjs/zalo.cjs +112 -0
  1128. package/node_modules/zca-js/dist/context.d.ts +179 -0
  1129. package/node_modules/zca-js/dist/context.js +28 -0
  1130. package/node_modules/zca-js/dist/index.d.ts +166 -0
  1131. package/node_modules/zca-js/dist/index.js +14 -0
  1132. package/node_modules/zca-js/dist/models/Attachment.d.ts +9 -0
  1133. package/node_modules/zca-js/dist/models/Attachment.js +1 -0
  1134. package/node_modules/zca-js/dist/models/AutoReply.d.ts +20 -0
  1135. package/node_modules/zca-js/dist/models/AutoReply.js +7 -0
  1136. package/node_modules/zca-js/dist/models/Bank.d.ts +291 -0
  1137. package/node_modules/zca-js/dist/models/Bank.js +262 -0
  1138. package/node_modules/zca-js/dist/models/Board.d.ts +60 -0
  1139. package/node_modules/zca-js/dist/models/Board.js +6 -0
  1140. package/node_modules/zca-js/dist/models/Catalog.d.ts +16 -0
  1141. package/node_modules/zca-js/dist/models/Catalog.js +1 -0
  1142. package/node_modules/zca-js/dist/models/DeliveredMessage.d.ts +27 -0
  1143. package/node_modules/zca-js/dist/models/DeliveredMessage.js +17 -0
  1144. package/node_modules/zca-js/dist/models/Enum.d.ts +21 -0
  1145. package/node_modules/zca-js/dist/models/Enum.js +25 -0
  1146. package/node_modules/zca-js/dist/models/FriendEvent.d.ts +107 -0
  1147. package/node_modules/zca-js/dist/models/FriendEvent.js +83 -0
  1148. package/node_modules/zca-js/dist/models/Group.d.ts +125 -0
  1149. package/node_modules/zca-js/dist/models/Group.js +11 -0
  1150. package/node_modules/zca-js/dist/models/GroupEvent.d.ts +178 -0
  1151. package/node_modules/zca-js/dist/models/GroupEvent.js +90 -0
  1152. package/node_modules/zca-js/dist/models/Label.d.ts +10 -0
  1153. package/node_modules/zca-js/dist/models/Label.js +1 -0
  1154. package/node_modules/zca-js/dist/models/Message.d.ts +91 -0
  1155. package/node_modules/zca-js/dist/models/Message.js +29 -0
  1156. package/node_modules/zca-js/dist/models/ProductCatalog.d.ts +17 -0
  1157. package/node_modules/zca-js/dist/models/ProductCatalog.js +1 -0
  1158. package/node_modules/zca-js/dist/models/QuickMessage.d.ts +25 -0
  1159. package/node_modules/zca-js/dist/models/QuickMessage.js +1 -0
  1160. package/node_modules/zca-js/dist/models/Reaction.d.ts +85 -0
  1161. package/node_modules/zca-js/dist/models/Reaction.js +70 -0
  1162. package/node_modules/zca-js/dist/models/Reminder.d.ts +51 -0
  1163. package/node_modules/zca-js/dist/models/Reminder.js +7 -0
  1164. package/node_modules/zca-js/dist/models/SeenMessage.d.ts +26 -0
  1165. package/node_modules/zca-js/dist/models/SeenMessage.js +17 -0
  1166. package/node_modules/zca-js/dist/models/Sticker.d.ts +27 -0
  1167. package/node_modules/zca-js/dist/models/Sticker.js +1 -0
  1168. package/node_modules/zca-js/dist/models/Typing.d.ts +24 -0
  1169. package/node_modules/zca-js/dist/models/Typing.js +17 -0
  1170. package/node_modules/zca-js/dist/models/Undo.d.ts +34 -0
  1171. package/node_modules/zca-js/dist/models/Undo.js +12 -0
  1172. package/node_modules/zca-js/dist/models/User.d.ts +70 -0
  1173. package/node_modules/zca-js/dist/models/User.js +1 -0
  1174. package/node_modules/zca-js/dist/models/ZBusiness.d.ts +22 -0
  1175. package/node_modules/zca-js/dist/models/ZBusiness.js +35 -0
  1176. package/node_modules/zca-js/dist/models/index.d.ts +22 -0
  1177. package/node_modules/zca-js/dist/models/index.js +22 -0
  1178. package/node_modules/zca-js/dist/update.d.ts +2 -0
  1179. package/node_modules/zca-js/dist/update.js +29 -0
  1180. package/node_modules/zca-js/dist/utils.d.ts +167 -0
  1181. package/node_modules/zca-js/dist/utils.js +719 -0
  1182. package/node_modules/zca-js/dist/zalo.d.ts +41 -0
  1183. package/node_modules/zca-js/dist/zalo.js +107 -0
  1184. package/node_modules/zca-js/eslint.config.js +21 -0
  1185. package/node_modules/zca-js/index.d.ts +2 -0
  1186. package/node_modules/zca-js/package.json +78 -0
  1187. package/node_modules/zca-js/rollup.config.js +28 -0
  1188. package/package.json +80 -62
  1189. package/patches/zca-js+2.2.0.patch +1677 -0
  1190. package/src/cli.test.js +34 -5
  1191. package/src/commands/account.js +98 -5
  1192. package/src/commands/auto-reply.js +30 -10
  1193. package/src/commands/catalog.js +5 -4
  1194. package/src/commands/conv.js +551 -14
  1195. package/src/commands/friend.js +19 -7
  1196. package/src/commands/group.js +82 -31
  1197. package/src/commands/listen.js +624 -68
  1198. package/src/commands/login.js +179 -20
  1199. package/src/commands/mcp.js +422 -44
  1200. package/src/commands/msg.js +1288 -140
  1201. package/src/commands/oa-listen.js +130 -20
  1202. package/src/commands/oa.js +26 -5
  1203. package/src/commands/poll.js +7 -2
  1204. package/src/commands/profile.js +3 -2
  1205. package/src/commands/sync.js +2052 -0
  1206. package/src/core/accounts.js +69 -6
  1207. package/src/core/cached-message.js +200 -0
  1208. package/src/core/coverage.js +90 -0
  1209. package/src/core/current-user-names.js +104 -0
  1210. package/src/core/daemon-account.js +61 -0
  1211. package/src/core/daemon-channel.js +638 -0
  1212. package/src/core/daemon-sync.js +181 -0
  1213. package/src/core/db.js +1625 -0
  1214. package/src/core/forward.js +112 -0
  1215. package/src/core/group-history.js +248 -0
  1216. package/src/core/group-members.js +68 -0
  1217. package/src/core/group-settings.js +250 -0
  1218. package/src/core/history-fetch.js +208 -0
  1219. package/src/core/listener-lifecycle.js +90 -0
  1220. package/src/core/live-api.js +47 -0
  1221. package/src/core/live-store.js +733 -0
  1222. package/src/core/lock.js +129 -0
  1223. package/src/core/logout.js +289 -0
  1224. package/src/core/offline-queue.js +194 -0
  1225. package/src/core/pin.js +222 -0
  1226. package/src/core/read-state.js +318 -0
  1227. package/src/core/receipts.js +679 -0
  1228. package/src/core/recent-conversations.js +30 -0
  1229. package/src/core/self-heal.js +522 -0
  1230. package/src/core/socket-tap.js +154 -0
  1231. package/src/core/sync-v2/assets.js +181 -0
  1232. package/src/core/sync-v2/board.js +338 -0
  1233. package/src/core/sync-v2/conv-state.js +152 -0
  1234. package/src/core/sync-v2/gap-advice.js +110 -0
  1235. package/src/core/sync-v2/gid.js +106 -0
  1236. package/src/core/sync-v2/index.js +1259 -0
  1237. package/src/core/sync-v2/keepalive.js +177 -0
  1238. package/src/core/sync-v2/media.js +704 -0
  1239. package/src/core/sync-v2/message-types.js +522 -0
  1240. package/src/core/sync-v2/plan.js +95 -0
  1241. package/src/core/sync-v2/reactions.js +236 -0
  1242. package/src/core/sync-v2/renewlink.js +124 -0
  1243. package/src/core/sync-v2/senders.js +61 -0
  1244. package/src/core/sync-v2/zcloud-cipher.js +88 -0
  1245. package/src/core/sync-v2/zcloud.js +675 -0
  1246. package/src/core/sync.js +540 -0
  1247. package/src/core/zalo-client.js +179 -61
  1248. package/src/core/zca-custom.js +78 -0
  1249. package/src/index.js +15 -3
  1250. package/src/mcp/mcp-config.js +40 -3
  1251. package/src/mcp/mcp-http-transport.js +12 -2
  1252. package/src/mcp/mcp-server.js +5 -2
  1253. package/src/mcp/mcp-tools.js +969 -99
  1254. package/src/mcp/message-buffer.js +38 -8
  1255. package/src/mcp/message-buffer.test.js +67 -15
  1256. package/src/mcp/notifier.js +17 -1
  1257. package/src/mcp/notifier.test.js +6 -0
  1258. package/src/mcp/sync-jobs.js +82 -0
  1259. package/src/mcp/thread-name-cache.js +14 -1
  1260. package/src/mcp/thread-name-cache.test.js +4 -1
  1261. package/src/utils/bank-helpers.js +8 -3
  1262. package/src/utils/device-fingerprint.js +72 -0
  1263. package/src/utils/mentions.js +140 -0
  1264. package/src/utils/my-documents.js +95 -0
  1265. package/src/utils/open-file.js +49 -0
  1266. package/src/utils/output.js +75 -4
  1267. package/src/utils/parse-options.js +56 -0
  1268. package/src/utils/qr-http-server.js +44 -7
  1269. package/src/utils/quote.js +203 -0
  1270. package/src/utils/thread-type.js +72 -0
  1271. package/src/utils/update-check.js +42 -1
  1272. package/src/utils/urgency.js +29 -0
  1273. package/src/mcp/media-downloader.js +0 -191
  1274. package/src/mcp/media-downloader.test.js +0 -45
  1275. package/src/utils/qr-display.test.js +0 -97
package/src/core/db.js ADDED
@@ -0,0 +1,1625 @@
1
+ import { mkdirSync } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ import Database from "better-sqlite3";
4
+
5
+ let db;
6
+
7
+ export function initDb(dbPath) {
8
+ // A fresh login has no accounts/<ownId>/ yet: only a daemon taking its
9
+ // lock (lock.js) used to create it, so every command that opened the
10
+ // cache before a listener had ever run crashed (sync-cloud, live
11
+ // 2026-09-30: "Cannot open database because the directory does not exist").
12
+ mkdirSync(dirname(dbPath), { recursive: true });
13
+ db = new Database(dbPath);
14
+
15
+ // Enable WAL mode for better performance
16
+ db.pragma("journal_mode = WAL");
17
+
18
+ // Create tables
19
+ db.exec(`
20
+ CREATE TABLE IF NOT EXISTS messages (
21
+ msgId TEXT PRIMARY KEY,
22
+ threadId TEXT,
23
+ senderId TEXT,
24
+ senderName TEXT,
25
+ text TEXT,
26
+ timestamp INTEGER,
27
+ type TEXT,
28
+ raw_data TEXT,
29
+ localPath TEXT,
30
+ has_attachment INTEGER DEFAULT 0,
31
+ msgStatus INTEGER,
32
+ mediaPrunedAt INTEGER
33
+ );
34
+
35
+ CREATE TABLE IF NOT EXISTS threads (
36
+ threadId TEXT PRIMARY KEY,
37
+ type TEXT,
38
+ name TEXT,
39
+ lastUpdate INTEGER,
40
+ sync_timestamp INTEGER DEFAULT 0,
41
+ respondedByMe INTEGER,
42
+ lastGlobalId TEXT,
43
+ lastClientId TEXT,
44
+ leftAt INTEGER,
45
+ deleteMarkerAt INTEGER
46
+ );
47
+
48
+ CREATE TABLE IF NOT EXISTS contacts (
49
+ userId TEXT PRIMARY KEY,
50
+ name TEXT,
51
+ phone TEXT
52
+ );
53
+
54
+ -- Small key/value store for sync bookkeeping: lastConnectedAt,
55
+ -- lastDisconnectedAt, lastFullSyncAt, etc. One row per key, per-account
56
+ -- (this whole DB file is already per-account under accounts/<ownId>/zalo.db).
57
+ CREATE TABLE IF NOT EXISTS sync_state (
58
+ key TEXT PRIMARY KEY,
59
+ value TEXT
60
+ );
61
+
62
+ -- Tracks time windows where we know (or suspect) messages may have been
63
+ -- missed — mirrors Zalo Web's own client-side "MissingMessageRange" table
64
+ -- (confirmed live via its IndexedDB schema: id/convId/fromTs/toTs/reason/status)
65
+ -- but kept account-wide rather than per-conversation, since pullMobileMsg/
66
+ -- getCrossDB operate on the whole account, not a single thread.
67
+ CREATE TABLE IF NOT EXISTS sync_gaps (
68
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
69
+ fromTs INTEGER,
70
+ toTs INTEGER,
71
+ reason TEXT,
72
+ status TEXT DEFAULT 'pending',
73
+ createdAt INTEGER,
74
+ resolvedAt INTEGER
75
+ );
76
+
77
+ -- Board items: notes ("Ghi chú"), pinned messages and polls. These are NOT
78
+ -- in the transfer-sync message stream at all — Zalo keeps them behind
79
+ -- /api/board/list, one call per thread — so they are synced separately and
80
+ -- stored here. boardType mirrors zca-js BoardType: 1=Note, 2=PinnedMessage,
81
+ -- 3=Poll. The id column is scoped by thread because item ids repeat across
82
+ -- threads. (No backticks anywhere in this SQL: it sits inside a JS template
83
+ -- literal, so one would close it and break the whole module.)
84
+ CREATE TABLE IF NOT EXISTS board_items (
85
+ id TEXT PRIMARY KEY,
86
+ threadId TEXT,
87
+ threadType TEXT,
88
+ boardType INTEGER,
89
+ itemId TEXT,
90
+ title TEXT,
91
+ creatorId TEXT,
92
+ createTime INTEGER,
93
+ editTime INTEGER,
94
+ startTime INTEGER,
95
+ duration INTEGER,
96
+ repeat INTEGER,
97
+ emoji TEXT,
98
+ color INTEGER,
99
+ raw_data TEXT,
100
+ sync_timestamp INTEGER
101
+ );
102
+
103
+ -- Reminders ("Nhắc hẹn"). Also out-of-stream: /api/board/oneone/list for
104
+ -- DMs, /api/board/listReminder for groups. The conversation *events* that
105
+ -- announce them do arrive as messages (msgType 24), but the reminder
106
+ -- objects themselves only exist here.
107
+ CREATE TABLE IF NOT EXISTS reminders (
108
+ id TEXT PRIMARY KEY,
109
+ reminderId TEXT,
110
+ threadId TEXT,
111
+ threadType TEXT,
112
+ title TEXT,
113
+ creatorId TEXT,
114
+ createTime INTEGER,
115
+ editTime INTEGER,
116
+ startTime INTEGER,
117
+ duration INTEGER,
118
+ repeatMode INTEGER,
119
+ emoji TEXT,
120
+ color INTEGER,
121
+ eventType INTEGER,
122
+ raw_data TEXT,
123
+ sync_timestamp INTEGER
124
+ );
125
+
126
+ -- zCloud / "Cloud cua toi" media index. Populated from the cloud verify
127
+ -- queue (cmd 621 -> /cloudmedia/queue/pc/verify) and from the per-thread
128
+ -- media store, and keyed by Zalo's noiseId. Each row records where the
129
+ -- backup lives and the per-item encryptKey; the blob itself stays on
130
+ -- Zalo's side until something fetches and decrypts it.
131
+ CREATE TABLE IF NOT EXISTS cloud_items (
132
+ noiseId TEXT PRIMARY KEY,
133
+ threadId TEXT,
134
+ msgId TEXT,
135
+ msgType INTEGER,
136
+ mediaType INTEGER,
137
+ cloudUrl TEXT,
138
+ encryptKey TEXT,
139
+ checksum TEXT,
140
+ mediaSize INTEGER,
141
+ timestamp INTEGER,
142
+ localPath TEXT,
143
+ raw_data TEXT,
144
+ sync_timestamp INTEGER
145
+ );
146
+
147
+ -- Reactions. NOT in the mobile sync payload at all -- the Sync2 protobuf
148
+ -- has no reaction field. They are NOT unrecoverable, though: the socket
149
+ -- serves them on cmd 610 (1-1) and 611 (group), which is how Zalo Web shows
150
+ -- them after a fresh login, so they arrive either live (cmd 612) or from
151
+ -- the sync-reactions command. (No backticks in this SQL: it sits inside a
152
+ -- JS template literal, so one would close it and break the module.)
153
+ --
154
+ -- Keyed by (msgId, userId, ICON), because Zalo ACCUMULATES: one person can
155
+ -- hold several different reactions on the same message at once, and all of
156
+ -- them are displayed. Confirmed against the app -- three icons sent to one
157
+ -- message show as three. A (msgId, userId) key kept only the last one and
158
+ -- silently discarded the rest.
159
+ CREATE TABLE IF NOT EXISTS reactions (
160
+ id TEXT PRIMARY KEY,
161
+ msgId TEXT,
162
+ threadId TEXT,
163
+ userId TEXT,
164
+ icon TEXT,
165
+ rType INTEGER,
166
+ source TEXT,
167
+ timestamp INTEGER
168
+ );
169
+
170
+ -- Conversation-level state: pinned, unread-marked. Like reactions, none of
171
+ -- this travels in the sync payload; it comes from REST reads and live
172
+ -- events. Applies to 1-1 conversations as much as to groups.
173
+ CREATE TABLE IF NOT EXISTS conv_state (
174
+ threadId TEXT PRIMARY KEY,
175
+ pinned INTEGER,
176
+ pinnedAt INTEGER,
177
+ unreadMarked INTEGER,
178
+ unreadMarkedAt INTEGER,
179
+ updatedAt INTEGER
180
+ );
181
+
182
+ CREATE INDEX IF NOT EXISTS idx_reactions_msg ON reactions(msgId);
183
+ CREATE INDEX IF NOT EXISTS idx_reactions_msg_user ON reactions(msgId, userId);
184
+ CREATE INDEX IF NOT EXISTS idx_reactions_thread ON reactions(threadId);
185
+ CREATE INDEX IF NOT EXISTS idx_cloud_thread ON cloud_items(threadId);
186
+ CREATE INDEX IF NOT EXISTS idx_cloud_msg ON cloud_items(msgId);
187
+ CREATE INDEX IF NOT EXISTS idx_messages_thread_ts ON messages(threadId, timestamp DESC);
188
+ CREATE INDEX IF NOT EXISTS idx_messages_attach ON messages(has_attachment) WHERE has_attachment = 1;
189
+ CREATE INDEX IF NOT EXISTS idx_board_thread ON board_items(threadId, boardType);
190
+ CREATE INDEX IF NOT EXISTS idx_reminders_thread ON reminders(threadId);
191
+ `);
192
+
193
+ // Migration for existing DBs
194
+ try {
195
+ db.exec("ALTER TABLE messages ADD COLUMN localPath TEXT");
196
+ } catch {
197
+ // column probably already exists
198
+ }
199
+ try {
200
+ db.exec("ALTER TABLE messages ADD COLUMN has_attachment INTEGER DEFAULT 0");
201
+ } catch {}
202
+ try {
203
+ db.exec("ALTER TABLE threads ADD COLUMN sync_timestamp INTEGER DEFAULT 0");
204
+ } catch {}
205
+ // Conversation-round fields from the mobile sync. Nullable: the listener
206
+ // never learns them, so only a transfer sync fills them in.
207
+ try {
208
+ db.exec("ALTER TABLE threads ADD COLUMN respondedByMe INTEGER");
209
+ } catch {}
210
+ try {
211
+ db.exec("ALTER TABLE threads ADD COLUMN lastGlobalId TEXT");
212
+ } catch {}
213
+ try {
214
+ db.exec("ALTER TABLE threads ADD COLUMN lastClientId TEXT");
215
+ } catch {}
216
+ // Sync2.Message.MessageStatus: 0 unspecified, 1 fail, 2 sending, 3 sent,
217
+ // 4 received, 5 seen. The mobile sync carries this per message -- it is the
218
+ // only place delivery/read state arrives -- so it gets a real column rather
219
+ // than living unnamed inside raw_data.
220
+ try {
221
+ db.exec("ALTER TABLE messages ADD COLUMN msgStatus INTEGER");
222
+ } catch {}
223
+ // When media was deliberately pruned. Pruning clears localPath, which would
224
+ // otherwise put the row straight back in the download queue -- so the next
225
+ // sync would re-fetch exactly what was just deleted on purpose. This marks
226
+ // the decision so automatic fetches skip it.
227
+ try {
228
+ db.exec("ALTER TABLE messages ADD COLUMN mediaPrunedAt INTEGER");
229
+ } catch {}
230
+ // An older listener stored the raw live msgType as the row type, so
231
+ // removals landed as 'chat.undo'/'chat.delete' and media as
232
+ // 'chat.photo'/'share.file'/... Every query keyed on the shared vocabulary
233
+ // (starting with the removal ones) is short by exactly those rows, so
234
+ // normalize them once. Idempotent: matches only the legacy spellings.
235
+ try {
236
+ db.prepare(
237
+ `UPDATE messages SET type = CASE type
238
+ WHEN 'chat.undo' THEN 'deleted'
239
+ WHEN 'chat.delete' THEN 'deleted'
240
+ WHEN 'webchat' THEN 'text'
241
+ WHEN 'chat.photo' THEN 'photo'
242
+ WHEN 'chat.video.msg' THEN 'video'
243
+ WHEN 'share.file' THEN 'file'
244
+ WHEN 'chat.gif' THEN 'gif'
245
+ WHEN 'chat.sticker' THEN 'sticker'
246
+ WHEN 'chat.voice' THEN 'voice'
247
+ WHEN 'chat.doodle' THEN 'doodle'
248
+ WHEN 'chat.ecard' THEN 'card'
249
+ WHEN 'chat.recommended' THEN 'link'
250
+ WHEN 'chat.link' THEN 'link'
251
+ -- msgType 18 had no sync mapping, so the same shared location
252
+ -- was stored as 'location' by the listener and 'type_18' by a
253
+ -- mobile sync. The classifier now agrees; these are the rows
254
+ -- written before it did.
255
+ WHEN 'type_18' THEN 'location'
256
+ -- zinstant content (a bank card): msgType 24 from a sync, stored
257
+ -- under its raw live spelling until the live map learned it.
258
+ WHEN 'chat.webcontent' THEN 'event'
259
+ -- msgType 2 is a doodle: live says chat.doodle for the same message.
260
+ WHEN 'type_2' THEN 'doodle'
261
+ ELSE type END
262
+ WHERE type IN ('chat.undo','chat.delete','webchat','chat.photo','chat.video.msg','share.file',
263
+ 'chat.gif','chat.sticker','chat.voice','chat.doodle','chat.ecard',
264
+ 'chat.recommended','chat.link','type_18','chat.webcontent','type_2')`,
265
+ ).run();
266
+ } catch {
267
+ /* a fresh database has nothing to normalize */
268
+ }
269
+ // Voice notes a mobile sync stored before msgType 6 was mapped. The row
270
+ // type alone is not enough: the downloader keys on the kind stored INSIDE
271
+ // each attachment, and that also read type_6 -- so without rewriting it
272
+ // (and has_attachment) the audio would stay unfetchable forever.
273
+ try {
274
+ db.prepare(
275
+ "UPDATE messages SET type = 'voice', " +
276
+ "raw_data = json_set(raw_data, '$.attachments[0].kind', 'voice'), " +
277
+ "has_attachment = CASE WHEN json_extract(raw_data, '$.attachments[0].url') IS NOT NULL " +
278
+ "THEN 1 ELSE has_attachment END " +
279
+ "WHERE type = 'type_6' AND json_valid(raw_data)",
280
+ ).run();
281
+ } catch {
282
+ /* nothing to repair */
283
+ }
284
+ // Repair threads an earlier listener downgraded to "dm" (see the sticky
285
+ // type rule in upsertThread). The evidence is a group event the LISTENER
286
+ // saw (a `ge:` row, written only for cmd 601 group controls). It used to be
287
+ // any `group_event` row, but that type is also a pin notice
288
+ // (msginfo.actionlist), which a 1-1 carries too: measured live 2026-09-30,
289
+ // pinning a message in a DM flipped the DM to "group" here on every open,
290
+ // and every default-typed command on it then went out as a group command.
291
+ try {
292
+ db.prepare(
293
+ "UPDATE threads SET type = 'group' WHERE type = 'dm' AND threadId IN " +
294
+ "(SELECT threadId FROM messages WHERE type = 'group_event' AND msgId LIKE 'ge:%')",
295
+ ).run();
296
+ } catch {
297
+ /* no messages table yet, or nothing to repair */
298
+ }
299
+ // Heal a 1-1 that rule (or anything else) wrongly made a group. In a DM the
300
+ // conversation id IS the other person's uid, so a real message sent by the
301
+ // conversation id itself proves a 1-1; a group id never sends one. System
302
+ // lines are excluded: their sender is whoever acted.
303
+ try {
304
+ db.prepare(
305
+ "UPDATE threads SET type = 'dm' WHERE type = 'group' AND threadId IN " +
306
+ "(SELECT threadId FROM messages WHERE senderId = threadId AND msgId NOT LIKE 'ge:%' " +
307
+ "AND COALESCE(type, '') NOT IN ('group_event', 'event', 'poll_event', 'deleted'))",
308
+ ).run();
309
+ } catch {
310
+ /* no messages table yet, or nothing to heal */
311
+ }
312
+ // When the conversation stopped being ours: dispersed, deleted, or we were
313
+ // removed. Nothing else records this, so without it a vanished group keeps
314
+ // its messages and media forever with no code path that would revisit them.
315
+ try {
316
+ db.exec("ALTER TABLE threads ADD COLUMN leftAt INTEGER");
317
+ } catch {}
318
+ // The cutoff `msg history` honors, split out of leftAt. leftAt used to be
319
+ // both "this conversation is not ours" and "nothing at or before this
320
+ // comes back from history". The first is now cleared when the account is
321
+ // seen in the conversation again; the second must not be -- a DM you
322
+ // deleted keeps its old messages deleted after the contact writes again.
323
+ // Copied once, in the same transaction that adds the column: from then on
324
+ // leftAt is also set by a conversation list, which is not a deletion and
325
+ // must never become a cutoff.
326
+ if (!db.prepare("SELECT 1 FROM pragma_table_info('threads') WHERE name = 'deleteMarkerAt'").get()) {
327
+ db.transaction(() => {
328
+ db.exec("ALTER TABLE threads ADD COLUMN deleteMarkerAt INTEGER");
329
+ db.exec("UPDATE threads SET deleteMarkerAt = leftAt WHERE leftAt IS NOT NULL");
330
+ })();
331
+ }
332
+ // The read watermark: the newest message this account has read in the
333
+ // conversation, on any device, as the server reports it (./read-state.js).
334
+ // Nullable: nothing is known until the listener sees a report.
335
+ try {
336
+ db.exec("ALTER TABLE conv_state ADD COLUMN lastReadMsgId TEXT");
337
+ } catch {}
338
+ try {
339
+ db.exec("ALTER TABLE conv_state ADD COLUMN lastReadTs INTEGER");
340
+ } catch {}
341
+
342
+ return db;
343
+ }
344
+
345
+ /** Get a bookkeeping value (e.g. "lastConnectedAt"). Returns null if unset. */
346
+ export function getSyncState(key) {
347
+ if (!db) throw new Error("Database not initialized");
348
+ const row = db.prepare("SELECT value FROM sync_state WHERE key = ?").get(key);
349
+ return row ? row.value : null;
350
+ }
351
+
352
+ /** Set a bookkeeping value. Value is stringified on write, so callers get
353
+ * strings back from getSyncState() and should Number()/JSON.parse() as needed. */
354
+ export function setSyncState(key, value) {
355
+ if (!db) throw new Error("Database not initialized");
356
+ db.prepare(
357
+ `
358
+ INSERT INTO sync_state (key, value) VALUES (@key, @value)
359
+ ON CONFLICT(key) DO UPDATE SET value = excluded.value
360
+ `,
361
+ ).run({ key, value: String(value) });
362
+ }
363
+
364
+ /**
365
+ * Remove a bookkeeping value.
366
+ *
367
+ * Needed because some keys are per-thread flags rather than durable state:
368
+ * `boardStale:<threadId>` says "this conversation's board moved, refetch it",
369
+ * and a flag that is never cleared is indistinguishable from one that was
370
+ * never set. Without this, every thread that ever saw a pin stayed "stale"
371
+ * forever and the prioritization it exists for degraded to a no-op.
372
+ *
373
+ * @param {string} key
374
+ */
375
+ export function clearSyncState(key) {
376
+ if (!db) throw new Error("Database not initialized");
377
+ return db.prepare("DELETE FROM sync_state WHERE key = ?").run(key);
378
+ }
379
+
380
+ /** Record a window of time we may have missed messages in (reason: e.g.
381
+ * "startup-gap", "reconnect-gap", "manual"). Returns the new gap's id. */
382
+ export function recordSyncGap(fromTs, toTs, reason) {
383
+ if (!db) throw new Error("Database not initialized");
384
+ const stmt = db.prepare(`
385
+ INSERT INTO sync_gaps (fromTs, toTs, reason, status, createdAt)
386
+ VALUES (@fromTs, @toTs, @reason, 'pending', @createdAt)
387
+ `);
388
+ const info = stmt.run({ fromTs, toTs, reason, createdAt: Date.now() });
389
+ return info.lastInsertRowid;
390
+ }
391
+
392
+ /** All gaps not yet confirmed synced, oldest first. */
393
+ export function getPendingSyncGaps() {
394
+ if (!db) throw new Error("Database not initialized");
395
+ return db.prepare("SELECT * FROM sync_gaps WHERE status = 'pending' ORDER BY fromTs ASC").all();
396
+ }
397
+
398
+ /** Mark a gap resolved after a sync round-trip has actually covered it. */
399
+ export function resolveSyncGap(id) {
400
+ if (!db) throw new Error("Database not initialized");
401
+ db.prepare("UPDATE sync_gaps SET status = 'resolved', resolvedAt = ? WHERE id = ?").run(Date.now(), id);
402
+ }
403
+
404
+ /** Mark every currently-pending gap resolved (used after a full sync cycle
405
+ * completes successfully — we don't currently track gaps per-thread, so a
406
+ * successful round-trip is treated as covering everything outstanding). */
407
+ export function resolveAllPendingSyncGaps() {
408
+ if (!db) throw new Error("Database not initialized");
409
+ db.prepare("UPDATE sync_gaps SET status = 'resolved', resolvedAt = ? WHERE status = 'pending'").run(Date.now());
410
+ }
411
+
412
+ /**
413
+ * How many recorded coverage gaps are still pending, and how many have been
414
+ * resolved (by a restore that covered them, or by the self-heal). Read-only.
415
+ *
416
+ * @returns {{pending: number, resolved: number}}
417
+ */
418
+ export function countSyncGaps() {
419
+ if (!db) throw new Error("Database not initialized");
420
+ const row = db
421
+ .prepare(
422
+ "SELECT SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) AS pending, " +
423
+ "SUM(CASE WHEN status = 'resolved' THEN 1 ELSE 0 END) AS resolved FROM sync_gaps",
424
+ )
425
+ .get();
426
+ return { pending: Number(row?.pending) || 0, resolved: Number(row?.resolved) || 0 };
427
+ }
428
+
429
+ /**
430
+ * Run `fn` inside a single SQLite transaction.
431
+ *
432
+ * Bulk restores insert tens of thousands of rows; without this each statement
433
+ * is its own transaction and pays a WAL commit, which is both slow and -- worse
434
+ * for the mobile sync -- blocks the event loop long enough that the Zalo socket
435
+ * keepalive ping is missed and the connection is dropped mid-run.
436
+ *
437
+ * @param {() => T} fn
438
+ * @returns {T}
439
+ * @template T
440
+ */
441
+ export function runInTransaction(fn) {
442
+ if (!db) throw new Error("Database not initialized");
443
+ return db.transaction(fn)();
444
+ }
445
+
446
+ export function insertMessage(msg) {
447
+ if (!db) throw new Error("Database not initialized");
448
+
449
+ // A replay may resolve an opaque sender from an older sync. Never let an
450
+ // unresolved replay replace a canonical live UID, or a different numeric
451
+ // sender overwrite an already established identity.
452
+ const canResolveSender = `(
453
+ COALESCE(messages.senderId, '') = '' OR
454
+ (messages.senderId GLOB '*[^0-9]*' AND
455
+ excluded.senderId <> '' AND excluded.senderId <> '0' AND
456
+ excluded.senderId NOT GLOB '*[^0-9]*')
457
+ )`;
458
+ const stmt = db.prepare(`
459
+ INSERT INTO messages (msgId, threadId, senderId, senderName, text, timestamp, type, raw_data, localPath, has_attachment, msgStatus)
460
+ VALUES (@msgId, @threadId, @senderId, @senderName, @text, @timestamp, @type, @raw_data, @localPath, @has_attachment, @msgStatus)
461
+ ON CONFLICT(msgId) DO UPDATE SET
462
+ senderId = CASE WHEN ${canResolveSender} THEN excluded.senderId ELSE messages.senderId END,
463
+ senderName = CASE
464
+ WHEN COALESCE(messages.senderName, '') = '' AND
465
+ (messages.senderId = excluded.senderId OR ${canResolveSender})
466
+ THEN COALESCE(NULLIF(excluded.senderName, ''), messages.senderName)
467
+ ELSE messages.senderName END,
468
+ -- A removal is terminal. Once a row is a tombstone, a later write of the
469
+ -- same msgId -- a re-sync, a history replay, a backfill -- must not bring
470
+ -- the message back or replace the tombstone's record of HOW it was
471
+ -- removed (raw_data.removedAs: recall vs delete-for-me, originalType).
472
+ -- The phone keeps its own tombstone, so a sync arriving after a live
473
+ -- recall used to overwrite ours with a poorer one.
474
+ text = CASE WHEN messages.type = 'deleted' THEN messages.text ELSE excluded.text END,
475
+ timestamp = excluded.timestamp,
476
+ type = CASE WHEN messages.type = 'deleted' THEN messages.type ELSE excluded.type END,
477
+ raw_data = CASE WHEN messages.type = 'deleted' THEN messages.raw_data ELSE excluded.raw_data END,
478
+ localPath = COALESCE(excluded.localPath, messages.localPath),
479
+ has_attachment = CASE WHEN messages.type = 'deleted' THEN messages.has_attachment ELSE excluded.has_attachment END,
480
+ -- Never regress delivery state: a re-sync of an older snapshot must not
481
+ -- turn a seen message back into merely received. NULL is preserved as
482
+ -- NULL, because "we were never told" is not the same as status 0, and
483
+ -- with read receipts switched off it is the normal state.
484
+ msgStatus = CASE
485
+ WHEN excluded.msgStatus IS NULL AND messages.msgStatus IS NULL THEN NULL
486
+ ELSE MAX(COALESCE(excluded.msgStatus, 0), COALESCE(messages.msgStatus, 0)) END
487
+ `);
488
+
489
+ const raw_data =
490
+ typeof msg.raw_data === "object" && msg.raw_data !== null ? JSON.stringify(msg.raw_data) : msg.raw_data;
491
+
492
+ return stmt.run({
493
+ msgId: msg.msgId,
494
+ threadId: msg.threadId,
495
+ senderId: msg.senderId,
496
+ senderName: msg.senderName,
497
+ text: msg.text,
498
+ timestamp: msg.timestamp,
499
+ type: msg.type,
500
+ raw_data: raw_data,
501
+ localPath: msg.localPath || null,
502
+ has_attachment: msg.has_attachment ? 1 : 0,
503
+ msgStatus: Number.isFinite(Number(msg.msgStatus)) ? Number(msg.msgStatus) : null,
504
+ });
505
+ }
506
+
507
+ /**
508
+ * Insert a message only if its msgId is not stored yet -- never update one.
509
+ *
510
+ * msg history's write-back (storeHistoryMessage in ./live-store.js). Zalo Web
511
+ * writes the history it fetches the same way, ZStorage.setMessage with
512
+ * replace:false. A stored row keeps every column, which is the point: the
513
+ * listener and later events put things on it that a re-fetch cannot know --
514
+ * the media downloader's localPath, a receipt's msgStatus, a recall's
515
+ * tombstone, the st/at/cmd a seen receipt echoes back. {@link insertMessage},
516
+ * the listener's upsert, would replace most of them.
517
+ *
518
+ * Same columns and value mapping as insertMessage.
519
+ *
520
+ * @param {object} msg - the row, as for insertMessage
521
+ * @returns {{changes: number}} 1 when inserted, 0 when the msgId was already stored
522
+ */
523
+ export function insertMessageIfAbsent(msg) {
524
+ if (!db) throw new Error("Database not initialized");
525
+
526
+ const stmt = db.prepare(`
527
+ INSERT INTO messages (msgId, threadId, senderId, senderName, text, timestamp, type, raw_data, localPath, has_attachment, msgStatus)
528
+ VALUES (@msgId, @threadId, @senderId, @senderName, @text, @timestamp, @type, @raw_data, @localPath, @has_attachment, @msgStatus)
529
+ ON CONFLICT(msgId) DO NOTHING
530
+ `);
531
+
532
+ const raw_data =
533
+ typeof msg.raw_data === "object" && msg.raw_data !== null ? JSON.stringify(msg.raw_data) : msg.raw_data;
534
+
535
+ return stmt.run({
536
+ msgId: msg.msgId,
537
+ threadId: msg.threadId,
538
+ senderId: msg.senderId,
539
+ senderName: msg.senderName,
540
+ text: msg.text,
541
+ timestamp: msg.timestamp,
542
+ type: msg.type,
543
+ raw_data: raw_data,
544
+ localPath: msg.localPath || null,
545
+ has_attachment: msg.has_attachment ? 1 : 0,
546
+ msgStatus: Number.isFinite(Number(msg.msgStatus)) ? Number(msg.msgStatus) : null,
547
+ });
548
+ }
549
+
550
+ /**
551
+ * When a conversation stopped being ours, or null while it is ours.
552
+ *
553
+ * The gone marker. Set by `conv delete` and our own leave, removal or block
554
+ * event ({@link markThreadGone}) and by a full-history conversation list that
555
+ * no longer holds the thread ({@link recordConversationList}); cleared when
556
+ * the account is seen in the conversation again ({@link markThreadBack}).
557
+ * What `sync-media --prune-orphans` and `conv forget --orphans` act on, via
558
+ * {@link getOrphanThreads}.
559
+ *
560
+ * Not the history cutoff: that is {@link getThreadDeleteMarker}, which a
561
+ * return does not clear.
562
+ *
563
+ * @param {string} threadId
564
+ * @returns {number|null} epoch ms
565
+ */
566
+ export function getThreadLeftAt(threadId) {
567
+ if (!db) throw new Error("Database not initialized");
568
+ const row = db.prepare("SELECT leftAt FROM threads WHERE threadId = ?").get(String(threadId));
569
+ const at = Number(row?.leftAt);
570
+ return Number.isFinite(at) && at > 0 ? at : null;
571
+ }
572
+
573
+ /**
574
+ * The conversation's delete marker: nothing at or before this time may come
575
+ * back from fetched history. Null when there is none.
576
+ *
577
+ * The nearest thing this cache has to Zalo Web's per-conversation delete
578
+ * marker. Set with the gone marker by `conv delete` and by our own leave,
579
+ * removal or block ({@link markThreadGone}), and kept when the account comes
580
+ * back -- a deleted DM's old messages stay deleted after the contact writes
581
+ * again, while the conversation itself stops being an orphan.
582
+ *
583
+ * @param {string} threadId
584
+ * @returns {number|null} epoch ms
585
+ */
586
+ export function getThreadDeleteMarker(threadId) {
587
+ if (!db) throw new Error("Database not initialized");
588
+ const row = db.prepare("SELECT deleteMarkerAt FROM threads WHERE threadId = ?").get(String(threadId));
589
+ const at = Number(row?.deleteMarkerAt);
590
+ return Number.isFinite(at) && at > 0 ? at : null;
591
+ }
592
+
593
+ export function getMessages(threadId, limit = 50, fromTimestamp = null) {
594
+ if (!db) throw new Error("Database not initialized");
595
+
596
+ let query = "SELECT * FROM messages WHERE threadId = ?";
597
+ const params = [threadId];
598
+
599
+ if (fromTimestamp) {
600
+ query += " AND timestamp < ?";
601
+ params.push(fromTimestamp);
602
+ }
603
+
604
+ query += " ORDER BY timestamp DESC LIMIT ?";
605
+ params.push(limit);
606
+
607
+ return db.prepare(query).all(...params);
608
+ }
609
+
610
+ /**
611
+ * One message by its global id, or null.
612
+ *
613
+ * Callers that hold a msgId and nothing else (the MCP media tool, a delete
614
+ * that needs the row's cliMsgId) had to scan a thread's messages to find it.
615
+ *
616
+ * @param {string} msgId
617
+ * @returns {object|null}
618
+ */
619
+ export function getMessageById(msgId) {
620
+ if (!db) throw new Error("Database not initialized");
621
+ return db.prepare("SELECT * FROM messages WHERE msgId = ?").get(String(msgId)) || null;
622
+ }
623
+
624
+ /**
625
+ * Most recently active threads, newest first.
626
+ *
627
+ * `type` filters in SQL rather than after the fact. That distinction is the
628
+ * whole point: `getRecentThreads(5)` followed by a JS filter returns the
629
+ * groups *among the newest five threads of any kind* — frequently none —
630
+ * whereas asking for 5 groups should return the 5 newest groups.
631
+ *
632
+ * @param {number} [limit=20]
633
+ * @param {"dm"|"group"|null} [type=null] - null means both
634
+ */
635
+ export function getRecentThreads(limit = 20, type = null) {
636
+ if (!db) throw new Error("Database not initialized");
637
+ if (type) {
638
+ return db.prepare("SELECT * FROM threads WHERE type = ? ORDER BY lastUpdate DESC LIMIT ?").all(type, limit);
639
+ }
640
+ return db.prepare("SELECT * FROM threads ORDER BY lastUpdate DESC LIMIT ?").all(limit);
641
+ }
642
+
643
+ /**
644
+ * One conversation's kind, or null when the cache has never seen it.
645
+ *
646
+ * Callers use this to answer "is this a group?" without loading the thread, so
647
+ * they must be able to tell "not a group" from "don't know" -- hence null
648
+ * rather than a default of "dm".
649
+ *
650
+ * @param {string} threadId
651
+ * @returns {"dm"|"group"|null}
652
+ */
653
+ export function getThreadType(threadId) {
654
+ if (!db) throw new Error("Database not initialized");
655
+ const row = db.prepare("SELECT type FROM threads WHERE threadId = ?").get(String(threadId));
656
+ return row?.type || null;
657
+ }
658
+
659
+ export function upsertThread(thread) {
660
+ if (!db) throw new Error("Database not initialized");
661
+
662
+ const stmt = db.prepare(`
663
+ INSERT INTO threads (threadId, type, name, lastUpdate, sync_timestamp, respondedByMe, lastGlobalId, lastClientId)
664
+ VALUES (@threadId, @type, @name, @lastUpdate, @sync_timestamp, @respondedByMe, @lastGlobalId, @lastClientId)
665
+ ON CONFLICT(threadId) DO UPDATE SET
666
+ -- Group-ness is durable, so it is sticky. A live message is classified by
667
+ -- the socket command that carried it -- cmd 501 builds a UserMessage, cmd
668
+ -- 521 a GroupMessage -- and the server echoes the sender's own message
669
+ -- back on whichever channel matches the thread type the SEND declared.
670
+ -- Send to a group with the wrong type and the echo returns on the DM
671
+ -- channel, and a blind assignment here rewrote a synced group to "dm".
672
+ -- Measured: two threads holding group_event rows were stored as "dm".
673
+ -- A group id is never later a user id, so promoting dm -> group is a
674
+ -- correction worth taking and the reverse is wrong for a LIVE write.
675
+ -- An authoritative write is the exception: the phone sync reads the type
676
+ -- from its own partition (oneone/ vs group/), which no wrong-type send
677
+ -- can skew, so it may undo a "group" that weak evidence put on a 1-1.
678
+ type = CASE
679
+ WHEN @authoritative = 1 AND excluded.type IN ('dm', 'group') THEN excluded.type
680
+ WHEN threads.type = 'group' THEN 'group'
681
+ WHEN excluded.type IS NULL OR excluded.type = '' THEN threads.type
682
+ ELSE excluded.type END,
683
+ -- Never overwrite a known name with a blank one: the sync upserts threads
684
+ -- per message and only some of those carry a display name.
685
+ --
686
+ -- A nameHint write is weaker still: it fills a name in but never replaces
687
+ -- one. A live message carries the SENDER's display name (dName), which is
688
+ -- not the conversation's name -- a group has exactly one name, and a 1-1
689
+ -- is titled by the contact's alias when we set one. Letting a per-message
690
+ -- field win renamed a synced group after its next message and replaced a
691
+ -- deliberate alias with whatever the contact currently calls themselves.
692
+ name = CASE
693
+ WHEN excluded.name IS NULL OR excluded.name = '' THEN threads.name
694
+ WHEN @nameHint = 1 AND threads.name IS NOT NULL AND threads.name != '' THEN threads.name
695
+ ELSE excluded.name END,
696
+ -- MAX, not assignment. A sync calls this once per message, and messages
697
+ -- do not arrive newest-first, so a plain assignment left every thread
698
+ -- stamped with whichever message happened to be processed last -- which
699
+ -- is what made conv recent order wrongly after a sync. (No backticks:
700
+ -- this sits inside a JS template literal.)
701
+ lastUpdate = MAX(COALESCE(excluded.lastUpdate, 0), COALESCE(threads.lastUpdate, 0)),
702
+ sync_timestamp = COALESCE(excluded.sync_timestamp, threads.sync_timestamp),
703
+ respondedByMe = COALESCE(excluded.respondedByMe, threads.respondedByMe),
704
+ lastGlobalId = COALESCE(excluded.lastGlobalId, threads.lastGlobalId),
705
+ lastClientId = COALESCE(excluded.lastClientId, threads.lastClientId)
706
+ `);
707
+
708
+ return stmt.run({
709
+ threadId: thread.threadId,
710
+ type: thread.type,
711
+ name: thread.name,
712
+ lastUpdate: thread.lastUpdate,
713
+ sync_timestamp: thread.sync_timestamp || null,
714
+ // Only a mobile sync knows these; a listener write leaves them alone.
715
+ respondedByMe: thread.respondedByMe === undefined ? null : thread.respondedByMe ? 1 : 0,
716
+ lastGlobalId: thread.lastGlobalId === undefined ? null : String(thread.lastGlobalId),
717
+ lastClientId: thread.lastClientId === undefined ? null : String(thread.lastClientId),
718
+ nameHint: thread.nameHint ? 1 : 0,
719
+ // Only the phone sync passes this (see the type rule above).
720
+ authoritative: thread.authoritative ? 1 : 0,
721
+ });
722
+ }
723
+
724
+ /**
725
+ * threadId -> {name, type} for every cached conversation.
726
+ *
727
+ * One map, one definition of a conversation's folder and label, shared by the
728
+ * sync, the listener and `msg history`. They each used to derive it
729
+ * differently -- the sync from this table, the listener from the arriving
730
+ * message's `dName`, `msg history` not at all -- so one conversation's media
731
+ * could land in three different folders depending on which command fetched it.
732
+ *
733
+ * @param {number} [limit=5000]
734
+ * @returns {Map<string, {name: string, type: string}>}
735
+ */
736
+ export function getThreadNames(limit = 5000) {
737
+ const map = new Map();
738
+ try {
739
+ for (const t of getRecentThreads(limit)) {
740
+ map.set(String(t.threadId), { name: t.name || String(t.threadId), type: t.type });
741
+ }
742
+ } catch {
743
+ /* an empty or unopened cache just means folders fall back to thread ids */
744
+ }
745
+ return map;
746
+ }
747
+
748
+ /**
749
+ * Messages carrying at least one downloadable attachment, newest first.
750
+ *
751
+ * Reads the `has_attachment` flag rather than scanning `raw_data`, which is
752
+ * why the sync path must set it — a JSON scan over a six-figure message table
753
+ * is not something a CLI command can afford to do per run.
754
+ *
755
+ * @param {object} [opts]
756
+ * @param {string} [opts.threadId] - restrict to one thread
757
+ * @param {number} [opts.since] - only messages at/after this epoch ms
758
+ * @param {number} [opts.until] - only messages at/before this epoch ms
759
+ * @param {boolean} [opts.onlyMissing=true] - skip rows already downloaded
760
+ * @param {boolean} [opts.includePruned=false] - also consider media deliberately pruned
761
+ * @param {number} [opts.limit=500]
762
+ */
763
+ export function getAttachmentMessages(opts = {}) {
764
+ if (!db) throw new Error("Database not initialized");
765
+ const { threadId, since, until, onlyMissing = true, includePruned = false, limit = 500 } = opts;
766
+ const where = ["has_attachment = 1"];
767
+ const params = [];
768
+ if (onlyMissing) where.push("localPath IS NULL");
769
+ // A deliberate prune is a decision, not a gap to be refilled. Automatic
770
+ // fetches respect it; an explicit re-fetch can opt back in.
771
+ if (!includePruned) where.push("mediaPrunedAt IS NULL");
772
+ if (threadId) (where.push("threadId = ?"), params.push(String(threadId)));
773
+ if (Number.isFinite(since)) (where.push("timestamp >= ?"), params.push(since));
774
+ if (Number.isFinite(until)) (where.push("timestamp <= ?"), params.push(until));
775
+ params.push(limit);
776
+ return db
777
+ .prepare(`SELECT * FROM messages WHERE ${where.join(" AND ")} ORDER BY timestamp DESC LIMIT ?`)
778
+ .all(...params);
779
+ }
780
+
781
+ /**
782
+ * Links shared in conversations, newest first — the local equivalent of the
783
+ * "Link" tab in Zalo's media store, which is a third media kind alongside
784
+ * images and files rather than something separate.
785
+ *
786
+ * Kept as a query over `raw_data` rather than its own table: a link has no
787
+ * bytes to download and no lifecycle of its own, so the message row is already
788
+ * the record. One row per link, so a message carrying several yields several.
789
+ *
790
+ * @param {object} [opts]
791
+ * @param {string} [opts.threadId]
792
+ * @param {number} [opts.limit=200]
793
+ * @returns {Array<{msgId: string, threadId: string, timestamp: number, url: string, title: string|null, description: string|null, thumbUrl: string|null}>}
794
+ */
795
+ export function getLinkMessages(opts = {}) {
796
+ if (!db) throw new Error("Database not initialized");
797
+ const { threadId, limit = 200 } = opts;
798
+ const where = ["json_extract(a.value, '$.kind') = 'link'", "json_extract(a.value, '$.url') IS NOT NULL"];
799
+ const params = [];
800
+ if (threadId) {
801
+ where.push("m.threadId = ?");
802
+ params.push(String(threadId));
803
+ }
804
+ params.push(limit);
805
+ return db
806
+ .prepare(
807
+ `SELECT m.msgId, m.threadId, m.senderId, m.timestamp,
808
+ json_extract(a.value, '$.url') AS url,
809
+ json_extract(a.value, '$.title') AS title,
810
+ json_extract(a.value, '$.description') AS description,
811
+ json_extract(a.value, '$.thumbUrl') AS thumbUrl
812
+ FROM messages m, json_each(CASE WHEN json_valid(m.raw_data) THEN json_extract(m.raw_data, '$.attachments') END) a
813
+ WHERE ${where.join(" AND ")}
814
+ ORDER BY m.timestamp DESC LIMIT ?`,
815
+ )
816
+ .all(...params);
817
+ }
818
+
819
+ /**
820
+ * Downloaded attachments older than `before`, for pruning.
821
+ *
822
+ * Returns the rows rather than deleting anything: the caller has to see what it
823
+ * is about to remove from disk, and a dry run has to be possible.
824
+ *
825
+ * @param {number} before - epoch ms; rows with an older timestamp are returned
826
+ * @param {string} [threadId] - restrict to one thread
827
+ * @returns {Array<{msgId: string, threadId: string, timestamp: number, localPath: string}>}
828
+ */
829
+ export function getDownloadedMediaBefore(before, threadId = null) {
830
+ if (!db) throw new Error("Database not initialized");
831
+ // `before === null` means every downloaded file regardless of age. It is a
832
+ // separate mode rather than a very large cutoff so that an accidental
833
+ // arithmetic slip on a date can never become "delete everything".
834
+ const wherePieces = ["localPath IS NOT NULL"];
835
+ const params = [];
836
+ if (before !== null) {
837
+ wherePieces.push("timestamp < ?");
838
+ params.push(before);
839
+ }
840
+ if (threadId) {
841
+ wherePieces.push("threadId = ?");
842
+ params.push(String(threadId));
843
+ }
844
+ return db
845
+ .prepare(
846
+ `SELECT msgId, threadId, timestamp, localPath FROM messages WHERE ${wherePieces.join(" AND ")} ORDER BY timestamp ASC`,
847
+ )
848
+ .all(...params);
849
+ }
850
+
851
+ /**
852
+ * Conversations the account no longer has that are still cached here: a
853
+ * dispersed group, a deleted chat, a group you left or were removed from.
854
+ *
855
+ * One definition, read alike by `sync`'s orphan warning, `sync-media
856
+ * --prune-orphans` and `conv forget --orphans`: a thread is an orphan when its
857
+ * gone marker (threads.leftAt) is set and nothing in it is newer. Every signal
858
+ * that a conversation is gone records that marker -- our own leave, removal or
859
+ * block event, `conv delete`, and a full-history conversation list that no
860
+ * longer holds it -- so every reader sees the same set however long after the
861
+ * signal it runs. `sync` used to take its warning from the list it had just
862
+ * restored, which nothing recorded, and then recommend a prune that could not
863
+ * see that list.
864
+ *
865
+ * A message newer than the marker means the account is back, whichever writer
866
+ * stored it. The listener clears the marker itself; a restore or a history
867
+ * fetch does not, and this is what keeps them from leaving a conversation you
868
+ * are in marked gone. System lines do not count: the phone's row for our own
869
+ * leave is dated after the leave itself.
870
+ *
871
+ * @param {string[]|null} [liveThreadIds] - PREVIEW ONLY: also count every
872
+ * thread missing from this list, recording nothing. No command passes one --
873
+ * an unrecorded list is exactly how the warning and the prune came to
874
+ * disagree. Recording a list is {@link recordConversationList}.
875
+ * @returns {Array<{threadId: string, name: string, type: string, leftAt: number|null, messages: number, files: number, lastSeenAt: number|null}>}
876
+ */
877
+ export function getOrphanThreads(liveThreadIds = null) {
878
+ if (!db) throw new Error("Database not initialized");
879
+ const rows = db
880
+ .prepare(
881
+ `SELECT t.threadId, t.name, t.type, t.leftAt,
882
+ COUNT(m.msgId) AS messages,
883
+ SUM(CASE WHEN m.localPath IS NOT NULL THEN 1 ELSE 0 END) AS files,
884
+ MAX(CASE WHEN m.type = 'group_event' THEN NULL ELSE m.timestamp END) AS lastSeenAt
885
+ FROM threads t LEFT JOIN messages m ON m.threadId = t.threadId
886
+ GROUP BY t.threadId, t.name, t.type, t.leftAt`,
887
+ )
888
+ .all();
889
+ const gone = (r) => Boolean(r.leftAt) && !(Number(r.lastSeenAt) > Number(r.leftAt));
890
+ if (!Array.isArray(liveThreadIds)) return rows.filter(gone);
891
+ const live = new Set(liveThreadIds.map(String));
892
+ return rows.filter((r) => gone(r) || !live.has(String(r.threadId)));
893
+ }
894
+
895
+ /**
896
+ * Record what a conversation list says about which cached threads are ours.
897
+ *
898
+ * A restore's conversation round is the phone's list of the conversations the
899
+ * account has. Recording it, rather than holding it for one report, is what
900
+ * lets `sync-media --prune-orphans` and `conv forget --orphans` -- run any time
901
+ * later -- act on the same conversations `sync` said were gone.
902
+ *
903
+ * One transaction, two writes:
904
+ *
905
+ * - a listed thread whose gone marker predates the list is back: a group
906
+ * rejoined since we left it, a deleted DM the contact wrote to again. Any
907
+ * list counts, windowed or partial -- a thread IN it is present, however
908
+ * little else the list covers.
909
+ * - where the caller vouches the list is complete for a kind of thread, a
910
+ * cached thread of that kind missing from it is gone -- unless it was active
911
+ * at or after `markBefore`, because a list cannot hold a conversation that
912
+ * started while it was being taken.
913
+ *
914
+ * The delete marker is never touched. A list is evidence of absence, not a
915
+ * deletion, and must not stop `msg history` from filling a thread in.
916
+ *
917
+ * @param {object} list
918
+ * @param {string[]} list.present - every thread id the list accounted for
919
+ * @param {number} list.clearBefore - a present thread's marker is cleared only if older than this
920
+ * @param {number} list.markBefore - only threads quiet since before this are marked, and at this time
921
+ * @param {string[]} [list.markKinds=[]] - thread types ("dm", "group") the list is complete for
922
+ * @param {string[]} [list.keep=[]] - ids a list never marks: the account's own threads
923
+ * @returns {{cleared: string[], marked: string[], unproven: number}} `unproven` counts the cached
924
+ * conversations with messages that are missing from the list and were left unmarked, because
925
+ * the list is not complete for their kind
926
+ */
927
+ export function recordConversationList({ present, clearBefore, markBefore, markKinds = [], keep = [] }) {
928
+ if (!db) throw new Error("Database not initialized");
929
+ const params = {
930
+ present: JSON.stringify((present || []).map(String)),
931
+ kinds: JSON.stringify(markKinds.map(String)),
932
+ keep: JSON.stringify(keep.filter(Boolean).map(String)),
933
+ clearBefore: Number(clearBefore),
934
+ markBefore: Number(markBefore),
935
+ };
936
+ // Not an orphan right now, by the rule getOrphanThreads reads with.
937
+ const notGone =
938
+ "(threads.leftAt IS NULL OR EXISTS (SELECT 1 FROM messages m WHERE m.threadId = threads.threadId " +
939
+ "AND m.timestamp > threads.leftAt AND COALESCE(m.type, '') <> 'group_event'))";
940
+ const missingAndQuiet =
941
+ "threads.threadId NOT IN (SELECT value FROM json_each(@present)) " +
942
+ "AND threads.threadId NOT IN (SELECT value FROM json_each(@keep)) " +
943
+ `AND COALESCE(threads.lastUpdate, 0) < @markBefore AND ${notGone}`;
944
+ return db.transaction(() => {
945
+ const cleared = db
946
+ .prepare(
947
+ "UPDATE threads SET leftAt = NULL WHERE leftAt IS NOT NULL AND leftAt < @clearBefore " +
948
+ "AND threadId IN (SELECT value FROM json_each(@present)) RETURNING threadId",
949
+ )
950
+ .all(params)
951
+ .map((r) => r.threadId);
952
+ const marked = db
953
+ .prepare(
954
+ `UPDATE threads SET leftAt = @markBefore WHERE ${missingAndQuiet} ` +
955
+ "AND threads.type IN (SELECT value FROM json_each(@kinds)) RETURNING threadId",
956
+ )
957
+ .all(params)
958
+ .map((r) => r.threadId);
959
+ const { unproven } = db
960
+ .prepare(
961
+ `SELECT COUNT(*) AS unproven FROM threads WHERE ${missingAndQuiet} ` +
962
+ "AND (threads.type IS NULL OR threads.type NOT IN (SELECT value FROM json_each(@kinds))) " +
963
+ "AND EXISTS (SELECT 1 FROM messages m WHERE m.threadId = threads.threadId)",
964
+ )
965
+ .get(params);
966
+ return { cleared, marked, unproven };
967
+ })();
968
+ }
969
+
970
+ /**
971
+ * Id prefix of a group-event row the LISTENER wrote.
972
+ *
973
+ * A group system line (a rename, a member joining, a pin) reaches the socket
974
+ * only as a cmd 601 control, and that control carries no message id: its
975
+ * actionId/controlId are queue sequence numbers. The row a mobile sync
976
+ * restores for the same event is keyed by the PHONE's own clientId -- a local
977
+ * timestamp taken when the phone processed the event, 0.3-5.7 s after it
978
+ * happened (measured). No shared key exists, so the listener writes under this
979
+ * prefix and a sync replaces it.
980
+ */
981
+ export const LIVE_GROUP_EVENT_PREFIX = "ge:";
982
+
983
+ /**
984
+ * Delete the listener's placeholder for a group event a sync just restored.
985
+ *
986
+ * Matches on thread and time only, because nothing else is shared: the synced
987
+ * row's timestamp landed 1 and 4 ms from the live event's time on the two
988
+ * events measured. Only the single closest placeholder is removed, so two
989
+ * events a few seconds apart each keep their own row.
990
+ *
991
+ * @param {string} threadId
992
+ * @param {number} timestamp - the synced row's timestamp
993
+ * @param {number} [windowMs=2000]
994
+ * @returns {number} rows deleted (0 or 1)
995
+ */
996
+ export function replaceLiveGroupEventPlaceholder(threadId, timestamp, windowMs = 2000) {
997
+ if (!db) throw new Error("Database not initialized");
998
+ return db
999
+ .prepare(
1000
+ "DELETE FROM messages WHERE msgId = (SELECT msgId FROM messages WHERE threadId = @threadId " +
1001
+ "AND type = 'group_event' AND msgId LIKE @prefix AND abs(timestamp - @ts) <= @win " +
1002
+ "ORDER BY abs(timestamp - @ts) LIMIT 1)",
1003
+ )
1004
+ .run({
1005
+ threadId: String(threadId),
1006
+ ts: Number(timestamp),
1007
+ win: windowMs,
1008
+ prefix: `${LIVE_GROUP_EVENT_PREFIX}%`,
1009
+ }).changes;
1010
+ }
1011
+
1012
+ /**
1013
+ * Whether a sync has already stored the system line for an event at this time.
1014
+ *
1015
+ * @param {string} threadId
1016
+ * @param {number} timestamp
1017
+ * @param {number} [windowMs=2000]
1018
+ * @returns {boolean}
1019
+ */
1020
+ export function hasSyncedGroupEventNear(threadId, timestamp, windowMs = 2000) {
1021
+ if (!db) throw new Error("Database not initialized");
1022
+ return Boolean(
1023
+ db
1024
+ .prepare(
1025
+ "SELECT 1 FROM messages WHERE threadId = ? AND type = 'group_event' AND msgId NOT LIKE ? " +
1026
+ "AND abs(timestamp - ?) <= ? LIMIT 1",
1027
+ )
1028
+ .get(String(threadId), `${LIVE_GROUP_EVENT_PREFIX}%`, Number(timestamp), windowMs),
1029
+ );
1030
+ }
1031
+
1032
+ /**
1033
+ * Record that a conversation is no longer ours: deleted, or we left, were
1034
+ * removed or were blocked.
1035
+ *
1036
+ * Sets the gone marker and the delete marker together, because both callers
1037
+ * -- `conv delete` and our own leave/removal/block event -- are a deletion as
1038
+ * far as fetched history goes. A conversation list is not, and records the
1039
+ * gone marker alone ({@link recordConversationList}).
1040
+ *
1041
+ * @param {string} threadId
1042
+ * @param {number} [at=Date.now()] - epoch ms; the event's own time when it has one
1043
+ */
1044
+ export function markThreadGone(threadId, at = Date.now()) {
1045
+ if (!db) throw new Error("Database not initialized");
1046
+ return db
1047
+ .prepare(
1048
+ "UPDATE threads SET leftAt = @at, deleteMarkerAt = MAX(COALESCE(deleteMarkerAt, 0), @at) " +
1049
+ "WHERE threadId = @threadId",
1050
+ )
1051
+ .run({ at: Number(at), threadId: String(threadId) });
1052
+ }
1053
+
1054
+ /**
1055
+ * Record that the account was seen in a conversation: clear its gone marker,
1056
+ * if that marker predates the sighting.
1057
+ *
1058
+ * Zalo delivers a conversation's traffic only to the people in it, so a
1059
+ * message or group event dated after we left means we are back. One dated
1060
+ * before it proves nothing -- a backlog replay, or a late delivery of
1061
+ * something said before we left, must not undo the departure. The delete
1062
+ * marker stays either way ({@link getThreadDeleteMarker}).
1063
+ *
1064
+ * @param {string} threadId
1065
+ * @param {number} seenAt - epoch ms of the sighting
1066
+ * @returns {{changes: number}} 1 when a marker was cleared
1067
+ */
1068
+ export function markThreadBack(threadId, seenAt) {
1069
+ if (!db) throw new Error("Database not initialized");
1070
+ const at = Number(seenAt);
1071
+ if (!Number.isFinite(at)) return { changes: 0 };
1072
+ return db
1073
+ .prepare("UPDATE threads SET leftAt = NULL WHERE threadId = ? AND leftAt IS NOT NULL AND leftAt < ?")
1074
+ .run(String(threadId), at);
1075
+ }
1076
+
1077
+ /**
1078
+ * Delete every local trace of one conversation.
1079
+ *
1080
+ * Deliberately explicit and never automatic. Files on disk are the caller's
1081
+ * job (see pruneDownloadedMedia); this clears the rows, and reports what it
1082
+ * removed so the caller can say so rather than claim a silent success.
1083
+ *
1084
+ * @returns {{messages:number, threads:number, boardItems:number, reminders:number, reactions:number, cloudItems:number, convState:number}}
1085
+ */
1086
+ export function forgetThread(threadId) {
1087
+ if (!db) throw new Error("Database not initialized");
1088
+ const id = String(threadId);
1089
+ const counts = {};
1090
+ const run = (key, sql) => {
1091
+ counts[key] = db.prepare(sql).run(id).changes;
1092
+ };
1093
+ db.transaction(() => {
1094
+ run("messages", "DELETE FROM messages WHERE threadId = ?");
1095
+ run("reactions", "DELETE FROM reactions WHERE threadId = ?");
1096
+ run("boardItems", "DELETE FROM board_items WHERE threadId = ?");
1097
+ run("reminders", "DELETE FROM reminders WHERE threadId = ?");
1098
+ run("cloudItems", "DELETE FROM cloud_items WHERE threadId = ?");
1099
+ run("convState", "DELETE FROM conv_state WHERE threadId = ?");
1100
+ run("threads", "DELETE FROM threads WHERE threadId = ?");
1101
+ })();
1102
+ return counts;
1103
+ }
1104
+
1105
+ /**
1106
+ * Forget where an attachment was stored, after its file has been removed.
1107
+ *
1108
+ * Clearing `localPath` is what puts the row back in the download queue, so a
1109
+ * pruned message can be fetched again later if its link is still alive.
1110
+ */
1111
+ export function clearMessageLocalPath(msgId, prunedAt = null) {
1112
+ if (!db) throw new Error("Database not initialized");
1113
+ return db
1114
+ .prepare("UPDATE messages SET localPath = NULL, mediaPrunedAt = ? WHERE msgId = ?")
1115
+ .run(prunedAt === null ? null : Number(prunedAt), String(msgId));
1116
+ }
1117
+
1118
+ /**
1119
+ * Record where an attachment was written to disk.
1120
+ *
1121
+ * Clears any prune marker: the file is back, so the earlier decision to remove
1122
+ * it no longer applies.
1123
+ */
1124
+ export function setMessageLocalPath(msgId, localPath) {
1125
+ if (!db) throw new Error("Database not initialized");
1126
+ return db
1127
+ .prepare("UPDATE messages SET localPath = ?, mediaPrunedAt = NULL WHERE msgId = ?")
1128
+ .run(localPath, String(msgId));
1129
+ }
1130
+
1131
+ /** How many attachment-bearing messages are still undownloaded. */
1132
+ export function countPendingAttachments(threadId = null) {
1133
+ if (!db) throw new Error("Database not initialized");
1134
+ const sql =
1135
+ "SELECT count(*) AS n FROM messages WHERE has_attachment = 1 AND localPath IS NULL AND mediaPrunedAt IS NULL" +
1136
+ (threadId ? " AND threadId = ?" : "");
1137
+ return (threadId ? db.prepare(sql).get(String(threadId)) : db.prepare(sql).get()).n;
1138
+ }
1139
+
1140
+ export function upsertBoardItem(item) {
1141
+ if (!db) throw new Error("Database not initialized");
1142
+ return db
1143
+ .prepare(
1144
+ `INSERT INTO board_items
1145
+ (id, threadId, threadType, boardType, itemId, title, creatorId, createTime, editTime,
1146
+ startTime, duration, repeat, emoji, color, raw_data, sync_timestamp)
1147
+ VALUES (@id, @threadId, @threadType, @boardType, @itemId, @title, @creatorId, @createTime, @editTime,
1148
+ @startTime, @duration, @repeat, @emoji, @color, @raw_data, @sync_timestamp)
1149
+ ON CONFLICT(id) DO UPDATE SET
1150
+ title = excluded.title, editTime = excluded.editTime, startTime = excluded.startTime,
1151
+ duration = excluded.duration, repeat = excluded.repeat, emoji = excluded.emoji,
1152
+ color = excluded.color, raw_data = excluded.raw_data, sync_timestamp = excluded.sync_timestamp`,
1153
+ )
1154
+ .run({
1155
+ id: `${item.threadId}:${item.boardType}:${item.itemId}`,
1156
+ threadId: String(item.threadId),
1157
+ threadType: item.threadType || null,
1158
+ boardType: Number(item.boardType) || 0,
1159
+ itemId: String(item.itemId),
1160
+ title: item.title ?? null,
1161
+ creatorId: item.creatorId ?? null,
1162
+ createTime: Number(item.createTime) || null,
1163
+ editTime: Number(item.editTime) || null,
1164
+ startTime: Number(item.startTime) || null,
1165
+ duration: Number(item.duration) || null,
1166
+ repeat: Number(item.repeat) || null,
1167
+ emoji: item.emoji ?? null,
1168
+ color: Number(item.color) || null,
1169
+ raw_data: typeof item.raw_data === "object" ? JSON.stringify(item.raw_data) : (item.raw_data ?? null),
1170
+ sync_timestamp: item.sync_timestamp || Date.now(),
1171
+ });
1172
+ }
1173
+
1174
+ /** Board items for a thread (or all threads), optionally one boardType. */
1175
+ export function getBoardItems(threadId = null, boardType = null) {
1176
+ if (!db) throw new Error("Database not initialized");
1177
+ const where = [];
1178
+ const params = [];
1179
+ if (threadId) (where.push("threadId = ?"), params.push(String(threadId)));
1180
+ if (boardType) (where.push("boardType = ?"), params.push(Number(boardType)));
1181
+ const sql = `SELECT * FROM board_items${where.length ? ` WHERE ${where.join(" AND ")}` : ""} ORDER BY createTime DESC`;
1182
+ return db.prepare(sql).all(...params);
1183
+ }
1184
+
1185
+ export function upsertReminder(r) {
1186
+ if (!db) throw new Error("Database not initialized");
1187
+ return db
1188
+ .prepare(
1189
+ `INSERT INTO reminders
1190
+ (id, reminderId, threadId, threadType, title, creatorId, createTime, editTime,
1191
+ startTime, duration, repeatMode, emoji, color, eventType, raw_data, sync_timestamp)
1192
+ VALUES (@id, @reminderId, @threadId, @threadType, @title, @creatorId, @createTime, @editTime,
1193
+ @startTime, @duration, @repeatMode, @emoji, @color, @eventType, @raw_data, @sync_timestamp)
1194
+ ON CONFLICT(id) DO UPDATE SET
1195
+ title = excluded.title, editTime = excluded.editTime, startTime = excluded.startTime,
1196
+ duration = excluded.duration, repeatMode = excluded.repeatMode, emoji = excluded.emoji,
1197
+ color = excluded.color, eventType = excluded.eventType, raw_data = excluded.raw_data,
1198
+ sync_timestamp = excluded.sync_timestamp`,
1199
+ )
1200
+ .run({
1201
+ id: `${r.threadId}:${r.reminderId}`,
1202
+ reminderId: String(r.reminderId),
1203
+ threadId: String(r.threadId),
1204
+ threadType: r.threadType || null,
1205
+ title: r.title ?? null,
1206
+ creatorId: r.creatorId ?? null,
1207
+ createTime: Number(r.createTime) || null,
1208
+ editTime: Number(r.editTime) || null,
1209
+ startTime: Number(r.startTime) || null,
1210
+ duration: Number(r.duration) || null,
1211
+ repeatMode: Number(r.repeatMode) || 0,
1212
+ emoji: r.emoji ?? null,
1213
+ color: Number(r.color) || null,
1214
+ eventType: Number(r.eventType) || null,
1215
+ raw_data: typeof r.raw_data === "object" ? JSON.stringify(r.raw_data) : (r.raw_data ?? null),
1216
+ sync_timestamp: r.sync_timestamp || Date.now(),
1217
+ });
1218
+ }
1219
+
1220
+ /** Reminders for a thread, or all of them, soonest start first. */
1221
+ export function getReminders(threadId = null) {
1222
+ if (!db) throw new Error("Database not initialized");
1223
+ return threadId
1224
+ ? db.prepare("SELECT * FROM reminders WHERE threadId = ? ORDER BY startTime ASC").all(String(threadId))
1225
+ : db.prepare("SELECT * FROM reminders ORDER BY startTime ASC").all();
1226
+ }
1227
+
1228
+ /**
1229
+ * Record a zCloud media item. Keyed by Zalo's `noiseId`, which is the id the
1230
+ * cloud queue and the download endpoint both speak.
1231
+ */
1232
+ export function upsertCloudItem(item) {
1233
+ if (!db) throw new Error("Database not initialized");
1234
+ return db
1235
+ .prepare(
1236
+ `INSERT INTO cloud_items
1237
+ (noiseId, threadId, msgId, msgType, mediaType, cloudUrl, encryptKey, checksum,
1238
+ mediaSize, timestamp, localPath, raw_data, sync_timestamp)
1239
+ VALUES (@noiseId, @threadId, @msgId, @msgType, @mediaType, @cloudUrl, @encryptKey, @checksum,
1240
+ @mediaSize, @timestamp, @localPath, @raw_data, @sync_timestamp)
1241
+ ON CONFLICT(noiseId) DO UPDATE SET
1242
+ threadId = COALESCE(excluded.threadId, cloud_items.threadId),
1243
+ msgId = COALESCE(excluded.msgId, cloud_items.msgId),
1244
+ cloudUrl = excluded.cloudUrl,
1245
+ encryptKey = COALESCE(excluded.encryptKey, cloud_items.encryptKey),
1246
+ checksum = COALESCE(excluded.checksum, cloud_items.checksum),
1247
+ mediaSize = COALESCE(excluded.mediaSize, cloud_items.mediaSize),
1248
+ localPath = COALESCE(excluded.localPath, cloud_items.localPath),
1249
+ raw_data = excluded.raw_data,
1250
+ sync_timestamp = excluded.sync_timestamp`,
1251
+ )
1252
+ .run({
1253
+ noiseId: String(item.noiseId),
1254
+ threadId: item.threadId === undefined || item.threadId === null ? null : String(item.threadId),
1255
+ msgId: item.msgId === undefined || item.msgId === null ? null : String(item.msgId),
1256
+ msgType: Number(item.msgType) || null,
1257
+ mediaType: Number(item.mediaType) || null,
1258
+ cloudUrl: item.cloudUrl ?? null,
1259
+ encryptKey: item.encryptKey ?? null,
1260
+ checksum: item.checksum ?? null,
1261
+ mediaSize: Number(item.mediaSize) || null,
1262
+ timestamp: Number(item.timestamp) || null,
1263
+ localPath: item.localPath ?? null,
1264
+ raw_data: typeof item.raw_data === "object" ? JSON.stringify(item.raw_data) : (item.raw_data ?? null),
1265
+ sync_timestamp: item.sync_timestamp || Date.now(),
1266
+ });
1267
+ }
1268
+
1269
+ /** zCloud items, newest first; optionally one thread's. */
1270
+ export function getCloudItems(threadId = null, limit = 500) {
1271
+ if (!db) throw new Error("Database not initialized");
1272
+ return threadId
1273
+ ? db
1274
+ .prepare("SELECT * FROM cloud_items WHERE threadId = ? ORDER BY timestamp DESC LIMIT ?")
1275
+ .all(String(threadId), limit)
1276
+ : db.prepare("SELECT * FROM cloud_items ORDER BY timestamp DESC LIMIT ?").all(limit);
1277
+ }
1278
+
1279
+ /** The zCloud backup for one message, if the cloud queue has told us about it. */
1280
+ export function getCloudItemByMsgId(msgId) {
1281
+ if (!db) throw new Error("Database not initialized");
1282
+ return db.prepare("SELECT * FROM cloud_items WHERE msgId = ? LIMIT 1").get(String(msgId)) || null;
1283
+ }
1284
+
1285
+ /**
1286
+ * Advance a message's delivery state.
1287
+ *
1288
+ * Only ever forwards: a late-arriving "delivered" must not undo a "seen" that
1289
+ * already landed, and re-syncing an older snapshot must not either.
1290
+ */
1291
+ export function setMessageStatus(msgId, status) {
1292
+ if (!db) throw new Error("Database not initialized");
1293
+ return db
1294
+ .prepare("UPDATE messages SET msgStatus = MAX(COALESCE(msgStatus, 0), ?) WHERE msgId = ?")
1295
+ .run(Number(status) || 0, String(msgId));
1296
+ }
1297
+
1298
+ /** Sync2.Message.MessageStatus: delivery and read state. */
1299
+ export const MESSAGE_STATUS = {
1300
+ 0: "unspecified",
1301
+ 1: "failed",
1302
+ 2: "sending",
1303
+ 3: "sent",
1304
+ 4: "received",
1305
+ 5: "seen",
1306
+ };
1307
+
1308
+ /**
1309
+ * Record a reaction.
1310
+ *
1311
+ * One person holds at most one reaction per message, so the key is
1312
+ * (msgId, userId): reacting again replaces it, and Zalo signals removal by
1313
+ * sending an empty icon, which deletes the row rather than storing a blank.
1314
+ */
1315
+ /**
1316
+ * A reaction type as a number, or null when Zalo did not send one.
1317
+ *
1318
+ * `Number.isFinite(Number(v))` is not enough on its own: `Number(null)` is 0,
1319
+ * and 0 is a real reaction type (HAHA), so a missing type silently became a
1320
+ * haha -- and a removal that named no type deleted the wrong row.
1321
+ *
1322
+ * @param {unknown} v
1323
+ * @returns {number|null}
1324
+ */
1325
+ function reactionType(v) {
1326
+ if (v === null || v === undefined || v === "") return null;
1327
+ const n = Number(v);
1328
+ return Number.isFinite(n) ? n : null;
1329
+ }
1330
+
1331
+ export function upsertReaction(r) {
1332
+ if (!db) throw new Error("Database not initialized");
1333
+ // The icon is part of the identity: the same person holding both a heart
1334
+ // and a haha on one message is two rows, which is what Zalo displays.
1335
+ const id = `${r.msgId}:${r.userId}:${r.icon}`;
1336
+ if (!r.icon) {
1337
+ // Removal is ALL-OR-NOTHING, measured against a real frame: un-reacting
1338
+ // sends rIcon "" with rType -1 -- a sentinel, not one of the types to
1339
+ // match -- and the app offers no way to drop one of several icons. An
1340
+ // earlier build read that -1 as a type and deleted WHERE rType = -1,
1341
+ // which matched nothing, so a removal silently left the reactions in
1342
+ // place.
1343
+ return db
1344
+ .prepare("DELETE FROM reactions WHERE msgId = ? AND userId = ?")
1345
+ .run(String(r.msgId), String(r.userId));
1346
+ }
1347
+ return db
1348
+ .prepare(
1349
+ `INSERT INTO reactions (id, msgId, threadId, userId, icon, rType, source, timestamp)
1350
+ VALUES (@id, @msgId, @threadId, @userId, @icon, @rType, @source, @timestamp)
1351
+ ON CONFLICT(id) DO UPDATE SET
1352
+ icon = excluded.icon, rType = excluded.rType,
1353
+ source = excluded.source, timestamp = excluded.timestamp`,
1354
+ )
1355
+ .run({
1356
+ id,
1357
+ msgId: String(r.msgId),
1358
+ threadId: r.threadId === null || r.threadId === undefined ? null : String(r.threadId),
1359
+ userId: String(r.userId),
1360
+ icon: r.icon,
1361
+ // 0 is a real reaction type (HAHA), and a missing one is not 0.
1362
+ rType: reactionType(r.rType),
1363
+ source: r.source || "listen",
1364
+ timestamp: Number(r.timestamp) || Date.now(),
1365
+ });
1366
+ }
1367
+
1368
+ /** Reactions on one message, or across a thread. */
1369
+ export function getReactions({ msgId = null, threadId = null, limit = 500 } = {}) {
1370
+ if (!db) throw new Error("Database not initialized");
1371
+ if (msgId) return db.prepare("SELECT * FROM reactions WHERE msgId = ?").all(String(msgId));
1372
+ if (threadId)
1373
+ return db
1374
+ .prepare("SELECT * FROM reactions WHERE threadId = ? ORDER BY timestamp DESC LIMIT ?")
1375
+ .all(String(threadId), limit);
1376
+ return db.prepare("SELECT * FROM reactions ORDER BY timestamp DESC LIMIT ?").all(limit);
1377
+ }
1378
+
1379
+ /**
1380
+ * Mark a message recalled without deleting the row.
1381
+ *
1382
+ * Zalo's "Thu hồi" removes the message for everyone; a cache that keeps the
1383
+ * text readable afterwards is retaining something the sender withdrew. The row
1384
+ * stays so the conversation still shows that something was there and when.
1385
+ */
1386
+ export function markMessageRecalled(msgId, at = Date.now(), opts = {}) {
1387
+ if (!db) throw new Error("Database not initialized");
1388
+ const row = db
1389
+ .prepare("SELECT type, raw_data, localPath, has_attachment FROM messages WHERE msgId = ?")
1390
+ .get(String(msgId));
1391
+ // Nothing to tombstone. Reported rather than swallowed: the previous
1392
+ // version always claimed success, which is how a recall handler that
1393
+ // updated zero rows went unnoticed.
1394
+ if (!row) return { changes: 0, localPath: null, missing: true };
1395
+
1396
+ // Keep the identifiers, drop the content. `cliMsgId` is the only local copy
1397
+ // of a client id and `msg delete` / `msg undo` / `conv delete` all need it,
1398
+ // so replacing raw_data wholesale made a recalled message undeletable.
1399
+ // `originalType` mirrors what the phone itself preserves for a removed
1400
+ // message (params.original_type), so our tombstone is no poorer than
1401
+ // Zalo's own.
1402
+ let cliMsgId;
1403
+ try {
1404
+ cliMsgId = JSON.parse(row.raw_data)?.cliMsgId;
1405
+ } catch {
1406
+ /* 108k legacy rows hold the bare content string, not JSON */
1407
+ }
1408
+ const raw = JSON.stringify({
1409
+ src: "listen",
1410
+ removedAs: opts.reason === "delete-for-me" ? "delete-for-me" : "recall",
1411
+ removedAt: Number(at) || Date.now(),
1412
+ originalType: row.type,
1413
+ cliMsgId: cliMsgId === undefined || cliMsgId === null ? undefined : String(cliMsgId),
1414
+ });
1415
+ const hadMedia = row.has_attachment === 1 || !!row.localPath;
1416
+
1417
+ const res = db
1418
+ .prepare(
1419
+ `UPDATE messages SET
1420
+ type = 'deleted',
1421
+ text = '[deleted]',
1422
+ raw_data = @raw,
1423
+ -- The media goes with the message. Leaving has_attachment set would
1424
+ -- queue the attachment of a just-withdrawn message for download;
1425
+ -- mediaPrunedAt is the existing "do not fetch this again" marker.
1426
+ has_attachment = 0,
1427
+ localPath = NULL,
1428
+ mediaPrunedAt = CASE WHEN @hadMedia = 1 THEN @at ELSE mediaPrunedAt END
1429
+ WHERE msgId = @msgId`,
1430
+ )
1431
+ .run({ raw, at: Number(at) || Date.now(), hadMedia: hadMedia ? 1 : 0, msgId: String(msgId) });
1432
+
1433
+ return { changes: res.changes, localPath: row.localPath || null, originalType: row.type, missing: false };
1434
+ }
1435
+
1436
+ /**
1437
+ * Find a message by the client-side id its sender generated.
1438
+ *
1439
+ * A "delete for me" frame names its target by `clientDelMsgId` when the
1440
+ * deleting client did not know the server id, so this is the only way to
1441
+ * resolve it. Guarded with json_valid() because an older writer stored the
1442
+ * bare content string in raw_data on six figures of rows, and an unguarded
1443
+ * json_extract over this table raises "malformed JSON" and takes the whole
1444
+ * query with it.
1445
+ *
1446
+ * @param {string|number} cliMsgId
1447
+ * @returns {object|null}
1448
+ */
1449
+ export function findMessageByClientId(cliMsgId) {
1450
+ if (!db) throw new Error("Database not initialized");
1451
+ if (cliMsgId === undefined || cliMsgId === null || cliMsgId === "") return null;
1452
+ return (
1453
+ db
1454
+ .prepare(
1455
+ `SELECT * FROM messages
1456
+ WHERE json_valid(raw_data) AND json_extract(raw_data, '$.cliMsgId') = ?
1457
+ ORDER BY timestamp DESC LIMIT 1`,
1458
+ )
1459
+ .get(String(cliMsgId)) || null
1460
+ );
1461
+ }
1462
+
1463
+ /** Pinned / unread-marked state for a conversation. Applies to DMs too. */
1464
+ export function upsertConvState(st) {
1465
+ if (!db) throw new Error("Database not initialized");
1466
+ return db
1467
+ .prepare(
1468
+ `INSERT INTO conv_state (threadId, pinned, pinnedAt, unreadMarked, unreadMarkedAt, updatedAt)
1469
+ VALUES (@threadId, @pinned, @pinnedAt, @unreadMarked, @unreadMarkedAt, @updatedAt)
1470
+ ON CONFLICT(threadId) DO UPDATE SET
1471
+ pinned = COALESCE(excluded.pinned, conv_state.pinned),
1472
+ pinnedAt = COALESCE(excluded.pinnedAt, conv_state.pinnedAt),
1473
+ unreadMarked = COALESCE(excluded.unreadMarked, conv_state.unreadMarked),
1474
+ unreadMarkedAt = COALESCE(excluded.unreadMarkedAt, conv_state.unreadMarkedAt),
1475
+ updatedAt = excluded.updatedAt`,
1476
+ )
1477
+ .run({
1478
+ threadId: String(st.threadId),
1479
+ pinned: st.pinned === undefined ? null : st.pinned ? 1 : 0,
1480
+ pinnedAt: st.pinned === undefined ? null : Number(st.pinnedAt) || Date.now(),
1481
+ unreadMarked: st.unreadMarked === undefined ? null : st.unreadMarked ? 1 : 0,
1482
+ unreadMarkedAt: st.unreadMarked === undefined ? null : Number(st.unreadMarkedAt) || Date.now(),
1483
+ updatedAt: Date.now(),
1484
+ });
1485
+ }
1486
+
1487
+ /** Conversation state for one thread, or every thread that has any. */
1488
+ export function getConvState(threadId = null) {
1489
+ if (!db) throw new Error("Database not initialized");
1490
+ return threadId
1491
+ ? db.prepare("SELECT * FROM conv_state WHERE threadId = ?").get(String(threadId)) || null
1492
+ : db.prepare("SELECT * FROM conv_state ORDER BY updatedAt DESC").all();
1493
+ }
1494
+
1495
+ /**
1496
+ * Move a conversation's read watermark: the newest message this account has
1497
+ * read in it, on any device.
1498
+ *
1499
+ * It only moves forward. The same read is reported more than once -- on its
1500
+ * own cmd and again inside the next envelope -- and an offline-queue page can
1501
+ * arrive after a newer live push, so an older or equal id changes nothing.
1502
+ * Message ids are global and increase with time, so a larger id is a later
1503
+ * message; they are compared as integers, never as strings or doubles.
1504
+ *
1505
+ * @param {{threadId: string, msgId: string, ts?: number}} read - `ts` is when
1506
+ * the read was reported; now when the report carries none
1507
+ * @returns {boolean} whether the watermark moved
1508
+ */
1509
+ export function recordReadWatermark({ threadId, msgId, ts }) {
1510
+ if (!db) throw new Error("Database not initialized");
1511
+ const id = String(msgId ?? "");
1512
+ if (!/^\d+$/.test(id) || BigInt(id) === 0n) return false;
1513
+ const now = Date.now();
1514
+ return db.transaction(() => {
1515
+ const cur = db.prepare("SELECT lastReadMsgId FROM conv_state WHERE threadId = ?").get(String(threadId));
1516
+ if (/^\d+$/.test(cur?.lastReadMsgId ?? "") && BigInt(cur.lastReadMsgId) >= BigInt(id)) return false;
1517
+ db.prepare(
1518
+ `INSERT INTO conv_state (threadId, lastReadMsgId, lastReadTs, updatedAt)
1519
+ VALUES (?, ?, ?, ?)
1520
+ ON CONFLICT(threadId) DO UPDATE SET
1521
+ lastReadMsgId = excluded.lastReadMsgId,
1522
+ lastReadTs = excluded.lastReadTs,
1523
+ updatedAt = excluded.updatedAt`,
1524
+ ).run(String(threadId), id, Number(ts) > 0 ? Number(ts) : now, now);
1525
+ return true;
1526
+ })();
1527
+ }
1528
+
1529
+ /**
1530
+ * Where the account stands on reading each conversation: its read watermark,
1531
+ * its manual unread mark, and how many messages from others the cache holds
1532
+ * after the watermark.
1533
+ *
1534
+ * `unreadAfter` counts cached messages only -- ids after the watermark that
1535
+ * someone other than this account sent, not recalled or deleted -- so it is a
1536
+ * floor, and null when no watermark is known yet ("never told", not "all
1537
+ * read"). Own messages are told apart as everywhere else: zca-js rewrites an
1538
+ * own message's raw sender "0" to this account's uid before it is stored.
1539
+ *
1540
+ * @param {string[]} threadIds
1541
+ * @param {string} ownId
1542
+ * @returns {Map<string, {lastReadMsgId: string|null, lastReadTs: number|null,
1543
+ * unreadMarked: boolean, unreadAfter: number|null}>} one entry per thread with any state
1544
+ */
1545
+ export function getReadStates(threadIds, ownId) {
1546
+ if (!db) throw new Error("Database not initialized");
1547
+ const state = db.prepare(
1548
+ "SELECT threadId, lastReadMsgId, lastReadTs, unreadMarked FROM conv_state WHERE threadId = ?",
1549
+ );
1550
+ const after = db.prepare(
1551
+ `SELECT COUNT(*) AS n FROM messages
1552
+ WHERE threadId = ? AND msgId NOT GLOB '*[^0-9]*' AND msgId != ''
1553
+ AND CAST(msgId AS INTEGER) > CAST(? AS INTEGER)
1554
+ AND COALESCE(senderId, '') != ? AND COALESCE(type, '') != 'deleted'`,
1555
+ );
1556
+ const out = new Map();
1557
+ for (const threadId of threadIds) {
1558
+ const row = state.get(String(threadId));
1559
+ if (!row) continue;
1560
+ const known = /^\d+$/.test(row.lastReadMsgId ?? "");
1561
+ out.set(String(threadId), {
1562
+ lastReadMsgId: known ? row.lastReadMsgId : null,
1563
+ lastReadTs: known ? row.lastReadTs : null,
1564
+ unreadMarked: Boolean(row.unreadMarked),
1565
+ unreadAfter: known ? after.get(String(threadId), row.lastReadMsgId, String(ownId ?? "")).n : null,
1566
+ });
1567
+ }
1568
+ return out;
1569
+ }
1570
+
1571
+ export function upsertContact(contact) {
1572
+ if (!db) throw new Error("Database not initialized");
1573
+
1574
+ const stmt = db.prepare(`
1575
+ INSERT INTO contacts (userId, name, phone)
1576
+ VALUES (@userId, @name, @phone)
1577
+ ON CONFLICT(userId) DO UPDATE SET
1578
+ name = excluded.name,
1579
+ phone = excluded.phone
1580
+ `);
1581
+
1582
+ return stmt.run({
1583
+ userId: contact.userId,
1584
+ name: contact.name,
1585
+ phone: contact.phone,
1586
+ });
1587
+ }
1588
+
1589
+ /**
1590
+ * The display name this account has seen for a user id, or null.
1591
+ *
1592
+ * Used to turn a `@[uid]` mention token into "@Display Name". Two sources,
1593
+ * in order:
1594
+ *
1595
+ * 1. `contacts` — authoritative, and the only source that can name someone
1596
+ * who has never posted. `msg send` fills it in: any uid it has to look
1597
+ * up through `getGroupMembersInfo` is written back here, so the next
1598
+ * send needs no call.
1599
+ * 2. the most recent `messages.senderName` for that sender — the live
1600
+ * listener stores Zalo's own `dName` on every row it writes, so anyone
1601
+ * who has spoken is named here without a network call.
1602
+ *
1603
+ * Null when the uid has never been seen; the caller falls back to the uid,
1604
+ * which still produces a valid mention.
1605
+ *
1606
+ * @param {string|number} userId
1607
+ * @returns {string|null}
1608
+ */
1609
+ export function getDisplayName(userId) {
1610
+ if (!db) throw new Error("Database not initialized");
1611
+ if (userId === undefined || userId === null || userId === "") return null;
1612
+ const id = String(userId);
1613
+
1614
+ const contact = db.prepare("SELECT name FROM contacts WHERE userId = ?").get(id);
1615
+ if (contact?.name) return contact.name;
1616
+
1617
+ const seen = db
1618
+ .prepare(
1619
+ `SELECT senderName FROM messages
1620
+ WHERE senderId = ? AND senderName IS NOT NULL AND senderName <> ''
1621
+ ORDER BY timestamp DESC LIMIT 1`,
1622
+ )
1623
+ .get(id);
1624
+ return seen?.senderName || null;
1625
+ }