@aglyn/plugins-crm 1.0.0-beta.143

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 (669) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +7 -0
  3. package/package.json +57 -0
  4. package/src/index.d.ts +21 -0
  5. package/src/index.js +29 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/components/activity-list.d.ts +98 -0
  8. package/src/lib/components/activity-list.js +321 -0
  9. package/src/lib/components/activity-list.js.map +1 -0
  10. package/src/lib/components/activity-queries.d.ts +117 -0
  11. package/src/lib/components/activity-queries.js +198 -0
  12. package/src/lib/components/activity-queries.js.map +1 -0
  13. package/src/lib/components/add-to-list-button.d.ts +25 -0
  14. package/src/lib/components/add-to-list-button.js +64 -0
  15. package/src/lib/components/add-to-list-button.js.map +1 -0
  16. package/src/lib/components/add-to-list-dialog.d.ts +24 -0
  17. package/src/lib/components/add-to-list-dialog.js +327 -0
  18. package/src/lib/components/add-to-list-dialog.js.map +1 -0
  19. package/src/lib/components/assignment-rule-drawer.d.ts +43 -0
  20. package/src/lib/components/assignment-rule-drawer.js +293 -0
  21. package/src/lib/components/assignment-rule-drawer.js.map +1 -0
  22. package/src/lib/components/companies-bulk-bar.d.ts +29 -0
  23. package/src/lib/components/companies-bulk-bar.js +274 -0
  24. package/src/lib/components/companies-bulk-bar.js.map +1 -0
  25. package/src/lib/components/companies-section.d.ts +54 -0
  26. package/src/lib/components/companies-section.js +522 -0
  27. package/src/lib/components/companies-section.js.map +1 -0
  28. package/src/lib/components/company-contacts-card.d.ts +49 -0
  29. package/src/lib/components/company-contacts-card.js +435 -0
  30. package/src/lib/components/company-contacts-card.js.map +1 -0
  31. package/src/lib/components/company-deals-card.d.ts +20 -0
  32. package/src/lib/components/company-deals-card.js +38 -0
  33. package/src/lib/components/company-deals-card.js.map +1 -0
  34. package/src/lib/components/company-detail-page.d.ts +20 -0
  35. package/src/lib/components/company-detail-page.js +165 -0
  36. package/src/lib/components/company-detail-page.js.map +1 -0
  37. package/src/lib/components/company-edit-drawer.d.ts +65 -0
  38. package/src/lib/components/company-edit-drawer.js +433 -0
  39. package/src/lib/components/company-edit-drawer.js.map +1 -0
  40. package/src/lib/components/company-import-drawer.d.ts +42 -0
  41. package/src/lib/components/company-import-drawer.js +99 -0
  42. package/src/lib/components/company-import-drawer.js.map +1 -0
  43. package/src/lib/components/company-picker.d.ts +127 -0
  44. package/src/lib/components/company-picker.js +323 -0
  45. package/src/lib/components/company-picker.js.map +1 -0
  46. package/src/lib/components/company-properties-card.d.ts +47 -0
  47. package/src/lib/components/company-properties-card.js +289 -0
  48. package/src/lib/components/company-properties-card.js.map +1 -0
  49. package/src/lib/components/contact-address-fields.d.ts +29 -0
  50. package/src/lib/components/contact-address-fields.js +149 -0
  51. package/src/lib/components/contact-address-fields.js.map +1 -0
  52. package/src/lib/components/contact-associations-card.d.ts +72 -0
  53. package/src/lib/components/contact-associations-card.js +296 -0
  54. package/src/lib/components/contact-associations-card.js.map +1 -0
  55. package/src/lib/components/contact-custom-columns.d.ts +38 -0
  56. package/src/lib/components/contact-custom-columns.js +102 -0
  57. package/src/lib/components/contact-custom-columns.js.map +1 -0
  58. package/src/lib/components/contact-custom-fields-card.d.ts +39 -0
  59. package/src/lib/components/contact-custom-fields-card.js +204 -0
  60. package/src/lib/components/contact-custom-fields-card.js.map +1 -0
  61. package/src/lib/components/contact-deals-card.d.ts +20 -0
  62. package/src/lib/components/contact-deals-card.js +38 -0
  63. package/src/lib/components/contact-deals-card.js.map +1 -0
  64. package/src/lib/components/contact-detail-page.d.ts +46 -0
  65. package/src/lib/components/contact-detail-page.js +535 -0
  66. package/src/lib/components/contact-detail-page.js.map +1 -0
  67. package/src/lib/components/contact-duplicates-card.d.ts +42 -0
  68. package/src/lib/components/contact-duplicates-card.js +167 -0
  69. package/src/lib/components/contact-duplicates-card.js.map +1 -0
  70. package/src/lib/components/contact-field-drawer.d.ts +64 -0
  71. package/src/lib/components/contact-field-drawer.js +251 -0
  72. package/src/lib/components/contact-field-drawer.js.map +1 -0
  73. package/src/lib/components/contact-import-drawer.d.ts +46 -0
  74. package/src/lib/components/contact-import-drawer.js +149 -0
  75. package/src/lib/components/contact-import-drawer.js.map +1 -0
  76. package/src/lib/components/contact-known-by-card.d.ts +39 -0
  77. package/src/lib/components/contact-known-by-card.js +142 -0
  78. package/src/lib/components/contact-known-by-card.js.map +1 -0
  79. package/src/lib/components/contact-list-columns.d.ts +53 -0
  80. package/src/lib/components/contact-list-columns.js +288 -0
  81. package/src/lib/components/contact-list-columns.js.map +1 -0
  82. package/src/lib/components/contact-merge-dialog.d.ts +79 -0
  83. package/src/lib/components/contact-merge-dialog.js +405 -0
  84. package/src/lib/components/contact-merge-dialog.js.map +1 -0
  85. package/src/lib/components/contact-properties-card.d.ts +89 -0
  86. package/src/lib/components/contact-properties-card.js +492 -0
  87. package/src/lib/components/contact-properties-card.js.map +1 -0
  88. package/src/lib/components/contact-timeline-card.d.ts +68 -0
  89. package/src/lib/components/contact-timeline-card.js +435 -0
  90. package/src/lib/components/contact-timeline-card.js.map +1 -0
  91. package/src/lib/components/contacts-bulk-bar.d.ts +91 -0
  92. package/src/lib/components/contacts-bulk-bar.js +493 -0
  93. package/src/lib/components/contacts-bulk-bar.js.map +1 -0
  94. package/src/lib/components/contacts-section.d.ts +26 -0
  95. package/src/lib/components/contacts-section.js +1025 -0
  96. package/src/lib/components/contacts-section.js.map +1 -0
  97. package/src/lib/components/copy-capture-address-button.d.ts +33 -0
  98. package/src/lib/components/copy-capture-address-button.js +60 -0
  99. package/src/lib/components/copy-capture-address-button.js.map +1 -0
  100. package/src/lib/components/crm-attribution-zone.d.ts +38 -0
  101. package/src/lib/components/crm-attribution-zone.js +36 -0
  102. package/src/lib/components/crm-attribution-zone.js.map +1 -0
  103. package/src/lib/components/crm-booking-zone.d.ts +61 -0
  104. package/src/lib/components/crm-booking-zone.js +50 -0
  105. package/src/lib/components/crm-booking-zone.js.map +1 -0
  106. package/src/lib/components/crm-bulk-bar-frame.d.ts +47 -0
  107. package/src/lib/components/crm-bulk-bar-frame.js +137 -0
  108. package/src/lib/components/crm-bulk-bar-frame.js.map +1 -0
  109. package/src/lib/components/crm-call-actions.d.ts +65 -0
  110. package/src/lib/components/crm-call-actions.js +110 -0
  111. package/src/lib/components/crm-call-actions.js.map +1 -0
  112. package/src/lib/components/crm-column-menu.d.ts +21 -0
  113. package/src/lib/components/crm-column-menu.js +103 -0
  114. package/src/lib/components/crm-column-menu.js.map +1 -0
  115. package/src/lib/components/crm-console-page.d.ts +19 -0
  116. package/src/lib/components/crm-console-page.js +151 -0
  117. package/src/lib/components/crm-console-page.js.map +1 -0
  118. package/src/lib/components/crm-console-sections.d.ts +52 -0
  119. package/src/lib/components/crm-console-sections.js +83 -0
  120. package/src/lib/components/crm-console-sections.js.map +1 -0
  121. package/src/lib/components/crm-custom-field-control.d.ts +26 -0
  122. package/src/lib/components/crm-custom-field-control.js +131 -0
  123. package/src/lib/components/crm-custom-field-control.js.map +1 -0
  124. package/src/lib/components/crm-email-template-tools.d.ts +69 -0
  125. package/src/lib/components/crm-email-template-tools.js +240 -0
  126. package/src/lib/components/crm-email-template-tools.js.map +1 -0
  127. package/src/lib/components/crm-export-all-button.d.ts +39 -0
  128. package/src/lib/components/crm-export-all-button.js +98 -0
  129. package/src/lib/components/crm-export-all-button.js.map +1 -0
  130. package/src/lib/components/crm-filter-bar.d.ts +53 -0
  131. package/src/lib/components/crm-filter-bar.js +294 -0
  132. package/src/lib/components/crm-filter-bar.js.map +1 -0
  133. package/src/lib/components/crm-glance-card.d.ts +54 -0
  134. package/src/lib/components/crm-glance-card.js +219 -0
  135. package/src/lib/components/crm-glance-card.js.map +1 -0
  136. package/src/lib/components/crm-next-activity-column.d.ts +35 -0
  137. package/src/lib/components/crm-next-activity-column.js +100 -0
  138. package/src/lib/components/crm-next-activity-column.js.map +1 -0
  139. package/src/lib/components/crm-record-header.d.ts +97 -0
  140. package/src/lib/components/crm-record-header.js +160 -0
  141. package/src/lib/components/crm-record-header.js.map +1 -0
  142. package/src/lib/components/crm-record-insights-zone.d.ts +50 -0
  143. package/src/lib/components/crm-record-insights-zone.js +169 -0
  144. package/src/lib/components/crm-record-insights-zone.js.map +1 -0
  145. package/src/lib/components/crm-record-picker.d.ts +42 -0
  146. package/src/lib/components/crm-record-picker.js +104 -0
  147. package/src/lib/components/crm-record-picker.js.map +1 -0
  148. package/src/lib/components/crm-send-email-button.d.ts +39 -0
  149. package/src/lib/components/crm-send-email-button.js +81 -0
  150. package/src/lib/components/crm-send-email-button.js.map +1 -0
  151. package/src/lib/components/crm-send-email-dialog.d.ts +61 -0
  152. package/src/lib/components/crm-send-email-dialog.js +851 -0
  153. package/src/lib/components/crm-send-email-dialog.js.map +1 -0
  154. package/src/lib/components/crm-site-picker.d.ts +61 -0
  155. package/src/lib/components/crm-site-picker.js +99 -0
  156. package/src/lib/components/crm-site-picker.js.map +1 -0
  157. package/src/lib/components/crm-suite-lock.d.ts +29 -0
  158. package/src/lib/components/crm-suite-lock.js +114 -0
  159. package/src/lib/components/crm-suite-lock.js.map +1 -0
  160. package/src/lib/components/crm-tasks-due-card.d.ts +42 -0
  161. package/src/lib/components/crm-tasks-due-card.js +225 -0
  162. package/src/lib/components/crm-tasks-due-card.js.map +1 -0
  163. package/src/lib/components/crm-views-control.d.ts +65 -0
  164. package/src/lib/components/crm-views-control.js +518 -0
  165. package/src/lib/components/crm-views-control.js.map +1 -0
  166. package/src/lib/components/csv-import-drawer.d.ts +132 -0
  167. package/src/lib/components/csv-import-drawer.js +746 -0
  168. package/src/lib/components/csv-import-drawer.js.map +1 -0
  169. package/src/lib/components/deal-board.d.ts +70 -0
  170. package/src/lib/components/deal-board.js +478 -0
  171. package/src/lib/components/deal-board.js.map +1 -0
  172. package/src/lib/components/deal-detail-page.d.ts +18 -0
  173. package/src/lib/components/deal-detail-page.js +323 -0
  174. package/src/lib/components/deal-detail-page.js.map +1 -0
  175. package/src/lib/components/deal-edit-drawer.d.ts +59 -0
  176. package/src/lib/components/deal-edit-drawer.js +640 -0
  177. package/src/lib/components/deal-edit-drawer.js.map +1 -0
  178. package/src/lib/components/deal-import-drawer.d.ts +24 -0
  179. package/src/lib/components/deal-import-drawer.js +83 -0
  180. package/src/lib/components/deal-import-drawer.js.map +1 -0
  181. package/src/lib/components/deal-products-card.d.ts +48 -0
  182. package/src/lib/components/deal-products-card.js +614 -0
  183. package/src/lib/components/deal-products-card.js.map +1 -0
  184. package/src/lib/components/deal-properties-card.d.ts +29 -0
  185. package/src/lib/components/deal-properties-card.js +144 -0
  186. package/src/lib/components/deal-properties-card.js.map +1 -0
  187. package/src/lib/components/deal-stage-card.d.ts +24 -0
  188. package/src/lib/components/deal-stage-card.js +199 -0
  189. package/src/lib/components/deal-stage-card.js.map +1 -0
  190. package/src/lib/components/deals-bulk-bar.d.ts +31 -0
  191. package/src/lib/components/deals-bulk-bar.js +340 -0
  192. package/src/lib/components/deals-bulk-bar.js.map +1 -0
  193. package/src/lib/components/deals-section.d.ts +49 -0
  194. package/src/lib/components/deals-section.js +767 -0
  195. package/src/lib/components/deals-section.js.map +1 -0
  196. package/src/lib/components/email-capture-card.d.ts +42 -0
  197. package/src/lib/components/email-capture-card.js +134 -0
  198. package/src/lib/components/email-capture-card.js.map +1 -0
  199. package/src/lib/components/email-template-drawer.d.ts +33 -0
  200. package/src/lib/components/email-template-drawer.js +209 -0
  201. package/src/lib/components/email-template-drawer.js.map +1 -0
  202. package/src/lib/components/email-templates-card.d.ts +33 -0
  203. package/src/lib/components/email-templates-card.js +370 -0
  204. package/src/lib/components/email-templates-card.js.map +1 -0
  205. package/src/lib/components/erase-person-action.d.ts +92 -0
  206. package/src/lib/components/erase-person-action.js +261 -0
  207. package/src/lib/components/erase-person-action.js.map +1 -0
  208. package/src/lib/components/fields-section.d.ts +37 -0
  209. package/src/lib/components/fields-section.js +641 -0
  210. package/src/lib/components/fields-section.js.map +1 -0
  211. package/src/lib/components/form-contact-fields-card.d.ts +46 -0
  212. package/src/lib/components/form-contact-fields-card.js +253 -0
  213. package/src/lib/components/form-contact-fields-card.js.map +1 -0
  214. package/src/lib/components/insert-link-at-caret.d.ts +28 -0
  215. package/src/lib/components/insert-link-at-caret.js +37 -0
  216. package/src/lib/components/insert-link-at-caret.js.map +1 -0
  217. package/src/lib/components/lead-convert-dialog.d.ts +32 -0
  218. package/src/lib/components/lead-convert-dialog.js +493 -0
  219. package/src/lib/components/lead-convert-dialog.js.map +1 -0
  220. package/src/lib/components/lead-detail-page.d.ts +16 -0
  221. package/src/lib/components/lead-detail-page.js +163 -0
  222. package/src/lib/components/lead-detail-page.js.map +1 -0
  223. package/src/lib/components/lead-history-card.d.ts +32 -0
  224. package/src/lib/components/lead-history-card.js +165 -0
  225. package/src/lib/components/lead-history-card.js.map +1 -0
  226. package/src/lib/components/lead-import-drawer.d.ts +24 -0
  227. package/src/lib/components/lead-import-drawer.js +95 -0
  228. package/src/lib/components/lead-import-drawer.js.map +1 -0
  229. package/src/lib/components/lead-owner-select.d.ts +35 -0
  230. package/src/lib/components/lead-owner-select.js +91 -0
  231. package/src/lib/components/lead-owner-select.js.map +1 -0
  232. package/src/lib/components/lead-properties-card.d.ts +61 -0
  233. package/src/lib/components/lead-properties-card.js +395 -0
  234. package/src/lib/components/lead-properties-card.js.map +1 -0
  235. package/src/lib/components/lead-status-chip.d.ts +12 -0
  236. package/src/lib/components/lead-status-chip.js +43 -0
  237. package/src/lib/components/lead-status-chip.js.map +1 -0
  238. package/src/lib/components/lead-surfaces-note.d.ts +126 -0
  239. package/src/lib/components/lead-surfaces-note.js +262 -0
  240. package/src/lib/components/lead-surfaces-note.js.map +1 -0
  241. package/src/lib/components/lead-unqualify-dialog.d.ts +24 -0
  242. package/src/lib/components/lead-unqualify-dialog.js +125 -0
  243. package/src/lib/components/lead-unqualify-dialog.js.map +1 -0
  244. package/src/lib/components/leads-bulk-bar.d.ts +58 -0
  245. package/src/lib/components/leads-bulk-bar.js +307 -0
  246. package/src/lib/components/leads-bulk-bar.js.map +1 -0
  247. package/src/lib/components/leads-section.d.ts +23 -0
  248. package/src/lib/components/leads-section.js +664 -0
  249. package/src/lib/components/leads-section.js.map +1 -0
  250. package/src/lib/components/linked-deals-card.d.ts +32 -0
  251. package/src/lib/components/linked-deals-card.js +163 -0
  252. package/src/lib/components/linked-deals-card.js.map +1 -0
  253. package/src/lib/components/log-activity-dialog.d.ts +60 -0
  254. package/src/lib/components/log-activity-dialog.js +368 -0
  255. package/src/lib/components/log-activity-dialog.js.map +1 -0
  256. package/src/lib/components/lost-reason-dialog.d.ts +26 -0
  257. package/src/lib/components/lost-reason-dialog.js +95 -0
  258. package/src/lib/components/lost-reason-dialog.js.map +1 -0
  259. package/src/lib/components/new-contact-drawer.d.ts +78 -0
  260. package/src/lib/components/new-contact-drawer.js +343 -0
  261. package/src/lib/components/new-contact-drawer.js.map +1 -0
  262. package/src/lib/components/org-lead-surfaces-note.d.ts +57 -0
  263. package/src/lib/components/org-lead-surfaces-note.js +172 -0
  264. package/src/lib/components/org-lead-surfaces-note.js.map +1 -0
  265. package/src/lib/components/owner-avatar.d.ts +18 -0
  266. package/src/lib/components/owner-avatar.js +61 -0
  267. package/src/lib/components/owner-avatar.js.map +1 -0
  268. package/src/lib/components/pipeline-stages-dialog.d.ts +43 -0
  269. package/src/lib/components/pipeline-stages-dialog.js +339 -0
  270. package/src/lib/components/pipeline-stages-dialog.js.map +1 -0
  271. package/src/lib/components/pipelines-dialog.d.ts +55 -0
  272. package/src/lib/components/pipelines-dialog.js +517 -0
  273. package/src/lib/components/pipelines-dialog.js.map +1 -0
  274. package/src/lib/components/recent-activity-feed.d.ts +39 -0
  275. package/src/lib/components/recent-activity-feed.js +103 -0
  276. package/src/lib/components/recent-activity-feed.js.map +1 -0
  277. package/src/lib/components/recipes-card.d.ts +39 -0
  278. package/src/lib/components/recipes-card.js +485 -0
  279. package/src/lib/components/recipes-card.js.map +1 -0
  280. package/src/lib/components/record-activity-card.d.ts +26 -0
  281. package/src/lib/components/record-activity-card.js +121 -0
  282. package/src/lib/components/record-activity-card.js.map +1 -0
  283. package/src/lib/components/record-files-card.d.ts +67 -0
  284. package/src/lib/components/record-files-card.js +290 -0
  285. package/src/lib/components/record-files-card.js.map +1 -0
  286. package/src/lib/components/record-tasks-card.d.ts +32 -0
  287. package/src/lib/components/record-tasks-card.js +306 -0
  288. package/src/lib/components/record-tasks-card.js.map +1 -0
  289. package/src/lib/components/reports/activity-card.d.ts +57 -0
  290. package/src/lib/components/reports/activity-card.js +281 -0
  291. package/src/lib/components/reports/activity-card.js.map +1 -0
  292. package/src/lib/components/reports/closed-deals-card.d.ts +20 -0
  293. package/src/lib/components/reports/closed-deals-card.js +194 -0
  294. package/src/lib/components/reports/closed-deals-card.js.map +1 -0
  295. package/src/lib/components/reports/contacts-mix-card.d.ts +27 -0
  296. package/src/lib/components/reports/contacts-mix-card.js +161 -0
  297. package/src/lib/components/reports/contacts-mix-card.js.map +1 -0
  298. package/src/lib/components/reports/contacts-trend-card.d.ts +31 -0
  299. package/src/lib/components/reports/contacts-trend-card.js +144 -0
  300. package/src/lib/components/reports/contacts-trend-card.js.map +1 -0
  301. package/src/lib/components/reports/forecast-card.d.ts +22 -0
  302. package/src/lib/components/reports/forecast-card.js +251 -0
  303. package/src/lib/components/reports/forecast-card.js.map +1 -0
  304. package/src/lib/components/reports/lead-counts.d.ts +32 -0
  305. package/src/lib/components/reports/lead-counts.js +44 -0
  306. package/src/lib/components/reports/lead-counts.js.map +1 -0
  307. package/src/lib/components/reports/lead-funnel-card.d.ts +38 -0
  308. package/src/lib/components/reports/lead-funnel-card.js +375 -0
  309. package/src/lib/components/reports/lead-funnel-card.js.map +1 -0
  310. package/src/lib/components/reports/pipeline-card.d.ts +19 -0
  311. package/src/lib/components/reports/pipeline-card.js +338 -0
  312. package/src/lib/components/reports/pipeline-card.js.map +1 -0
  313. package/src/lib/components/reports/report-bar-chart.d.ts +39 -0
  314. package/src/lib/components/reports/report-bar-chart.js +133 -0
  315. package/src/lib/components/reports/report-bar-chart.js.map +1 -0
  316. package/src/lib/components/reports/report-breakdown.d.ts +32 -0
  317. package/src/lib/components/reports/report-breakdown.js +105 -0
  318. package/src/lib/components/reports/report-breakdown.js.map +1 -0
  319. package/src/lib/components/reports/report-export.d.ts +37 -0
  320. package/src/lib/components/reports/report-export.js +66 -0
  321. package/src/lib/components/reports/report-export.js.map +1 -0
  322. package/src/lib/components/reports/report-format.d.ts +36 -0
  323. package/src/lib/components/reports/report-format.js +43 -0
  324. package/src/lib/components/reports/report-format.js.map +1 -0
  325. package/src/lib/components/reports/report-scope.d.ts +81 -0
  326. package/src/lib/components/reports/report-scope.js +58 -0
  327. package/src/lib/components/reports/report-scope.js.map +1 -0
  328. package/src/lib/components/reports/report-stat-tile.d.ts +47 -0
  329. package/src/lib/components/reports/report-stat-tile.js +96 -0
  330. package/src/lib/components/reports/report-stat-tile.js.map +1 -0
  331. package/src/lib/components/reports/source-conversion-card.d.ts +28 -0
  332. package/src/lib/components/reports/source-conversion-card.js +205 -0
  333. package/src/lib/components/reports/source-conversion-card.js.map +1 -0
  334. package/src/lib/components/reports/tasks-card.d.ts +26 -0
  335. package/src/lib/components/reports/tasks-card.js +279 -0
  336. package/src/lib/components/reports/tasks-card.js.map +1 -0
  337. package/src/lib/components/reports/use-aggregate-read.d.ts +99 -0
  338. package/src/lib/components/reports/use-aggregate-read.js +195 -0
  339. package/src/lib/components/reports/use-aggregate-read.js.map +1 -0
  340. package/src/lib/components/reports/won-lost-by-owner-card.d.ts +30 -0
  341. package/src/lib/components/reports/won-lost-by-owner-card.js +168 -0
  342. package/src/lib/components/reports/won-lost-by-owner-card.js.map +1 -0
  343. package/src/lib/components/reports-section.d.ts +42 -0
  344. package/src/lib/components/reports-section.js +308 -0
  345. package/src/lib/components/reports-section.js.map +1 -0
  346. package/src/lib/components/sending-addresses-card.d.ts +49 -0
  347. package/src/lib/components/sending-addresses-card.js +262 -0
  348. package/src/lib/components/sending-addresses-card.js.map +1 -0
  349. package/src/lib/components/settings-section.d.ts +151 -0
  350. package/src/lib/components/settings-section.js +783 -0
  351. package/src/lib/components/settings-section.js.map +1 -0
  352. package/src/lib/components/task-cells.d.ts +51 -0
  353. package/src/lib/components/task-cells.js +139 -0
  354. package/src/lib/components/task-cells.js.map +1 -0
  355. package/src/lib/components/task-edit-drawer.d.ts +53 -0
  356. package/src/lib/components/task-edit-drawer.js +483 -0
  357. package/src/lib/components/task-edit-drawer.js.map +1 -0
  358. package/src/lib/components/task-import-drawer.d.ts +24 -0
  359. package/src/lib/components/task-import-drawer.js +82 -0
  360. package/src/lib/components/task-import-drawer.js.map +1 -0
  361. package/src/lib/components/task-snooze-menu.d.ts +65 -0
  362. package/src/lib/components/task-snooze-menu.js +207 -0
  363. package/src/lib/components/task-snooze-menu.js.map +1 -0
  364. package/src/lib/components/tasks-bulk-bar.d.ts +25 -0
  365. package/src/lib/components/tasks-bulk-bar.js +348 -0
  366. package/src/lib/components/tasks-bulk-bar.js.map +1 -0
  367. package/src/lib/components/tasks-calendar.d.ts +38 -0
  368. package/src/lib/components/tasks-calendar.js +228 -0
  369. package/src/lib/components/tasks-calendar.js.map +1 -0
  370. package/src/lib/components/tasks-section.d.ts +27 -0
  371. package/src/lib/components/tasks-section.js +579 -0
  372. package/src/lib/components/tasks-section.js.map +1 -0
  373. package/src/lib/components/use-contact-campaign-emails.d.ts +32 -0
  374. package/src/lib/components/use-contact-campaign-emails.js +83 -0
  375. package/src/lib/components/use-contact-campaign-emails.js.map +1 -0
  376. package/src/lib/components/use-crm-api.d.ts +44 -0
  377. package/src/lib/components/use-crm-api.js +84 -0
  378. package/src/lib/components/use-crm-api.js.map +1 -0
  379. package/src/lib/components/use-crm-inbound-address.d.ts +60 -0
  380. package/src/lib/components/use-crm-inbound-address.js +124 -0
  381. package/src/lib/components/use-crm-inbound-address.js.map +1 -0
  382. package/src/lib/components/use-emails-hub-path.d.ts +24 -0
  383. package/src/lib/components/use-emails-hub-path.js +59 -0
  384. package/src/lib/components/use-emails-hub-path.js.map +1 -0
  385. package/src/lib/components/use-member-email-aliases.d.ts +54 -0
  386. package/src/lib/components/use-member-email-aliases.js +186 -0
  387. package/src/lib/components/use-member-email-aliases.js.map +1 -0
  388. package/src/lib/components/use-org-members.d.ts +40 -0
  389. package/src/lib/components/use-org-members.js +100 -0
  390. package/src/lib/components/use-org-members.js.map +1 -0
  391. package/src/lib/constants/api-routes.d.ts +109 -0
  392. package/src/lib/constants/api-routes.js +74 -0
  393. package/src/lib/constants/api-routes.js.map +1 -0
  394. package/src/lib/constants/bundle-common.d.ts +14 -0
  395. package/src/lib/constants/bundle-common.js +14 -0
  396. package/src/lib/constants/bundle-common.js.map +1 -0
  397. package/src/lib/constants/company-filters.d.ts +18 -0
  398. package/src/lib/constants/company-filters.js +51 -0
  399. package/src/lib/constants/company-filters.js.map +1 -0
  400. package/src/lib/constants/contact-filters.d.ts +38 -0
  401. package/src/lib/constants/contact-filters.js +294 -0
  402. package/src/lib/constants/contact-filters.js.map +1 -0
  403. package/src/lib/hooks/use-contact-field-definitions.d.ts +48 -0
  404. package/src/lib/hooks/use-contact-field-definitions.js +72 -0
  405. package/src/lib/hooks/use-contact-field-definitions.js.map +1 -0
  406. package/src/lib/hooks/use-contact-update.d.ts +25 -0
  407. package/src/lib/hooks/use-contact-update.js +80 -0
  408. package/src/lib/hooks/use-contact-update.js.map +1 -0
  409. package/src/lib/hooks/use-crm-activity-logger.d.ts +73 -0
  410. package/src/lib/hooks/use-crm-activity-logger.js +101 -0
  411. package/src/lib/hooks/use-crm-activity-logger.js.map +1 -0
  412. package/src/lib/hooks/use-crm-bulk-apply.d.ts +52 -0
  413. package/src/lib/hooks/use-crm-bulk-apply.js +112 -0
  414. package/src/lib/hooks/use-crm-bulk-apply.js.map +1 -0
  415. package/src/lib/hooks/use-crm-default-view.d.ts +24 -0
  416. package/src/lib/hooks/use-crm-default-view.js +64 -0
  417. package/src/lib/hooks/use-crm-default-view.js.map +1 -0
  418. package/src/lib/hooks/use-crm-email-templates.d.ts +59 -0
  419. package/src/lib/hooks/use-crm-email-templates.js +103 -0
  420. package/src/lib/hooks/use-crm-email-templates.js.map +1 -0
  421. package/src/lib/hooks/use-crm-hub-path.d.ts +29 -0
  422. package/src/lib/hooks/use-crm-hub-path.js +41 -0
  423. package/src/lib/hooks/use-crm-hub-path.js.map +1 -0
  424. package/src/lib/hooks/use-crm-org-mount.d.ts +97 -0
  425. package/src/lib/hooks/use-crm-org-mount.js +215 -0
  426. package/src/lib/hooks/use-crm-org-mount.js.map +1 -0
  427. package/src/lib/hooks/use-crm-record-names.d.ts +52 -0
  428. package/src/lib/hooks/use-crm-record-names.js +126 -0
  429. package/src/lib/hooks/use-crm-record-names.js.map +1 -0
  430. package/src/lib/hooks/use-crm-records-quota.d.ts +68 -0
  431. package/src/lib/hooks/use-crm-records-quota.js +118 -0
  432. package/src/lib/hooks/use-crm-records-quota.js.map +1 -0
  433. package/src/lib/hooks/use-crm-saved-view.d.ts +96 -0
  434. package/src/lib/hooks/use-crm-saved-view.js +329 -0
  435. package/src/lib/hooks/use-crm-saved-view.js.map +1 -0
  436. package/src/lib/hooks/use-crm-scope.d.ts +117 -0
  437. package/src/lib/hooks/use-crm-scope.js +147 -0
  438. package/src/lib/hooks/use-crm-scope.js.map +1 -0
  439. package/src/lib/hooks/use-crm-tasks.d.ts +85 -0
  440. package/src/lib/hooks/use-crm-tasks.js +153 -0
  441. package/src/lib/hooks/use-crm-tasks.js.map +1 -0
  442. package/src/lib/hooks/use-crm-view-grid.d.ts +55 -0
  443. package/src/lib/hooks/use-crm-view-grid.js +170 -0
  444. package/src/lib/hooks/use-crm-view-grid.js.map +1 -0
  445. package/src/lib/hooks/use-crm-views.d.ts +42 -0
  446. package/src/lib/hooks/use-crm-views.js +84 -0
  447. package/src/lib/hooks/use-crm-views.js.map +1 -0
  448. package/src/lib/hooks/use-deal-stage-api.d.ts +69 -0
  449. package/src/lib/hooks/use-deal-stage-api.js +78 -0
  450. package/src/lib/hooks/use-deal-stage-api.js.map +1 -0
  451. package/src/lib/hooks/use-deals.d.ts +47 -0
  452. package/src/lib/hooks/use-deals.js +105 -0
  453. package/src/lib/hooks/use-deals.js.map +1 -0
  454. package/src/lib/hooks/use-org-leads.d.ts +53 -0
  455. package/src/lib/hooks/use-org-leads.js +114 -0
  456. package/src/lib/hooks/use-org-leads.js.map +1 -0
  457. package/src/lib/hooks/use-org-member-directory.d.ts +36 -0
  458. package/src/lib/hooks/use-org-member-directory.js +116 -0
  459. package/src/lib/hooks/use-org-member-directory.js.map +1 -0
  460. package/src/lib/hooks/use-org-member-options.d.ts +38 -0
  461. package/src/lib/hooks/use-org-member-options.js +131 -0
  462. package/src/lib/hooks/use-org-member-options.js.map +1 -0
  463. package/src/lib/hooks/use-pipeline.d.ts +71 -0
  464. package/src/lib/hooks/use-pipeline.js +159 -0
  465. package/src/lib/hooks/use-pipeline.js.map +1 -0
  466. package/src/lib/model/companies-bulk-writes.d.ts +40 -0
  467. package/src/lib/model/companies-bulk-writes.js +103 -0
  468. package/src/lib/model/companies-bulk-writes.js.map +1 -0
  469. package/src/lib/model/companies-csv.d.ts +36 -0
  470. package/src/lib/model/companies-csv.js +38 -0
  471. package/src/lib/model/companies-csv.js.map +1 -0
  472. package/src/lib/model/companies.d.ts +99 -0
  473. package/src/lib/model/companies.js +168 -0
  474. package/src/lib/model/companies.js.map +1 -0
  475. package/src/lib/model/company-delete-route.d.ts +43 -0
  476. package/src/lib/model/company-delete-route.js +31 -0
  477. package/src/lib/model/company-delete-route.js.map +1 -0
  478. package/src/lib/model/company-delete.d.ts +42 -0
  479. package/src/lib/model/company-delete.js +52 -0
  480. package/src/lib/model/company-delete.js.map +1 -0
  481. package/src/lib/model/contact-duplicates.d.ts +58 -0
  482. package/src/lib/model/contact-duplicates.js +67 -0
  483. package/src/lib/model/contact-duplicates.js.map +1 -0
  484. package/src/lib/model/contact-record.d.ts +113 -0
  485. package/src/lib/model/contact-record.js +70 -0
  486. package/src/lib/model/contact-record.js.map +1 -0
  487. package/src/lib/model/contact-update.d.ts +93 -0
  488. package/src/lib/model/contact-update.js +50 -0
  489. package/src/lib/model/contact-update.js.map +1 -0
  490. package/src/lib/model/contacts-bulk-writes.d.ts +173 -0
  491. package/src/lib/model/contacts-bulk-writes.js +196 -0
  492. package/src/lib/model/contacts-bulk-writes.js.map +1 -0
  493. package/src/lib/model/contacts-csv.d.ts +54 -0
  494. package/src/lib/model/contacts-csv.js +67 -0
  495. package/src/lib/model/contacts-csv.js.map +1 -0
  496. package/src/lib/model/contacts-list-seed.d.ts +51 -0
  497. package/src/lib/model/contacts-list-seed.js +63 -0
  498. package/src/lib/model/contacts-list-seed.js.map +1 -0
  499. package/src/lib/model/crm-activity-report.d.ts +27 -0
  500. package/src/lib/model/crm-activity-report.js +56 -0
  501. package/src/lib/model/crm-activity-report.js.map +1 -0
  502. package/src/lib/model/crm-api.d.ts +49 -0
  503. package/src/lib/model/crm-api.js +47 -0
  504. package/src/lib/model/crm-api.js.map +1 -0
  505. package/src/lib/model/crm-bulk-writes.d.ts +147 -0
  506. package/src/lib/model/crm-bulk-writes.js +207 -0
  507. package/src/lib/model/crm-bulk-writes.js.map +1 -0
  508. package/src/lib/model/crm-company-import.d.ts +154 -0
  509. package/src/lib/model/crm-company-import.js +331 -0
  510. package/src/lib/model/crm-company-import.js.map +1 -0
  511. package/src/lib/model/crm-custom-draft.d.ts +62 -0
  512. package/src/lib/model/crm-custom-draft.js +67 -0
  513. package/src/lib/model/crm-custom-draft.js.map +1 -0
  514. package/src/lib/model/crm-deal-import.d.ts +112 -0
  515. package/src/lib/model/crm-deal-import.js +263 -0
  516. package/src/lib/model/crm-deal-import.js.map +1 -0
  517. package/src/lib/model/crm-import.d.ts +244 -0
  518. package/src/lib/model/crm-import.js +466 -0
  519. package/src/lib/model/crm-import.js.map +1 -0
  520. package/src/lib/model/crm-lead-import.d.ts +105 -0
  521. package/src/lib/model/crm-lead-import.js +255 -0
  522. package/src/lib/model/crm-lead-import.js.map +1 -0
  523. package/src/lib/model/crm-record-routes.d.ts +21 -0
  524. package/src/lib/model/crm-record-routes.js +70 -0
  525. package/src/lib/model/crm-record-routes.js.map +1 -0
  526. package/src/lib/model/crm-routes.d.ts +101 -0
  527. package/src/lib/model/crm-routes.js +92 -0
  528. package/src/lib/model/crm-routes.js.map +1 -0
  529. package/src/lib/model/crm-task-import.d.ts +94 -0
  530. package/src/lib/model/crm-task-import.js +275 -0
  531. package/src/lib/model/crm-task-import.js.map +1 -0
  532. package/src/lib/model/crm-view-param.d.ts +43 -0
  533. package/src/lib/model/crm-view-param.js +49 -0
  534. package/src/lib/model/crm-view-param.js.map +1 -0
  535. package/src/lib/model/deal-board-model.d.ts +241 -0
  536. package/src/lib/model/deal-board-model.js +439 -0
  537. package/src/lib/model/deal-board-model.js.map +1 -0
  538. package/src/lib/model/deal-form-model.d.ts +114 -0
  539. package/src/lib/model/deal-form-model.js +218 -0
  540. package/src/lib/model/deal-form-model.js.map +1 -0
  541. package/src/lib/model/deals-csv.d.ts +32 -0
  542. package/src/lib/model/deals-csv.js +37 -0
  543. package/src/lib/model/deals-csv.js.map +1 -0
  544. package/src/lib/model/import-column-shapes.d.ts +36 -0
  545. package/src/lib/model/import-column-shapes.js +76 -0
  546. package/src/lib/model/import-column-shapes.js.map +1 -0
  547. package/src/lib/model/lead-company-suggestion.d.ts +61 -0
  548. package/src/lib/model/lead-company-suggestion.js +65 -0
  549. package/src/lib/model/lead-company-suggestion.js.map +1 -0
  550. package/src/lib/model/lead-filters.d.ts +29 -0
  551. package/src/lib/model/lead-filters.js +39 -0
  552. package/src/lib/model/lead-filters.js.map +1 -0
  553. package/src/lib/model/lead-surfaces.d.ts +58 -0
  554. package/src/lib/model/lead-surfaces.js +67 -0
  555. package/src/lib/model/lead-surfaces.js.map +1 -0
  556. package/src/lib/model/leads-csv.d.ts +40 -0
  557. package/src/lib/model/leads-csv.js +40 -0
  558. package/src/lib/model/leads-csv.js.map +1 -0
  559. package/src/lib/model/next-activity-api.d.ts +31 -0
  560. package/src/lib/model/next-activity-api.js +57 -0
  561. package/src/lib/model/next-activity-api.js.map +1 -0
  562. package/src/lib/model/next-activity.d.ts +64 -0
  563. package/src/lib/model/next-activity.js +47 -0
  564. package/src/lib/model/next-activity.js.map +1 -0
  565. package/src/lib/model/person-key-web.d.ts +43 -0
  566. package/src/lib/model/person-key-web.js +52 -0
  567. package/src/lib/model/person-key-web.js.map +1 -0
  568. package/src/lib/model/record-facts.d.ts +282 -0
  569. package/src/lib/model/record-facts.js +434 -0
  570. package/src/lib/model/record-facts.js.map +1 -0
  571. package/src/lib/model/task-api.d.ts +28 -0
  572. package/src/lib/model/task-api.js +57 -0
  573. package/src/lib/model/task-api.js.map +1 -0
  574. package/src/lib/model/task-calendar.d.ts +108 -0
  575. package/src/lib/model/task-calendar.js +139 -0
  576. package/src/lib/model/task-calendar.js.map +1 -0
  577. package/src/lib/model/task-routes.d.ts +177 -0
  578. package/src/lib/model/task-routes.js +197 -0
  579. package/src/lib/model/task-routes.js.map +1 -0
  580. package/src/lib/model/task-scope.d.ts +45 -0
  581. package/src/lib/model/task-scope.js +51 -0
  582. package/src/lib/model/task-scope.js.map +1 -0
  583. package/src/lib/model/task-views.d.ts +149 -0
  584. package/src/lib/model/task-views.js +286 -0
  585. package/src/lib/model/task-views.js.map +1 -0
  586. package/src/lib/model/tasks-csv.d.ts +28 -0
  587. package/src/lib/model/tasks-csv.js +28 -0
  588. package/src/lib/model/tasks-csv.js.map +1 -0
  589. package/src/lib/plugin.d.ts +32 -0
  590. package/src/lib/plugin.js +208 -0
  591. package/src/lib/plugin.js.map +1 -0
  592. package/src/lib/server/companies-import.d.ts +57 -0
  593. package/src/lib/server/companies-import.js +242 -0
  594. package/src/lib/server/companies-import.js.map +1 -0
  595. package/src/lib/server/company-delete.d.ts +59 -0
  596. package/src/lib/server/company-delete.js +146 -0
  597. package/src/lib/server/company-delete.js.map +1 -0
  598. package/src/lib/server/contact-email-history.d.ts +82 -0
  599. package/src/lib/server/contact-email-history.js +264 -0
  600. package/src/lib/server/contact-email-history.js.map +1 -0
  601. package/src/lib/server/contact-profile.d.ts +41 -0
  602. package/src/lib/server/contact-profile.js +45 -0
  603. package/src/lib/server/contact-profile.js.map +1 -0
  604. package/src/lib/server/contact-update.d.ts +92 -0
  605. package/src/lib/server/contact-update.js +512 -0
  606. package/src/lib/server/contact-update.js.map +1 -0
  607. package/src/lib/server/contacts-import.d.ts +73 -0
  608. package/src/lib/server/contacts-import.js +263 -0
  609. package/src/lib/server/contacts-import.js.map +1 -0
  610. package/src/lib/server/contacts-merge.d.ts +86 -0
  611. package/src/lib/server/contacts-merge.js +206 -0
  612. package/src/lib/server/contacts-merge.js.map +1 -0
  613. package/src/lib/server/deals-import.d.ts +76 -0
  614. package/src/lib/server/deals-import.js +246 -0
  615. package/src/lib/server/deals-import.js.map +1 -0
  616. package/src/lib/server/email-send.d.ts +119 -0
  617. package/src/lib/server/email-send.js +667 -0
  618. package/src/lib/server/email-send.js.map +1 -0
  619. package/src/lib/server/email-template-duplicate.d.ts +19 -0
  620. package/src/lib/server/email-template-duplicate.js +206 -0
  621. package/src/lib/server/email-template-duplicate.js.map +1 -0
  622. package/src/lib/server/erase-person.d.ts +108 -0
  623. package/src/lib/server/erase-person.js +309 -0
  624. package/src/lib/server/erase-person.js.map +1 -0
  625. package/src/lib/server/import-context.d.ts +85 -0
  626. package/src/lib/server/import-context.js +181 -0
  627. package/src/lib/server/import-context.js.map +1 -0
  628. package/src/lib/server/inbound-address.d.ts +61 -0
  629. package/src/lib/server/inbound-address.js +188 -0
  630. package/src/lib/server/inbound-address.js.map +1 -0
  631. package/src/lib/server/lead-convert.d.ts +78 -0
  632. package/src/lib/server/lead-convert.js +250 -0
  633. package/src/lib/server/lead-convert.js.map +1 -0
  634. package/src/lib/server/leads-import.d.ts +84 -0
  635. package/src/lib/server/leads-import.js +261 -0
  636. package/src/lib/server/leads-import.js.map +1 -0
  637. package/src/lib/server/next-activity-routes.d.ts +33 -0
  638. package/src/lib/server/next-activity-routes.js +110 -0
  639. package/src/lib/server/next-activity-routes.js.map +1 -0
  640. package/src/lib/server/org-activity.d.ts +61 -0
  641. package/src/lib/server/org-activity.js +120 -0
  642. package/src/lib/server/org-activity.js.map +1 -0
  643. package/src/lib/server/org-caller.d.ts +110 -0
  644. package/src/lib/server/org-caller.js +154 -0
  645. package/src/lib/server/org-caller.js.map +1 -0
  646. package/src/lib/server/recipe-routes.d.ts +75 -0
  647. package/src/lib/server/recipe-routes.js +442 -0
  648. package/src/lib/server/recipe-routes.js.map +1 -0
  649. package/src/lib/server/record-facts.d.ts +65 -0
  650. package/src/lib/server/record-facts.js +337 -0
  651. package/src/lib/server/record-facts.js.map +1 -0
  652. package/src/lib/server/record-timeline.d.ts +51 -0
  653. package/src/lib/server/record-timeline.js +215 -0
  654. package/src/lib/server/record-timeline.js.map +1 -0
  655. package/src/lib/server/suite-gate.d.ts +42 -0
  656. package/src/lib/server/suite-gate.js +87 -0
  657. package/src/lib/server/suite-gate.js.map +1 -0
  658. package/src/lib/server/task-routes.d.ts +132 -0
  659. package/src/lib/server/task-routes.js +699 -0
  660. package/src/lib/server/task-routes.js.map +1 -0
  661. package/src/lib/server/tasks-import.d.ts +54 -0
  662. package/src/lib/server/tasks-import.js +157 -0
  663. package/src/lib/server/tasks-import.js.map +1 -0
  664. package/src/lib/server-deal-stage.d.ts +88 -0
  665. package/src/lib/server-deal-stage.js +316 -0
  666. package/src/lib/server-deal-stage.js.map +1 -0
  667. package/src/lib/server.d.ts +149 -0
  668. package/src/lib/server.js +615 -0
  669. package/src/lib/server.js.map +1 -0
@@ -0,0 +1,173 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * What a bulk action on the contacts table does to each row (AGL-2603, and
19
+ * through the server since AGL-2804).
20
+ *
21
+ * The bar over the table offers one act over many rows — tag them, hand them
22
+ * to an owner, file them under a company, move them along the funnel, let
23
+ * them go. A contact's tags, owner and company are one holder's records in
24
+ * that holder's facet, and a facet is the server's to write: the rules cannot
25
+ * tell one field of it from another, so they leave a client nothing there
26
+ * but letting a holder go. So every act but that one is a request to a route,
27
+ * and what this module decides is WHICH rows the request names — the bar
28
+ * holds only the controls.
29
+ *
30
+ * ## A row with nothing to change is left out, and a row that cannot be
31
+ * ## reached is REPORTED
32
+ *
33
+ * A row already carrying the tag, or already at the company, is left out of
34
+ * the request silently: the route would write nothing, and a report saying
35
+ * so would be noise. A row already at the tag cap, or whose company link the
36
+ * table could not project, is left out and named by address — a count of
37
+ * "398 of 400" is a number nobody can act on; an address is. The route asks
38
+ * the same questions of the stored document, so a row that changed since the
39
+ * table read it is still refused by name rather than slipped past.
40
+ *
41
+ * ## Letting go is still written here
42
+ *
43
+ * Removing a contact from a site drops that holder's facet, consent entries,
44
+ * capture attribution and scope tokens — the one change to a facet a holder
45
+ * may make client-direct. Those patches are built here and applied in
46
+ * batches with a per-row fallback, so a refused row is named rather than
47
+ * failing the other 399 with it.
48
+ *
49
+ * Pure apart from the Firestore sentinels the detach carries: the runner takes
50
+ * its writers as ports, so the bar wires `writeBatch`/`updateDoc`/`deleteDoc`
51
+ * in and a spec wires a ledger in.
52
+ */
53
+ import { type ContactCompanyLinkState } from '@aglyn/aglyn';
54
+ import { chunked } from './crm-bulk-writes';
55
+ export declare const CONTACT_BULK_WRITE_CHUNK = 400;
56
+ export { chunked };
57
+ /** The record page's cap on a holder's tags — the same number, so the two agree. */
58
+ export declare const CONTACT_TAGS_CAP = 20;
59
+ /** As much of a table row as a bulk act reads. */
60
+ export interface ContactBulkRow {
61
+ $id: string;
62
+ email?: string;
63
+ /**
64
+ * The holder this row was flattened through (`ContactRecord.groupId`),
65
+ * which a cross-holder reader — the organization-level list (AGL-2630) —
66
+ * writes each row through, since no one viewing group covers every
67
+ * selected person there.
68
+ */
69
+ groupId?: string;
70
+ /** A site of that holder's group — where the row's stage is moved (`ContactRecord.holderHostId`). */
71
+ holderHostId?: string;
72
+ /** THIS holder's tags, already read through the facet by the table. */
73
+ tags?: string[];
74
+ /** The holder tokens — what `planContactDetach` counts. */
75
+ visibleTo?: string[];
76
+ /** The link state the company planner reads — see `ContactRecord.companyLink`. */
77
+ companyLink?: ContactCompanyLinkState;
78
+ }
79
+ /** One client-direct write to one contact document, named by the address it is about. */
80
+ export type ContactBulkWrite = {
81
+ id: string;
82
+ email: string;
83
+ } & ({
84
+ kind: 'update';
85
+ data: Record<string, unknown>;
86
+ } | {
87
+ kind: 'delete';
88
+ });
89
+ /** A row an action deliberately left alone, and why. */
90
+ export interface ContactBulkSkip {
91
+ email: string;
92
+ reason: string;
93
+ }
94
+ /** What a letting-go wants written, and what it declined to. */
95
+ export interface ContactBulkPlan {
96
+ writes: ContactBulkWrite[];
97
+ skipped: ContactBulkSkip[];
98
+ }
99
+ /** The rows a request to a route names, and the rows it leaves out by name. */
100
+ export interface ContactBulkSelection {
101
+ rows: ContactBulkRow[];
102
+ skipped: ContactBulkSkip[];
103
+ }
104
+ /** The address a report names a row by, falling back to the id. */
105
+ export declare const contactBulkAddressOf: (row: ContactBulkRow) => string;
106
+ /**
107
+ * A typed tag as the record page stores one, or `null` when nothing survives.
108
+ *
109
+ * Lowercased and trimmed because the record page lowercases and trims, and
110
+ * `contactMatchesSegment` compares lowercased — a bulk "VIP" beside a typed
111
+ * "vip" would otherwise be two tags on one list and one filter finding half
112
+ * of them.
113
+ */
114
+ export declare function normalizeBulkTag(input: string): string | null;
115
+ /**
116
+ * The rows adding one tag reaches.
117
+ *
118
+ * A row that already carries the tag is left out silently. A row already at
119
+ * the cap without it is left out AND reported: the cap is the record page's,
120
+ * and a bulk path that slipped past it would leave a tag the page's next
121
+ * save silently drops.
122
+ */
123
+ export declare function planAddTag(rows: readonly ContactBulkRow[], tag: string): ContactBulkSelection;
124
+ /** The rows taking one tag off reaches: the ones that carry it. */
125
+ export declare function planRemoveTag(rows: readonly ContactBulkRow[], tag: string): ContactBulkSelection;
126
+ /**
127
+ * The rows filing under one company reaches — or unlinking, with `null`
128
+ * (AGL-2613).
129
+ *
130
+ * A row already where it was asked to be is left out silently, as a row
131
+ * already tagged is. A row the table could not project a link state for is
132
+ * left out AND named: whether its link would change cannot be told, and the
133
+ * request is not the place to guess.
134
+ */
135
+ export declare function planSetCompany(rows: readonly ContactBulkRow[], companyId: string | null): ContactBulkSelection;
136
+ /**
137
+ * Let every row go — the record page's DELETE IS A DETACH, per row.
138
+ *
139
+ * `planContactDetach` decides for each document whether this holder is the
140
+ * last one (delete) or one of several (drop this group's facet, consent
141
+ * entries, capture attribution and scope tokens). The `arrayRemove` and
142
+ * `deleteField` sentinels are the ones the record page writes, so a row
143
+ * detached here and a row detached there are the same document afterwards.
144
+ *
145
+ * ⛔ Not the erasure path: a privacy erasure removes the person everywhere
146
+ * regardless of holders.
147
+ */
148
+ export declare function planDetach(rows: readonly ContactBulkRow[], group: {
149
+ groupId: string;
150
+ hostIds: readonly string[];
151
+ }, nowMs: number): ContactBulkPlan;
152
+ /** The writers the runner needs — Firestore's, or a spec's ledger. */
153
+ export interface ContactBulkWriters {
154
+ /** Apply every write atomically, or throw. */
155
+ commitBatch: (writes: readonly ContactBulkWrite[]) => Promise<void>;
156
+ /** Apply one write, or throw. */
157
+ commitOne: (write: ContactBulkWrite) => Promise<void>;
158
+ }
159
+ export interface ContactBulkOutcome {
160
+ /** Rows written. */
161
+ done: number;
162
+ /** Rows the store refused, by address, with the reason it gave. */
163
+ refused: Array<{
164
+ email: string;
165
+ error: string;
166
+ }>;
167
+ }
168
+ /**
169
+ * The shared runner over contact writes — batched, with a per-row pass for
170
+ * the chunk that failed (`crm-bulk-writes.ts`) — reporting by ADDRESS, which
171
+ * is the name a contacts report lists a row under.
172
+ */
173
+ export declare function runContactBulkWrites(writers: ContactBulkWriters, writes: readonly ContactBulkWrite[], chunkSize?: number): Promise<ContactBulkOutcome>;
@@ -0,0 +1,196 @@
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
+ * What a bulk action on the contacts table does to each row (AGL-2603, and
19
+ * through the server since AGL-2804).
20
+ *
21
+ * The bar over the table offers one act over many rows — tag them, hand them
22
+ * to an owner, file them under a company, move them along the funnel, let
23
+ * them go. A contact's tags, owner and company are one holder's records in
24
+ * that holder's facet, and a facet is the server's to write: the rules cannot
25
+ * tell one field of it from another, so they leave a client nothing there
26
+ * but letting a holder go. So every act but that one is a request to a route,
27
+ * and what this module decides is WHICH rows the request names — the bar
28
+ * holds only the controls.
29
+ *
30
+ * ## A row with nothing to change is left out, and a row that cannot be
31
+ * ## reached is REPORTED
32
+ *
33
+ * A row already carrying the tag, or already at the company, is left out of
34
+ * the request silently: the route would write nothing, and a report saying
35
+ * so would be noise. A row already at the tag cap, or whose company link the
36
+ * table could not project, is left out and named by address — a count of
37
+ * "398 of 400" is a number nobody can act on; an address is. The route asks
38
+ * the same questions of the stored document, so a row that changed since the
39
+ * table read it is still refused by name rather than slipped past.
40
+ *
41
+ * ## Letting go is still written here
42
+ *
43
+ * Removing a contact from a site drops that holder's facet, consent entries,
44
+ * capture attribution and scope tokens — the one change to a facet a holder
45
+ * may make client-direct. Those patches are built here and applied in
46
+ * batches with a per-row fallback, so a refused row is named rather than
47
+ * failing the other 399 with it.
48
+ *
49
+ * Pure apart from the Firestore sentinels the detach carries: the runner takes
50
+ * its writers as ports, so the bar wires `writeBatch`/`updateDoc`/`deleteDoc`
51
+ * in and a spec wires a ledger in.
52
+ */ import { planContactCompanyLink, planContactDetach } from "@aglyn/aglyn";
53
+ import { arrayRemove, deleteField } from "firebase/firestore";
54
+ import { CRM_BULK_WRITE_CHUNK, chunked, runCrmBulkWrites } from "./crm-bulk-writes.js";
55
+ /*
56
+ * The runner and its chunk size are the shared ones (`crm-bulk-writes.ts`,
57
+ * AGL-2621), under the names this module has always exported: the batch
58
+ * cap and the per-row fallback are about Firestore, not about people.
59
+ */ export const CONTACT_BULK_WRITE_CHUNK = CRM_BULK_WRITE_CHUNK;
60
+ export { chunked };
61
+ /** The record page's cap on a holder's tags — the same number, so the two agree. */ export const CONTACT_TAGS_CAP = 20;
62
+ /** The address a report names a row by, falling back to the id. */ export const contactBulkAddressOf = (row)=>String(row.email || row.$id);
63
+ /**
64
+ * A typed tag as the record page stores one, or `null` when nothing survives.
65
+ *
66
+ * Lowercased and trimmed because the record page lowercases and trims, and
67
+ * `contactMatchesSegment` compares lowercased — a bulk "VIP" beside a typed
68
+ * "vip" would otherwise be two tags on one list and one filter finding half
69
+ * of them.
70
+ */ export function normalizeBulkTag(input) {
71
+ const tag = input.trim().toLowerCase().slice(0, 60);
72
+ return tag || null;
73
+ }
74
+ /**
75
+ * The rows adding one tag reaches.
76
+ *
77
+ * A row that already carries the tag is left out silently. A row already at
78
+ * the cap without it is left out AND reported: the cap is the record page's,
79
+ * and a bulk path that slipped past it would leave a tag the page's next
80
+ * save silently drops.
81
+ */ export function planAddTag(rows, tag) {
82
+ const reached = [];
83
+ const skipped = [];
84
+ for (const row of rows){
85
+ var _row_tags;
86
+ const held = ((_row_tags = row.tags) != null ? _row_tags : []).map((held)=>held.toLowerCase());
87
+ if (held.includes(tag)) continue;
88
+ if (held.length >= CONTACT_TAGS_CAP) {
89
+ skipped.push({
90
+ email: contactBulkAddressOf(row),
91
+ reason: `already has ${CONTACT_TAGS_CAP} tags`
92
+ });
93
+ continue;
94
+ }
95
+ reached.push(row);
96
+ }
97
+ return {
98
+ rows: reached,
99
+ skipped
100
+ };
101
+ }
102
+ /** The rows taking one tag off reaches: the ones that carry it. */ export function planRemoveTag(rows, tag) {
103
+ return {
104
+ rows: rows.filter((row)=>{
105
+ var _row_tags;
106
+ return ((_row_tags = row.tags) != null ? _row_tags : []).map((held)=>held.toLowerCase()).includes(tag);
107
+ }),
108
+ skipped: []
109
+ };
110
+ }
111
+ /**
112
+ * The rows filing under one company reaches — or unlinking, with `null`
113
+ * (AGL-2613).
114
+ *
115
+ * A row already where it was asked to be is left out silently, as a row
116
+ * already tagged is. A row the table could not project a link state for is
117
+ * left out AND named: whether its link would change cannot be told, and the
118
+ * request is not the place to guess.
119
+ */ export function planSetCompany(rows, companyId) {
120
+ const reached = [];
121
+ const skipped = [];
122
+ for (const row of rows){
123
+ if (!row.companyLink) {
124
+ skipped.push({
125
+ email: contactBulkAddressOf(row),
126
+ reason: 'its company link could not be read'
127
+ });
128
+ continue;
129
+ }
130
+ if (planContactCompanyLink(row.companyLink, companyId)) reached.push(row);
131
+ }
132
+ return {
133
+ rows: reached,
134
+ skipped
135
+ };
136
+ }
137
+ /**
138
+ * Let every row go — the record page's DELETE IS A DETACH, per row.
139
+ *
140
+ * `planContactDetach` decides for each document whether this holder is the
141
+ * last one (delete) or one of several (drop this group's facet, consent
142
+ * entries, capture attribution and scope tokens). The `arrayRemove` and
143
+ * `deleteField` sentinels are the ones the record page writes, so a row
144
+ * detached here and a row detached there are the same document afterwards.
145
+ *
146
+ * ⛔ Not the erasure path: a privacy erasure removes the person everywhere
147
+ * regardless of holders.
148
+ */ export function planDetach(rows, group, nowMs) {
149
+ return {
150
+ writes: rows.map((row)=>{
151
+ var _row_visibleTo;
152
+ // Only the holder tokens reach the plan: that is all it reads, and a
153
+ // projected table row carries fields the detach must not consult.
154
+ const plan = planContactDetach({
155
+ visibleTo: (_row_visibleTo = row.visibleTo) != null ? _row_visibleTo : []
156
+ }, group);
157
+ if (plan.action === 'delete') {
158
+ return {
159
+ id: row.$id,
160
+ email: contactBulkAddressOf(row),
161
+ kind: 'delete'
162
+ };
163
+ }
164
+ return {
165
+ id: row.$id,
166
+ email: contactBulkAddressOf(row),
167
+ kind: 'update',
168
+ data: _extends({}, Object.fromEntries(plan.remove.map((path)=>[
169
+ path,
170
+ deleteField()
171
+ ])), {
172
+ visibleTo: arrayRemove(...plan.removeTokens),
173
+ capturedByHostIds: arrayRemove(...plan.removeHostIds),
174
+ updatedAt: new Date(nowMs)
175
+ })
176
+ };
177
+ }),
178
+ skipped: []
179
+ };
180
+ }
181
+ /**
182
+ * The shared runner over contact writes — batched, with a per-row pass for
183
+ * the chunk that failed (`crm-bulk-writes.ts`) — reporting by ADDRESS, which
184
+ * is the name a contacts report lists a row under.
185
+ */ export async function runContactBulkWrites(writers, writes, chunkSize = CONTACT_BULK_WRITE_CHUNK) {
186
+ const outcome = await runCrmBulkWrites(writers, writes, (write)=>write.email, chunkSize);
187
+ return {
188
+ done: outcome.done,
189
+ refused: outcome.refused.map((row)=>({
190
+ email: row.label,
191
+ error: row.error
192
+ }))
193
+ };
194
+ }
195
+
196
+ //# sourceMappingURL=contacts-bulk-writes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/model/contacts-bulk-writes.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * What a bulk action on the contacts table does to each row (AGL-2603, and\n * through the server since AGL-2804).\n *\n * The bar over the table offers one act over many rows — tag them, hand them\n * to an owner, file them under a company, move them along the funnel, let\n * them go. A contact's tags, owner and company are one holder's records in\n * that holder's facet, and a facet is the server's to write: the rules cannot\n * tell one field of it from another, so they leave a client nothing there\n * but letting a holder go. So every act but that one is a request to a route,\n * and what this module decides is WHICH rows the request names — the bar\n * holds only the controls.\n *\n * ## A row with nothing to change is left out, and a row that cannot be\n * ## reached is REPORTED\n *\n * A row already carrying the tag, or already at the company, is left out of\n * the request silently: the route would write nothing, and a report saying\n * so would be noise. A row already at the tag cap, or whose company link the\n * table could not project, is left out and named by address — a count of\n * \"398 of 400\" is a number nobody can act on; an address is. The route asks\n * the same questions of the stored document, so a row that changed since the\n * table read it is still refused by name rather than slipped past.\n *\n * ## Letting go is still written here\n *\n * Removing a contact from a site drops that holder's facet, consent entries,\n * capture attribution and scope tokens — the one change to a facet a holder\n * may make client-direct. Those patches are built here and applied in\n * batches with a per-row fallback, so a refused row is named rather than\n * failing the other 399 with it.\n *\n * Pure apart from the Firestore sentinels the detach carries: the runner takes\n * its writers as ports, so the bar wires `writeBatch`/`updateDoc`/`deleteDoc`\n * in and a spec wires a ledger in.\n */\n\nimport {\n type ContactCompanyLinkState,\n planContactCompanyLink,\n planContactDetach,\n} from '@aglyn/aglyn'\nimport { arrayRemove, deleteField } from 'firebase/firestore'\nimport {\n CRM_BULK_WRITE_CHUNK,\n chunked,\n runCrmBulkWrites,\n} from './crm-bulk-writes'\n\n/*\n * The runner and its chunk size are the shared ones (`crm-bulk-writes.ts`,\n * AGL-2621), under the names this module has always exported: the batch\n * cap and the per-row fallback are about Firestore, not about people.\n */\nexport const CONTACT_BULK_WRITE_CHUNK = CRM_BULK_WRITE_CHUNK\nexport { chunked }\n\n/** The record page's cap on a holder's tags — the same number, so the two agree. */\nexport const CONTACT_TAGS_CAP = 20\n\n/** As much of a table row as a bulk act reads. */\nexport interface ContactBulkRow {\n $id: string\n email?: string\n /**\n * The holder this row was flattened through (`ContactRecord.groupId`),\n * which a cross-holder reader — the organization-level list (AGL-2630) —\n * writes each row through, since no one viewing group covers every\n * selected person there.\n */\n groupId?: string\n /** A site of that holder's group — where the row's stage is moved (`ContactRecord.holderHostId`). */\n holderHostId?: string\n /** THIS holder's tags, already read through the facet by the table. */\n tags?: string[]\n /** The holder tokens — what `planContactDetach` counts. */\n visibleTo?: string[]\n /** The link state the company planner reads — see `ContactRecord.companyLink`. */\n companyLink?: ContactCompanyLinkState\n}\n\n/** One client-direct write to one contact document, named by the address it is about. */\nexport type ContactBulkWrite = { id: string; email: string } & (\n | { kind: 'update'; data: Record<string, unknown> }\n | { kind: 'delete' }\n)\n\n/** A row an action deliberately left alone, and why. */\nexport interface ContactBulkSkip {\n email: string\n reason: string\n}\n\n/** What a letting-go wants written, and what it declined to. */\nexport interface ContactBulkPlan {\n writes: ContactBulkWrite[]\n skipped: ContactBulkSkip[]\n}\n\n/** The rows a request to a route names, and the rows it leaves out by name. */\nexport interface ContactBulkSelection {\n rows: ContactBulkRow[]\n skipped: ContactBulkSkip[]\n}\n\n/** The address a report names a row by, falling back to the id. */\nexport const contactBulkAddressOf = (row: ContactBulkRow): string =>\n String(row.email || row.$id)\n\n/**\n * A typed tag as the record page stores one, or `null` when nothing survives.\n *\n * Lowercased and trimmed because the record page lowercases and trims, and\n * `contactMatchesSegment` compares lowercased — a bulk \"VIP\" beside a typed\n * \"vip\" would otherwise be two tags on one list and one filter finding half\n * of them.\n */\nexport function normalizeBulkTag(input: string): string | null {\n const tag = input.trim().toLowerCase().slice(0, 60)\n return tag || null\n}\n\n/**\n * The rows adding one tag reaches.\n *\n * A row that already carries the tag is left out silently. A row already at\n * the cap without it is left out AND reported: the cap is the record page's,\n * and a bulk path that slipped past it would leave a tag the page's next\n * save silently drops.\n */\nexport function planAddTag(\n rows: readonly ContactBulkRow[],\n tag: string,\n): ContactBulkSelection {\n const reached: ContactBulkRow[] = []\n const skipped: ContactBulkSkip[] = []\n for (const row of rows) {\n const held = (row.tags ?? []).map((held) => held.toLowerCase())\n if (held.includes(tag)) continue\n if (held.length >= CONTACT_TAGS_CAP) {\n skipped.push({\n email: contactBulkAddressOf(row),\n reason: `already has ${CONTACT_TAGS_CAP} tags`,\n })\n continue\n }\n reached.push(row)\n }\n return { rows: reached, skipped }\n}\n\n/** The rows taking one tag off reaches: the ones that carry it. */\nexport function planRemoveTag(\n rows: readonly ContactBulkRow[],\n tag: string,\n): ContactBulkSelection {\n return {\n rows: rows.filter((row) =>\n (row.tags ?? []).map((held) => held.toLowerCase()).includes(tag),\n ),\n skipped: [],\n }\n}\n\n/**\n * The rows filing under one company reaches — or unlinking, with `null`\n * (AGL-2613).\n *\n * A row already where it was asked to be is left out silently, as a row\n * already tagged is. A row the table could not project a link state for is\n * left out AND named: whether its link would change cannot be told, and the\n * request is not the place to guess.\n */\nexport function planSetCompany(\n rows: readonly ContactBulkRow[],\n companyId: string | null,\n): ContactBulkSelection {\n const reached: ContactBulkRow[] = []\n const skipped: ContactBulkSkip[] = []\n for (const row of rows) {\n if (!row.companyLink) {\n skipped.push({\n email: contactBulkAddressOf(row),\n reason: 'its company link could not be read',\n })\n continue\n }\n if (planContactCompanyLink(row.companyLink, companyId)) reached.push(row)\n }\n return { rows: reached, skipped }\n}\n\n/**\n * Let every row go — the record page's DELETE IS A DETACH, per row.\n *\n * `planContactDetach` decides for each document whether this holder is the\n * last one (delete) or one of several (drop this group's facet, consent\n * entries, capture attribution and scope tokens). The `arrayRemove` and\n * `deleteField` sentinels are the ones the record page writes, so a row\n * detached here and a row detached there are the same document afterwards.\n *\n * ⛔ Not the erasure path: a privacy erasure removes the person everywhere\n * regardless of holders.\n */\nexport function planDetach(\n rows: readonly ContactBulkRow[],\n group: { groupId: string; hostIds: readonly string[] },\n nowMs: number,\n): ContactBulkPlan {\n return {\n writes: rows.map((row) => {\n // Only the holder tokens reach the plan: that is all it reads, and a\n // projected table row carries fields the detach must not consult.\n const plan = planContactDetach({ visibleTo: row.visibleTo ?? [] }, group)\n if (plan.action === 'delete') {\n return { id: row.$id, email: contactBulkAddressOf(row), kind: 'delete' as const }\n }\n return {\n id: row.$id,\n email: contactBulkAddressOf(row),\n kind: 'update' as const,\n data: {\n ...Object.fromEntries(plan.remove.map((path) => [path, deleteField()])),\n visibleTo: arrayRemove(...plan.removeTokens),\n capturedByHostIds: arrayRemove(...plan.removeHostIds),\n updatedAt: new Date(nowMs),\n },\n }\n }),\n skipped: [],\n }\n}\n\n/** The writers the runner needs — Firestore's, or a spec's ledger. */\nexport interface ContactBulkWriters {\n /** Apply every write atomically, or throw. */\n commitBatch: (writes: readonly ContactBulkWrite[]) => Promise<void>\n /** Apply one write, or throw. */\n commitOne: (write: ContactBulkWrite) => Promise<void>\n}\n\nexport interface ContactBulkOutcome {\n /** Rows written. */\n done: number\n /** Rows the store refused, by address, with the reason it gave. */\n refused: Array<{ email: string; error: string }>\n}\n\n/**\n * The shared runner over contact writes — batched, with a per-row pass for\n * the chunk that failed (`crm-bulk-writes.ts`) — reporting by ADDRESS, which\n * is the name a contacts report lists a row under.\n */\nexport async function runContactBulkWrites(\n writers: ContactBulkWriters,\n writes: readonly ContactBulkWrite[],\n chunkSize: number = CONTACT_BULK_WRITE_CHUNK,\n): Promise<ContactBulkOutcome> {\n const outcome = await runCrmBulkWrites(\n writers,\n writes,\n (write) => write.email,\n chunkSize,\n )\n return {\n done: outcome.done,\n refused: outcome.refused.map((row) => ({ email: row.label, error: row.error })),\n }\n}\n"],"names":["planContactCompanyLink","planContactDetach","arrayRemove","deleteField","CRM_BULK_WRITE_CHUNK","chunked","runCrmBulkWrites","CONTACT_BULK_WRITE_CHUNK","CONTACT_TAGS_CAP","contactBulkAddressOf","row","String","email","$id","normalizeBulkTag","input","tag","trim","toLowerCase","slice","planAddTag","rows","reached","skipped","held","tags","map","includes","length","push","reason","planRemoveTag","filter","planSetCompany","companyId","companyLink","planDetach","group","nowMs","writes","plan","visibleTo","action","id","kind","data","Object","fromEntries","remove","path","removeTokens","capturedByHostIds","removeHostIds","updatedAt","Date","runContactBulkWrites","writers","chunkSize","outcome","write","done","refused","label","error"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCC,GAED,SAEEA,sBAAsB,EACtBC,iBAAiB,QACZ,eAAc;AACrB,SAASC,WAAW,EAAEC,WAAW,QAAQ,qBAAoB;AAC7D,SACEC,oBAAoB,EACpBC,OAAO,EACPC,gBAAgB,QACX,uBAAmB;AAE1B;;;;CAIC,GACD,OAAO,MAAMC,2BAA2BH,qBAAoB;AAC5D,SAASC,OAAO,GAAE;AAElB,kFAAkF,GAClF,OAAO,MAAMG,mBAAmB,GAAE;AA+ClC,iEAAiE,GACjE,OAAO,MAAMC,uBAAuB,CAACC,MACnCC,OAAOD,IAAIE,KAAK,IAAIF,IAAIG,GAAG,EAAC;AAE9B;;;;;;;CAOC,GACD,OAAO,SAASC,iBAAiBC,KAAa;IAC5C,MAAMC,MAAMD,MAAME,IAAI,GAAGC,WAAW,GAAGC,KAAK,CAAC,GAAG;IAChD,OAAOH,OAAO;AAChB;AAEA;;;;;;;CAOC,GACD,OAAO,SAASI,WACdC,IAA+B,EAC/BL,GAAW;IAEX,MAAMM,UAA4B,EAAE;IACpC,MAAMC,UAA6B,EAAE;IACrC,KAAK,MAAMb,OAAOW,KAAM;YACRX;QAAd,MAAMc,OAAO,EAACd,YAAAA,IAAIe,IAAI,YAARf,YAAY,EAAE,EAAEgB,GAAG,CAAC,CAACF,OAASA,KAAKN,WAAW;QAC5D,IAAIM,KAAKG,QAAQ,CAACX,MAAM;QACxB,IAAIQ,KAAKI,MAAM,IAAIpB,kBAAkB;YACnCe,QAAQM,IAAI,CAAC;gBACXjB,OAAOH,qBAAqBC;gBAC5BoB,QAAQ,CAAC,YAAY,EAAEtB,iBAAiB,KAAK,CAAC;YAChD;YACA;QACF;QACAc,QAAQO,IAAI,CAACnB;IACf;IACA,OAAO;QAAEW,MAAMC;QAASC;IAAQ;AAClC;AAEA,iEAAiE,GACjE,OAAO,SAASQ,cACdV,IAA+B,EAC/BL,GAAW;IAEX,OAAO;QACLK,MAAMA,KAAKW,MAAM,CAAC,CAACtB;gBAChBA;mBAAD,EAACA,YAAAA,IAAIe,IAAI,YAARf,YAAY,EAAE,EAAEgB,GAAG,CAAC,CAACF,OAASA,KAAKN,WAAW,IAAIS,QAAQ,CAACX;;QAE9DO,SAAS,EAAE;IACb;AACF;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASU,eACdZ,IAA+B,EAC/Ba,SAAwB;IAExB,MAAMZ,UAA4B,EAAE;IACpC,MAAMC,UAA6B,EAAE;IACrC,KAAK,MAAMb,OAAOW,KAAM;QACtB,IAAI,CAACX,IAAIyB,WAAW,EAAE;YACpBZ,QAAQM,IAAI,CAAC;gBACXjB,OAAOH,qBAAqBC;gBAC5BoB,QAAQ;YACV;YACA;QACF;QACA,IAAI9B,uBAAuBU,IAAIyB,WAAW,EAAED,YAAYZ,QAAQO,IAAI,CAACnB;IACvE;IACA,OAAO;QAAEW,MAAMC;QAASC;IAAQ;AAClC;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,SAASa,WACdf,IAA+B,EAC/BgB,KAAsD,EACtDC,KAAa;IAEb,OAAO;QACLC,QAAQlB,KAAKK,GAAG,CAAC,CAAChB;gBAG4BA;YAF5C,qEAAqE;YACrE,kEAAkE;YAClE,MAAM8B,OAAOvC,kBAAkB;gBAAEwC,SAAS,GAAE/B,iBAAAA,IAAI+B,SAAS,YAAb/B,iBAAiB,EAAE;YAAC,GAAG2B;YACnE,IAAIG,KAAKE,MAAM,KAAK,UAAU;gBAC5B,OAAO;oBAAEC,IAAIjC,IAAIG,GAAG;oBAAED,OAAOH,qBAAqBC;oBAAMkC,MAAM;gBAAkB;YAClF;YACA,OAAO;gBACLD,IAAIjC,IAAIG,GAAG;gBACXD,OAAOH,qBAAqBC;gBAC5BkC,MAAM;gBACNC,MAAM,aACDC,OAAOC,WAAW,CAACP,KAAKQ,MAAM,CAACtB,GAAG,CAAC,CAACuB,OAAS;wBAACA;wBAAM9C;qBAAc;oBACrEsC,WAAWvC,eAAesC,KAAKU,YAAY;oBAC3CC,mBAAmBjD,eAAesC,KAAKY,aAAa;oBACpDC,WAAW,IAAIC,KAAKhB;;YAExB;QACF;QACAf,SAAS,EAAE;IACb;AACF;AAiBA;;;;CAIC,GACD,OAAO,eAAegC,qBACpBC,OAA2B,EAC3BjB,MAAmC,EACnCkB,YAAoBlD,wBAAwB;IAE5C,MAAMmD,UAAU,MAAMpD,iBACpBkD,SACAjB,QACA,CAACoB,QAAUA,MAAM/C,KAAK,EACtB6C;IAEF,OAAO;QACLG,MAAMF,QAAQE,IAAI;QAClBC,SAASH,QAAQG,OAAO,CAACnC,GAAG,CAAC,CAAChB,MAAS,CAAA;gBAAEE,OAAOF,IAAIoD,KAAK;gBAAEC,OAAOrD,IAAIqD,KAAK;YAAC,CAAA;IAC9E;AACF"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * The contacts CSV — every CRM column, the same file from the table's
19
+ * Export button and the bulk bar's (AGL-2603, widened by AGL-2621).
20
+ *
21
+ * The selection's export and the table's export are the same file over a
22
+ * different set of rows: the same columns in the same order, the same `|`
23
+ * between multi-valued cells, the same quoting. A second column list would
24
+ * be a second file format for one feature, and the person opening both in
25
+ * a spreadsheet would be the one to find the difference.
26
+ *
27
+ * ## The header row is the import's own vocabulary
28
+ *
29
+ * Each column is headed by a name `guessContactImportMapping` recognizes —
30
+ * "Job title", "Address line 1", "Lifecycle stage", a custom field's label
31
+ * — so an export re-imports without a hand mapping, and the template the
32
+ * Import drawer offers IS this header over no rows. The owner column
33
+ * carries the member's ADDRESS rather than a uid for the same reason: the
34
+ * import resolves an owner by email, and a uid is nothing a spreadsheet
35
+ * can read anyway. The three columns the import has no field for — sources,
36
+ * the last interaction and the last campaign engagement — are still
37
+ * written, because they are what a merchant reads the file for; they map to
38
+ * "Do not import" on the way back.
39
+ */
40
+ export { CONTACT_CSV_COLUMNS, contactCsvHeader, contactsCsv, type ContactCsvOptions, type ContactCsvRow, } from '@aglyn/aglyn';
41
+ import { type ContactCsvOptions } from '@aglyn/aglyn';
42
+ /**
43
+ * The file the Import drawer hands out to start from: the export's header
44
+ * and nothing under it, so a sheet filled in against it maps itself.
45
+ */
46
+ export declare function contactImportTemplateCsv(customFields?: ContactCsvOptions['customFields']): string;
47
+ /**
48
+ * Hand the browser a file to save.
49
+ *
50
+ * The one writer that stayed: it touches `URL.createObjectURL` and
51
+ * `document`, so it belongs to the browser and not to the library a server
52
+ * route imports.
53
+ */
54
+ export declare function downloadTextFile(name: string, mime: string, text: string): void;
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ /**
17
+ * The contacts CSV — every CRM column, the same file from the table's
18
+ * Export button and the bulk bar's (AGL-2603, widened by AGL-2621).
19
+ *
20
+ * The selection's export and the table's export are the same file over a
21
+ * different set of rows: the same columns in the same order, the same `|`
22
+ * between multi-valued cells, the same quoting. A second column list would
23
+ * be a second file format for one feature, and the person opening both in
24
+ * a spreadsheet would be the one to find the difference.
25
+ *
26
+ * ## The header row is the import's own vocabulary
27
+ *
28
+ * Each column is headed by a name `guessContactImportMapping` recognizes —
29
+ * "Job title", "Address line 1", "Lifecycle stage", a custom field's label
30
+ * — so an export re-imports without a hand mapping, and the template the
31
+ * Import drawer offers IS this header over no rows. The owner column
32
+ * carries the member's ADDRESS rather than a uid for the same reason: the
33
+ * import resolves an owner by email, and a uid is nothing a spreadsheet
34
+ * can read anyway. The three columns the import has no field for — sources,
35
+ * the last interaction and the last campaign engagement — are still
36
+ * written, because they are what a merchant reads the file for; they map to
37
+ * "Do not import" on the way back.
38
+ */ /* The writer moved to `@aglyn/aglyn` under AGL-2662 — see `deals-csv.ts`. */ export { CONTACT_CSV_COLUMNS, contactCsvHeader, contactsCsv } from "@aglyn/aglyn";
39
+ import { contactsCsv } from "@aglyn/aglyn";
40
+ /**
41
+ * The file the Import drawer hands out to start from: the export's header
42
+ * and nothing under it, so a sheet filled in against it maps itself.
43
+ */ export function contactImportTemplateCsv(customFields = []) {
44
+ return contactsCsv([], {
45
+ customFields
46
+ });
47
+ }
48
+ /**
49
+ * Hand the browser a file to save.
50
+ *
51
+ * The one writer that stayed: it touches `URL.createObjectURL` and
52
+ * `document`, so it belongs to the browser and not to the library a server
53
+ * route imports.
54
+ */ export function downloadTextFile(name, mime, text) {
55
+ const url = URL.createObjectURL(new Blob([
56
+ text
57
+ ], {
58
+ type: mime
59
+ }));
60
+ const anchor = document.createElement('a');
61
+ anchor.href = url;
62
+ anchor.download = name;
63
+ anchor.click();
64
+ URL.revokeObjectURL(url);
65
+ }
66
+
67
+ //# sourceMappingURL=contacts-csv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/model/contacts-csv.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * The contacts CSV — every CRM column, the same file from the table's\n * Export button and the bulk bar's (AGL-2603, widened by AGL-2621).\n *\n * The selection's export and the table's export are the same file over a\n * different set of rows: the same columns in the same order, the same `|`\n * between multi-valued cells, the same quoting. A second column list would\n * be a second file format for one feature, and the person opening both in\n * a spreadsheet would be the one to find the difference.\n *\n * ## The header row is the import's own vocabulary\n *\n * Each column is headed by a name `guessContactImportMapping` recognizes —\n * \"Job title\", \"Address line 1\", \"Lifecycle stage\", a custom field's label\n * — so an export re-imports without a hand mapping, and the template the\n * Import drawer offers IS this header over no rows. The owner column\n * carries the member's ADDRESS rather than a uid for the same reason: the\n * import resolves an owner by email, and a uid is nothing a spreadsheet\n * can read anyway. The three columns the import has no field for — sources,\n * the last interaction and the last campaign engagement — are still\n * written, because they are what a merchant reads the file for; they map to\n * \"Do not import\" on the way back.\n */\n\n/* The writer moved to `@aglyn/aglyn` under AGL-2662 — see `deals-csv.ts`. */\nexport {\n CONTACT_CSV_COLUMNS,\n contactCsvHeader,\n contactsCsv,\n type ContactCsvOptions,\n type ContactCsvRow,\n} from '@aglyn/aglyn'\n\nimport { contactsCsv, type ContactCsvOptions } from '@aglyn/aglyn'\n\n/**\n * The file the Import drawer hands out to start from: the export's header\n * and nothing under it, so a sheet filled in against it maps itself.\n */\nexport function contactImportTemplateCsv(\n customFields: ContactCsvOptions['customFields'] = [],\n): string {\n return contactsCsv([], { customFields })\n}\n\n/**\n * Hand the browser a file to save.\n *\n * The one writer that stayed: it touches `URL.createObjectURL` and\n * `document`, so it belongs to the browser and not to the library a server\n * route imports.\n */\nexport function downloadTextFile(name: string, mime: string, text: string): void {\n const url = URL.createObjectURL(new Blob([text], { type: mime }))\n const anchor = document.createElement('a')\n anchor.href = url\n anchor.download = name\n anchor.click()\n URL.revokeObjectURL(url)\n}\n"],"names":["CONTACT_CSV_COLUMNS","contactCsvHeader","contactsCsv","contactImportTemplateCsv","customFields","downloadTextFile","name","mime","text","url","URL","createObjectURL","Blob","type","anchor","document","createElement","href","download","click","revokeObjectURL"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;;;;;CAsBC,GAED,2EAA2E,GAC3E,SACEA,mBAAmB,EACnBC,gBAAgB,EAChBC,WAAW,QAGN,eAAc;AAErB,SAASA,WAAW,QAAgC,eAAc;AAElE;;;CAGC,GACD,OAAO,SAASC,yBACdC,eAAkD,EAAE;IAEpD,OAAOF,YAAY,EAAE,EAAE;QAAEE;IAAa;AACxC;AAEA;;;;;;CAMC,GACD,OAAO,SAASC,iBAAiBC,IAAY,EAAEC,IAAY,EAAEC,IAAY;IACvE,MAAMC,MAAMC,IAAIC,eAAe,CAAC,IAAIC,KAAK;QAACJ;KAAK,EAAE;QAAEK,MAAMN;IAAK;IAC9D,MAAMO,SAASC,SAASC,aAAa,CAAC;IACtCF,OAAOG,IAAI,GAAGR;IACdK,OAAOI,QAAQ,GAAGZ;IAClBQ,OAAOK,KAAK;IACZT,IAAIU,eAAe,CAACX;AACtB"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { type ContactSource } from '@aglyn/aglyn';
18
+ import type { ListFilterRequest } from '@aglyn/shared-ui-jsx/const/list-filter';
19
+ /** What the Contacts list opens ON, read off its own address. */
20
+ export interface ContactsListSeed {
21
+ /** The grid filter to start with — the query's predicate — or none. */
22
+ filter: ListFilterRequest | null;
23
+ /** The source select's starting value. */
24
+ source: ContactSource | '';
25
+ /** The form the list was opened for, when it was. */
26
+ formId: string | null;
27
+ /**
28
+ * The address the list was asked to OPEN, normalized, when it was — the
29
+ * list moves on to the record itself once exactly one row matches.
30
+ */
31
+ openEmail: string | null;
32
+ }
33
+ /**
34
+ * The Contacts list's starting state, from the query string another surface
35
+ * sent it with (AGL-2612).
36
+ *
37
+ * Two surfaces address the list rather than a record: a form's own page,
38
+ * asking for the people that form captured, and an Inbox submission row,
39
+ * asking for the person with this address. Each is a filter the list
40
+ * already speaks — `formIds contains` and `email equals` — so the seed is
41
+ * the SAME `ListFilterRequest` the grid's own panel would produce, and the
42
+ * query built from it is the query a typed filter builds. Nothing here is a
43
+ * second predicate.
44
+ *
45
+ * Pure, and strict about what it accepts: an unknown source or an address
46
+ * that is not one seeds nothing rather than a filter that matches nothing,
47
+ * because an empty list under a bad link reads as "no such people".
48
+ */
49
+ export declare function contactsListSeed(params: {
50
+ get(name: string): string | null;
51
+ } | null | undefined): ContactsListSeed;
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ import { CONTACT_SOURCE_LABELS, normalizeContactEmail } from "@aglyn/aglyn";
17
+ import { CONTACTS_LIST_EMAIL_PARAM, CONTACTS_LIST_FORM_PARAM, CONTACTS_LIST_SOURCE_PARAM } from "./crm-routes.js";
18
+ const NO_SEED = {
19
+ filter: null,
20
+ source: '',
21
+ formId: null,
22
+ openEmail: null
23
+ };
24
+ /**
25
+ * The Contacts list's starting state, from the query string another surface
26
+ * sent it with (AGL-2612).
27
+ *
28
+ * Two surfaces address the list rather than a record: a form's own page,
29
+ * asking for the people that form captured, and an Inbox submission row,
30
+ * asking for the person with this address. Each is a filter the list
31
+ * already speaks — `formIds contains` and `email equals` — so the seed is
32
+ * the SAME `ListFilterRequest` the grid's own panel would produce, and the
33
+ * query built from it is the query a typed filter builds. Nothing here is a
34
+ * second predicate.
35
+ *
36
+ * Pure, and strict about what it accepts: an unknown source or an address
37
+ * that is not one seeds nothing rather than a filter that matches nothing,
38
+ * because an empty list under a bad link reads as "no such people".
39
+ */ export function contactsListSeed(params) {
40
+ var _params_get, _params_get1;
41
+ if (!params) return NO_SEED;
42
+ const rawSource = (_params_get = params.get(CONTACTS_LIST_SOURCE_PARAM)) != null ? _params_get : '';
43
+ const source = rawSource in CONTACT_SOURCE_LABELS ? rawSource : '';
44
+ const formId = ((_params_get1 = params.get(CONTACTS_LIST_FORM_PARAM)) != null ? _params_get1 : '').trim() || null;
45
+ const openEmail = normalizeContactEmail(params.get(CONTACTS_LIST_EMAIL_PARAM));
46
+ const filter = formId ? {
47
+ field: 'formIds',
48
+ op: 'contains',
49
+ value: formId
50
+ } : openEmail ? {
51
+ field: 'email',
52
+ op: 'equals',
53
+ value: openEmail
54
+ } : null;
55
+ return {
56
+ filter,
57
+ source,
58
+ formId,
59
+ openEmail
60
+ };
61
+ }
62
+
63
+ //# sourceMappingURL=contacts-list-seed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/model/contacts-list-seed.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CONTACT_SOURCE_LABELS,\n type ContactSource,\n normalizeContactEmail,\n} from '@aglyn/aglyn'\nimport type { ListFilterRequest } from '@aglyn/shared-ui-jsx/const/list-filter'\nimport {\n CONTACTS_LIST_EMAIL_PARAM,\n CONTACTS_LIST_FORM_PARAM,\n CONTACTS_LIST_SOURCE_PARAM,\n} from './crm-routes'\n\n/** What the Contacts list opens ON, read off its own address. */\nexport interface ContactsListSeed {\n /** The grid filter to start with — the query's predicate — or none. */\n filter: ListFilterRequest | null\n /** The source select's starting value. */\n source: ContactSource | ''\n /** The form the list was opened for, when it was. */\n formId: string | null\n /**\n * The address the list was asked to OPEN, normalized, when it was — the\n * list moves on to the record itself once exactly one row matches.\n */\n openEmail: string | null\n}\n\nconst NO_SEED: ContactsListSeed = {\n filter: null,\n source: '',\n formId: null,\n openEmail: null,\n}\n\n/**\n * The Contacts list's starting state, from the query string another surface\n * sent it with (AGL-2612).\n *\n * Two surfaces address the list rather than a record: a form's own page,\n * asking for the people that form captured, and an Inbox submission row,\n * asking for the person with this address. Each is a filter the list\n * already speaks — `formIds contains` and `email equals` — so the seed is\n * the SAME `ListFilterRequest` the grid's own panel would produce, and the\n * query built from it is the query a typed filter builds. Nothing here is a\n * second predicate.\n *\n * Pure, and strict about what it accepts: an unknown source or an address\n * that is not one seeds nothing rather than a filter that matches nothing,\n * because an empty list under a bad link reads as \"no such people\".\n */\nexport function contactsListSeed(\n params: { get(name: string): string | null } | null | undefined,\n): ContactsListSeed {\n if (!params) return NO_SEED\n const rawSource = params.get(CONTACTS_LIST_SOURCE_PARAM) ?? ''\n const source =\n rawSource in CONTACT_SOURCE_LABELS ? (rawSource as ContactSource) : ''\n const formId = (params.get(CONTACTS_LIST_FORM_PARAM) ?? '').trim() || null\n const openEmail = normalizeContactEmail(\n params.get(CONTACTS_LIST_EMAIL_PARAM),\n )\n const filter: ListFilterRequest | null = formId\n ? { field: 'formIds', op: 'contains', value: formId }\n : openEmail\n ? { field: 'email', op: 'equals', value: openEmail }\n : null\n return { filter, source, formId, openEmail }\n}\n"],"names":["CONTACT_SOURCE_LABELS","normalizeContactEmail","CONTACTS_LIST_EMAIL_PARAM","CONTACTS_LIST_FORM_PARAM","CONTACTS_LIST_SOURCE_PARAM","NO_SEED","filter","source","formId","openEmail","contactsListSeed","params","rawSource","get","trim","field","op","value"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SACEA,qBAAqB,EAErBC,qBAAqB,QAChB,eAAc;AAErB,SACEC,yBAAyB,EACzBC,wBAAwB,EACxBC,0BAA0B,QACrB,kBAAc;AAiBrB,MAAMC,UAA4B;IAChCC,QAAQ;IACRC,QAAQ;IACRC,QAAQ;IACRC,WAAW;AACb;AAEA;;;;;;;;;;;;;;;CAeC,GACD,OAAO,SAASC,iBACdC,MAA+D;QAG7CA,aAGFA;IAJhB,IAAI,CAACA,QAAQ,OAAON;IACpB,MAAMO,aAAYD,cAAAA,OAAOE,GAAG,CAACT,uCAAXO,cAA0C;IAC5D,MAAMJ,SACJK,aAAaZ,wBAAyBY,YAA8B;IACtE,MAAMJ,SAAS,EAACG,eAAAA,OAAOE,GAAG,CAACV,qCAAXQ,eAAwC,IAAIG,IAAI,MAAM;IACtE,MAAML,YAAYR,sBAChBU,OAAOE,GAAG,CAACX;IAEb,MAAMI,SAAmCE,SACrC;QAAEO,OAAO;QAAWC,IAAI;QAAYC,OAAOT;IAAO,IAClDC,YACE;QAAEM,OAAO;QAASC,IAAI;QAAUC,OAAOR;IAAU,IACjD;IACN,OAAO;QAAEH;QAAQC;QAAQC;QAAQC;IAAU;AAC7C"}