@aglyn/plugins-crm 1.0.0-beta.143
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +7 -0
- package/package.json +57 -0
- package/src/index.d.ts +21 -0
- package/src/index.js +29 -0
- package/src/index.js.map +1 -0
- package/src/lib/components/activity-list.d.ts +98 -0
- package/src/lib/components/activity-list.js +321 -0
- package/src/lib/components/activity-list.js.map +1 -0
- package/src/lib/components/activity-queries.d.ts +117 -0
- package/src/lib/components/activity-queries.js +198 -0
- package/src/lib/components/activity-queries.js.map +1 -0
- package/src/lib/components/add-to-list-button.d.ts +25 -0
- package/src/lib/components/add-to-list-button.js +64 -0
- package/src/lib/components/add-to-list-button.js.map +1 -0
- package/src/lib/components/add-to-list-dialog.d.ts +24 -0
- package/src/lib/components/add-to-list-dialog.js +327 -0
- package/src/lib/components/add-to-list-dialog.js.map +1 -0
- package/src/lib/components/assignment-rule-drawer.d.ts +43 -0
- package/src/lib/components/assignment-rule-drawer.js +293 -0
- package/src/lib/components/assignment-rule-drawer.js.map +1 -0
- package/src/lib/components/companies-bulk-bar.d.ts +29 -0
- package/src/lib/components/companies-bulk-bar.js +274 -0
- package/src/lib/components/companies-bulk-bar.js.map +1 -0
- package/src/lib/components/companies-section.d.ts +54 -0
- package/src/lib/components/companies-section.js +522 -0
- package/src/lib/components/companies-section.js.map +1 -0
- package/src/lib/components/company-contacts-card.d.ts +49 -0
- package/src/lib/components/company-contacts-card.js +435 -0
- package/src/lib/components/company-contacts-card.js.map +1 -0
- package/src/lib/components/company-deals-card.d.ts +20 -0
- package/src/lib/components/company-deals-card.js +38 -0
- package/src/lib/components/company-deals-card.js.map +1 -0
- package/src/lib/components/company-detail-page.d.ts +20 -0
- package/src/lib/components/company-detail-page.js +165 -0
- package/src/lib/components/company-detail-page.js.map +1 -0
- package/src/lib/components/company-edit-drawer.d.ts +65 -0
- package/src/lib/components/company-edit-drawer.js +433 -0
- package/src/lib/components/company-edit-drawer.js.map +1 -0
- package/src/lib/components/company-import-drawer.d.ts +42 -0
- package/src/lib/components/company-import-drawer.js +99 -0
- package/src/lib/components/company-import-drawer.js.map +1 -0
- package/src/lib/components/company-picker.d.ts +127 -0
- package/src/lib/components/company-picker.js +323 -0
- package/src/lib/components/company-picker.js.map +1 -0
- package/src/lib/components/company-properties-card.d.ts +47 -0
- package/src/lib/components/company-properties-card.js +289 -0
- package/src/lib/components/company-properties-card.js.map +1 -0
- package/src/lib/components/contact-address-fields.d.ts +29 -0
- package/src/lib/components/contact-address-fields.js +149 -0
- package/src/lib/components/contact-address-fields.js.map +1 -0
- package/src/lib/components/contact-associations-card.d.ts +72 -0
- package/src/lib/components/contact-associations-card.js +296 -0
- package/src/lib/components/contact-associations-card.js.map +1 -0
- package/src/lib/components/contact-custom-columns.d.ts +38 -0
- package/src/lib/components/contact-custom-columns.js +102 -0
- package/src/lib/components/contact-custom-columns.js.map +1 -0
- package/src/lib/components/contact-custom-fields-card.d.ts +39 -0
- package/src/lib/components/contact-custom-fields-card.js +204 -0
- package/src/lib/components/contact-custom-fields-card.js.map +1 -0
- package/src/lib/components/contact-deals-card.d.ts +20 -0
- package/src/lib/components/contact-deals-card.js +38 -0
- package/src/lib/components/contact-deals-card.js.map +1 -0
- package/src/lib/components/contact-detail-page.d.ts +46 -0
- package/src/lib/components/contact-detail-page.js +535 -0
- package/src/lib/components/contact-detail-page.js.map +1 -0
- package/src/lib/components/contact-duplicates-card.d.ts +42 -0
- package/src/lib/components/contact-duplicates-card.js +167 -0
- package/src/lib/components/contact-duplicates-card.js.map +1 -0
- package/src/lib/components/contact-field-drawer.d.ts +64 -0
- package/src/lib/components/contact-field-drawer.js +251 -0
- package/src/lib/components/contact-field-drawer.js.map +1 -0
- package/src/lib/components/contact-import-drawer.d.ts +46 -0
- package/src/lib/components/contact-import-drawer.js +149 -0
- package/src/lib/components/contact-import-drawer.js.map +1 -0
- package/src/lib/components/contact-known-by-card.d.ts +39 -0
- package/src/lib/components/contact-known-by-card.js +142 -0
- package/src/lib/components/contact-known-by-card.js.map +1 -0
- package/src/lib/components/contact-list-columns.d.ts +53 -0
- package/src/lib/components/contact-list-columns.js +288 -0
- package/src/lib/components/contact-list-columns.js.map +1 -0
- package/src/lib/components/contact-merge-dialog.d.ts +79 -0
- package/src/lib/components/contact-merge-dialog.js +405 -0
- package/src/lib/components/contact-merge-dialog.js.map +1 -0
- package/src/lib/components/contact-properties-card.d.ts +89 -0
- package/src/lib/components/contact-properties-card.js +492 -0
- package/src/lib/components/contact-properties-card.js.map +1 -0
- package/src/lib/components/contact-timeline-card.d.ts +68 -0
- package/src/lib/components/contact-timeline-card.js +435 -0
- package/src/lib/components/contact-timeline-card.js.map +1 -0
- package/src/lib/components/contacts-bulk-bar.d.ts +91 -0
- package/src/lib/components/contacts-bulk-bar.js +493 -0
- package/src/lib/components/contacts-bulk-bar.js.map +1 -0
- package/src/lib/components/contacts-section.d.ts +26 -0
- package/src/lib/components/contacts-section.js +1025 -0
- package/src/lib/components/contacts-section.js.map +1 -0
- package/src/lib/components/copy-capture-address-button.d.ts +33 -0
- package/src/lib/components/copy-capture-address-button.js +60 -0
- package/src/lib/components/copy-capture-address-button.js.map +1 -0
- package/src/lib/components/crm-attribution-zone.d.ts +38 -0
- package/src/lib/components/crm-attribution-zone.js +36 -0
- package/src/lib/components/crm-attribution-zone.js.map +1 -0
- package/src/lib/components/crm-booking-zone.d.ts +61 -0
- package/src/lib/components/crm-booking-zone.js +50 -0
- package/src/lib/components/crm-booking-zone.js.map +1 -0
- package/src/lib/components/crm-bulk-bar-frame.d.ts +47 -0
- package/src/lib/components/crm-bulk-bar-frame.js +137 -0
- package/src/lib/components/crm-bulk-bar-frame.js.map +1 -0
- package/src/lib/components/crm-call-actions.d.ts +65 -0
- package/src/lib/components/crm-call-actions.js +110 -0
- package/src/lib/components/crm-call-actions.js.map +1 -0
- package/src/lib/components/crm-column-menu.d.ts +21 -0
- package/src/lib/components/crm-column-menu.js +103 -0
- package/src/lib/components/crm-column-menu.js.map +1 -0
- package/src/lib/components/crm-console-page.d.ts +19 -0
- package/src/lib/components/crm-console-page.js +151 -0
- package/src/lib/components/crm-console-page.js.map +1 -0
- package/src/lib/components/crm-console-sections.d.ts +52 -0
- package/src/lib/components/crm-console-sections.js +83 -0
- package/src/lib/components/crm-console-sections.js.map +1 -0
- package/src/lib/components/crm-custom-field-control.d.ts +26 -0
- package/src/lib/components/crm-custom-field-control.js +131 -0
- package/src/lib/components/crm-custom-field-control.js.map +1 -0
- package/src/lib/components/crm-email-template-tools.d.ts +69 -0
- package/src/lib/components/crm-email-template-tools.js +240 -0
- package/src/lib/components/crm-email-template-tools.js.map +1 -0
- package/src/lib/components/crm-export-all-button.d.ts +39 -0
- package/src/lib/components/crm-export-all-button.js +98 -0
- package/src/lib/components/crm-export-all-button.js.map +1 -0
- package/src/lib/components/crm-filter-bar.d.ts +53 -0
- package/src/lib/components/crm-filter-bar.js +294 -0
- package/src/lib/components/crm-filter-bar.js.map +1 -0
- package/src/lib/components/crm-glance-card.d.ts +54 -0
- package/src/lib/components/crm-glance-card.js +219 -0
- package/src/lib/components/crm-glance-card.js.map +1 -0
- package/src/lib/components/crm-next-activity-column.d.ts +35 -0
- package/src/lib/components/crm-next-activity-column.js +100 -0
- package/src/lib/components/crm-next-activity-column.js.map +1 -0
- package/src/lib/components/crm-record-header.d.ts +97 -0
- package/src/lib/components/crm-record-header.js +160 -0
- package/src/lib/components/crm-record-header.js.map +1 -0
- package/src/lib/components/crm-record-insights-zone.d.ts +50 -0
- package/src/lib/components/crm-record-insights-zone.js +169 -0
- package/src/lib/components/crm-record-insights-zone.js.map +1 -0
- package/src/lib/components/crm-record-picker.d.ts +42 -0
- package/src/lib/components/crm-record-picker.js +104 -0
- package/src/lib/components/crm-record-picker.js.map +1 -0
- package/src/lib/components/crm-send-email-button.d.ts +39 -0
- package/src/lib/components/crm-send-email-button.js +81 -0
- package/src/lib/components/crm-send-email-button.js.map +1 -0
- package/src/lib/components/crm-send-email-dialog.d.ts +61 -0
- package/src/lib/components/crm-send-email-dialog.js +851 -0
- package/src/lib/components/crm-send-email-dialog.js.map +1 -0
- package/src/lib/components/crm-site-picker.d.ts +61 -0
- package/src/lib/components/crm-site-picker.js +99 -0
- package/src/lib/components/crm-site-picker.js.map +1 -0
- package/src/lib/components/crm-suite-lock.d.ts +29 -0
- package/src/lib/components/crm-suite-lock.js +114 -0
- package/src/lib/components/crm-suite-lock.js.map +1 -0
- package/src/lib/components/crm-tasks-due-card.d.ts +42 -0
- package/src/lib/components/crm-tasks-due-card.js +225 -0
- package/src/lib/components/crm-tasks-due-card.js.map +1 -0
- package/src/lib/components/crm-views-control.d.ts +65 -0
- package/src/lib/components/crm-views-control.js +518 -0
- package/src/lib/components/crm-views-control.js.map +1 -0
- package/src/lib/components/csv-import-drawer.d.ts +132 -0
- package/src/lib/components/csv-import-drawer.js +746 -0
- package/src/lib/components/csv-import-drawer.js.map +1 -0
- package/src/lib/components/deal-board.d.ts +70 -0
- package/src/lib/components/deal-board.js +478 -0
- package/src/lib/components/deal-board.js.map +1 -0
- package/src/lib/components/deal-detail-page.d.ts +18 -0
- package/src/lib/components/deal-detail-page.js +323 -0
- package/src/lib/components/deal-detail-page.js.map +1 -0
- package/src/lib/components/deal-edit-drawer.d.ts +59 -0
- package/src/lib/components/deal-edit-drawer.js +640 -0
- package/src/lib/components/deal-edit-drawer.js.map +1 -0
- package/src/lib/components/deal-import-drawer.d.ts +24 -0
- package/src/lib/components/deal-import-drawer.js +83 -0
- package/src/lib/components/deal-import-drawer.js.map +1 -0
- package/src/lib/components/deal-products-card.d.ts +48 -0
- package/src/lib/components/deal-products-card.js +614 -0
- package/src/lib/components/deal-products-card.js.map +1 -0
- package/src/lib/components/deal-properties-card.d.ts +29 -0
- package/src/lib/components/deal-properties-card.js +144 -0
- package/src/lib/components/deal-properties-card.js.map +1 -0
- package/src/lib/components/deal-stage-card.d.ts +24 -0
- package/src/lib/components/deal-stage-card.js +199 -0
- package/src/lib/components/deal-stage-card.js.map +1 -0
- package/src/lib/components/deals-bulk-bar.d.ts +31 -0
- package/src/lib/components/deals-bulk-bar.js +340 -0
- package/src/lib/components/deals-bulk-bar.js.map +1 -0
- package/src/lib/components/deals-section.d.ts +49 -0
- package/src/lib/components/deals-section.js +767 -0
- package/src/lib/components/deals-section.js.map +1 -0
- package/src/lib/components/email-capture-card.d.ts +42 -0
- package/src/lib/components/email-capture-card.js +134 -0
- package/src/lib/components/email-capture-card.js.map +1 -0
- package/src/lib/components/email-template-drawer.d.ts +33 -0
- package/src/lib/components/email-template-drawer.js +209 -0
- package/src/lib/components/email-template-drawer.js.map +1 -0
- package/src/lib/components/email-templates-card.d.ts +33 -0
- package/src/lib/components/email-templates-card.js +370 -0
- package/src/lib/components/email-templates-card.js.map +1 -0
- package/src/lib/components/erase-person-action.d.ts +92 -0
- package/src/lib/components/erase-person-action.js +261 -0
- package/src/lib/components/erase-person-action.js.map +1 -0
- package/src/lib/components/fields-section.d.ts +37 -0
- package/src/lib/components/fields-section.js +641 -0
- package/src/lib/components/fields-section.js.map +1 -0
- package/src/lib/components/form-contact-fields-card.d.ts +46 -0
- package/src/lib/components/form-contact-fields-card.js +253 -0
- package/src/lib/components/form-contact-fields-card.js.map +1 -0
- package/src/lib/components/insert-link-at-caret.d.ts +28 -0
- package/src/lib/components/insert-link-at-caret.js +37 -0
- package/src/lib/components/insert-link-at-caret.js.map +1 -0
- package/src/lib/components/lead-convert-dialog.d.ts +32 -0
- package/src/lib/components/lead-convert-dialog.js +493 -0
- package/src/lib/components/lead-convert-dialog.js.map +1 -0
- package/src/lib/components/lead-detail-page.d.ts +16 -0
- package/src/lib/components/lead-detail-page.js +163 -0
- package/src/lib/components/lead-detail-page.js.map +1 -0
- package/src/lib/components/lead-history-card.d.ts +32 -0
- package/src/lib/components/lead-history-card.js +165 -0
- package/src/lib/components/lead-history-card.js.map +1 -0
- package/src/lib/components/lead-import-drawer.d.ts +24 -0
- package/src/lib/components/lead-import-drawer.js +95 -0
- package/src/lib/components/lead-import-drawer.js.map +1 -0
- package/src/lib/components/lead-owner-select.d.ts +35 -0
- package/src/lib/components/lead-owner-select.js +91 -0
- package/src/lib/components/lead-owner-select.js.map +1 -0
- package/src/lib/components/lead-properties-card.d.ts +61 -0
- package/src/lib/components/lead-properties-card.js +395 -0
- package/src/lib/components/lead-properties-card.js.map +1 -0
- package/src/lib/components/lead-status-chip.d.ts +12 -0
- package/src/lib/components/lead-status-chip.js +43 -0
- package/src/lib/components/lead-status-chip.js.map +1 -0
- package/src/lib/components/lead-surfaces-note.d.ts +126 -0
- package/src/lib/components/lead-surfaces-note.js +262 -0
- package/src/lib/components/lead-surfaces-note.js.map +1 -0
- package/src/lib/components/lead-unqualify-dialog.d.ts +24 -0
- package/src/lib/components/lead-unqualify-dialog.js +125 -0
- package/src/lib/components/lead-unqualify-dialog.js.map +1 -0
- package/src/lib/components/leads-bulk-bar.d.ts +58 -0
- package/src/lib/components/leads-bulk-bar.js +307 -0
- package/src/lib/components/leads-bulk-bar.js.map +1 -0
- package/src/lib/components/leads-section.d.ts +23 -0
- package/src/lib/components/leads-section.js +664 -0
- package/src/lib/components/leads-section.js.map +1 -0
- package/src/lib/components/linked-deals-card.d.ts +32 -0
- package/src/lib/components/linked-deals-card.js +163 -0
- package/src/lib/components/linked-deals-card.js.map +1 -0
- package/src/lib/components/log-activity-dialog.d.ts +60 -0
- package/src/lib/components/log-activity-dialog.js +368 -0
- package/src/lib/components/log-activity-dialog.js.map +1 -0
- package/src/lib/components/lost-reason-dialog.d.ts +26 -0
- package/src/lib/components/lost-reason-dialog.js +95 -0
- package/src/lib/components/lost-reason-dialog.js.map +1 -0
- package/src/lib/components/new-contact-drawer.d.ts +78 -0
- package/src/lib/components/new-contact-drawer.js +343 -0
- package/src/lib/components/new-contact-drawer.js.map +1 -0
- package/src/lib/components/org-lead-surfaces-note.d.ts +57 -0
- package/src/lib/components/org-lead-surfaces-note.js +172 -0
- package/src/lib/components/org-lead-surfaces-note.js.map +1 -0
- package/src/lib/components/owner-avatar.d.ts +18 -0
- package/src/lib/components/owner-avatar.js +61 -0
- package/src/lib/components/owner-avatar.js.map +1 -0
- package/src/lib/components/pipeline-stages-dialog.d.ts +43 -0
- package/src/lib/components/pipeline-stages-dialog.js +339 -0
- package/src/lib/components/pipeline-stages-dialog.js.map +1 -0
- package/src/lib/components/pipelines-dialog.d.ts +55 -0
- package/src/lib/components/pipelines-dialog.js +517 -0
- package/src/lib/components/pipelines-dialog.js.map +1 -0
- package/src/lib/components/recent-activity-feed.d.ts +39 -0
- package/src/lib/components/recent-activity-feed.js +103 -0
- package/src/lib/components/recent-activity-feed.js.map +1 -0
- package/src/lib/components/recipes-card.d.ts +39 -0
- package/src/lib/components/recipes-card.js +485 -0
- package/src/lib/components/recipes-card.js.map +1 -0
- package/src/lib/components/record-activity-card.d.ts +26 -0
- package/src/lib/components/record-activity-card.js +121 -0
- package/src/lib/components/record-activity-card.js.map +1 -0
- package/src/lib/components/record-files-card.d.ts +67 -0
- package/src/lib/components/record-files-card.js +290 -0
- package/src/lib/components/record-files-card.js.map +1 -0
- package/src/lib/components/record-tasks-card.d.ts +32 -0
- package/src/lib/components/record-tasks-card.js +306 -0
- package/src/lib/components/record-tasks-card.js.map +1 -0
- package/src/lib/components/reports/activity-card.d.ts +57 -0
- package/src/lib/components/reports/activity-card.js +281 -0
- package/src/lib/components/reports/activity-card.js.map +1 -0
- package/src/lib/components/reports/closed-deals-card.d.ts +20 -0
- package/src/lib/components/reports/closed-deals-card.js +194 -0
- package/src/lib/components/reports/closed-deals-card.js.map +1 -0
- package/src/lib/components/reports/contacts-mix-card.d.ts +27 -0
- package/src/lib/components/reports/contacts-mix-card.js +161 -0
- package/src/lib/components/reports/contacts-mix-card.js.map +1 -0
- package/src/lib/components/reports/contacts-trend-card.d.ts +31 -0
- package/src/lib/components/reports/contacts-trend-card.js +144 -0
- package/src/lib/components/reports/contacts-trend-card.js.map +1 -0
- package/src/lib/components/reports/forecast-card.d.ts +22 -0
- package/src/lib/components/reports/forecast-card.js +251 -0
- package/src/lib/components/reports/forecast-card.js.map +1 -0
- package/src/lib/components/reports/lead-counts.d.ts +32 -0
- package/src/lib/components/reports/lead-counts.js +44 -0
- package/src/lib/components/reports/lead-counts.js.map +1 -0
- package/src/lib/components/reports/lead-funnel-card.d.ts +38 -0
- package/src/lib/components/reports/lead-funnel-card.js +375 -0
- package/src/lib/components/reports/lead-funnel-card.js.map +1 -0
- package/src/lib/components/reports/pipeline-card.d.ts +19 -0
- package/src/lib/components/reports/pipeline-card.js +338 -0
- package/src/lib/components/reports/pipeline-card.js.map +1 -0
- package/src/lib/components/reports/report-bar-chart.d.ts +39 -0
- package/src/lib/components/reports/report-bar-chart.js +133 -0
- package/src/lib/components/reports/report-bar-chart.js.map +1 -0
- package/src/lib/components/reports/report-breakdown.d.ts +32 -0
- package/src/lib/components/reports/report-breakdown.js +105 -0
- package/src/lib/components/reports/report-breakdown.js.map +1 -0
- package/src/lib/components/reports/report-export.d.ts +37 -0
- package/src/lib/components/reports/report-export.js +66 -0
- package/src/lib/components/reports/report-export.js.map +1 -0
- package/src/lib/components/reports/report-format.d.ts +36 -0
- package/src/lib/components/reports/report-format.js +43 -0
- package/src/lib/components/reports/report-format.js.map +1 -0
- package/src/lib/components/reports/report-scope.d.ts +81 -0
- package/src/lib/components/reports/report-scope.js +58 -0
- package/src/lib/components/reports/report-scope.js.map +1 -0
- package/src/lib/components/reports/report-stat-tile.d.ts +47 -0
- package/src/lib/components/reports/report-stat-tile.js +96 -0
- package/src/lib/components/reports/report-stat-tile.js.map +1 -0
- package/src/lib/components/reports/source-conversion-card.d.ts +28 -0
- package/src/lib/components/reports/source-conversion-card.js +205 -0
- package/src/lib/components/reports/source-conversion-card.js.map +1 -0
- package/src/lib/components/reports/tasks-card.d.ts +26 -0
- package/src/lib/components/reports/tasks-card.js +279 -0
- package/src/lib/components/reports/tasks-card.js.map +1 -0
- package/src/lib/components/reports/use-aggregate-read.d.ts +99 -0
- package/src/lib/components/reports/use-aggregate-read.js +195 -0
- package/src/lib/components/reports/use-aggregate-read.js.map +1 -0
- package/src/lib/components/reports/won-lost-by-owner-card.d.ts +30 -0
- package/src/lib/components/reports/won-lost-by-owner-card.js +168 -0
- package/src/lib/components/reports/won-lost-by-owner-card.js.map +1 -0
- package/src/lib/components/reports-section.d.ts +42 -0
- package/src/lib/components/reports-section.js +308 -0
- package/src/lib/components/reports-section.js.map +1 -0
- package/src/lib/components/sending-addresses-card.d.ts +49 -0
- package/src/lib/components/sending-addresses-card.js +262 -0
- package/src/lib/components/sending-addresses-card.js.map +1 -0
- package/src/lib/components/settings-section.d.ts +151 -0
- package/src/lib/components/settings-section.js +783 -0
- package/src/lib/components/settings-section.js.map +1 -0
- package/src/lib/components/task-cells.d.ts +51 -0
- package/src/lib/components/task-cells.js +139 -0
- package/src/lib/components/task-cells.js.map +1 -0
- package/src/lib/components/task-edit-drawer.d.ts +53 -0
- package/src/lib/components/task-edit-drawer.js +483 -0
- package/src/lib/components/task-edit-drawer.js.map +1 -0
- package/src/lib/components/task-import-drawer.d.ts +24 -0
- package/src/lib/components/task-import-drawer.js +82 -0
- package/src/lib/components/task-import-drawer.js.map +1 -0
- package/src/lib/components/task-snooze-menu.d.ts +65 -0
- package/src/lib/components/task-snooze-menu.js +207 -0
- package/src/lib/components/task-snooze-menu.js.map +1 -0
- package/src/lib/components/tasks-bulk-bar.d.ts +25 -0
- package/src/lib/components/tasks-bulk-bar.js +348 -0
- package/src/lib/components/tasks-bulk-bar.js.map +1 -0
- package/src/lib/components/tasks-calendar.d.ts +38 -0
- package/src/lib/components/tasks-calendar.js +228 -0
- package/src/lib/components/tasks-calendar.js.map +1 -0
- package/src/lib/components/tasks-section.d.ts +27 -0
- package/src/lib/components/tasks-section.js +579 -0
- package/src/lib/components/tasks-section.js.map +1 -0
- package/src/lib/components/use-contact-campaign-emails.d.ts +32 -0
- package/src/lib/components/use-contact-campaign-emails.js +83 -0
- package/src/lib/components/use-contact-campaign-emails.js.map +1 -0
- package/src/lib/components/use-crm-api.d.ts +44 -0
- package/src/lib/components/use-crm-api.js +84 -0
- package/src/lib/components/use-crm-api.js.map +1 -0
- package/src/lib/components/use-crm-inbound-address.d.ts +60 -0
- package/src/lib/components/use-crm-inbound-address.js +124 -0
- package/src/lib/components/use-crm-inbound-address.js.map +1 -0
- package/src/lib/components/use-emails-hub-path.d.ts +24 -0
- package/src/lib/components/use-emails-hub-path.js +59 -0
- package/src/lib/components/use-emails-hub-path.js.map +1 -0
- package/src/lib/components/use-member-email-aliases.d.ts +54 -0
- package/src/lib/components/use-member-email-aliases.js +186 -0
- package/src/lib/components/use-member-email-aliases.js.map +1 -0
- package/src/lib/components/use-org-members.d.ts +40 -0
- package/src/lib/components/use-org-members.js +100 -0
- package/src/lib/components/use-org-members.js.map +1 -0
- package/src/lib/constants/api-routes.d.ts +109 -0
- package/src/lib/constants/api-routes.js +74 -0
- package/src/lib/constants/api-routes.js.map +1 -0
- package/src/lib/constants/bundle-common.d.ts +14 -0
- package/src/lib/constants/bundle-common.js +14 -0
- package/src/lib/constants/bundle-common.js.map +1 -0
- package/src/lib/constants/company-filters.d.ts +18 -0
- package/src/lib/constants/company-filters.js +51 -0
- package/src/lib/constants/company-filters.js.map +1 -0
- package/src/lib/constants/contact-filters.d.ts +38 -0
- package/src/lib/constants/contact-filters.js +294 -0
- package/src/lib/constants/contact-filters.js.map +1 -0
- package/src/lib/hooks/use-contact-field-definitions.d.ts +48 -0
- package/src/lib/hooks/use-contact-field-definitions.js +72 -0
- package/src/lib/hooks/use-contact-field-definitions.js.map +1 -0
- package/src/lib/hooks/use-contact-update.d.ts +25 -0
- package/src/lib/hooks/use-contact-update.js +80 -0
- package/src/lib/hooks/use-contact-update.js.map +1 -0
- package/src/lib/hooks/use-crm-activity-logger.d.ts +73 -0
- package/src/lib/hooks/use-crm-activity-logger.js +101 -0
- package/src/lib/hooks/use-crm-activity-logger.js.map +1 -0
- package/src/lib/hooks/use-crm-bulk-apply.d.ts +52 -0
- package/src/lib/hooks/use-crm-bulk-apply.js +112 -0
- package/src/lib/hooks/use-crm-bulk-apply.js.map +1 -0
- package/src/lib/hooks/use-crm-default-view.d.ts +24 -0
- package/src/lib/hooks/use-crm-default-view.js +64 -0
- package/src/lib/hooks/use-crm-default-view.js.map +1 -0
- package/src/lib/hooks/use-crm-email-templates.d.ts +59 -0
- package/src/lib/hooks/use-crm-email-templates.js +103 -0
- package/src/lib/hooks/use-crm-email-templates.js.map +1 -0
- package/src/lib/hooks/use-crm-hub-path.d.ts +29 -0
- package/src/lib/hooks/use-crm-hub-path.js +41 -0
- package/src/lib/hooks/use-crm-hub-path.js.map +1 -0
- package/src/lib/hooks/use-crm-org-mount.d.ts +97 -0
- package/src/lib/hooks/use-crm-org-mount.js +215 -0
- package/src/lib/hooks/use-crm-org-mount.js.map +1 -0
- package/src/lib/hooks/use-crm-record-names.d.ts +52 -0
- package/src/lib/hooks/use-crm-record-names.js +126 -0
- package/src/lib/hooks/use-crm-record-names.js.map +1 -0
- package/src/lib/hooks/use-crm-records-quota.d.ts +68 -0
- package/src/lib/hooks/use-crm-records-quota.js +118 -0
- package/src/lib/hooks/use-crm-records-quota.js.map +1 -0
- package/src/lib/hooks/use-crm-saved-view.d.ts +96 -0
- package/src/lib/hooks/use-crm-saved-view.js +329 -0
- package/src/lib/hooks/use-crm-saved-view.js.map +1 -0
- package/src/lib/hooks/use-crm-scope.d.ts +117 -0
- package/src/lib/hooks/use-crm-scope.js +147 -0
- package/src/lib/hooks/use-crm-scope.js.map +1 -0
- package/src/lib/hooks/use-crm-tasks.d.ts +85 -0
- package/src/lib/hooks/use-crm-tasks.js +153 -0
- package/src/lib/hooks/use-crm-tasks.js.map +1 -0
- package/src/lib/hooks/use-crm-view-grid.d.ts +55 -0
- package/src/lib/hooks/use-crm-view-grid.js +170 -0
- package/src/lib/hooks/use-crm-view-grid.js.map +1 -0
- package/src/lib/hooks/use-crm-views.d.ts +42 -0
- package/src/lib/hooks/use-crm-views.js +84 -0
- package/src/lib/hooks/use-crm-views.js.map +1 -0
- package/src/lib/hooks/use-deal-stage-api.d.ts +69 -0
- package/src/lib/hooks/use-deal-stage-api.js +78 -0
- package/src/lib/hooks/use-deal-stage-api.js.map +1 -0
- package/src/lib/hooks/use-deals.d.ts +47 -0
- package/src/lib/hooks/use-deals.js +105 -0
- package/src/lib/hooks/use-deals.js.map +1 -0
- package/src/lib/hooks/use-org-leads.d.ts +53 -0
- package/src/lib/hooks/use-org-leads.js +114 -0
- package/src/lib/hooks/use-org-leads.js.map +1 -0
- package/src/lib/hooks/use-org-member-directory.d.ts +36 -0
- package/src/lib/hooks/use-org-member-directory.js +116 -0
- package/src/lib/hooks/use-org-member-directory.js.map +1 -0
- package/src/lib/hooks/use-org-member-options.d.ts +38 -0
- package/src/lib/hooks/use-org-member-options.js +131 -0
- package/src/lib/hooks/use-org-member-options.js.map +1 -0
- package/src/lib/hooks/use-pipeline.d.ts +71 -0
- package/src/lib/hooks/use-pipeline.js +159 -0
- package/src/lib/hooks/use-pipeline.js.map +1 -0
- package/src/lib/model/companies-bulk-writes.d.ts +40 -0
- package/src/lib/model/companies-bulk-writes.js +103 -0
- package/src/lib/model/companies-bulk-writes.js.map +1 -0
- package/src/lib/model/companies-csv.d.ts +36 -0
- package/src/lib/model/companies-csv.js +38 -0
- package/src/lib/model/companies-csv.js.map +1 -0
- package/src/lib/model/companies.d.ts +99 -0
- package/src/lib/model/companies.js +168 -0
- package/src/lib/model/companies.js.map +1 -0
- package/src/lib/model/company-delete-route.d.ts +43 -0
- package/src/lib/model/company-delete-route.js +31 -0
- package/src/lib/model/company-delete-route.js.map +1 -0
- package/src/lib/model/company-delete.d.ts +42 -0
- package/src/lib/model/company-delete.js +52 -0
- package/src/lib/model/company-delete.js.map +1 -0
- package/src/lib/model/contact-duplicates.d.ts +58 -0
- package/src/lib/model/contact-duplicates.js +67 -0
- package/src/lib/model/contact-duplicates.js.map +1 -0
- package/src/lib/model/contact-record.d.ts +113 -0
- package/src/lib/model/contact-record.js +70 -0
- package/src/lib/model/contact-record.js.map +1 -0
- package/src/lib/model/contact-update.d.ts +93 -0
- package/src/lib/model/contact-update.js +50 -0
- package/src/lib/model/contact-update.js.map +1 -0
- package/src/lib/model/contacts-bulk-writes.d.ts +173 -0
- package/src/lib/model/contacts-bulk-writes.js +196 -0
- package/src/lib/model/contacts-bulk-writes.js.map +1 -0
- package/src/lib/model/contacts-csv.d.ts +54 -0
- package/src/lib/model/contacts-csv.js +67 -0
- package/src/lib/model/contacts-csv.js.map +1 -0
- package/src/lib/model/contacts-list-seed.d.ts +51 -0
- package/src/lib/model/contacts-list-seed.js +63 -0
- package/src/lib/model/contacts-list-seed.js.map +1 -0
- package/src/lib/model/crm-activity-report.d.ts +27 -0
- package/src/lib/model/crm-activity-report.js +56 -0
- package/src/lib/model/crm-activity-report.js.map +1 -0
- package/src/lib/model/crm-api.d.ts +49 -0
- package/src/lib/model/crm-api.js +47 -0
- package/src/lib/model/crm-api.js.map +1 -0
- package/src/lib/model/crm-bulk-writes.d.ts +147 -0
- package/src/lib/model/crm-bulk-writes.js +207 -0
- package/src/lib/model/crm-bulk-writes.js.map +1 -0
- package/src/lib/model/crm-company-import.d.ts +154 -0
- package/src/lib/model/crm-company-import.js +331 -0
- package/src/lib/model/crm-company-import.js.map +1 -0
- package/src/lib/model/crm-custom-draft.d.ts +62 -0
- package/src/lib/model/crm-custom-draft.js +67 -0
- package/src/lib/model/crm-custom-draft.js.map +1 -0
- package/src/lib/model/crm-deal-import.d.ts +112 -0
- package/src/lib/model/crm-deal-import.js +263 -0
- package/src/lib/model/crm-deal-import.js.map +1 -0
- package/src/lib/model/crm-import.d.ts +244 -0
- package/src/lib/model/crm-import.js +466 -0
- package/src/lib/model/crm-import.js.map +1 -0
- package/src/lib/model/crm-lead-import.d.ts +105 -0
- package/src/lib/model/crm-lead-import.js +255 -0
- package/src/lib/model/crm-lead-import.js.map +1 -0
- package/src/lib/model/crm-record-routes.d.ts +21 -0
- package/src/lib/model/crm-record-routes.js +70 -0
- package/src/lib/model/crm-record-routes.js.map +1 -0
- package/src/lib/model/crm-routes.d.ts +101 -0
- package/src/lib/model/crm-routes.js +92 -0
- package/src/lib/model/crm-routes.js.map +1 -0
- package/src/lib/model/crm-task-import.d.ts +94 -0
- package/src/lib/model/crm-task-import.js +275 -0
- package/src/lib/model/crm-task-import.js.map +1 -0
- package/src/lib/model/crm-view-param.d.ts +43 -0
- package/src/lib/model/crm-view-param.js +49 -0
- package/src/lib/model/crm-view-param.js.map +1 -0
- package/src/lib/model/deal-board-model.d.ts +241 -0
- package/src/lib/model/deal-board-model.js +439 -0
- package/src/lib/model/deal-board-model.js.map +1 -0
- package/src/lib/model/deal-form-model.d.ts +114 -0
- package/src/lib/model/deal-form-model.js +218 -0
- package/src/lib/model/deal-form-model.js.map +1 -0
- package/src/lib/model/deals-csv.d.ts +32 -0
- package/src/lib/model/deals-csv.js +37 -0
- package/src/lib/model/deals-csv.js.map +1 -0
- package/src/lib/model/import-column-shapes.d.ts +36 -0
- package/src/lib/model/import-column-shapes.js +76 -0
- package/src/lib/model/import-column-shapes.js.map +1 -0
- package/src/lib/model/lead-company-suggestion.d.ts +61 -0
- package/src/lib/model/lead-company-suggestion.js +65 -0
- package/src/lib/model/lead-company-suggestion.js.map +1 -0
- package/src/lib/model/lead-filters.d.ts +29 -0
- package/src/lib/model/lead-filters.js +39 -0
- package/src/lib/model/lead-filters.js.map +1 -0
- package/src/lib/model/lead-surfaces.d.ts +58 -0
- package/src/lib/model/lead-surfaces.js +67 -0
- package/src/lib/model/lead-surfaces.js.map +1 -0
- package/src/lib/model/leads-csv.d.ts +40 -0
- package/src/lib/model/leads-csv.js +40 -0
- package/src/lib/model/leads-csv.js.map +1 -0
- package/src/lib/model/next-activity-api.d.ts +31 -0
- package/src/lib/model/next-activity-api.js +57 -0
- package/src/lib/model/next-activity-api.js.map +1 -0
- package/src/lib/model/next-activity.d.ts +64 -0
- package/src/lib/model/next-activity.js +47 -0
- package/src/lib/model/next-activity.js.map +1 -0
- package/src/lib/model/person-key-web.d.ts +43 -0
- package/src/lib/model/person-key-web.js +52 -0
- package/src/lib/model/person-key-web.js.map +1 -0
- package/src/lib/model/record-facts.d.ts +282 -0
- package/src/lib/model/record-facts.js +434 -0
- package/src/lib/model/record-facts.js.map +1 -0
- package/src/lib/model/task-api.d.ts +28 -0
- package/src/lib/model/task-api.js +57 -0
- package/src/lib/model/task-api.js.map +1 -0
- package/src/lib/model/task-calendar.d.ts +108 -0
- package/src/lib/model/task-calendar.js +139 -0
- package/src/lib/model/task-calendar.js.map +1 -0
- package/src/lib/model/task-routes.d.ts +177 -0
- package/src/lib/model/task-routes.js +197 -0
- package/src/lib/model/task-routes.js.map +1 -0
- package/src/lib/model/task-scope.d.ts +45 -0
- package/src/lib/model/task-scope.js +51 -0
- package/src/lib/model/task-scope.js.map +1 -0
- package/src/lib/model/task-views.d.ts +149 -0
- package/src/lib/model/task-views.js +286 -0
- package/src/lib/model/task-views.js.map +1 -0
- package/src/lib/model/tasks-csv.d.ts +28 -0
- package/src/lib/model/tasks-csv.js +28 -0
- package/src/lib/model/tasks-csv.js.map +1 -0
- package/src/lib/plugin.d.ts +32 -0
- package/src/lib/plugin.js +208 -0
- package/src/lib/plugin.js.map +1 -0
- package/src/lib/server/companies-import.d.ts +57 -0
- package/src/lib/server/companies-import.js +242 -0
- package/src/lib/server/companies-import.js.map +1 -0
- package/src/lib/server/company-delete.d.ts +59 -0
- package/src/lib/server/company-delete.js +146 -0
- package/src/lib/server/company-delete.js.map +1 -0
- package/src/lib/server/contact-email-history.d.ts +82 -0
- package/src/lib/server/contact-email-history.js +264 -0
- package/src/lib/server/contact-email-history.js.map +1 -0
- package/src/lib/server/contact-profile.d.ts +41 -0
- package/src/lib/server/contact-profile.js +45 -0
- package/src/lib/server/contact-profile.js.map +1 -0
- package/src/lib/server/contact-update.d.ts +92 -0
- package/src/lib/server/contact-update.js +512 -0
- package/src/lib/server/contact-update.js.map +1 -0
- package/src/lib/server/contacts-import.d.ts +73 -0
- package/src/lib/server/contacts-import.js +263 -0
- package/src/lib/server/contacts-import.js.map +1 -0
- package/src/lib/server/contacts-merge.d.ts +86 -0
- package/src/lib/server/contacts-merge.js +206 -0
- package/src/lib/server/contacts-merge.js.map +1 -0
- package/src/lib/server/deals-import.d.ts +76 -0
- package/src/lib/server/deals-import.js +246 -0
- package/src/lib/server/deals-import.js.map +1 -0
- package/src/lib/server/email-send.d.ts +119 -0
- package/src/lib/server/email-send.js +667 -0
- package/src/lib/server/email-send.js.map +1 -0
- package/src/lib/server/email-template-duplicate.d.ts +19 -0
- package/src/lib/server/email-template-duplicate.js +206 -0
- package/src/lib/server/email-template-duplicate.js.map +1 -0
- package/src/lib/server/erase-person.d.ts +108 -0
- package/src/lib/server/erase-person.js +309 -0
- package/src/lib/server/erase-person.js.map +1 -0
- package/src/lib/server/import-context.d.ts +85 -0
- package/src/lib/server/import-context.js +181 -0
- package/src/lib/server/import-context.js.map +1 -0
- package/src/lib/server/inbound-address.d.ts +61 -0
- package/src/lib/server/inbound-address.js +188 -0
- package/src/lib/server/inbound-address.js.map +1 -0
- package/src/lib/server/lead-convert.d.ts +78 -0
- package/src/lib/server/lead-convert.js +250 -0
- package/src/lib/server/lead-convert.js.map +1 -0
- package/src/lib/server/leads-import.d.ts +84 -0
- package/src/lib/server/leads-import.js +261 -0
- package/src/lib/server/leads-import.js.map +1 -0
- package/src/lib/server/next-activity-routes.d.ts +33 -0
- package/src/lib/server/next-activity-routes.js +110 -0
- package/src/lib/server/next-activity-routes.js.map +1 -0
- package/src/lib/server/org-activity.d.ts +61 -0
- package/src/lib/server/org-activity.js +120 -0
- package/src/lib/server/org-activity.js.map +1 -0
- package/src/lib/server/org-caller.d.ts +110 -0
- package/src/lib/server/org-caller.js +154 -0
- package/src/lib/server/org-caller.js.map +1 -0
- package/src/lib/server/recipe-routes.d.ts +75 -0
- package/src/lib/server/recipe-routes.js +442 -0
- package/src/lib/server/recipe-routes.js.map +1 -0
- package/src/lib/server/record-facts.d.ts +65 -0
- package/src/lib/server/record-facts.js +337 -0
- package/src/lib/server/record-facts.js.map +1 -0
- package/src/lib/server/record-timeline.d.ts +51 -0
- package/src/lib/server/record-timeline.js +215 -0
- package/src/lib/server/record-timeline.js.map +1 -0
- package/src/lib/server/suite-gate.d.ts +42 -0
- package/src/lib/server/suite-gate.js +87 -0
- package/src/lib/server/suite-gate.js.map +1 -0
- package/src/lib/server/task-routes.d.ts +132 -0
- package/src/lib/server/task-routes.js +699 -0
- package/src/lib/server/task-routes.js.map +1 -0
- package/src/lib/server/tasks-import.d.ts +54 -0
- package/src/lib/server/tasks-import.js +157 -0
- package/src/lib/server/tasks-import.js.map +1 -0
- package/src/lib/server-deal-stage.d.ts +88 -0
- package/src/lib/server-deal-stage.js +316 -0
- package/src/lib/server-deal-stage.js.map +1 -0
- package/src/lib/server.d.ts +149 -0
- package/src/lib/server.js +615 -0
- package/src/lib/server.js.map +1 -0
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
export declare function reportDroppedActivityLine(error: unknown): void;
|
|
18
|
+
/**
|
|
19
|
+
* A refusal the route ANSWERED rather than threw.
|
|
20
|
+
*
|
|
21
|
+
* `authorizedFetch` resolves for a 403 as readily as for a 200, so a line
|
|
22
|
+
* the route declined to write comes back through the success path. Turning
|
|
23
|
+
* it into an error is what puts it on the same reporting road as a network
|
|
24
|
+
* failure — without this, the one outcome the reporting exists to catch is
|
|
25
|
+
* the one that leaves no trace.
|
|
26
|
+
*/
|
|
27
|
+
export declare function orgActivityRefusal(status: number, payload: Record<string, unknown>): Error;
|
|
@@ -0,0 +1,56 @@
|
|
|
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
|
+
* WHAT A DROPPED CRM ACTIVITY LINE DOES INSTEAD OF NOTHING (AGL-2738).
|
|
18
|
+
*
|
|
19
|
+
* Every CRM feed append is fire-and-forget on both sides of the hub — an
|
|
20
|
+
* audit miss must never turn a finished save into a failed one, and a
|
|
21
|
+
* snackbar about the LOG is a worse answer to "your record saved" than
|
|
22
|
+
* silence. But a line that can only fail silently is a feature that stays
|
|
23
|
+
* broken for months without a single signal, so a drop leaves by the two
|
|
24
|
+
* doors `useHostActivityLogger` already opens for a refused client-direct
|
|
25
|
+
* append, and for the same reasons: the beacon reaches Cloud Error
|
|
26
|
+
* Reporting and dedupes a failure that repeats on every edit into one
|
|
27
|
+
* report, and the console line fires once for whoever has devtools open.
|
|
28
|
+
*
|
|
29
|
+
* A module of its own, and not a hook: the bulk bars' hook and the record
|
|
30
|
+
* surfaces' both report through it, and only one of them has any business
|
|
31
|
+
* pulling in the tenant runtime.
|
|
32
|
+
*/ import { reportHandledError } from "@aglyn/aglyn/app-utils/error-beacon";
|
|
33
|
+
/** One console line per session, however many lines are dropped. */ let announced = false;
|
|
34
|
+
export function reportDroppedActivityLine(error) {
|
|
35
|
+
reportHandledError(error, {
|
|
36
|
+
kind: 'crm-activity-write'
|
|
37
|
+
});
|
|
38
|
+
if (announced) return;
|
|
39
|
+
announced = true;
|
|
40
|
+
console.error('CRM activity logging failed; lines from this session are being dropped.', error);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A refusal the route ANSWERED rather than threw.
|
|
44
|
+
*
|
|
45
|
+
* `authorizedFetch` resolves for a 403 as readily as for a 200, so a line
|
|
46
|
+
* the route declined to write comes back through the success path. Turning
|
|
47
|
+
* it into an error is what puts it on the same reporting road as a network
|
|
48
|
+
* failure — without this, the one outcome the reporting exists to catch is
|
|
49
|
+
* the one that leaves no trace.
|
|
50
|
+
*/ export function orgActivityRefusal(status, payload) {
|
|
51
|
+
var _payload_error;
|
|
52
|
+
const said = String((_payload_error = payload['error']) != null ? _payload_error : '').slice(0, 200);
|
|
53
|
+
return new Error(`crm/org-activity refused the line (${status})${said ? `: ${said}` : ''}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=crm-activity-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/model/crm-activity-report.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * WHAT A DROPPED CRM ACTIVITY LINE DOES INSTEAD OF NOTHING (AGL-2738).\n *\n * Every CRM feed append is fire-and-forget on both sides of the hub — an\n * audit miss must never turn a finished save into a failed one, and a\n * snackbar about the LOG is a worse answer to \"your record saved\" than\n * silence. But a line that can only fail silently is a feature that stays\n * broken for months without a single signal, so a drop leaves by the two\n * doors `useHostActivityLogger` already opens for a refused client-direct\n * append, and for the same reasons: the beacon reaches Cloud Error\n * Reporting and dedupes a failure that repeats on every edit into one\n * report, and the console line fires once for whoever has devtools open.\n *\n * A module of its own, and not a hook: the bulk bars' hook and the record\n * surfaces' both report through it, and only one of them has any business\n * pulling in the tenant runtime.\n */\n\nimport { reportHandledError } from '@aglyn/aglyn/app-utils/error-beacon'\n\n/** One console line per session, however many lines are dropped. */\nlet announced = false\n\nexport function reportDroppedActivityLine(error: unknown): void {\n reportHandledError(error, { kind: 'crm-activity-write' })\n if (announced) return\n announced = true\n console.error(\n 'CRM activity logging failed; lines from this session are being dropped.',\n error,\n )\n}\n\n/**\n * A refusal the route ANSWERED rather than threw.\n *\n * `authorizedFetch` resolves for a 403 as readily as for a 200, so a line\n * the route declined to write comes back through the success path. Turning\n * it into an error is what puts it on the same reporting road as a network\n * failure — without this, the one outcome the reporting exists to catch is\n * the one that leaves no trace.\n */\nexport function orgActivityRefusal(\n status: number,\n payload: Record<string, unknown>,\n): Error {\n const said = String(payload['error'] ?? '').slice(0, 200)\n return new Error(\n `crm/org-activity refused the line (${status})${said ? `: ${said}` : ''}`,\n )\n}\n"],"names":["reportHandledError","announced","reportDroppedActivityLine","error","kind","console","orgActivityRefusal","status","payload","said","String","slice","Error"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;CAgBC,GAED,SAASA,kBAAkB,QAAQ,sCAAqC;AAExE,kEAAkE,GAClE,IAAIC,YAAY;AAEhB,OAAO,SAASC,0BAA0BC,KAAc;IACtDH,mBAAmBG,OAAO;QAAEC,MAAM;IAAqB;IACvD,IAAIH,WAAW;IACfA,YAAY;IACZI,QAAQF,KAAK,CACX,2EACAA;AAEJ;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASG,mBACdC,MAAc,EACdC,OAAgC;QAEZA;IAApB,MAAMC,OAAOC,QAAOF,iBAAAA,OAAO,CAAC,QAAQ,YAAhBA,iBAAoB,IAAIG,KAAK,CAAC,GAAG;IACrD,OAAO,IAAIC,MACT,CAAC,mCAAmC,EAAEL,OAAO,CAAC,EAAEE,OAAO,CAAC,EAAE,EAAEA,MAAM,GAAG,IAAI;AAE7E"}
|
|
@@ -0,0 +1,49 @@
|
|
|
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 { ContactLifecycleStage } from '@aglyn/aglyn';
|
|
18
|
+
import { type MaybeTokenSource } from '@aglyn/shared-util-http/authorized-token';
|
|
19
|
+
/**
|
|
20
|
+
* The console's client half of the CRM server routes (AGL-2605).
|
|
21
|
+
*
|
|
22
|
+
* A stage change goes through the server rather than a client-direct
|
|
23
|
+
* Firestore write, and the reason is the event: `contactStageChanged` can
|
|
24
|
+
* only be emitted by a server path that performed the write, so a record
|
|
25
|
+
* page that wrote the facet itself would move the person and tell no
|
|
26
|
+
* automation. A CLEAR comes the same way (AGL-2804), because a facet is the
|
|
27
|
+
* server's to write. This is the one function a stage control calls.
|
|
28
|
+
*/
|
|
29
|
+
/** What `crm/contact-stage` answers. */
|
|
30
|
+
export interface ContactStageResult {
|
|
31
|
+
ok: true;
|
|
32
|
+
/** False when the contact was already in that stage — nothing moved. */
|
|
33
|
+
changed: boolean;
|
|
34
|
+
/** The stage the contact now holds, `''` after a clear. */
|
|
35
|
+
lifecycleStage: ContactLifecycleStage | '';
|
|
36
|
+
/** The stage before the move, `''` when the contact had none. */
|
|
37
|
+
previousStage: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Moves one contact to a lifecycle stage — or, with `null`, clears it — as
|
|
41
|
+
* the signed-in user.
|
|
42
|
+
*
|
|
43
|
+
* Throws with the route's own message on a refusal, so a control can show
|
|
44
|
+
* "Not a site admin or editor" rather than a generic failure; a network
|
|
45
|
+
* failure throws as `fetch` would.
|
|
46
|
+
*/
|
|
47
|
+
export declare function setContactStage(user: MaybeTokenSource, hostId: string, contactId: string, stage: ContactLifecycleStage | null, options?: {
|
|
48
|
+
fetchImpl?: typeof fetch;
|
|
49
|
+
}): Promise<ContactStageResult>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
|
|
17
|
+
import { crmApiUrl } from "../constants/api-routes.js";
|
|
18
|
+
/**
|
|
19
|
+
* Moves one contact to a lifecycle stage — or, with `null`, clears it — as
|
|
20
|
+
* the signed-in user.
|
|
21
|
+
*
|
|
22
|
+
* Throws with the route's own message on a refusal, so a control can show
|
|
23
|
+
* "Not a site admin or editor" rather than a generic failure; a network
|
|
24
|
+
* failure throws as `fetch` would.
|
|
25
|
+
*/ export async function setContactStage(user, hostId, contactId, stage, options = {}) {
|
|
26
|
+
const response = await authorizedFetch(user, crmApiUrl('contactStage'), {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
headers: {
|
|
29
|
+
'Content-Type': 'application/json'
|
|
30
|
+
},
|
|
31
|
+
body: JSON.stringify({
|
|
32
|
+
hostId,
|
|
33
|
+
contactId,
|
|
34
|
+
lifecycleStage: stage
|
|
35
|
+
})
|
|
36
|
+
}, options.fetchImpl ? {
|
|
37
|
+
fetchImpl: options.fetchImpl
|
|
38
|
+
} : {});
|
|
39
|
+
const payload = await response.json().catch(()=>({}));
|
|
40
|
+
if (!response.ok) {
|
|
41
|
+
var _payload_error;
|
|
42
|
+
throw new Error((_payload_error = payload.error) != null ? _payload_error : 'The stage could not be changed');
|
|
43
|
+
}
|
|
44
|
+
return payload;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=crm-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/model/crm-api.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ContactLifecycleStage } from '@aglyn/aglyn'\nimport {\n authorizedFetch,\n type MaybeTokenSource,\n} from '@aglyn/shared-util-http/authorized-token'\nimport { crmApiUrl } from '../constants/api-routes'\n\n/**\n * The console's client half of the CRM server routes (AGL-2605).\n *\n * A stage change goes through the server rather than a client-direct\n * Firestore write, and the reason is the event: `contactStageChanged` can\n * only be emitted by a server path that performed the write, so a record\n * page that wrote the facet itself would move the person and tell no\n * automation. A CLEAR comes the same way (AGL-2804), because a facet is the\n * server's to write. This is the one function a stage control calls.\n */\n\n/** What `crm/contact-stage` answers. */\nexport interface ContactStageResult {\n ok: true\n /** False when the contact was already in that stage — nothing moved. */\n changed: boolean\n /** The stage the contact now holds, `''` after a clear. */\n lifecycleStage: ContactLifecycleStage | ''\n /** The stage before the move, `''` when the contact had none. */\n previousStage: string\n}\n\n/**\n * Moves one contact to a lifecycle stage — or, with `null`, clears it — as\n * the signed-in user.\n *\n * Throws with the route's own message on a refusal, so a control can show\n * \"Not a site admin or editor\" rather than a generic failure; a network\n * failure throws as `fetch` would.\n */\nexport async function setContactStage(\n user: MaybeTokenSource,\n hostId: string,\n contactId: string,\n stage: ContactLifecycleStage | null,\n options: { fetchImpl?: typeof fetch } = {},\n): Promise<ContactStageResult> {\n const response = await authorizedFetch(\n user,\n crmApiUrl('contactStage'),\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ hostId, contactId, lifecycleStage: stage }),\n },\n options.fetchImpl ? { fetchImpl: options.fetchImpl } : {},\n )\n const payload = (await response.json().catch(() => ({}))) as\n | ContactStageResult\n | { error?: string }\n if (!response.ok) {\n throw new Error(\n (payload as { error?: string }).error ?? 'The stage could not be changed',\n )\n }\n return payload as ContactStageResult\n}\n"],"names":["authorizedFetch","crmApiUrl","setContactStage","user","hostId","contactId","stage","options","response","method","headers","body","JSON","stringify","lifecycleStage","fetchImpl","payload","json","catch","ok","Error","error"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAGD,SACEA,eAAe,QAEV,2CAA0C;AACjD,SAASC,SAAS,QAAQ,6BAAyB;AAwBnD;;;;;;;CAOC,GACD,OAAO,eAAeC,gBACpBC,IAAsB,EACtBC,MAAc,EACdC,SAAiB,EACjBC,KAAmC,EACnCC,UAAwC,CAAC,CAAC;IAE1C,MAAMC,WAAW,MAAMR,gBACrBG,MACAF,UAAU,iBACV;QACEQ,QAAQ;QACRC,SAAS;YAAE,gBAAgB;QAAmB;QAC9CC,MAAMC,KAAKC,SAAS,CAAC;YAAET;YAAQC;YAAWS,gBAAgBR;QAAM;IAClE,GACAC,QAAQQ,SAAS,GAAG;QAAEA,WAAWR,QAAQQ,SAAS;IAAC,IAAI,CAAC;IAE1D,MAAMC,UAAW,MAAMR,SAASS,IAAI,GAAGC,KAAK,CAAC,IAAO,CAAA,CAAC,CAAA;IAGrD,IAAI,CAACV,SAASW,EAAE,EAAE;YAEd;QADF,MAAM,IAAIC,OACR,iBAAA,AAACJ,QAA+BK,KAAK,YAArC,iBAAyC;IAE7C;IACA,OAAOL;AACT"}
|
|
@@ -0,0 +1,147 @@
|
|
|
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
|
+
* HOW A BULK ACTION IS APPLIED, whichever CRM collection it is over
|
|
19
|
+
* (AGL-2621).
|
|
20
|
+
*
|
|
21
|
+
* The contacts bar settled the shape (AGL-2603): one act over many rows is
|
|
22
|
+
* a PLAN of per-row writes, applied in batches with a per-row fallback, and
|
|
23
|
+
* whatever the store refused comes back NAMED — by the address, the company,
|
|
24
|
+
* the deal's title — never as a count. Companies, deals and tasks each have
|
|
25
|
+
* a bar now, and each bar's runner would be the same forty lines with a
|
|
26
|
+
* different noun. So the runner lives here once, parametric over what a
|
|
27
|
+
* write is called, and `contacts-bulk-writes.ts` stands on it under the
|
|
28
|
+
* names it always exported.
|
|
29
|
+
*
|
|
30
|
+
* ## Two kinds of act
|
|
31
|
+
*
|
|
32
|
+
* A write to the document — an owner, a tag, a due date, a delete — goes
|
|
33
|
+
* through {@link runCrmBulkWrites}: batched, and re-applied row by row when a
|
|
34
|
+
* batch fails, because a batch that fails names no row. An act with a side
|
|
35
|
+
* effect outside the document — a deal's stage, a task's completion, an
|
|
36
|
+
* assignment that notifies — goes through its ROUTE, one request per row, and
|
|
37
|
+
* {@link runCrmBulkCalls} is the same tally over those: each refusal is named
|
|
38
|
+
* by the row and carries the route's own sentence. A route that takes the
|
|
39
|
+
* whole selection at once and answers per row — the organization-level task
|
|
40
|
+
* routes (AGL-2637) — is tallied by {@link runCrmBulkBatch} from its answers.
|
|
41
|
+
*
|
|
42
|
+
* Pure apart from the Firestore SDK the writer factory binds: the runners
|
|
43
|
+
* take their writers as ports, so a spec wires a ledger in.
|
|
44
|
+
*/
|
|
45
|
+
import { type DocumentReference, type Firestore } from 'firebase/firestore';
|
|
46
|
+
/**
|
|
47
|
+
* The Firestore batch cap is 500 writes; 400 leaves room for the sentinel
|
|
48
|
+
* transforms a patch carries, which the cap counts as writes of their own.
|
|
49
|
+
* The same margin the datasets card keeps.
|
|
50
|
+
*/
|
|
51
|
+
export declare const CRM_BULK_WRITE_CHUNK = 400;
|
|
52
|
+
/**
|
|
53
|
+
* One write to one document, named for the report — the name a person
|
|
54
|
+
* recognizes the row by, which is what a refusal is listed under.
|
|
55
|
+
*/
|
|
56
|
+
export type CrmBulkWrite = {
|
|
57
|
+
id: string;
|
|
58
|
+
label: string;
|
|
59
|
+
} & ({
|
|
60
|
+
kind: 'update';
|
|
61
|
+
data: Record<string, unknown>;
|
|
62
|
+
} | {
|
|
63
|
+
kind: 'delete';
|
|
64
|
+
});
|
|
65
|
+
/** A row an action deliberately left alone, and why. */
|
|
66
|
+
export interface CrmBulkSkip {
|
|
67
|
+
label: string;
|
|
68
|
+
reason: string;
|
|
69
|
+
}
|
|
70
|
+
/** What one action wants written, and what it declined to. */
|
|
71
|
+
export interface CrmBulkPlan<W = CrmBulkWrite> {
|
|
72
|
+
writes: W[];
|
|
73
|
+
skipped: CrmBulkSkip[];
|
|
74
|
+
}
|
|
75
|
+
/** The writers the runner needs — Firestore's, or a spec's ledger. */
|
|
76
|
+
export interface CrmBulkWriters<W> {
|
|
77
|
+
/** Apply every write atomically, or throw. */
|
|
78
|
+
commitBatch: (writes: readonly W[]) => Promise<void>;
|
|
79
|
+
/** Apply one write, or throw. */
|
|
80
|
+
commitOne: (write: W) => Promise<void>;
|
|
81
|
+
}
|
|
82
|
+
export interface CrmBulkOutcome {
|
|
83
|
+
/** Rows written, or requests answered. */
|
|
84
|
+
done: number;
|
|
85
|
+
/** Rows the store or the route refused, by label, with the reason given. */
|
|
86
|
+
refused: Array<{
|
|
87
|
+
label: string;
|
|
88
|
+
error: string;
|
|
89
|
+
}>;
|
|
90
|
+
}
|
|
91
|
+
export declare function chunked<T>(items: readonly T[], size: number): T[][];
|
|
92
|
+
/** Whatever the store or the route threw, as one sentence a report can carry. */
|
|
93
|
+
export declare function bulkRefusalReason(error: unknown): string;
|
|
94
|
+
/**
|
|
95
|
+
* Apply the writes in chunks, and re-apply a failed chunk row by row.
|
|
96
|
+
*
|
|
97
|
+
* The batch is the fast path and the common one: four hundred patches in
|
|
98
|
+
* one round trip. The fallback is the honest one: a batch that fails names
|
|
99
|
+
* no row, so the only way to say WHICH of four hundred was refused is to
|
|
100
|
+
* ask about each. The chunk that failed is the only one that pays for that;
|
|
101
|
+
* the others commit as batches.
|
|
102
|
+
*/
|
|
103
|
+
export declare function runCrmBulkWrites<W>(writers: CrmBulkWriters<W>, writes: readonly W[], labelOf: (write: W) => string, chunkSize?: number): Promise<CrmBulkOutcome>;
|
|
104
|
+
/**
|
|
105
|
+
* One request per row, in order, tallied the same way.
|
|
106
|
+
*
|
|
107
|
+
* In ORDER rather than in parallel: the routes these calls reach each
|
|
108
|
+
* verify a session, resolve a membership and emit an event, and two hundred
|
|
109
|
+
* of them fired at once is a burst the console's request budget is not
|
|
110
|
+
* sized for. A refusal carries the route's own sentence, which is written
|
|
111
|
+
* for the person reading it.
|
|
112
|
+
*/
|
|
113
|
+
export declare function runCrmBulkCalls<T>(items: readonly T[], labelOf: (item: T) => string, call: (item: T) => Promise<unknown>): Promise<CrmBulkOutcome>;
|
|
114
|
+
/** What a batch route answers for one row: written, or refused with a sentence. */
|
|
115
|
+
export interface CrmBulkAnswer {
|
|
116
|
+
id: string;
|
|
117
|
+
ok: boolean;
|
|
118
|
+
error?: string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* One request for the whole selection, answered per row (AGL-2637).
|
|
122
|
+
*
|
|
123
|
+
* The tally is read off the answers rather than off N calls, in the rows'
|
|
124
|
+
* own order. A row the answer does not mention was not written — a route
|
|
125
|
+
* that dropped it silently would otherwise read as success — and is refused
|
|
126
|
+
* by name. A request refused WHOLE (no session, no reach over the org) is
|
|
127
|
+
* every row it carried refused with the route's one sentence, which is what
|
|
128
|
+
* the same selection through {@link runCrmBulkCalls} would have said N times.
|
|
129
|
+
*
|
|
130
|
+
* A route that caps how many rows one request names takes the selection in
|
|
131
|
+
* pieces of `chunkSize`, one request after another; by default the whole
|
|
132
|
+
* selection is one request.
|
|
133
|
+
*/
|
|
134
|
+
export declare function runCrmBulkBatch<T>(items: readonly T[], idOf: (item: T) => string, labelOf: (item: T) => string, call: (items: readonly T[]) => Promise<readonly CrmBulkAnswer[]>, chunkSize?: number): Promise<CrmBulkOutcome>;
|
|
135
|
+
/**
|
|
136
|
+
* The Firestore writers for a collection whose bulk writes touch ONE
|
|
137
|
+
* document each — companies, deals, tasks. The contacts bar keeps its own
|
|
138
|
+
* pair, because a contact's company link moves a count on a second document
|
|
139
|
+
* and that count has to land in the same commit.
|
|
140
|
+
*/
|
|
141
|
+
export declare function crmBulkWriters(firestore: Firestore, refFor: (id: string) => DocumentReference): CrmBulkWriters<CrmBulkWrite>;
|
|
142
|
+
/**
|
|
143
|
+
* The report under a bar: what the plan skipped on purpose, then what the
|
|
144
|
+
* store refused, one line each, named. `null` when there is nothing to say,
|
|
145
|
+
* so the bar renders no empty alert.
|
|
146
|
+
*/
|
|
147
|
+
export declare function bulkReport(plan: Pick<CrmBulkPlan<unknown>, 'skipped'>, outcome: CrmBulkOutcome): CrmBulkSkip[] | null;
|
|
@@ -0,0 +1,207 @@
|
|
|
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
|
+
* HOW A BULK ACTION IS APPLIED, whichever CRM collection it is over
|
|
18
|
+
* (AGL-2621).
|
|
19
|
+
*
|
|
20
|
+
* The contacts bar settled the shape (AGL-2603): one act over many rows is
|
|
21
|
+
* a PLAN of per-row writes, applied in batches with a per-row fallback, and
|
|
22
|
+
* whatever the store refused comes back NAMED — by the address, the company,
|
|
23
|
+
* the deal's title — never as a count. Companies, deals and tasks each have
|
|
24
|
+
* a bar now, and each bar's runner would be the same forty lines with a
|
|
25
|
+
* different noun. So the runner lives here once, parametric over what a
|
|
26
|
+
* write is called, and `contacts-bulk-writes.ts` stands on it under the
|
|
27
|
+
* names it always exported.
|
|
28
|
+
*
|
|
29
|
+
* ## Two kinds of act
|
|
30
|
+
*
|
|
31
|
+
* A write to the document — an owner, a tag, a due date, a delete — goes
|
|
32
|
+
* through {@link runCrmBulkWrites}: batched, and re-applied row by row when a
|
|
33
|
+
* batch fails, because a batch that fails names no row. An act with a side
|
|
34
|
+
* effect outside the document — a deal's stage, a task's completion, an
|
|
35
|
+
* assignment that notifies — goes through its ROUTE, one request per row, and
|
|
36
|
+
* {@link runCrmBulkCalls} is the same tally over those: each refusal is named
|
|
37
|
+
* by the row and carries the route's own sentence. A route that takes the
|
|
38
|
+
* whole selection at once and answers per row — the organization-level task
|
|
39
|
+
* routes (AGL-2637) — is tallied by {@link runCrmBulkBatch} from its answers.
|
|
40
|
+
*
|
|
41
|
+
* Pure apart from the Firestore SDK the writer factory binds: the runners
|
|
42
|
+
* take their writers as ports, so a spec wires a ledger in.
|
|
43
|
+
*/ import { deleteDoc, updateDoc, writeBatch } from "firebase/firestore";
|
|
44
|
+
/**
|
|
45
|
+
* The Firestore batch cap is 500 writes; 400 leaves room for the sentinel
|
|
46
|
+
* transforms a patch carries, which the cap counts as writes of their own.
|
|
47
|
+
* The same margin the datasets card keeps.
|
|
48
|
+
*/ export const CRM_BULK_WRITE_CHUNK = 400;
|
|
49
|
+
export function chunked(items, size) {
|
|
50
|
+
const chunks = [];
|
|
51
|
+
for(let start = 0; start < items.length; start += size){
|
|
52
|
+
chunks.push(items.slice(start, start + size));
|
|
53
|
+
}
|
|
54
|
+
return chunks;
|
|
55
|
+
}
|
|
56
|
+
/** Whatever the store or the route threw, as one sentence a report can carry. */ export function bulkRefusalReason(error) {
|
|
57
|
+
const code = error == null ? void 0 : error.code;
|
|
58
|
+
if (code === 'permission-denied') return 'not permitted';
|
|
59
|
+
if (code === 'not-found') return 'no longer exists';
|
|
60
|
+
const message = error == null ? void 0 : error.message;
|
|
61
|
+
return typeof message === 'string' && message ? message : 'the write failed';
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Apply the writes in chunks, and re-apply a failed chunk row by row.
|
|
65
|
+
*
|
|
66
|
+
* The batch is the fast path and the common one: four hundred patches in
|
|
67
|
+
* one round trip. The fallback is the honest one: a batch that fails names
|
|
68
|
+
* no row, so the only way to say WHICH of four hundred was refused is to
|
|
69
|
+
* ask about each. The chunk that failed is the only one that pays for that;
|
|
70
|
+
* the others commit as batches.
|
|
71
|
+
*/ export async function runCrmBulkWrites(writers, writes, labelOf, chunkSize = CRM_BULK_WRITE_CHUNK) {
|
|
72
|
+
const outcome = {
|
|
73
|
+
done: 0,
|
|
74
|
+
refused: []
|
|
75
|
+
};
|
|
76
|
+
for (const chunk of chunked(writes, chunkSize)){
|
|
77
|
+
try {
|
|
78
|
+
await writers.commitBatch(chunk);
|
|
79
|
+
outcome.done += chunk.length;
|
|
80
|
+
continue;
|
|
81
|
+
} catch (unused) {
|
|
82
|
+
// Fall through to the per-row pass below.
|
|
83
|
+
}
|
|
84
|
+
for (const write of chunk){
|
|
85
|
+
try {
|
|
86
|
+
await writers.commitOne(write);
|
|
87
|
+
outcome.done += 1;
|
|
88
|
+
} catch (error) {
|
|
89
|
+
outcome.refused.push({
|
|
90
|
+
label: labelOf(write),
|
|
91
|
+
error: bulkRefusalReason(error)
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return outcome;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* One request per row, in order, tallied the same way.
|
|
100
|
+
*
|
|
101
|
+
* In ORDER rather than in parallel: the routes these calls reach each
|
|
102
|
+
* verify a session, resolve a membership and emit an event, and two hundred
|
|
103
|
+
* of them fired at once is a burst the console's request budget is not
|
|
104
|
+
* sized for. A refusal carries the route's own sentence, which is written
|
|
105
|
+
* for the person reading it.
|
|
106
|
+
*/ export async function runCrmBulkCalls(items, labelOf, call) {
|
|
107
|
+
const outcome = {
|
|
108
|
+
done: 0,
|
|
109
|
+
refused: []
|
|
110
|
+
};
|
|
111
|
+
for (const item of items){
|
|
112
|
+
try {
|
|
113
|
+
await call(item);
|
|
114
|
+
outcome.done += 1;
|
|
115
|
+
} catch (error) {
|
|
116
|
+
outcome.refused.push({
|
|
117
|
+
label: labelOf(item),
|
|
118
|
+
error: bulkRefusalReason(error)
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return outcome;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* One request for the whole selection, answered per row (AGL-2637).
|
|
126
|
+
*
|
|
127
|
+
* The tally is read off the answers rather than off N calls, in the rows'
|
|
128
|
+
* own order. A row the answer does not mention was not written — a route
|
|
129
|
+
* that dropped it silently would otherwise read as success — and is refused
|
|
130
|
+
* by name. A request refused WHOLE (no session, no reach over the org) is
|
|
131
|
+
* every row it carried refused with the route's one sentence, which is what
|
|
132
|
+
* the same selection through {@link runCrmBulkCalls} would have said N times.
|
|
133
|
+
*
|
|
134
|
+
* A route that caps how many rows one request names takes the selection in
|
|
135
|
+
* pieces of `chunkSize`, one request after another; by default the whole
|
|
136
|
+
* selection is one request.
|
|
137
|
+
*/ export async function runCrmBulkBatch(items, idOf, labelOf, call, chunkSize = Number.POSITIVE_INFINITY) {
|
|
138
|
+
const outcome = {
|
|
139
|
+
done: 0,
|
|
140
|
+
refused: []
|
|
141
|
+
};
|
|
142
|
+
for (const piece of chunked(items, chunkSize)){
|
|
143
|
+
let answers;
|
|
144
|
+
try {
|
|
145
|
+
answers = await call(piece);
|
|
146
|
+
} catch (error) {
|
|
147
|
+
const reason = bulkRefusalReason(error);
|
|
148
|
+
for (const item of piece)outcome.refused.push({
|
|
149
|
+
label: labelOf(item),
|
|
150
|
+
error: reason
|
|
151
|
+
});
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
const byId = new Map(answers.map((answer)=>[
|
|
155
|
+
answer.id,
|
|
156
|
+
answer
|
|
157
|
+
]));
|
|
158
|
+
for (const item of piece){
|
|
159
|
+
const answer = byId.get(idOf(item));
|
|
160
|
+
if (answer == null ? void 0 : answer.ok) outcome.done += 1;
|
|
161
|
+
else {
|
|
162
|
+
outcome.refused.push({
|
|
163
|
+
label: labelOf(item),
|
|
164
|
+
error: (answer == null ? void 0 : answer.error) || 'the write failed'
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return outcome;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* The Firestore writers for a collection whose bulk writes touch ONE
|
|
173
|
+
* document each — companies, deals, tasks. The contacts bar keeps its own
|
|
174
|
+
* pair, because a contact's company link moves a count on a second document
|
|
175
|
+
* and that count has to land in the same commit.
|
|
176
|
+
*/ export function crmBulkWriters(firestore, refFor) {
|
|
177
|
+
return {
|
|
178
|
+
commitBatch: async (writes)=>{
|
|
179
|
+
const batch = writeBatch(firestore);
|
|
180
|
+
for (const write of writes){
|
|
181
|
+
if (write.kind === 'delete') batch.delete(refFor(write.id));
|
|
182
|
+
else batch.update(refFor(write.id), write.data);
|
|
183
|
+
}
|
|
184
|
+
await batch.commit();
|
|
185
|
+
},
|
|
186
|
+
commitOne: async (write)=>{
|
|
187
|
+
if (write.kind === 'delete') await deleteDoc(refFor(write.id));
|
|
188
|
+
else await updateDoc(refFor(write.id), write.data);
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* The report under a bar: what the plan skipped on purpose, then what the
|
|
194
|
+
* store refused, one line each, named. `null` when there is nothing to say,
|
|
195
|
+
* so the bar renders no empty alert.
|
|
196
|
+
*/ export function bulkReport(plan, outcome) {
|
|
197
|
+
const left = [
|
|
198
|
+
...plan.skipped,
|
|
199
|
+
...outcome.refused.map((row)=>({
|
|
200
|
+
label: row.label,
|
|
201
|
+
reason: row.error
|
|
202
|
+
}))
|
|
203
|
+
];
|
|
204
|
+
return left.length ? left : null;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
//# sourceMappingURL=crm-bulk-writes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/model/crm-bulk-writes.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * HOW A BULK ACTION IS APPLIED, whichever CRM collection it is over\n * (AGL-2621).\n *\n * The contacts bar settled the shape (AGL-2603): one act over many rows is\n * a PLAN of per-row writes, applied in batches with a per-row fallback, and\n * whatever the store refused comes back NAMED — by the address, the company,\n * the deal's title — never as a count. Companies, deals and tasks each have\n * a bar now, and each bar's runner would be the same forty lines with a\n * different noun. So the runner lives here once, parametric over what a\n * write is called, and `contacts-bulk-writes.ts` stands on it under the\n * names it always exported.\n *\n * ## Two kinds of act\n *\n * A write to the document — an owner, a tag, a due date, a delete — goes\n * through {@link runCrmBulkWrites}: batched, and re-applied row by row when a\n * batch fails, because a batch that fails names no row. An act with a side\n * effect outside the document — a deal's stage, a task's completion, an\n * assignment that notifies — goes through its ROUTE, one request per row, and\n * {@link runCrmBulkCalls} is the same tally over those: each refusal is named\n * by the row and carries the route's own sentence. A route that takes the\n * whole selection at once and answers per row — the organization-level task\n * routes (AGL-2637) — is tallied by {@link runCrmBulkBatch} from its answers.\n *\n * Pure apart from the Firestore SDK the writer factory binds: the runners\n * take their writers as ports, so a spec wires a ledger in.\n */\n\nimport {\n deleteDoc,\n type DocumentReference,\n type Firestore,\n updateDoc,\n writeBatch,\n} from 'firebase/firestore'\n\n/**\n * The Firestore batch cap is 500 writes; 400 leaves room for the sentinel\n * transforms a patch carries, which the cap counts as writes of their own.\n * The same margin the datasets card keeps.\n */\nexport const CRM_BULK_WRITE_CHUNK = 400\n\n/**\n * One write to one document, named for the report — the name a person\n * recognizes the row by, which is what a refusal is listed under.\n */\nexport type CrmBulkWrite = { id: string; label: string } & (\n | { kind: 'update'; data: Record<string, unknown> }\n | { kind: 'delete' }\n)\n\n/** A row an action deliberately left alone, and why. */\nexport interface CrmBulkSkip {\n label: string\n reason: string\n}\n\n/** What one action wants written, and what it declined to. */\nexport interface CrmBulkPlan<W = CrmBulkWrite> {\n writes: W[]\n skipped: CrmBulkSkip[]\n}\n\n/** The writers the runner needs — Firestore's, or a spec's ledger. */\nexport interface CrmBulkWriters<W> {\n /** Apply every write atomically, or throw. */\n commitBatch: (writes: readonly W[]) => Promise<void>\n /** Apply one write, or throw. */\n commitOne: (write: W) => Promise<void>\n}\n\nexport interface CrmBulkOutcome {\n /** Rows written, or requests answered. */\n done: number\n /** Rows the store or the route refused, by label, with the reason given. */\n refused: Array<{ label: string; error: string }>\n}\n\nexport function chunked<T>(items: readonly T[], size: number): T[][] {\n const chunks: T[][] = []\n for (let start = 0; start < items.length; start += size) {\n chunks.push(items.slice(start, start + size))\n }\n return chunks\n}\n\n/** Whatever the store or the route threw, as one sentence a report can carry. */\nexport function bulkRefusalReason(error: unknown): string {\n const code = (error as { code?: unknown } | null)?.code\n if (code === 'permission-denied') return 'not permitted'\n if (code === 'not-found') return 'no longer exists'\n const message = (error as { message?: unknown } | null)?.message\n return typeof message === 'string' && message ? message : 'the write failed'\n}\n\n/**\n * Apply the writes in chunks, and re-apply a failed chunk row by row.\n *\n * The batch is the fast path and the common one: four hundred patches in\n * one round trip. The fallback is the honest one: a batch that fails names\n * no row, so the only way to say WHICH of four hundred was refused is to\n * ask about each. The chunk that failed is the only one that pays for that;\n * the others commit as batches.\n */\nexport async function runCrmBulkWrites<W>(\n writers: CrmBulkWriters<W>,\n writes: readonly W[],\n labelOf: (write: W) => string,\n chunkSize: number = CRM_BULK_WRITE_CHUNK,\n): Promise<CrmBulkOutcome> {\n const outcome: CrmBulkOutcome = { done: 0, refused: [] }\n for (const chunk of chunked(writes, chunkSize)) {\n try {\n await writers.commitBatch(chunk)\n outcome.done += chunk.length\n continue\n } catch {\n // Fall through to the per-row pass below.\n }\n for (const write of chunk) {\n try {\n await writers.commitOne(write)\n outcome.done += 1\n } catch (error) {\n outcome.refused.push({ label: labelOf(write), error: bulkRefusalReason(error) })\n }\n }\n }\n return outcome\n}\n\n/**\n * One request per row, in order, tallied the same way.\n *\n * In ORDER rather than in parallel: the routes these calls reach each\n * verify a session, resolve a membership and emit an event, and two hundred\n * of them fired at once is a burst the console's request budget is not\n * sized for. A refusal carries the route's own sentence, which is written\n * for the person reading it.\n */\nexport async function runCrmBulkCalls<T>(\n items: readonly T[],\n labelOf: (item: T) => string,\n call: (item: T) => Promise<unknown>,\n): Promise<CrmBulkOutcome> {\n const outcome: CrmBulkOutcome = { done: 0, refused: [] }\n for (const item of items) {\n try {\n await call(item)\n outcome.done += 1\n } catch (error) {\n outcome.refused.push({ label: labelOf(item), error: bulkRefusalReason(error) })\n }\n }\n return outcome\n}\n\n/** What a batch route answers for one row: written, or refused with a sentence. */\nexport interface CrmBulkAnswer {\n id: string\n ok: boolean\n error?: string\n}\n\n/**\n * One request for the whole selection, answered per row (AGL-2637).\n *\n * The tally is read off the answers rather than off N calls, in the rows'\n * own order. A row the answer does not mention was not written — a route\n * that dropped it silently would otherwise read as success — and is refused\n * by name. A request refused WHOLE (no session, no reach over the org) is\n * every row it carried refused with the route's one sentence, which is what\n * the same selection through {@link runCrmBulkCalls} would have said N times.\n *\n * A route that caps how many rows one request names takes the selection in\n * pieces of `chunkSize`, one request after another; by default the whole\n * selection is one request.\n */\nexport async function runCrmBulkBatch<T>(\n items: readonly T[],\n idOf: (item: T) => string,\n labelOf: (item: T) => string,\n call: (items: readonly T[]) => Promise<readonly CrmBulkAnswer[]>,\n chunkSize: number = Number.POSITIVE_INFINITY,\n): Promise<CrmBulkOutcome> {\n const outcome: CrmBulkOutcome = { done: 0, refused: [] }\n for (const piece of chunked(items, chunkSize)) {\n let answers: readonly CrmBulkAnswer[]\n try {\n answers = await call(piece)\n } catch (error) {\n const reason = bulkRefusalReason(error)\n for (const item of piece) outcome.refused.push({ label: labelOf(item), error: reason })\n continue\n }\n const byId = new Map(answers.map((answer) => [answer.id, answer]))\n for (const item of piece) {\n const answer = byId.get(idOf(item))\n if (answer?.ok) outcome.done += 1\n else {\n outcome.refused.push({\n label: labelOf(item),\n error: answer?.error || 'the write failed',\n })\n }\n }\n }\n return outcome\n}\n\n/**\n * The Firestore writers for a collection whose bulk writes touch ONE\n * document each — companies, deals, tasks. The contacts bar keeps its own\n * pair, because a contact's company link moves a count on a second document\n * and that count has to land in the same commit.\n */\nexport function crmBulkWriters(\n firestore: Firestore,\n refFor: (id: string) => DocumentReference,\n): CrmBulkWriters<CrmBulkWrite> {\n return {\n commitBatch: async (writes) => {\n const batch = writeBatch(firestore)\n for (const write of writes) {\n if (write.kind === 'delete') batch.delete(refFor(write.id))\n else batch.update(refFor(write.id), write.data)\n }\n await batch.commit()\n },\n commitOne: async (write) => {\n if (write.kind === 'delete') await deleteDoc(refFor(write.id))\n else await updateDoc(refFor(write.id), write.data)\n },\n }\n}\n\n/**\n * The report under a bar: what the plan skipped on purpose, then what the\n * store refused, one line each, named. `null` when there is nothing to say,\n * so the bar renders no empty alert.\n */\nexport function bulkReport(\n plan: Pick<CrmBulkPlan<unknown>, 'skipped'>,\n outcome: CrmBulkOutcome,\n): CrmBulkSkip[] | null {\n const left: CrmBulkSkip[] = [\n ...plan.skipped,\n ...outcome.refused.map((row) => ({ label: row.label, reason: row.error })),\n ]\n return left.length ? left : null\n}\n"],"names":["deleteDoc","updateDoc","writeBatch","CRM_BULK_WRITE_CHUNK","chunked","items","size","chunks","start","length","push","slice","bulkRefusalReason","error","code","message","runCrmBulkWrites","writers","writes","labelOf","chunkSize","outcome","done","refused","chunk","commitBatch","write","commitOne","label","runCrmBulkCalls","call","item","runCrmBulkBatch","idOf","Number","POSITIVE_INFINITY","piece","answers","reason","byId","Map","map","answer","id","get","ok","crmBulkWriters","firestore","refFor","batch","kind","delete","update","data","commit","bulkReport","plan","left","skipped","row"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BC,GAED,SACEA,SAAS,EAGTC,SAAS,EACTC,UAAU,QACL,qBAAoB;AAE3B;;;;CAIC,GACD,OAAO,MAAMC,uBAAuB,IAAG;AAsCvC,OAAO,SAASC,QAAWC,KAAmB,EAAEC,IAAY;IAC1D,MAAMC,SAAgB,EAAE;IACxB,IAAK,IAAIC,QAAQ,GAAGA,QAAQH,MAAMI,MAAM,EAAED,SAASF,KAAM;QACvDC,OAAOG,IAAI,CAACL,MAAMM,KAAK,CAACH,OAAOA,QAAQF;IACzC;IACA,OAAOC;AACT;AAEA,+EAA+E,GAC/E,OAAO,SAASK,kBAAkBC,KAAc;IAC9C,MAAMC,OAAQD,yBAAD,AAACA,MAAqCC,IAAI;IACvD,IAAIA,SAAS,qBAAqB,OAAO;IACzC,IAAIA,SAAS,aAAa,OAAO;IACjC,MAAMC,UAAWF,yBAAD,AAACA,MAAwCE,OAAO;IAChE,OAAO,OAAOA,YAAY,YAAYA,UAAUA,UAAU;AAC5D;AAEA;;;;;;;;CAQC,GACD,OAAO,eAAeC,iBACpBC,OAA0B,EAC1BC,MAAoB,EACpBC,OAA6B,EAC7BC,YAAoBjB,oBAAoB;IAExC,MAAMkB,UAA0B;QAAEC,MAAM;QAAGC,SAAS,EAAE;IAAC;IACvD,KAAK,MAAMC,SAASpB,QAAQc,QAAQE,WAAY;QAC9C,IAAI;YACF,MAAMH,QAAQQ,WAAW,CAACD;YAC1BH,QAAQC,IAAI,IAAIE,MAAMf,MAAM;YAC5B;QACF,EAAE,eAAM;QACN,0CAA0C;QAC5C;QACA,KAAK,MAAMiB,SAASF,MAAO;YACzB,IAAI;gBACF,MAAMP,QAAQU,SAAS,CAACD;gBACxBL,QAAQC,IAAI,IAAI;YAClB,EAAE,OAAOT,OAAO;gBACdQ,QAAQE,OAAO,CAACb,IAAI,CAAC;oBAAEkB,OAAOT,QAAQO;oBAAQb,OAAOD,kBAAkBC;gBAAO;YAChF;QACF;IACF;IACA,OAAOQ;AACT;AAEA;;;;;;;;CAQC,GACD,OAAO,eAAeQ,gBACpBxB,KAAmB,EACnBc,OAA4B,EAC5BW,IAAmC;IAEnC,MAAMT,UAA0B;QAAEC,MAAM;QAAGC,SAAS,EAAE;IAAC;IACvD,KAAK,MAAMQ,QAAQ1B,MAAO;QACxB,IAAI;YACF,MAAMyB,KAAKC;YACXV,QAAQC,IAAI,IAAI;QAClB,EAAE,OAAOT,OAAO;YACdQ,QAAQE,OAAO,CAACb,IAAI,CAAC;gBAAEkB,OAAOT,QAAQY;gBAAOlB,OAAOD,kBAAkBC;YAAO;QAC/E;IACF;IACA,OAAOQ;AACT;AASA;;;;;;;;;;;;;CAaC,GACD,OAAO,eAAeW,gBACpB3B,KAAmB,EACnB4B,IAAyB,EACzBd,OAA4B,EAC5BW,IAAgE,EAChEV,YAAoBc,OAAOC,iBAAiB;IAE5C,MAAMd,UAA0B;QAAEC,MAAM;QAAGC,SAAS,EAAE;IAAC;IACvD,KAAK,MAAMa,SAAShC,QAAQC,OAAOe,WAAY;QAC7C,IAAIiB;QACJ,IAAI;YACFA,UAAU,MAAMP,KAAKM;QACvB,EAAE,OAAOvB,OAAO;YACd,MAAMyB,SAAS1B,kBAAkBC;YACjC,KAAK,MAAMkB,QAAQK,MAAOf,QAAQE,OAAO,CAACb,IAAI,CAAC;gBAAEkB,OAAOT,QAAQY;gBAAOlB,OAAOyB;YAAO;YACrF;QACF;QACA,MAAMC,OAAO,IAAIC,IAAIH,QAAQI,GAAG,CAAC,CAACC,SAAW;gBAACA,OAAOC,EAAE;gBAAED;aAAO;QAChE,KAAK,MAAMX,QAAQK,MAAO;YACxB,MAAMM,SAASH,KAAKK,GAAG,CAACX,KAAKF;YAC7B,IAAIW,0BAAAA,OAAQG,EAAE,EAAExB,QAAQC,IAAI,IAAI;iBAC3B;gBACHD,QAAQE,OAAO,CAACb,IAAI,CAAC;oBACnBkB,OAAOT,QAAQY;oBACflB,OAAO6B,CAAAA,0BAAAA,OAAQ7B,KAAK,KAAI;gBAC1B;YACF;QACF;IACF;IACA,OAAOQ;AACT;AAEA;;;;;CAKC,GACD,OAAO,SAASyB,eACdC,SAAoB,EACpBC,MAAyC;IAEzC,OAAO;QACLvB,aAAa,OAAOP;YAClB,MAAM+B,QAAQ/C,WAAW6C;YACzB,KAAK,MAAMrB,SAASR,OAAQ;gBAC1B,IAAIQ,MAAMwB,IAAI,KAAK,UAAUD,MAAME,MAAM,CAACH,OAAOtB,MAAMiB,EAAE;qBACpDM,MAAMG,MAAM,CAACJ,OAAOtB,MAAMiB,EAAE,GAAGjB,MAAM2B,IAAI;YAChD;YACA,MAAMJ,MAAMK,MAAM;QACpB;QACA3B,WAAW,OAAOD;YAChB,IAAIA,MAAMwB,IAAI,KAAK,UAAU,MAAMlD,UAAUgD,OAAOtB,MAAMiB,EAAE;iBACvD,MAAM1C,UAAU+C,OAAOtB,MAAMiB,EAAE,GAAGjB,MAAM2B,IAAI;QACnD;IACF;AACF;AAEA;;;;CAIC,GACD,OAAO,SAASE,WACdC,IAA2C,EAC3CnC,OAAuB;IAEvB,MAAMoC,OAAsB;WACvBD,KAAKE,OAAO;WACZrC,QAAQE,OAAO,CAACkB,GAAG,CAAC,CAACkB,MAAS,CAAA;gBAAE/B,OAAO+B,IAAI/B,KAAK;gBAAEU,QAAQqB,IAAI9C,KAAK;YAAC,CAAA;KACxE;IACD,OAAO4C,KAAKhD,MAAM,GAAGgD,OAAO;AAC9B"}
|