@aglyn/plugins-crm 1.0.0-beta.220 → 1.0.0-beta.222

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 (514) hide show
  1. package/README.md +2 -1
  2. package/package.json +13 -13
  3. package/src/lib/components/activity-list.js +12 -5
  4. package/src/lib/components/activity-list.js.map +1 -1
  5. package/src/lib/components/companies-bulk-bar.d.ts +1 -4
  6. package/src/lib/components/companies-bulk-bar.js +7 -20
  7. package/src/lib/components/companies-bulk-bar.js.map +1 -1
  8. package/src/lib/components/companies-section.d.ts +3 -3
  9. package/src/lib/components/companies-section.js +149 -46
  10. package/src/lib/components/companies-section.js.map +1 -1
  11. package/src/lib/components/company-edit-drawer.js +281 -20
  12. package/src/lib/components/company-edit-drawer.js.map +1 -1
  13. package/src/lib/components/company-properties-card.js +99 -8
  14. package/src/lib/components/company-properties-card.js.map +1 -1
  15. package/src/lib/components/contact-detail-page.js +3 -1
  16. package/src/lib/components/contact-detail-page.js.map +1 -1
  17. package/src/lib/components/contact-merge-dialog.js +33 -10
  18. package/src/lib/components/contact-merge-dialog.js.map +1 -1
  19. package/src/lib/components/contact-properties-card.d.ts +0 -69
  20. package/src/lib/components/contact-properties-card.js +350 -60
  21. package/src/lib/components/contact-properties-card.js.map +1 -1
  22. package/src/lib/components/contact-reports-to-field.d.ts +46 -0
  23. package/src/lib/components/contact-reports-to-field.js +67 -0
  24. package/src/lib/components/contact-reports-to-field.js.map +1 -0
  25. package/src/lib/components/contacts-bulk-bar.d.ts +1 -8
  26. package/src/lib/components/contacts-bulk-bar.js +7 -19
  27. package/src/lib/components/contacts-bulk-bar.js.map +1 -1
  28. package/src/lib/components/contacts-section.js +46 -33
  29. package/src/lib/components/contacts-section.js.map +1 -1
  30. package/src/lib/components/crm-call-actions.d.ts +10 -0
  31. package/src/lib/components/crm-call-actions.js +26 -9
  32. package/src/lib/components/crm-call-actions.js.map +1 -1
  33. package/src/lib/components/crm-record-picker.d.ts +15 -0
  34. package/src/lib/components/crm-record-picker.js +16 -10
  35. package/src/lib/components/crm-record-picker.js.map +1 -1
  36. package/src/lib/components/crm-transfer-buttons.d.ts +54 -0
  37. package/src/lib/components/crm-transfer-buttons.js +167 -0
  38. package/src/lib/components/crm-transfer-buttons.js.map +1 -0
  39. package/src/lib/components/deal-contact-roles-card.d.ts +46 -0
  40. package/src/lib/components/deal-contact-roles-card.js +368 -0
  41. package/src/lib/components/deal-contact-roles-card.js.map +1 -0
  42. package/src/lib/components/deal-detail-page.d.ts +3 -2
  43. package/src/lib/components/deal-detail-page.js +25 -6
  44. package/src/lib/components/deal-detail-page.js.map +1 -1
  45. package/src/lib/components/deal-edit-drawer.d.ts +10 -0
  46. package/src/lib/components/deal-edit-drawer.js +219 -10
  47. package/src/lib/components/deal-edit-drawer.js.map +1 -1
  48. package/src/lib/components/deal-properties-card.d.ts +7 -0
  49. package/src/lib/components/deal-properties-card.js +34 -3
  50. package/src/lib/components/deal-properties-card.js.map +1 -1
  51. package/src/lib/components/deal-stage-card.d.ts +4 -0
  52. package/src/lib/components/deal-stage-card.js +10 -2
  53. package/src/lib/components/deal-stage-card.js.map +1 -1
  54. package/src/lib/components/deals-bulk-bar.d.ts +0 -3
  55. package/src/lib/components/deals-bulk-bar.js +7 -20
  56. package/src/lib/components/deals-bulk-bar.js.map +1 -1
  57. package/src/lib/components/deals-section.d.ts +3 -3
  58. package/src/lib/components/deals-section.js +123 -63
  59. package/src/lib/components/deals-section.js.map +1 -1
  60. package/src/lib/components/fields-section.js +31 -17
  61. package/src/lib/components/fields-section.js.map +1 -1
  62. package/src/lib/components/lead-convert-dialog.d.ts +4 -0
  63. package/src/lib/components/lead-convert-dialog.js +23 -1
  64. package/src/lib/components/lead-convert-dialog.js.map +1 -1
  65. package/src/lib/components/lead-detail-page.js +8 -2
  66. package/src/lib/components/lead-detail-page.js.map +1 -1
  67. package/src/lib/components/lead-profile-fields.d.ts +71 -0
  68. package/src/lib/components/lead-profile-fields.js +386 -0
  69. package/src/lib/components/lead-profile-fields.js.map +1 -0
  70. package/src/lib/components/lead-properties-card.d.ts +2 -1
  71. package/src/lib/components/lead-properties-card.js +85 -176
  72. package/src/lib/components/lead-properties-card.js.map +1 -1
  73. package/src/lib/components/lead-source-select.d.ts +4 -23
  74. package/src/lib/components/lead-source-select.js +9 -73
  75. package/src/lib/components/lead-source-select.js.map +1 -1
  76. package/src/lib/components/lead-status-chip.d.ts +9 -3
  77. package/src/lib/components/lead-status-chip.js +8 -4
  78. package/src/lib/components/lead-status-chip.js.map +1 -1
  79. package/src/lib/components/lead-status-options.d.ts +20 -0
  80. package/src/lib/components/lead-status-options.js +51 -0
  81. package/src/lib/components/lead-status-options.js.map +1 -0
  82. package/src/lib/components/lead-unqualify-dialog.d.ts +5 -0
  83. package/src/lib/components/lead-unqualify-dialog.js +50 -18
  84. package/src/lib/components/lead-unqualify-dialog.js.map +1 -1
  85. package/src/lib/components/leads-bulk-bar.d.ts +0 -3
  86. package/src/lib/components/leads-bulk-bar.js +29 -29
  87. package/src/lib/components/leads-bulk-bar.js.map +1 -1
  88. package/src/lib/components/leads-section.js +120 -68
  89. package/src/lib/components/leads-section.js.map +1 -1
  90. package/src/lib/components/linked-deals-card.d.ts +4 -0
  91. package/src/lib/components/linked-deals-card.js +47 -3
  92. package/src/lib/components/linked-deals-card.js.map +1 -1
  93. package/src/lib/components/log-activity-dialog.js +43 -3
  94. package/src/lib/components/log-activity-dialog.js.map +1 -1
  95. package/src/lib/components/new-contact-drawer.d.ts +8 -0
  96. package/src/lib/components/new-contact-drawer.js +108 -6
  97. package/src/lib/components/new-contact-drawer.js.map +1 -1
  98. package/src/lib/components/new-lead-drawer.d.ts +9 -2
  99. package/src/lib/components/new-lead-drawer.js +88 -121
  100. package/src/lib/components/new-lead-drawer.js.map +1 -1
  101. package/src/lib/components/picklist-select.d.ts +36 -0
  102. package/src/lib/components/picklist-select.js +114 -0
  103. package/src/lib/components/picklist-select.js.map +1 -0
  104. package/src/lib/components/picklist-values-card.d.ts +34 -0
  105. package/src/lib/components/{lead-source-values-card.js → picklist-values-card.js} +241 -58
  106. package/src/lib/components/picklist-values-card.js.map +1 -0
  107. package/src/lib/components/pipeline-stages-dialog.d.ts +7 -0
  108. package/src/lib/components/pipeline-stages-dialog.js +26 -4
  109. package/src/lib/components/pipeline-stages-dialog.js.map +1 -1
  110. package/src/lib/components/pipelines-dialog.js +15 -6
  111. package/src/lib/components/pipelines-dialog.js.map +1 -1
  112. package/src/lib/components/recent-activity-feed.js +20 -5
  113. package/src/lib/components/recent-activity-feed.js.map +1 -1
  114. package/src/lib/components/recipes-card.js +4 -2
  115. package/src/lib/components/recipes-card.js.map +1 -1
  116. package/src/lib/components/record-tasks-card.js +15 -8
  117. package/src/lib/components/record-tasks-card.js.map +1 -1
  118. package/src/lib/components/reports/forecast-card.d.ts +6 -0
  119. package/src/lib/components/reports/forecast-card.js +101 -3
  120. package/src/lib/components/reports/forecast-card.js.map +1 -1
  121. package/src/lib/components/reports/lead-funnel-card.d.ts +12 -0
  122. package/src/lib/components/reports/lead-funnel-card.js +9 -5
  123. package/src/lib/components/reports/lead-funnel-card.js.map +1 -1
  124. package/src/lib/components/reports/lead-source-card.d.ts +23 -0
  125. package/src/lib/components/reports/lead-source-card.js +318 -0
  126. package/src/lib/components/reports/lead-source-card.js.map +1 -0
  127. package/src/lib/components/reports/report-export.js +1 -1
  128. package/src/lib/components/reports/report-export.js.map +1 -1
  129. package/src/lib/components/reports-section.js +8 -0
  130. package/src/lib/components/reports-section.js.map +1 -1
  131. package/src/lib/components/sharing-rule-drawer.d.ts +5 -0
  132. package/src/lib/components/sharing-rule-drawer.js +108 -19
  133. package/src/lib/components/sharing-rule-drawer.js.map +1 -1
  134. package/src/lib/components/sharing-rules-card.js +11 -3
  135. package/src/lib/components/sharing-rules-card.js.map +1 -1
  136. package/src/lib/components/task-cells.d.ts +9 -1
  137. package/src/lib/components/task-cells.js +9 -4
  138. package/src/lib/components/task-cells.js.map +1 -1
  139. package/src/lib/components/task-edit-drawer.js +111 -43
  140. package/src/lib/components/task-edit-drawer.js.map +1 -1
  141. package/src/lib/components/tasks-bulk-bar.d.ts +0 -3
  142. package/src/lib/components/tasks-bulk-bar.js +7 -20
  143. package/src/lib/components/tasks-bulk-bar.js.map +1 -1
  144. package/src/lib/components/tasks-calendar.d.ts +3 -0
  145. package/src/lib/components/tasks-calendar.js +8 -1
  146. package/src/lib/components/tasks-calendar.js.map +1 -1
  147. package/src/lib/components/tasks-section.d.ts +3 -3
  148. package/src/lib/components/tasks-section.js +58 -43
  149. package/src/lib/components/tasks-section.js.map +1 -1
  150. package/src/lib/constants/api-routes.d.ts +2 -9
  151. package/src/lib/constants/api-routes.js +1 -7
  152. package/src/lib/constants/api-routes.js.map +1 -1
  153. package/src/lib/constants/bundle-common.d.ts +6 -0
  154. package/src/lib/constants/bundle-common.js +11 -0
  155. package/src/lib/constants/bundle-common.js.map +1 -1
  156. package/src/lib/constants/company-filters.d.ts +14 -0
  157. package/src/lib/constants/company-filters.js +51 -1
  158. package/src/lib/constants/company-filters.js.map +1 -1
  159. package/src/lib/constants/contact-filters.d.ts +2 -0
  160. package/src/lib/constants/contact-filters.js +18 -1
  161. package/src/lib/constants/contact-filters.js.map +1 -1
  162. package/src/lib/constants/deal-filters.d.ts +22 -1
  163. package/src/lib/constants/deal-filters.js +67 -4
  164. package/src/lib/constants/deal-filters.js.map +1 -1
  165. package/src/lib/declarations.console-server.d.ts +3 -0
  166. package/src/lib/declarations.console-server.js +35 -0
  167. package/src/lib/declarations.console-server.js.map +1 -1
  168. package/src/lib/declarations.d.ts +26 -0
  169. package/src/lib/declarations.js +35 -0
  170. package/src/lib/declarations.js.map +1 -0
  171. package/src/lib/declarations.server.d.ts +11 -0
  172. package/src/lib/declarations.server.js +92 -1
  173. package/src/lib/declarations.server.js.map +1 -1
  174. package/src/lib/hooks/use-company-picklists.d.ts +15 -0
  175. package/src/lib/hooks/use-company-picklists.js +55 -0
  176. package/src/lib/hooks/use-company-picklists.js.map +1 -0
  177. package/src/lib/hooks/use-crm-picklist.d.ts +25 -0
  178. package/src/lib/hooks/use-crm-picklist.js +53 -0
  179. package/src/lib/hooks/use-crm-picklist.js.map +1 -0
  180. package/src/lib/hooks/use-crm-record-names.d.ts +16 -0
  181. package/src/lib/hooks/use-crm-record-names.js +45 -19
  182. package/src/lib/hooks/use-crm-record-names.js.map +1 -1
  183. package/src/lib/hooks/use-crm-task-picklists.d.ts +11 -0
  184. package/src/lib/hooks/use-crm-task-picklists.js +45 -0
  185. package/src/lib/hooks/use-crm-task-picklists.js.map +1 -0
  186. package/src/lib/hooks/use-deals.d.ts +14 -0
  187. package/src/lib/hooks/use-deals.js +29 -0
  188. package/src/lib/hooks/use-deals.js.map +1 -1
  189. package/src/lib/hooks/use-lead-picklists.d.ts +14 -0
  190. package/src/lib/hooks/use-lead-picklists.js +46 -0
  191. package/src/lib/hooks/use-lead-picklists.js.map +1 -0
  192. package/src/lib/hooks/use-lead-source-picklist.d.ts +5 -19
  193. package/src/lib/hooks/use-lead-source-picklist.js +12 -22
  194. package/src/lib/hooks/use-lead-source-picklist.js.map +1 -1
  195. package/src/lib/hooks/use-lead-status-picklist.d.ts +9 -0
  196. package/src/lib/hooks/use-lead-status-picklist.js +40 -0
  197. package/src/lib/hooks/use-lead-status-picklist.js.map +1 -0
  198. package/src/lib/model/companies.d.ts +32 -3
  199. package/src/lib/model/companies.js +133 -16
  200. package/src/lib/model/companies.js.map +1 -1
  201. package/src/lib/model/contact-merge.d.ts +27 -3
  202. package/src/lib/model/contact-merge.js +81 -7
  203. package/src/lib/model/contact-merge.js.map +1 -1
  204. package/src/lib/model/contact-record.d.ts +17 -0
  205. package/src/lib/model/contact-record.js +15 -1
  206. package/src/lib/model/contact-record.js.map +1 -1
  207. package/src/lib/model/contact-update.d.ts +31 -2
  208. package/src/lib/model/contact-update.js +14 -0
  209. package/src/lib/model/contact-update.js.map +1 -1
  210. package/src/lib/model/crm-list-query.d.ts +5 -0
  211. package/src/lib/model/crm-list-query.js +8 -0
  212. package/src/lib/model/crm-list-query.js.map +1 -1
  213. package/src/lib/model/crm-recipes.d.ts +40 -0
  214. package/src/lib/model/crm-recipes.js +244 -0
  215. package/src/lib/model/crm-recipes.js.map +1 -0
  216. package/src/lib/model/crm-record-counts.d.ts +36 -0
  217. package/src/lib/model/crm-record-counts.js +54 -0
  218. package/src/lib/model/crm-record-counts.js.map +1 -0
  219. package/src/lib/model/crm-record-lists.d.ts +23 -0
  220. package/src/lib/model/crm-record-lists.js +161 -0
  221. package/src/lib/model/crm-record-lists.js.map +1 -0
  222. package/src/lib/model/crm-reports.d.ts +73 -3
  223. package/src/lib/model/crm-reports.js +120 -1
  224. package/src/lib/model/crm-reports.js.map +1 -1
  225. package/src/lib/model/crm-sharing.d.ts +21 -3
  226. package/src/lib/model/crm-sharing.js +27 -6
  227. package/src/lib/model/crm-sharing.js.map +1 -1
  228. package/src/lib/model/deal-board-model.d.ts +8 -2
  229. package/src/lib/model/deal-board-model.js +15 -2
  230. package/src/lib/model/deal-board-model.js.map +1 -1
  231. package/src/lib/model/deal-contact-roles.d.ts +45 -0
  232. package/src/lib/model/deal-contact-roles.js +73 -0
  233. package/src/lib/model/deal-contact-roles.js.map +1 -0
  234. package/src/lib/model/deal-form-model.d.ts +56 -0
  235. package/src/lib/model/deal-form-model.js +79 -7
  236. package/src/lib/model/deal-form-model.js.map +1 -1
  237. package/src/lib/model/download-text-file.d.ts +23 -0
  238. package/src/lib/model/download-text-file.js +34 -0
  239. package/src/lib/model/download-text-file.js.map +1 -0
  240. package/src/lib/model/lead-filters.d.ts +36 -2
  241. package/src/lib/model/lead-filters.js +123 -2
  242. package/src/lib/model/lead-filters.js.map +1 -1
  243. package/src/lib/model/lead-source-direction.d.ts +38 -0
  244. package/src/lib/model/lead-source-direction.js +52 -0
  245. package/src/lib/model/lead-source-direction.js.map +1 -0
  246. package/src/lib/model/picklist-values.d.ts +119 -0
  247. package/src/lib/model/picklist-values.js +256 -0
  248. package/src/lib/model/picklist-values.js.map +1 -0
  249. package/src/lib/model/record-facts-disclosed.d.ts +81 -0
  250. package/src/lib/model/record-facts-disclosed.js +281 -0
  251. package/src/lib/model/record-facts-disclosed.js.map +1 -0
  252. package/src/lib/model/record-facts.d.ts +215 -34
  253. package/src/lib/model/record-facts.js +307 -128
  254. package/src/lib/model/record-facts.js.map +1 -1
  255. package/src/lib/model/task-picklists.d.ts +52 -0
  256. package/src/lib/model/task-picklists.js +83 -0
  257. package/src/lib/model/task-picklists.js.map +1 -0
  258. package/src/lib/model/task-routes.d.ts +13 -0
  259. package/src/lib/model/task-routes.js +23 -4
  260. package/src/lib/model/task-routes.js.map +1 -1
  261. package/src/lib/plan-entitlements.js +6 -4
  262. package/src/lib/plan-entitlements.js.map +1 -1
  263. package/src/lib/plugin.js +17 -0
  264. package/src/lib/plugin.js.map +1 -1
  265. package/src/lib/server/api-v1/contacts.js +220 -14
  266. package/src/lib/server/api-v1/contacts.js.map +1 -1
  267. package/src/lib/server/api-v1/crm-activities.js +14 -1
  268. package/src/lib/server/api-v1/crm-activities.js.map +1 -1
  269. package/src/lib/server/api-v1/crm-companies.js +123 -14
  270. package/src/lib/server/api-v1/crm-companies.js.map +1 -1
  271. package/src/lib/server/api-v1/crm-deals.js +291 -26
  272. package/src/lib/server/api-v1/crm-deals.js.map +1 -1
  273. package/src/lib/server/api-v1/crm-leads.js +144 -38
  274. package/src/lib/server/api-v1/crm-leads.js.map +1 -1
  275. package/src/lib/server/api-v1/crm-pipelines.d.ts +6 -0
  276. package/src/lib/server/api-v1/crm-pipelines.js +8 -2
  277. package/src/lib/server/api-v1/crm-pipelines.js.map +1 -1
  278. package/src/lib/server/api-v1/crm-tasks.js +75 -33
  279. package/src/lib/server/api-v1/crm-tasks.js.map +1 -1
  280. package/src/lib/server/api-v1/openapi.d.ts +0 -11
  281. package/src/lib/server/api-v1/openapi.js +171 -16
  282. package/src/lib/server/api-v1/openapi.js.map +1 -1
  283. package/src/lib/server/assign-contact-owner.d.ts +162 -0
  284. package/src/lib/server/assign-contact-owner.js +340 -0
  285. package/src/lib/server/assign-contact-owner.js.map +1 -0
  286. package/src/lib/server/associate-company-by-domain.d.ts +70 -0
  287. package/src/lib/server/associate-company-by-domain.js +153 -0
  288. package/src/lib/server/associate-company-by-domain.js.map +1 -0
  289. package/src/lib/server/automation-steps.d.ts +139 -0
  290. package/src/lib/server/automation-steps.js +472 -0
  291. package/src/lib/server/automation-steps.js.map +1 -0
  292. package/src/lib/server/capture-contact.js +69 -22
  293. package/src/lib/server/capture-contact.js.map +1 -1
  294. package/src/lib/server/capture-host-contact.d.ts +104 -0
  295. package/src/lib/server/capture-host-contact.js +151 -0
  296. package/src/lib/server/capture-host-contact.js.map +1 -0
  297. package/src/lib/server/company-children.d.ts +25 -0
  298. package/src/lib/server/company-children.js +42 -0
  299. package/src/lib/server/company-children.js.map +1 -0
  300. package/src/lib/server/company-delete.d.ts +18 -0
  301. package/src/lib/server/company-delete.js +44 -21
  302. package/src/lib/server/company-delete.js.map +1 -1
  303. package/src/lib/server/contact-email-history.js +21 -19
  304. package/src/lib/server/contact-email-history.js.map +1 -1
  305. package/src/lib/server/contact-remove.js +27 -2
  306. package/src/lib/server/contact-remove.js.map +1 -1
  307. package/src/lib/server/contact-reports-to.d.ts +61 -0
  308. package/src/lib/server/contact-reports-to.js +114 -0
  309. package/src/lib/server/contact-reports-to.js.map +1 -0
  310. package/src/lib/server/contact-update.d.ts +42 -1
  311. package/src/lib/server/contact-update.js +204 -23
  312. package/src/lib/server/contact-update.js.map +1 -1
  313. package/src/lib/server/convert-host-lead.d.ts +46 -1
  314. package/src/lib/server/convert-host-lead.js +173 -15
  315. package/src/lib/server/convert-host-lead.js.map +1 -1
  316. package/src/lib/server/convert-open-lead.js +12 -5
  317. package/src/lib/server/convert-open-lead.js.map +1 -1
  318. package/src/lib/server/crm-record-indexes.d.ts +45 -0
  319. package/src/lib/server/crm-record-indexes.js +78 -0
  320. package/src/lib/server/crm-record-indexes.js.map +1 -0
  321. package/src/lib/server/crm-sharing.d.ts +9 -1
  322. package/src/lib/server/crm-sharing.js +23 -3
  323. package/src/lib/server/crm-sharing.js.map +1 -1
  324. package/src/lib/server/deal-contact-roles.d.ts +27 -0
  325. package/src/lib/server/deal-contact-roles.js +89 -0
  326. package/src/lib/server/deal-contact-roles.js.map +1 -0
  327. package/src/lib/server/lead-convert.d.ts +5 -0
  328. package/src/lib/server/lead-convert.js +19 -3
  329. package/src/lib/server/lead-convert.js.map +1 -1
  330. package/src/lib/server/lead-create.d.ts +17 -2
  331. package/src/lib/server/lead-create.js +46 -14
  332. package/src/lib/server/lead-create.js.map +1 -1
  333. package/src/lib/server/lead-nurturing.d.ts +6 -0
  334. package/src/lib/server/lead-nurturing.js +57 -20
  335. package/src/lib/server/lead-nurturing.js.map +1 -1
  336. package/src/lib/server/lead-picklists.d.ts +35 -0
  337. package/src/lib/server/lead-picklists.js +52 -0
  338. package/src/lib/server/lead-picklists.js.map +1 -0
  339. package/src/lib/server/lead-source-picklist.d.ts +1 -13
  340. package/src/lib/server/lead-source-picklist.js +6 -33
  341. package/src/lib/server/lead-source-picklist.js.map +1 -1
  342. package/src/lib/server/merge-contacts.js +22 -4
  343. package/src/lib/server/merge-contacts.js.map +1 -1
  344. package/src/lib/server/person-eraser.d.ts +53 -0
  345. package/src/lib/server/person-eraser.js +149 -0
  346. package/src/lib/server/person-eraser.js.map +1 -0
  347. package/src/lib/server/person-records.d.ts +69 -0
  348. package/src/lib/server/person-records.js +317 -0
  349. package/src/lib/server/person-records.js.map +1 -0
  350. package/src/lib/server/person-refund.d.ts +97 -0
  351. package/src/lib/server/person-refund.js +221 -0
  352. package/src/lib/server/person-refund.js.map +1 -0
  353. package/src/lib/server/picklist-values.d.ts +21 -0
  354. package/src/lib/server/picklist-values.js +308 -0
  355. package/src/lib/server/picklist-values.js.map +1 -0
  356. package/src/lib/server/read-picklist.d.ts +44 -0
  357. package/src/lib/server/read-picklist.js +65 -0
  358. package/src/lib/server/read-picklist.js.map +1 -0
  359. package/src/lib/server/recipe-routes.js +15 -7
  360. package/src/lib/server/recipe-routes.js.map +1 -1
  361. package/src/lib/server/record-email-state.js +7 -1
  362. package/src/lib/server/record-email-state.js.map +1 -1
  363. package/src/lib/server/record-facts.d.ts +3 -0
  364. package/src/lib/server/record-facts.js +233 -31
  365. package/src/lib/server/record-facts.js.map +1 -1
  366. package/src/lib/server/record-origin.d.ts +27 -0
  367. package/src/lib/server/record-origin.js +104 -0
  368. package/src/lib/server/record-origin.js.map +1 -0
  369. package/src/lib/server/record-timeline.js +15 -2
  370. package/src/lib/server/record-timeline.js.map +1 -1
  371. package/src/lib/server/suite-gate.js +4 -3
  372. package/src/lib/server/suite-gate.js.map +1 -1
  373. package/src/lib/server/task-routes.js +30 -16
  374. package/src/lib/server/task-routes.js.map +1 -1
  375. package/src/lib/server-deal-stage.d.ts +5 -1
  376. package/src/lib/server-deal-stage.js +10 -5
  377. package/src/lib/server-deal-stage.js.map +1 -1
  378. package/src/lib/server.d.ts +8 -3
  379. package/src/lib/server.js +47 -43
  380. package/src/lib/server.js.map +1 -1
  381. package/src/lib/testing/memory-firestore.d.ts +55 -0
  382. package/src/lib/testing/memory-firestore.js +335 -0
  383. package/src/lib/testing/memory-firestore.js.map +1 -0
  384. package/src/lib/testing/stand-in-email-send-index.d.ts +25 -0
  385. package/src/lib/testing/stand-in-email-send-index.js +49 -0
  386. package/src/lib/testing/stand-in-email-send-index.js.map +1 -0
  387. package/src/lib/transfer/activities.d.ts +30 -0
  388. package/src/lib/transfer/activities.js +132 -0
  389. package/src/lib/transfer/activities.js.map +1 -0
  390. package/src/lib/transfer/aliases.d.ts +22 -0
  391. package/src/lib/transfer/aliases.js +1342 -0
  392. package/src/lib/transfer/aliases.js.map +1 -0
  393. package/src/lib/transfer/common.d.ts +222 -0
  394. package/src/lib/transfer/common.js +832 -0
  395. package/src/lib/transfer/common.js.map +1 -0
  396. package/src/lib/transfer/companies.d.ts +43 -0
  397. package/src/lib/transfer/companies.js +549 -0
  398. package/src/lib/transfer/companies.js.map +1 -0
  399. package/src/lib/transfer/contacts.d.ts +31 -0
  400. package/src/lib/transfer/contacts.js +727 -0
  401. package/src/lib/transfer/contacts.js.map +1 -0
  402. package/src/lib/transfer/deals.d.ts +66 -0
  403. package/src/lib/transfer/deals.js +698 -0
  404. package/src/lib/transfer/deals.js.map +1 -0
  405. package/src/lib/transfer/email-templates-package.d.ts +40 -0
  406. package/src/lib/transfer/email-templates-package.js +76 -0
  407. package/src/lib/transfer/email-templates-package.js.map +1 -0
  408. package/src/lib/transfer/email-templates-package.server.d.ts +32 -0
  409. package/src/lib/transfer/email-templates-package.server.js +176 -0
  410. package/src/lib/transfer/email-templates-package.server.js.map +1 -0
  411. package/src/lib/transfer/fields.d.ts +102 -0
  412. package/src/lib/transfer/fields.js +1755 -0
  413. package/src/lib/transfer/fields.js.map +1 -0
  414. package/src/lib/transfer/leads.d.ts +30 -0
  415. package/src/lib/transfer/leads.js +582 -0
  416. package/src/lib/transfer/leads.js.map +1 -0
  417. package/src/lib/transfer/pipelines.d.ts +21 -0
  418. package/src/lib/transfer/pipelines.js +172 -0
  419. package/src/lib/transfer/pipelines.js.map +1 -0
  420. package/src/lib/transfer/register.d.ts +47 -0
  421. package/src/lib/transfer/register.js +277 -0
  422. package/src/lib/transfer/register.js.map +1 -0
  423. package/src/lib/transfer/tasks.d.ts +30 -0
  424. package/src/lib/transfer/tasks.js +418 -0
  425. package/src/lib/transfer/tasks.js.map +1 -0
  426. package/src/lib/transfer/ui.d.ts +20 -0
  427. package/src/lib/transfer/ui.js +42 -0
  428. package/src/lib/transfer/ui.js.map +1 -0
  429. package/src/lib/components/company-import-drawer.d.ts +0 -42
  430. package/src/lib/components/company-import-drawer.js +0 -99
  431. package/src/lib/components/company-import-drawer.js.map +0 -1
  432. package/src/lib/components/contact-import-drawer.d.ts +0 -46
  433. package/src/lib/components/contact-import-drawer.js +0 -149
  434. package/src/lib/components/contact-import-drawer.js.map +0 -1
  435. package/src/lib/components/crm-export-all-button.d.ts +0 -39
  436. package/src/lib/components/crm-export-all-button.js +0 -98
  437. package/src/lib/components/crm-export-all-button.js.map +0 -1
  438. package/src/lib/components/csv-import-drawer.d.ts +0 -139
  439. package/src/lib/components/csv-import-drawer.js +0 -757
  440. package/src/lib/components/csv-import-drawer.js.map +0 -1
  441. package/src/lib/components/deal-import-drawer.d.ts +0 -24
  442. package/src/lib/components/deal-import-drawer.js +0 -83
  443. package/src/lib/components/deal-import-drawer.js.map +0 -1
  444. package/src/lib/components/lead-import-drawer.d.ts +0 -27
  445. package/src/lib/components/lead-import-drawer.js +0 -118
  446. package/src/lib/components/lead-import-drawer.js.map +0 -1
  447. package/src/lib/components/lead-source-values-card.d.ts +0 -27
  448. package/src/lib/components/lead-source-values-card.js.map +0 -1
  449. package/src/lib/components/task-import-drawer.d.ts +0 -24
  450. package/src/lib/components/task-import-drawer.js +0 -82
  451. package/src/lib/components/task-import-drawer.js.map +0 -1
  452. package/src/lib/model/companies-csv.d.ts +0 -36
  453. package/src/lib/model/companies-csv.js +0 -38
  454. package/src/lib/model/companies-csv.js.map +0 -1
  455. package/src/lib/model/contacts-csv.d.ts +0 -54
  456. package/src/lib/model/contacts-csv.js +0 -67
  457. package/src/lib/model/contacts-csv.js.map +0 -1
  458. package/src/lib/model/crm-company-import.d.ts +0 -154
  459. package/src/lib/model/crm-company-import.js +0 -331
  460. package/src/lib/model/crm-company-import.js.map +0 -1
  461. package/src/lib/model/crm-csv.d.ts +0 -239
  462. package/src/lib/model/crm-csv.js +0 -467
  463. package/src/lib/model/crm-csv.js.map +0 -1
  464. package/src/lib/model/crm-deal-import.d.ts +0 -112
  465. package/src/lib/model/crm-deal-import.js +0 -263
  466. package/src/lib/model/crm-deal-import.js.map +0 -1
  467. package/src/lib/model/crm-import.d.ts +0 -250
  468. package/src/lib/model/crm-import.js +0 -467
  469. package/src/lib/model/crm-import.js.map +0 -1
  470. package/src/lib/model/crm-lead-import.d.ts +0 -138
  471. package/src/lib/model/crm-lead-import.js +0 -446
  472. package/src/lib/model/crm-lead-import.js.map +0 -1
  473. package/src/lib/model/crm-task-import.d.ts +0 -94
  474. package/src/lib/model/crm-task-import.js +0 -275
  475. package/src/lib/model/crm-task-import.js.map +0 -1
  476. package/src/lib/model/deals-csv.d.ts +0 -32
  477. package/src/lib/model/deals-csv.js +0 -36
  478. package/src/lib/model/deals-csv.js.map +0 -1
  479. package/src/lib/model/import-column-shapes.d.ts +0 -36
  480. package/src/lib/model/import-column-shapes.js +0 -76
  481. package/src/lib/model/import-column-shapes.js.map +0 -1
  482. package/src/lib/model/lead-source-values.d.ts +0 -82
  483. package/src/lib/model/lead-source-values.js +0 -149
  484. package/src/lib/model/lead-source-values.js.map +0 -1
  485. package/src/lib/model/leads-csv.d.ts +0 -40
  486. package/src/lib/model/leads-csv.js +0 -40
  487. package/src/lib/model/leads-csv.js.map +0 -1
  488. package/src/lib/model/tasks-csv.d.ts +0 -28
  489. package/src/lib/model/tasks-csv.js +0 -28
  490. package/src/lib/model/tasks-csv.js.map +0 -1
  491. package/src/lib/server/companies-import.d.ts +0 -57
  492. package/src/lib/server/companies-import.js +0 -242
  493. package/src/lib/server/companies-import.js.map +0 -1
  494. package/src/lib/server/contacts-import.d.ts +0 -109
  495. package/src/lib/server/contacts-import.js +0 -393
  496. package/src/lib/server/contacts-import.js.map +0 -1
  497. package/src/lib/server/deals-import.d.ts +0 -76
  498. package/src/lib/server/deals-import.js +0 -248
  499. package/src/lib/server/deals-import.js.map +0 -1
  500. package/src/lib/server/export-route.d.ts +0 -60
  501. package/src/lib/server/export-route.js +0 -447
  502. package/src/lib/server/export-route.js.map +0 -1
  503. package/src/lib/server/import-context.d.ts +0 -87
  504. package/src/lib/server/import-context.js +0 -182
  505. package/src/lib/server/import-context.js.map +0 -1
  506. package/src/lib/server/lead-source-values.d.ts +0 -50
  507. package/src/lib/server/lead-source-values.js +0 -191
  508. package/src/lib/server/lead-source-values.js.map +0 -1
  509. package/src/lib/server/leads-import.d.ts +0 -84
  510. package/src/lib/server/leads-import.js +0 -367
  511. package/src/lib/server/leads-import.js.map +0 -1
  512. package/src/lib/server/tasks-import.d.ts +0 -54
  513. package/src/lib/server/tasks-import.js +0 -160
  514. package/src/lib/server/tasks-import.js.map +0 -1
@@ -0,0 +1,727 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Aglyn LLC
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */ /*==========================================
18
+ * CONTACTS ON THE TRANSFER FRAMEWORK (AGL-3527) — the server half of
19
+ * `crm.contacts`.
20
+ *
21
+ * A contact is one person shared by every site of the workspace, and each
22
+ * site's consent group keeps its own profile of them — its facet. So a
23
+ * transfer reads and writes the facet of the site it was opened under: an
24
+ * export at the organization level reads each person's primary holder, as
25
+ * the org-level list does; an import always names a site, because a
26
+ * contact is a person some site met.
27
+ *
28
+ * ## The writes are the CRM's own
29
+ *
30
+ * A new person goes through `captureHostContact`, the door every capture
31
+ * goes through — the records band, the erasure check, the consent group's
32
+ * facet, `contactCreated` for the automations, the company by the email's
33
+ * domain and the owner by the assignment rules when the row names neither.
34
+ * A matched person is changed through the contact profile route's own
35
+ * patch (`contactPatch`): the composed name, the company link and its
36
+ * contact counts, the list's filter keys. A stage that moves raises
37
+ * `contactStageChanged`, as the stage route does.
38
+ *
39
+ * ## What a file may not do
40
+ *
41
+ * The locked rules: an existing contact's email is who they are; consent is
42
+ * never taken from a file; a stage moves forward only; Do not call is
43
+ * turned on by a file and never off; the full name follows the first and
44
+ * last names once either is set. The plan holds each one back by row and
45
+ * names it, so the person acknowledges it before anything is written.
46
+ *=========================================*/ import { composeContactName, contactDisplayName, contactFacetPath, CRM_COLLECTIONS, interactionsForGroup, isContactLifecycleStage, normalizeContactBirthdate, normalizePhone, planContactDetach, readContactFacet, readMarketingBasis } from "@aglyn/aglyn/server";
47
+ import { CONTACT_LIFECYCLE_STAGE_LABELS } from "@aglyn/aglyn/app-utils/crm";
48
+ import { CONTACT_EXTRA_PHONE_FIELDS as PHONE_FIELDS } from "@aglyn/aglyn/app-utils/contacts";
49
+ import { buildTransferPlan, planTransferUndo, rankTransferLookupSuggestions, TRANSFER_ID_FIELD, transferLookupNewName } from "@aglyn/aglyn/data-transfer";
50
+ import { prepareContactCaptureBatch, removeContactKeepingRefusals, restampCrmListFieldsOf } from "@aglyn/tenant-data-admin";
51
+ import { emitHostEvent } from "@aglyn/tenant-runtime";
52
+ import { FieldValue } from "firebase-admin/firestore";
53
+ import { contactPrimaryGroup } from "../model/contact-holder.js";
54
+ import { captureHostContact } from "../server/capture-host-contact.js";
55
+ import { CONTACT_NOTES_MAX } from "../server/contact-profile.js";
56
+ import { cachedContactReader, clearReportsToOf, CONTACT_REPORTS_TO_LOOP_REFUSAL, CONTACT_REPORTS_TO_SELF_REFUSAL, contactFacetHolders, contactReportsToLoops } from "../server/contact-reports-to.js";
57
+ import { contactPatch, settleCompanyCounts } from "../server/contact-update.js";
58
+ import { sweepDealContactRoles } from "../server/deal-contact-roles.js";
59
+ import { CONTACT_ALIASES } from "./aliases.js";
60
+ import { addCrmPicklistValues, addressFromValues, addressValues, countCrmExport, crmCustomDefinitions, crmMemberEmails, crmMembersTarget, crmPicklistLists, crmRecordsRoom, crmTransferEnv, customTransferValues, customWriteValues, eachWithinBudget, failureMessage, holdBackChanges, IN_LIMIT, isoOf, lookupByField, lookupById, lookupResult, pickValues, plannedValues, readCrmExportPage, requireCrmSuite, requireSite, textOf, TransferEngineError, visibleIn } from "./common.js";
61
+ import { companyForName } from "./companies.js";
62
+ import { CONTACT_TRANSFER_DERIVED, CONTACT_TRANSFER_FIELDS, CONTACT_TRANSFER_GROUPS, CRM_MEMBERS_TARGET, CRM_TIMESTAMP_FIELDS, crmCustomTransferFields, crmLifecycleStageOf, crmLifecycleStageRank } from "./fields.js";
63
+ /** The sentence an imported person's timeline opens with. */ export const CONTACT_TRANSFER_INTERACTION_SUMMARY = 'Imported from a file';
64
+ const SUITE_ACT = 'Importing contacts';
65
+ const contactsOf = (env)=>env.orgRef.collection('contacts');
66
+ /** The holder a contact is read through: the site's group, else the person's primary holder. */ function holderOf(env, contact) {
67
+ var _env_group;
68
+ return (_env_group = env.group) != null ? _env_group : contactPrimaryGroup(contact, env.org);
69
+ }
70
+ /** Why a capture refused a person, in the result's words. */ const CAPTURE_REFUSALS = {
71
+ band: 'The contact limit is reached.',
72
+ 'invalid-email': 'Not a valid email address.',
73
+ erased: 'Erased from this workspace at their request.',
74
+ error: 'The contact could not be saved.'
75
+ };
76
+ /**
77
+ * One contact as values by field id, read through one holder's facet. A
78
+ * lookup and an undo read links by id (`ids`), so the plan compares what is
79
+ * stored; an export writes names a file can carry back (`names`).
80
+ */ export function contactTransferValues(id, contact, group, definitions, names) {
81
+ var _names_manager, _names_owner, _facet_sources;
82
+ var _interactionsForGroup_;
83
+ const facet = readContactFacet(contact, group.groupId);
84
+ const text = (value)=>textOf(value) || null;
85
+ const stage = isContactLifecycleStage(facet.lifecycleStage) ? CONTACT_LIFECYCLE_STAGE_LABELS[facet.lifecycleStage] : null;
86
+ const basis = group.groupId ? readMarketingBasis(contact, group).basis : 'unrecorded';
87
+ const ownerUid = text(facet.ownerUid);
88
+ const managerId = text(facet.reportsToContactId);
89
+ return _extends({
90
+ // The name first: a record's label is the first text it holds.
91
+ name: text(contactDisplayName(contact, group.groupId)),
92
+ email: text(contact['email']),
93
+ salutation: text(facet.salutation),
94
+ firstName: text(facet.firstName),
95
+ lastName: text(facet.lastName),
96
+ birthdate: text(facet.birthdate),
97
+ phone: text(facet.phone),
98
+ mobilePhone: text(facet.mobilePhone),
99
+ homePhone: text(facet.homePhone),
100
+ otherPhone: text(facet.otherPhone),
101
+ fax: text(facet.fax),
102
+ doNotCall: facet.doNotCall === true,
103
+ assistantName: text(facet.assistantName),
104
+ assistantPhone: text(facet.assistantPhone),
105
+ jobTitle: text(facet.jobTitle),
106
+ department: text(facet.department),
107
+ company: names ? text(facet.companyName) : text(facet.companyId),
108
+ reportsTo: managerId ? names ? (_names_manager = names.manager(managerId)) != null ? _names_manager : managerId : managerId : null
109
+ }, addressValues('mailing', facet.address), addressValues('other', facet.otherAddress), {
110
+ owner: ownerUid ? names ? (_names_owner = names.owner(ownerUid)) != null ? _names_owner : ownerUid : ownerUid : null,
111
+ lifecycleStage: stage,
112
+ leadSource: text(facet.leadSource),
113
+ tags: Array.isArray(facet.tags) ? facet.tags : [],
114
+ notes: text(facet.notes),
115
+ marketingConsent: basis === 'granted' ? true : basis === 'declined' ? false : null,
116
+ sources: Object.keys((_facet_sources = facet.sources) != null ? _facet_sources : {}),
117
+ lastInteractionAt: isoOf((_interactionsForGroup_ = interactionsForGroup(facet.interactions, group.hostIds)[0]) == null ? void 0 : _interactionsForGroup_.atMs),
118
+ lastEngagedAt: isoOf(facet.lastEmailEngagementAtMs),
119
+ createdAt: isoOf(contact['createdAt']),
120
+ updatedAt: isoOf(contact['updatedAt'])
121
+ }, customTransferValues(definitions, facet.custom), {
122
+ [TRANSFER_ID_FIELD]: id
123
+ });
124
+ }
125
+ /** The contacts these ids name, as values through the site's facet. */ async function readContacts(env, ids, definitions) {
126
+ const out = new Map();
127
+ for(let at = 0; at < ids.length; at += 500){
128
+ const page = ids.slice(at, at + 500).filter((id)=>id && !id.includes('/'));
129
+ if (!page.length) continue;
130
+ for (const snapshot of (await env.firestore.getAll(...page.map((id)=>contactsOf(env).doc(id))))){
131
+ const data = snapshot.data();
132
+ if (snapshot.exists && data && visibleIn(env, data['visibleTo'])) {
133
+ out.set(snapshot.id, contactTransferValues(snapshot.id, data, holderOf(env, data), definitions));
134
+ }
135
+ }
136
+ }
137
+ return out;
138
+ }
139
+ /** The company a row's company column names, resolved: an id the engine found, or one created by name. */ async function companyLinkFor(run, value) {
140
+ if (value === null || value === undefined || value === '') return {
141
+ id: null,
142
+ name: ''
143
+ };
144
+ const create = transferLookupNewName(value);
145
+ if (create) {
146
+ const company = await companyForName(run.env, create, run.actorUid, run.companies, run.admit);
147
+ if (!company) throw new TransferEngineError('invalid', 422, 'The CRM records limit has no room for the company.');
148
+ return company;
149
+ }
150
+ const snapshot = await run.env.orgRef.collection(CRM_COLLECTIONS.companies).doc(String(value)).get();
151
+ if (!snapshot.exists || !visibleIn(run.env, snapshot.get('visibleTo'))) {
152
+ throw new TransferEngineError('notFound', 404, 'The company this row names no longer exists.');
153
+ }
154
+ return {
155
+ id: snapshot.id,
156
+ name: textOf(snapshot.get('name')).slice(0, 120)
157
+ };
158
+ }
159
+ /**
160
+ * A row's values as the profile route's fields: each one normalized the way
161
+ * that route reads it, a blank clearing it. Fields a value could not be
162
+ * stored as are left out and named in `skipped`.
163
+ */ function profileFields(values, stored) {
164
+ var _fields_firstName, _fields_lastName;
165
+ const fields = {};
166
+ const skipped = [];
167
+ const text = (key, max = 120)=>textOf(values[key]).slice(0, max);
168
+ for (const key of [
169
+ 'jobTitle',
170
+ 'department',
171
+ 'assistantName',
172
+ 'salutation',
173
+ 'leadSource'
174
+ ]){
175
+ if (key in values) fields[key] = text(key);
176
+ }
177
+ if ('firstName' in values) fields.firstName = composeContactName(text('firstName'), '');
178
+ if ('lastName' in values) fields.lastName = composeContactName('', text('lastName'));
179
+ for (const key of [
180
+ 'phone',
181
+ ...PHONE_FIELDS
182
+ ]){
183
+ if (!(key in values)) continue;
184
+ const typed = text(key, 40);
185
+ const phone = typed ? normalizePhone(typed) : '';
186
+ if (phone === null) skipped.push(key);
187
+ else fields[key] = phone;
188
+ }
189
+ if ('birthdate' in values) {
190
+ const birthdate = normalizeContactBirthdate(text('birthdate', 20));
191
+ if (birthdate === null) skipped.push('birthdate');
192
+ else fields.birthdate = birthdate;
193
+ }
194
+ if ('doNotCall' in values) fields.doNotCall = values['doNotCall'] === true;
195
+ if ('notes' in values) fields.notes = textOf(values['notes']).slice(0, CONTACT_NOTES_MAX);
196
+ if ('tags' in values) fields.tags = Array.isArray(values['tags']) ? values['tags'].slice(0, 20) : [];
197
+ if ('owner' in values) fields.ownerUid = text('owner', 128);
198
+ if ('reportsTo' in values) fields.reportsToContactId = text('reportsTo', 200) || null;
199
+ const mailing = addressFromValues('mailing', values, stored.address);
200
+ if (mailing !== undefined) fields.address = mailing;
201
+ const other = addressFromValues('other', values, stored.otherAddress);
202
+ if (other !== undefined) fields.otherAddress = other;
203
+ // The name follows the first and last names once either is set; only a
204
+ // holder with neither keeps a name of its own.
205
+ const composed = composeContactName((_fields_firstName = fields.firstName) != null ? _fields_firstName : stored.firstName, (_fields_lastName = fields.lastName) != null ? _fields_lastName : stored.lastName);
206
+ if ('name' in values && !composed) fields.name = text('name');
207
+ return {
208
+ fields,
209
+ skipped
210
+ };
211
+ }
212
+ /** The sentence a row's result carries for fields it could not store. */ function skippedMessage(skipped) {
213
+ if (!skipped.length) return undefined;
214
+ const labels = skipped.map((id)=>{
215
+ var _ref;
216
+ var _CONTACT_TRANSFER_FIELDS_find;
217
+ return (_ref = (_CONTACT_TRANSFER_FIELDS_find = CONTACT_TRANSFER_FIELDS.find((field)=>field.id === id)) == null ? void 0 : _CONTACT_TRANSFER_FIELDS_find.label) != null ? _ref : id;
218
+ });
219
+ return `Not written, as the value could not be read: ${labels.join(', ')}.`;
220
+ }
221
+ /**
222
+ * Writes one existing contact's values through the profile route's patch,
223
+ * and the stage beside it. Answers the stage it replaced when it moved one,
224
+ * and the fields left out.
225
+ */ async function writeContact(run, contactId, values) {
226
+ var _patch_update;
227
+ const ref = contactsOf(run.env).doc(contactId);
228
+ const snapshot = await ref.get();
229
+ const contact = snapshot.data();
230
+ if (!snapshot.exists || !contact || !visibleIn(run.env, contact['visibleTo'])) {
231
+ throw new TransferEngineError('notFound', 404, 'That contact no longer exists.');
232
+ }
233
+ const groupId = run.group.groupId;
234
+ const stored = readContactFacet(contact, groupId);
235
+ const { fields, skipped } = profileFields(values, stored);
236
+ let linkedCompanyName = '';
237
+ if ('company' in values) {
238
+ const link = await companyLinkFor(run, values['company']);
239
+ fields.companyId = link.id;
240
+ linkedCompanyName = link.name;
241
+ }
242
+ if (fields.reportsToContactId) {
243
+ const managerId = fields.reportsToContactId;
244
+ if (managerId === contactId) throw new TransferEngineError('invalid', 422, CONTACT_REPORTS_TO_SELF_REFUSAL);
245
+ if (await contactReportsToLoops(run.readContact, contactId, managerId, groupId)) {
246
+ throw new TransferEngineError('invalid', 422, CONTACT_REPORTS_TO_LOOP_REFUSAL);
247
+ }
248
+ }
249
+ const custom = customWriteValues(values, run.definitions, 'contact');
250
+ if ('error' in custom) throw new TransferEngineError('invalid', 422, custom.error);
251
+ const patch = contactPatch(contact, groupId, fields, custom.values, linkedCompanyName);
252
+ if ('refused' in patch) throw new TransferEngineError('invalid', 422, patch.refused);
253
+ const update = _extends({}, (_patch_update = patch.update) != null ? _patch_update : {});
254
+ let movedFrom = null;
255
+ if ('lifecycleStage' in values) {
256
+ const stage = crmLifecycleStageOf(values['lifecycleStage']);
257
+ const previous = isContactLifecycleStage(stored.lifecycleStage) ? stored.lifecycleStage : '';
258
+ if ((stage != null ? stage : '') !== previous) {
259
+ update[contactFacetPath(groupId, 'lifecycleStage')] = stage != null ? stage : FieldValue.delete();
260
+ if (stage) movedFrom = previous;
261
+ }
262
+ }
263
+ if (!Object.keys(update).length) return {
264
+ skipped
265
+ };
266
+ update['updatedAt'] = FieldValue.serverTimestamp();
267
+ await ref.update(update);
268
+ await restampCrmListFieldsOf([
269
+ ref
270
+ ], 'contacts');
271
+ await settleCompanyCounts(run.env.orgRef.collection(CRM_COLLECTIONS.companies), [
272
+ {
273
+ contactId,
274
+ ref,
275
+ update,
276
+ counts: patch.counts
277
+ }
278
+ ]);
279
+ if (movedFrom !== null) {
280
+ await emitHostEvent(run.hostId, 'contactStageChanged', {
281
+ contactId,
282
+ email: textOf(contact['email']),
283
+ lifecycleStage: String(crmLifecycleStageOf(values['lifecycleStage'])),
284
+ previousStage: movedFrom
285
+ }, run.actorUid ? {
286
+ actor: {
287
+ kind: 'member',
288
+ uid: run.actorUid,
289
+ email: null
290
+ }
291
+ } : {}).catch((error)=>console.error('[crm] transfer stage event failed', contactId, error));
292
+ }
293
+ return {
294
+ skipped
295
+ };
296
+ }
297
+ /** Creates one person through the capture door, then what the door does not take. */ async function createContact(run, values, batch) {
298
+ var _fields_tags;
299
+ const email = textOf(values['email']);
300
+ const { fields, skipped } = profileFields(values, {
301
+ sources: {},
302
+ interactions: []
303
+ });
304
+ const link = 'company' in values ? await companyLinkFor(run, values['company']) : null;
305
+ const custom = customWriteValues(values, run.definitions, 'contact');
306
+ if ('error' in custom) throw new TransferEngineError('invalid', 422, custom.error);
307
+ const stage = crmLifecycleStageOf(values['lifecycleStage']);
308
+ const verdict = await captureHostContact(_extends({
309
+ hostId: run.hostId,
310
+ email
311
+ }, fields.name ? {
312
+ name: fields.name
313
+ } : {}, {
314
+ source: 'import'
315
+ }, run.actorUid ? {
316
+ actor: {
317
+ kind: 'member',
318
+ uid: run.actorUid,
319
+ email: null
320
+ }
321
+ } : {}, {
322
+ interaction: {
323
+ summary: CONTACT_TRANSFER_INTERACTION_SUMMARY
324
+ },
325
+ tags: (_fields_tags = fields.tags) != null ? _fields_tags : [],
326
+ facet: _extends({}, fields.phone ? {
327
+ phone: fields.phone
328
+ } : {}, fields.jobTitle ? {
329
+ jobTitle: fields.jobTitle
330
+ } : {}, fields.salutation ? {
331
+ salutation: fields.salutation
332
+ } : {}, fields.firstName ? {
333
+ firstName: fields.firstName
334
+ } : {}, fields.lastName ? {
335
+ lastName: fields.lastName
336
+ } : {}, fields.department ? {
337
+ department: fields.department
338
+ } : {}, Object.fromEntries(PHONE_FIELDS.filter((key)=>fields[key]).map((key)=>[
339
+ key,
340
+ fields[key]
341
+ ])), fields.birthdate ? {
342
+ birthdate: fields.birthdate
343
+ } : {}, fields.assistantName ? {
344
+ assistantName: fields.assistantName
345
+ } : {}, fields.leadSource ? {
346
+ leadSource: fields.leadSource
347
+ } : {}, fields.doNotCall ? {
348
+ doNotCall: true
349
+ } : {}, fields.address ? {
350
+ address: fields.address
351
+ } : {}, fields.otherAddress ? {
352
+ otherAddress: fields.otherAddress
353
+ } : {}, (link == null ? void 0 : link.id) ? {
354
+ companyId: link.id,
355
+ companyName: link.name
356
+ } : {}, fields.ownerUid ? {
357
+ ownerUid: fields.ownerUid
358
+ } : {}, stage ? {
359
+ lifecycleStage: stage
360
+ } : {}, Object.keys(custom.values).length ? {
361
+ custom: custom.values
362
+ } : {}),
363
+ // An import files nobody under a campaign; the record's picker does.
364
+ campaignIds: []
365
+ }, batch ? {
366
+ batch
367
+ } : {}));
368
+ if ('refused' in verdict) {
369
+ var _CAPTURE_REFUSALS_verdict_refused;
370
+ throw new TransferEngineError('invalid', 422, (_CAPTURE_REFUSALS_verdict_refused = CAPTURE_REFUSALS[verdict.refused]) != null ? _CAPTURE_REFUSALS_verdict_refused : CAPTURE_REFUSALS['error']);
371
+ }
372
+ // What the capture door does not write: who they report to, and the notes.
373
+ const extra = {};
374
+ if (fields.reportsToContactId) extra['reportsTo'] = fields.reportsToContactId;
375
+ if (fields.notes) extra['notes'] = fields.notes;
376
+ if (Object.keys(extra).length) await writeContact(run, verdict.contactId, extra);
377
+ return {
378
+ contactId: verdict.contactId,
379
+ created: verdict.created,
380
+ skipped
381
+ };
382
+ }
383
+ /** The `crm.contacts` hooks. */ export function contactsTransferResource() {
384
+ return {
385
+ async fields (ctx) {
386
+ const env = await crmTransferEnv(ctx);
387
+ return {
388
+ standard: CONTACT_TRANSFER_FIELDS,
389
+ derived: CONTACT_TRANSFER_DERIVED,
390
+ system: CRM_TIMESTAMP_FIELDS,
391
+ custom: crmCustomTransferFields(await crmCustomDefinitions(env, 'contact'), 'contact'),
392
+ groups: CONTACT_TRANSFER_GROUPS
393
+ };
394
+ },
395
+ matchKeys: [
396
+ {
397
+ fieldId: TRANSFER_ID_FIELD,
398
+ normalizer: 'aglynId'
399
+ },
400
+ {
401
+ fieldId: 'email',
402
+ normalizer: 'email'
403
+ }
404
+ ],
405
+ aliases: CONTACT_ALIASES,
406
+ lookupTargets: {
407
+ [CRM_MEMBERS_TARGET]: crmMembersTarget()
408
+ },
409
+ // The people a workspace holds are its own on every plan (AGL-2839):
410
+ // exporting them asks nothing of the plan.
411
+ async count (ctx, options) {
412
+ const env = await crmTransferEnv(ctx);
413
+ return countCrmExport(env, contactsOf(env), options, (data)=>visibleIn(env, data['visibleTo'], options.scopeTokens));
414
+ },
415
+ async readPage (ctx, cursor, fieldIds, options) {
416
+ const env = await crmTransferEnv(ctx);
417
+ const definitions = await crmCustomDefinitions(env, 'contact');
418
+ const emails = fieldIds.includes('owner') ? await crmMemberEmails(env.orgId) : new Map();
419
+ return readCrmExportPage(env, contactsOf(env), cursor, options, (data)=>visibleIn(env, data['visibleTo'], options == null ? void 0 : options.scopeTokens), async (docs)=>{
420
+ const managers = new Map();
421
+ if (fieldIds.includes('reportsTo')) {
422
+ const ids = [
423
+ ...new Set(docs.map((doc)=>textOf(readContactFacet(doc.data, holderOf(env, doc.data).groupId).reportsToContactId)).filter((id)=>id && !id.includes('/')))
424
+ ];
425
+ for(let at = 0; at < ids.length; at += 500){
426
+ const page = ids.slice(at, at + 500);
427
+ for (const snapshot of (await env.firestore.getAll(...page.map((id)=>contactsOf(env).doc(id))))){
428
+ if (snapshot.exists) managers.set(snapshot.id, textOf(snapshot.get('email')));
429
+ }
430
+ }
431
+ }
432
+ return docs.map((doc)=>pickValues(contactTransferValues(doc.id, doc.data, holderOf(env, doc.data), definitions, {
433
+ owner: (uid)=>emails.get(uid),
434
+ manager: (id)=>managers.get(id)
435
+ }), fieldIds));
436
+ });
437
+ },
438
+ async lookup (ctx, requests) {
439
+ const env = await crmTransferEnv(ctx);
440
+ const definitions = await crmCustomDefinitions(env, 'contact');
441
+ const visible = (data)=>visibleIn(env, data['visibleTo']);
442
+ const found = {
443
+ lookup: new Map(),
444
+ docs: new Map()
445
+ };
446
+ for (const request of requests){
447
+ if (request.fieldId === TRANSFER_ID_FIELD) await lookupById(env, contactsOf(env), request, visible, found);
448
+ else if (request.fieldId === 'email') {
449
+ await lookupByField(contactsOf(env), request, 'email', (value)=>value.trim().toLowerCase(), visible, found);
450
+ }
451
+ }
452
+ return lookupResult(found, (id, data)=>contactTransferValues(id, data, holderOf(env, data), definitions));
453
+ },
454
+ async suggest (ctx, request) {
455
+ const env = await crmTransferEnv(ctx);
456
+ const answer = {};
457
+ for (const value of request.values){
458
+ var _ref;
459
+ var _value_trim_toLowerCase_split_;
460
+ // People sharing the value's first word: the token the list's own
461
+ // search reads, so a mistyped domain still finds the person.
462
+ const word = (_ref = (_value_trim_toLowerCase_split_ = value.trim().toLowerCase().split(/[\s@.+_-]+/)[0]) == null ? void 0 : _value_trim_toLowerCase_split_.slice(0, 12)) != null ? _ref : '';
463
+ if (word.length < 2) {
464
+ answer[value] = [];
465
+ continue;
466
+ }
467
+ const snapshot = await contactsOf(env).where('searchTokens', 'array-contains', word).limit(IN_LIMIT).get();
468
+ const candidates = snapshot.docs.filter((doc)=>visibleIn(env, doc.get('visibleTo'))).flatMap((doc)=>{
469
+ const email = textOf(doc.get('email'));
470
+ return email ? [
471
+ {
472
+ recordId: doc.id,
473
+ label: email
474
+ }
475
+ ] : [];
476
+ });
477
+ answer[value] = rankTransferLookupSuggestions(value, candidates);
478
+ }
479
+ return answer;
480
+ },
481
+ async picklists (ctx, ids) {
482
+ const env = await crmTransferEnv(ctx);
483
+ return crmPicklistLists(env, ids, await crmCustomDefinitions(env, 'contact'));
484
+ },
485
+ async addPicklistValues (ctx, picklistId, values) {
486
+ await addCrmPicklistValues(await crmTransferEnv(ctx), picklistId, values);
487
+ },
488
+ lockedRules: ()=>[
489
+ {
490
+ fieldId: 'email',
491
+ reason: 'An existing contact’s email is who they are; change it on the contact’s page.',
492
+ forced: {
493
+ mode: 'keepExisting'
494
+ }
495
+ },
496
+ {
497
+ fieldId: 'marketingConsent',
498
+ reason: 'Consent is never taken from a file: a person gives it on a form, or a team member records how it was given on the contact’s page.',
499
+ refuseValues: true
500
+ },
501
+ {
502
+ fieldId: 'lifecycleStage',
503
+ reason: 'A stage moves forward only: a later stage in the file advances the contact, an earlier one is held back.',
504
+ forced: {
505
+ mode: 'overwrite'
506
+ }
507
+ },
508
+ {
509
+ fieldId: 'doNotCall',
510
+ reason: 'A file can say a person asked not to be called, never that they took it back.',
511
+ forced: {
512
+ mode: 'overwrite'
513
+ }
514
+ },
515
+ {
516
+ fieldId: 'name',
517
+ reason: 'The full name is built from the first and last names once either is set.'
518
+ }
519
+ ],
520
+ async plan (ctx, input) {
521
+ const env = await crmTransferEnv(ctx);
522
+ requireCrmSuite(env, SUITE_ACT);
523
+ requireSite(env, 'contacts');
524
+ const plan = buildTransferPlan(input);
525
+ return holdBackChanges(plan, (row, change)=>{
526
+ const before = row.recordId ? input.existing.get(row.recordId) : undefined;
527
+ if (change.fieldId === 'lifecycleStage' && before) {
528
+ const from = crmLifecycleStageRank(before['lifecycleStage']);
529
+ const to = crmLifecycleStageRank(change.after);
530
+ if (from >= 0 && (to < from || to < 0)) return 'A stage moves forward only.';
531
+ }
532
+ if (change.fieldId === 'doNotCall' && (before == null ? void 0 : before['doNotCall']) === true && change.after !== true) {
533
+ return 'Do not call is turned off on the contact’s page, never by a file.';
534
+ }
535
+ if (change.fieldId === 'name') {
536
+ const values = Object.fromEntries(row.diff.map((entry)=>[
537
+ entry.fieldId,
538
+ entry.after
539
+ ]));
540
+ const first = 'firstName' in values ? values['firstName'] : before == null ? void 0 : before['firstName'];
541
+ const last = 'lastName' in values ? values['lastName'] : before == null ? void 0 : before['lastName'];
542
+ if (textOf(first) || textOf(last)) return 'Built from the first and last names.';
543
+ }
544
+ return null;
545
+ });
546
+ },
547
+ async apply (ctx, chunk, writer) {
548
+ const env = await crmTransferEnv(ctx);
549
+ requireCrmSuite(env, SUITE_ACT);
550
+ const { hostId, group } = requireSite(env, 'contacts');
551
+ const run = {
552
+ env,
553
+ hostId,
554
+ group,
555
+ actorUid: ctx.actorUid,
556
+ definitions: await crmCustomDefinitions(env, 'contact'),
557
+ companies: new Map(),
558
+ admit: crmRecordsRoom(env),
559
+ readContact: cachedContactReader(contactsOf(env))
560
+ };
561
+ const rows = chunk.rows;
562
+ const creating = [];
563
+ for (const row of rows){
564
+ if (row.verdict === 'create' && !await writer.alreadyApplied(row.index)) {
565
+ const email = textOf(plannedValues(row)['email']);
566
+ if (email) creating.push(email);
567
+ }
568
+ }
569
+ // The capture door's lookups for every new person at once (AGL-3423).
570
+ const batch = creating.length ? await prepareContactCaptureBatch(hostId, creating) : undefined;
571
+ const results = [];
572
+ const undo = [];
573
+ await eachWithinBudget(rows, ()=>writer.timeLeftMs(), async (row)=>{
574
+ const earlier = await writer.alreadyApplied(row.index);
575
+ if (earlier) {
576
+ results.push(earlier);
577
+ return;
578
+ }
579
+ const changed = row.diff.map((change)=>change.fieldId);
580
+ let result;
581
+ let entry;
582
+ try {
583
+ const values = plannedValues(row);
584
+ if (row.verdict === 'update' && row.recordId) {
585
+ var _get;
586
+ const before = (await readContacts(env, [
587
+ row.recordId
588
+ ], run.definitions)).get(row.recordId);
589
+ if (!before) throw new TransferEngineError('notFound', 404, 'That contact no longer exists.');
590
+ const { skipped } = await writeContact(run, row.recordId, values);
591
+ const after = (_get = (await readContacts(env, [
592
+ row.recordId
593
+ ], run.definitions)).get(row.recordId)) != null ? _get : {};
594
+ const message = skippedMessage(skipped);
595
+ result = _extends({
596
+ row: row.index,
597
+ outcome: 'updated',
598
+ recordId: row.recordId
599
+ }, message ? {
600
+ message
601
+ } : {});
602
+ entry = {
603
+ row: row.index,
604
+ recordId: row.recordId,
605
+ action: 'updated',
606
+ previous: pickValues(before, changed),
607
+ written: pickValues(after, changed)
608
+ };
609
+ } else {
610
+ var _get1;
611
+ const made = await createContact(run, values, batch);
612
+ const after = (_get1 = (await readContacts(env, [
613
+ made.contactId
614
+ ], run.definitions)).get(made.contactId)) != null ? _get1 : {};
615
+ const message = made.created ? skippedMessage(made.skipped) : 'Merged into the contact already holding this email.';
616
+ result = _extends({
617
+ row: row.index,
618
+ outcome: made.created ? 'created' : 'updated',
619
+ recordId: made.contactId
620
+ }, message ? {
621
+ message
622
+ } : {});
623
+ // A merge into a person somebody else created meanwhile has no
624
+ // "before" to put back, so undo leaves it alone.
625
+ entry = made.created ? {
626
+ row: row.index,
627
+ recordId: made.contactId,
628
+ action: 'created',
629
+ written: pickValues(after, changed)
630
+ } : undefined;
631
+ }
632
+ } catch (error) {
633
+ result = _extends({
634
+ row: row.index,
635
+ outcome: 'failed'
636
+ }, row.recordId ? {
637
+ recordId: row.recordId
638
+ } : {}, {
639
+ message: failureMessage(error)
640
+ });
641
+ entry = undefined;
642
+ }
643
+ await writer.markApplied(result, entry);
644
+ results.push(result);
645
+ if (entry) undo.push(entry);
646
+ });
647
+ return {
648
+ results,
649
+ undo
650
+ };
651
+ },
652
+ async revert (ctx, snapshot, decisions) {
653
+ const env = await crmTransferEnv(ctx);
654
+ const { hostId, group } = requireSite(env, 'contacts');
655
+ const run = {
656
+ env,
657
+ hostId,
658
+ group,
659
+ actorUid: ctx.actorUid,
660
+ definitions: await crmCustomDefinitions(env, 'contact'),
661
+ companies: new Map(),
662
+ admit: crmRecordsRoom(env),
663
+ readContact: cachedContactReader(contactsOf(env))
664
+ };
665
+ const current = await readContacts(env, snapshot.entries.map((entry)=>entry.recordId), run.definitions);
666
+ const done = [];
667
+ const conflicts = [];
668
+ for (const entry of snapshot.entries){
669
+ var _current_get;
670
+ const step = planTransferUndo(entry, (_current_get = current.get(entry.recordId)) != null ? _current_get : null);
671
+ if (step.action === 'conflict' && (decisions == null ? void 0 : decisions[entry.recordId]) !== 'revert') {
672
+ if ((decisions == null ? void 0 : decisions[entry.recordId]) === 'keep') done.push({
673
+ action: 'nothing',
674
+ recordId: entry.recordId,
675
+ why: 'alreadyReverted'
676
+ });
677
+ else conflicts.push(step);
678
+ continue;
679
+ }
680
+ if (step.action === 'nothing') {
681
+ done.push(step);
682
+ continue;
683
+ }
684
+ if (entry.action === 'created') {
685
+ // The site lets the person go, as "Remove from this site" does: a
686
+ // person only this import's site held is deleted, keeping every
687
+ // refusal they made; one another site holds too stays theirs.
688
+ const contactRef = contactsOf(env).doc(entry.recordId);
689
+ let holders = [];
690
+ const removal = await removeContactKeepingRefusals({
691
+ contactRef,
692
+ decide: (contact)=>{
693
+ holders = contactFacetHolders(contact);
694
+ return planContactDetach(contact, group);
695
+ },
696
+ nowMs: Date.now()
697
+ });
698
+ if (removal.outcome === 'deleted') {
699
+ await clearReportsToOf(env.firestore, contactsOf(env), holders, entry.recordId);
700
+ await sweepDealContactRoles(env.firestore, env.orgRef.collection(CRM_COLLECTIONS.deals), entry.recordId, null, '[crm] transfer undo');
701
+ } else if (removal.outcome === 'detached') {
702
+ await clearReportsToOf(env.firestore, contactsOf(env), [
703
+ group.groupId
704
+ ], entry.recordId);
705
+ await restampCrmListFieldsOf([
706
+ contactRef
707
+ ], 'contacts').catch(()=>undefined);
708
+ }
709
+ done.push({
710
+ action: 'delete',
711
+ recordId: entry.recordId
712
+ });
713
+ continue;
714
+ }
715
+ const values = step.action === 'restore' || step.action === 'conflict' ? step.values : {};
716
+ await writeContact(run, entry.recordId, values);
717
+ done.push(step);
718
+ }
719
+ return {
720
+ done,
721
+ conflicts
722
+ };
723
+ }
724
+ };
725
+ }
726
+
727
+ //# sourceMappingURL=contacts.js.map