@aglyn/plugins-crm 1.0.0-beta.221 → 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 +65 -21
  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 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/transfer/leads.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 * LEADS ON THE TRANSFER FRAMEWORK (AGL-3528) — the server half of\n * `crm.leads`.\n *\n * A lead is one person an organization's sites captured and nobody has\n * qualified yet: one document per person (`personKey(email)`), seen by the\n * sites that captured them. Every field a lead holds — its own profile of\n * the person and their company as text, its status, owner, lead source,\n * campaigns, notes and custom fields — is read for an export, and an import\n * writes through the door every capture uses (`addHostLead`: the person\n * keyed by address, the lead ceiling, the capturing site's scope), then the\n * working state the old leads import wrote beside it.\n *\n * A lead is QUALIFIED only by converting it, which makes the contact, the\n * company and the deal; a file may set any other status. Do not call is\n * turned on by a file and never off, and the name follows the first and\n * last names once either is set — the rules the lead page keeps.\n *=========================================*/\n\nimport {\n checkVisitorRecordCeiling,\n CONTACT_EXTRA_PHONE_FIELDS,\n type ContactFieldDefinition,\n CRM_LEAD_STATUS_PICKLIST,\n CRM_LEAD_STATUSES,\n type CrmLeadStatus,\n type CrmPicklist,\n crmLeadComposedName,\n crmLeadStatusLabel,\n LEADS_MAX_PER_HOST,\n normalizeCompanyWebsite,\n normalizeCrmLeadTags,\n normalizePhone,\n personKey,\n resolveCrmLeadStatusWrite,\n} from '@aglyn/aglyn/server'\nimport { CONTACT_SOURCE_LABELS } from '@aglyn/aglyn/app-utils/contacts'\nimport {\n buildTransferPlan,\n matchLookupKey,\n planTransferUndo,\n TRANSFER_ID_FIELD,\n type CurrencyAmount,\n type PlannedTransferRow,\n type TransferRowResult,\n type TransferUndoEntry,\n type TransferUndoStep,\n} from '@aglyn/aglyn/data-transfer'\nimport type { TransferRecordsHooks } from '@aglyn/aglyn/plugin-manager/plugin-transfer-resources'\nimport { addHostLeadOutcome, restampCrmListFieldsAt } from '@aglyn/tenant-data-admin'\nimport { FieldValue } from 'firebase-admin/firestore'\nimport { judgeLeadPicklistPatch, readLeadPicklists } from '../server/lead-picklists'\nimport { readLeadSourcePicklist, resolveLeadSourceWrite } from '../server/lead-source-picklist'\nimport { readCrmPicklist } from '../server/read-picklist'\nimport { LEAD_ALIASES } from './aliases'\nimport {\n addCrmPicklistValues,\n addressFromValues,\n addressValues,\n campaignDirectory,\n countCrmExport,\n crmCustomDefinitions,\n crmMemberEmails,\n crmMembersTarget,\n crmPicklistLists,\n crmTransferEnv,\n type CrmTransferEnv,\n customTransferValues,\n customWriteValues,\n eachWithinBudget,\n failureMessage,\n holdBackChanges,\n isoOf,\n lookupById,\n lookupResult,\n pickValues,\n plannedValues,\n readCrmExportPage,\n requireCrmSuite,\n requireSite,\n textOf,\n TransferEngineError,\n visibleIn,\n} from './common'\nimport {\n CRM_MEMBERS_TARGET,\n CRM_TIMESTAMP_FIELDS,\n crmCustomTransferFields,\n LEAD_TRANSFER_DERIVED,\n LEAD_TRANSFER_FIELDS,\n LEAD_TRANSFER_GROUPS,\n} from './fields'\n\nconst SUITE_ACT = 'Importing leads'\n\n/** How an import names itself as a lead's source — the capture surface `import`. */\nconst LEAD_IMPORT_SOURCE = 'import'\n\n/** The statuses a file may set: every one but Qualified, which a conversion alone sets. */\nconst FILE_STATUSES: readonly CrmLeadStatus[] = CRM_LEAD_STATUSES.filter((status) => status !== 'qualified')\n\nconst leadsOf = (env: CrmTransferEnv) => env.orgRef.collection('leads')\n\n/** How one capture surface reads in a file. */\nfunction captureSourceLabel(source: string): string {\n if (source === 'signup') return 'Sign-up'\n if (source === 'booking') return 'Booking'\n if (source === 'import') return CONTACT_SOURCE_LABELS.import\n if (source === 'form') return CONTACT_SOURCE_LABELS.form\n // A lead entered by hand or over the REST API (AGL-3231).\n if (source === 'manual') return 'Added by hand'\n if (source === 'api') return 'API'\n if (source.startsWith('form:')) return `Form ${source.slice('form:'.length)}`\n return source\n}\n\n/** Every surface that produced a capture — the array, or the older single field. */\nfunction captureSources(lead: Record<string, unknown>): string[] {\n const sources = lead['sources']\n if (Array.isArray(sources) && sources.length) {\n return sources.map((source) => String(source))\n }\n return typeof lead['source'] === 'string' && lead['source'] ? [lead['source']] : []\n}\n\n/** Names written in place of ids, and the org's status list. */\ninterface LeadNames {\n owner?: (uid: string) => string | undefined\n campaign?: (id: string) => string | undefined\n /** Amounts as `1250.00 USD`. */\n display?: boolean\n}\n\n/** One lead as values by field id. */\nexport function leadTransferValues(\n id: string,\n lead: Record<string, unknown>,\n statuses: CrmPicklist,\n definitions: readonly ContactFieldDefinition[],\n names: LeadNames = {},\n): Record<string, unknown> {\n const text = (value: unknown) => textOf(value) || null\n const revenue = typeof lead['annualRevenueCents'] === 'number' ? (lead['annualRevenueCents'] as number) : null\n const currency = String(lead['currency'] || 'usd').toUpperCase()\n const ownerUid = text(lead['ownerUid'])\n const campaignIds = Array.isArray(lead['campaignIds']) ? (lead['campaignIds'] as unknown[]).map(String) : []\n const captures = Number(lead['submissionCount'] ?? 0)\n return {\n // The name first: a record's label is the first text it holds.\n name: text(lead['name']),\n email: text(lead['email']),\n salutation: text(lead['salutation']),\n firstName: text(lead['firstName']),\n lastName: text(lead['lastName']),\n company: text(lead['company']),\n jobTitle: text(lead['jobTitle']),\n phone: text(lead['phone']),\n mobilePhone: text(lead['mobilePhone']),\n fax: text(lead['fax']),\n doNotCall: lead['doNotCall'] === true,\n website: text(lead['website']),\n ...addressValues('address', lead['address']),\n status: crmLeadStatusLabel(lead, statuses) || null,\n owner: ownerUid ? (names.owner?.(ownerUid) ?? ownerUid) : null,\n leadSource: text(lead['leadSource']),\n industry: text(lead['industry']),\n rating: text(lead['rating']),\n numberOfEmployees: typeof lead['numberOfEmployees'] === 'number' ? lead['numberOfEmployees'] : null,\n annualRevenue:\n revenue === null ? null : names.display ? `${(revenue / 100).toFixed(2)} ${currency}` : { amountMinor: revenue, currency },\n tags: Array.isArray(lead['tags']) ? (lead['tags'] as string[]) : [],\n campaigns: campaignIds.map((campaign) => names.campaign?.(campaign) ?? campaign),\n notes: text(lead['notes']),\n unqualifiedReason: text(lead['unqualifiedReason']),\n sources: captureSources(lead).map(captureSourceLabel),\n firstSeenAt: isoOf(lead['firstSeenAtMs'] ?? lead['createdAt']),\n lastSeenAt: isoOf(lead['lastSeenAtMs'] ?? lead['createdAt']),\n captures: Number.isFinite(captures) && captures > 0 ? captures : 0,\n convertedAt: isoOf(lead['convertedAtMs']),\n createdAt: isoOf(lead['createdAt']),\n updatedAt: isoOf(lead['updatedAt']),\n ...customTransferValues(definitions, lead['custom']),\n [TRANSFER_ID_FIELD]: id,\n }\n}\n\n/** Everything one apply call shares. */\ninterface ApplyRun {\n env: CrmTransferEnv\n hostId: string\n statuses: CrmPicklist\n leadSources: CrmPicklist\n picklists: Awaited<ReturnType<typeof readLeadPicklists>>\n definitions: ContactFieldDefinition[]\n campaigns: Awaited<ReturnType<typeof campaignDirectory>>\n}\n\n/** The leads these ids name, as values (campaigns by name, so the plan compares what a file carries). */\nasync function readLeads(run: Pick<ApplyRun, 'env' | 'statuses' | 'definitions' | 'campaigns'>, ids: readonly string[]) {\n const out = new Map<string, Record<string, unknown>>()\n const wanted = ids.filter((id) => id && !id.includes('/'))\n for (let at = 0; at < wanted.length; at += 500) {\n for (const snapshot of await run.env.firestore.getAll(...wanted.slice(at, at + 500).map((id) => leadsOf(run.env).doc(id)))) {\n const data = snapshot.data()\n if (snapshot.exists && data && visibleIn(run.env, data['visibleTo'])) {\n out.set(snapshot.id, leadTransferValues(snapshot.id, data, run.statuses, run.definitions, { campaign: (id) => run.campaigns.names.get(id) }))\n }\n }\n }\n return out\n}\n\n/**\n * The fields a row's values write to a lead, over the lead as it stands;\n * `null` clears. Each value is held to the shape the lead page stores it in.\n */\nfunction leadFields(\n run: ApplyRun,\n values: Readonly<Record<string, unknown>>,\n current: Record<string, unknown> | null,\n): Record<string, unknown> {\n const fields: Record<string, unknown> = {}\n const text = (key: string, max = 120) => textOf(values[key]).slice(0, max) || null\n for (const key of ['company', 'jobTitle', 'salutation', 'industry', 'rating', 'unqualifiedReason'] as const) {\n if (key in values) fields[key] = text(key)\n }\n for (const key of ['firstName', 'lastName'] as const) if (key in values) fields[key] = text(key)\n if ('notes' in values) fields['notes'] = text('notes', 4000)\n for (const key of ['phone', ...CONTACT_EXTRA_PHONE_FIELDS.filter((field) => field === 'mobilePhone' || field === 'fax')] as const) {\n if (!(key in values)) continue\n const typed = textOf(values[key])\n const phone = typed ? normalizePhone(typed) : null\n if (typed && !phone) throw new TransferEngineError('invalid', 422, `“${typed}” is not a phone number.`)\n fields[key] = phone\n }\n if ('website' in values) {\n const typed = textOf(values['website'])\n const website = typed ? normalizeCompanyWebsite(typed) : null\n if (typed && !website) throw new TransferEngineError('invalid', 422, `“${typed}” is not a web address.`)\n fields['website'] = website\n }\n if ('doNotCall' in values) fields['doNotCall'] = values['doNotCall'] === true ? true : null\n if ('numberOfEmployees' in values) fields['numberOfEmployees'] = values['numberOfEmployees'] ?? null\n if ('annualRevenue' in values) {\n const revenue = values['annualRevenue'] as CurrencyAmount | null\n fields['annualRevenueCents'] = revenue && typeof revenue === 'object' ? revenue.amountMinor : null\n fields['currency'] = revenue && typeof revenue === 'object' ? String(revenue.currency).toLowerCase() : null\n }\n const address = addressFromValues('address', values, current?.['address'])\n if (address !== undefined) fields['address'] = address\n if ('tags' in values) fields['tags'] = normalizeCrmLeadTags(values['tags'])\n if ('owner' in values) fields['ownerUid'] = text('owner', 128)\n if ('status' in values) {\n const label = textOf(values['status'])\n if (label) {\n const write = resolveCrmLeadStatusWrite(run.statuses, label, {\n allowed: FILE_STATUSES,\n current: current as never,\n })\n if (write.ok === false) throw new TransferEngineError('invalid', 422, write.error)\n fields['status'] = write.status\n fields['statusLabel'] = write.statusLabel\n }\n }\n // A reason is what an unqualified lead was closed for: on any other lead it is not written.\n if ('unqualifiedReason' in fields && (fields['status'] ?? current?.['status']) !== 'unqualified') {\n delete fields['unqualifiedReason']\n }\n if ('campaigns' in values) {\n const named = Array.isArray(values['campaigns']) ? (values['campaigns'] as unknown[]).map((name) => textOf(name)).filter(Boolean) : []\n const ids = named.map((name) => run.campaigns.byName.get(name.toLowerCase()) ?? '')\n const unknown = named.find((_name, at) => !ids[at])\n if (unknown) throw new TransferEngineError('invalid', 422, `No campaign is called “${unknown}”.`)\n fields['campaignIds'] = [...new Set(ids)]\n }\n return fields\n}\n\n/** Fields as an update writes them: a cleared field is deleted. */\nconst asUpdate = (fields: Record<string, unknown>) =>\n Object.fromEntries(Object.entries(fields).map(([key, value]) => [key, value === null ? FieldValue.delete() : value]))\n\n/**\n * Writes a lead's working state and profile over what it holds, as the lead\n * page writes it: the lead source and the picklists judged against the\n * org's lists, the name composed from its parts, custom values by their\n * definitions, and the list's search and filter keys restamped.\n */\nasync function writeLead(\n run: ApplyRun,\n ref: FirebaseFirestore.DocumentReference,\n values: Readonly<Record<string, unknown>>,\n options: { created: boolean },\n): Promise<void> {\n const stored = (await ref.get()).data() ?? {}\n const fields = leadFields(run, values, stored)\n if ('leadSource' in values || options.created) {\n const source = resolveLeadSourceWrite(run.leadSources, textOf(values['leadSource']) || undefined, {\n current: stored['leadSource'],\n created: options.created,\n })\n if (source.ok === false) throw new TransferEngineError('invalid', 422, source.error)\n if (source.write !== undefined) fields['leadSource'] = source.write\n else if ('leadSource' in values && !textOf(values['leadSource'])) fields['leadSource'] = null\n }\n const patch: Record<string, unknown> = { ...fields }\n const refused = judgeLeadPicklistPatch(run.picklists, patch as never, { current: stored, created: options.created })\n const first = Object.entries(refused)[0]\n if (first) throw new TransferEngineError('invalid', 422, String(first[1]))\n const composed = crmLeadComposedName(stored, {\n ...('firstName' in fields ? { firstName: fields['firstName'] as string | null } : {}),\n ...('lastName' in fields ? { lastName: fields['lastName'] as string | null } : {}),\n } as never)\n if (composed) patch['name'] = composed\n else if ('name' in values && !textOf(stored['firstName']) && !textOf(stored['lastName'])) {\n patch['name'] = textOf(values['name']).slice(0, 120) || null\n }\n const custom = customWriteValues(values, run.definitions, 'lead')\n if ('error' in custom) throw new TransferEngineError('invalid', 422, custom.error)\n for (const [key, value] of Object.entries(custom.values)) patch[`custom.${key}`] = value\n if (!Object.keys(patch).length) return\n await ref.update({ ...asUpdate(patch), updatedAt: FieldValue.serverTimestamp() })\n // What the Leads list searches and filters by (AGL-3321).\n await restampCrmListFieldsAt(ref, 'leads')\n}\n\n/** The `crm.leads` hooks. */\nexport function leadsTransferResource(): TransferRecordsHooks {\n const run = async (ctx: Parameters<NonNullable<TransferRecordsHooks['readPage']>>[0]): Promise<ApplyRun & { hostId: string | null }> => {\n const env = await crmTransferEnv(ctx)\n const [statuses, leadSources, picklists, definitions, campaigns] = await Promise.all([\n readCrmPicklist(env.firestore, env.orgId, CRM_LEAD_STATUS_PICKLIST),\n readLeadSourcePicklist(env.firestore, env.orgId),\n readLeadPicklists(env.firestore, env.orgId),\n crmCustomDefinitions(env, 'lead'),\n campaignDirectory(env),\n ])\n return { env, hostId: env.hostId ?? '', statuses, leadSources, picklists, definitions, campaigns }\n }\n return {\n async fields(ctx) {\n const env = await crmTransferEnv(ctx)\n return {\n standard: LEAD_TRANSFER_FIELDS,\n derived: LEAD_TRANSFER_DERIVED,\n system: CRM_TIMESTAMP_FIELDS,\n custom: crmCustomTransferFields(await crmCustomDefinitions(env, 'lead'), 'lead'),\n groups: LEAD_TRANSFER_GROUPS,\n }\n },\n matchKeys: [\n { fieldId: TRANSFER_ID_FIELD, normalizer: 'aglynId' },\n { fieldId: 'email', normalizer: 'email' },\n ],\n aliases: LEAD_ALIASES,\n lookupTargets: { [CRM_MEMBERS_TARGET]: crmMembersTarget() },\n\n // The people a workspace holds are its own on every plan (AGL-2839).\n async count(ctx, options) {\n const env = await crmTransferEnv(ctx)\n return countCrmExport(env, leadsOf(env), options, (data) => visibleIn(env, data['visibleTo'], options.scopeTokens))\n },\n\n async readPage(ctx, cursor, fieldIds, options) {\n const context = await run(ctx)\n const emails = fieldIds.includes('owner') ? await crmMemberEmails(context.env.orgId) : new Map<string, string>()\n return readCrmExportPage(\n context.env,\n leadsOf(context.env),\n cursor,\n options,\n (data) => visibleIn(context.env, data['visibleTo'], options?.scopeTokens),\n async (docs) =>\n docs.map((doc) =>\n pickValues(\n leadTransferValues(doc.id, doc.data, context.statuses, context.definitions, {\n owner: (uid) => emails.get(uid),\n campaign: (id) => context.campaigns.names.get(id),\n display: true,\n }),\n fieldIds,\n ),\n ),\n )\n },\n\n async lookup(ctx, requests) {\n const context = await run(ctx)\n const visible = (data: Record<string, unknown>) => visibleIn(context.env, data['visibleTo'])\n const found = { lookup: new Map<string, string[]>(), docs: new Map<string, Record<string, unknown>>() }\n for (const request of requests) {\n if (request.fieldId === TRANSFER_ID_FIELD) await lookupById(context.env, leadsOf(context.env), request, visible, found)\n else if (request.fieldId === 'email') {\n // A lead's id IS its person key: one document per person.\n const byKey = new Map<string, string>()\n for (const value of request.values) {\n const key = personKey(value)\n if (key) byKey.set(key, value)\n }\n const keys = [...byKey.keys()]\n for (let at = 0; at < keys.length; at += 500) {\n const page = keys.slice(at, at + 500)\n for (const snapshot of await context.env.firestore.getAll(...page.map((key) => leadsOf(context.env).doc(key)))) {\n const data = snapshot.data()\n if (!snapshot.exists || !data || !visible(data)) continue\n found.docs.set(snapshot.id, data)\n found.lookup.set(matchLookupKey(request.fieldId, byKey.get(snapshot.id) as string), [snapshot.id])\n }\n }\n }\n }\n return lookupResult(found, (id, data) =>\n leadTransferValues(id, data, context.statuses, context.definitions, { campaign: (campaign) => context.campaigns.names.get(campaign) }),\n )\n },\n\n async picklists(ctx, ids) {\n const env = await crmTransferEnv(ctx)\n return crmPicklistLists(env, ids, await crmCustomDefinitions(env, 'lead'))\n },\n\n async addPicklistValues(ctx, picklistId, values) {\n await addCrmPicklistValues(await crmTransferEnv(ctx), picklistId, values)\n },\n\n lockedRules: () => [\n { fieldId: 'email', reason: 'A lead is the person at this address; a different address is a different lead.', forced: { mode: 'keepExisting' } },\n { fieldId: 'status', reason: 'A lead becomes Qualified only by converting it, which makes its contact, company and deal.' },\n { fieldId: 'doNotCall', reason: 'A file can say a person asked not to be called, never that they took it back.', forced: { mode: 'overwrite' } },\n { fieldId: 'name', reason: 'The name is built from the first and last names once either is set.' },\n ],\n\n async plan(ctx, input) {\n const context = await run(ctx)\n requireCrmSuite(context.env, SUITE_ACT)\n requireSite(context.env, 'leads')\n const plan = buildTransferPlan(input)\n return holdBackChanges(plan, (row, change) => {\n const before = row.recordId ? input.existing.get(row.recordId) : undefined\n if (change.fieldId === 'status' && textOf(change.after)) {\n const write = resolveCrmLeadStatusWrite(context.statuses, change.after, { current: null })\n if (write.ok && write.status === 'qualified') return 'Qualified only by converting the lead.'\n }\n if (change.fieldId === 'doNotCall' && before?.['doNotCall'] === true && change.after !== true) {\n return 'Do not call is turned off on the lead’s page, never by a file.'\n }\n if (change.fieldId === 'name') {\n const values = Object.fromEntries(row.diff.map((entry) => [entry.fieldId, entry.after]))\n const first = 'firstName' in values ? values['firstName'] : before?.['firstName']\n const last = 'lastName' in values ? values['lastName'] : before?.['lastName']\n if (textOf(first) || textOf(last)) return 'Built from the first and last names.'\n }\n return null\n })\n },\n\n async apply(ctx, chunk, writer) {\n const context = await run(ctx)\n requireCrmSuite(context.env, SUITE_ACT)\n const { hostId } = requireSite(context.env, 'leads')\n const applyRun: ApplyRun = { ...context, hostId }\n const hostRef = context.env.firestore.collection('hosts').doc(hostId)\n let counted: number | null = null\n let createdHere = 0\n const results: TransferRowResult[] = []\n const undo: TransferUndoEntry[] = []\n await eachWithinBudget(chunk.rows as PlannedTransferRow[], () => writer.timeLeftMs(), async (row) => {\n const earlier = await writer.alreadyApplied(row.index)\n if (earlier) {\n results.push(earlier)\n return\n }\n const changed = row.diff.map((change) => change.fieldId)\n let result: TransferRowResult\n let entry: TransferUndoEntry | undefined\n try {\n const values = plannedValues(row)\n if (row.verdict === 'update' && row.recordId) {\n const before = (await readLeads(applyRun, [row.recordId])).get(row.recordId)\n if (!before) throw new TransferEngineError('notFound', 404, 'That lead no longer exists.')\n const ref = leadsOf(context.env).doc(row.recordId)\n await writeLead(applyRun, ref, values, { created: false })\n const after = (await readLeads(applyRun, [ref.id])).get(ref.id) ?? {}\n result = { row: row.index, outcome: 'updated', recordId: ref.id }\n entry = { row: row.index, recordId: ref.id, action: 'updated', previous: pickValues(before, changed), written: pickValues(after, changed) }\n } else {\n const email = textOf(values['email'])\n const key = personKey(email)\n if (!key) throw new TransferEngineError('invalid', 422, 'Not a valid email address.')\n // Every value read before the door is knocked on, so a row the\n // lead page would refuse files nobody.\n leadFields(applyRun, values, null)\n const custom = customWriteValues(values, context.definitions, 'lead')\n if ('error' in custom) throw new TransferEngineError('invalid', 422, custom.error)\n if (counted === null) counted = Number((await leadsOf(context.env).count().get()).data().count ?? 0)\n if (checkVisitorRecordCeiling(counted + createdHere, LEADS_MAX_PER_HOST).exceeded) {\n throw new TransferEngineError('invalid', 422, 'This site holds as many leads as it can.')\n }\n // The door every capture goes through: the person keyed by address,\n // the ceiling judged again in its own transaction, the site's scope.\n const outcome = await addHostLeadOutcome({\n hostRef,\n hostId,\n lead: { email, ...(textOf(values['name']) ? { name: textOf(values['name']) } : {}), source: LEAD_IMPORT_SOURCE },\n })\n if (!outcome.stored) throw new TransferEngineError('invalid', 422, 'The lead could not be saved; this site may hold as many leads as it can.')\n if (outcome.created) createdHere += 1\n const ref = leadsOf(context.env).doc(key)\n await writeLead(applyRun, ref, values, { created: outcome.created })\n const after = (await readLeads(applyRun, [ref.id])).get(ref.id) ?? {}\n result = {\n row: row.index,\n outcome: outcome.created ? 'created' : 'updated',\n recordId: ref.id,\n ...(outcome.created ? {} : { message: 'Merged into the lead already holding this address.' }),\n }\n entry = outcome.created\n ? { row: row.index, recordId: ref.id, action: 'created', written: pickValues(after, changed) }\n : undefined\n }\n } catch (error) {\n result = { row: row.index, outcome: 'failed', ...(row.recordId ? { recordId: row.recordId } : {}), message: failureMessage(error) }\n entry = undefined\n }\n await writer.markApplied(result, entry)\n results.push(result)\n if (entry) undo.push(entry)\n })\n return { results, undo }\n },\n\n async revert(ctx, snapshot, decisions) {\n const context = await run(ctx)\n const { hostId } = requireSite(context.env, 'leads')\n const applyRun: ApplyRun = { ...context, hostId }\n const current = await readLeads(applyRun, snapshot.entries.map((entry) => entry.recordId))\n const done: TransferUndoStep[] = []\n const conflicts: TransferUndoStep[] = []\n for (const entry of snapshot.entries) {\n const step = planTransferUndo(entry, current.get(entry.recordId) ?? null)\n if (step.action === 'conflict' && decisions?.[entry.recordId] !== 'revert') {\n if (decisions?.[entry.recordId] === 'keep') done.push({ action: 'nothing', recordId: entry.recordId, why: 'alreadyReverted' })\n else conflicts.push(step)\n continue\n }\n if (step.action === 'nothing') {\n done.push(step)\n continue\n }\n const ref = leadsOf(context.env).doc(entry.recordId)\n if (entry.action === 'created') {\n await ref.delete()\n done.push({ action: 'delete', recordId: entry.recordId })\n continue\n }\n await writeLead(applyRun, ref, step.action === 'restore' || step.action === 'conflict' ? step.values : {}, { created: false })\n done.push(step)\n }\n return { done, conflicts }\n },\n }\n}\n"],"names":["checkVisitorRecordCeiling","CONTACT_EXTRA_PHONE_FIELDS","CRM_LEAD_STATUS_PICKLIST","CRM_LEAD_STATUSES","crmLeadComposedName","crmLeadStatusLabel","LEADS_MAX_PER_HOST","normalizeCompanyWebsite","normalizeCrmLeadTags","normalizePhone","personKey","resolveCrmLeadStatusWrite","CONTACT_SOURCE_LABELS","buildTransferPlan","matchLookupKey","planTransferUndo","TRANSFER_ID_FIELD","addHostLeadOutcome","restampCrmListFieldsAt","FieldValue","judgeLeadPicklistPatch","readLeadPicklists","readLeadSourcePicklist","resolveLeadSourceWrite","readCrmPicklist","LEAD_ALIASES","addCrmPicklistValues","addressFromValues","addressValues","campaignDirectory","countCrmExport","crmCustomDefinitions","crmMemberEmails","crmMembersTarget","crmPicklistLists","crmTransferEnv","customTransferValues","customWriteValues","eachWithinBudget","failureMessage","holdBackChanges","isoOf","lookupById","lookupResult","pickValues","plannedValues","readCrmExportPage","requireCrmSuite","requireSite","textOf","TransferEngineError","visibleIn","CRM_MEMBERS_TARGET","CRM_TIMESTAMP_FIELDS","crmCustomTransferFields","LEAD_TRANSFER_DERIVED","LEAD_TRANSFER_FIELDS","LEAD_TRANSFER_GROUPS","SUITE_ACT","LEAD_IMPORT_SOURCE","FILE_STATUSES","filter","status","leadsOf","env","orgRef","collection","captureSourceLabel","source","import","form","startsWith","slice","length","captureSources","lead","sources","Array","isArray","map","String","leadTransferValues","id","statuses","definitions","names","text","value","revenue","currency","toUpperCase","ownerUid","campaignIds","captures","Number","name","email","salutation","firstName","lastName","company","jobTitle","phone","mobilePhone","fax","doNotCall","website","owner","leadSource","industry","rating","numberOfEmployees","annualRevenue","display","toFixed","amountMinor","tags","campaigns","campaign","notes","unqualifiedReason","firstSeenAt","lastSeenAt","isFinite","convertedAt","createdAt","updatedAt","readLeads","run","ids","out","Map","wanted","includes","at","snapshot","firestore","getAll","doc","data","exists","set","get","leadFields","values","current","fields","key","max","field","typed","toLowerCase","address","undefined","label","write","allowed","ok","error","statusLabel","named","Boolean","byName","unknown","find","_name","Set","asUpdate","Object","fromEntries","entries","delete","writeLead","ref","options","stored","created","leadSources","patch","refused","picklists","first","composed","custom","keys","update","serverTimestamp","leadsTransferResource","ctx","Promise","all","orgId","hostId","standard","derived","system","groups","matchKeys","fieldId","normalizer","aliases","lookupTargets","count","scopeTokens","readPage","cursor","fieldIds","context","emails","docs","uid","lookup","requests","visible","found","request","byKey","page","addPicklistValues","picklistId","lockedRules","reason","forced","mode","plan","input","row","change","before","recordId","existing","after","diff","entry","last","apply","chunk","writer","applyRun","hostRef","counted","createdHere","results","undo","rows","timeLeftMs","earlier","alreadyApplied","index","push","changed","result","verdict","outcome","action","previous","written","exceeded","message","markApplied","revert","decisions","done","conflicts","step","why"],"mappings":"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"}
@@ -0,0 +1,21 @@
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 TransferExportHooks } from './common';
18
+ /** The `crm.pipelines` hooks. */
19
+ export declare function pipelinesTransferResource(): TransferExportHooks;
20
+ /** The `crm.fields` hooks. */
21
+ export declare function fieldDefinitionsTransferResource(): TransferExportHooks;
@@ -0,0 +1,172 @@
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
+ * PIPELINES AND FIELD DEFINITIONS, AS FILES (AGL-3528) — `crm.pipelines`
19
+ * and `crm.fields`, exported.
20
+ *
21
+ * The shape of the CRM rather than its records: each pipeline with its
22
+ * stages in order (one row per stage — its kind, its probability, its
23
+ * forecast category), and every custom field the organization defined, on
24
+ * which kind of record, of what type, with its choices. Taken out to
25
+ * document a setup or to rebuild it elsewhere; both are edited on their
26
+ * own pages, so neither is imported (`directions: ["export"]`).
27
+ *=========================================*/ import { CRM_COLLECTIONS, CRM_FIELD_OBJECT_LABELS, CRM_FORECAST_CATEGORY_LABELS, dealStageForecastCategory, fieldDefinitionObject, isPipelineArchived } from "@aglyn/aglyn/server";
28
+ import { TRANSFER_ID_FIELD, matchLookupKey } from "@aglyn/aglyn/data-transfer";
29
+ import { crmTransferEnv, isoOf, pickValues, requireCrmRecords, textOf, visibleIn } from "./common.js";
30
+ import { CRM_TIMESTAMP_FIELDS, FIELD_DEFINITION_TRANSFER_FIELDS, PIPELINE_TRANSFER_FIELDS, PIPELINE_TRANSFER_GROUPS } from "./fields.js";
31
+ /** How a stage's kind reads in a file. */ const STAGE_KINDS = {
32
+ open: 'Open',
33
+ won: 'Won',
34
+ lost: 'Lost'
35
+ };
36
+ /** How a custom field's type reads in a file. */ const FIELD_TYPES = {
37
+ text: 'Text',
38
+ number: 'Number',
39
+ date: 'Date',
40
+ select: 'Dropdown',
41
+ checkbox: 'Checkbox',
42
+ url: 'Link'
43
+ };
44
+ /** Pages `rows` by offset, honoring a selection by row id. */ function pagedHooks(source) {
45
+ const selected = async (ctx, options)=>{
46
+ const env = await crmTransferEnv(ctx);
47
+ requireCrmRecords(env, 'the CRM’s setup');
48
+ const rows = await source.rows(env, options);
49
+ const ids = (options == null ? void 0 : options.ids) ? new Set(options.ids) : null;
50
+ return ids ? rows.filter((row)=>ids.has(String(row[TRANSFER_ID_FIELD]))) : rows;
51
+ };
52
+ return {
53
+ matchKeys: [
54
+ {
55
+ fieldId: TRANSFER_ID_FIELD,
56
+ normalizer: 'aglynId'
57
+ }
58
+ ],
59
+ async count (ctx, options) {
60
+ return (await selected(ctx, options)).length;
61
+ },
62
+ async readPage (ctx, cursor, fieldIds, options) {
63
+ var _ref;
64
+ const rows = await selected(ctx, options);
65
+ const start = Number(cursor != null ? cursor : 0) || 0;
66
+ const size = Math.min((_ref = options == null ? void 0 : options.pageSize) != null ? _ref : 500, 500);
67
+ return {
68
+ rows: rows.slice(start, start + size).map((row)=>pickValues(row, fieldIds)),
69
+ next: start + size < rows.length ? String(start + size) : null
70
+ };
71
+ },
72
+ async lookup (ctx, requests) {
73
+ const rows = await selected(ctx, undefined);
74
+ const lookup = new Map();
75
+ const records = new Map();
76
+ for (const request of requests){
77
+ if (request.fieldId !== TRANSFER_ID_FIELD) continue;
78
+ for (const value of request.values){
79
+ const row = rows.find((entry)=>entry[TRANSFER_ID_FIELD] === value);
80
+ if (!row) continue;
81
+ lookup.set(matchLookupKey(request.fieldId, value), [
82
+ value
83
+ ]);
84
+ records.set(value, row);
85
+ }
86
+ }
87
+ return {
88
+ lookup,
89
+ records
90
+ };
91
+ }
92
+ };
93
+ }
94
+ /** One row per stage, pipeline by pipeline, in the order the board shows them. */ const PIPELINE_ROWS = {
95
+ async rows (env, options) {
96
+ const snapshot = await env.orgRef.collection(CRM_COLLECTIONS.pipelines).get();
97
+ return snapshot.docs.map((doc)=>({
98
+ id: doc.id,
99
+ pipeline: doc.data()
100
+ })).filter((entry)=>visibleIn(env, entry.pipeline.visibleTo, options == null ? void 0 : options.scopeTokens)).sort((a, b)=>Number(Boolean(b.pipeline.isDefault)) - Number(Boolean(a.pipeline.isDefault)) || textOf(a.pipeline.name).localeCompare(textOf(b.pipeline.name))).flatMap(({ id, pipeline })=>{
101
+ var _pipeline_stages;
102
+ return [
103
+ ...(_pipeline_stages = pipeline.stages) != null ? _pipeline_stages : []
104
+ ].sort((a, b)=>a.order - b.order).map((stage, position)=>{
105
+ var _STAGE_KINDS_stage_kind;
106
+ return {
107
+ pipeline: textOf(pipeline.name) || null,
108
+ pipelineId: id,
109
+ isDefault: pipeline.isDefault === true,
110
+ archived: isPipelineArchived(pipeline),
111
+ stage: textOf(stage.name) || null,
112
+ stageId: stage.id,
113
+ position: position + 1,
114
+ kind: (_STAGE_KINDS_stage_kind = STAGE_KINDS[stage.kind]) != null ? _STAGE_KINDS_stage_kind : stage.kind,
115
+ probability: typeof stage.probability === 'number' ? stage.probability : null,
116
+ forecastCategory: CRM_FORECAST_CATEGORY_LABELS[dealStageForecastCategory(stage)],
117
+ createdAt: isoOf(pipeline.createdAt),
118
+ updatedAt: isoOf(pipeline.updatedAt),
119
+ [TRANSFER_ID_FIELD]: `${id}:${stage.id}`
120
+ };
121
+ });
122
+ });
123
+ }
124
+ };
125
+ /** Every custom field, by the record it describes and then its order. */ const FIELD_ROWS = {
126
+ async rows (env, options) {
127
+ const snapshot = await env.orgRef.collection(CRM_COLLECTIONS.contactFields).limit(500).get();
128
+ return snapshot.docs.map((doc)=>({
129
+ id: doc.id,
130
+ field: doc.data()
131
+ })).filter((entry)=>entry.field.key && visibleIn(env, entry.field.visibleTo, options == null ? void 0 : options.scopeTokens)).map((entry)=>_extends({}, entry, {
132
+ object: fieldDefinitionObject(entry.field)
133
+ })).sort((a, b)=>{
134
+ var _a_field_order, _b_field_order;
135
+ return a.object.localeCompare(b.object) || Number((_a_field_order = a.field.order) != null ? _a_field_order : 0) - Number((_b_field_order = b.field.order) != null ? _b_field_order : 0);
136
+ }).map(({ id, field, object })=>{
137
+ var _CRM_FIELD_OBJECT_LABELS_object, _FIELD_TYPES_field_type;
138
+ return {
139
+ label: textOf(field.label) || field.key,
140
+ key: field.key,
141
+ object: (_CRM_FIELD_OBJECT_LABELS_object = CRM_FIELD_OBJECT_LABELS[object]) != null ? _CRM_FIELD_OBJECT_LABELS_object : object,
142
+ type: (_FIELD_TYPES_field_type = FIELD_TYPES[field.type]) != null ? _FIELD_TYPES_field_type : field.type,
143
+ options: Array.isArray(field.options) ? field.options.map(String) : [],
144
+ required: field.required === true,
145
+ position: typeof field.order === 'number' ? field.order : null,
146
+ retired: typeof field.retiredAt === 'number' && field.retiredAt > 0,
147
+ createdAt: isoOf(field.createdAt),
148
+ updatedAt: isoOf(field.updatedAt),
149
+ [TRANSFER_ID_FIELD]: id
150
+ };
151
+ });
152
+ }
153
+ };
154
+ /** The `crm.pipelines` hooks. */ export function pipelinesTransferResource() {
155
+ return _extends({
156
+ fields: ()=>({
157
+ standard: PIPELINE_TRANSFER_FIELDS,
158
+ system: CRM_TIMESTAMP_FIELDS,
159
+ groups: PIPELINE_TRANSFER_GROUPS
160
+ })
161
+ }, pagedHooks(PIPELINE_ROWS));
162
+ }
163
+ /** The `crm.fields` hooks. */ export function fieldDefinitionsTransferResource() {
164
+ return _extends({
165
+ fields: ()=>({
166
+ standard: FIELD_DEFINITION_TRANSFER_FIELDS,
167
+ system: CRM_TIMESTAMP_FIELDS
168
+ })
169
+ }, pagedHooks(FIELD_ROWS));
170
+ }
171
+
172
+ //# sourceMappingURL=pipelines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/transfer/pipelines.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 * PIPELINES AND FIELD DEFINITIONS, AS FILES (AGL-3528) — `crm.pipelines`\n * and `crm.fields`, exported.\n *\n * The shape of the CRM rather than its records: each pipeline with its\n * stages in order (one row per stage — its kind, its probability, its\n * forecast category), and every custom field the organization defined, on\n * which kind of record, of what type, with its choices. Taken out to\n * document a setup or to rebuild it elsewhere; both are edited on their\n * own pages, so neither is imported (`directions: [\"export\"]`).\n *=========================================*/\n\nimport {\n CRM_COLLECTIONS,\n CRM_FIELD_OBJECT_LABELS,\n CRM_FORECAST_CATEGORY_LABELS,\n type ContactFieldDefinition,\n type CrmDealStage,\n type CrmPipeline,\n dealStageForecastCategory,\n fieldDefinitionObject,\n isPipelineArchived,\n} from '@aglyn/aglyn/server'\nimport { TRANSFER_ID_FIELD, matchLookupKey } from '@aglyn/aglyn/data-transfer'\nimport type {\n TransferReadOptions,\n TransferResourceContext,\n} from '@aglyn/aglyn/plugin-manager/plugin-transfer-resources'\nimport {\n crmTransferEnv,\n type CrmTransferEnv,\n isoOf,\n pickValues,\n requireCrmRecords,\n textOf,\n type TransferExportHooks,\n visibleIn,\n} from './common'\nimport {\n CRM_TIMESTAMP_FIELDS,\n FIELD_DEFINITION_TRANSFER_FIELDS,\n PIPELINE_TRANSFER_FIELDS,\n PIPELINE_TRANSFER_GROUPS,\n} from './fields'\n\n/** How a stage's kind reads in a file. */\nconst STAGE_KINDS: Readonly<Record<string, string>> = { open: 'Open', won: 'Won', lost: 'Lost' }\n\n/** How a custom field's type reads in a file. */\nconst FIELD_TYPES: Readonly<Record<string, string>> = {\n text: 'Text',\n number: 'Number',\n date: 'Date',\n select: 'Dropdown',\n checkbox: 'Checkbox',\n url: 'Link',\n}\n\n/** A whole collection as rows, read once: what these small exports page over. */\ninterface RowSource {\n rows(env: CrmTransferEnv, options: TransferReadOptions | undefined): Promise<Array<Record<string, unknown>>>\n}\n\n/** Pages `rows` by offset, honoring a selection by row id. */\nfunction pagedHooks(source: RowSource): Pick<TransferExportHooks, 'count' | 'readPage' | 'lookup' | 'matchKeys'> {\n const selected = async (ctx: TransferResourceContext, options: TransferReadOptions | undefined) => {\n const env = await crmTransferEnv(ctx)\n requireCrmRecords(env, 'the CRM’s setup')\n const rows = await source.rows(env, options)\n const ids = options?.ids ? new Set(options.ids) : null\n return ids ? rows.filter((row) => ids.has(String(row[TRANSFER_ID_FIELD]))) : rows\n }\n return {\n matchKeys: [{ fieldId: TRANSFER_ID_FIELD, normalizer: 'aglynId' }],\n async count(ctx, options) {\n return (await selected(ctx, options)).length\n },\n async readPage(ctx, cursor, fieldIds, options) {\n const rows = await selected(ctx, options)\n const start = Number(cursor ?? 0) || 0\n const size = Math.min(options?.pageSize ?? 500, 500)\n return {\n rows: rows.slice(start, start + size).map((row) => pickValues(row, fieldIds)),\n next: start + size < rows.length ? String(start + size) : null,\n }\n },\n async lookup(ctx, requests) {\n const rows = await selected(ctx, undefined)\n const lookup = new Map<string, string[]>()\n const records = new Map<string, Readonly<Record<string, unknown>>>()\n for (const request of requests) {\n if (request.fieldId !== TRANSFER_ID_FIELD) continue\n for (const value of request.values) {\n const row = rows.find((entry) => entry[TRANSFER_ID_FIELD] === value)\n if (!row) continue\n lookup.set(matchLookupKey(request.fieldId, value), [value])\n records.set(value, row)\n }\n }\n return { lookup, records }\n },\n }\n}\n\n/** One row per stage, pipeline by pipeline, in the order the board shows them. */\nconst PIPELINE_ROWS: RowSource = {\n async rows(env, options) {\n const snapshot = await env.orgRef.collection(CRM_COLLECTIONS.pipelines).get()\n return snapshot.docs\n .map((doc) => ({ id: doc.id, pipeline: doc.data() as CrmPipeline }))\n .filter((entry) => visibleIn(env, entry.pipeline.visibleTo, options?.scopeTokens))\n .sort((a, b) => Number(Boolean(b.pipeline.isDefault)) - Number(Boolean(a.pipeline.isDefault)) || textOf(a.pipeline.name).localeCompare(textOf(b.pipeline.name)))\n .flatMap(({ id, pipeline }) =>\n [...(pipeline.stages ?? [])]\n .sort((a, b) => a.order - b.order)\n .map((stage: CrmDealStage, position) => ({\n pipeline: textOf(pipeline.name) || null,\n pipelineId: id,\n isDefault: pipeline.isDefault === true,\n archived: isPipelineArchived(pipeline),\n stage: textOf(stage.name) || null,\n stageId: stage.id,\n position: position + 1,\n kind: STAGE_KINDS[stage.kind] ?? stage.kind,\n probability: typeof stage.probability === 'number' ? stage.probability : null,\n forecastCategory: CRM_FORECAST_CATEGORY_LABELS[dealStageForecastCategory(stage)],\n createdAt: isoOf(pipeline.createdAt),\n updatedAt: isoOf(pipeline.updatedAt),\n [TRANSFER_ID_FIELD]: `${id}:${stage.id}`,\n })),\n )\n },\n}\n\n/** Every custom field, by the record it describes and then its order. */\nconst FIELD_ROWS: RowSource = {\n async rows(env, options) {\n const snapshot = await env.orgRef.collection(CRM_COLLECTIONS.contactFields).limit(500).get()\n return snapshot.docs\n .map((doc) => ({ id: doc.id, field: doc.data() as ContactFieldDefinition }))\n .filter((entry) => entry.field.key && visibleIn(env, entry.field.visibleTo, options?.scopeTokens))\n .map((entry) => ({ ...entry, object: fieldDefinitionObject(entry.field) }))\n .sort((a, b) => a.object.localeCompare(b.object) || Number(a.field.order ?? 0) - Number(b.field.order ?? 0))\n .map(({ id, field, object }) => ({\n label: textOf(field.label) || field.key,\n key: field.key,\n object: CRM_FIELD_OBJECT_LABELS[object] ?? object,\n type: FIELD_TYPES[field.type] ?? field.type,\n options: Array.isArray(field.options) ? field.options.map(String) : [],\n required: field.required === true,\n position: typeof field.order === 'number' ? field.order : null,\n retired: typeof field.retiredAt === 'number' && field.retiredAt > 0,\n createdAt: isoOf(field.createdAt),\n updatedAt: isoOf(field.updatedAt),\n [TRANSFER_ID_FIELD]: id,\n }))\n },\n}\n\n/** The `crm.pipelines` hooks. */\nexport function pipelinesTransferResource(): TransferExportHooks {\n return {\n fields: () => ({ standard: PIPELINE_TRANSFER_FIELDS, system: CRM_TIMESTAMP_FIELDS, groups: PIPELINE_TRANSFER_GROUPS }),\n ...pagedHooks(PIPELINE_ROWS),\n }\n}\n\n/** The `crm.fields` hooks. */\nexport function fieldDefinitionsTransferResource(): TransferExportHooks {\n return {\n fields: () => ({ standard: FIELD_DEFINITION_TRANSFER_FIELDS, system: CRM_TIMESTAMP_FIELDS }),\n ...pagedHooks(FIELD_ROWS),\n }\n}\n"],"names":["CRM_COLLECTIONS","CRM_FIELD_OBJECT_LABELS","CRM_FORECAST_CATEGORY_LABELS","dealStageForecastCategory","fieldDefinitionObject","isPipelineArchived","TRANSFER_ID_FIELD","matchLookupKey","crmTransferEnv","isoOf","pickValues","requireCrmRecords","textOf","visibleIn","CRM_TIMESTAMP_FIELDS","FIELD_DEFINITION_TRANSFER_FIELDS","PIPELINE_TRANSFER_FIELDS","PIPELINE_TRANSFER_GROUPS","STAGE_KINDS","open","won","lost","FIELD_TYPES","text","number","date","select","checkbox","url","pagedHooks","source","selected","ctx","options","env","rows","ids","Set","filter","row","has","String","matchKeys","fieldId","normalizer","count","length","readPage","cursor","fieldIds","start","Number","size","Math","min","pageSize","slice","map","next","lookup","requests","undefined","Map","records","request","value","values","find","entry","set","PIPELINE_ROWS","snapshot","orgRef","collection","pipelines","get","docs","doc","id","pipeline","data","visibleTo","scopeTokens","sort","a","b","Boolean","isDefault","name","localeCompare","flatMap","stages","order","stage","position","pipelineId","archived","stageId","kind","probability","forecastCategory","createdAt","updatedAt","FIELD_ROWS","contactFields","limit","field","key","object","label","type","Array","isArray","required","retired","retiredAt","pipelinesTransferResource","fields","standard","system","groups","fieldDefinitionsTransferResource"],"mappings":"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"}
@@ -0,0 +1,47 @@
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 { PluginTransferResource, TransferPlanGateHooks, TransferRecordsHooks } from '@aglyn/aglyn/plugin-manager/plugin-transfer-resources';
18
+ import type { MatchKeySpec, TransferAliasDictionary } from '@aglyn/aglyn/data-transfer';
19
+ /** What a resource is registered with before its module loads. */
20
+ interface LazyResource {
21
+ key: string;
22
+ /** What the records are called inside a refusal's sentence ("Exporting companies"). */
23
+ noun: string;
24
+ matchKeys: readonly MatchKeySpec[];
25
+ aliases?: readonly TransferAliasDictionary[];
26
+ /** Lookup targets the resource answers itself, by key. */
27
+ targets?: readonly string[];
28
+ /** The hooks its module answers, beyond the required reads; every one by default. */
29
+ hooks?: readonly (typeof HOOKS)[number][];
30
+ load: () => Promise<Partial<TransferRecordsHooks>>;
31
+ }
32
+ /** Every hook a records resource may answer with, besides its data. */
33
+ declare const HOOKS: readonly ["fields", "count", "readPage", "lookup", "suggest", "picklists", "addPicklistValues", "plan", "lockedRules", "apply", "revert"];
34
+ /**
35
+ * The CRM's plan question for a transfer (AGL-3555), in the words of every
36
+ * other CRM route: `suite-gate.ts`'s refusal, 403 `plan_required` / `crm`.
37
+ * The declaration (`featureFlag: "crm"`) decides which intents ask — every
38
+ * one, but the contacts and leads exports — and this answers them.
39
+ */
40
+ export declare function crmTransferPlanGate(noun: string): NonNullable<TransferPlanGateHooks['planGate']>;
41
+ /** A resource whose hooks load its module with the first call, once. */
42
+ export declare function lazyCrmTransferResource(resource: LazyResource): PluginTransferResource;
43
+ /** The CRM's resources: what each is found by, how other products name its columns, and where it loads from. */
44
+ export declare const CRM_TRANSFER_RESOURCES: readonly LazyResource[];
45
+ /** Registers the server half of every CRM transfer resource. Registering again replaces them. */
46
+ export declare function registerCrmTransferResources(pluginId: string): void;
47
+ export {};