@dereekb/firebase-server 12.6.21 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (332) hide show
  1. package/LICENSE +1 -1
  2. package/index.cjs.js +2937 -0
  3. package/index.esm.js +2775 -0
  4. package/mailgun/index.cjs.js +48 -0
  5. package/mailgun/index.esm.js +46 -0
  6. package/mailgun/package.json +26 -6
  7. package/model/index.cjs.js +5298 -0
  8. package/model/index.d.ts +1 -0
  9. package/model/index.esm.js +5161 -0
  10. package/model/package.json +31 -3
  11. package/model/src/lib/notification/notification.module.d.ts +10 -10
  12. package/model/src/lib/storagefile/storagefile.task.service.handler.d.ts +3 -14
  13. package/package.json +48 -27
  14. package/src/lib/auth/auth.context.d.ts +1 -1
  15. package/src/lib/auth/auth.service.d.ts +1 -1
  16. package/src/lib/function/assert.d.ts +2 -2
  17. package/src/lib/function/context.d.ts +1 -1
  18. package/src/lib/index.d.ts +1 -0
  19. package/src/lib/nest/app.d.ts +1 -1
  20. package/src/lib/nest/development/development.app.function.d.ts +1 -2
  21. package/src/lib/nest/function/call.d.ts +1 -1
  22. package/src/lib/nest/function/context.d.ts +0 -4
  23. package/src/lib/nest/function/index.d.ts +0 -1
  24. package/src/lib/nest/function/nest.d.ts +1 -1
  25. package/src/lib/nest/function/v2/blocking.d.ts +3 -2
  26. package/src/lib/nest/model/crud.assert.function.d.ts +0 -4
  27. package/src/lib/storage/storage.d.ts +1 -1
  28. package/src/lib/type.d.ts +9 -0
  29. package/test/index.cjs.js +1324 -0
  30. package/test/index.d.ts +1 -0
  31. package/test/index.esm.js +1247 -0
  32. package/test/package.json +34 -3
  33. package/test/src/lib/firebase/firebase.admin.auth.d.ts +22 -13
  34. package/test/src/lib/firebase/firebase.admin.collection.d.ts +6 -6
  35. package/test/src/lib/firebase/firebase.admin.d.ts +10 -10
  36. package/test/src/lib/firebase/firebase.admin.function.d.ts +9 -9
  37. package/test/src/lib/firebase/firebase.admin.nest.d.ts +8 -8
  38. package/test/src/lib/firebase/firebase.admin.nest.function.d.ts +9 -9
  39. package/test/src/lib/firebase/firebase.test.d.ts +30 -0
  40. package/test/src/lib/firebase/index.d.ts +1 -1
  41. package/test/src/lib/firestore/firestore.admin.d.ts +3 -3
  42. package/test/src/lib/firestore/firestore.d.ts +2 -2
  43. package/test/src/lib/storage/storage.admin.d.ts +3 -3
  44. package/test/src/lib/storage/storage.d.ts +2 -2
  45. package/zoho/LICENSE +1 -1
  46. package/zoho/index.d.ts +1 -0
  47. package/zoho/index.esm.js +2 -2
  48. package/zoho/package.json +12 -8
  49. package/CHANGELOG.md +0 -2233
  50. package/mailgun/src/index.js +0 -5
  51. package/mailgun/src/index.js.map +0 -1
  52. package/mailgun/src/lib/auth.mailgun.js +0 -41
  53. package/mailgun/src/lib/auth.mailgun.js.map +0 -1
  54. package/mailgun/src/lib/index.js +0 -5
  55. package/mailgun/src/lib/index.js.map +0 -1
  56. package/model/src/index.js +0 -5
  57. package/model/src/index.js.map +0 -1
  58. package/model/src/lib/index.js +0 -7
  59. package/model/src/lib/index.js.map +0 -1
  60. package/model/src/lib/mailgun/index.js +0 -5
  61. package/model/src/lib/mailgun/index.js.map +0 -1
  62. package/model/src/lib/mailgun/notification.send.service.mailgun.js +0 -68
  63. package/model/src/lib/mailgun/notification.send.service.mailgun.js.map +0 -1
  64. package/model/src/lib/notification/index.js +0 -20
  65. package/model/src/lib/notification/index.js.map +0 -1
  66. package/model/src/lib/notification/notification.action.init.service.js +0 -230
  67. package/model/src/lib/notification/notification.action.init.service.js.map +0 -1
  68. package/model/src/lib/notification/notification.action.service.js +0 -1487
  69. package/model/src/lib/notification/notification.action.service.js.map +0 -1
  70. package/model/src/lib/notification/notification.config.js +0 -13
  71. package/model/src/lib/notification/notification.config.js.map +0 -1
  72. package/model/src/lib/notification/notification.config.service.js +0 -60
  73. package/model/src/lib/notification/notification.config.service.js.map +0 -1
  74. package/model/src/lib/notification/notification.create.run.js +0 -59
  75. package/model/src/lib/notification/notification.create.run.js.map +0 -1
  76. package/model/src/lib/notification/notification.error.js +0 -87
  77. package/model/src/lib/notification/notification.error.js.map +0 -1
  78. package/model/src/lib/notification/notification.expedite.service.js +0 -112
  79. package/model/src/lib/notification/notification.expedite.service.js.map +0 -1
  80. package/model/src/lib/notification/notification.module.js +0 -106
  81. package/model/src/lib/notification/notification.module.js.map +0 -1
  82. package/model/src/lib/notification/notification.send.js +0 -3
  83. package/model/src/lib/notification/notification.send.js.map +0 -1
  84. package/model/src/lib/notification/notification.send.service.js +0 -10
  85. package/model/src/lib/notification/notification.send.service.js.map +0 -1
  86. package/model/src/lib/notification/notification.send.service.notificationsummary.js +0 -104
  87. package/model/src/lib/notification/notification.send.service.notificationsummary.js.map +0 -1
  88. package/model/src/lib/notification/notification.send.service.text.js +0 -29
  89. package/model/src/lib/notification/notification.send.service.text.js.map +0 -1
  90. package/model/src/lib/notification/notification.task.service.handler.js +0 -65
  91. package/model/src/lib/notification/notification.task.service.handler.js.map +0 -1
  92. package/model/src/lib/notification/notification.task.service.js +0 -10
  93. package/model/src/lib/notification/notification.task.service.js.map +0 -1
  94. package/model/src/lib/notification/notification.task.service.util.js +0 -27
  95. package/model/src/lib/notification/notification.task.service.util.js.map +0 -1
  96. package/model/src/lib/notification/notification.task.subtask.handler.js +0 -256
  97. package/model/src/lib/notification/notification.task.subtask.handler.js.map +0 -1
  98. package/model/src/lib/notification/notification.util.js +0 -478
  99. package/model/src/lib/notification/notification.util.js.map +0 -1
  100. package/model/src/lib/storagefile/index.js +0 -12
  101. package/model/src/lib/storagefile/index.js.map +0 -1
  102. package/model/src/lib/storagefile/storagefile.action.init.service.js +0 -155
  103. package/model/src/lib/storagefile/storagefile.action.init.service.js.map +0 -1
  104. package/model/src/lib/storagefile/storagefile.action.server.js +0 -797
  105. package/model/src/lib/storagefile/storagefile.action.server.js.map +0 -1
  106. package/model/src/lib/storagefile/storagefile.error.js +0 -106
  107. package/model/src/lib/storagefile/storagefile.error.js.map +0 -1
  108. package/model/src/lib/storagefile/storagefile.module.js +0 -64
  109. package/model/src/lib/storagefile/storagefile.module.js.map +0 -1
  110. package/model/src/lib/storagefile/storagefile.task.service.handler.js +0 -287
  111. package/model/src/lib/storagefile/storagefile.task.service.handler.js.map +0 -1
  112. package/model/src/lib/storagefile/storagefile.upload.service.initializer.js +0 -180
  113. package/model/src/lib/storagefile/storagefile.upload.service.initializer.js.map +0 -1
  114. package/model/src/lib/storagefile/storagefile.upload.service.js +0 -10
  115. package/model/src/lib/storagefile/storagefile.upload.service.js.map +0 -1
  116. package/model/src/lib/storagefile/storagefile.util.js +0 -54
  117. package/model/src/lib/storagefile/storagefile.util.js.map +0 -1
  118. package/src/index.js +0 -5
  119. package/src/index.js.map +0 -1
  120. package/src/lib/auth/auth.context.js +0 -13
  121. package/src/lib/auth/auth.context.js.map +0 -1
  122. package/src/lib/auth/auth.service.error.js +0 -34
  123. package/src/lib/auth/auth.service.error.js.map +0 -1
  124. package/src/lib/auth/auth.service.js +0 -427
  125. package/src/lib/auth/auth.service.js.map +0 -1
  126. package/src/lib/auth/auth.util.js +0 -23
  127. package/src/lib/auth/auth.util.js.map +0 -1
  128. package/src/lib/auth/index.js +0 -8
  129. package/src/lib/auth/index.js.map +0 -1
  130. package/src/lib/env/env.service.js +0 -7
  131. package/src/lib/env/env.service.js.map +0 -1
  132. package/src/lib/env/index.js +0 -5
  133. package/src/lib/env/index.js.map +0 -1
  134. package/src/lib/firestore/array.js +0 -34
  135. package/src/lib/firestore/array.js.map +0 -1
  136. package/src/lib/firestore/driver.accessor.batch.js +0 -93
  137. package/src/lib/firestore/driver.accessor.batch.js.map +0 -1
  138. package/src/lib/firestore/driver.accessor.default.js +0 -62
  139. package/src/lib/firestore/driver.accessor.default.js.map +0 -1
  140. package/src/lib/firestore/driver.accessor.js +0 -50
  141. package/src/lib/firestore/driver.accessor.js.map +0 -1
  142. package/src/lib/firestore/driver.accessor.transaction.js +0 -96
  143. package/src/lib/firestore/driver.accessor.transaction.js.map +0 -1
  144. package/src/lib/firestore/driver.js +0 -14
  145. package/src/lib/firestore/driver.js.map +0 -1
  146. package/src/lib/firestore/driver.query.js +0 -55
  147. package/src/lib/firestore/driver.query.js.map +0 -1
  148. package/src/lib/firestore/firestore.js +0 -10
  149. package/src/lib/firestore/firestore.js.map +0 -1
  150. package/src/lib/firestore/increment.js +0 -17
  151. package/src/lib/firestore/increment.js.map +0 -1
  152. package/src/lib/firestore/index.js +0 -9
  153. package/src/lib/firestore/index.js.map +0 -1
  154. package/src/lib/function/assert.js +0 -68
  155. package/src/lib/function/assert.js.map +0 -1
  156. package/src/lib/function/context.js +0 -14
  157. package/src/lib/function/context.js.map +0 -1
  158. package/src/lib/function/error.auth.js +0 -25
  159. package/src/lib/function/error.auth.js.map +0 -1
  160. package/src/lib/function/error.js +0 -221
  161. package/src/lib/function/error.js.map +0 -1
  162. package/src/lib/function/index.js +0 -9
  163. package/src/lib/function/index.js.map +0 -1
  164. package/src/lib/function/type.js +0 -3
  165. package/src/lib/function/type.js.map +0 -1
  166. package/src/lib/index.js +0 -11
  167. package/src/lib/index.js.map +0 -1
  168. package/src/lib/nest/app.js +0 -114
  169. package/src/lib/nest/app.js.map +0 -1
  170. package/src/lib/nest/auth/auth.module.js +0 -60
  171. package/src/lib/nest/auth/auth.module.js.map +0 -1
  172. package/src/lib/nest/auth/auth.util.js +0 -72
  173. package/src/lib/nest/auth/auth.util.js.map +0 -1
  174. package/src/lib/nest/auth/index.js +0 -6
  175. package/src/lib/nest/auth/index.js.map +0 -1
  176. package/src/lib/nest/development/development.app.function.js +0 -38
  177. package/src/lib/nest/development/development.app.function.js.map +0 -1
  178. package/src/lib/nest/development/development.assert.function.js +0 -3
  179. package/src/lib/nest/development/development.assert.function.js.map +0 -1
  180. package/src/lib/nest/development/development.function.js +0 -41
  181. package/src/lib/nest/development/development.function.js.map +0 -1
  182. package/src/lib/nest/development/development.schedule.function.error.js +0 -35
  183. package/src/lib/nest/development/development.schedule.function.error.js.map +0 -1
  184. package/src/lib/nest/development/development.schedule.function.js +0 -54
  185. package/src/lib/nest/development/development.schedule.function.js.map +0 -1
  186. package/src/lib/nest/development/index.js +0 -9
  187. package/src/lib/nest/development/index.js.map +0 -1
  188. package/src/lib/nest/env/env.service.js +0 -19
  189. package/src/lib/nest/env/env.service.js.map +0 -1
  190. package/src/lib/nest/env/env.util.js +0 -12
  191. package/src/lib/nest/env/env.util.js.map +0 -1
  192. package/src/lib/nest/env/index.js +0 -6
  193. package/src/lib/nest/env/index.js.map +0 -1
  194. package/src/lib/nest/firebase/firebase.module.js +0 -17
  195. package/src/lib/nest/firebase/firebase.module.js.map +0 -1
  196. package/src/lib/nest/firebase/index.js +0 -5
  197. package/src/lib/nest/firebase/index.js.map +0 -1
  198. package/src/lib/nest/firestore/firestore.module.js +0 -86
  199. package/src/lib/nest/firestore/firestore.module.js.map +0 -1
  200. package/src/lib/nest/firestore/index.js +0 -5
  201. package/src/lib/nest/firestore/index.js.map +0 -1
  202. package/src/lib/nest/function/call.js +0 -46
  203. package/src/lib/nest/function/call.js.map +0 -1
  204. package/src/lib/nest/function/context.js +0 -79
  205. package/src/lib/nest/function/context.js.map +0 -1
  206. package/src/lib/nest/function/index.js +0 -10
  207. package/src/lib/nest/function/index.js.map +0 -1
  208. package/src/lib/nest/function/nest.js +0 -17
  209. package/src/lib/nest/function/nest.js.map +0 -1
  210. package/src/lib/nest/function/schedule.js +0 -8
  211. package/src/lib/nest/function/schedule.js.map +0 -1
  212. package/src/lib/nest/function/v1/call.d.ts +0 -59
  213. package/src/lib/nest/function/v1/call.js +0 -55
  214. package/src/lib/nest/function/v1/call.js.map +0 -1
  215. package/src/lib/nest/function/v1/event.d.ts +0 -80
  216. package/src/lib/nest/function/v1/event.js +0 -52
  217. package/src/lib/nest/function/v1/event.js.map +0 -1
  218. package/src/lib/nest/function/v1/index.d.ts +0 -3
  219. package/src/lib/nest/function/v1/index.js +0 -7
  220. package/src/lib/nest/function/v1/index.js.map +0 -1
  221. package/src/lib/nest/function/v1/schedule.d.ts +0 -47
  222. package/src/lib/nest/function/v1/schedule.js +0 -68
  223. package/src/lib/nest/function/v1/schedule.js.map +0 -1
  224. package/src/lib/nest/function/v2/blocking.js +0 -38
  225. package/src/lib/nest/function/v2/blocking.js.map +0 -1
  226. package/src/lib/nest/function/v2/call.js +0 -31
  227. package/src/lib/nest/function/v2/call.js.map +0 -1
  228. package/src/lib/nest/function/v2/event.js +0 -25
  229. package/src/lib/nest/function/v2/event.js.map +0 -1
  230. package/src/lib/nest/function/v2/index.js +0 -9
  231. package/src/lib/nest/function/v2/index.js.map +0 -1
  232. package/src/lib/nest/function/v2/schedule.js +0 -56
  233. package/src/lib/nest/function/v2/schedule.js.map +0 -1
  234. package/src/lib/nest/function/v2/taskqueue.js +0 -26
  235. package/src/lib/nest/function/v2/taskqueue.js.map +0 -1
  236. package/src/lib/nest/index.js +0 -15
  237. package/src/lib/nest/index.js.map +0 -1
  238. package/src/lib/nest/middleware/appcheck.decorator.js +0 -12
  239. package/src/lib/nest/middleware/appcheck.decorator.js.map +0 -1
  240. package/src/lib/nest/middleware/appcheck.js +0 -3
  241. package/src/lib/nest/middleware/appcheck.js.map +0 -1
  242. package/src/lib/nest/middleware/appcheck.middleware.js +0 -74
  243. package/src/lib/nest/middleware/appcheck.middleware.js.map +0 -1
  244. package/src/lib/nest/middleware/appcheck.module.js +0 -21
  245. package/src/lib/nest/middleware/appcheck.module.js.map +0 -1
  246. package/src/lib/nest/middleware/globalprefix.js +0 -11
  247. package/src/lib/nest/middleware/globalprefix.js.map +0 -1
  248. package/src/lib/nest/middleware/index.js +0 -10
  249. package/src/lib/nest/middleware/index.js.map +0 -1
  250. package/src/lib/nest/middleware/rawbody.middleware.js +0 -16
  251. package/src/lib/nest/middleware/rawbody.middleware.js.map +0 -1
  252. package/src/lib/nest/middleware/webhook.js +0 -24
  253. package/src/lib/nest/middleware/webhook.js.map +0 -1
  254. package/src/lib/nest/model/call.model.function.js +0 -73
  255. package/src/lib/nest/model/call.model.function.js.map +0 -1
  256. package/src/lib/nest/model/create.model.function.js +0 -27
  257. package/src/lib/nest/model/create.model.function.js.map +0 -1
  258. package/src/lib/nest/model/crud.assert.function.js +0 -3
  259. package/src/lib/nest/model/crud.assert.function.js.map +0 -1
  260. package/src/lib/nest/model/delete.model.function.js +0 -27
  261. package/src/lib/nest/model/delete.model.function.js.map +0 -1
  262. package/src/lib/nest/model/index.js +0 -11
  263. package/src/lib/nest/model/index.js.map +0 -1
  264. package/src/lib/nest/model/permission.error.js +0 -24
  265. package/src/lib/nest/model/permission.error.js.map +0 -1
  266. package/src/lib/nest/model/read.model.function.js +0 -27
  267. package/src/lib/nest/model/read.model.function.js.map +0 -1
  268. package/src/lib/nest/model/specifier.function.js +0 -35
  269. package/src/lib/nest/model/specifier.function.js.map +0 -1
  270. package/src/lib/nest/model/update.model.function.js +0 -27
  271. package/src/lib/nest/model/update.model.function.js.map +0 -1
  272. package/src/lib/nest/nest.provider.js +0 -89
  273. package/src/lib/nest/nest.provider.js.map +0 -1
  274. package/src/lib/nest/storage/index.js +0 -5
  275. package/src/lib/nest/storage/index.js.map +0 -1
  276. package/src/lib/nest/storage/storage.module.js +0 -112
  277. package/src/lib/nest/storage/storage.module.js.map +0 -1
  278. package/src/lib/storage/driver.accessor.js +0 -299
  279. package/src/lib/storage/driver.accessor.js.map +0 -1
  280. package/src/lib/storage/driver.js +0 -12
  281. package/src/lib/storage/driver.js.map +0 -1
  282. package/src/lib/storage/index.js +0 -8
  283. package/src/lib/storage/index.js.map +0 -1
  284. package/src/lib/storage/storage.js +0 -20
  285. package/src/lib/storage/storage.js.map +0 -1
  286. package/src/lib/storage/storage.service.js +0 -26
  287. package/src/lib/storage/storage.service.js.map +0 -1
  288. package/test/src/index.js +0 -5
  289. package/test/src/index.js.map +0 -1
  290. package/test/src/lib/firebase/firebase.admin.auth.js +0 -260
  291. package/test/src/lib/firebase/firebase.admin.auth.js.map +0 -1
  292. package/test/src/lib/firebase/firebase.admin.collection.js +0 -108
  293. package/test/src/lib/firebase/firebase.admin.collection.js.map +0 -1
  294. package/test/src/lib/firebase/firebase.admin.function.js +0 -132
  295. package/test/src/lib/firebase/firebase.admin.function.js.map +0 -1
  296. package/test/src/lib/firebase/firebase.admin.js +0 -174
  297. package/test/src/lib/firebase/firebase.admin.js.map +0 -1
  298. package/test/src/lib/firebase/firebase.admin.nest.function.callable.context.js +0 -42
  299. package/test/src/lib/firebase/firebase.admin.nest.function.callable.context.js.map +0 -1
  300. package/test/src/lib/firebase/firebase.admin.nest.function.cloud.context.js +0 -40
  301. package/test/src/lib/firebase/firebase.admin.nest.function.cloud.context.js.map +0 -1
  302. package/test/src/lib/firebase/firebase.admin.nest.function.js +0 -64
  303. package/test/src/lib/firebase/firebase.admin.nest.function.js.map +0 -1
  304. package/test/src/lib/firebase/firebase.admin.nest.js +0 -107
  305. package/test/src/lib/firebase/firebase.admin.nest.js.map +0 -1
  306. package/test/src/lib/firebase/firebase.admin.test.server.js +0 -37
  307. package/test/src/lib/firebase/firebase.admin.test.server.js.map +0 -1
  308. package/test/src/lib/firebase/firebase.function.js +0 -58
  309. package/test/src/lib/firebase/firebase.function.js.map +0 -1
  310. package/test/src/lib/firebase/firebase.jest.d.ts +0 -21
  311. package/test/src/lib/firebase/firebase.jest.js +0 -45
  312. package/test/src/lib/firebase/firebase.jest.js.map +0 -1
  313. package/test/src/lib/firebase/firebase.js +0 -74
  314. package/test/src/lib/firebase/firebase.js.map +0 -1
  315. package/test/src/lib/firebase/index.js +0 -15
  316. package/test/src/lib/firebase/index.js.map +0 -1
  317. package/test/src/lib/firestore/firestore.admin.js +0 -21
  318. package/test/src/lib/firestore/firestore.admin.js.map +0 -1
  319. package/test/src/lib/firestore/firestore.js +0 -57
  320. package/test/src/lib/firestore/firestore.js.map +0 -1
  321. package/test/src/lib/firestore/index.js +0 -6
  322. package/test/src/lib/firestore/index.js.map +0 -1
  323. package/test/src/lib/index.js +0 -7
  324. package/test/src/lib/index.js.map +0 -1
  325. package/test/src/lib/storage/index.js +0 -6
  326. package/test/src/lib/storage/index.js.map +0 -1
  327. package/test/src/lib/storage/storage.admin.js +0 -21
  328. package/test/src/lib/storage/storage.admin.js.map +0 -1
  329. package/test/src/lib/storage/storage.js +0 -59
  330. package/test/src/lib/storage/storage.js.map +0 -1
  331. /package/{zoho/index.cjs.d.ts → index.d.ts} +0 -0
  332. /package/{zoho/index.esm.d.ts → mailgun/index.d.ts} +0 -0
@@ -1,1487 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SEND_QUEUE_NOTIFICATIONS_TASK_EXCESS_THRESHOLD = exports.NOTIFICATION_TASK_TYPE_FAILURE_DELAY_MS = exports.NOTIFICATION_TASK_TYPE_FAILURE_DELAY_HOURS = exports.NOTIFICATION_TASK_TYPE_MAX_SEND_ATTEMPTS = exports.NOTIFICATION_TASK_MINIMUM_SET_AT_THROTTLE_TIME_MINUTES = exports.NOTIFICATION_BOX_NOT_INITIALIZED_DELAY_MINUTES = exports.NOTIFICATION_MAX_SEND_ATTEMPTS = exports.KNOWN_BUT_UNCONFIGURED_NOTIFICATION_TEMPLATE_TYPE_DELETE_AFTER_RETRY_ATTEMPTS = exports.KNOWN_BUT_UNCONFIGURED_NOTIFICATION_TEMPLATE_TYPE_HOURS_DELAY = exports.UNKNOWN_NOTIFICATION_TASK_TYPE_DELETE_AFTER_RETRY_ATTEMPTS = exports.UNKNOWN_NOTIFICATION_TASK_TYPE_HOURS_DELAY = exports.UNKNOWN_NOTIFICATION_TEMPLATE_TYPE_DELETE_AFTER_RETRY_ATTEMPTS = exports.UNKNOWN_NOTIFICATION_TEMPLATE_TYPE_HOURS_DELAY = exports.NotificationServerActions = exports.NOTIFICATION_SERVER_ACTION_CONTEXT_TOKEN = exports.BASE_NOTIFICATION_SERVER_ACTION_CONTEXT_TOKEN = void 0;
4
- exports.notificationServerActions = notificationServerActions;
5
- exports.createNotificationUserFactory = createNotificationUserFactory;
6
- exports.updateNotificationUserFactory = updateNotificationUserFactory;
7
- exports.resyncNotificationUserFactory = resyncNotificationUserFactory;
8
- exports.resyncAllNotificationUsersFactory = resyncAllNotificationUsersFactory;
9
- exports.createNotificationSummaryFactory = createNotificationSummaryFactory;
10
- exports.updateNotificationSummaryFactory = updateNotificationSummaryFactory;
11
- exports.createNotificationBoxInTransactionFactory = createNotificationBoxInTransactionFactory;
12
- exports.createNotificationBoxFactory = createNotificationBoxFactory;
13
- exports.updateNotificationBoxFactory = updateNotificationBoxFactory;
14
- exports.updateNotificationBoxRecipientExclusionInTransactionFactory = updateNotificationBoxRecipientExclusionInTransactionFactory;
15
- exports.updateNotificationBoxRecipientInTransactionFactory = updateNotificationBoxRecipientInTransactionFactory;
16
- exports.updateNotificationBoxRecipientFactory = updateNotificationBoxRecipientFactory;
17
- exports.sendNotificationFactory = sendNotificationFactory;
18
- exports.sendQueuedNotificationsFactory = sendQueuedNotificationsFactory;
19
- exports.cleanupSentNotificationsFactory = cleanupSentNotificationsFactory;
20
- const date_1 = require("@dereekb/date");
21
- const firebase_1 = require("@dereekb/firebase");
22
- const firebase_server_1 = require("@dereekb/firebase-server");
23
- const util_1 = require("@dereekb/util");
24
- const date_fns_1 = require("date-fns");
25
- const notification_error_1 = require("./notification.error");
26
- const notification_util_1 = require("./notification.util");
27
- const notification_task_service_util_1 = require("./notification.task.service.util");
28
- /**
29
- * Injection token for the BaseNotificationServerActionsContext
30
- */
31
- exports.BASE_NOTIFICATION_SERVER_ACTION_CONTEXT_TOKEN = 'BASE_NOTIFICATION_SERVER_ACTION_CONTEXT';
32
- /**
33
- * Injection token for the NotificationServerActionsContext
34
- */
35
- exports.NOTIFICATION_SERVER_ACTION_CONTEXT_TOKEN = 'NOTIFICATION_SERVER_ACTION_CONTEXT';
36
- class NotificationServerActions {
37
- }
38
- exports.NotificationServerActions = NotificationServerActions;
39
- function notificationServerActions(context) {
40
- return {
41
- createNotificationUser: createNotificationUserFactory(context),
42
- updateNotificationUser: updateNotificationUserFactory(context),
43
- resyncNotificationUser: resyncNotificationUserFactory(context),
44
- resyncAllNotificationUsers: resyncAllNotificationUsersFactory(context),
45
- createNotificationSummary: createNotificationSummaryFactory(context),
46
- updateNotificationSummary: updateNotificationSummaryFactory(context),
47
- createNotificationBox: createNotificationBoxFactory(context),
48
- updateNotificationBox: updateNotificationBoxFactory(context),
49
- updateNotificationBoxRecipient: updateNotificationBoxRecipientFactory(context),
50
- sendNotification: sendNotificationFactory(context),
51
- sendQueuedNotifications: sendQueuedNotificationsFactory(context),
52
- cleanupSentNotifications: cleanupSentNotificationsFactory(context)
53
- };
54
- }
55
- // MARK: Actions
56
- function createNotificationUserFactory(context) {
57
- const { firebaseServerActionTransformFunctionFactory, notificationUserCollection, authService } = context;
58
- return firebaseServerActionTransformFunctionFactory(firebase_1.CreateNotificationUserParams, async (params) => {
59
- const { uid } = params;
60
- return async () => {
61
- // assert they exist in the auth system
62
- const userContext = authService.userContext(uid);
63
- const userExistsInAuth = await userContext.exists();
64
- if (!userExistsInAuth) {
65
- throw (0, notification_error_1.notificationUserInvalidUidForCreateError)(uid);
66
- }
67
- const notificationUserDocument = notificationUserCollection.documentAccessor().loadDocumentForId(uid);
68
- const newUserTemplate = {
69
- uid,
70
- x: [],
71
- bc: [],
72
- b: [],
73
- dc: {
74
- c: {}
75
- },
76
- gc: {
77
- c: {}
78
- }
79
- };
80
- await notificationUserDocument.create(newUserTemplate);
81
- return notificationUserDocument;
82
- };
83
- });
84
- }
85
- function updateNotificationUserFactory(context) {
86
- const { firestoreContext, firebaseServerActionTransformFunctionFactory, notificationUserCollection, appNotificationTemplateTypeInfoRecordService } = context;
87
- return firebaseServerActionTransformFunctionFactory(firebase_1.UpdateNotificationUserParams, async (params) => {
88
- const { gc: inputGc, dc: inputDc, bc: inputBc } = params;
89
- return async (notificationUserDocument) => {
90
- await firestoreContext.runTransaction(async (transaction) => {
91
- const notificationUserDocumentInTransaction = notificationUserCollection.documentAccessorForTransaction(transaction).loadDocumentFrom(notificationUserDocument);
92
- const notificationUser = await (0, firebase_server_1.assertSnapshotData)(notificationUserDocumentInTransaction);
93
- const updateTemplate = {};
94
- const allKnownNotificationTypes = appNotificationTemplateTypeInfoRecordService.getAllKnownTemplateTypes();
95
- if (inputDc != null) {
96
- updateTemplate.dc = (0, firebase_1.updateNotificationUserDefaultNotificationBoxRecipientConfig)(notificationUser.dc, inputDc, allKnownNotificationTypes);
97
- }
98
- if (inputGc != null) {
99
- const nextGc = (0, firebase_1.updateNotificationUserDefaultNotificationBoxRecipientConfig)(notificationUser.gc, inputGc, allKnownNotificationTypes);
100
- if (!(0, util_1.areEqualPOJOValues)(notificationUser.gc, nextGc)) {
101
- updateTemplate.gc = nextGc;
102
- // iterate and update any box config that has the effective recipient change
103
- updateTemplate.bc = notificationUser.bc.map((currentConfig) => {
104
- // check item isn't already marked for sync or marked as removed
105
- if (currentConfig.ns === true || currentConfig.rm === true) {
106
- return currentConfig;
107
- }
108
- const currentEffectiveRecipient = (0, firebase_1.effectiveNotificationBoxRecipientConfig)({
109
- uid: notificationUser.uid,
110
- appNotificationTemplateTypeInfoRecordService,
111
- gc: notificationUser.gc,
112
- boxConfig: currentConfig
113
- });
114
- const nextEffectiveRecipient = (0, firebase_1.effectiveNotificationBoxRecipientConfig)({
115
- uid: notificationUser.uid,
116
- appNotificationTemplateTypeInfoRecordService,
117
- gc: nextGc,
118
- boxConfig: currentConfig
119
- });
120
- const effectiveConfigChanged = !(0, util_1.areEqualPOJOValues)(currentEffectiveRecipient, nextEffectiveRecipient);
121
- return effectiveConfigChanged ? { ...currentConfig, ns: true } : currentConfig;
122
- });
123
- }
124
- }
125
- if (inputBc != null) {
126
- const updateTemplateBc = (0, firebase_1.updateNotificationUserNotificationBoxRecipientConfigs)(updateTemplate.bc ?? notificationUser.bc, inputBc, appNotificationTemplateTypeInfoRecordService);
127
- if (updateTemplateBc != null) {
128
- // re-apply exclusions to the updated configs
129
- const withExclusions = (0, firebase_1.applyExclusionsToNotificationUserNotificationBoxRecipientConfigs)({
130
- notificationUser,
131
- bc: updateTemplateBc,
132
- recalculateNs: false
133
- });
134
- updateTemplate.bc = withExclusions.bc;
135
- updateTemplate.b = updateTemplateBc.map((x) => x.nb);
136
- }
137
- }
138
- // if bc is being updated, then also update ns
139
- if (updateTemplate.bc != null) {
140
- updateTemplate.ns = (0, firebase_1.calculateNsForNotificationUserNotificationBoxRecipientConfigs)(updateTemplate.bc);
141
- }
142
- await notificationUserDocumentInTransaction.update(updateTemplate);
143
- });
144
- return notificationUserDocument;
145
- };
146
- });
147
- }
148
- const MAX_NOTIFICATION_BOXES_TO_UPDATE_PER_BATCH = 50;
149
- function resyncNotificationUserFactory(context) {
150
- const { firestoreContext, firebaseServerActionTransformFunctionFactory, notificationBoxCollection, notificationUserCollection, appNotificationTemplateTypeInfoRecordService } = context;
151
- return firebaseServerActionTransformFunctionFactory(firebase_1.ResyncNotificationUserParams, async () => {
152
- return async (notificationUserDocument) => {
153
- // run updates in batches
154
- let notificationBoxesUpdated = 0;
155
- let hasMoreNotificationBoxesToSync = true;
156
- while (hasMoreNotificationBoxesToSync) {
157
- const batchResult = await firestoreContext.runTransaction(async (transaction) => {
158
- const notificationUserDocumentInTransaction = notificationUserCollection.documentAccessorForTransaction(transaction).loadDocumentFrom(notificationUserDocument);
159
- const notificationUser = await (0, firebase_server_1.assertSnapshotData)(notificationUserDocumentInTransaction);
160
- const { gc } = notificationUser;
161
- const notificationBoxConfigsToSync = notificationUser.bc.filter((x) => x.ns);
162
- const notificationBoxConfigsToSyncInThisBatch = (0, util_1.takeFront)(notificationBoxConfigsToSync, MAX_NOTIFICATION_BOXES_TO_UPDATE_PER_BATCH);
163
- /**
164
- * These are the actual number of NotificationBox values that had recipients updated.
165
- */
166
- let notificationBoxesUpdatedInBatch = 0;
167
- let hasUnsyncedNotificationBoxConfigs = false;
168
- if (notificationBoxConfigsToSyncInThisBatch.length > 0) {
169
- const notificationBoxConfigsToSyncInThisBatchMap = (0, util_1.makeModelMap)(notificationBoxConfigsToSyncInThisBatch, (x) => x.nb);
170
- const notificationBoxIdsToSyncInThisBatch = Array.from(notificationBoxConfigsToSyncInThisBatchMap.keys());
171
- const notificationBoxDocuments = (0, firebase_1.loadDocumentsForIds)(notificationBoxCollection.documentAccessorForTransaction(transaction), notificationBoxIdsToSyncInThisBatch);
172
- const notificationBoxDocumentSnapshotDataPairs = await (0, firebase_1.getDocumentSnapshotDataPairs)(notificationBoxDocuments);
173
- const notificationBoxConfigsToRemoveFromNotificationUser = new Set();
174
- const notificationUserNotificationBoxConfigsToMarkAsRemoved = new Set();
175
- const nextRecipientsMap = new Map();
176
- // update each NotificationBoxDocument
177
- await (0, util_1.performAsyncTasks)(notificationBoxDocumentSnapshotDataPairs, async (notificationBoxDocumentSnapshotDataPair) => {
178
- const { data: notificationBox, document } = notificationBoxDocumentSnapshotDataPair;
179
- const nb = document.id;
180
- const notificationUserNotificationBoxConfig = notificationBoxConfigsToSyncInThisBatchMap.get(nb); // always exists
181
- if (!notificationBox) {
182
- // if the entire NotificationBox no longer exists, flag to remove it from the user as a cleanup measure
183
- notificationBoxConfigsToRemoveFromNotificationUser.add(nb);
184
- }
185
- else {
186
- // update in the NotificationBox
187
- const recipientIndex = notificationBox.r.findIndex((x) => x.uid === notificationUser.uid);
188
- let r;
189
- if (recipientIndex === -1) {
190
- // if they are not in the NotificationBox, then mark them as removed on the user
191
- notificationUserNotificationBoxConfigsToMarkAsRemoved.add(nb);
192
- }
193
- else if (notificationUserNotificationBoxConfig.rm) {
194
- // remove from the notification box if it is flagged
195
- r = (0, util_1.removeValuesAtIndexesFromArrayCopy)(notificationBox.r, recipientIndex);
196
- }
197
- else {
198
- const { m } = notificationBox;
199
- const recipient = notificationBox.r[recipientIndex];
200
- const nextRecipient = (0, firebase_1.effectiveNotificationBoxRecipientConfig)({
201
- uid: notificationUser.uid,
202
- m,
203
- appNotificationTemplateTypeInfoRecordService,
204
- gc,
205
- boxConfig: notificationUserNotificationBoxConfig,
206
- recipient
207
- });
208
- const recipientHasChange = !(0, util_1.areEqualPOJOValues)(nextRecipient, recipient);
209
- // only update recipients if the next/new recipient is not equal to the existing one
210
- if (recipientHasChange) {
211
- r = [...notificationBox.r];
212
- r[recipientIndex] = nextRecipient;
213
- nextRecipientsMap.set(nb, nextRecipient);
214
- }
215
- else {
216
- nextRecipientsMap.set(nb, recipient);
217
- }
218
- }
219
- // update recipients if needed
220
- if (r != null) {
221
- await document.update({ r });
222
- notificationBoxesUpdatedInBatch += 1;
223
- }
224
- }
225
- });
226
- // Update the NotificationUser
227
- const notificationBoxIdsSynced = new Set(notificationBoxIdsToSyncInThisBatch);
228
- // start nextConfigs off as a new array with none of the sync'd ids
229
- const nextConfigs = notificationBoxConfigsToSyncInThisBatch.filter((x) => !notificationBoxIdsSynced.has(x.nb));
230
- notificationBoxIdsToSyncInThisBatch.forEach((nb) => {
231
- let nextConfig;
232
- if (notificationBoxConfigsToRemoveFromNotificationUser.has(nb)) {
233
- // do nothing, as it should be removed
234
- }
235
- else {
236
- const existingConfig = notificationBoxConfigsToSyncInThisBatchMap.get(nb);
237
- if (notificationUserNotificationBoxConfigsToMarkAsRemoved.has(nb) || existingConfig.rm) {
238
- // if the recipient was being removed or is marked as removed, then update the config to confirm removal
239
- nextConfig = {
240
- ...existingConfig,
241
- nb,
242
- rm: true,
243
- i: util_1.UNSET_INDEX_NUMBER
244
- };
245
- }
246
- else {
247
- // else, use the updated recipient and keep/copy the
248
- const updatedRecipient = nextRecipientsMap.get(nb);
249
- nextConfig = {
250
- ...existingConfig,
251
- nb,
252
- rm: false, // mark as not removed
253
- i: updatedRecipient.i ?? util_1.UNSET_INDEX_NUMBER
254
- };
255
- }
256
- }
257
- if (nextConfig != null) {
258
- nextConfig.ns = false; // mark as synced
259
- nextConfigs.push(nextConfig);
260
- }
261
- });
262
- const ns = nextConfigs.some((x) => x.ns);
263
- await notificationUserDocumentInTransaction.update({ bc: nextConfigs, ns });
264
- hasUnsyncedNotificationBoxConfigs = ns;
265
- }
266
- const batchResult = {
267
- hasMoreNotificationBoxesToSync: hasUnsyncedNotificationBoxConfigs,
268
- notificationBoxesUpdatedInBatch
269
- };
270
- return batchResult;
271
- });
272
- hasMoreNotificationBoxesToSync = batchResult.hasMoreNotificationBoxesToSync;
273
- notificationBoxesUpdated += batchResult.notificationBoxesUpdatedInBatch;
274
- }
275
- const result = {
276
- notificationBoxesUpdated
277
- };
278
- return result;
279
- };
280
- });
281
- }
282
- function resyncAllNotificationUsersFactory(context) {
283
- const { notificationUserCollection } = context;
284
- const resyncNotificationUser = resyncNotificationUserFactory(context);
285
- return async () => {
286
- let notificationBoxesUpdated = 0;
287
- const resyncNotificationUserParams = { key: (0, firebase_1.firestoreDummyKey)() };
288
- const resyncNotificationUserInstance = await resyncNotificationUser(resyncNotificationUserParams);
289
- const iterateResult = await (0, firebase_1.iterateFirestoreDocumentSnapshotPairs)({
290
- documentAccessor: notificationUserCollection.documentAccessor(),
291
- iterateSnapshotPair: async (snapshotPair) => {
292
- const { document: notificationUserDocument } = snapshotPair;
293
- const result = await resyncNotificationUserInstance(notificationUserDocument);
294
- notificationBoxesUpdated += result.notificationBoxesUpdated;
295
- },
296
- constraintsFactory: () => (0, firebase_1.notificationUsersFlaggedForNeedsSyncQuery)(),
297
- snapshotsPerformTasksConfig: {
298
- // prevent NotificationUsers with the same NotificationBoxes from being updated/sync'd at the same time
299
- nonConcurrentTaskKeyFactory: (x) => {
300
- const notificationBoxIdsToSync = x
301
- .data()
302
- .bc.filter((x) => x.ns)
303
- .map((x) => x.nb);
304
- return notificationBoxIdsToSync;
305
- }
306
- },
307
- queryFactory: notificationUserCollection,
308
- batchSize: undefined,
309
- performTasksConfig: {
310
- maxParallelTasks: 10
311
- }
312
- });
313
- const result = {
314
- notificationUsersResynced: iterateResult.totalSnapshotsVisited,
315
- notificationBoxesUpdated
316
- };
317
- return result;
318
- };
319
- }
320
- function createNotificationSummaryFactory(context) {
321
- const { firebaseServerActionTransformFunctionFactory, notificationSummaryCollection } = context;
322
- return firebaseServerActionTransformFunctionFactory(firebase_1.CreateNotificationSummaryParams, async (params) => {
323
- const { model } = params;
324
- return async () => {
325
- const notificationSummaryId = (0, firebase_1.notificationSummaryIdForModel)(model);
326
- const notificationSummaryDocument = notificationSummaryCollection.documentAccessor().loadDocumentForId(notificationSummaryId);
327
- const newSummaryTemplate = (0, notification_util_1.makeNewNotificationSummaryTemplate)(model);
328
- await notificationSummaryDocument.create(newSummaryTemplate);
329
- return notificationSummaryDocument;
330
- };
331
- });
332
- }
333
- function updateNotificationSummaryFactory(context) {
334
- const { firebaseServerActionTransformFunctionFactory } = context;
335
- return firebaseServerActionTransformFunctionFactory(firebase_1.UpdateNotificationSummaryParams, async (params) => {
336
- const { setReadAtTime, flagAllRead } = params;
337
- return async (notificationSummaryDocument) => {
338
- let updateTemplate;
339
- if (setReadAtTime != null) {
340
- updateTemplate = { rat: setReadAtTime };
341
- }
342
- else if (flagAllRead === true) {
343
- updateTemplate = { rat: new Date() };
344
- }
345
- if (updateTemplate != null) {
346
- await notificationSummaryDocument.update(updateTemplate);
347
- }
348
- return notificationSummaryDocument;
349
- };
350
- });
351
- }
352
- function createNotificationBoxInTransactionFactory(context) {
353
- const { notificationBoxCollection } = context;
354
- return async (params, transaction) => {
355
- const { now: inputNow, skipCreate } = params;
356
- const now = inputNow ?? new Date();
357
- const notificationBoxDocument = (0, firebase_1.loadNotificationBoxDocumentForReferencePair)(params, notificationBoxCollection.documentAccessorForTransaction(transaction));
358
- const notificationBoxTemplate = {
359
- m: notificationBoxDocument.notificationBoxRelatedModelKey,
360
- o: (0, firebase_1.firestoreDummyKey)(), // set during initialization
361
- r: [],
362
- cat: now,
363
- w: (0, date_1.yearWeekCode)(now),
364
- s: true // requires initialization
365
- };
366
- if (!skipCreate) {
367
- await notificationBoxDocument.create(notificationBoxTemplate);
368
- }
369
- return {
370
- notificationBoxTemplate,
371
- notificationBoxDocument
372
- };
373
- };
374
- }
375
- function createNotificationBoxFactory(context) {
376
- const { firestoreContext, notificationBoxCollection, firebaseServerActionTransformFunctionFactory } = context;
377
- const createNotificationBoxInTransaction = createNotificationBoxInTransactionFactory(context);
378
- return firebaseServerActionTransformFunctionFactory(firebase_1.CreateNotificationBoxParams, async (params) => {
379
- const { model } = params;
380
- return async () => {
381
- const result = await firestoreContext.runTransaction(async (transaction) => {
382
- const { notificationBoxDocument } = await createNotificationBoxInTransaction({ notificationBoxRelatedModelKey: model }, transaction);
383
- return notificationBoxDocument;
384
- });
385
- return notificationBoxCollection.documentAccessor().loadDocumentFrom(result);
386
- };
387
- });
388
- }
389
- function updateNotificationBoxFactory({ firebaseServerActionTransformFunctionFactory }) {
390
- return firebaseServerActionTransformFunctionFactory(firebase_1.UpdateNotificationBoxParams, async () => {
391
- return async (notificationBoxDocument) => {
392
- // does nothing currently.
393
- return notificationBoxDocument;
394
- };
395
- });
396
- }
397
- function updateNotificationBoxRecipientExclusionInTransactionFactory(context) {
398
- const { notificationBoxCollection, notificationUserCollection } = context;
399
- return async (input, transaction) => {
400
- const { params } = input;
401
- const { uid: inputUid, i, setExclusion } = params;
402
- const notificationBoxDocument = (0, firebase_1.loadNotificationBoxDocumentForReferencePair)(input, notificationBoxCollection.documentAccessorForTransaction(transaction));
403
- let targetUid = inputUid;
404
- let result = undefined;
405
- if (setExclusion == null) {
406
- throw new Error('setExclusion was undefined. Maybe you wanted to call updateNotificationBoxRecipientInTransactionFactory() instead?');
407
- }
408
- else if (!inputUid && i != null) {
409
- // only load the notification box if targeting a recipient by index
410
- const notificationBox = await notificationBoxDocument.snapshotData();
411
- if (!notificationBox) {
412
- throw (0, notification_error_1.notificationBoxExclusionTargetInvalidError)();
413
- }
414
- const targetRecipient = notificationBox.r.find((x) => x.i === i);
415
- if (!targetRecipient || !targetRecipient.uid) {
416
- throw (0, notification_error_1.notificationBoxExclusionTargetInvalidError)();
417
- }
418
- else {
419
- targetUid = targetRecipient.uid;
420
- }
421
- }
422
- if (!targetUid) {
423
- throw (0, notification_error_1.notificationBoxExclusionTargetInvalidError)();
424
- }
425
- const notificationUserDocument = await notificationUserCollection.documentAccessorForTransaction(transaction).loadDocumentForId(targetUid);
426
- const notificationUser = await notificationUserDocument.snapshotData();
427
- if (notificationUser) {
428
- // only update if the user exists
429
- const targetExclusions = [notificationBoxDocument.id];
430
- const { update: notificationUserUpdate } = (0, firebase_1.updateNotificationUserNotificationSendExclusions)({
431
- notificationUser,
432
- addExclusions: setExclusion ? targetExclusions : undefined,
433
- removeExclusions: setExclusion ? undefined : targetExclusions
434
- });
435
- await notificationUserDocument.update(notificationUserUpdate);
436
- result = {
437
- notificationUserUpdate
438
- };
439
- }
440
- return result;
441
- };
442
- }
443
- function updateNotificationBoxRecipientInTransactionFactory(context) {
444
- const { authService, notificationBoxCollection, notificationUserCollection } = context;
445
- const createNotificationBoxInTransaction = createNotificationBoxInTransactionFactory(context);
446
- return async (input, transaction) => {
447
- const { params, allowCreateNotificationBoxIfItDoesNotExist, throwErrorIfNotificationBoxDoesNotExist } = input;
448
- const { uid, i, insert, remove, configs: inputC, setExclusion } = params;
449
- const findRecipientFn = (x) => (uid != null && x.uid === uid) || (i != null && x.i === i);
450
- if (setExclusion != null) {
451
- throw new Error('exclusion update must be processed by updateNotificationBoxRecipientExclusionInTransactionFactory() function.');
452
- }
453
- const notificationBoxDocument = (0, firebase_1.loadNotificationBoxDocumentForReferencePair)(input, notificationBoxCollection.documentAccessorForTransaction(transaction));
454
- let notificationBox = await notificationBoxDocument.snapshotData();
455
- let createNotificationBox = false;
456
- let result = undefined;
457
- if (!notificationBox) {
458
- if (allowCreateNotificationBoxIfItDoesNotExist) {
459
- const { notificationBoxTemplate } = await createNotificationBoxInTransaction({
460
- notificationBoxDocument,
461
- skipCreate: true // don't create since we still need to read things for the transaction
462
- }, transaction);
463
- notificationBox = notificationBoxTemplate;
464
- createNotificationBox = true;
465
- }
466
- else if (throwErrorIfNotificationBoxDoesNotExist) {
467
- throw (0, notification_error_1.notificationBoxDoesNotExist)();
468
- }
469
- }
470
- if (notificationBox) {
471
- const { m } = notificationBox;
472
- let r;
473
- let targetRecipientIndex = notificationBox.r.findIndex(findRecipientFn);
474
- const targetRecipient = notificationBox.r[targetRecipientIndex];
475
- let nextRecipient;
476
- if (remove) {
477
- if (targetRecipientIndex != null) {
478
- r = [...notificationBox.r]; // remove if they exist.
479
- delete r[targetRecipientIndex];
480
- }
481
- }
482
- else {
483
- if (!targetRecipient && !insert) {
484
- throw (0, notification_error_1.notificationBoxRecipientDoesNotExistsError)();
485
- }
486
- const c = (inputC != null ? (0, firebase_1.notificationBoxRecipientTemplateConfigArrayToRecord)(inputC) : targetRecipient?.c) ?? {};
487
- nextRecipient = {
488
- uid,
489
- i: targetRecipient?.i ?? util_1.UNSET_INDEX_NUMBER,
490
- c,
491
- ...(0, firebase_1.updateNotificationRecipient)(targetRecipient ?? {}, params)
492
- };
493
- r = [...notificationBox.r];
494
- if (targetRecipient) {
495
- nextRecipient.i = targetRecipient.i;
496
- nextRecipient = (0, firebase_1.mergeNotificationBoxRecipients)(targetRecipient, nextRecipient);
497
- r[targetRecipientIndex] = nextRecipient; // override in the array
498
- }
499
- else {
500
- const nextI = (0, util_1.computeNextFreeIndexOnSortedValuesFunction)(util_1.readIndexNumber)(notificationBox.r); // r is sorted by index in ascending order, so the last value is the largest i
501
- nextRecipient.i = nextI;
502
- // should have the greatest i value, push to end
503
- r.push(nextRecipient);
504
- targetRecipientIndex = r.length - 1;
505
- }
506
- }
507
- // save changes to r if it has changed
508
- if (r != null) {
509
- const notificationUserId = targetRecipient?.uid ?? nextRecipient?.uid;
510
- // sync with the notification user's document, if it exists
511
- if (notificationUserId != null) {
512
- const notificationBoxId = notificationBoxDocument.id;
513
- const notificationUserDocument = await notificationUserCollection.documentAccessorForTransaction(transaction).loadDocumentForId(notificationUserId);
514
- let notificationUser = await notificationUserDocument.snapshotData();
515
- const createNotificationUser = !notificationUser && !remove && insert;
516
- if (createNotificationUser) {
517
- // assert they exist in the auth system
518
- const userContext = authService.userContext(notificationUserId);
519
- const userExistsInAuth = await userContext.exists();
520
- if (!userExistsInAuth) {
521
- throw (0, notification_error_1.notificationUserInvalidUidForCreateError)(notificationUserId);
522
- }
523
- const notificationUserTemplate = {
524
- uid: notificationUserId,
525
- b: [],
526
- x: [],
527
- bc: [],
528
- ns: false,
529
- dc: {
530
- c: {}
531
- },
532
- gc: {
533
- c: {}
534
- }
535
- };
536
- notificationUser = notificationUserTemplate;
537
- }
538
- // if the user is being inserted or exists, then make updates
539
- if (notificationUser != null) {
540
- const { updatedBc, updatedNotificationBoxRecipient } = (0, notification_util_1.updateNotificationUserNotificationBoxRecipientConfig)({
541
- notificationBoxId,
542
- notificationUserId,
543
- notificationBoxAssociatedModelKey: m,
544
- notificationUser,
545
- insertingRecipientIntoNotificationBox: insert,
546
- removeRecipientFromNotificationBox: remove,
547
- notificationBoxRecipient: nextRecipient
548
- });
549
- const updatedB = updatedBc ? updatedBc.map((x) => x.nb) : undefined;
550
- if (createNotificationUser) {
551
- const newUserTemplate = {
552
- ...notificationUser,
553
- bc: updatedBc ?? [],
554
- b: updatedB ?? []
555
- };
556
- await notificationUserDocument.create(newUserTemplate);
557
- }
558
- else if (updatedBc != null) {
559
- await notificationUserDocument.update({ bc: updatedBc, b: updatedB });
560
- }
561
- // Set if nextRecipient is updated/influence from existing configuration
562
- if (targetRecipientIndex != null && updatedNotificationBoxRecipient && !remove) {
563
- r[targetRecipientIndex] = updatedNotificationBoxRecipient; // set the updated value in r
564
- }
565
- }
566
- // else, if removing and they don't exist, nothing to update
567
- }
568
- const updatedNotificationBox = { ...notificationBox, r };
569
- let notificationBoxWasCreated = false;
570
- if (createNotificationBox) {
571
- await notificationBoxDocument.create(updatedNotificationBox);
572
- notificationBoxWasCreated = true;
573
- }
574
- else {
575
- await notificationBoxDocument.update({ r });
576
- }
577
- result = {
578
- updatedNotificationBox,
579
- notificationBoxWasCreated,
580
- notificationBoxDocument
581
- };
582
- }
583
- }
584
- return result;
585
- };
586
- }
587
- function updateNotificationBoxRecipientFactory(context) {
588
- const { firestoreContext, firebaseServerActionTransformFunctionFactory } = context;
589
- const updateNotificationBoxRecipientInTransaction = updateNotificationBoxRecipientInTransactionFactory(context);
590
- const updateNotificationBoxRecipientExclusionInTransaction = updateNotificationBoxRecipientExclusionInTransactionFactory(context);
591
- return firebaseServerActionTransformFunctionFactory(firebase_1.UpdateNotificationBoxRecipientParams, async (params) => {
592
- return async (notificationBoxDocument) => {
593
- await firestoreContext.runTransaction(async (transaction) => {
594
- if (params.setExclusion != null) {
595
- await updateNotificationBoxRecipientExclusionInTransaction({
596
- params,
597
- notificationBoxDocument
598
- }, transaction);
599
- }
600
- else {
601
- await updateNotificationBoxRecipientInTransaction({
602
- params,
603
- throwErrorIfNotificationBoxDoesNotExist: true,
604
- notificationBoxDocument
605
- }, transaction);
606
- }
607
- });
608
- return notificationBoxDocument;
609
- };
610
- });
611
- }
612
- exports.UNKNOWN_NOTIFICATION_TEMPLATE_TYPE_HOURS_DELAY = 8;
613
- exports.UNKNOWN_NOTIFICATION_TEMPLATE_TYPE_DELETE_AFTER_RETRY_ATTEMPTS = 1;
614
- exports.UNKNOWN_NOTIFICATION_TASK_TYPE_HOURS_DELAY = 8;
615
- exports.UNKNOWN_NOTIFICATION_TASK_TYPE_DELETE_AFTER_RETRY_ATTEMPTS = 1;
616
- exports.KNOWN_BUT_UNCONFIGURED_NOTIFICATION_TEMPLATE_TYPE_HOURS_DELAY = exports.UNKNOWN_NOTIFICATION_TEMPLATE_TYPE_HOURS_DELAY;
617
- exports.KNOWN_BUT_UNCONFIGURED_NOTIFICATION_TEMPLATE_TYPE_DELETE_AFTER_RETRY_ATTEMPTS = 5;
618
- exports.NOTIFICATION_MAX_SEND_ATTEMPTS = 5;
619
- exports.NOTIFICATION_BOX_NOT_INITIALIZED_DELAY_MINUTES = 8;
620
- /**
621
- * Minimum time in minutes that a notification task can be attempted again
622
- */
623
- exports.NOTIFICATION_TASK_MINIMUM_SET_AT_THROTTLE_TIME_MINUTES = 1;
624
- exports.NOTIFICATION_TASK_TYPE_MAX_SEND_ATTEMPTS = 5;
625
- exports.NOTIFICATION_TASK_TYPE_FAILURE_DELAY_HOURS = 3;
626
- exports.NOTIFICATION_TASK_TYPE_FAILURE_DELAY_MS = (0, date_fns_1.hoursToMilliseconds)(exports.NOTIFICATION_TASK_TYPE_FAILURE_DELAY_HOURS);
627
- function sendNotificationFactory(context) {
628
- const { appNotificationTemplateTypeInfoRecordService, notificationSendService, notificationTaskService, notificationTemplateService, authService, notificationBoxCollection, notificationCollectionGroup, notificationUserCollection, firestoreContext, firebaseServerActionTransformFunctionFactory } = context;
629
- const createNotificationBoxInTransaction = createNotificationBoxInTransactionFactory(context);
630
- const notificationUserAccessor = notificationUserCollection.documentAccessor();
631
- return firebaseServerActionTransformFunctionFactory(firebase_1.SendNotificationParams, async (params) => {
632
- const { ignoreSendAtThrottle } = params;
633
- return async (inputNotificationDocument) => {
634
- const now = new Date();
635
- // Load the notification document outside of any potential context (transaction, etc.)
636
- const notificationDocument = notificationCollectionGroup.documentAccessor().loadDocumentFrom(inputNotificationDocument);
637
- const { nextSat, throttled, tryRun, isNotificationTask, notificationTaskHandler, notification, createdBox, notificationBoxNeedsInitialization, notificationBox, notificationBoxModelKey, deletedNotification, templateInstance, isConfiguredTemplateType, isKnownTemplateType, onlySendToExplicitlyEnabledRecipients, onlyTextExplicitlyEnabledRecipients } = await firestoreContext.runTransaction(async (transaction) => {
638
- const notificationBoxDocument = notificationBoxCollection.documentAccessorForTransaction(transaction).loadDocument(notificationDocument.parent);
639
- const notificationDocumentInTransaction = notificationCollectionGroup.documentAccessorForTransaction(transaction).loadDocumentFrom(notificationDocument);
640
- let [notificationBox, notification] = await Promise.all([(0, firebase_1.getDocumentSnapshotData)(notificationBoxDocument), (0, firebase_1.getDocumentSnapshotData)(notificationDocumentInTransaction)]);
641
- const model = (0, firebase_1.inferKeyFromTwoWayFlatFirestoreModelKey)(notificationBoxDocument.id);
642
- const isNotificationTask = notification?.st === firebase_1.NotificationSendType.TASK_NOTIFICATION;
643
- let tryRun = true;
644
- let throttled = false;
645
- let nextSat;
646
- if (!notification) {
647
- tryRun = false;
648
- }
649
- else if (!ignoreSendAtThrottle) {
650
- tryRun = !(0, date_fns_1.isFuture)(notification.sat);
651
- if (!tryRun) {
652
- throttled = true;
653
- }
654
- }
655
- // always set nextSat if tryRun is true
656
- if (tryRun) {
657
- if (isNotificationTask) {
658
- // can try to run the task again in 1 minute
659
- nextSat = (0, date_fns_1.addMinutes)(now, exports.NOTIFICATION_TASK_MINIMUM_SET_AT_THROTTLE_TIME_MINUTES);
660
- }
661
- else {
662
- // update the next send type of non-tasks to try being sent again in 10 minutes, if they fail
663
- nextSat = (0, date_fns_1.addMinutes)(now, 10);
664
- }
665
- }
666
- let createdBox = false;
667
- let deletedNotification = false;
668
- let notificationBoxNeedsInitialization = false;
669
- let isKnownTemplateType;
670
- let isConfiguredTemplateType;
671
- let onlySendToExplicitlyEnabledRecipients;
672
- let onlyTextExplicitlyEnabledRecipients;
673
- let templateInstance;
674
- let notificationTaskHandler;
675
- async function deleteNotification() {
676
- tryRun = false;
677
- await notificationDocumentInTransaction.accessor.delete();
678
- deletedNotification = true;
679
- }
680
- // create/init the notification box if necessary/configured.
681
- if (notification && tryRun) {
682
- // if we're still trying to run, check the template is ok. If not, cancel the run.
683
- const { t // notification task/template type
684
- } = notification.n;
685
- if (isNotificationTask) {
686
- notificationTaskHandler = notificationTaskService.taskHandlerForNotificationTaskType(t);
687
- if (notificationTaskHandler) {
688
- if (notification.a >= exports.NOTIFICATION_TASK_TYPE_MAX_SEND_ATTEMPTS) {
689
- tryRun = false;
690
- console.warn(`Configured notification task of type "${t}" has reached the delete threshhold after being attempted ${notification.a} times. Deleting notification task.`);
691
- await deleteNotification();
692
- }
693
- }
694
- else {
695
- tryRun = false;
696
- const delay = exports.UNKNOWN_NOTIFICATION_TASK_TYPE_HOURS_DELAY;
697
- if (notification.a < exports.UNKNOWN_NOTIFICATION_TASK_TYPE_DELETE_AFTER_RETRY_ATTEMPTS) {
698
- console.warn(`Notification task type of "${t}" was found in a Notification but has no handler. Action is being delayed by ${delay} hours.`);
699
- nextSat = (0, date_fns_1.addHours)(now, delay);
700
- }
701
- else {
702
- console.warn(`Notification task type of "${t}" was found in a Notification but has no handler. Action is being deleted.`);
703
- // delete the notification
704
- await deleteNotification();
705
- }
706
- }
707
- }
708
- else {
709
- templateInstance = notificationTemplateService.templateInstanceForType(t);
710
- isConfiguredTemplateType = templateInstance.isConfiguredType;
711
- const templateTypeInfo = appNotificationTemplateTypeInfoRecordService.appNotificationTemplateTypeInfoRecord[t];
712
- isKnownTemplateType = templateTypeInfo != null;
713
- onlySendToExplicitlyEnabledRecipients = notification.ois ?? templateTypeInfo?.onlySendToExplicitlyEnabledRecipients;
714
- onlyTextExplicitlyEnabledRecipients = notification.ots ?? templateTypeInfo?.onlyTextExplicitlyEnabledRecipients;
715
- if (!isConfiguredTemplateType) {
716
- // log the issue that an notification with an unconfigured type was queued
717
- const retryAttempts = isKnownTemplateType ? exports.KNOWN_BUT_UNCONFIGURED_NOTIFICATION_TEMPLATE_TYPE_DELETE_AFTER_RETRY_ATTEMPTS : exports.UNKNOWN_NOTIFICATION_TEMPLATE_TYPE_DELETE_AFTER_RETRY_ATTEMPTS;
718
- const delay = isKnownTemplateType ? exports.KNOWN_BUT_UNCONFIGURED_NOTIFICATION_TEMPLATE_TYPE_HOURS_DELAY : exports.UNKNOWN_NOTIFICATION_TEMPLATE_TYPE_HOURS_DELAY;
719
- if (notification.a < retryAttempts) {
720
- if (isKnownTemplateType) {
721
- console.warn(`Unconfigured but known template type of "${t}" (${templateTypeInfo.name}) was found in a Notification. Send is being delayed by ${delay} hours.`);
722
- }
723
- else {
724
- console.warn(`Unknown template type of "${t}" was found in a Notification. Send is being delayed by ${delay} hours.`);
725
- }
726
- // delay send for 12 hours, for a max of 24 hours incase it is an issue.
727
- nextSat = (0, date_fns_1.addHours)(now, delay);
728
- tryRun = false;
729
- }
730
- else {
731
- console.warn(`Unconfigured template type of "${t}" was found in a Notification. The Notification has reached the delete threshhold after failing to send due to misconfiguration multiple times and is being deleted.`);
732
- // after attempting to send 3 times, delete it.
733
- await deleteNotification();
734
- }
735
- }
736
- // handle the notification box's absence
737
- if (!notificationBox && tryRun) {
738
- switch (notification.st) {
739
- case firebase_1.NotificationSendType.INIT_BOX_AND_SEND:
740
- const { notificationBoxTemplate } = await createNotificationBoxInTransaction({ notificationBoxDocument }, transaction);
741
- notificationBox = (0, firebase_1.setIdAndKeyFromKeyIdRefOnDocumentData)(notificationBoxTemplate, notificationBoxDocument);
742
- createdBox = true;
743
- break;
744
- case firebase_1.NotificationSendType.SEND_IF_BOX_EXISTS:
745
- // delete the notification since it won't get sent.
746
- await deleteNotification();
747
- break;
748
- case firebase_1.NotificationSendType.SEND_WITHOUT_CREATING_BOX:
749
- // continue with current tryRun
750
- break;
751
- }
752
- }
753
- // if the notification box is not initialized/synchronized yet, do not run.
754
- if (tryRun && notificationBox && notificationBox.s) {
755
- notificationBoxNeedsInitialization = true;
756
- tryRun = false;
757
- nextSat = (0, date_fns_1.addMinutes)(now, exports.NOTIFICATION_BOX_NOT_INITIALIZED_DELAY_MINUTES);
758
- }
759
- }
760
- }
761
- // update the notification send at time and attempt count
762
- if (notification != null && nextSat != null && !deletedNotification) {
763
- const isAtMaxAttempts = notification.a >= exports.NOTIFICATION_MAX_SEND_ATTEMPTS;
764
- if (isAtMaxAttempts && notificationBoxNeedsInitialization) {
765
- await deleteNotification(); // just delete the notification if the box still hasn't been initialized successfully at this point.
766
- }
767
- // check if it was just deleted
768
- if (!deletedNotification) {
769
- const a = isNotificationTask && tryRun ? notification.a : notification.a + 1; // do not update a notification task's attempt count here, unless tryRun fails
770
- // NOTE: It is important to update sat so the notification task queue running doesn't get stuck in a query loop by notifications/tasks that have a sat value that is in the past, but was just run.
771
- await notificationDocumentInTransaction.update({ sat: nextSat, a });
772
- }
773
- }
774
- return {
775
- nextSat,
776
- throttled,
777
- isNotificationTask,
778
- deletedNotification,
779
- createdBox,
780
- notificationBoxModelKey: model,
781
- notificationBoxNeedsInitialization,
782
- notificationBox,
783
- notification,
784
- templateInstance,
785
- isKnownTemplateType,
786
- notificationTaskHandler,
787
- isConfiguredTemplateType,
788
- tryRun,
789
- onlySendToExplicitlyEnabledRecipients,
790
- onlyTextExplicitlyEnabledRecipients
791
- };
792
- });
793
- let success = false;
794
- let isUniqueNotificationTask = false;
795
- let uniqueNotificationTaskConflict = false;
796
- let sendEmailsResult;
797
- let sendTextsResult;
798
- let sendNotificationSummaryResult;
799
- let loadMessageFunctionFailure = false;
800
- let buildMessageFailure = false;
801
- let notificationMarkedDone = false;
802
- let notificationTaskCompletionType;
803
- let notificationTaskPartsRunCount = 0;
804
- let notificationTaskLoopingProtectionTriggered;
805
- let onSendAttemptedResult;
806
- let onSendSuccessResult;
807
- const notificationTemplateType = templateInstance?.type;
808
- if (isNotificationTask) {
809
- await handleNotificationTask();
810
- }
811
- else {
812
- await handleNormalNotification();
813
- }
814
- async function _runNotificationTaskNextPart(input) {
815
- const { notification, notificationTaskHandler, previouslyCompleteSubTasks } = input;
816
- const { n: item, cat, ut } = notification;
817
- let tryRunNextPart = false;
818
- let partNotificationTaskCompletionType;
819
- let partNotificationMarkedDone = false;
820
- let partTprReversal = false;
821
- let partSuccess = false;
822
- let nextCompleteSubTasks;
823
- const unique = ut ?? false;
824
- const notificationTask = {
825
- notificationDocument,
826
- totalSendAttempts: notification.a,
827
- currentCheckpointSendAttempts: notification.at ?? 0,
828
- taskType: item.t,
829
- item,
830
- data: item.d,
831
- checkpoints: notification.tpr,
832
- createdAt: cat,
833
- unique
834
- };
835
- // calculate results
836
- const notificationTemplate = {};
837
- // perform the task
838
- try {
839
- const handleTaskResult = await notificationTaskHandler.handleNotificationTask(notificationTask);
840
- const { completion, updateMetadata, delayUntil, canRunNextCheckpoint, allCompletedSubTasks } = handleTaskResult;
841
- partNotificationTaskCompletionType = completion;
842
- partSuccess = true;
843
- switch (completion) {
844
- case true:
845
- notificationTemplate.d = true; // mark as done
846
- break;
847
- case false:
848
- // failed
849
- notificationTemplate.a = notification.a + 1; // increase attempts count
850
- notificationTemplate.at = (notification.at ?? 0) + 1; // increase checkpoint attempts count
851
- // remove any completions, if applicable
852
- notificationTemplate.tpr = (0, notification_task_service_util_1.removeFromCompletionsArrayWithTaskResult)(notification.tpr, handleTaskResult);
853
- partSuccess = false;
854
- break;
855
- default:
856
- // default case called if not true or false, which implies either a delay or partial completion
857
- // update the checkpoint attempts count
858
- if (Array.isArray(completion) && completion.length === 0) {
859
- notificationTemplate.at = (notification.at ?? 0) + 1; // increase checkpoint attempt/delays count
860
- tryRunNextPart = canRunNextCheckpoint === true && allCompletedSubTasks != null && delayUntil == null; // can only run the next part if subtasks were returned and there is no delay
861
- }
862
- else {
863
- tryRunNextPart = canRunNextCheckpoint === true && delayUntil == null; // can try the next part if there is no delayUntil and canRunNextCheckpoint is true
864
- notificationTemplate.at = 0; // reset checkpoint attempt/delay count
865
- }
866
- // add the checkpoint to the notification
867
- notificationTemplate.tpr = [
868
- ...(0, notification_task_service_util_1.removeFromCompletionsArrayWithTaskResult)(notification.tpr, handleTaskResult), // remove any completions, if applicable
869
- ...(0, util_1.asArray)(completion)
870
- ];
871
- // calculate the updated notification item
872
- notificationTemplate.n = {
873
- ...notification.n,
874
- d: {
875
- ...notification.n.d,
876
- ...(updateMetadata ? (0, util_1.filterOnlyUndefinedValues)(updateMetadata) : undefined) // ignore any undefined values
877
- }
878
- };
879
- // can only run the next part if the tpr has changed, and the number of checkpoints completed has increased
880
- // if the tpr has not changed, then it is also considered a reversal
881
- if (tryRunNextPart) {
882
- const tprChanged = !(0, util_1.iterablesAreSetEquivalent)(notification.tpr, notificationTemplate.tpr);
883
- partTprReversal = !tprChanged || (tprChanged && notificationTemplate.tpr.length <= notification.tpr.length);
884
- if (allCompletedSubTasks != null) {
885
- switch (allCompletedSubTasks) {
886
- case true:
887
- case false:
888
- // only run if there is no tpr reversal flagged
889
- tryRunNextPart = !partTprReversal;
890
- break;
891
- default:
892
- // check subtask tpr changes
893
- nextCompleteSubTasks = (0, util_1.asArray)(allCompletedSubTasks);
894
- const subtaskTprChanged = !(0, util_1.iterablesAreSetEquivalent)(previouslyCompleteSubTasks, nextCompleteSubTasks);
895
- partTprReversal = !subtaskTprChanged || (subtaskTprChanged && nextCompleteSubTasks.length <= previouslyCompleteSubTasks.length);
896
- break;
897
- }
898
- }
899
- }
900
- break;
901
- }
902
- // do not update sat if the task is complete
903
- if (completion !== true && delayUntil != null) {
904
- // must be at least 20 seconds into the future from now, and/or the nextSat time to avoid parallel runs
905
- const minimumNextSatTime = (0, date_fns_1.addSeconds)(new Date(), 20);
906
- notificationTemplate.sat = (0, date_1.findMaxDate)([(0, util_1.dateOrMillisecondsToDate)(delayUntil, now), nextSat, minimumNextSatTime]) ?? minimumNextSatTime;
907
- }
908
- partNotificationMarkedDone = notificationTemplate.d === true;
909
- }
910
- catch (e) {
911
- console.error(`Failed handling task for notification "${notification.key}" with type "${notificationTask.taskType}": `, e);
912
- notificationTemplate.a = notification.a + 1; // increase attempts count
913
- notificationTemplate.sat = (0, util_1.dateOrMillisecondsToDate)(exports.NOTIFICATION_TASK_TYPE_FAILURE_DELAY_MS, now);
914
- partSuccess = false;
915
- }
916
- // notification tasks are read
917
- let saveTaskResult = true;
918
- if (unique) {
919
- isUniqueNotificationTask = true;
920
- const latestNotification = await notificationDocument.snapshotData();
921
- if (!latestNotification || !(0, date_1.isSameDate)(latestNotification.cat, notification.cat)) {
922
- saveTaskResult = false;
923
- uniqueNotificationTaskConflict = true;
924
- }
925
- }
926
- if (saveTaskResult) {
927
- await notificationDocument.update(notificationTemplate);
928
- }
929
- return {
930
- tryRunNextPart,
931
- partNotificationMarkedDone,
932
- partNotificationTaskCompletionType,
933
- partTprReversal,
934
- nextCompleteSubTasks,
935
- partSuccess
936
- };
937
- }
938
- /**
939
- * Notification task handling.
940
- *
941
- * Notification takss can have multiple async but sequential parts.
942
- *
943
- * Some of these parts may be able to be run immediately one after the other, instead of waiting for
944
- * another sendNotification() to complete on it.
945
- */
946
- async function handleNotificationTask() {
947
- const MAX_NOTIFICATION_TASK_PARTS_RUN_ALLOWED = 5;
948
- if (tryRun && notification != null && notificationTaskHandler) {
949
- let currentNotification = notification;
950
- let previouslyCompleteSubTasks = [];
951
- notificationTaskLoopingProtectionTriggered = false;
952
- notificationTaskPartsRunCount = 0;
953
- while (notificationTaskPartsRunCount < MAX_NOTIFICATION_TASK_PARTS_RUN_ALLOWED) {
954
- notificationTaskPartsRunCount += 1;
955
- const result = await _runNotificationTaskNextPart({
956
- notification: currentNotification,
957
- notificationTaskHandler,
958
- previouslyCompleteSubTasks
959
- });
960
- notificationTaskCompletionType = result.partNotificationTaskCompletionType;
961
- previouslyCompleteSubTasks = result.nextCompleteSubTasks ?? [];
962
- success = result.partSuccess;
963
- const tryRunNextPart = result.partSuccess && result.tryRunNextPart && !notificationTaskLoopingProtectionTriggered;
964
- notificationTaskLoopingProtectionTriggered = notificationTaskLoopingProtectionTriggered || result.partTprReversal; // update the flag if the TPR has been reversed
965
- if (tryRunNextPart) {
966
- const updatedNotificationData = await notificationDocument.snapshotData();
967
- if (updatedNotificationData) {
968
- currentNotification = (0, firebase_1.setIdAndKeyFromKeyIdRefOnDocumentData)(updatedNotificationData, notificationDocument);
969
- }
970
- else {
971
- break; // notification is unavailable now
972
- }
973
- }
974
- else {
975
- break; // escape the loop
976
- }
977
- }
978
- }
979
- }
980
- /**
981
- * Handles a normal (non-task) notification.
982
- */
983
- async function handleNormalNotification() {
984
- // notification is only null/undefined if it didn't exist.
985
- if (notification != null) {
986
- if (tryRun && templateInstance != null) {
987
- // first load the message function
988
- const messageFunction = await templateInstance
989
- .loadMessageFunction({
990
- item: notification.n,
991
- notification,
992
- notificationBox: {
993
- m: notificationBoxModelKey
994
- }
995
- })
996
- .catch((e) => {
997
- loadMessageFunctionFailure = true;
998
- success = false;
999
- console.error(`Failed loading message function for type ${notificationTemplateType}: `, e);
1000
- return undefined;
1001
- });
1002
- if (messageFunction) {
1003
- function filterOutNoContentNotificationMessages(messages) {
1004
- return messages.filter((x) => !x.flag);
1005
- }
1006
- // expand recipients
1007
- const { emails: emailRecipients, texts: textRecipients, notificationSummaries: notificationSummaryRecipients } = await (0, notification_util_1.expandNotificationRecipients)({
1008
- notification,
1009
- notificationBox,
1010
- authService,
1011
- notificationUserAccessor,
1012
- globalRecipients: messageFunction.globalRecipients,
1013
- onlySendToExplicitlyEnabledRecipients,
1014
- onlyTextExplicitlyEnabledRecipients,
1015
- notificationSummaryIdForUid: notificationSendService.notificationSummaryIdForUidFunction
1016
- });
1017
- let { es, ts, ps, ns, esr: currentEsr, tsr: currentTsr } = notification;
1018
- // do emails
1019
- let esr;
1020
- if (es === firebase_1.NotificationSendState.QUEUED || es === firebase_1.NotificationSendState.SENT_PARTIAL) {
1021
- const emailRecipientsAlreadySentTo = new Set(currentEsr.map((x) => x.toLowerCase()));
1022
- const emailInputContexts = emailRecipients
1023
- .filter((x) => !emailRecipientsAlreadySentTo.has(x.emailAddress.toLowerCase()))
1024
- .map((x) => {
1025
- const context = {
1026
- recipient: {
1027
- n: x.name,
1028
- e: x.emailAddress,
1029
- t: x.phoneNumber
1030
- }
1031
- };
1032
- return context;
1033
- });
1034
- const emailMessages = await Promise.all(emailInputContexts.map(messageFunction))
1035
- .then(filterOutNoContentNotificationMessages)
1036
- .catch((e) => {
1037
- console.error(`Failed building message function for type ${notificationTemplateType}: `, e);
1038
- buildMessageFailure = true;
1039
- return undefined;
1040
- });
1041
- if (emailMessages?.length) {
1042
- if (notificationSendService.emailSendService != null) {
1043
- let sendInstance;
1044
- try {
1045
- sendInstance = await notificationSendService.emailSendService.buildSendInstanceForEmailNotificationMessages(emailMessages);
1046
- }
1047
- catch (e) {
1048
- console.error(`Failed building email send instance for notification "${notification.id}" with type "${notificationTemplateType}": `, e);
1049
- es = firebase_1.NotificationSendState.CONFIG_ERROR;
1050
- }
1051
- if (sendInstance) {
1052
- try {
1053
- sendEmailsResult = await sendInstance();
1054
- }
1055
- catch (e) {
1056
- console.error(`Failed sending email notification "${notification.id}" with type "${notificationTemplateType}": `, e);
1057
- es = firebase_1.NotificationSendState.SEND_ERROR;
1058
- }
1059
- }
1060
- }
1061
- else {
1062
- console.error(`Failed sending email notification "${notification.id}" with type "${notificationTemplateType}" due to no email service being configured.`);
1063
- es = firebase_1.NotificationSendState.CONFIG_ERROR;
1064
- }
1065
- if (sendEmailsResult != null) {
1066
- const { success, failed } = sendEmailsResult;
1067
- esr = success.length ? currentEsr.concat(success.map((x) => x.toLowerCase())) : undefined;
1068
- if (failed.length > 0) {
1069
- es = firebase_1.NotificationSendState.SENT_PARTIAL;
1070
- }
1071
- else {
1072
- es = firebase_1.NotificationSendState.SENT;
1073
- }
1074
- }
1075
- }
1076
- else {
1077
- es = firebase_1.NotificationSendState.SENT;
1078
- }
1079
- }
1080
- // do phone numbers
1081
- let tsr;
1082
- if (ts === firebase_1.NotificationSendState.QUEUED || ts === firebase_1.NotificationSendState.SENT_PARTIAL) {
1083
- const textRecipientsAlreadySentTo = new Set(currentTsr);
1084
- const textInputContexts = textRecipients
1085
- .filter((x) => !textRecipientsAlreadySentTo.has(x.phoneNumber))
1086
- .map((x) => {
1087
- const context = {
1088
- recipient: {
1089
- n: x.name,
1090
- e: x.emailAddress,
1091
- t: x.phoneNumber
1092
- }
1093
- };
1094
- return context;
1095
- });
1096
- const textMessages = await Promise.all(textInputContexts.map(messageFunction))
1097
- .then(filterOutNoContentNotificationMessages)
1098
- .catch((e) => {
1099
- console.error(`Failed building message function for type ${notificationTemplateType}: `, e);
1100
- buildMessageFailure = true;
1101
- return undefined;
1102
- });
1103
- if (textMessages?.length) {
1104
- if (notificationSendService.textSendService != null) {
1105
- let sendInstance;
1106
- try {
1107
- sendInstance = await notificationSendService.textSendService.buildSendInstanceForTextNotificationMessages(textMessages);
1108
- }
1109
- catch (e) {
1110
- console.error(`Failed building text send instance for notification "${notification.id}" with type "${notificationTemplateType}": `, e);
1111
- ts = firebase_1.NotificationSendState.CONFIG_ERROR;
1112
- }
1113
- if (sendInstance) {
1114
- try {
1115
- sendTextsResult = await sendInstance();
1116
- }
1117
- catch (e) {
1118
- console.error(`Failed sending text notification "${notification.id}" with type "${notificationTemplateType}": `, e);
1119
- ts = firebase_1.NotificationSendState.SEND_ERROR;
1120
- }
1121
- }
1122
- }
1123
- else {
1124
- console.error(`Failed sending text notification "${notification.id}" with type "${notificationTemplateType}" due to no text service being configured.`);
1125
- ts = firebase_1.NotificationSendState.CONFIG_ERROR;
1126
- }
1127
- if (sendTextsResult != null) {
1128
- const { success, failed } = sendTextsResult;
1129
- tsr = success.length ? currentTsr.concat(success) : undefined;
1130
- if (failed.length > 0) {
1131
- ts = firebase_1.NotificationSendState.SENT_PARTIAL;
1132
- }
1133
- else {
1134
- ts = firebase_1.NotificationSendState.SENT;
1135
- }
1136
- }
1137
- }
1138
- else {
1139
- ts = firebase_1.NotificationSendState.SENT;
1140
- }
1141
- }
1142
- ps = firebase_1.NotificationSendState.NO_TRY;
1143
- // NOTE: FCM token management will probably done with a separate system within Notification that stores FCMs for specific users in the app. May also use UIDs to determine who got the push notificdation or not...
1144
- // do notification summaries
1145
- if (ns === firebase_1.NotificationSendState.QUEUED || ns === firebase_1.NotificationSendState.SENT_PARTIAL) {
1146
- const notificationSummaryInputContexts = notificationSummaryRecipients.map((x) => {
1147
- const context = {
1148
- recipient: {
1149
- n: x.name,
1150
- s: x.notificationSummaryId
1151
- }
1152
- };
1153
- return context;
1154
- });
1155
- const notificationSummaryMessages = await Promise.all(notificationSummaryInputContexts.map(messageFunction))
1156
- .then(filterOutNoContentNotificationMessages)
1157
- .catch((e) => {
1158
- console.error(`Failed building message function for type ${notificationTemplateType}: `, e);
1159
- buildMessageFailure = true;
1160
- return undefined;
1161
- });
1162
- if (notificationSummaryMessages?.length) {
1163
- if (notificationSendService.notificationSummarySendService != null) {
1164
- let sendInstance;
1165
- try {
1166
- sendInstance = await notificationSendService.notificationSummarySendService.buildSendInstanceForNotificationSummaryMessages(notificationSummaryMessages);
1167
- }
1168
- catch (e) {
1169
- console.error(`Failed building notification summary send instance for notification "${notification.id}" with type "${notificationTemplateType}": `, e);
1170
- ns = firebase_1.NotificationSendState.CONFIG_ERROR;
1171
- }
1172
- if (sendInstance) {
1173
- try {
1174
- sendNotificationSummaryResult = await sendInstance();
1175
- ns = firebase_1.NotificationSendState.SENT;
1176
- }
1177
- catch (e) {
1178
- console.error(`Failed sending notification summary notification "${notification.id}" with type "${notificationTemplateType}": `, e);
1179
- ns = firebase_1.NotificationSendState.SEND_ERROR;
1180
- }
1181
- }
1182
- }
1183
- else {
1184
- console.error(`Failed sending notification summary notification "${notification.id}" with type "${notificationTemplateType}" due to no notification summary service being configured.`);
1185
- ns = firebase_1.NotificationSendState.CONFIG_ERROR;
1186
- }
1187
- }
1188
- else {
1189
- ns = firebase_1.NotificationSendState.SENT;
1190
- }
1191
- }
1192
- // calculate results
1193
- const notificationTemplate = { es, ts, ps, ns, esr, tsr };
1194
- success = (0, firebase_1.notificationSendFlagsImplyIsComplete)(notificationTemplate);
1195
- if (success) {
1196
- notificationTemplate.d = true;
1197
- }
1198
- else {
1199
- notificationTemplate.a = notification.a + 1;
1200
- if (notificationTemplate.a >= exports.NOTIFICATION_MAX_SEND_ATTEMPTS) {
1201
- notificationTemplate.d = true;
1202
- }
1203
- }
1204
- await notificationDocument.update(notificationTemplate);
1205
- notificationMarkedDone = notificationTemplate.d === true;
1206
- const callbackDetails = {
1207
- success,
1208
- updatedSendFlags: notificationTemplate,
1209
- sendEmailsResult,
1210
- sendTextsResult,
1211
- sendNotificationSummaryResult
1212
- };
1213
- const { onSendAttempted, onSendSuccess } = messageFunction;
1214
- // call onSendAttempted, if one is configured
1215
- if (onSendAttempted) {
1216
- onSendAttemptedResult = await (0, util_1.asPromise)(onSendAttempted(callbackDetails))
1217
- .then((value) => {
1218
- return { value };
1219
- })
1220
- .catch((e) => {
1221
- console.warn(`Caught exception while calling onSendAttempted for notification "${notification.id}" with type "${notificationTemplateType}": `, e);
1222
- return { error: e };
1223
- });
1224
- }
1225
- // call onSendSuccess, if one is configured
1226
- if (notificationMarkedDone && onSendSuccess) {
1227
- onSendSuccessResult = await (0, util_1.asPromise)(onSendSuccess(callbackDetails))
1228
- .then((value) => {
1229
- return { value };
1230
- })
1231
- .catch((e) => {
1232
- console.warn(`Caught exception while calling onSendSuccess for notification "${notification.id}" with type "${notificationTemplateType}": `, e);
1233
- return { error: e };
1234
- });
1235
- }
1236
- }
1237
- }
1238
- else {
1239
- switch (notification.st) {
1240
- case firebase_1.NotificationSendType.SEND_IF_BOX_EXISTS:
1241
- // deleted successfully
1242
- success = deletedNotification;
1243
- break;
1244
- }
1245
- }
1246
- }
1247
- }
1248
- const result = {
1249
- notificationTemplateType,
1250
- isKnownTemplateType,
1251
- isNotificationTask,
1252
- isUniqueNotificationTask,
1253
- uniqueNotificationTaskConflict,
1254
- isConfiguredTemplateType,
1255
- throttled,
1256
- exists: notification != null,
1257
- boxExists: notificationBox != null,
1258
- notificationTaskPartsRunCount,
1259
- notificationTaskLoopingProtectionTriggered,
1260
- notificationBoxNeedsInitialization,
1261
- notificationTaskCompletionType,
1262
- createdBox,
1263
- deletedNotification,
1264
- notificationMarkedDone,
1265
- tryRun,
1266
- success,
1267
- sendEmailsResult,
1268
- sendTextsResult,
1269
- sendNotificationSummaryResult,
1270
- loadMessageFunctionFailure,
1271
- buildMessageFailure,
1272
- onSendAttemptedResult,
1273
- onSendSuccessResult
1274
- };
1275
- return result;
1276
- };
1277
- });
1278
- }
1279
- exports.SEND_QUEUE_NOTIFICATIONS_TASK_EXCESS_THRESHOLD = 5000;
1280
- function sendQueuedNotificationsFactory(context) {
1281
- const { firebaseServerActionTransformFunctionFactory, notificationCollectionGroup } = context;
1282
- const sendNotification = sendNotificationFactory(context);
1283
- return firebaseServerActionTransformFunctionFactory(firebase_1.SendQueuedNotificationsParams, async (params) => {
1284
- const { maxSendNotificationLoops } = params;
1285
- const maxLoops = maxSendNotificationLoops ?? Number.MAX_SAFE_INTEGER;
1286
- const sendNotificationLoopsTaskExcessThreshold = params.sendNotificationLoopsTaskExcessThreshold ?? exports.SEND_QUEUE_NOTIFICATIONS_TASK_EXCESS_THRESHOLD;
1287
- return async (input) => {
1288
- const maxParallelTasks = input?.maxParellelSendTasks ?? params.maxParellelSendTasks ?? 5;
1289
- const onSendNotificationResult = input?.onSendNotificationResult ?? (0, util_1.mapIdentityFunction)();
1290
- let notificationLoopCount = 0;
1291
- let notificationBoxesCreated = 0;
1292
- let notificationsDeleted = 0;
1293
- let notificationTasksVisited = 0;
1294
- let notificationsVisited = 0;
1295
- let notificationsSucceeded = 0;
1296
- let notificationsDelayed = 0;
1297
- let notificationsFailed = 0;
1298
- let sendEmailsResult;
1299
- let sendTextsResult;
1300
- let sendNotificationSummaryResult;
1301
- const sendNotificationParams = { key: (0, firebase_1.firestoreDummyKey)(), throwErrorIfSent: false };
1302
- const sendNotificationInstance = await sendNotification(sendNotificationParams);
1303
- let excessLoopsDetected = false;
1304
- const sendQueuedNotifications = async () => {
1305
- const query = notificationCollectionGroup.queryDocument((0, firebase_1.notificationsPastSendAtTimeQuery)());
1306
- const notificationDocuments = await query.getDocs();
1307
- const result = await (0, util_1.performAsyncTasks)(notificationDocuments, async (notificationDocument) => {
1308
- const result = await sendNotificationInstance(notificationDocument);
1309
- onSendNotificationResult(result, notificationDocument);
1310
- return result;
1311
- }, {
1312
- maxParallelTasks
1313
- });
1314
- return result;
1315
- };
1316
- // iterate through all notification items that need to be synced
1317
- // eslint-disable-next-line no-constant-condition
1318
- while (notificationLoopCount < maxLoops) {
1319
- const sendQueuedNotificationsResults = await sendQueuedNotifications();
1320
- sendQueuedNotificationsResults.results.forEach((x) => {
1321
- const result = x[1];
1322
- if (result.success) {
1323
- notificationsSucceeded += 1;
1324
- }
1325
- else if (result.createdBox || result.notificationBoxNeedsInitialization) {
1326
- notificationsDelayed += 1;
1327
- }
1328
- else {
1329
- notificationsFailed += 1;
1330
- }
1331
- if (result.isNotificationTask) {
1332
- notificationTasksVisited += 1;
1333
- }
1334
- if (result.deletedNotification) {
1335
- notificationsDeleted += 1;
1336
- }
1337
- if (result.createdBox) {
1338
- notificationBoxesCreated += 1;
1339
- }
1340
- sendEmailsResult = (0, firebase_1.mergeNotificationSendMessagesResult)(sendEmailsResult, result.sendEmailsResult);
1341
- sendTextsResult = (0, firebase_1.mergeNotificationSendMessagesResult)(sendTextsResult, result.sendTextsResult);
1342
- sendNotificationSummaryResult = (0, firebase_1.mergeNotificationSendMessagesResult)(sendNotificationSummaryResult, result.sendNotificationSummaryResult);
1343
- });
1344
- const found = sendQueuedNotificationsResults.results.length;
1345
- notificationsVisited += found;
1346
- notificationLoopCount += 1;
1347
- if (!found) {
1348
- break;
1349
- }
1350
- else if (!excessLoopsDetected && notificationLoopCount > sendNotificationLoopsTaskExcessThreshold) {
1351
- excessLoopsDetected = true;
1352
- console.error(`sendQueuedNotifications(EXCESS_LOOPS_DETECTED): Exceeded send notification loops task excess threshold of ${sendNotificationLoopsTaskExcessThreshold}.`);
1353
- // continue the loops
1354
- }
1355
- }
1356
- const result = {
1357
- excessLoopsDetected,
1358
- notificationLoopCount,
1359
- notificationBoxesCreated,
1360
- notificationsDeleted,
1361
- notificationTasksVisited,
1362
- notificationsVisited,
1363
- notificationsSucceeded,
1364
- notificationsDelayed,
1365
- notificationsFailed,
1366
- sendEmailsResult,
1367
- sendTextsResult,
1368
- sendNotificationSummaryResult
1369
- };
1370
- return result;
1371
- };
1372
- });
1373
- }
1374
- function cleanupSentNotificationsFactory(context) {
1375
- const { firestoreContext, firebaseServerActionTransformFunctionFactory, notificationCollectionGroup, notificationBoxCollection, notificationWeekCollectionFactory } = context;
1376
- return firebaseServerActionTransformFunctionFactory(firebase_1.CleanupSentNotificationsParams, async () => {
1377
- return async () => {
1378
- let notificationBoxesUpdatesCount = 0;
1379
- let notificationsDeleted = 0;
1380
- const notificationTasksDeletedCount = 0;
1381
- let notificationWeeksCreated = 0;
1382
- let notificationWeeksUpdated = 0;
1383
- // iterate through all Notification items that need to be cleaned up
1384
- // eslint-disable-next-line no-constant-condition
1385
- while (true) {
1386
- const cleanupSentNotificationsResults = await cleanupSentNotifications();
1387
- cleanupSentNotificationsResults.results.forEach((x) => {
1388
- const { itemsDeleted, weeksCreated, weeksUpdated } = x[1];
1389
- notificationsDeleted += itemsDeleted;
1390
- notificationWeeksCreated += weeksCreated;
1391
- notificationWeeksUpdated += weeksUpdated;
1392
- });
1393
- const notificationBoxesUpdated = cleanupSentNotificationsResults.results.length;
1394
- notificationBoxesUpdatesCount += notificationBoxesUpdated;
1395
- if (!notificationBoxesUpdated) {
1396
- break;
1397
- }
1398
- }
1399
- async function cleanupSentNotifications() {
1400
- const query = notificationCollectionGroup.queryDocument((0, firebase_1.notificationsReadyForCleanupQuery)());
1401
- const notificationDocuments = await query.getDocs();
1402
- const notificationDocumentsGroupedByNotificationBox = Array.from((0, util_1.makeValuesGroupMap)(notificationDocuments, (x) => x.parent.id).values());
1403
- const result = await (0, util_1.performAsyncTasks)(notificationDocumentsGroupedByNotificationBox, async (notificationDocumentsInSameBox) => {
1404
- const allPairs = await (0, firebase_1.getDocumentSnapshotDataPairs)(notificationDocumentsInSameBox);
1405
- const allPairsWithDataAndMarkedDeleted = allPairs.filter((x) => x.data?.d);
1406
- const { included: taskPairsWithDataAndMarkedDeleted, excluded: normalPairsWithDataAndMarkedDeleted } = (0, util_1.separateValues)(allPairsWithDataAndMarkedDeleted, (x) => x.data?.st === firebase_1.NotificationSendType.TASK_NOTIFICATION);
1407
- const pairsGroupedByWeek = Array.from((0, util_1.makeValuesGroupMap)(normalPairsWithDataAndMarkedDeleted, (x) => (0, date_1.yearWeekCode)(x.data.sat)).entries());
1408
- // batch incase there are a lot of new notifications to move to week
1409
- const pairsGroupedByWeekInBatches = pairsGroupedByWeek
1410
- .map((x) => {
1411
- const batches = (0, util_1.batch)(x[1], 40);
1412
- return batches.map((batch) => [x[0], batch]);
1413
- })
1414
- .flat();
1415
- const notificationBoxDocument = await notificationBoxCollection.documentAccessor().loadDocument(notificationDocumentsInSameBox[0].parent);
1416
- // create/update the NotificationWeek
1417
- const notificationWeekResults = await (0, util_1.performAsyncTasks)(pairsGroupedByWeekInBatches, async ([yearWeekCode, notificationDocumentsInSameWeek]) => {
1418
- return firestoreContext.runTransaction(async (transaction) => {
1419
- const notificationWeekDocument = notificationWeekCollectionFactory(notificationBoxDocument).documentAccessorForTransaction(transaction).loadDocumentForId(`${yearWeekCode}`);
1420
- const notificationDocumentsInTransaction = (0, firebase_1.loadDocumentsForDocumentReferencesFromValues)(notificationCollectionGroup.documentAccessorForTransaction(transaction), notificationDocumentsInSameWeek, (x) => x.snapshot.ref);
1421
- const notificationWeek = await notificationWeekDocument.snapshotData();
1422
- const newItems = (0, util_1.filterMaybeArrayValues)(notificationDocumentsInSameWeek.map((x) => {
1423
- const data = x.data;
1424
- const shouldSaveToNotificationWeek = (0, firebase_1.shouldSaveNotificationToNotificationWeek)(data);
1425
- return shouldSaveToNotificationWeek ? data.n : undefined;
1426
- }));
1427
- const n = [...(notificationWeek?.n ?? []), ...newItems];
1428
- if (!notificationWeek) {
1429
- // create
1430
- await notificationWeekDocument.create({
1431
- w: yearWeekCode,
1432
- n
1433
- });
1434
- }
1435
- else {
1436
- // update
1437
- await notificationWeekDocument.update({
1438
- n
1439
- });
1440
- }
1441
- // delete the notification items
1442
- await Promise.all(notificationDocumentsInTransaction.map((x) => x.accessor.delete()));
1443
- return {
1444
- created: !notificationWeek
1445
- };
1446
- });
1447
- });
1448
- // delete all the task notifications
1449
- const writeBatch = firestoreContext.batch();
1450
- const writeBatchAccessor = notificationCollectionGroup.documentAccessorForTransaction(writeBatch);
1451
- await Promise.all(taskPairsWithDataAndMarkedDeleted.map((x) => writeBatchAccessor.loadDocumentFrom(x.document).accessor.delete()));
1452
- await writeBatch.commit();
1453
- let weeksCreated = 0;
1454
- let weeksUpdated = 0;
1455
- const tasksDeleted = taskPairsWithDataAndMarkedDeleted.length;
1456
- notificationWeekResults.results.forEach((x) => {
1457
- if (x[1].created) {
1458
- weeksCreated += 1;
1459
- }
1460
- else {
1461
- weeksUpdated += 1;
1462
- }
1463
- });
1464
- const result = {
1465
- weeksCreated,
1466
- weeksUpdated,
1467
- itemsDeleted: allPairsWithDataAndMarkedDeleted.length,
1468
- tasksDeleted
1469
- };
1470
- return result;
1471
- }, {
1472
- maxParallelTasks: 10
1473
- });
1474
- return result;
1475
- }
1476
- const result = {
1477
- notificationBoxesUpdatesCount,
1478
- notificationTasksDeletedCount,
1479
- notificationsDeleted,
1480
- notificationWeeksCreated,
1481
- notificationWeeksUpdated
1482
- };
1483
- return result;
1484
- };
1485
- });
1486
- }
1487
- //# sourceMappingURL=notification.action.service.js.map