@aglyn/plugins-crm 1.0.0-beta.221 → 1.0.0-beta.223
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.
- package/README.md +2 -1
- package/package.json +13 -13
- package/src/lib/components/activity-list.js +12 -5
- package/src/lib/components/activity-list.js.map +1 -1
- package/src/lib/components/companies-bulk-bar.d.ts +1 -4
- package/src/lib/components/companies-bulk-bar.js +7 -20
- package/src/lib/components/companies-bulk-bar.js.map +1 -1
- package/src/lib/components/companies-section.d.ts +3 -3
- package/src/lib/components/companies-section.js +149 -46
- package/src/lib/components/companies-section.js.map +1 -1
- package/src/lib/components/company-edit-drawer.js +281 -20
- package/src/lib/components/company-edit-drawer.js.map +1 -1
- package/src/lib/components/company-properties-card.js +99 -8
- package/src/lib/components/company-properties-card.js.map +1 -1
- package/src/lib/components/contact-detail-page.js +3 -1
- package/src/lib/components/contact-detail-page.js.map +1 -1
- package/src/lib/components/contact-merge-dialog.js +33 -10
- package/src/lib/components/contact-merge-dialog.js.map +1 -1
- package/src/lib/components/contact-properties-card.d.ts +0 -69
- package/src/lib/components/contact-properties-card.js +350 -60
- package/src/lib/components/contact-properties-card.js.map +1 -1
- package/src/lib/components/contact-reports-to-field.d.ts +46 -0
- package/src/lib/components/contact-reports-to-field.js +67 -0
- package/src/lib/components/contact-reports-to-field.js.map +1 -0
- package/src/lib/components/contacts-bulk-bar.d.ts +1 -8
- package/src/lib/components/contacts-bulk-bar.js +7 -19
- package/src/lib/components/contacts-bulk-bar.js.map +1 -1
- package/src/lib/components/contacts-section.js +46 -33
- package/src/lib/components/contacts-section.js.map +1 -1
- package/src/lib/components/crm-call-actions.d.ts +10 -0
- package/src/lib/components/crm-call-actions.js +26 -9
- package/src/lib/components/crm-call-actions.js.map +1 -1
- package/src/lib/components/crm-next-activity-column.js +1 -1
- package/src/lib/components/crm-next-activity-column.js.map +1 -1
- package/src/lib/components/crm-record-picker.d.ts +15 -0
- package/src/lib/components/crm-record-picker.js +16 -10
- package/src/lib/components/crm-record-picker.js.map +1 -1
- package/src/lib/components/crm-transfer-buttons.d.ts +54 -0
- package/src/lib/components/crm-transfer-buttons.js +167 -0
- package/src/lib/components/crm-transfer-buttons.js.map +1 -0
- package/src/lib/components/deal-contact-roles-card.d.ts +46 -0
- package/src/lib/components/deal-contact-roles-card.js +368 -0
- package/src/lib/components/deal-contact-roles-card.js.map +1 -0
- package/src/lib/components/deal-detail-page.d.ts +3 -2
- package/src/lib/components/deal-detail-page.js +25 -6
- package/src/lib/components/deal-detail-page.js.map +1 -1
- package/src/lib/components/deal-edit-drawer.d.ts +10 -0
- package/src/lib/components/deal-edit-drawer.js +219 -10
- package/src/lib/components/deal-edit-drawer.js.map +1 -1
- package/src/lib/components/deal-properties-card.d.ts +7 -0
- package/src/lib/components/deal-properties-card.js +34 -3
- package/src/lib/components/deal-properties-card.js.map +1 -1
- package/src/lib/components/deal-stage-card.d.ts +4 -0
- package/src/lib/components/deal-stage-card.js +10 -2
- package/src/lib/components/deal-stage-card.js.map +1 -1
- package/src/lib/components/deals-bulk-bar.d.ts +0 -3
- package/src/lib/components/deals-bulk-bar.js +7 -20
- package/src/lib/components/deals-bulk-bar.js.map +1 -1
- package/src/lib/components/deals-section.d.ts +3 -3
- package/src/lib/components/deals-section.js +123 -63
- package/src/lib/components/deals-section.js.map +1 -1
- package/src/lib/components/fields-section.js +31 -17
- package/src/lib/components/fields-section.js.map +1 -1
- package/src/lib/components/lead-convert-dialog.d.ts +4 -0
- package/src/lib/components/lead-convert-dialog.js +23 -1
- package/src/lib/components/lead-convert-dialog.js.map +1 -1
- package/src/lib/components/lead-detail-page.js +8 -2
- package/src/lib/components/lead-detail-page.js.map +1 -1
- package/src/lib/components/lead-profile-fields.d.ts +71 -0
- package/src/lib/components/lead-profile-fields.js +386 -0
- package/src/lib/components/lead-profile-fields.js.map +1 -0
- package/src/lib/components/lead-properties-card.d.ts +2 -1
- package/src/lib/components/lead-properties-card.js +85 -176
- package/src/lib/components/lead-properties-card.js.map +1 -1
- package/src/lib/components/lead-source-select.d.ts +4 -23
- package/src/lib/components/lead-source-select.js +9 -73
- package/src/lib/components/lead-source-select.js.map +1 -1
- package/src/lib/components/lead-status-chip.d.ts +9 -3
- package/src/lib/components/lead-status-chip.js +8 -4
- package/src/lib/components/lead-status-chip.js.map +1 -1
- package/src/lib/components/lead-status-options.d.ts +20 -0
- package/src/lib/components/lead-status-options.js +51 -0
- package/src/lib/components/lead-status-options.js.map +1 -0
- package/src/lib/components/lead-unqualify-dialog.d.ts +5 -0
- package/src/lib/components/lead-unqualify-dialog.js +50 -18
- package/src/lib/components/lead-unqualify-dialog.js.map +1 -1
- package/src/lib/components/leads-bulk-bar.d.ts +0 -3
- package/src/lib/components/leads-bulk-bar.js +29 -29
- package/src/lib/components/leads-bulk-bar.js.map +1 -1
- package/src/lib/components/leads-section.js +120 -68
- package/src/lib/components/leads-section.js.map +1 -1
- package/src/lib/components/linked-deals-card.d.ts +4 -0
- package/src/lib/components/linked-deals-card.js +47 -3
- package/src/lib/components/linked-deals-card.js.map +1 -1
- package/src/lib/components/log-activity-dialog.js +43 -3
- package/src/lib/components/log-activity-dialog.js.map +1 -1
- package/src/lib/components/new-contact-drawer.d.ts +8 -0
- package/src/lib/components/new-contact-drawer.js +108 -6
- package/src/lib/components/new-contact-drawer.js.map +1 -1
- package/src/lib/components/new-lead-drawer.d.ts +9 -2
- package/src/lib/components/new-lead-drawer.js +88 -121
- package/src/lib/components/new-lead-drawer.js.map +1 -1
- package/src/lib/components/picklist-select.d.ts +36 -0
- package/src/lib/components/picklist-select.js +114 -0
- package/src/lib/components/picklist-select.js.map +1 -0
- package/src/lib/components/picklist-values-card.d.ts +34 -0
- package/src/lib/components/{lead-source-values-card.js → picklist-values-card.js} +241 -58
- package/src/lib/components/picklist-values-card.js.map +1 -0
- package/src/lib/components/pipeline-stages-dialog.d.ts +7 -0
- package/src/lib/components/pipeline-stages-dialog.js +26 -4
- package/src/lib/components/pipeline-stages-dialog.js.map +1 -1
- package/src/lib/components/pipelines-dialog.js +15 -6
- package/src/lib/components/pipelines-dialog.js.map +1 -1
- package/src/lib/components/recent-activity-feed.js +20 -5
- package/src/lib/components/recent-activity-feed.js.map +1 -1
- package/src/lib/components/recipes-card.js +4 -2
- package/src/lib/components/recipes-card.js.map +1 -1
- package/src/lib/components/record-tasks-card.js +15 -8
- package/src/lib/components/record-tasks-card.js.map +1 -1
- package/src/lib/components/reports/forecast-card.d.ts +6 -0
- package/src/lib/components/reports/forecast-card.js +101 -3
- package/src/lib/components/reports/forecast-card.js.map +1 -1
- package/src/lib/components/reports/lead-funnel-card.d.ts +12 -0
- package/src/lib/components/reports/lead-funnel-card.js +9 -5
- package/src/lib/components/reports/lead-funnel-card.js.map +1 -1
- package/src/lib/components/reports/lead-source-card.d.ts +23 -0
- package/src/lib/components/reports/lead-source-card.js +318 -0
- package/src/lib/components/reports/lead-source-card.js.map +1 -0
- package/src/lib/components/reports/pipeline-card.js +2 -1
- package/src/lib/components/reports/pipeline-card.js.map +1 -1
- package/src/lib/components/reports/report-export.js +1 -1
- package/src/lib/components/reports/report-export.js.map +1 -1
- package/src/lib/components/reports-section.js +8 -0
- package/src/lib/components/reports-section.js.map +1 -1
- package/src/lib/components/sharing-rule-drawer.d.ts +5 -0
- package/src/lib/components/sharing-rule-drawer.js +108 -19
- package/src/lib/components/sharing-rule-drawer.js.map +1 -1
- package/src/lib/components/sharing-rules-card.js +11 -3
- package/src/lib/components/sharing-rules-card.js.map +1 -1
- package/src/lib/components/task-cells.d.ts +9 -1
- package/src/lib/components/task-cells.js +9 -4
- package/src/lib/components/task-cells.js.map +1 -1
- package/src/lib/components/task-edit-drawer.js +111 -43
- package/src/lib/components/task-edit-drawer.js.map +1 -1
- package/src/lib/components/tasks-bulk-bar.d.ts +0 -3
- package/src/lib/components/tasks-bulk-bar.js +7 -20
- package/src/lib/components/tasks-bulk-bar.js.map +1 -1
- package/src/lib/components/tasks-calendar.d.ts +3 -0
- package/src/lib/components/tasks-calendar.js +8 -1
- package/src/lib/components/tasks-calendar.js.map +1 -1
- package/src/lib/components/tasks-section.d.ts +3 -3
- package/src/lib/components/tasks-section.js +58 -43
- package/src/lib/components/tasks-section.js.map +1 -1
- package/src/lib/constants/api-routes.d.ts +2 -9
- package/src/lib/constants/api-routes.js +1 -7
- package/src/lib/constants/api-routes.js.map +1 -1
- package/src/lib/constants/bundle-common.d.ts +6 -0
- package/src/lib/constants/bundle-common.js +11 -0
- package/src/lib/constants/bundle-common.js.map +1 -1
- package/src/lib/constants/company-filters.d.ts +14 -0
- package/src/lib/constants/company-filters.js +51 -1
- package/src/lib/constants/company-filters.js.map +1 -1
- package/src/lib/constants/contact-filters.d.ts +2 -0
- package/src/lib/constants/contact-filters.js +18 -1
- package/src/lib/constants/contact-filters.js.map +1 -1
- package/src/lib/constants/deal-filters.d.ts +22 -1
- package/src/lib/constants/deal-filters.js +67 -4
- package/src/lib/constants/deal-filters.js.map +1 -1
- package/src/lib/declarations.console-server.d.ts +3 -0
- package/src/lib/declarations.console-server.js +35 -0
- package/src/lib/declarations.console-server.js.map +1 -1
- package/src/lib/declarations.d.ts +26 -0
- package/src/lib/declarations.js +35 -0
- package/src/lib/declarations.js.map +1 -0
- package/src/lib/declarations.server.d.ts +11 -0
- package/src/lib/declarations.server.js +97 -1
- package/src/lib/declarations.server.js.map +1 -1
- package/src/lib/hooks/use-company-picklists.d.ts +15 -0
- package/src/lib/hooks/use-company-picklists.js +55 -0
- package/src/lib/hooks/use-company-picklists.js.map +1 -0
- package/src/lib/hooks/use-crm-picklist.d.ts +25 -0
- package/src/lib/hooks/use-crm-picklist.js +53 -0
- package/src/lib/hooks/use-crm-picklist.js.map +1 -0
- package/src/lib/hooks/use-crm-record-names.d.ts +16 -0
- package/src/lib/hooks/use-crm-record-names.js +45 -19
- package/src/lib/hooks/use-crm-record-names.js.map +1 -1
- package/src/lib/hooks/use-crm-task-picklists.d.ts +11 -0
- package/src/lib/hooks/use-crm-task-picklists.js +45 -0
- package/src/lib/hooks/use-crm-task-picklists.js.map +1 -0
- package/src/lib/hooks/use-deals.d.ts +14 -0
- package/src/lib/hooks/use-deals.js +29 -0
- package/src/lib/hooks/use-deals.js.map +1 -1
- package/src/lib/hooks/use-lead-picklists.d.ts +14 -0
- package/src/lib/hooks/use-lead-picklists.js +46 -0
- package/src/lib/hooks/use-lead-picklists.js.map +1 -0
- package/src/lib/hooks/use-lead-source-picklist.d.ts +5 -19
- package/src/lib/hooks/use-lead-source-picklist.js +12 -22
- package/src/lib/hooks/use-lead-source-picklist.js.map +1 -1
- package/src/lib/hooks/use-lead-status-picklist.d.ts +9 -0
- package/src/lib/hooks/use-lead-status-picklist.js +40 -0
- package/src/lib/hooks/use-lead-status-picklist.js.map +1 -0
- package/src/lib/model/companies.d.ts +32 -3
- package/src/lib/model/companies.js +133 -16
- package/src/lib/model/companies.js.map +1 -1
- package/src/lib/model/contact-merge.d.ts +27 -3
- package/src/lib/model/contact-merge.js +81 -7
- package/src/lib/model/contact-merge.js.map +1 -1
- package/src/lib/model/contact-record.d.ts +17 -0
- package/src/lib/model/contact-record.js +17 -2
- package/src/lib/model/contact-record.js.map +1 -1
- package/src/lib/model/contact-update.d.ts +31 -2
- package/src/lib/model/contact-update.js +14 -0
- package/src/lib/model/contact-update.js.map +1 -1
- package/src/lib/model/crm-list-query.d.ts +5 -0
- package/src/lib/model/crm-list-query.js +8 -0
- package/src/lib/model/crm-list-query.js.map +1 -1
- package/src/lib/model/crm-next-activity.d.ts +107 -0
- package/src/lib/model/crm-next-activity.js +140 -0
- package/src/lib/model/crm-next-activity.js.map +1 -0
- package/src/lib/model/crm-recipes.d.ts +40 -0
- package/src/lib/model/crm-recipes.js +259 -0
- package/src/lib/model/crm-recipes.js.map +1 -0
- package/src/lib/model/crm-record-counts.d.ts +36 -0
- package/src/lib/model/crm-record-counts.js +54 -0
- package/src/lib/model/crm-record-counts.js.map +1 -0
- package/src/lib/model/crm-record-lists.d.ts +23 -0
- package/src/lib/model/crm-record-lists.js +161 -0
- package/src/lib/model/crm-record-lists.js.map +1 -0
- package/src/lib/model/crm-reports.d.ts +73 -3
- package/src/lib/model/crm-reports.js +120 -1
- package/src/lib/model/crm-reports.js.map +1 -1
- package/src/lib/model/crm-sharing.d.ts +21 -3
- package/src/lib/model/crm-sharing.js +27 -6
- package/src/lib/model/crm-sharing.js.map +1 -1
- package/src/lib/model/crm-task-reminders.d.ts +152 -0
- package/src/lib/model/crm-task-reminders.js +161 -0
- package/src/lib/model/crm-task-reminders.js.map +1 -0
- package/src/lib/model/deal-board-model.d.ts +8 -2
- package/src/lib/model/deal-board-model.js +15 -2
- package/src/lib/model/deal-board-model.js.map +1 -1
- package/src/lib/model/deal-contact-roles.d.ts +45 -0
- package/src/lib/model/deal-contact-roles.js +73 -0
- package/src/lib/model/deal-contact-roles.js.map +1 -0
- package/src/lib/model/deal-form-model.d.ts +56 -0
- package/src/lib/model/deal-form-model.js +79 -7
- package/src/lib/model/deal-form-model.js.map +1 -1
- package/src/lib/model/download-text-file.d.ts +23 -0
- package/src/lib/model/download-text-file.js +34 -0
- package/src/lib/model/download-text-file.js.map +1 -0
- package/src/lib/model/lead-filters.d.ts +36 -2
- package/src/lib/model/lead-filters.js +123 -2
- package/src/lib/model/lead-filters.js.map +1 -1
- package/src/lib/model/lead-source-direction.d.ts +38 -0
- package/src/lib/model/lead-source-direction.js +52 -0
- package/src/lib/model/lead-source-direction.js.map +1 -0
- package/src/lib/model/next-activity.d.ts +1 -1
- package/src/lib/model/next-activity.js.map +1 -1
- package/src/lib/model/picklist-values.d.ts +119 -0
- package/src/lib/model/picklist-values.js +256 -0
- package/src/lib/model/picklist-values.js.map +1 -0
- package/src/lib/model/record-facts-disclosed.d.ts +81 -0
- package/src/lib/model/record-facts-disclosed.js +281 -0
- package/src/lib/model/record-facts-disclosed.js.map +1 -0
- package/src/lib/model/record-facts.d.ts +215 -34
- package/src/lib/model/record-facts.js +307 -128
- package/src/lib/model/record-facts.js.map +1 -1
- package/src/lib/model/task-picklists.d.ts +52 -0
- package/src/lib/model/task-picklists.js +83 -0
- package/src/lib/model/task-picklists.js.map +1 -0
- package/src/lib/model/task-routes.d.ts +13 -0
- package/src/lib/model/task-routes.js +23 -4
- package/src/lib/model/task-routes.js.map +1 -1
- package/src/lib/plan-entitlements.js +6 -4
- package/src/lib/plan-entitlements.js.map +1 -1
- package/src/lib/plugin.js +17 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/server/api-v1/contacts.js +220 -14
- package/src/lib/server/api-v1/contacts.js.map +1 -1
- package/src/lib/server/api-v1/crm-activities.js +14 -1
- package/src/lib/server/api-v1/crm-activities.js.map +1 -1
- package/src/lib/server/api-v1/crm-companies.js +123 -14
- package/src/lib/server/api-v1/crm-companies.js.map +1 -1
- package/src/lib/server/api-v1/crm-deals.js +291 -26
- package/src/lib/server/api-v1/crm-deals.js.map +1 -1
- package/src/lib/server/api-v1/crm-leads.js +144 -38
- package/src/lib/server/api-v1/crm-leads.js.map +1 -1
- package/src/lib/server/api-v1/crm-pipelines.d.ts +6 -0
- package/src/lib/server/api-v1/crm-pipelines.js +8 -2
- package/src/lib/server/api-v1/crm-pipelines.js.map +1 -1
- package/src/lib/server/api-v1/crm-tasks.js +78 -34
- package/src/lib/server/api-v1/crm-tasks.js.map +1 -1
- package/src/lib/server/api-v1/openapi.d.ts +0 -11
- package/src/lib/server/api-v1/openapi.js +171 -16
- package/src/lib/server/api-v1/openapi.js.map +1 -1
- package/src/lib/server/assign-contact-owner.d.ts +188 -0
- package/src/lib/server/assign-contact-owner.js +446 -0
- package/src/lib/server/assign-contact-owner.js.map +1 -0
- package/src/lib/server/associate-company-by-domain.d.ts +70 -0
- package/src/lib/server/associate-company-by-domain.js +153 -0
- package/src/lib/server/associate-company-by-domain.js.map +1 -0
- package/src/lib/server/automation-steps.d.ts +140 -0
- package/src/lib/server/automation-steps.js +669 -0
- package/src/lib/server/automation-steps.js.map +1 -0
- package/src/lib/server/capture-contact.d.ts +17 -0
- package/src/lib/server/capture-contact.js +95 -26
- package/src/lib/server/capture-contact.js.map +1 -1
- package/src/lib/server/capture-host-contact.d.ts +104 -0
- package/src/lib/server/capture-host-contact.js +151 -0
- package/src/lib/server/capture-host-contact.js.map +1 -0
- package/src/lib/server/company-children.d.ts +25 -0
- package/src/lib/server/company-children.js +42 -0
- package/src/lib/server/company-children.js.map +1 -0
- package/src/lib/server/company-delete.d.ts +18 -0
- package/src/lib/server/company-delete.js +44 -21
- package/src/lib/server/company-delete.js.map +1 -1
- package/src/lib/server/contact-email-history.js +21 -19
- package/src/lib/server/contact-email-history.js.map +1 -1
- package/src/lib/server/contact-remove.js +27 -2
- package/src/lib/server/contact-remove.js.map +1 -1
- package/src/lib/server/contact-reports-to.d.ts +61 -0
- package/src/lib/server/contact-reports-to.js +114 -0
- package/src/lib/server/contact-reports-to.js.map +1 -0
- package/src/lib/server/contact-update.d.ts +42 -1
- package/src/lib/server/contact-update.js +204 -23
- package/src/lib/server/contact-update.js.map +1 -1
- package/src/lib/server/convert-host-lead.d.ts +46 -1
- package/src/lib/server/convert-host-lead.js +173 -15
- package/src/lib/server/convert-host-lead.js.map +1 -1
- package/src/lib/server/convert-open-lead.js +12 -5
- package/src/lib/server/convert-open-lead.js.map +1 -1
- package/src/lib/server/crm-email-activity.d.ts +118 -0
- package/src/lib/server/crm-email-activity.js +148 -0
- package/src/lib/server/crm-email-activity.js.map +1 -0
- package/src/lib/server/crm-inbound-email.js +1 -1
- package/src/lib/server/crm-inbound-email.js.map +1 -1
- package/src/lib/server/crm-next-activity.d.ts +74 -0
- package/src/lib/server/crm-next-activity.js +194 -0
- package/src/lib/server/crm-next-activity.js.map +1 -0
- package/src/lib/server/crm-record-indexes.d.ts +45 -0
- package/src/lib/server/crm-record-indexes.js +78 -0
- package/src/lib/server/crm-record-indexes.js.map +1 -0
- package/src/lib/server/crm-sharing.d.ts +9 -1
- package/src/lib/server/crm-sharing.js +23 -3
- package/src/lib/server/crm-sharing.js.map +1 -1
- package/src/lib/server/deal-contact-roles.d.ts +27 -0
- package/src/lib/server/deal-contact-roles.js +89 -0
- package/src/lib/server/deal-contact-roles.js.map +1 -0
- package/src/lib/server/email-send.js +2 -1
- package/src/lib/server/email-send.js.map +1 -1
- package/src/lib/server/lead-convert.d.ts +5 -0
- package/src/lib/server/lead-convert.js +19 -3
- package/src/lib/server/lead-convert.js.map +1 -1
- package/src/lib/server/lead-create.d.ts +17 -2
- package/src/lib/server/lead-create.js +46 -14
- package/src/lib/server/lead-create.js.map +1 -1
- package/src/lib/server/lead-nurturing.d.ts +6 -0
- package/src/lib/server/lead-nurturing.js +57 -20
- package/src/lib/server/lead-nurturing.js.map +1 -1
- package/src/lib/server/lead-picklists.d.ts +35 -0
- package/src/lib/server/lead-picklists.js +52 -0
- package/src/lib/server/lead-picklists.js.map +1 -0
- package/src/lib/server/lead-source-picklist.d.ts +1 -13
- package/src/lib/server/lead-source-picklist.js +6 -33
- package/src/lib/server/lead-source-picklist.js.map +1 -1
- package/src/lib/server/merge-contacts.js +23 -5
- package/src/lib/server/merge-contacts.js.map +1 -1
- package/src/lib/server/next-activity-routes.js +2 -1
- package/src/lib/server/next-activity-routes.js.map +1 -1
- package/src/lib/server/person-eraser.d.ts +53 -0
- package/src/lib/server/person-eraser.js +149 -0
- package/src/lib/server/person-eraser.js.map +1 -0
- package/src/lib/server/person-records.d.ts +69 -0
- package/src/lib/server/person-records.js +317 -0
- package/src/lib/server/person-records.js.map +1 -0
- package/src/lib/server/person-refund.d.ts +97 -0
- package/src/lib/server/person-refund.js +221 -0
- package/src/lib/server/person-refund.js.map +1 -0
- package/src/lib/server/picklist-values.d.ts +21 -0
- package/src/lib/server/picklist-values.js +308 -0
- package/src/lib/server/picklist-values.js.map +1 -0
- package/src/lib/server/read-picklist.d.ts +44 -0
- package/src/lib/server/read-picklist.js +65 -0
- package/src/lib/server/read-picklist.js.map +1 -0
- package/src/lib/server/recipe-routes.js +22 -8
- package/src/lib/server/recipe-routes.js.map +1 -1
- package/src/lib/server/record-email-state.js +7 -1
- package/src/lib/server/record-email-state.js.map +1 -1
- package/src/lib/server/record-facts.d.ts +3 -0
- package/src/lib/server/record-facts.js +233 -31
- package/src/lib/server/record-facts.js.map +1 -1
- package/src/lib/server/record-origin.d.ts +27 -0
- package/src/lib/server/record-origin.js +104 -0
- package/src/lib/server/record-origin.js.map +1 -0
- package/src/lib/server/record-timeline.js +40 -3
- package/src/lib/server/record-timeline.js.map +1 -1
- package/src/lib/server/suite-gate.js +4 -3
- package/src/lib/server/suite-gate.js.map +1 -1
- package/src/lib/server/task-reminders-route.js +2 -1
- package/src/lib/server/task-reminders-route.js.map +1 -1
- package/src/lib/server/task-routes.js +33 -17
- package/src/lib/server/task-routes.js.map +1 -1
- package/src/lib/server-deal-stage.d.ts +5 -1
- package/src/lib/server-deal-stage.js +10 -5
- package/src/lib/server-deal-stage.js.map +1 -1
- package/src/lib/server.d.ts +8 -3
- package/src/lib/server.js +47 -43
- package/src/lib/server.js.map +1 -1
- package/src/lib/testing/memory-firestore.d.ts +55 -0
- package/src/lib/testing/memory-firestore.js +335 -0
- package/src/lib/testing/memory-firestore.js.map +1 -0
- package/src/lib/testing/stand-in-email-send-index.d.ts +25 -0
- package/src/lib/testing/stand-in-email-send-index.js +49 -0
- package/src/lib/testing/stand-in-email-send-index.js.map +1 -0
- package/src/lib/transfer/activities.d.ts +30 -0
- package/src/lib/transfer/activities.js +132 -0
- package/src/lib/transfer/activities.js.map +1 -0
- package/src/lib/transfer/aliases.d.ts +22 -0
- package/src/lib/transfer/aliases.js +1342 -0
- package/src/lib/transfer/aliases.js.map +1 -0
- package/src/lib/transfer/common.d.ts +222 -0
- package/src/lib/transfer/common.js +832 -0
- package/src/lib/transfer/common.js.map +1 -0
- package/src/lib/transfer/companies.d.ts +43 -0
- package/src/lib/transfer/companies.js +549 -0
- package/src/lib/transfer/companies.js.map +1 -0
- package/src/lib/transfer/contacts.d.ts +31 -0
- package/src/lib/transfer/contacts.js +727 -0
- package/src/lib/transfer/contacts.js.map +1 -0
- package/src/lib/transfer/deals.d.ts +66 -0
- package/src/lib/transfer/deals.js +698 -0
- package/src/lib/transfer/deals.js.map +1 -0
- package/src/lib/transfer/email-templates-package.d.ts +40 -0
- package/src/lib/transfer/email-templates-package.js +76 -0
- package/src/lib/transfer/email-templates-package.js.map +1 -0
- package/src/lib/transfer/email-templates-package.server.d.ts +32 -0
- package/src/lib/transfer/email-templates-package.server.js +176 -0
- package/src/lib/transfer/email-templates-package.server.js.map +1 -0
- package/src/lib/transfer/fields.d.ts +102 -0
- package/src/lib/transfer/fields.js +1755 -0
- package/src/lib/transfer/fields.js.map +1 -0
- package/src/lib/transfer/leads.d.ts +30 -0
- package/src/lib/transfer/leads.js +582 -0
- package/src/lib/transfer/leads.js.map +1 -0
- package/src/lib/transfer/pipelines.d.ts +21 -0
- package/src/lib/transfer/pipelines.js +172 -0
- package/src/lib/transfer/pipelines.js.map +1 -0
- package/src/lib/transfer/register.d.ts +47 -0
- package/src/lib/transfer/register.js +277 -0
- package/src/lib/transfer/register.js.map +1 -0
- package/src/lib/transfer/tasks.d.ts +30 -0
- package/src/lib/transfer/tasks.js +418 -0
- package/src/lib/transfer/tasks.js.map +1 -0
- package/src/lib/transfer/ui.d.ts +20 -0
- package/src/lib/transfer/ui.js +42 -0
- package/src/lib/transfer/ui.js.map +1 -0
- package/src/lib/components/company-import-drawer.d.ts +0 -42
- package/src/lib/components/company-import-drawer.js +0 -99
- package/src/lib/components/company-import-drawer.js.map +0 -1
- package/src/lib/components/contact-import-drawer.d.ts +0 -46
- package/src/lib/components/contact-import-drawer.js +0 -149
- package/src/lib/components/contact-import-drawer.js.map +0 -1
- package/src/lib/components/crm-export-all-button.d.ts +0 -39
- package/src/lib/components/crm-export-all-button.js +0 -98
- package/src/lib/components/crm-export-all-button.js.map +0 -1
- package/src/lib/components/csv-import-drawer.d.ts +0 -139
- package/src/lib/components/csv-import-drawer.js +0 -757
- package/src/lib/components/csv-import-drawer.js.map +0 -1
- package/src/lib/components/deal-import-drawer.d.ts +0 -24
- package/src/lib/components/deal-import-drawer.js +0 -83
- package/src/lib/components/deal-import-drawer.js.map +0 -1
- package/src/lib/components/lead-import-drawer.d.ts +0 -27
- package/src/lib/components/lead-import-drawer.js +0 -118
- package/src/lib/components/lead-import-drawer.js.map +0 -1
- package/src/lib/components/lead-source-values-card.d.ts +0 -27
- package/src/lib/components/lead-source-values-card.js.map +0 -1
- package/src/lib/components/task-import-drawer.d.ts +0 -24
- package/src/lib/components/task-import-drawer.js +0 -82
- package/src/lib/components/task-import-drawer.js.map +0 -1
- package/src/lib/model/companies-csv.d.ts +0 -36
- package/src/lib/model/companies-csv.js +0 -38
- package/src/lib/model/companies-csv.js.map +0 -1
- package/src/lib/model/contacts-csv.d.ts +0 -54
- package/src/lib/model/contacts-csv.js +0 -67
- package/src/lib/model/contacts-csv.js.map +0 -1
- package/src/lib/model/crm-company-import.d.ts +0 -154
- package/src/lib/model/crm-company-import.js +0 -331
- package/src/lib/model/crm-company-import.js.map +0 -1
- package/src/lib/model/crm-csv.d.ts +0 -239
- package/src/lib/model/crm-csv.js +0 -467
- package/src/lib/model/crm-csv.js.map +0 -1
- package/src/lib/model/crm-deal-import.d.ts +0 -112
- package/src/lib/model/crm-deal-import.js +0 -263
- package/src/lib/model/crm-deal-import.js.map +0 -1
- package/src/lib/model/crm-import.d.ts +0 -250
- package/src/lib/model/crm-import.js +0 -467
- package/src/lib/model/crm-import.js.map +0 -1
- package/src/lib/model/crm-lead-import.d.ts +0 -138
- package/src/lib/model/crm-lead-import.js +0 -446
- package/src/lib/model/crm-lead-import.js.map +0 -1
- package/src/lib/model/crm-task-import.d.ts +0 -94
- package/src/lib/model/crm-task-import.js +0 -275
- package/src/lib/model/crm-task-import.js.map +0 -1
- package/src/lib/model/deals-csv.d.ts +0 -32
- package/src/lib/model/deals-csv.js +0 -36
- package/src/lib/model/deals-csv.js.map +0 -1
- package/src/lib/model/import-column-shapes.d.ts +0 -36
- package/src/lib/model/import-column-shapes.js +0 -76
- package/src/lib/model/import-column-shapes.js.map +0 -1
- package/src/lib/model/lead-source-values.d.ts +0 -82
- package/src/lib/model/lead-source-values.js +0 -149
- package/src/lib/model/lead-source-values.js.map +0 -1
- package/src/lib/model/leads-csv.d.ts +0 -40
- package/src/lib/model/leads-csv.js +0 -40
- package/src/lib/model/leads-csv.js.map +0 -1
- package/src/lib/model/tasks-csv.d.ts +0 -28
- package/src/lib/model/tasks-csv.js +0 -28
- package/src/lib/model/tasks-csv.js.map +0 -1
- package/src/lib/server/companies-import.d.ts +0 -57
- package/src/lib/server/companies-import.js +0 -242
- package/src/lib/server/companies-import.js.map +0 -1
- package/src/lib/server/contacts-import.d.ts +0 -109
- package/src/lib/server/contacts-import.js +0 -393
- package/src/lib/server/contacts-import.js.map +0 -1
- package/src/lib/server/deals-import.d.ts +0 -76
- package/src/lib/server/deals-import.js +0 -248
- package/src/lib/server/deals-import.js.map +0 -1
- package/src/lib/server/export-route.d.ts +0 -60
- package/src/lib/server/export-route.js +0 -447
- package/src/lib/server/export-route.js.map +0 -1
- package/src/lib/server/import-context.d.ts +0 -87
- package/src/lib/server/import-context.js +0 -182
- package/src/lib/server/import-context.js.map +0 -1
- package/src/lib/server/lead-source-values.d.ts +0 -50
- package/src/lib/server/lead-source-values.js +0 -191
- package/src/lib/server/lead-source-values.js.map +0 -1
- package/src/lib/server/leads-import.d.ts +0 -84
- package/src/lib/server/leads-import.js +0 -367
- package/src/lib/server/leads-import.js.map +0 -1
- package/src/lib/server/tasks-import.d.ts +0 -54
- package/src/lib/server/tasks-import.js +0 -160
- package/src/lib/server/tasks-import.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/transfer/deals.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 * DEALS ON THE TRANSFER FRAMEWORK (AGL-3528) — the server half of\n * `crm.deals`.\n *\n * Every field a deal holds, its custom fields and its contact roles, read\n * for an export and written by an import the way the deals import route\n * wrote them — the pipeline and the stage by name, the scope stamp of the\n * importing site, the records band, the org's lists judging each label, the\n * list's search and filter keys — and now FOUND again: a row matches its\n * deal by Aglyn ID or by the external id another CRM gave it, so a file\n * imported twice updates rather than duplicating every deal.\n *\n * The contact, the company and every contact role name records, resolved\n * as lookups (a contact by email, a company by domain or name).\n *\n * A matched deal's pipeline and stage are locked: a stage moves on the\n * board, where the move tells automations and makes a won deal's contact a\n * customer, never as a side effect of a file.\n *=========================================*/\n\nimport {\n checkCrmRecordsQuota,\n CRM_COLLECTIONS,\n CRM_FORECAST_CATEGORIES,\n CRM_FORECAST_CATEGORY_LABELS,\n type ContactFieldDefinition,\n type CrmDealContactRole,\n type CrmDealStage,\n type CrmPipeline,\n crmListFields,\n crmPicklistDefaultLabel,\n crmNewRecordListFields,\n dealContactRoleFields,\n dealContactRolesOf,\n dealContactRolesWithPrimary,\n dealStageForecastCategory,\n isCrmForecastCategory,\n isPipelineArchived,\n judgeDealContactRoles,\n nameSearchKey,\n} from '@aglyn/aglyn/server'\nimport { createResourceUid } from '@aglyn/aglyn/app-utils/create-resource-uid'\nimport {\n buildTransferPlan,\n planTransferUndo,\n rankTransferLookupSuggestions,\n TRANSFER_ID_FIELD,\n transferLookupNewName,\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 { crmRecordsQuotaForOrg, restampCrmListFieldsOf } from '@aglyn/tenant-data-admin'\nimport { FieldValue } from 'firebase-admin/firestore'\nimport { DEAL_ALIASES } from './aliases'\nimport {\n addCrmPicklistValues,\n campaignDirectory,\n countCrmExport,\n creationScope,\n crmCustomDefinitions,\n crmMemberEmails,\n crmMembersTarget,\n crmPicklistLists,\n crmRecordsRoom,\n crmTransferEnv,\n type CrmTransferEnv,\n customTransferValues,\n customWriteValues,\n eachWithinBudget,\n failureMessage,\n IN_LIMIT,\n isoOf,\n lookupByField,\n lookupById,\n lookupResult,\n pickValues,\n plannedValues,\n readCrmExportPage,\n requireCrmRecords,\n requireCrmSuite,\n requireSite,\n storedMs,\n textOf,\n TransferEngineError,\n visibleIn,\n} from './common'\nimport { companyForName } from './companies'\nimport {\n CRM_MEMBERS_TARGET,\n CRM_TIMESTAMP_FIELDS,\n crmCustomTransferFields,\n DEAL_TRANSFER_DERIVED,\n DEAL_TRANSFER_FIELDS,\n DEAL_TRANSFER_GROUPS,\n} from './fields'\n\nconst SUITE_ACT = 'Importing deals'\n\n/** The currency a deal carries when the file names none — the deal form's own. */\nconst DEFAULT_CURRENCY = 'usd'\n\n/** How a deal's status reads in a file. */\nconst STATUS_LABELS: Readonly<Record<string, string>> = { open: 'Open', won: 'Won', lost: 'Lost' }\n\nconst dealsOf = (env: CrmTransferEnv) => env.orgRef.collection(CRM_COLLECTIONS.deals)\nconst contactsOf = (env: CrmTransferEnv) => env.orgRef.collection('contacts')\n\n/** A pipeline the site may file into, with its stages in order. */\ninterface PipelineChoice {\n id: string\n pipeline: CrmPipeline\n stages: CrmDealStage[]\n}\n\n/** Every pipeline the site sees, archived ones included (an export names them), in read order. */\nasync function readPipelines(env: CrmTransferEnv): Promise<PipelineChoice[]> {\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))\n .map((entry) => ({ ...entry, stages: [...(entry.pipeline.stages ?? [])].sort((a, b) => a.order - b.order) }))\n}\n\n/**\n * The pipeline and stage a new deal is filed in: by name (case and spacing\n * aside) among the active pipelines, or the default pipeline and its first\n * open stage when the row names none. `null` names what could not be found.\n */\nexport function placeDeal(\n choices: readonly PipelineChoice[],\n pipelineName: string,\n stageName: string,\n): { pipeline: PipelineChoice; stage: CrmDealStage } | { error: string } {\n const active = choices.filter((choice) => !isPipelineArchived(choice.pipeline))\n const pipeline = pipelineName\n ? active.find((choice) => nameSearchKey(choice.pipeline.name ?? '') === nameSearchKey(pipelineName))\n : (active.find((choice) => choice.pipeline.isDefault) ?? (active.length === 1 ? active[0] : undefined))\n if (!pipeline) {\n return { error: pipelineName ? `No pipeline is called “${pipelineName}”.` : 'Name the pipeline: this workspace has several.' }\n }\n const stage = stageName\n ? pipeline.stages.find((candidate) => nameSearchKey(candidate.name ?? '') === nameSearchKey(stageName))\n : (pipeline.stages.find((candidate) => candidate.kind === 'open') ?? pipeline.stages[0])\n if (!stage) return { error: `“${pipeline.pipeline.name}” has no stage called “${stageName}”.` }\n return { pipeline, stage }\n}\n\n/** A stored day (epoch ms at local noon) as the file reads it, `YYYY-MM-DD`. */\nfunction dayOf(ms: unknown): string | null {\n const value = storedMs(ms)\n return value === null ? null : new Date(value).toISOString().slice(0, 10)\n}\n\n/** A day the file names as the stored epoch: noon UTC, so the calendar day survives every zone. */\nfunction storedDay(value: unknown): number | null {\n const text = textOf(value)\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(text)) return null\n return Date.parse(`${text}T12:00:00.000Z`)\n}\n\n/**\n * The words written in place of stored ids. An export names every link; a\n * lookup names only what a file can only name in words — the pipeline, the\n * stage, the people in the contact roles — and keeps the links a lookup\n * column resolves to ids as ids, so the plan compares like with like.\n */\ninterface DealNames {\n /** Amounts as `1250.00 USD` rather than an amount and a currency. */\n display?: boolean\n owner?: (uid: string) => string | undefined\n contact?: (id: string) => string | undefined\n company?: (id: string) => string | undefined\n campaign?: (id: string) => string | undefined\n pipeline?: (id: string) => string | undefined\n stage?: (pipelineId: string, stageId: string) => string | undefined\n /** Who a contact role names: an email. */\n roleContact?: (id: string) => string | undefined\n}\n\n/** A deal's contact roles as one cell: `email (Role)`, the Primary first, `; ` between. */\nfunction rolesCell(roles: readonly CrmDealContactRole[], contact: (id: string) => string | undefined): string | null {\n const ordered = [...roles].sort((a, b) => Number(b.primary) - Number(a.primary))\n const cell = ordered\n .map((row) => {\n const who = contact(row.contactId) ?? row.contactId\n return row.role ? `${who} (${row.role})` : who\n })\n .join('; ')\n return cell || null\n}\n\n/** A contact roles cell read back: each person and the role in parentheses after them. */\nexport function parseRolesCell(value: unknown): Array<{ who: string; role: string }> {\n return textOf(value)\n .split(/[;\\n]+/)\n .map((part) => part.trim())\n .filter(Boolean)\n .map((part) => {\n const match = /^(.*?)\\s*\\(([^)]*)\\)\\s*$/.exec(part)\n return match ? { who: (match[1] as string).trim(), role: (match[2] as string).trim() } : { who: part, role: '' }\n })\n}\n\n/**\n * One deal as values by field id. A lookup and an undo read links by id\n * so the plan compares what is stored; an export writes names.\n */\nexport function dealTransferValues(\n id: string,\n deal: Record<string, unknown>,\n definitions: readonly ContactFieldDefinition[],\n names?: DealNames,\n): Record<string, unknown> {\n const text = (value: unknown) => textOf(value) || null\n const pipelineId = textOf(deal['pipelineId'])\n const stageId = textOf(deal['stageId'])\n const amount = typeof deal['amountCents'] === 'number' ? (deal['amountCents'] as number) : null\n const currency = String(deal['currency'] || DEFAULT_CURRENCY).toUpperCase()\n const ownerUid = text(deal['ownerUid'])\n const contactId = text(deal['contactId'])\n const companyId = text(deal['companyId'])\n const campaignId = text(deal['campaignId'])\n const roles = dealContactRolesOf(deal)\n const forecast = isCrmForecastCategory(deal['forecastCategory'])\n ? CRM_FORECAST_CATEGORY_LABELS[deal['forecastCategory']]\n : null\n const named = <T extends unknown[]>(resolve: ((...args: T) => string | undefined) | undefined, fallback: string, ...args: T) =>\n resolve?.(...args) || fallback\n return {\n title: text(deal['title']),\n externalId: text(deal['externalId']),\n pipeline: pipelineId ? named(names?.pipeline, pipelineId, pipelineId) : null,\n stage: stageId ? named(names?.stage, stageId, pipelineId, stageId) : null,\n status: STATUS_LABELS[textOf(deal['status'])] ?? null,\n amount: amount === null ? null : names?.display ? `${(amount / 100).toFixed(2)} ${currency}` : { amountMinor: amount, currency },\n expectedClose: dayOf(deal['expectedCloseAtMs']),\n closedAt: isoOf(deal['closedAtMs']),\n owner: ownerUid ? named(names?.owner, ownerUid, ownerUid) : null,\n contact: contactId ? named(names?.contact, names?.contact ? (text(deal['contactName']) ?? contactId) : contactId, contactId) : null,\n company: companyId ? named(names?.company, names?.company ? (text(deal['companyName']) ?? companyId) : companyId, companyId) : null,\n contactRoles: rolesCell(roles, (contact) => names?.roleContact?.(contact)),\n type: text(deal['type']),\n leadSource: text(deal['leadSource']),\n nextStep: text(deal['nextStep']),\n probability: typeof deal['probability'] === 'number' ? deal['probability'] : null,\n forecastCategory: forecast,\n lostReason: text(deal['lostReason']),\n campaign: campaignId ? named(names?.campaign, campaignId, campaignId) : null,\n notes: text(deal['notes']),\n createdAt: isoOf(deal['createdAt']),\n updatedAt: isoOf(deal['updatedAt']),\n ...customTransferValues(definitions, deal['custom']),\n [TRANSFER_ID_FIELD]: id,\n }\n}\n\n/** What a lookup and an undo name in words: the pipeline, the stage and the role contacts. */\nasync function wordNames(env: CrmTransferEnv, deals: ReadonlyArray<Record<string, unknown>>): Promise<DealNames> {\n const pipelines = deals.length ? await readPipelines(env) : []\n const ids = [...new Set(deals.flatMap((deal) => dealContactRolesOf(deal).map((row) => row.contactId)))].filter(\n (id) => !id.includes('/'),\n )\n const emails = new Map<string, string>()\n for (let at = 0; at < ids.length; at += 500) {\n for (const snapshot of await env.firestore.getAll(...ids.slice(at, at + 500).map((id) => contactsOf(env).doc(id)))) {\n if (snapshot.exists) emails.set(snapshot.id, textOf(snapshot.get('email')))\n }\n }\n const campaigns = deals.some((deal) => textOf(deal['campaignId'])) ? await campaignDirectory(env) : null\n return {\n pipeline: (id) => pipelines.find((choice) => choice.id === id)?.pipeline.name,\n stage: (pipelineId, stageId) =>\n pipelines.find((choice) => choice.id === pipelineId)?.stages.find((stage) => stage.id === stageId)?.name,\n roleContact: (id) => emails.get(id) || undefined,\n campaign: (id) => campaigns?.names.get(id),\n }\n}\n\n/** The deals these ids name, as values. */\nasync function readDeals(\n env: CrmTransferEnv,\n ids: readonly string[],\n definitions: readonly ContactFieldDefinition[],\n): Promise<Map<string, Record<string, unknown>>> {\n const docs = 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 env.firestore.getAll(...wanted.slice(at, at + 500).map((id) => dealsOf(env).doc(id)))) {\n const data = snapshot.data()\n if (snapshot.exists && data && visibleIn(env, data['visibleTo'])) docs.set(snapshot.id, data)\n }\n }\n const names = await wordNames(env, [...docs.values()])\n return new Map([...docs].map(([id, data]) => [id, dealTransferValues(id, data, definitions, names)]))\n}\n\n/** Everything one apply call shares across its rows. */\ninterface ApplyRun {\n env: CrmTransferEnv\n actorUid: string | null\n definitions: ContactFieldDefinition[]\n pipelines: PipelineChoice[]\n lists: Awaited<ReturnType<typeof crmPicklistLists>>\n campaigns: Awaited<ReturnType<typeof campaignDirectory>>\n companies: Map<string, Promise<{ id: string; name: string } | null>>\n admit: () => Promise<boolean>\n}\n\n/** A contact the import may link: one the site sees, by id or by email. */\nasync function contactFor(run: ApplyRun, value: string): Promise<{ id: string; name: string } | null> {\n const byId = !value.includes('@') && !value.includes('/') ? await contactsOf(run.env).doc(value).get() : null\n const snapshot = byId?.exists\n ? byId\n : (await contactsOf(run.env).where('email', '==', value.trim().toLowerCase()).limit(IN_LIMIT).get()).docs.find((doc) =>\n visibleIn(run.env, doc.get('visibleTo')),\n )\n if (!snapshot || !snapshot.exists || !visibleIn(run.env, snapshot.get('visibleTo'))) return null\n return { id: snapshot.id, name: textOf(snapshot.get('name')) || textOf(snapshot.get('email')) }\n}\n\n/**\n * The fields a row's values write to a deal, over the deal as it stands\n * (`current`, empty for a new one): each label judged against the org's\n * lists, a link resolved, a blank clearing (`null`).\n */\nasync function dealFields(\n run: ApplyRun,\n values: Readonly<Record<string, unknown>>,\n current: Record<string, unknown>,\n): Promise<Record<string, unknown>> {\n const fields: Record<string, unknown> = {}\n const set = (field: string, value: unknown) => {\n fields[field] = value === undefined || value === '' ? null : value\n }\n if ('title' in values) {\n const title = textOf(values['title']).slice(0, 200)\n if (!title) throw new TransferEngineError('invalid', 422, 'A deal needs a title.')\n fields['title'] = title\n fields['titleLower'] = nameSearchKey(title)\n }\n if ('externalId' in values) set('externalId', textOf(values['externalId']).slice(0, 200) || null)\n if ('amount' in values) {\n const amount = values['amount'] as CurrencyAmount | null\n if (amount && typeof amount === 'object') {\n fields['amountCents'] = amount.amountMinor\n fields['currency'] = String(amount.currency || DEFAULT_CURRENCY).toLowerCase()\n } else fields['amountCents'] = null\n }\n if ('expectedClose' in values) set('expectedCloseAtMs', storedDay(values['expectedClose']))\n if ('owner' in values) set('ownerUid', textOf(values['owner']) || null)\n if ('nextStep' in values) set('nextStep', textOf(values['nextStep']).slice(0, 255) || null)\n if ('probability' in values) {\n const probability = values['probability']\n if (probability !== null && (typeof probability !== 'number' || probability < 0 || probability > 100)) {\n throw new TransferEngineError('invalid', 422, 'A probability is a percent from 0 to 100.')\n }\n set('probability', probability === null ? null : Math.round(probability as number))\n }\n if ('forecastCategory' in values) {\n const label = textOf(values['forecastCategory']).toLowerCase()\n const category = CRM_FORECAST_CATEGORIES.find((entry) => CRM_FORECAST_CATEGORY_LABELS[entry].toLowerCase() === label)\n set('forecastCategory', category ?? null)\n }\n if ('lostReason' in values) set('lostReason', textOf(values['lostReason']).slice(0, 500) || null)\n if ('notes' in values) set('notes', textOf(values['notes']).slice(0, 4000) || null)\n for (const field of ['type', 'leadSource'] as const) {\n if (field in values) set(field, textOf(values[field]) || null)\n }\n if ('campaign' in values) {\n const name = textOf(values['campaign'])\n const id = name ? (run.campaigns.byName.get(name.toLowerCase()) ?? null) : null\n if (name && !id) throw new TransferEngineError('invalid', 422, `No campaign is called “${name}”.`)\n set('campaignId', id)\n }\n if ('company' in values) {\n const value = values['company']\n if (value === null || value === undefined || value === '') {\n fields['companyId'] = null\n fields['companyName'] = null\n } else {\n const create = transferLookupNewName(value)\n const company = create\n ? await companyForName(run.env, create, run.actorUid, run.companies, run.admit)\n : await (async () => {\n const snapshot = await run.env.orgRef.collection(CRM_COLLECTIONS.companies).doc(String(value)).get()\n return snapshot.exists && visibleIn(run.env, snapshot.get('visibleTo'))\n ? { id: snapshot.id, name: textOf(snapshot.get('name')) }\n : null\n })()\n if (!company) throw new TransferEngineError('invalid', 422, 'The company this row names could not be found or created.')\n fields['companyId'] = company.id\n fields['companyName'] = company.name\n }\n }\n\n // The contact and the roles: the Primary is `contactId`, written together.\n let roles = dealContactRolesOf(current)\n const rolesNamed = 'contactRoles' in values\n if (rolesNamed) {\n const next: CrmDealContactRole[] = []\n for (const { who, role } of parseRolesCell(values['contactRoles'])) {\n const contact = await contactFor(run, who)\n if (!contact) throw new TransferEngineError('invalid', 422, `No contact this site sees is “${who}”.`)\n if (!next.some((row) => row.contactId === contact.id)) {\n next.push({ contactId: contact.id, ...(role ? { role } : {}), primary: next.length === 0 })\n }\n }\n const list = run.lists['opportunityContactRole']?.set\n const judged = list ? judgeDealContactRoles(list, next, roles) : { ok: true as const, roles: next }\n if (judged.ok === false) throw new TransferEngineError('invalid', 422, judged.error)\n roles = judged.roles\n }\n if ('contact' in values) {\n const contactId = textOf(values['contact']) || null\n roles = dealContactRolesWithPrimary(roles, contactId)\n if (!contactId) roles = roles.map((row) => ({ ...row, primary: false }))\n }\n if (rolesNamed || 'contact' in values) {\n const { contactRoles, contactId } = dealContactRoleFields(roles)\n fields['contactRoles'] = contactRoles\n fields['contactId'] = contactId\n fields['contactName'] = contactId ? ((await contactFor(run, contactId))?.name ?? null) : null\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/** Fields as a create writes them: a cleared field is simply absent. */\nconst asCreate = (fields: Record<string, unknown>) =>\n Object.fromEntries(Object.entries(fields).filter(([, value]) => value !== null && value !== undefined))\n\n/** The `crm.deals` hooks. */\nexport function dealsTransferResource(): TransferRecordsHooks {\n return {\n async fields(ctx) {\n const env = await crmTransferEnv(ctx)\n return {\n standard: DEAL_TRANSFER_FIELDS,\n derived: DEAL_TRANSFER_DERIVED,\n system: CRM_TIMESTAMP_FIELDS,\n custom: crmCustomTransferFields(await crmCustomDefinitions(env, 'deal'), 'deal'),\n groups: DEAL_TRANSFER_GROUPS,\n }\n },\n matchKeys: [\n { fieldId: TRANSFER_ID_FIELD, normalizer: 'aglynId' },\n { fieldId: 'externalId', normalizer: 'externalId' },\n ],\n aliases: DEAL_ALIASES,\n lookupTargets: { [CRM_MEMBERS_TARGET]: crmMembersTarget() },\n\n async count(ctx, options) {\n const env = await crmTransferEnv(ctx)\n requireCrmRecords(env, 'deals')\n return countCrmExport(env, dealsOf(env), options, (data) => visibleIn(env, data['visibleTo'], options.scopeTokens))\n },\n\n async readPage(ctx, cursor, fieldIds, options) {\n const env = await crmTransferEnv(ctx)\n requireCrmRecords(env, 'deals')\n const definitions = await crmCustomDefinitions(env, 'deal')\n const emails = fieldIds.includes('owner') ? await crmMemberEmails(env.orgId) : new Map<string, string>()\n const pipelines = fieldIds.some((id) => id === 'pipeline' || id === 'stage') ? await readPipelines(env) : []\n const campaigns = fieldIds.includes('campaign') ? await campaignDirectory(env) : null\n return readCrmExportPage(\n env,\n dealsOf(env),\n cursor,\n options,\n (data) => visibleIn(env, data['visibleTo'], options?.scopeTokens),\n async (docs) => {\n // People and companies by the words a file carries: a contact's email, a company's name.\n const contactIds = new Set<string>()\n const companyIds = new Set<string>()\n for (const doc of docs) {\n for (const row of dealContactRolesOf(doc.data)) contactIds.add(row.contactId)\n const companyId = textOf(doc.data['companyId'])\n if (companyId) companyIds.add(companyId)\n }\n const emailsOf = new Map<string, string>()\n const companyNames = new Map<string, string>()\n if (fieldIds.includes('contact') || fieldIds.includes('contactRoles')) {\n const ids = [...contactIds].filter((id) => !id.includes('/'))\n for (let at = 0; at < ids.length; at += 500) {\n for (const snapshot of await env.firestore.getAll(...ids.slice(at, at + 500).map((id) => contactsOf(env).doc(id)))) {\n if (snapshot.exists) emailsOf.set(snapshot.id, textOf(snapshot.get('email')))\n }\n }\n }\n if (fieldIds.includes('company')) {\n const ids = [...companyIds].filter((id) => !id.includes('/'))\n for (let at = 0; at < ids.length; at += 500) {\n const refs = ids.slice(at, at + 500).map((id) => env.orgRef.collection(CRM_COLLECTIONS.companies).doc(id))\n for (const snapshot of await env.firestore.getAll(...refs)) {\n if (snapshot.exists) companyNames.set(snapshot.id, textOf(snapshot.get('name')))\n }\n }\n }\n const names: DealNames = {\n display: true,\n owner: (uid) => emails.get(uid),\n contact: (id) => emailsOf.get(id) || undefined,\n roleContact: (id) => emailsOf.get(id) || undefined,\n company: (id) => companyNames.get(id) || undefined,\n campaign: (id) => campaigns?.names.get(id),\n pipeline: (id) => pipelines.find((choice) => choice.id === id)?.pipeline.name,\n stage: (pipelineId, stageId) =>\n pipelines.find((choice) => choice.id === pipelineId)?.stages.find((stage) => stage.id === stageId)?.name,\n }\n return docs.map((doc) => pickValues(dealTransferValues(doc.id, doc.data, definitions, names), fieldIds))\n },\n )\n },\n\n async lookup(ctx, requests) {\n const env = await crmTransferEnv(ctx)\n const definitions = await crmCustomDefinitions(env, 'deal')\n const visible = (data: Record<string, unknown>) => visibleIn(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(env, dealsOf(env), request, visible, found)\n else if (request.fieldId === 'externalId') {\n await lookupByField(dealsOf(env), request, 'externalId', (value) => value.trim(), visible, found)\n } else if (request.fieldId === 'title') {\n await lookupByField(dealsOf(env), request, 'titleLower', (value) => nameSearchKey(value), visible, found)\n }\n }\n const names = await wordNames(env, [...found.docs.values()])\n return lookupResult(found, (id, data) => dealTransferValues(id, data, definitions, names))\n },\n\n async suggest(ctx, request) {\n const env = await crmTransferEnv(ctx)\n const answer: Record<string, ReturnType<typeof rankTransferLookupSuggestions>> = {}\n for (const value of request.values) {\n const first = nameSearchKey(value).split(' ')[0] ?? ''\n if (first.length < 2) {\n answer[value] = []\n continue\n }\n const snapshot = await dealsOf(env).where('titleLower', '>=', first).where('titleLower', '<', `${first}`).limit(IN_LIMIT).get()\n answer[value] = rankTransferLookupSuggestions(\n value,\n snapshot.docs\n .filter((doc) => visibleIn(env, doc.get('visibleTo')))\n .map((doc) => ({ recordId: doc.id, label: textOf(doc.get('title')) || doc.id })),\n )\n }\n return answer\n },\n\n async picklists(ctx, ids) {\n const env = await crmTransferEnv(ctx)\n return crmPicklistLists(env, ids, await crmCustomDefinitions(env, 'deal'))\n },\n\n async addPicklistValues(ctx, picklistId, values) {\n await addCrmPicklistValues(await crmTransferEnv(ctx), picklistId, values)\n },\n\n lockedRules: () => [\n {\n fieldId: 'pipeline',\n reason: 'A deal moves between pipelines and stages on the board, where the move tells your automations; an import sets them only on a new deal.',\n forced: { mode: 'keepExisting' },\n },\n {\n fieldId: 'stage',\n reason: 'A deal moves between stages on the board, where the move tells your automations; an import sets the stage only on a new deal.',\n forced: { mode: 'keepExisting' },\n },\n ],\n\n async plan(ctx, input) {\n const env = await crmTransferEnv(ctx)\n requireCrmSuite(env, SUITE_ACT)\n requireSite(env, 'deals')\n return buildTransferPlan(input)\n },\n\n async apply(ctx, chunk, writer) {\n const env = await crmTransferEnv(ctx)\n requireCrmSuite(env, SUITE_ACT)\n requireSite(env, 'deals')\n const run: ApplyRun = {\n env,\n actorUid: ctx.actorUid,\n definitions: await crmCustomDefinitions(env, 'deal'),\n pipelines: await readPipelines(env),\n lists: await crmPicklistLists(env, ['opportunityContactRole', 'opportunityType'], []),\n campaigns: await campaignDirectory(env),\n companies: new Map(),\n admit: crmRecordsRoom(env),\n }\n let counted: { crmRecordsCount: number } | null = null\n let createdHere = 0\n const results: TransferRowResult[] = []\n const undo: TransferUndoEntry[] = []\n\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 ref = dealsOf(env).doc(row.recordId)\n const current = (await ref.get()).data()\n if (!current || !visibleIn(env, current['visibleTo'])) throw new TransferEngineError('notFound', 404, 'That deal no longer exists.')\n const before = dealTransferValues(ref.id, current, run.definitions)\n const fields = await dealFields(run, values, current)\n const custom = customWriteValues(values, run.definitions, 'deal')\n if ('error' in custom) throw new TransferEngineError('invalid', 422, custom.error)\n await ref.update({\n ...asUpdate(fields),\n ...Object.fromEntries(Object.entries(custom.values).map(([key, value]) => [`custom.${key}`, value])),\n ...crmListFields('deals', { ...current, ...fields }),\n updatedAt: FieldValue.serverTimestamp(),\n })\n const after = (await readDeals(env, [ref.id], run.definitions)).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 placed = placeDeal(run.pipelines, textOf(values['pipeline']), textOf(values['stage']))\n if ('error' in placed) throw new TransferEngineError('invalid', 422, placed.error)\n counted ??= await crmRecordsQuotaForOrg(env.org as never, env.orgRef)\n if (!checkCrmRecordsQuota(env.org as never, counted.crmRecordsCount + createdHere).allowed) {\n throw new TransferEngineError('invalid', 422, 'The CRM records limit is reached.')\n }\n const fields = asCreate(await dealFields(run, values, {}))\n // A new deal with no Type starts on the list's default, as the deal form does.\n const typeDefault = run.lists['opportunityType'] ? crmPicklistDefaultLabel(run.lists['opportunityType'].set) : null\n if (!fields['type'] && typeDefault) fields['type'] = typeDefault\n const custom = customWriteValues(values, run.definitions, 'deal')\n if ('error' in custom) throw new TransferEngineError('invalid', 422, custom.error)\n const { stage } = placed\n const status = stage.kind === 'won' ? 'won' : stage.kind === 'lost' ? 'lost' : 'open'\n const nowMs = Date.now()\n const scope = creationScope(env, ctx.actorUid)\n const ref = dealsOf(env).doc(createResourceUid())\n const opportunity = {\n forecastCategory: (fields['forecastCategory'] as string | undefined) ?? dealStageForecastCategory(stage),\n }\n await ref.set({\n currency: DEFAULT_CURRENCY,\n ...fields,\n ...opportunity,\n pipelineId: placed.pipeline.id,\n stageId: stage.id,\n status,\n stageChangedAtMs: nowMs,\n closedAtMs: status === 'open' ? null : nowMs,\n ...(Object.keys(custom.values).length ? { custom: custom.values } : {}),\n ...scope,\n // What the Deals list searches and filters by (AGL-3321, AGL-3516).\n ...crmNewRecordListFields('deals', { ...fields, ...opportunity, ...scope }),\n })\n createdHere += 1\n const after = (await readDeals(env, [ref.id], run.definitions)).get(ref.id) ?? {}\n result = { row: row.index, outcome: 'created', recordId: ref.id }\n entry = { row: row.index, recordId: ref.id, action: 'created', written: pickValues(after, changed) }\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 env = await crmTransferEnv(ctx)\n const run: ApplyRun = {\n env,\n actorUid: ctx.actorUid,\n definitions: await crmCustomDefinitions(env, 'deal'),\n pipelines: [],\n lists: {},\n campaigns: await campaignDirectory(env),\n companies: new Map(),\n admit: crmRecordsRoom(env),\n }\n const current = await readDeals(env, snapshot.entries.map((entry) => entry.recordId), run.definitions)\n const done: TransferUndoStep[] = []\n const conflicts: TransferUndoStep[] = []\n const touched: FirebaseFirestore.DocumentReference[] = []\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 = dealsOf(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 const values = step.action === 'restore' || step.action === 'conflict' ? step.values : {}\n const stored = (await ref.get()).data() ?? {}\n const fields = await dealFields(run, values, stored)\n await ref.update({ ...asUpdate(fields), ...crmListFields('deals', { ...stored, ...fields }), updatedAt: FieldValue.serverTimestamp() })\n touched.push(ref)\n done.push(step)\n }\n if (touched.length) await restampCrmListFieldsOf(touched, 'deals').catch(() => undefined)\n return { done, conflicts }\n },\n }\n}\n\n"],"names":["checkCrmRecordsQuota","CRM_COLLECTIONS","CRM_FORECAST_CATEGORIES","CRM_FORECAST_CATEGORY_LABELS","crmListFields","crmPicklistDefaultLabel","crmNewRecordListFields","dealContactRoleFields","dealContactRolesOf","dealContactRolesWithPrimary","dealStageForecastCategory","isCrmForecastCategory","isPipelineArchived","judgeDealContactRoles","nameSearchKey","createResourceUid","buildTransferPlan","planTransferUndo","rankTransferLookupSuggestions","TRANSFER_ID_FIELD","transferLookupNewName","crmRecordsQuotaForOrg","restampCrmListFieldsOf","FieldValue","DEAL_ALIASES","addCrmPicklistValues","campaignDirectory","countCrmExport","creationScope","crmCustomDefinitions","crmMemberEmails","crmMembersTarget","crmPicklistLists","crmRecordsRoom","crmTransferEnv","customTransferValues","customWriteValues","eachWithinBudget","failureMessage","IN_LIMIT","isoOf","lookupByField","lookupById","lookupResult","pickValues","plannedValues","readCrmExportPage","requireCrmRecords","requireCrmSuite","requireSite","storedMs","textOf","TransferEngineError","visibleIn","companyForName","CRM_MEMBERS_TARGET","CRM_TIMESTAMP_FIELDS","crmCustomTransferFields","DEAL_TRANSFER_DERIVED","DEAL_TRANSFER_FIELDS","DEAL_TRANSFER_GROUPS","SUITE_ACT","DEFAULT_CURRENCY","STATUS_LABELS","open","won","lost","dealsOf","env","orgRef","collection","deals","contactsOf","readPipelines","snapshot","pipelines","get","docs","map","doc","id","pipeline","data","filter","entry","visibleTo","stages","sort","a","b","order","placeDeal","choices","pipelineName","stageName","active","choice","find","name","isDefault","length","undefined","error","stage","candidate","kind","dayOf","ms","value","Date","toISOString","slice","storedDay","text","test","parse","rolesCell","roles","contact","ordered","Number","primary","cell","row","who","contactId","role","join","parseRolesCell","split","part","trim","Boolean","match","exec","dealTransferValues","deal","definitions","names","pipelineId","stageId","amount","currency","String","toUpperCase","ownerUid","companyId","campaignId","forecast","named","resolve","fallback","args","title","externalId","status","display","toFixed","amountMinor","expectedClose","closedAt","owner","company","contactRoles","roleContact","type","leadSource","nextStep","probability","forecastCategory","lostReason","campaign","notes","createdAt","updatedAt","wordNames","ids","Set","flatMap","includes","emails","Map","at","firestore","getAll","exists","set","campaigns","some","readDeals","wanted","values","contactFor","run","byId","where","toLowerCase","limit","dealFields","current","fields","field","Math","round","label","category","byName","create","actorUid","companies","admit","rolesNamed","next","push","list","lists","judged","ok","asUpdate","Object","fromEntries","entries","key","delete","asCreate","dealsTransferResource","ctx","standard","derived","system","custom","groups","matchKeys","fieldId","normalizer","aliases","lookupTargets","count","options","scopeTokens","readPage","cursor","fieldIds","orgId","contactIds","companyIds","add","emailsOf","companyNames","refs","uid","lookup","requests","visible","found","request","suggest","answer","first","recordId","picklists","addPicklistValues","picklistId","lockedRules","reason","forced","mode","plan","input","apply","chunk","writer","counted","createdHere","results","undo","rows","timeLeftMs","earlier","alreadyApplied","index","changed","diff","change","result","verdict","ref","before","update","serverTimestamp","after","outcome","action","previous","written","placed","org","crmRecordsCount","allowed","typeDefault","nowMs","now","scope","opportunity","stageChangedAtMs","closedAtMs","keys","message","markApplied","revert","decisions","done","conflicts","touched","step","why","stored","catch"],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
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 CrmEmailTemplateKind, type CrmEmailTemplateVisibility } from '@aglyn/aglyn/app-utils/crm-email-templates';
|
|
18
|
+
import type { PackageDependency } from '@aglyn/aglyn/data-transfer/package';
|
|
19
|
+
/** The resource key, and so the kind every template item carries. */
|
|
20
|
+
export declare const CRM_EMAIL_TEMPLATES_TRANSFER_KEY = "crm.email-templates";
|
|
21
|
+
/** A template as a package carries it. */
|
|
22
|
+
export interface CrmEmailTemplatePackageContent {
|
|
23
|
+
name: string;
|
|
24
|
+
kind: CrmEmailTemplateKind;
|
|
25
|
+
visibility: CrmEmailTemplateVisibility;
|
|
26
|
+
subject: string;
|
|
27
|
+
body: string;
|
|
28
|
+
hostId: string | null;
|
|
29
|
+
}
|
|
30
|
+
/** The package content of a stored template, or of an incoming item, held to the template's own shape. */
|
|
31
|
+
export declare function crmEmailTemplatePackageContent(source: unknown): CrmEmailTemplatePackageContent;
|
|
32
|
+
export declare function crmEmailTemplateDependencies(content: CrmEmailTemplatePackageContent): PackageDependency[];
|
|
33
|
+
export declare function remapCrmEmailTemplateIds(content: CrmEmailTemplatePackageContent, idMap: ReadonlyMap<string, string>): CrmEmailTemplatePackageContent;
|
|
34
|
+
/** What a template must be before it is stored, each a sentence. */
|
|
35
|
+
export declare function crmEmailTemplatePackageProblems(content: CrmEmailTemplatePackageContent): string[];
|
|
36
|
+
export declare const CRM_EMAIL_TEMPLATE_PACKAGE_RULES: readonly [{
|
|
37
|
+
readonly id: "personal";
|
|
38
|
+
readonly label: "A personal template becomes yours";
|
|
39
|
+
readonly reason: "A personal template is listed for one person. One you import is filed as your own, and a colleague’s personal templates are never exported.";
|
|
40
|
+
}];
|
|
@@ -0,0 +1,76 @@
|
|
|
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
|
+
* EMAIL TEMPLATES AS PACKAGE ITEMS (AGL-3535).
|
|
19
|
+
*
|
|
20
|
+
* An item is a template as a person reads it: its name, kind, visibility,
|
|
21
|
+
* subject and body, and the site it was written under (`hostId`, `null`
|
|
22
|
+
* for the organization's own). Never who wrote it or when, so a template
|
|
23
|
+
* exported and imported back is `identical`. A personal template travels
|
|
24
|
+
* as personal and lands as the importer's own — a colleague's personal
|
|
25
|
+
* templates are theirs, and are neither exported nor matched.
|
|
26
|
+
*
|
|
27
|
+
* What it names: its site, if any. A dropped site makes it the
|
|
28
|
+
* organization's own.
|
|
29
|
+
*
|
|
30
|
+
* Pure: the server half (`email-templates-package.server.ts`) reads and
|
|
31
|
+
* writes.
|
|
32
|
+
*=========================================*/ import { CRM_EMAIL_TEMPLATE_NAME_MAX, normalizeCrmEmailTemplate } from "@aglyn/aglyn/app-utils/crm-email-templates";
|
|
33
|
+
import { remapPackageReference, TRANSFER_SITE_KIND } from "@aglyn/aglyn/data-transfer/package-plan";
|
|
34
|
+
/** The resource key, and so the kind every template item carries. */ export const CRM_EMAIL_TEMPLATES_TRANSFER_KEY = 'crm.email-templates';
|
|
35
|
+
/** The package content of a stored template, or of an incoming item, held to the template's own shape. */ export function crmEmailTemplatePackageContent(source) {
|
|
36
|
+
const template = normalizeCrmEmailTemplate(source && typeof source === 'object' ? source : {});
|
|
37
|
+
return {
|
|
38
|
+
name: template.name,
|
|
39
|
+
kind: template.kind,
|
|
40
|
+
visibility: template.visibility,
|
|
41
|
+
subject: template.kind === 'snippet' ? '' : template.subject,
|
|
42
|
+
body: template.body,
|
|
43
|
+
hostId: template.hostId
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export function crmEmailTemplateDependencies(content) {
|
|
47
|
+
return content.hostId ? [
|
|
48
|
+
{
|
|
49
|
+
kind: TRANSFER_SITE_KIND,
|
|
50
|
+
id: content.hostId
|
|
51
|
+
}
|
|
52
|
+
] : [];
|
|
53
|
+
}
|
|
54
|
+
export function remapCrmEmailTemplateIds(content, idMap) {
|
|
55
|
+
return _extends({}, content, {
|
|
56
|
+
hostId: remapPackageReference(idMap, TRANSFER_SITE_KIND, content.hostId)
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/** What a template must be before it is stored, each a sentence. */ export function crmEmailTemplatePackageProblems(content) {
|
|
60
|
+
const problems = [];
|
|
61
|
+
if (!content.name.trim()) problems.push('Name the template.');
|
|
62
|
+
if (content.name.length > CRM_EMAIL_TEMPLATE_NAME_MAX) {
|
|
63
|
+
problems.push(`Keep the name under ${CRM_EMAIL_TEMPLATE_NAME_MAX} characters.`);
|
|
64
|
+
}
|
|
65
|
+
if (!content.body.trim()) problems.push('A template needs its text.');
|
|
66
|
+
return problems;
|
|
67
|
+
}
|
|
68
|
+
export const CRM_EMAIL_TEMPLATE_PACKAGE_RULES = [
|
|
69
|
+
{
|
|
70
|
+
id: 'personal',
|
|
71
|
+
label: 'A personal template becomes yours',
|
|
72
|
+
reason: 'A personal template is listed for one person. One you import is filed as your own, and a colleague’s personal templates are never exported.'
|
|
73
|
+
}
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
//# sourceMappingURL=email-templates-package.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/transfer/email-templates-package.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 * EMAIL TEMPLATES AS PACKAGE ITEMS (AGL-3535).\n *\n * An item is a template as a person reads it: its name, kind, visibility,\n * subject and body, and the site it was written under (`hostId`, `null`\n * for the organization's own). Never who wrote it or when, so a template\n * exported and imported back is `identical`. A personal template travels\n * as personal and lands as the importer's own — a colleague's personal\n * templates are theirs, and are neither exported nor matched.\n *\n * What it names: its site, if any. A dropped site makes it the\n * organization's own.\n *\n * Pure: the server half (`email-templates-package.server.ts`) reads and\n * writes.\n *=========================================*/\n\nimport {\n CRM_EMAIL_TEMPLATE_NAME_MAX,\n normalizeCrmEmailTemplate,\n type CrmEmailTemplateKind,\n type CrmEmailTemplateVisibility,\n} from '@aglyn/aglyn/app-utils/crm-email-templates'\nimport type { PackageDependency } from '@aglyn/aglyn/data-transfer/package'\nimport { remapPackageReference, TRANSFER_SITE_KIND } from '@aglyn/aglyn/data-transfer/package-plan'\n\n/** The resource key, and so the kind every template item carries. */\nexport const CRM_EMAIL_TEMPLATES_TRANSFER_KEY = 'crm.email-templates'\n\n/** A template as a package carries it. */\nexport interface CrmEmailTemplatePackageContent {\n name: string\n kind: CrmEmailTemplateKind\n visibility: CrmEmailTemplateVisibility\n subject: string\n body: string\n hostId: string | null\n}\n\n/** The package content of a stored template, or of an incoming item, held to the template's own shape. */\nexport function crmEmailTemplatePackageContent(source: unknown): CrmEmailTemplatePackageContent {\n const template = normalizeCrmEmailTemplate((source && typeof source === 'object' ? source : {}) as Record<string, unknown>)\n return {\n name: template.name,\n kind: template.kind,\n visibility: template.visibility,\n subject: template.kind === 'snippet' ? '' : template.subject,\n body: template.body,\n hostId: template.hostId,\n }\n}\n\nexport function crmEmailTemplateDependencies(content: CrmEmailTemplatePackageContent): PackageDependency[] {\n return content.hostId ? [{ kind: TRANSFER_SITE_KIND, id: content.hostId }] : []\n}\n\nexport function remapCrmEmailTemplateIds(\n content: CrmEmailTemplatePackageContent,\n idMap: ReadonlyMap<string, string>,\n): CrmEmailTemplatePackageContent {\n return { ...content, hostId: remapPackageReference(idMap, TRANSFER_SITE_KIND, content.hostId) }\n}\n\n/** What a template must be before it is stored, each a sentence. */\nexport function crmEmailTemplatePackageProblems(content: CrmEmailTemplatePackageContent): string[] {\n const problems: string[] = []\n if (!content.name.trim()) problems.push('Name the template.')\n if (content.name.length > CRM_EMAIL_TEMPLATE_NAME_MAX) {\n problems.push(`Keep the name under ${CRM_EMAIL_TEMPLATE_NAME_MAX} characters.`)\n }\n if (!content.body.trim()) problems.push('A template needs its text.')\n return problems\n}\n\nexport const CRM_EMAIL_TEMPLATE_PACKAGE_RULES = [\n {\n id: 'personal',\n label: 'A personal template becomes yours',\n reason: 'A personal template is listed for one person. One you import is filed as your own, and a colleague’s personal templates are never exported.',\n },\n] as const\n"],"names":["CRM_EMAIL_TEMPLATE_NAME_MAX","normalizeCrmEmailTemplate","remapPackageReference","TRANSFER_SITE_KIND","CRM_EMAIL_TEMPLATES_TRANSFER_KEY","crmEmailTemplatePackageContent","source","template","name","kind","visibility","subject","body","hostId","crmEmailTemplateDependencies","content","id","remapCrmEmailTemplateIds","idMap","crmEmailTemplatePackageProblems","problems","trim","push","length","CRM_EMAIL_TEMPLATE_PACKAGE_RULES","label","reason"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;2CAe2C,GAE3C,SACEA,2BAA2B,EAC3BC,yBAAyB,QAGpB,6CAA4C;AAEnD,SAASC,qBAAqB,EAAEC,kBAAkB,QAAQ,0CAAyC;AAEnG,mEAAmE,GACnE,OAAO,MAAMC,mCAAmC,sBAAqB;AAYrE,wGAAwG,GACxG,OAAO,SAASC,+BAA+BC,MAAe;IAC5D,MAAMC,WAAWN,0BAA2BK,UAAU,OAAOA,WAAW,WAAWA,SAAS,CAAC;IAC7F,OAAO;QACLE,MAAMD,SAASC,IAAI;QACnBC,MAAMF,SAASE,IAAI;QACnBC,YAAYH,SAASG,UAAU;QAC/BC,SAASJ,SAASE,IAAI,KAAK,YAAY,KAAKF,SAASI,OAAO;QAC5DC,MAAML,SAASK,IAAI;QACnBC,QAAQN,SAASM,MAAM;IACzB;AACF;AAEA,OAAO,SAASC,6BAA6BC,OAAuC;IAClF,OAAOA,QAAQF,MAAM,GAAG;QAAC;YAAEJ,MAAMN;YAAoBa,IAAID,QAAQF,MAAM;QAAC;KAAE,GAAG,EAAE;AACjF;AAEA,OAAO,SAASI,yBACdF,OAAuC,EACvCG,KAAkC;IAElC,OAAO,aAAKH;QAASF,QAAQX,sBAAsBgB,OAAOf,oBAAoBY,QAAQF,MAAM;;AAC9F;AAEA,kEAAkE,GAClE,OAAO,SAASM,gCAAgCJ,OAAuC;IACrF,MAAMK,WAAqB,EAAE;IAC7B,IAAI,CAACL,QAAQP,IAAI,CAACa,IAAI,IAAID,SAASE,IAAI,CAAC;IACxC,IAAIP,QAAQP,IAAI,CAACe,MAAM,GAAGvB,6BAA6B;QACrDoB,SAASE,IAAI,CAAC,CAAC,oBAAoB,EAAEtB,4BAA4B,YAAY,CAAC;IAChF;IACA,IAAI,CAACe,QAAQH,IAAI,CAACS,IAAI,IAAID,SAASE,IAAI,CAAC;IACxC,OAAOF;AACT;AAEA,OAAO,MAAMI,mCAAmC;IAC9C;QACER,IAAI;QACJS,OAAO;QACPC,QAAQ;IACV;CACD,CAAS"}
|
|
@@ -0,0 +1,32 @@
|
|
|
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 ExistingPackageItem } from '@aglyn/aglyn/data-transfer';
|
|
18
|
+
import type { TransferApplyResult, TransferApplyWriter, TransferPackageItemContent, TransferPackageItemWrite, TransferPackageRevertResult, TransferPackageRevertStep, TransferResourceContext } from '@aglyn/aglyn/plugin-manager/plugin-transfer-resources';
|
|
19
|
+
import { type CrmEmailTemplatePackageContent } from './email-templates-package';
|
|
20
|
+
type Firestore = FirebaseFirestore.Firestore;
|
|
21
|
+
export interface CrmEmailTemplatesPackageDeps {
|
|
22
|
+
firestore(): Firestore;
|
|
23
|
+
now(): number;
|
|
24
|
+
}
|
|
25
|
+
export declare function createCrmEmailTemplatesPackage(deps?: CrmEmailTemplatesPackageDeps): {
|
|
26
|
+
items(ctx: TransferResourceContext): Promise<ExistingPackageItem[]>;
|
|
27
|
+
readItems(ctx: TransferResourceContext, ids: readonly string[]): Promise<TransferPackageItemContent<CrmEmailTemplatePackageContent>[]>;
|
|
28
|
+
problems(ctx: TransferResourceContext, write: TransferPackageItemWrite<CrmEmailTemplatePackageContent>): Promise<string[]>;
|
|
29
|
+
writeItems(ctx: TransferResourceContext, items: ReadonlyArray<TransferPackageItemWrite<CrmEmailTemplatePackageContent>>, writer: TransferApplyWriter): Promise<TransferApplyResult>;
|
|
30
|
+
revertItems(ctx: TransferResourceContext, steps: ReadonlyArray<TransferPackageRevertStep<CrmEmailTemplatePackageContent>>): Promise<TransferPackageRevertResult>;
|
|
31
|
+
};
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,176 @@
|
|
|
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
|
+
* EMAIL TEMPLATES IN A WORKSPACE PACKAGE — the server half (AGL-3535).
|
|
19
|
+
*
|
|
20
|
+
* Written the way the template's duplicate writes a copy
|
|
21
|
+
* (`email-template-duplicate.ts`): inside a transaction that holds the
|
|
22
|
+
* listing's ceiling (`CRM_EMAIL_TEMPLATES_LIMIT`), scoped to its site's
|
|
23
|
+
* token or the organization's, filed under the person importing — a
|
|
24
|
+
* personal template becomes theirs. A replace rewrites what a person reads
|
|
25
|
+
* (name, kind, visibility, subject, body, site) and keeps who wrote it.
|
|
26
|
+
*=========================================*/ import { CRM_COLLECTIONS } from "@aglyn/aglyn/app-utils/crm";
|
|
27
|
+
import { CRM_EMAIL_TEMPLATES_LIMIT, crmEmailTemplateIsListed, normalizeCrmEmailTemplate } from "@aglyn/aglyn/app-utils/crm-email-templates";
|
|
28
|
+
import { hostScopeToken, ORG_SCOPE_TOKEN } from "@aglyn/aglyn/app-utils/scope-tokens";
|
|
29
|
+
import { existingPackageItemsOf } from "@aglyn/aglyn/data-transfer";
|
|
30
|
+
import firebaseAdmin from "@aglyn/tenant-data-admin/server/firebase-admin";
|
|
31
|
+
import { CRM_EMAIL_TEMPLATES_TRANSFER_KEY, crmEmailTemplatePackageContent, crmEmailTemplatePackageProblems } from "./email-templates-package.js";
|
|
32
|
+
function defaultDeps() {
|
|
33
|
+
return {
|
|
34
|
+
firestore: ()=>firebaseAdmin.app().firestore(),
|
|
35
|
+
now: Date.now
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const templatesOf = (firestore, orgId)=>firestore.collection('orgs').doc(orgId).collection(CRM_COLLECTIONS.emailTemplates);
|
|
39
|
+
/** The fields a person reads, as stored: scoped to the site's token, or the organization's. */ function readableFields(content, actorUid, nowMs) {
|
|
40
|
+
return _extends({
|
|
41
|
+
name: content.name,
|
|
42
|
+
kind: content.kind,
|
|
43
|
+
visibility: content.visibility,
|
|
44
|
+
subject: content.kind === 'snippet' ? '' : content.subject,
|
|
45
|
+
body: content.body
|
|
46
|
+
}, content.visibility === 'personal' ? {
|
|
47
|
+
ownerUid: actorUid
|
|
48
|
+
} : {}, {
|
|
49
|
+
hostId: content.hostId,
|
|
50
|
+
visibleTo: [
|
|
51
|
+
content.hostId ? hostScopeToken(content.hostId) : ORG_SCOPE_TOKEN
|
|
52
|
+
],
|
|
53
|
+
updatedAtMs: nowMs,
|
|
54
|
+
updatedAt: new Date(nowMs)
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async function readAll(deps, ctx, ids) {
|
|
58
|
+
const collection = templatesOf(deps.firestore(), ctx.orgId);
|
|
59
|
+
const docs = ids ? (await Promise.all(ids.map((id)=>collection.doc(id).get()))).filter((doc)=>doc.exists) : (await collection.get()).docs;
|
|
60
|
+
return docs.flatMap((doc)=>{
|
|
61
|
+
const template = normalizeCrmEmailTemplate(doc.data());
|
|
62
|
+
// A colleague's personal template is theirs; only the importer's own and the shared ones move.
|
|
63
|
+
if (!crmEmailTemplateIsListed(template, ctx.actorUid)) return [];
|
|
64
|
+
const content = crmEmailTemplatePackageContent(template);
|
|
65
|
+
return [
|
|
66
|
+
{
|
|
67
|
+
kind: CRM_EMAIL_TEMPLATES_TRANSFER_KEY,
|
|
68
|
+
id: doc.id,
|
|
69
|
+
name: content.name,
|
|
70
|
+
content
|
|
71
|
+
}
|
|
72
|
+
];
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
export function createCrmEmailTemplatesPackage(deps = defaultDeps()) {
|
|
76
|
+
return {
|
|
77
|
+
async items (ctx) {
|
|
78
|
+
return existingPackageItemsOf(CRM_EMAIL_TEMPLATES_TRANSFER_KEY, await readAll(deps, ctx));
|
|
79
|
+
},
|
|
80
|
+
async readItems (ctx, ids) {
|
|
81
|
+
return readAll(deps, ctx, ids);
|
|
82
|
+
},
|
|
83
|
+
async problems (ctx, write) {
|
|
84
|
+
var _ref;
|
|
85
|
+
var _write_rename;
|
|
86
|
+
const problems = crmEmailTemplatePackageProblems(_extends({}, write.content, {
|
|
87
|
+
name: (_ref = (_write_rename = write.rename) == null ? void 0 : _write_rename.name) != null ? _ref : write.content.name
|
|
88
|
+
}));
|
|
89
|
+
if (write.decision !== 'replace') {
|
|
90
|
+
const held = (await templatesOf(deps.firestore(), ctx.orgId).count().get()).data().count;
|
|
91
|
+
if (held >= CRM_EMAIL_TEMPLATES_LIMIT) {
|
|
92
|
+
problems.push(`This workspace holds ${CRM_EMAIL_TEMPLATES_LIMIT} email templates — delete one to make room.`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return problems;
|
|
96
|
+
},
|
|
97
|
+
async writeItems (ctx, items, writer) {
|
|
98
|
+
var _ctx_actorUid;
|
|
99
|
+
const firestore = deps.firestore();
|
|
100
|
+
const templates = templatesOf(firestore, ctx.orgId);
|
|
101
|
+
const actor = (_ctx_actorUid = ctx.actorUid) != null ? _ctx_actorUid : '';
|
|
102
|
+
const results = [];
|
|
103
|
+
for (const write of items){
|
|
104
|
+
var _ref;
|
|
105
|
+
var _write_rename;
|
|
106
|
+
const before = await writer.alreadyApplied(write.row);
|
|
107
|
+
if (before) {
|
|
108
|
+
results.push(before);
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
const content = crmEmailTemplatePackageContent(_extends({}, write.content, {
|
|
112
|
+
name: (_ref = (_write_rename = write.rename) == null ? void 0 : _write_rename.name) != null ? _ref : write.content.name
|
|
113
|
+
}));
|
|
114
|
+
const nowMs = deps.now();
|
|
115
|
+
const result = await firestore.runTransaction(async (transaction)=>{
|
|
116
|
+
const ref = templates.doc(write.targetId);
|
|
117
|
+
const current = await transaction.get(ref);
|
|
118
|
+
if (write.decision === 'replace') {
|
|
119
|
+
if (!current.exists) return {
|
|
120
|
+
row: write.row,
|
|
121
|
+
outcome: 'failed',
|
|
122
|
+
recordId: write.targetId,
|
|
123
|
+
message: 'That template no longer exists.'
|
|
124
|
+
};
|
|
125
|
+
transaction.update(ref, readableFields(content, actor, nowMs));
|
|
126
|
+
return {
|
|
127
|
+
row: write.row,
|
|
128
|
+
outcome: 'updated',
|
|
129
|
+
recordId: write.targetId
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const siblings = await transaction.get(templates.select('name'));
|
|
133
|
+
if (siblings.size >= CRM_EMAIL_TEMPLATES_LIMIT) {
|
|
134
|
+
return {
|
|
135
|
+
row: write.row,
|
|
136
|
+
outcome: 'failed',
|
|
137
|
+
message: `This workspace holds ${CRM_EMAIL_TEMPLATES_LIMIT} email templates — delete one to make room.`
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
transaction.create(ref, _extends({}, readableFields(content, actor, nowMs), {
|
|
141
|
+
createdByUid: actor,
|
|
142
|
+
createdAtMs: nowMs,
|
|
143
|
+
createdAt: new Date(nowMs)
|
|
144
|
+
}));
|
|
145
|
+
return {
|
|
146
|
+
row: write.row,
|
|
147
|
+
outcome: 'created',
|
|
148
|
+
recordId: write.targetId
|
|
149
|
+
};
|
|
150
|
+
});
|
|
151
|
+
await writer.markApplied(result);
|
|
152
|
+
results.push(result);
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
results,
|
|
156
|
+
undo: []
|
|
157
|
+
};
|
|
158
|
+
},
|
|
159
|
+
async revertItems (ctx, steps) {
|
|
160
|
+
const templates = templatesOf(deps.firestore(), ctx.orgId);
|
|
161
|
+
const outcome = {
|
|
162
|
+
done: [],
|
|
163
|
+
refused: []
|
|
164
|
+
};
|
|
165
|
+
for (const step of steps){
|
|
166
|
+
var _ctx_actorUid;
|
|
167
|
+
if (step.action === 'delete') await templates.doc(step.id).delete();
|
|
168
|
+
else await templates.doc(step.id).update(readableFields(crmEmailTemplatePackageContent(step.content), (_ctx_actorUid = ctx.actorUid) != null ? _ctx_actorUid : '', deps.now()));
|
|
169
|
+
outcome.done.push(step.id);
|
|
170
|
+
}
|
|
171
|
+
return outcome;
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
//# sourceMappingURL=email-templates-package.server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/transfer/email-templates-package.server.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 * EMAIL TEMPLATES IN A WORKSPACE PACKAGE — the server half (AGL-3535).\n *\n * Written the way the template's duplicate writes a copy\n * (`email-template-duplicate.ts`): inside a transaction that holds the\n * listing's ceiling (`CRM_EMAIL_TEMPLATES_LIMIT`), scoped to its site's\n * token or the organization's, filed under the person importing — a\n * personal template becomes theirs. A replace rewrites what a person reads\n * (name, kind, visibility, subject, body, site) and keeps who wrote it.\n *=========================================*/\n\nimport { CRM_COLLECTIONS } from '@aglyn/aglyn/app-utils/crm'\nimport {\n CRM_EMAIL_TEMPLATES_LIMIT,\n crmEmailTemplateIsListed,\n normalizeCrmEmailTemplate,\n} from '@aglyn/aglyn/app-utils/crm-email-templates'\nimport { hostScopeToken, ORG_SCOPE_TOKEN } from '@aglyn/aglyn/app-utils/scope-tokens'\nimport {\n existingPackageItemsOf,\n type ExistingPackageItem,\n type TransferRowResult,\n} from '@aglyn/aglyn/data-transfer'\nimport type {\n TransferApplyResult,\n TransferApplyWriter,\n TransferPackageItemContent,\n TransferPackageItemWrite,\n TransferPackageRevertResult,\n TransferPackageRevertStep,\n TransferResourceContext,\n} from '@aglyn/aglyn/plugin-manager/plugin-transfer-resources'\nimport firebaseAdmin from '@aglyn/tenant-data-admin/server/firebase-admin'\nimport {\n CRM_EMAIL_TEMPLATES_TRANSFER_KEY,\n crmEmailTemplatePackageContent,\n crmEmailTemplatePackageProblems,\n type CrmEmailTemplatePackageContent,\n} from './email-templates-package'\n\ntype Firestore = FirebaseFirestore.Firestore\n\nexport interface CrmEmailTemplatesPackageDeps {\n firestore(): Firestore\n now(): number\n}\n\nfunction defaultDeps(): CrmEmailTemplatesPackageDeps {\n return { firestore: () => firebaseAdmin.app().firestore() as unknown as Firestore, now: Date.now }\n}\n\nconst templatesOf = (firestore: Firestore, orgId: string) =>\n firestore.collection('orgs').doc(orgId).collection(CRM_COLLECTIONS.emailTemplates)\n\n/** The fields a person reads, as stored: scoped to the site's token, or the organization's. */\nfunction readableFields(content: CrmEmailTemplatePackageContent, actorUid: string, nowMs: number) {\n return {\n name: content.name,\n kind: content.kind,\n visibility: content.visibility,\n subject: content.kind === 'snippet' ? '' : content.subject,\n body: content.body,\n ...(content.visibility === 'personal' ? { ownerUid: actorUid } : {}),\n hostId: content.hostId,\n visibleTo: [content.hostId ? hostScopeToken(content.hostId) : ORG_SCOPE_TOKEN],\n updatedAtMs: nowMs,\n updatedAt: new Date(nowMs),\n }\n}\n\nasync function readAll(\n deps: CrmEmailTemplatesPackageDeps,\n ctx: TransferResourceContext,\n ids?: readonly string[],\n): Promise<Array<TransferPackageItemContent<CrmEmailTemplatePackageContent>>> {\n const collection = templatesOf(deps.firestore(), ctx.orgId)\n const docs = ids\n ? (await Promise.all(ids.map((id) => collection.doc(id).get()))).filter((doc) => doc.exists)\n : (await collection.get()).docs\n return docs.flatMap((doc) => {\n const template = normalizeCrmEmailTemplate(doc.data() as Record<string, unknown>)\n // A colleague's personal template is theirs; only the importer's own and the shared ones move.\n if (!crmEmailTemplateIsListed(template, ctx.actorUid)) return []\n const content = crmEmailTemplatePackageContent(template)\n return [{ kind: CRM_EMAIL_TEMPLATES_TRANSFER_KEY, id: doc.id, name: content.name, content }]\n })\n}\n\nexport function createCrmEmailTemplatesPackage(deps: CrmEmailTemplatesPackageDeps = defaultDeps()) {\n return {\n async items(ctx: TransferResourceContext): Promise<ExistingPackageItem[]> {\n return existingPackageItemsOf(CRM_EMAIL_TEMPLATES_TRANSFER_KEY, await readAll(deps, ctx))\n },\n\n async readItems(ctx: TransferResourceContext, ids: readonly string[]) {\n return readAll(deps, ctx, ids)\n },\n\n async problems(ctx: TransferResourceContext, write: TransferPackageItemWrite<CrmEmailTemplatePackageContent>) {\n const problems = crmEmailTemplatePackageProblems({ ...write.content, name: write.rename?.name ?? write.content.name })\n if (write.decision !== 'replace') {\n const held = (await templatesOf(deps.firestore(), ctx.orgId).count().get()).data().count\n if (held >= CRM_EMAIL_TEMPLATES_LIMIT) {\n problems.push(`This workspace holds ${CRM_EMAIL_TEMPLATES_LIMIT} email templates — delete one to make room.`)\n }\n }\n return problems\n },\n\n async writeItems(\n ctx: TransferResourceContext,\n items: ReadonlyArray<TransferPackageItemWrite<CrmEmailTemplatePackageContent>>,\n writer: TransferApplyWriter,\n ): Promise<TransferApplyResult> {\n const firestore = deps.firestore()\n const templates = templatesOf(firestore, ctx.orgId)\n const actor = ctx.actorUid ?? ''\n const results: TransferRowResult[] = []\n for (const write of items) {\n const before = await writer.alreadyApplied(write.row)\n if (before) {\n results.push(before)\n continue\n }\n const content = crmEmailTemplatePackageContent({ ...write.content, name: write.rename?.name ?? write.content.name })\n const nowMs = deps.now()\n const result = await firestore.runTransaction(async (transaction): Promise<TransferRowResult> => {\n const ref = templates.doc(write.targetId)\n const current = await transaction.get(ref)\n if (write.decision === 'replace') {\n if (!current.exists) return { row: write.row, outcome: 'failed', recordId: write.targetId, message: 'That template no longer exists.' }\n transaction.update(ref, readableFields(content, actor, nowMs))\n return { row: write.row, outcome: 'updated', recordId: write.targetId }\n }\n const siblings = await transaction.get(templates.select('name'))\n if (siblings.size >= CRM_EMAIL_TEMPLATES_LIMIT) {\n return {\n row: write.row,\n outcome: 'failed',\n message: `This workspace holds ${CRM_EMAIL_TEMPLATES_LIMIT} email templates — delete one to make room.`,\n }\n }\n transaction.create(ref, {\n ...readableFields(content, actor, nowMs),\n createdByUid: actor,\n createdAtMs: nowMs,\n createdAt: new Date(nowMs),\n })\n return { row: write.row, outcome: 'created', recordId: write.targetId }\n })\n await writer.markApplied(result)\n results.push(result)\n }\n return { results, undo: [] }\n },\n\n async revertItems(\n ctx: TransferResourceContext,\n steps: ReadonlyArray<TransferPackageRevertStep<CrmEmailTemplatePackageContent>>,\n ): Promise<TransferPackageRevertResult> {\n const templates = templatesOf(deps.firestore(), ctx.orgId)\n const outcome: TransferPackageRevertResult = { done: [], refused: [] }\n for (const step of steps) {\n if (step.action === 'delete') await templates.doc(step.id).delete()\n else await templates.doc(step.id).update(readableFields(crmEmailTemplatePackageContent(step.content), ctx.actorUid ?? '', deps.now()))\n outcome.done.push(step.id)\n }\n return outcome\n },\n }\n}\n"],"names":["CRM_COLLECTIONS","CRM_EMAIL_TEMPLATES_LIMIT","crmEmailTemplateIsListed","normalizeCrmEmailTemplate","hostScopeToken","ORG_SCOPE_TOKEN","existingPackageItemsOf","firebaseAdmin","CRM_EMAIL_TEMPLATES_TRANSFER_KEY","crmEmailTemplatePackageContent","crmEmailTemplatePackageProblems","defaultDeps","firestore","app","now","Date","templatesOf","orgId","collection","doc","emailTemplates","readableFields","content","actorUid","nowMs","name","kind","visibility","subject","body","ownerUid","hostId","visibleTo","updatedAtMs","updatedAt","readAll","deps","ctx","ids","docs","Promise","all","map","id","get","filter","exists","flatMap","template","data","createCrmEmailTemplatesPackage","items","readItems","problems","write","rename","decision","held","count","push","writeItems","writer","templates","actor","results","before","alreadyApplied","row","result","runTransaction","transaction","ref","targetId","current","outcome","recordId","message","update","siblings","select","size","create","createdByUid","createdAtMs","createdAt","markApplied","undo","revertItems","steps","done","refused","step","action","delete"],"mappings":"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"}
|