@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
|
@@ -1,112 +0,0 @@
|
|
|
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 ImportChunkResult, type ImportDroppedValue } from '@aglyn/aglyn/app-utils/csv-import';
|
|
18
|
-
/** The shared ceilings, under this collection's names. */
|
|
19
|
-
export declare const DEAL_IMPORT_MAX_ROWS = 5000;
|
|
20
|
-
export declare const DEAL_IMPORT_CHUNK_SIZE = 200;
|
|
21
|
-
export declare const DEAL_IMPORT_MAX_BODY_BYTES = 2000000;
|
|
22
|
-
export declare const DEAL_IMPORT_PREVIEW_ROWS = 10;
|
|
23
|
-
/** The same caps the deal drawer holds a typed deal to. */
|
|
24
|
-
export declare const DEAL_IMPORT_TITLE_MAX = 120;
|
|
25
|
-
export declare const DEAL_IMPORT_NOTES_MAX = 4000;
|
|
26
|
-
/** The most cents one row may carry — past this the number is a slip. */
|
|
27
|
-
export declare const DEAL_IMPORT_AMOUNT_CENTS_MAX = 1000000000000;
|
|
28
|
-
/** The fields a column may be mapped to, in the order the mapping menu lists them. */
|
|
29
|
-
export declare const DEAL_IMPORT_FIELDS: readonly ["title", "pipeline", "stage", "amount", "currency", "ownerEmail", "expectedClose", "notes"];
|
|
30
|
-
export type DealImportField = (typeof DEAL_IMPORT_FIELDS)[number];
|
|
31
|
-
/** How each field reads in the mapping menu. Typed so a field cannot ship unlabeled. */
|
|
32
|
-
export declare const DEAL_IMPORT_FIELD_LABELS: Record<DealImportField, string>;
|
|
33
|
-
/** Column index → field. A column absent from the map is not imported. */
|
|
34
|
-
export type DealImportMapping = Record<number, DealImportField>;
|
|
35
|
-
/** A proposed mapping from a file's header row, each field taken at most once. */
|
|
36
|
-
export declare function guessDealImportMapping(columns: readonly string[]): DealImportMapping;
|
|
37
|
-
/**
|
|
38
|
-
* What the browser posts for one line: the cells the mapping selected,
|
|
39
|
-
* under the field they were mapped to, verbatim. `unknown` because the
|
|
40
|
-
* server reads this off an untrusted body.
|
|
41
|
-
*/
|
|
42
|
-
export type DealImportRawRow = Partial<Record<DealImportField, unknown>>;
|
|
43
|
-
/**
|
|
44
|
-
* One parsed line under the mapping. Empty cells are left absent. A deal
|
|
45
|
-
* has no custom fields yet, so a custom target the shared drawer could
|
|
46
|
-
* name is dropped here rather than refused at the type.
|
|
47
|
-
*/
|
|
48
|
-
export declare function mapDealImportRow(cells: readonly string[], mapping: Record<number, DealImportField | `custom:${string}`>): DealImportRawRow;
|
|
49
|
-
export type DealImportSkipReason = 'missing-title' | 'unknown-pipeline' | 'unknown-stage' | 'records-band' | 'write-failed';
|
|
50
|
-
/** How a skip reason reads on screen and in the downloaded file. */
|
|
51
|
-
export declare const DEAL_IMPORT_SKIP_LABELS: Record<DealImportSkipReason, string>;
|
|
52
|
-
/** One row, ready for the server to resolve and write. */
|
|
53
|
-
export interface DealImportRow {
|
|
54
|
-
title: string;
|
|
55
|
-
/** The pipeline's name as typed, trimmed; absent means the default pipeline. */
|
|
56
|
-
pipeline?: string;
|
|
57
|
-
/** The stage's name as typed, trimmed; absent means the pipeline's first open stage. */
|
|
58
|
-
stage?: string;
|
|
59
|
-
amountCents?: number;
|
|
60
|
-
/** Lowercase ISO 4217. */
|
|
61
|
-
currency?: string;
|
|
62
|
-
/** Normalized, for the server to resolve against the org's members. */
|
|
63
|
-
ownerEmail?: string;
|
|
64
|
-
/** Epoch ms at noon UTC of the typed calendar day, or the typed instant. */
|
|
65
|
-
expectedCloseAtMs?: number;
|
|
66
|
-
notes?: string;
|
|
67
|
-
dropped: ImportDroppedValue[];
|
|
68
|
-
}
|
|
69
|
-
export type DealImportRowVerdict = {
|
|
70
|
-
ok: true;
|
|
71
|
-
row: DealImportRow;
|
|
72
|
-
} | {
|
|
73
|
-
ok: false;
|
|
74
|
-
reason: 'missing-title';
|
|
75
|
-
input: string;
|
|
76
|
-
};
|
|
77
|
-
/**
|
|
78
|
-
* A money cell as cents — `1,250.00`, `$1250`, `1250` → 125000 — or
|
|
79
|
-
* `null` when it is not a number. Rounded to the cent: a spreadsheet
|
|
80
|
-
* that computed `12.345` meant a price, not a third of a cent.
|
|
81
|
-
*/
|
|
82
|
-
export declare function parseImportAmountCents(value: unknown): number | null;
|
|
83
|
-
/**
|
|
84
|
-
* A date cell as epoch ms: a calendar day (`2026-09-30`) at noon UTC — a
|
|
85
|
-
* day, not an instant, so any zone reads the same date back — or an ISO
|
|
86
|
-
* instant as itself. `null` when it is neither.
|
|
87
|
-
*/
|
|
88
|
-
export declare function parseImportDate(value: unknown): number | null;
|
|
89
|
-
/**
|
|
90
|
-
* One raw row as the values that will be written, or the reason it cannot
|
|
91
|
-
* be. Refused here only for a missing title; the pipeline and the stage
|
|
92
|
-
* are refused by the server, which alone can look them up; every other
|
|
93
|
-
* unreadable cell is dropped and named.
|
|
94
|
-
*/
|
|
95
|
-
export declare function normalizeDealImportRow(raw: DealImportRawRow): DealImportRowVerdict;
|
|
96
|
-
/** A name as the key two spellings of one pipeline or stage meet at. */
|
|
97
|
-
export declare function dealImportNameKey(name: string): string;
|
|
98
|
-
/** One row the server did not store, by its index in the request, named by the deal. */
|
|
99
|
-
export interface DealImportSkippedRow {
|
|
100
|
-
index: number;
|
|
101
|
-
title: string;
|
|
102
|
-
reason: DealImportSkipReason;
|
|
103
|
-
}
|
|
104
|
-
/** What one request did. The drawer sums these across a file. */
|
|
105
|
-
export type DealImportChunkResult = ImportChunkResult<DealImportSkippedRow>;
|
|
106
|
-
export declare function emptyDealImportResult(): DealImportChunkResult;
|
|
107
|
-
export declare function mergeDealImportResults(total: DealImportChunkResult, chunk: DealImportChunkResult, offset?: number): DealImportChunkResult;
|
|
108
|
-
/** The skipped rows as a file the operator can fix and re-import. */
|
|
109
|
-
export declare function dealImportSkippedCsv(columns: readonly string[], entries: readonly {
|
|
110
|
-
cells: readonly string[];
|
|
111
|
-
reason: DealImportSkipReason;
|
|
112
|
-
}[]): string;
|
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
|
|
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
|
-
* BRINGING A SPREADSHEET OF DEALS INTO THE CRM — the pure half (AGL-2662).
|
|
19
|
-
*
|
|
20
|
-
* The contact import's three stages (`crm-import.ts`) over the deal
|
|
21
|
-
* vocabulary: a header row is matched to a proposed mapping, one line is
|
|
22
|
-
* mapped to a raw row of verbatim strings, and the server normalizes each
|
|
23
|
-
* row here before it resolves the two names a deal cannot be filed without.
|
|
24
|
-
*
|
|
25
|
-
* ## A deal names its pipeline and its stage by NAME
|
|
26
|
-
*
|
|
27
|
-
* A spreadsheet says "Sales" and "Proposal sent", never a document id, so
|
|
28
|
-
* the file carries names and the server resolves them against the org's
|
|
29
|
-
* own pipelines — case-insensitively, trimmed — and REFUSES the row, by
|
|
30
|
-
* name, when it cannot: an unknown pipeline is `unknown-pipeline`, an
|
|
31
|
-
* unknown stage in a known pipeline `unknown-stage`. A row with no
|
|
32
|
-
* pipeline cell lands in the default pipeline, and one with no stage cell
|
|
33
|
-
* in that pipeline's first open stage, the way the deal drawer opens.
|
|
34
|
-
*
|
|
35
|
-
* ## A deal has no key, so nothing is merged
|
|
36
|
-
*
|
|
37
|
-
* A contact is one address and a company one domain, but two deals titled
|
|
38
|
-
* "Renewal" are two deals. Every row CREATES; importing a file twice files
|
|
39
|
-
* it twice. What is refused is refused before any write.
|
|
40
|
-
*
|
|
41
|
-
* ## A bad cell is dropped and named; a bad row is skipped and named
|
|
42
|
-
*
|
|
43
|
-
* The contact import's rule: an amount that is not a number, a currency
|
|
44
|
-
* that is not a code, a close date that is not a date, an owner address
|
|
45
|
-
* that is not an address — each is left off the record and REPORTED under
|
|
46
|
-
* {@link DealImportRow.dropped}, never silently discarded.
|
|
47
|
-
*/ import { normalizeContactEmail } from "@aglyn/aglyn/app-utils/contacts";
|
|
48
|
-
import { CSV_IMPORT_CHUNK_SIZE, CSV_IMPORT_MAX_BODY_BYTES, CSV_IMPORT_MAX_ROWS, CSV_IMPORT_PREVIEW_ROWS, emptyImportResult, guessImportMapping, importAliasKeys, importSkippedCsv, importTextValue, mapImportRow, mergeImportResults } from "@aglyn/aglyn/app-utils/csv-import";
|
|
49
|
-
/** The shared ceilings, under this collection's names. */ export const DEAL_IMPORT_MAX_ROWS = CSV_IMPORT_MAX_ROWS;
|
|
50
|
-
export const DEAL_IMPORT_CHUNK_SIZE = CSV_IMPORT_CHUNK_SIZE;
|
|
51
|
-
export const DEAL_IMPORT_MAX_BODY_BYTES = CSV_IMPORT_MAX_BODY_BYTES;
|
|
52
|
-
export const DEAL_IMPORT_PREVIEW_ROWS = CSV_IMPORT_PREVIEW_ROWS;
|
|
53
|
-
/** The same caps the deal drawer holds a typed deal to. */ export const DEAL_IMPORT_TITLE_MAX = 120;
|
|
54
|
-
export const DEAL_IMPORT_NOTES_MAX = 4000;
|
|
55
|
-
/** The most cents one row may carry — past this the number is a slip. */ export const DEAL_IMPORT_AMOUNT_CENTS_MAX = 1000000000000;
|
|
56
|
-
/** The fields a column may be mapped to, in the order the mapping menu lists them. */ export const DEAL_IMPORT_FIELDS = [
|
|
57
|
-
'title',
|
|
58
|
-
'pipeline',
|
|
59
|
-
'stage',
|
|
60
|
-
'amount',
|
|
61
|
-
'currency',
|
|
62
|
-
'ownerEmail',
|
|
63
|
-
'expectedClose',
|
|
64
|
-
'notes'
|
|
65
|
-
];
|
|
66
|
-
/** How each field reads in the mapping menu. Typed so a field cannot ship unlabeled. */ export const DEAL_IMPORT_FIELD_LABELS = {
|
|
67
|
-
title: 'Title (required)',
|
|
68
|
-
pipeline: 'Pipeline (by name)',
|
|
69
|
-
stage: 'Stage (by name)',
|
|
70
|
-
amount: 'Amount (major units, 1250.00)',
|
|
71
|
-
currency: 'Currency (three-letter code)',
|
|
72
|
-
ownerEmail: 'Owner (team member email)',
|
|
73
|
-
expectedClose: 'Expected close (YYYY-MM-DD)',
|
|
74
|
-
notes: 'Notes'
|
|
75
|
-
};
|
|
76
|
-
/**
|
|
77
|
-
* Header aliases per field, matched after the shared header normalization.
|
|
78
|
-
*
|
|
79
|
-
* First in each list is the header this CRM's own deals export writes, so
|
|
80
|
-
* an export re-imports without a hand mapping; the export's Status,
|
|
81
|
-
* Contact, Company, Closed and Lost reason columns are deliberately
|
|
82
|
-
* absent, because the stage decides the status and a link is made on the
|
|
83
|
-
* record, not from a file.
|
|
84
|
-
*/ const FIELD_ALIASES = {
|
|
85
|
-
title: [
|
|
86
|
-
'title',
|
|
87
|
-
'deal',
|
|
88
|
-
'deal name',
|
|
89
|
-
'deal title',
|
|
90
|
-
'name',
|
|
91
|
-
'opportunity',
|
|
92
|
-
'opportunity name'
|
|
93
|
-
],
|
|
94
|
-
pipeline: [
|
|
95
|
-
'pipeline',
|
|
96
|
-
'pipeline name',
|
|
97
|
-
'board'
|
|
98
|
-
],
|
|
99
|
-
stage: [
|
|
100
|
-
'stage',
|
|
101
|
-
'stage name',
|
|
102
|
-
'deal stage',
|
|
103
|
-
'step'
|
|
104
|
-
],
|
|
105
|
-
amount: [
|
|
106
|
-
'amount',
|
|
107
|
-
'value',
|
|
108
|
-
'deal value',
|
|
109
|
-
'deal amount',
|
|
110
|
-
'total',
|
|
111
|
-
'price'
|
|
112
|
-
],
|
|
113
|
-
currency: [
|
|
114
|
-
'currency',
|
|
115
|
-
'currency code'
|
|
116
|
-
],
|
|
117
|
-
ownerEmail: [
|
|
118
|
-
'owner',
|
|
119
|
-
'owner email',
|
|
120
|
-
'deal owner',
|
|
121
|
-
'assigned to',
|
|
122
|
-
'rep'
|
|
123
|
-
],
|
|
124
|
-
expectedClose: [
|
|
125
|
-
'expected close',
|
|
126
|
-
'close date',
|
|
127
|
-
'expected close date',
|
|
128
|
-
'closing date',
|
|
129
|
-
'expected closing'
|
|
130
|
-
],
|
|
131
|
-
notes: [
|
|
132
|
-
'notes',
|
|
133
|
-
'note',
|
|
134
|
-
'description',
|
|
135
|
-
'comments'
|
|
136
|
-
]
|
|
137
|
-
};
|
|
138
|
-
const FIELD_ALIAS_KEYS = importAliasKeys(DEAL_IMPORT_FIELDS, FIELD_ALIASES);
|
|
139
|
-
/** A proposed mapping from a file's header row, each field taken at most once. */ export function guessDealImportMapping(columns) {
|
|
140
|
-
return guessImportMapping(columns, DEAL_IMPORT_FIELDS, FIELD_ALIAS_KEYS);
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* One parsed line under the mapping. Empty cells are left absent. A deal
|
|
144
|
-
* has no custom fields yet, so a custom target the shared drawer could
|
|
145
|
-
* name is dropped here rather than refused at the type.
|
|
146
|
-
*/ export function mapDealImportRow(cells, mapping) {
|
|
147
|
-
const _mapImportRow = mapImportRow(cells, mapping), { custom: _custom } = _mapImportRow, row = _object_without_properties_loose(_mapImportRow, [
|
|
148
|
-
"custom"
|
|
149
|
-
]);
|
|
150
|
-
return row;
|
|
151
|
-
}
|
|
152
|
-
/** How a skip reason reads on screen and in the downloaded file. */ export const DEAL_IMPORT_SKIP_LABELS = {
|
|
153
|
-
'missing-title': 'No title',
|
|
154
|
-
'unknown-pipeline': 'No pipeline by that name',
|
|
155
|
-
'unknown-stage': 'No stage by that name in that pipeline',
|
|
156
|
-
'records-band': 'CRM records limit reached',
|
|
157
|
-
'write-failed': 'Could not be saved'
|
|
158
|
-
};
|
|
159
|
-
/**
|
|
160
|
-
* A money cell as cents — `1,250.00`, `$1250`, `1250` → 125000 — or
|
|
161
|
-
* `null` when it is not a number. Rounded to the cent: a spreadsheet
|
|
162
|
-
* that computed `12.345` meant a price, not a third of a cent.
|
|
163
|
-
*/ export function parseImportAmountCents(value) {
|
|
164
|
-
if (typeof value === 'number') {
|
|
165
|
-
return Number.isFinite(value) && value >= 0 ? Math.round(value * 100) : null;
|
|
166
|
-
}
|
|
167
|
-
const text = String(value != null ? value : '').trim().replace(/[,\s]/g, '').replace(/^[^\d.-]+/, '');
|
|
168
|
-
if (!/^\d+(\.\d+)?$/.test(text)) return null;
|
|
169
|
-
const cents = Math.round(Number(text) * 100);
|
|
170
|
-
return Number.isFinite(cents) && cents <= DEAL_IMPORT_AMOUNT_CENTS_MAX ? cents : null;
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* A date cell as epoch ms: a calendar day (`2026-09-30`) at noon UTC — a
|
|
174
|
-
* day, not an instant, so any zone reads the same date back — or an ISO
|
|
175
|
-
* instant as itself. `null` when it is neither.
|
|
176
|
-
*/ export function parseImportDate(value) {
|
|
177
|
-
const text = String(value != null ? value : '').trim();
|
|
178
|
-
const day = /^(\d{4})-(\d{2})-(\d{2})$/.exec(text);
|
|
179
|
-
if (day) {
|
|
180
|
-
const ms = Date.UTC(Number(day[1]), Number(day[2]) - 1, Number(day[3]), 12);
|
|
181
|
-
// `Date.UTC` rolls February 30 into March; a typed day that moved is not a day.
|
|
182
|
-
const back = new Date(ms);
|
|
183
|
-
return back.getUTCMonth() === Number(day[2]) - 1 && back.getUTCDate() === Number(day[3]) ? ms : null;
|
|
184
|
-
}
|
|
185
|
-
if (!/^\d{4}-\d{2}-\d{2}T/.test(text)) return null;
|
|
186
|
-
const ms = Date.parse(text);
|
|
187
|
-
return Number.isFinite(ms) ? ms : null;
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* One raw row as the values that will be written, or the reason it cannot
|
|
191
|
-
* be. Refused here only for a missing title; the pipeline and the stage
|
|
192
|
-
* are refused by the server, which alone can look them up; every other
|
|
193
|
-
* unreadable cell is dropped and named.
|
|
194
|
-
*/ export function normalizeDealImportRow(raw) {
|
|
195
|
-
var _importTextValue;
|
|
196
|
-
const title = (_importTextValue = importTextValue(raw.title, DEAL_IMPORT_TITLE_MAX)) == null ? void 0 : _importTextValue.replace(/\s+/g, ' ');
|
|
197
|
-
if (!title) {
|
|
198
|
-
return {
|
|
199
|
-
ok: false,
|
|
200
|
-
reason: 'missing-title',
|
|
201
|
-
input: ''
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
const dropped = [];
|
|
205
|
-
const drop = (field, value)=>{
|
|
206
|
-
dropped.push({
|
|
207
|
-
field,
|
|
208
|
-
value: String(value != null ? value : '').trim()
|
|
209
|
-
});
|
|
210
|
-
};
|
|
211
|
-
const row = {
|
|
212
|
-
title,
|
|
213
|
-
dropped
|
|
214
|
-
};
|
|
215
|
-
const pipeline = importTextValue(raw.pipeline, 120);
|
|
216
|
-
if (pipeline) row.pipeline = pipeline;
|
|
217
|
-
const stage = importTextValue(raw.stage, 120);
|
|
218
|
-
if (stage) row.stage = stage;
|
|
219
|
-
const amountText = importTextValue(raw.amount, 64);
|
|
220
|
-
if (amountText) {
|
|
221
|
-
const cents = parseImportAmountCents(amountText);
|
|
222
|
-
if (cents !== null) row.amountCents = cents;
|
|
223
|
-
else drop('amount', amountText);
|
|
224
|
-
}
|
|
225
|
-
const currencyText = importTextValue(raw.currency, 16);
|
|
226
|
-
if (currencyText) {
|
|
227
|
-
const code = currencyText.toLowerCase();
|
|
228
|
-
if (/^[a-z]{3}$/.test(code)) row.currency = code;
|
|
229
|
-
else drop('currency', currencyText);
|
|
230
|
-
}
|
|
231
|
-
const ownerText = importTextValue(raw.ownerEmail, 320);
|
|
232
|
-
if (ownerText) {
|
|
233
|
-
const owner = normalizeContactEmail(ownerText);
|
|
234
|
-
if (owner) row.ownerEmail = owner;
|
|
235
|
-
else drop('ownerEmail', ownerText);
|
|
236
|
-
}
|
|
237
|
-
const closeText = importTextValue(raw.expectedClose, 64);
|
|
238
|
-
if (closeText) {
|
|
239
|
-
const ms = parseImportDate(closeText);
|
|
240
|
-
if (ms !== null) row.expectedCloseAtMs = ms;
|
|
241
|
-
else drop('expectedClose', closeText);
|
|
242
|
-
}
|
|
243
|
-
const notes = importTextValue(raw.notes, DEAL_IMPORT_NOTES_MAX);
|
|
244
|
-
if (notes) row.notes = notes;
|
|
245
|
-
return {
|
|
246
|
-
ok: true,
|
|
247
|
-
row
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
/** A name as the key two spellings of one pipeline or stage meet at. */ export function dealImportNameKey(name) {
|
|
251
|
-
return name.trim().replace(/\s+/g, ' ').toLowerCase();
|
|
252
|
-
}
|
|
253
|
-
export function emptyDealImportResult() {
|
|
254
|
-
return emptyImportResult();
|
|
255
|
-
}
|
|
256
|
-
export function mergeDealImportResults(total, chunk, offset = 0) {
|
|
257
|
-
return mergeImportResults(total, chunk, offset);
|
|
258
|
-
}
|
|
259
|
-
/** The skipped rows as a file the operator can fix and re-import. */ export function dealImportSkippedCsv(columns, entries) {
|
|
260
|
-
return importSkippedCsv(columns, entries, DEAL_IMPORT_SKIP_LABELS);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
//# sourceMappingURL=crm-deal-import.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/model/crm-deal-import.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 * BRINGING A SPREADSHEET OF DEALS INTO THE CRM — the pure half (AGL-2662).\n *\n * The contact import's three stages (`crm-import.ts`) over the deal\n * vocabulary: a header row is matched to a proposed mapping, one line is\n * mapped to a raw row of verbatim strings, and the server normalizes each\n * row here before it resolves the two names a deal cannot be filed without.\n *\n * ## A deal names its pipeline and its stage by NAME\n *\n * A spreadsheet says \"Sales\" and \"Proposal sent\", never a document id, so\n * the file carries names and the server resolves them against the org's\n * own pipelines — case-insensitively, trimmed — and REFUSES the row, by\n * name, when it cannot: an unknown pipeline is `unknown-pipeline`, an\n * unknown stage in a known pipeline `unknown-stage`. A row with no\n * pipeline cell lands in the default pipeline, and one with no stage cell\n * in that pipeline's first open stage, the way the deal drawer opens.\n *\n * ## A deal has no key, so nothing is merged\n *\n * A contact is one address and a company one domain, but two deals titled\n * \"Renewal\" are two deals. Every row CREATES; importing a file twice files\n * it twice. What is refused is refused before any write.\n *\n * ## A bad cell is dropped and named; a bad row is skipped and named\n *\n * The contact import's rule: an amount that is not a number, a currency\n * that is not a code, a close date that is not a date, an owner address\n * that is not an address — each is left off the record and REPORTED under\n * {@link DealImportRow.dropped}, never silently discarded.\n */\n\nimport { normalizeContactEmail } from '@aglyn/aglyn/app-utils/contacts'\nimport {\n CSV_IMPORT_CHUNK_SIZE,\n CSV_IMPORT_MAX_BODY_BYTES,\n CSV_IMPORT_MAX_ROWS,\n CSV_IMPORT_PREVIEW_ROWS,\n emptyImportResult,\n guessImportMapping,\n importAliasKeys,\n type ImportChunkResult,\n type ImportDroppedValue,\n importSkippedCsv,\n importTextValue,\n mapImportRow,\n mergeImportResults,\n} from '@aglyn/aglyn/app-utils/csv-import'\n\n/** The shared ceilings, under this collection's names. */\nexport const DEAL_IMPORT_MAX_ROWS = CSV_IMPORT_MAX_ROWS\nexport const DEAL_IMPORT_CHUNK_SIZE = CSV_IMPORT_CHUNK_SIZE\nexport const DEAL_IMPORT_MAX_BODY_BYTES = CSV_IMPORT_MAX_BODY_BYTES\nexport const DEAL_IMPORT_PREVIEW_ROWS = CSV_IMPORT_PREVIEW_ROWS\n\n/** The same caps the deal drawer holds a typed deal to. */\nexport const DEAL_IMPORT_TITLE_MAX = 120\nexport const DEAL_IMPORT_NOTES_MAX = 4000\n/** The most cents one row may carry — past this the number is a slip. */\nexport const DEAL_IMPORT_AMOUNT_CENTS_MAX = 1_000_000_000_000\n\n/** The fields a column may be mapped to, in the order the mapping menu lists them. */\nexport const DEAL_IMPORT_FIELDS = [\n 'title',\n 'pipeline',\n 'stage',\n 'amount',\n 'currency',\n 'ownerEmail',\n 'expectedClose',\n 'notes',\n] as const\n\nexport type DealImportField = (typeof DEAL_IMPORT_FIELDS)[number]\n\n/** How each field reads in the mapping menu. Typed so a field cannot ship unlabeled. */\nexport const DEAL_IMPORT_FIELD_LABELS: Record<DealImportField, string> = {\n title: 'Title (required)',\n pipeline: 'Pipeline (by name)',\n stage: 'Stage (by name)',\n amount: 'Amount (major units, 1250.00)',\n currency: 'Currency (three-letter code)',\n ownerEmail: 'Owner (team member email)',\n expectedClose: 'Expected close (YYYY-MM-DD)',\n notes: 'Notes',\n}\n\n/**\n * Header aliases per field, matched after the shared header normalization.\n *\n * First in each list is the header this CRM's own deals export writes, so\n * an export re-imports without a hand mapping; the export's Status,\n * Contact, Company, Closed and Lost reason columns are deliberately\n * absent, because the stage decides the status and a link is made on the\n * record, not from a file.\n */\nconst FIELD_ALIASES: Record<DealImportField, readonly string[]> = {\n title: ['title', 'deal', 'deal name', 'deal title', 'name', 'opportunity', 'opportunity name'],\n pipeline: ['pipeline', 'pipeline name', 'board'],\n stage: ['stage', 'stage name', 'deal stage', 'step'],\n amount: ['amount', 'value', 'deal value', 'deal amount', 'total', 'price'],\n currency: ['currency', 'currency code'],\n ownerEmail: ['owner', 'owner email', 'deal owner', 'assigned to', 'rep'],\n expectedClose: ['expected close', 'close date', 'expected close date', 'closing date', 'expected closing'],\n notes: ['notes', 'note', 'description', 'comments'],\n}\n\nconst FIELD_ALIAS_KEYS = importAliasKeys(DEAL_IMPORT_FIELDS, FIELD_ALIASES)\n\n/** Column index → field. A column absent from the map is not imported. */\nexport type DealImportMapping = Record<number, DealImportField>\n\n/** A proposed mapping from a file's header row, each field taken at most once. */\nexport function guessDealImportMapping(columns: readonly string[]): DealImportMapping {\n return guessImportMapping(columns, DEAL_IMPORT_FIELDS, FIELD_ALIAS_KEYS)\n}\n\n/**\n * What the browser posts for one line: the cells the mapping selected,\n * under the field they were mapped to, verbatim. `unknown` because the\n * server reads this off an untrusted body.\n */\nexport type DealImportRawRow = Partial<Record<DealImportField, unknown>>\n\n/**\n * One parsed line under the mapping. Empty cells are left absent. A deal\n * has no custom fields yet, so a custom target the shared drawer could\n * name is dropped here rather than refused at the type.\n */\nexport function mapDealImportRow(\n cells: readonly string[],\n mapping: Record<number, DealImportField | `custom:${string}`>,\n): DealImportRawRow {\n const { custom: _custom, ...row } = mapImportRow(cells, mapping)\n return row\n}\n\nexport type DealImportSkipReason =\n | 'missing-title'\n | 'unknown-pipeline'\n | 'unknown-stage'\n | 'records-band'\n | 'write-failed'\n\n/** How a skip reason reads on screen and in the downloaded file. */\nexport const DEAL_IMPORT_SKIP_LABELS: Record<DealImportSkipReason, string> = {\n 'missing-title': 'No title',\n 'unknown-pipeline': 'No pipeline by that name',\n 'unknown-stage': 'No stage by that name in that pipeline',\n 'records-band': 'CRM records limit reached',\n 'write-failed': 'Could not be saved',\n}\n\n/** One row, ready for the server to resolve and write. */\nexport interface DealImportRow {\n title: string\n /** The pipeline's name as typed, trimmed; absent means the default pipeline. */\n pipeline?: string\n /** The stage's name as typed, trimmed; absent means the pipeline's first open stage. */\n stage?: string\n amountCents?: number\n /** Lowercase ISO 4217. */\n currency?: string\n /** Normalized, for the server to resolve against the org's members. */\n ownerEmail?: string\n /** Epoch ms at noon UTC of the typed calendar day, or the typed instant. */\n expectedCloseAtMs?: number\n notes?: string\n dropped: ImportDroppedValue[]\n}\n\nexport type DealImportRowVerdict =\n | { ok: true; row: DealImportRow }\n | { ok: false; reason: 'missing-title'; input: string }\n\n/**\n * A money cell as cents — `1,250.00`, `$1250`, `1250` → 125000 — or\n * `null` when it is not a number. Rounded to the cent: a spreadsheet\n * that computed `12.345` meant a price, not a third of a cent.\n */\nexport function parseImportAmountCents(value: unknown): number | null {\n if (typeof value === 'number') {\n return Number.isFinite(value) && value >= 0 ? Math.round(value * 100) : null\n }\n const text = String(value ?? '')\n .trim()\n .replace(/[,\\s]/g, '')\n .replace(/^[^\\d.-]+/, '')\n if (!/^\\d+(\\.\\d+)?$/.test(text)) return null\n const cents = Math.round(Number(text) * 100)\n return Number.isFinite(cents) && cents <= DEAL_IMPORT_AMOUNT_CENTS_MAX ? cents : null\n}\n\n/**\n * A date cell as epoch ms: a calendar day (`2026-09-30`) at noon UTC — a\n * day, not an instant, so any zone reads the same date back — or an ISO\n * instant as itself. `null` when it is neither.\n */\nexport function parseImportDate(value: unknown): number | null {\n const text = String(value ?? '').trim()\n const day = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(text)\n if (day) {\n const ms = Date.UTC(Number(day[1]), Number(day[2]) - 1, Number(day[3]), 12)\n // `Date.UTC` rolls February 30 into March; a typed day that moved is not a day.\n const back = new Date(ms)\n return back.getUTCMonth() === Number(day[2]) - 1 && back.getUTCDate() === Number(day[3])\n ? ms\n : null\n }\n if (!/^\\d{4}-\\d{2}-\\d{2}T/.test(text)) return null\n const ms = Date.parse(text)\n return Number.isFinite(ms) ? ms : null\n}\n\n/**\n * One raw row as the values that will be written, or the reason it cannot\n * be. Refused here only for a missing title; the pipeline and the stage\n * are refused by the server, which alone can look them up; every other\n * unreadable cell is dropped and named.\n */\nexport function normalizeDealImportRow(raw: DealImportRawRow): DealImportRowVerdict {\n const title = importTextValue(raw.title, DEAL_IMPORT_TITLE_MAX)?.replace(/\\s+/g, ' ')\n if (!title) {\n return { ok: false, reason: 'missing-title', input: '' }\n }\n const dropped: ImportDroppedValue[] = []\n const drop = (field: DealImportField, value: unknown) => {\n dropped.push({ field, value: String(value ?? '').trim() })\n }\n const row: DealImportRow = { title, dropped }\n\n const pipeline = importTextValue(raw.pipeline, 120)\n if (pipeline) row.pipeline = pipeline\n const stage = importTextValue(raw.stage, 120)\n if (stage) row.stage = stage\n\n const amountText = importTextValue(raw.amount, 64)\n if (amountText) {\n const cents = parseImportAmountCents(amountText)\n if (cents !== null) row.amountCents = cents\n else drop('amount', amountText)\n }\n\n const currencyText = importTextValue(raw.currency, 16)\n if (currencyText) {\n const code = currencyText.toLowerCase()\n if (/^[a-z]{3}$/.test(code)) row.currency = code\n else drop('currency', currencyText)\n }\n\n const ownerText = importTextValue(raw.ownerEmail, 320)\n if (ownerText) {\n const owner = normalizeContactEmail(ownerText)\n if (owner) row.ownerEmail = owner\n else drop('ownerEmail', ownerText)\n }\n\n const closeText = importTextValue(raw.expectedClose, 64)\n if (closeText) {\n const ms = parseImportDate(closeText)\n if (ms !== null) row.expectedCloseAtMs = ms\n else drop('expectedClose', closeText)\n }\n\n const notes = importTextValue(raw.notes, DEAL_IMPORT_NOTES_MAX)\n if (notes) row.notes = notes\n\n return { ok: true, row }\n}\n\n/** A name as the key two spellings of one pipeline or stage meet at. */\nexport function dealImportNameKey(name: string): string {\n return name.trim().replace(/\\s+/g, ' ').toLowerCase()\n}\n\n/** One row the server did not store, by its index in the request, named by the deal. */\nexport interface DealImportSkippedRow {\n index: number\n title: string\n reason: DealImportSkipReason\n}\n\n/** What one request did. The drawer sums these across a file. */\nexport type DealImportChunkResult = ImportChunkResult<DealImportSkippedRow>\n\nexport function emptyDealImportResult(): DealImportChunkResult {\n return emptyImportResult<DealImportSkippedRow>()\n}\n\nexport function mergeDealImportResults(\n total: DealImportChunkResult,\n chunk: DealImportChunkResult,\n offset = 0,\n): DealImportChunkResult {\n return mergeImportResults(total, chunk, offset)\n}\n\n/** The skipped rows as a file the operator can fix and re-import. */\nexport function dealImportSkippedCsv(\n columns: readonly string[],\n entries: readonly { cells: readonly string[]; reason: DealImportSkipReason }[],\n): string {\n return importSkippedCsv(columns, entries, DEAL_IMPORT_SKIP_LABELS)\n}\n"],"names":["normalizeContactEmail","CSV_IMPORT_CHUNK_SIZE","CSV_IMPORT_MAX_BODY_BYTES","CSV_IMPORT_MAX_ROWS","CSV_IMPORT_PREVIEW_ROWS","emptyImportResult","guessImportMapping","importAliasKeys","importSkippedCsv","importTextValue","mapImportRow","mergeImportResults","DEAL_IMPORT_MAX_ROWS","DEAL_IMPORT_CHUNK_SIZE","DEAL_IMPORT_MAX_BODY_BYTES","DEAL_IMPORT_PREVIEW_ROWS","DEAL_IMPORT_TITLE_MAX","DEAL_IMPORT_NOTES_MAX","DEAL_IMPORT_AMOUNT_CENTS_MAX","DEAL_IMPORT_FIELDS","DEAL_IMPORT_FIELD_LABELS","title","pipeline","stage","amount","currency","ownerEmail","expectedClose","notes","FIELD_ALIASES","FIELD_ALIAS_KEYS","guessDealImportMapping","columns","mapDealImportRow","cells","mapping","custom","_custom","row","DEAL_IMPORT_SKIP_LABELS","parseImportAmountCents","value","Number","isFinite","Math","round","text","String","trim","replace","test","cents","parseImportDate","day","exec","ms","Date","UTC","back","getUTCMonth","getUTCDate","parse","normalizeDealImportRow","raw","ok","reason","input","dropped","drop","field","push","amountText","amountCents","currencyText","code","toLowerCase","ownerText","owner","closeText","expectedCloseAtMs","dealImportNameKey","name","emptyDealImportResult","mergeDealImportResults","total","chunk","offset","dealImportSkippedCsv","entries"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BC,GAED,SAASA,qBAAqB,QAAQ,kCAAiC;AACvE,SACEC,qBAAqB,EACrBC,yBAAyB,EACzBC,mBAAmB,EACnBC,uBAAuB,EACvBC,iBAAiB,EACjBC,kBAAkB,EAClBC,eAAe,EAGfC,gBAAgB,EAChBC,eAAe,EACfC,YAAY,EACZC,kBAAkB,QACb,oCAAmC;AAE1C,wDAAwD,GACxD,OAAO,MAAMC,uBAAuBT,oBAAmB;AACvD,OAAO,MAAMU,yBAAyBZ,sBAAqB;AAC3D,OAAO,MAAMa,6BAA6BZ,0BAAyB;AACnE,OAAO,MAAMa,2BAA2BX,wBAAuB;AAE/D,yDAAyD,GACzD,OAAO,MAAMY,wBAAwB,IAAG;AACxC,OAAO,MAAMC,wBAAwB,KAAI;AACzC,uEAAuE,GACvE,OAAO,MAAMC,+BAA+B,cAAiB;AAE7D,oFAAoF,GACpF,OAAO,MAAMC,qBAAqB;IAChC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD,CAAS;AAIV,sFAAsF,GACtF,OAAO,MAAMC,2BAA4D;IACvEC,OAAO;IACPC,UAAU;IACVC,OAAO;IACPC,QAAQ;IACRC,UAAU;IACVC,YAAY;IACZC,eAAe;IACfC,OAAO;AACT,EAAC;AAED;;;;;;;;CAQC,GACD,MAAMC,gBAA4D;IAChER,OAAO;QAAC;QAAS;QAAQ;QAAa;QAAc;QAAQ;QAAe;KAAmB;IAC9FC,UAAU;QAAC;QAAY;QAAiB;KAAQ;IAChDC,OAAO;QAAC;QAAS;QAAc;QAAc;KAAO;IACpDC,QAAQ;QAAC;QAAU;QAAS;QAAc;QAAe;QAAS;KAAQ;IAC1EC,UAAU;QAAC;QAAY;KAAgB;IACvCC,YAAY;QAAC;QAAS;QAAe;QAAc;QAAe;KAAM;IACxEC,eAAe;QAAC;QAAkB;QAAc;QAAuB;QAAgB;KAAmB;IAC1GC,OAAO;QAAC;QAAS;QAAQ;QAAe;KAAW;AACrD;AAEA,MAAME,mBAAmBvB,gBAAgBY,oBAAoBU;AAK7D,gFAAgF,GAChF,OAAO,SAASE,uBAAuBC,OAA0B;IAC/D,OAAO1B,mBAAmB0B,SAASb,oBAAoBW;AACzD;AASA;;;;CAIC,GACD,OAAO,SAASG,iBACdC,KAAwB,EACxBC,OAA6D;IAE7D,MAAoCzB,gBAAAA,aAAawB,OAAOC,UAAlD,EAAEC,QAAQC,OAAO,EAAU,GAAG3B,eAAR4B,uCAAQ5B;;;IACpC,OAAO4B;AACT;AASA,kEAAkE,GAClE,OAAO,MAAMC,0BAAgE;IAC3E,iBAAiB;IACjB,oBAAoB;IACpB,iBAAiB;IACjB,gBAAgB;IAChB,gBAAgB;AAClB,EAAC;AAwBD;;;;CAIC,GACD,OAAO,SAASC,uBAAuBC,KAAc;IACnD,IAAI,OAAOA,UAAU,UAAU;QAC7B,OAAOC,OAAOC,QAAQ,CAACF,UAAUA,SAAS,IAAIG,KAAKC,KAAK,CAACJ,QAAQ,OAAO;IAC1E;IACA,MAAMK,OAAOC,OAAON,gBAAAA,QAAS,IAC1BO,IAAI,GACJC,OAAO,CAAC,UAAU,IAClBA,OAAO,CAAC,aAAa;IACxB,IAAI,CAAC,gBAAgBC,IAAI,CAACJ,OAAO,OAAO;IACxC,MAAMK,QAAQP,KAAKC,KAAK,CAACH,OAAOI,QAAQ;IACxC,OAAOJ,OAAOC,QAAQ,CAACQ,UAAUA,SAASjC,+BAA+BiC,QAAQ;AACnF;AAEA;;;;CAIC,GACD,OAAO,SAASC,gBAAgBX,KAAc;IAC5C,MAAMK,OAAOC,OAAON,gBAAAA,QAAS,IAAIO,IAAI;IACrC,MAAMK,MAAM,4BAA4BC,IAAI,CAACR;IAC7C,IAAIO,KAAK;QACP,MAAME,KAAKC,KAAKC,GAAG,CAACf,OAAOW,GAAG,CAAC,EAAE,GAAGX,OAAOW,GAAG,CAAC,EAAE,IAAI,GAAGX,OAAOW,GAAG,CAAC,EAAE,GAAG;QACxE,gFAAgF;QAChF,MAAMK,OAAO,IAAIF,KAAKD;QACtB,OAAOG,KAAKC,WAAW,OAAOjB,OAAOW,GAAG,CAAC,EAAE,IAAI,KAAKK,KAAKE,UAAU,OAAOlB,OAAOW,GAAG,CAAC,EAAE,IACnFE,KACA;IACN;IACA,IAAI,CAAC,sBAAsBL,IAAI,CAACJ,OAAO,OAAO;IAC9C,MAAMS,KAAKC,KAAKK,KAAK,CAACf;IACtB,OAAOJ,OAAOC,QAAQ,CAACY,MAAMA,KAAK;AACpC;AAEA;;;;;CAKC,GACD,OAAO,SAASO,uBAAuBC,GAAqB;QAC5CtD;IAAd,MAAMY,SAAQZ,mBAAAA,gBAAgBsD,IAAI1C,KAAK,EAAEL,2CAA3BP,iBAAmDwC,OAAO,CAAC,QAAQ;IACjF,IAAI,CAAC5B,OAAO;QACV,OAAO;YAAE2C,IAAI;YAAOC,QAAQ;YAAiBC,OAAO;QAAG;IACzD;IACA,MAAMC,UAAgC,EAAE;IACxC,MAAMC,OAAO,CAACC,OAAwB5B;QACpC0B,QAAQG,IAAI,CAAC;YAAED;YAAO5B,OAAOM,OAAON,gBAAAA,QAAS,IAAIO,IAAI;QAAG;IAC1D;IACA,MAAMV,MAAqB;QAAEjB;QAAO8C;IAAQ;IAE5C,MAAM7C,WAAWb,gBAAgBsD,IAAIzC,QAAQ,EAAE;IAC/C,IAAIA,UAAUgB,IAAIhB,QAAQ,GAAGA;IAC7B,MAAMC,QAAQd,gBAAgBsD,IAAIxC,KAAK,EAAE;IACzC,IAAIA,OAAOe,IAAIf,KAAK,GAAGA;IAEvB,MAAMgD,aAAa9D,gBAAgBsD,IAAIvC,MAAM,EAAE;IAC/C,IAAI+C,YAAY;QACd,MAAMpB,QAAQX,uBAAuB+B;QACrC,IAAIpB,UAAU,MAAMb,IAAIkC,WAAW,GAAGrB;aACjCiB,KAAK,UAAUG;IACtB;IAEA,MAAME,eAAehE,gBAAgBsD,IAAItC,QAAQ,EAAE;IACnD,IAAIgD,cAAc;QAChB,MAAMC,OAAOD,aAAaE,WAAW;QACrC,IAAI,aAAazB,IAAI,CAACwB,OAAOpC,IAAIb,QAAQ,GAAGiD;aACvCN,KAAK,YAAYK;IACxB;IAEA,MAAMG,YAAYnE,gBAAgBsD,IAAIrC,UAAU,EAAE;IAClD,IAAIkD,WAAW;QACb,MAAMC,QAAQ7E,sBAAsB4E;QACpC,IAAIC,OAAOvC,IAAIZ,UAAU,GAAGmD;aACvBT,KAAK,cAAcQ;IAC1B;IAEA,MAAME,YAAYrE,gBAAgBsD,IAAIpC,aAAa,EAAE;IACrD,IAAImD,WAAW;QACb,MAAMvB,KAAKH,gBAAgB0B;QAC3B,IAAIvB,OAAO,MAAMjB,IAAIyC,iBAAiB,GAAGxB;aACpCa,KAAK,iBAAiBU;IAC7B;IAEA,MAAMlD,QAAQnB,gBAAgBsD,IAAInC,KAAK,EAAEX;IACzC,IAAIW,OAAOU,IAAIV,KAAK,GAAGA;IAEvB,OAAO;QAAEoC,IAAI;QAAM1B;IAAI;AACzB;AAEA,sEAAsE,GACtE,OAAO,SAAS0C,kBAAkBC,IAAY;IAC5C,OAAOA,KAAKjC,IAAI,GAAGC,OAAO,CAAC,QAAQ,KAAK0B,WAAW;AACrD;AAYA,OAAO,SAASO;IACd,OAAO7E;AACT;AAEA,OAAO,SAAS8E,uBACdC,KAA4B,EAC5BC,KAA4B,EAC5BC,SAAS,CAAC;IAEV,OAAO3E,mBAAmByE,OAAOC,OAAOC;AAC1C;AAEA,mEAAmE,GACnE,OAAO,SAASC,qBACdvD,OAA0B,EAC1BwD,OAA8E;IAE9E,OAAOhF,iBAAiBwB,SAASwD,SAASjD;AAC5C"}
|
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2026 Aglyn LLC
|
|
4
|
-
*
|
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
* you may not use this file except in compliance with the License.
|
|
7
|
-
* You may obtain a copy of the License at
|
|
8
|
-
*
|
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
*
|
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
* See the License for the specific language governing permissions and
|
|
15
|
-
* limitations under the License.
|
|
16
|
-
*/
|
|
17
|
-
/**
|
|
18
|
-
* BRINGING A SPREADSHEET OF PEOPLE INTO THE CRM — the pure half (AGL-2602).
|
|
19
|
-
*
|
|
20
|
-
* A merchant arriving from another CRM has a CSV: a header row naming
|
|
21
|
-
* columns in that product's vocabulary, and one person per line. Nothing
|
|
22
|
-
* about that file is in our shape. This module is every decision about the
|
|
23
|
-
* file that needs no Firestore and no React — which columns mean what, how a
|
|
24
|
-
* cell becomes a stored value, and what to say about a row that cannot be
|
|
25
|
-
* stored — so that the console drawer and the server route read the same
|
|
26
|
-
* rules rather than two copies of them.
|
|
27
|
-
*
|
|
28
|
-
* ## Three stages, and only the last one touches a record
|
|
29
|
-
*
|
|
30
|
-
* 1. {@link guessContactImportMapping} reads the header and proposes a
|
|
31
|
-
* column → field mapping from a table of aliases. It is a PROPOSAL: the
|
|
32
|
-
* drawer shows it and the operator corrects it, because an export's
|
|
33
|
-
* "Company" column may hold a job title and no alias table can know.
|
|
34
|
-
* 2. {@link mapContactImportRow} applies the mapping to one line, producing
|
|
35
|
-
* the raw row the browser posts. Strings only — the browser trims nothing
|
|
36
|
-
* and validates nothing, so the server is the one place the file is
|
|
37
|
-
* judged and a stale drawer cannot judge it differently.
|
|
38
|
-
* 3. {@link normalizeContactImportRow} turns a raw row into the values that
|
|
39
|
-
* will be written, through the SAME normalizers every other door uses:
|
|
40
|
-
* `normalizeContactEmail` for the dedupe key, `normalizePhone` for E.164,
|
|
41
|
-
* `normalizeAddress` for the postal shape, `isContactLifecycleStage` for
|
|
42
|
-
* the stage. An importer with its own idea of a valid phone number is how
|
|
43
|
-
* one collection ends up storing a value three ways.
|
|
44
|
-
*
|
|
45
|
-
* ## A bad cell is dropped and named; a bad row is skipped and named
|
|
46
|
-
*
|
|
47
|
-
* The only thing that makes a row unstorable is an unusable address, because
|
|
48
|
-
* the address is the identity the shared row is keyed by. Everything else is
|
|
49
|
-
* a value on the row: a phone that cannot be read as a number is left off
|
|
50
|
-
* the contact and REPORTED under {@link ContactImportRow.dropped}, so the
|
|
51
|
-
* operator learns that forty rows had a phone in a format we could not read
|
|
52
|
-
* rather than discovering, weeks later, that the phone column silently went
|
|
53
|
-
* nowhere. `list-import.ts` applies the same rule to a line that is not an
|
|
54
|
-
* address: reported, never quietly discarded.
|
|
55
|
-
*
|
|
56
|
-
* ## Ceilings are on the work, never on the audience
|
|
57
|
-
*
|
|
58
|
-
* {@link CONTACT_IMPORT_MAX_ROWS} bounds one FILE, and the drawer says so
|
|
59
|
-
* before anything is sent. {@link CONTACT_IMPORT_CHUNK_SIZE} bounds one
|
|
60
|
-
* REQUEST, so a five-thousand-row file is twenty-five requests with a
|
|
61
|
-
* progress bar between them rather than one that times out halfway with no
|
|
62
|
-
* record of what it did. Neither one ever trims a person to fit: a row past
|
|
63
|
-
* the file ceiling is refused with the file, and a row is never dropped to
|
|
64
|
-
* make a chunk smaller. The audience band is enforced where every capture
|
|
65
|
-
* enforces it — inside `upsertHostContact` — and an import reports that
|
|
66
|
-
* refusal per row rather than pre-empting it with a count of its own.
|
|
67
|
-
*/
|
|
68
|
-
import type { AglynPostalAddress } from '@aglyn/aglyn/foundation/definitions/contact.types';
|
|
69
|
-
import { type ImportChunkResult, type ImportDroppedValue } from '@aglyn/aglyn/app-utils/csv-import';
|
|
70
|
-
import { type ContactCustomValue, type ContactFieldDefinition, type ContactLifecycleStage } from '@aglyn/aglyn/app-utils/crm';
|
|
71
|
-
export { customImportTarget, customImportTargetKey } from '@aglyn/aglyn/app-utils/csv-import';
|
|
72
|
-
/**
|
|
73
|
-
* The ceilings are the shared ones (`csv-import.ts`), under the names this
|
|
74
|
-
* file has always exported: one file, one request and one preview are
|
|
75
|
-
* bounded the same way for every collection, because the bounds are about
|
|
76
|
-
* the browser's memory and a request's budget rather than about people.
|
|
77
|
-
*/
|
|
78
|
-
export declare const CONTACT_IMPORT_MAX_ROWS = 5000;
|
|
79
|
-
export declare const CONTACT_IMPORT_CHUNK_SIZE = 200;
|
|
80
|
-
export declare const CONTACT_IMPORT_MAX_BODY_BYTES = 2000000;
|
|
81
|
-
export declare const CONTACT_IMPORT_PREVIEW_ROWS = 10;
|
|
82
|
-
/**
|
|
83
|
-
* The most tags one row may carry — the profile drawer's own cap, so an
|
|
84
|
-
* imported person cannot hold more tags than a hand-edited one.
|
|
85
|
-
*/
|
|
86
|
-
export declare const CONTACT_IMPORT_TAGS_MAX = 20;
|
|
87
|
-
/**
|
|
88
|
-
* The standard fields a column may be mapped to, in the order the mapping
|
|
89
|
-
* menu lists them. A custom field is mapped by its key — see
|
|
90
|
-
* {@link ContactImportTargetId}.
|
|
91
|
-
*/
|
|
92
|
-
export declare const CONTACT_IMPORT_FIELDS: readonly ["email", "name", "phone", "jobTitle", "companyName", "addressLine1", "addressLine2", "addressCity", "addressState", "addressPostalCode", "addressCountry", "tags", "ownerEmail", "lifecycleStage", "marketingConsent"];
|
|
93
|
-
export type ContactImportField = (typeof CONTACT_IMPORT_FIELDS)[number];
|
|
94
|
-
/** How each field reads in the mapping menu. Typed so a field cannot ship unlabeled. */
|
|
95
|
-
export declare const CONTACT_IMPORT_FIELD_LABELS: Record<ContactImportField, string>;
|
|
96
|
-
/**
|
|
97
|
-
* What a column is mapped to: a standard field by name, or a custom field
|
|
98
|
-
* as `custom:<key>` — see `customImportTarget`.
|
|
99
|
-
*/
|
|
100
|
-
export type ContactImportTargetId = ContactImportField | `custom:${string}`;
|
|
101
|
-
/** Column index → target. A column absent from the map is not imported. */
|
|
102
|
-
export type ContactImportMapping = Record<number, ContactImportTargetId>;
|
|
103
|
-
/**
|
|
104
|
-
* A proposed mapping from a file's header row — the shared matcher over the
|
|
105
|
-
* contact vocabulary. Custom fields win over standard aliases when a header
|
|
106
|
-
* matches a definition's label or key exactly: a merchant who defined a
|
|
107
|
-
* field called "Status" meant THEIR status, not our lifecycle stage.
|
|
108
|
-
*/
|
|
109
|
-
export declare function guessContactImportMapping(columns: readonly string[], fields?: readonly Pick<ContactFieldDefinition, 'key' | 'label'>[]): ContactImportMapping;
|
|
110
|
-
/**
|
|
111
|
-
* What the browser posts for one line: the cells the mapping selected,
|
|
112
|
-
* under the field they were mapped to, verbatim.
|
|
113
|
-
*
|
|
114
|
-
* Values are `unknown` because the server reads this off an untrusted body;
|
|
115
|
-
* the mapper below only ever writes strings into it.
|
|
116
|
-
*/
|
|
117
|
-
export interface ContactImportRawRow {
|
|
118
|
-
email?: unknown;
|
|
119
|
-
name?: unknown;
|
|
120
|
-
phone?: unknown;
|
|
121
|
-
jobTitle?: unknown;
|
|
122
|
-
companyName?: unknown;
|
|
123
|
-
addressLine1?: unknown;
|
|
124
|
-
addressLine2?: unknown;
|
|
125
|
-
addressCity?: unknown;
|
|
126
|
-
addressState?: unknown;
|
|
127
|
-
addressPostalCode?: unknown;
|
|
128
|
-
addressCountry?: unknown;
|
|
129
|
-
tags?: unknown;
|
|
130
|
-
ownerEmail?: unknown;
|
|
131
|
-
lifecycleStage?: unknown;
|
|
132
|
-
marketingConsent?: unknown;
|
|
133
|
-
/** Custom values keyed by definition key. */
|
|
134
|
-
custom?: unknown;
|
|
135
|
-
}
|
|
136
|
-
/** One parsed line under the mapping. Empty cells are left absent. */
|
|
137
|
-
export declare function mapContactImportRow(cells: readonly string[], mapping: ContactImportMapping): ContactImportRawRow;
|
|
138
|
-
/** Why one row was not stored. */
|
|
139
|
-
export type ContactImportSkipReason = 'invalid-email' | 'duplicate' | 'audience-band'
|
|
140
|
-
/** The person was erased from this workspace at their request (AGL-2623). */
|
|
141
|
-
| 'erased' | 'write-failed'
|
|
142
|
-
/**
|
|
143
|
-
* The request ran out of time before it reached the row (AGL-3423). Nothing
|
|
144
|
-
* was written for it, and importing the skipped file again is safe: a row
|
|
145
|
-
* that did land merges into its record rather than creating a second one.
|
|
146
|
-
*/
|
|
147
|
-
| 'not-reached';
|
|
148
|
-
/** How a skip reason reads on screen and in the downloaded file. */
|
|
149
|
-
export declare const CONTACT_IMPORT_SKIP_LABELS: Record<ContactImportSkipReason, string>;
|
|
150
|
-
/** A cell the file carried that could not be read as the field it was mapped to. */
|
|
151
|
-
export type ContactImportDroppedValue = ImportDroppedValue;
|
|
152
|
-
/** One row, ready to be written. */
|
|
153
|
-
export interface ContactImportRow {
|
|
154
|
-
email: string;
|
|
155
|
-
name?: string;
|
|
156
|
-
/** E.164. */
|
|
157
|
-
phone?: string;
|
|
158
|
-
jobTitle?: string;
|
|
159
|
-
companyName?: string;
|
|
160
|
-
address?: AglynPostalAddress;
|
|
161
|
-
/** Lowercased, deduplicated, capped at {@link CONTACT_IMPORT_TAGS_MAX}. */
|
|
162
|
-
tags: string[];
|
|
163
|
-
/** Normalized, for the server to resolve against the org's members. */
|
|
164
|
-
ownerEmail?: string;
|
|
165
|
-
lifecycleStage?: ContactLifecycleStage;
|
|
166
|
-
marketingConsent: boolean;
|
|
167
|
-
/** Only the keys whose definition the caller supplied and whose value read. */
|
|
168
|
-
custom: Record<string, ContactCustomValue>;
|
|
169
|
-
dropped: ContactImportDroppedValue[];
|
|
170
|
-
}
|
|
171
|
-
export type ContactImportRowVerdict = {
|
|
172
|
-
ok: true;
|
|
173
|
-
row: ContactImportRow;
|
|
174
|
-
} | {
|
|
175
|
-
ok: false;
|
|
176
|
-
reason: 'invalid-email';
|
|
177
|
-
input: string;
|
|
178
|
-
};
|
|
179
|
-
/**
|
|
180
|
-
* A tag cell as the tags it names.
|
|
181
|
-
*
|
|
182
|
-
* `|` or `,` separated — the CSV export writes `|`, most other products
|
|
183
|
-
* write `,` — lowercased and trimmed like the profile drawer's own tag
|
|
184
|
-
* field, so an imported `VIP` and a typed `vip` are one tag and not two.
|
|
185
|
-
*/
|
|
186
|
-
export declare function parseContactImportTags(value: unknown): string[];
|
|
187
|
-
/**
|
|
188
|
-
* A yes/no cell as a boolean, or `null` when it is neither.
|
|
189
|
-
*
|
|
190
|
-
* The affirmatives are the ones consent and checkbox columns actually
|
|
191
|
-
* carry; the negatives are listed so that an explicit `no` is a `false`
|
|
192
|
-
* rather than an unreadable value that gets reported as dropped.
|
|
193
|
-
*/
|
|
194
|
-
export declare function parseContactImportFlag(value: unknown): boolean | null;
|
|
195
|
-
/**
|
|
196
|
-
* A stage cell as a stage, accepting the stored id (`sales-qualified`), its
|
|
197
|
-
* label ("Sales qualified") and the spellings between them
|
|
198
|
-
* (`Sales_Qualified`), or `null` when it names none of them.
|
|
199
|
-
*/
|
|
200
|
-
export declare function parseContactImportLifecycleStage(value: unknown): ContactLifecycleStage | null;
|
|
201
|
-
/**
|
|
202
|
-
* A cell as the value a custom field of this type stores.
|
|
203
|
-
*
|
|
204
|
-
* `{ value }` when it read, `{ value: undefined }` for a blank cell (nothing
|
|
205
|
-
* to write and nothing to report), and `null` when the cell held something
|
|
206
|
-
* the type cannot hold — a word in a number field, a choice a select does
|
|
207
|
-
* not offer. A date is stored as epoch milliseconds, the shape every other
|
|
208
|
-
* timestamp on a CRM record takes (`dueAtMs`, `expectedCloseAtMs`).
|
|
209
|
-
*/
|
|
210
|
-
export declare function parseContactImportCustomValue(definition: Pick<ContactFieldDefinition, 'type' | 'options'>, value: unknown): {
|
|
211
|
-
value: ContactCustomValue | undefined;
|
|
212
|
-
} | null;
|
|
213
|
-
/**
|
|
214
|
-
* One raw row as the values that will be written, or the reason it cannot
|
|
215
|
-
* be.
|
|
216
|
-
*
|
|
217
|
-
* `fields` is the holder's live definitions: a custom value under a key
|
|
218
|
-
* with no definition is dropped and reported, because a value nobody
|
|
219
|
-
* defined a field for is a value no form will ever show.
|
|
220
|
-
*/
|
|
221
|
-
export declare function normalizeContactImportRow(raw: ContactImportRawRow, fields?: readonly Pick<ContactFieldDefinition, 'key' | 'type' | 'options'>[]): ContactImportRowVerdict;
|
|
222
|
-
/** One row the server did not store, by its index in the request, named by address. */
|
|
223
|
-
export interface ContactImportSkippedRow {
|
|
224
|
-
index: number;
|
|
225
|
-
email: string;
|
|
226
|
-
reason: ContactImportSkipReason;
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* What one request did — the shared tally plus how many companies the
|
|
230
|
-
* company column brought into being. The drawer sums these across a file.
|
|
231
|
-
*/
|
|
232
|
-
export interface ContactImportChunkResult extends ImportChunkResult<ContactImportSkippedRow> {
|
|
233
|
-
companiesCreated: number;
|
|
234
|
-
}
|
|
235
|
-
/** An empty tally, for the drawer to fold chunk results into. */
|
|
236
|
-
export declare function emptyContactImportResult(): ContactImportChunkResult;
|
|
237
|
-
/**
|
|
238
|
-
* Two results as one — the shared fold, with the company tally beside it.
|
|
239
|
-
* `offset` is where the chunk started in the file, so a skipped row's index
|
|
240
|
-
* comes back as its position in the FILE rather than in the request.
|
|
241
|
-
*/
|
|
242
|
-
export declare function mergeContactImportResults(total: ContactImportChunkResult, chunk: ContactImportChunkResult, offset?: number): ContactImportChunkResult;
|
|
243
|
-
/**
|
|
244
|
-
* The skipped rows as a file the operator can fix and re-import: the
|
|
245
|
-
* original columns verbatim plus a trailing `Skipped because` column.
|
|
246
|
-
*/
|
|
247
|
-
export declare function contactImportSkippedCsv(columns: readonly string[], entries: readonly {
|
|
248
|
-
cells: readonly string[];
|
|
249
|
-
reason: ContactImportSkipReason;
|
|
250
|
-
}[]): string;
|