@aglyn/aglyn 1.0.0-beta.218 → 1.0.0-beta.220
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/package.json +12 -12
- package/src/lib/app-utils/actions.d.ts +26 -433
- package/src/lib/app-utils/actions.js +108 -633
- package/src/lib/app-utils/actions.js.map +1 -1
- package/src/lib/app-utils/activity-presenter.d.ts +3 -3
- package/src/lib/app-utils/activity-presenter.js +36 -52
- package/src/lib/app-utils/activity-presenter.js.map +1 -1
- package/src/lib/app-utils/analytics-events.d.ts +1 -1
- package/src/lib/app-utils/analytics-events.js.map +1 -1
- package/src/lib/app-utils/analytics-provider.d.ts +182 -0
- package/src/lib/app-utils/analytics-provider.js +133 -0
- package/src/lib/app-utils/analytics-provider.js.map +1 -0
- package/src/lib/app-utils/api-plugins.d.ts +46 -0
- package/src/lib/app-utils/api-plugins.js +19 -0
- package/src/lib/app-utils/api-plugins.js.map +1 -1
- package/src/lib/app-utils/{marketplace-overrides.d.ts → artifact-overrides.d.ts} +9 -6
- package/src/lib/app-utils/{marketplace-overrides.js → artifact-overrides.js} +10 -7
- package/src/lib/app-utils/artifact-overrides.js.map +1 -0
- package/src/lib/app-utils/{marketplace-provenance.d.ts → artifact-provenance.d.ts} +12 -10
- package/src/lib/app-utils/{marketplace-provenance.js → artifact-provenance.js} +9 -7
- package/src/lib/app-utils/artifact-provenance.js.map +1 -0
- package/src/lib/app-utils/binding-token-catalog.d.ts +5 -13
- package/src/lib/app-utils/binding-token-catalog.js +17 -41
- package/src/lib/app-utils/binding-token-catalog.js.map +1 -1
- package/src/lib/app-utils/brand-support-line.d.ts +36 -0
- package/src/lib/app-utils/brand-support-line.js +38 -0
- package/src/lib/app-utils/brand-support-line.js.map +1 -0
- package/src/lib/app-utils/collection-entries.d.ts +2 -2
- package/src/lib/app-utils/collection-entries.js.map +1 -1
- package/src/lib/app-utils/consent-group-change.d.ts +4 -0
- package/src/lib/app-utils/consent-group-change.js.map +1 -1
- package/src/lib/app-utils/consent-groups.d.ts +1 -1
- package/src/lib/app-utils/consent-groups.js.map +1 -1
- package/src/lib/app-utils/console-routes.d.ts +15 -42
- package/src/lib/app-utils/console-routes.js +10 -39
- package/src/lib/app-utils/console-routes.js.map +1 -1
- package/src/lib/app-utils/contacts.d.ts +24 -2
- package/src/lib/app-utils/contacts.js +21 -5
- package/src/lib/app-utils/contacts.js.map +1 -1
- package/src/lib/app-utils/container-membership.d.ts +93 -0
- package/src/lib/app-utils/container-membership.js +165 -0
- package/src/lib/app-utils/container-membership.js.map +1 -0
- package/src/lib/app-utils/crm-task-reminders.d.ts +23 -6
- package/src/lib/app-utils/crm-task-reminders.js +32 -11
- package/src/lib/app-utils/crm-task-reminders.js.map +1 -1
- package/src/lib/app-utils/crm.d.ts +24 -4
- package/src/lib/app-utils/crm.js +23 -0
- package/src/lib/app-utils/crm.js.map +1 -1
- package/src/lib/app-utils/cross-pool-desync.d.ts +39 -0
- package/src/lib/app-utils/cross-pool-desync.js +47 -0
- package/src/lib/app-utils/cross-pool-desync.js.map +1 -0
- package/src/lib/app-utils/csv-upload.d.ts +29 -0
- package/src/lib/app-utils/csv-upload.js +29 -0
- package/src/lib/app-utils/csv-upload.js.map +1 -0
- package/src/lib/app-utils/{dataset-csv.d.ts → csv.d.ts} +10 -43
- package/src/lib/app-utils/{dataset-csv.js → csv.js} +10 -81
- package/src/lib/app-utils/csv.js.map +1 -0
- package/src/lib/app-utils/dataset-models.d.ts +5 -5
- package/src/lib/app-utils/dataset-models.js +19 -2
- package/src/lib/app-utils/dataset-models.js.map +1 -1
- package/src/lib/app-utils/datasets.d.ts +65 -30
- package/src/lib/app-utils/datasets.js +74 -24
- package/src/lib/app-utils/datasets.js.map +1 -1
- package/src/lib/app-utils/docs-deflection.d.ts +6 -6
- package/src/lib/app-utils/docs-deflection.js.map +1 -1
- package/src/lib/app-utils/docs-help.generated.d.ts +14 -8
- package/src/lib/app-utils/docs-help.generated.js +23 -6
- package/src/lib/app-utils/docs-help.generated.js.map +1 -1
- package/src/lib/app-utils/docs-index.generated.d.ts +2 -2
- package/src/lib/app-utils/docs-index.generated.js +570 -346
- package/src/lib/app-utils/docs-index.generated.js.map +1 -1
- package/src/lib/app-utils/docs-retrieval.d.ts +3 -3
- package/src/lib/app-utils/docs-retrieval.js +14 -10
- package/src/lib/app-utils/docs-retrieval.js.map +1 -1
- package/src/lib/app-utils/duplicate-resource.d.ts +4 -1
- package/src/lib/app-utils/duplicate-resource.js +7 -4
- package/src/lib/app-utils/duplicate-resource.js.map +1 -1
- package/src/lib/app-utils/dynamic-list-rule.d.ts +1 -1
- package/src/lib/app-utils/dynamic-list-rule.js +3 -3
- package/src/lib/app-utils/dynamic-list-rule.js.map +1 -1
- package/src/lib/app-utils/element-ui.d.ts +1 -1
- package/src/lib/app-utils/element-ui.js +1 -1
- package/src/lib/app-utils/element-ui.js.map +1 -1
- package/src/lib/app-utils/email-starter-policy.js +3 -3
- package/src/lib/app-utils/email-starter-policy.js.map +1 -1
- package/src/lib/app-utils/email-text.d.ts +80 -0
- package/src/lib/app-utils/email-text.js +189 -0
- package/src/lib/app-utils/email-text.js.map +1 -0
- package/src/lib/app-utils/{list-assignment-policy.d.ts → enrollment-basis.d.ts} +4 -0
- package/src/lib/app-utils/{list-assignment-policy.js → enrollment-basis.js} +5 -1
- package/src/lib/app-utils/enrollment-basis.js.map +1 -0
- package/src/lib/app-utils/entity-picker-context.d.ts +10 -5
- package/src/lib/app-utils/entity-picker-context.js.map +1 -1
- package/src/lib/app-utils/error-beacon.d.ts +75 -6
- package/src/lib/app-utils/error-beacon.js +160 -21
- package/src/lib/app-utils/error-beacon.js.map +1 -1
- package/src/lib/app-utils/expand-repeatables.d.ts +10 -10
- package/src/lib/app-utils/expand-repeatables.js +14 -14
- package/src/lib/app-utils/expand-repeatables.js.map +1 -1
- package/src/lib/app-utils/forms.js +2 -2
- package/src/lib/app-utils/forms.js.map +1 -1
- package/src/lib/app-utils/health-report.d.ts +2 -3
- package/src/lib/app-utils/health-report.js +8 -6
- package/src/lib/app-utils/health-report.js.map +1 -1
- package/src/lib/app-utils/host-events.d.ts +82 -0
- package/src/lib/app-utils/host-events.js +62 -0
- package/src/lib/app-utils/host-events.js.map +1 -0
- package/src/lib/app-utils/inbound-mail-domain.d.ts +27 -0
- package/src/lib/app-utils/inbound-mail-domain.js +31 -0
- package/src/lib/app-utils/inbound-mail-domain.js.map +1 -0
- package/src/lib/app-utils/lockdown.d.ts +11 -0
- package/src/lib/app-utils/lockdown.js +33 -3
- package/src/lib/app-utils/lockdown.js.map +1 -1
- package/src/lib/app-utils/margin-utilization.d.ts +4 -69
- package/src/lib/app-utils/margin-utilization.js +82 -69
- package/src/lib/app-utils/margin-utilization.js.map +1 -1
- package/src/lib/app-utils/member-email-aliases.d.ts +25 -0
- package/src/lib/app-utils/member-email-aliases.js +29 -0
- package/src/lib/app-utils/member-email-aliases.js.map +1 -1
- package/src/lib/app-utils/node-definition-sanitizer.d.ts +16 -16
- package/src/lib/app-utils/node-definition-sanitizer.js +24 -20
- package/src/lib/app-utils/node-definition-sanitizer.js.map +1 -1
- package/src/lib/app-utils/node-interactions.d.ts +7 -7
- package/src/lib/app-utils/node-interactions.js.map +1 -1
- package/src/lib/app-utils/notifications.d.ts +147 -47
- package/src/lib/app-utils/notifications.js +182 -44
- package/src/lib/app-utils/notifications.js.map +1 -1
- package/src/lib/app-utils/operator-alerts.d.ts +15 -1
- package/src/lib/app-utils/operator-alerts.js +47 -10
- package/src/lib/app-utils/operator-alerts.js.map +1 -1
- package/src/lib/app-utils/payments-configured.d.ts +8 -21
- package/src/lib/app-utils/payments-configured.js +8 -23
- package/src/lib/app-utils/payments-configured.js.map +1 -1
- package/src/lib/app-utils/plan-entitlements.d.ts +207 -306
- package/src/lib/app-utils/plan-entitlements.js +345 -528
- package/src/lib/app-utils/plan-entitlements.js.map +1 -1
- package/src/lib/app-utils/platform-brand.d.ts +10 -0
- package/src/lib/app-utils/platform-brand.js +14 -3
- package/src/lib/app-utils/platform-brand.js.map +1 -1
- package/src/lib/app-utils/platform-marketing-consent.d.ts +56 -2
- package/src/lib/app-utils/platform-marketing-consent.js +6 -5
- package/src/lib/app-utils/platform-marketing-consent.js.map +1 -1
- package/src/lib/app-utils/plugin-api-rate-limit.d.ts +7 -1
- package/src/lib/app-utils/plugin-api-rate-limit.js +11 -3
- package/src/lib/app-utils/plugin-api-rate-limit.js.map +1 -1
- package/src/lib/app-utils/plugin-bundle-checks.js +2 -2
- package/src/lib/app-utils/plugin-bundle-checks.js.map +1 -1
- package/src/lib/app-utils/plugin-host-events.generated.d.ts +12 -0
- package/src/lib/app-utils/plugin-host-events.generated.js +169 -0
- package/src/lib/app-utils/plugin-host-events.generated.js.map +1 -0
- package/src/lib/app-utils/plugin-release-flags.generated.d.ts +12 -0
- package/src/lib/app-utils/plugin-release-flags.generated.js +106 -0
- package/src/lib/app-utils/plugin-release-flags.generated.js.map +1 -0
- package/src/lib/app-utils/plugin-starter-templates.generated.d.ts +12 -0
- package/src/lib/app-utils/plugin-starter-templates.generated.js +711 -0
- package/src/lib/app-utils/plugin-starter-templates.generated.js.map +1 -0
- package/src/lib/app-utils/realm-host-surface.generated.js +2 -0
- package/src/lib/app-utils/realm-host-surface.generated.js.map +1 -1
- package/src/lib/app-utils/release-flags.d.ts +14 -5
- package/src/lib/app-utils/release-flags.js +21 -125
- package/src/lib/app-utils/release-flags.js.map +1 -1
- package/src/lib/app-utils/repeat-query.d.ts +56 -0
- package/src/lib/app-utils/{dataset-query.js → repeat-query.js} +16 -16
- package/src/lib/app-utils/repeat-query.js.map +1 -0
- package/src/lib/app-utils/repeat-sources.d.ts +9 -0
- package/src/lib/app-utils/repeat-sources.js.map +1 -1
- package/src/lib/app-utils/retained-refusals.d.ts +73 -0
- package/src/lib/app-utils/retained-refusals.js +186 -0
- package/src/lib/app-utils/retained-refusals.js.map +1 -0
- package/src/lib/app-utils/scope-tokens.d.ts +27 -0
- package/src/lib/app-utils/scope-tokens.js +61 -0
- package/src/lib/app-utils/scope-tokens.js.map +1 -1
- package/src/lib/app-utils/screen-link-context.js +3 -3
- package/src/lib/app-utils/screen-link-context.js.map +1 -1
- package/src/lib/app-utils/screen-route.js +1 -1
- package/src/lib/app-utils/screen-route.js.map +1 -1
- package/src/lib/app-utils/seo-audit.d.ts +132 -0
- package/src/lib/app-utils/seo-audit.js +246 -0
- package/src/lib/app-utils/seo-audit.js.map +1 -0
- package/src/lib/app-utils/seo-keywords.d.ts +48 -0
- package/src/lib/app-utils/seo-keywords.js +60 -0
- package/src/lib/app-utils/seo-keywords.js.map +1 -0
- package/src/lib/app-utils/seo-page-facts.d.ts +66 -0
- package/src/lib/app-utils/seo-page-facts.js +155 -0
- package/src/lib/app-utils/seo-page-facts.js.map +1 -0
- package/src/lib/app-utils/seo-site-scan.d.ts +126 -0
- package/src/lib/app-utils/seo-site-scan.js +162 -0
- package/src/lib/app-utils/seo-site-scan.js.map +1 -0
- package/src/lib/app-utils/seo-title-variables.js +1 -1
- package/src/lib/app-utils/seo-title-variables.js.map +1 -1
- package/src/lib/app-utils/server.d.ts +13 -18
- package/src/lib/app-utils/server.js +33 -51
- package/src/lib/app-utils/server.js.map +1 -1
- package/src/lib/app-utils/site-interactions.d.ts +501 -0
- package/src/lib/app-utils/site-interactions.js +554 -0
- package/src/lib/app-utils/site-interactions.js.map +1 -0
- package/src/lib/app-utils/{marketplace-theme.d.ts → site-theme.d.ts} +13 -2
- package/src/lib/app-utils/{marketplace-theme.js → site-theme.js} +2 -2
- package/src/lib/app-utils/site-theme.js.map +1 -0
- package/src/lib/app-utils/sitemap.d.ts +4 -3
- package/src/lib/app-utils/sitemap.js +9 -7
- package/src/lib/app-utils/sitemap.js.map +1 -1
- package/src/lib/app-utils/stale-build-error.d.ts +51 -0
- package/src/lib/app-utils/stale-build-error.js +100 -1
- package/src/lib/app-utils/stale-build-error.js.map +1 -1
- package/src/lib/app-utils/starter-template-nodes.d.ts +137 -0
- package/src/lib/app-utils/starter-template-nodes.js +129 -0
- package/src/lib/app-utils/starter-template-nodes.js.map +1 -0
- package/src/lib/app-utils/starter-templates.d.ts +11 -34
- package/src/lib/app-utils/starter-templates.js +19 -230
- package/src/lib/app-utils/starter-templates.js.map +1 -1
- package/src/lib/app-utils/{email-topics.d.ts → subscription-topics.d.ts} +64 -48
- package/src/lib/app-utils/{email-topics.js → subscription-topics.js} +39 -109
- package/src/lib/app-utils/subscription-topics.js.map +1 -0
- package/src/lib/app-utils/tax-jurisdiction-figures.d.ts +118 -0
- package/src/lib/app-utils/tax-jurisdiction-figures.js +123 -0
- package/src/lib/app-utils/tax-jurisdiction-figures.js.map +1 -0
- package/src/lib/app-utils/theme-library.d.ts +10 -3
- package/src/lib/app-utils/theme-library.js +13 -4
- package/src/lib/app-utils/theme-library.js.map +1 -1
- package/src/lib/app-utils/usage-budget.d.ts +73 -188
- package/src/lib/app-utils/usage-budget.js +58 -194
- package/src/lib/app-utils/usage-budget.js.map +1 -1
- package/src/lib/app-utils/{campaign-attribution.d.ts → utm-attribution.d.ts} +11 -6
- package/src/lib/app-utils/{campaign-attribution.js → utm-attribution.js} +13 -8
- package/src/lib/app-utils/utm-attribution.js.map +1 -0
- package/src/lib/app-utils/{campaign-forwarding.d.ts → utm-forwarding.d.ts} +14 -14
- package/src/lib/app-utils/{campaign-forwarding.js → utm-forwarding.js} +26 -26
- package/src/lib/app-utils/utm-forwarding.js.map +1 -0
- package/src/lib/app-utils/{campaign-touch.d.ts → utm-touch.d.ts} +25 -17
- package/src/lib/app-utils/{campaign-touch.js → utm-touch.js} +38 -30
- package/src/lib/app-utils/utm-touch.js.map +1 -0
- package/src/lib/app-utils/variables.d.ts +9 -9
- package/src/lib/app-utils/variables.js.map +1 -1
- package/src/lib/app-utils/video-object.js +6 -5
- package/src/lib/app-utils/video-object.js.map +1 -1
- package/src/lib/app-utils/visitor-consent.d.ts +41 -164
- package/src/lib/app-utils/visitor-consent.js +66 -277
- package/src/lib/app-utils/visitor-consent.js.map +1 -1
- package/src/lib/app-utils/visitor-record-ceiling.d.ts +32 -0
- package/src/lib/app-utils/visitor-record-ceiling.js +39 -0
- package/src/lib/app-utils/visitor-record-ceiling.js.map +1 -1
- package/src/lib/app-utils/web-vitals-rum.d.ts +7 -7
- package/src/lib/app-utils/web-vitals-rum.js +31 -63
- package/src/lib/app-utils/web-vitals-rum.js.map +1 -1
- package/src/lib/app-utils/where-used.d.ts +11 -6
- package/src/lib/app-utils/where-used.js +3 -8
- package/src/lib/app-utils/where-used.js.map +1 -1
- package/src/lib/foundation/definitions/components.types.d.ts +1 -1
- package/src/lib/foundation/definitions/components.types.js +1 -1
- package/src/lib/foundation/definitions/components.types.js.map +1 -1
- package/src/lib/foundation/definitions/org-billing.types.d.ts +11 -137
- package/src/lib/foundation/definitions/org-billing.types.js.map +1 -1
- package/src/lib/foundation/definitions/organization.types.d.ts +1 -3
- package/src/lib/foundation/definitions/organization.types.js.map +1 -1
- package/src/lib/foundation/definitions/platform.types.d.ts +11 -5
- package/src/lib/foundation/definitions/platform.types.js.map +1 -1
- package/src/lib/foundation/definitions/write-deny-coverage.util.d.ts +16 -0
- package/src/lib/foundation/definitions/write-deny-coverage.util.js +20 -0
- package/src/lib/foundation/definitions/write-deny-coverage.util.js.map +1 -1
- package/src/lib/foundation/index.d.ts +1 -1
- package/src/lib/foundation/index.js.map +1 -1
- package/src/lib/plugin-manager/besigner-documents.d.ts +96 -0
- package/src/lib/plugin-manager/besigner-documents.js +61 -0
- package/src/lib/plugin-manager/besigner-documents.js.map +1 -0
- package/src/lib/plugin-manager/computed-variables.d.ts +71 -0
- package/src/lib/plugin-manager/computed-variables.js +74 -0
- package/src/lib/plugin-manager/computed-variables.js.map +1 -0
- package/src/lib/plugin-manager/custom-fields.d.ts +29 -2
- package/src/lib/plugin-manager/custom-fields.js +47 -1
- package/src/lib/plugin-manager/custom-fields.js.map +1 -1
- package/src/lib/plugin-manager/feature-plugins.d.ts +372 -99
- package/src/lib/plugin-manager/feature-plugins.js +126 -51
- package/src/lib/plugin-manager/feature-plugins.js.map +1 -1
- package/src/lib/plugin-manager/first-party-plugins.generated.d.ts +134 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.js +840 -10
- package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -1
- package/src/lib/plugin-manager/index.d.ts +0 -1
- package/src/lib/plugin-manager/index.js +0 -1
- package/src/lib/plugin-manager/index.js.map +1 -1
- package/src/lib/plugin-manager/plugin-activity-actions.d.ts +12 -0
- package/src/lib/plugin-manager/plugin-activity-actions.js +25 -0
- package/src/lib/plugin-manager/plugin-activity-actions.js.map +1 -1
- package/src/lib/plugin-manager/plugin-contact-capture.d.ts +9 -4
- package/src/lib/plugin-manager/plugin-contact-capture.js.map +1 -1
- package/src/lib/plugin-manager/plugin-containers.d.ts +68 -0
- package/src/lib/plugin-manager/plugin-containers.generated.d.ts +10 -0
- package/src/lib/plugin-manager/plugin-containers.generated.js +20 -0
- package/src/lib/plugin-manager/plugin-containers.generated.js.map +1 -0
- package/src/lib/plugin-manager/plugin-containers.js +27 -0
- package/src/lib/plugin-manager/plugin-containers.js.map +1 -0
- package/src/lib/plugin-manager/plugin-contributions.d.ts +1 -1
- package/src/lib/plugin-manager/plugin-contributions.js.map +1 -1
- package/src/lib/plugin-manager/plugin-declarations-repair.d.ts +36 -0
- package/src/lib/plugin-manager/plugin-declarations-repair.js +64 -0
- package/src/lib/plugin-manager/plugin-declarations-repair.js.map +1 -0
- package/src/lib/plugin-manager/plugin-dependents.d.ts +101 -0
- package/src/lib/plugin-manager/plugin-dependents.js +75 -0
- package/src/lib/plugin-manager/plugin-dependents.js.map +1 -0
- package/src/lib/plugin-manager/plugin-distribution.d.ts +55 -0
- package/src/lib/plugin-manager/plugin-distribution.js +45 -0
- package/src/lib/plugin-manager/plugin-distribution.js.map +1 -0
- package/src/lib/plugin-manager/plugin-entitlements.d.ts +8 -0
- package/src/lib/plugin-manager/plugin-entitlements.js.map +1 -1
- package/src/lib/plugin-manager/plugin-host-collections.d.ts +17 -0
- package/src/lib/plugin-manager/plugin-host-collections.js +6 -0
- package/src/lib/plugin-manager/plugin-host-collections.js.map +1 -1
- package/src/lib/plugin-manager/plugin-host-resources.d.ts +133 -0
- package/src/lib/plugin-manager/plugin-host-resources.js +52 -0
- package/src/lib/plugin-manager/plugin-host-resources.js.map +1 -0
- package/src/lib/plugin-manager/plugin-membership-detach.js +1 -1
- package/src/lib/plugin-manager/plugin-membership-detach.js.map +1 -1
- package/src/lib/plugin-manager/plugin-org-erasure.d.ts +28 -2
- package/src/lib/plugin-manager/plugin-org-erasure.js +61 -2
- package/src/lib/plugin-manager/plugin-org-erasure.js.map +1 -1
- package/src/lib/plugin-manager/plugin-plan-entitlements.d.ts +123 -0
- package/src/lib/plugin-manager/plugin-plan-entitlements.js +101 -0
- package/src/lib/plugin-manager/plugin-plan-entitlements.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-email-state.d.ts +69 -0
- package/src/lib/plugin-manager/plugin-record-email-state.js +32 -0
- package/src/lib/plugin-manager/plugin-record-email-state.js.map +1 -1
- package/src/lib/plugin-manager/plugin-record-index.d.ts +95 -0
- package/src/lib/plugin-manager/plugin-record-index.js +51 -0
- package/src/lib/plugin-manager/plugin-record-index.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-lists.d.ts +115 -0
- package/src/lib/plugin-manager/plugin-record-lists.js +75 -0
- package/src/lib/plugin-manager/plugin-record-lists.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-timeline.d.ts +42 -8
- package/src/lib/plugin-manager/plugin-record-timeline.js.map +1 -1
- package/src/lib/plugin-manager/plugin-record-written.d.ts +58 -0
- package/src/lib/plugin-manager/plugin-record-written.js +42 -0
- package/src/lib/plugin-manager/plugin-record-written.js.map +1 -0
- package/src/lib/plugin-manager/plugin-revenue-sources.d.ts +213 -0
- package/src/lib/plugin-manager/plugin-revenue-sources.js +194 -0
- package/src/lib/plugin-manager/plugin-revenue-sources.js.map +1 -0
- package/src/lib/plugin-manager/plugin-site-beacons.d.ts +71 -0
- package/src/lib/plugin-manager/plugin-site-beacons.js +54 -0
- package/src/lib/plugin-manager/plugin-site-beacons.js.map +1 -0
- package/src/lib/plugin-manager/plugin-site-bundle.d.ts +145 -0
- package/src/lib/plugin-manager/plugin-site-bundle.js +78 -0
- package/src/lib/plugin-manager/plugin-site-bundle.js.map +1 -0
- package/src/lib/plugin-manager/plugin-site-cache.d.ts +12 -0
- package/src/lib/plugin-manager/plugin-site-cache.js.map +1 -1
- package/src/lib/plugin-manager/plugin-site-export.d.ts +81 -0
- package/src/lib/plugin-manager/plugin-site-export.js +40 -0
- package/src/lib/plugin-manager/plugin-site-export.js.map +1 -0
- package/src/lib/plugin-manager/plugin-sitemap-sections.d.ts +88 -0
- package/src/lib/plugin-manager/plugin-sitemap-sections.js +29 -0
- package/src/lib/plugin-manager/plugin-sitemap-sections.js.map +1 -0
- package/src/lib/plugin-manager/plugin-subscription-topics.generated.d.ts +11 -0
- package/src/lib/plugin-manager/plugin-subscription-topics.generated.js +41 -0
- package/src/lib/plugin-manager/plugin-subscription-topics.generated.js.map +1 -0
- package/src/lib/plugin-manager/plugin-tax-profile.d.ts +20 -4
- package/src/lib/plugin-manager/plugin-tax-profile.js.map +1 -1
- package/src/lib/plugin-manager/plugin-tax-return-sources.d.ts +255 -0
- package/src/lib/plugin-manager/plugin-tax-return-sources.js +191 -0
- package/src/lib/plugin-manager/plugin-tax-return-sources.js.map +1 -0
- package/src/lib/plugin-manager/plugin-template-sources.d.ts +75 -0
- package/src/lib/plugin-manager/plugin-template-sources.js +37 -0
- package/src/lib/plugin-manager/plugin-template-sources.js.map +1 -0
- package/src/lib/plugin-manager/plugin-usage-axes.d.ts +319 -0
- package/src/lib/plugin-manager/plugin-usage-axes.js +186 -0
- package/src/lib/plugin-manager/plugin-usage-axes.js.map +1 -0
- package/src/lib/plugin-manager/plugin-usage-meters.d.ts +108 -0
- package/src/lib/plugin-manager/plugin-usage-meters.js +105 -0
- package/src/lib/plugin-manager/plugin-usage-meters.js.map +1 -0
- package/src/lib/plugin-manager/plugin-zones.d.ts +4 -5
- package/src/lib/plugin-manager/plugin-zones.js.map +1 -1
- package/src/lib/plugin-manager/realm-host-aglyn.generated.js +2 -0
- package/src/lib/plugin-manager/realm-host-aglyn.generated.js.map +1 -1
- package/src/lib/plugin-manager/record-captured-contact.d.ts +1 -14
- package/src/lib/plugin-manager/record-captured-contact.js +10 -32
- package/src/lib/plugin-manager/record-captured-contact.js.map +1 -1
- package/src/lib/plugin-manager/repeat-rows.d.ts +124 -0
- package/src/lib/plugin-manager/repeat-rows.js +108 -0
- package/src/lib/plugin-manager/repeat-rows.js.map +1 -0
- package/src/lib/plugin-manager/submission-record-target.d.ts +144 -0
- package/src/lib/plugin-manager/submission-record-target.js +125 -0
- package/src/lib/plugin-manager/submission-record-target.js.map +1 -0
- package/src/lib/plugin-manager/usage-alert-contributors.d.ts +76 -6
- package/src/lib/plugin-manager/usage-alert-contributors.js +23 -10
- package/src/lib/plugin-manager/usage-alert-contributors.js.map +1 -1
- package/src/lib/plugin-manager/video-embed-provider.d.ts +108 -0
- package/src/lib/plugin-manager/video-embed-provider.js +165 -0
- package/src/lib/plugin-manager/video-embed-provider.js.map +1 -0
- package/src/lib/types/nodes.d.ts +2 -2
- package/src/lib/types/nodes.js.map +1 -1
- package/src/lib/app-utils/assist-credits.d.ts +0 -482
- package/src/lib/app-utils/assist-credits.js +0 -509
- package/src/lib/app-utils/assist-credits.js.map +0 -1
- package/src/lib/app-utils/campaign-attribution.js.map +0 -1
- package/src/lib/app-utils/campaign-forwarding.js.map +0 -1
- package/src/lib/app-utils/campaign-membership.d.ts +0 -121
- package/src/lib/app-utils/campaign-membership.js +0 -189
- package/src/lib/app-utils/campaign-membership.js.map +0 -1
- package/src/lib/app-utils/campaign-touch.js.map +0 -1
- package/src/lib/app-utils/console-record-links.d.ts +0 -163
- package/src/lib/app-utils/console-record-links.js +0 -180
- package/src/lib/app-utils/console-record-links.js.map +0 -1
- package/src/lib/app-utils/contact-holder.d.ts +0 -68
- package/src/lib/app-utils/contact-holder.js +0 -129
- package/src/lib/app-utils/contact-holder.js.map +0 -1
- package/src/lib/app-utils/contact-merge.d.ts +0 -136
- package/src/lib/app-utils/contact-merge.js +0 -412
- package/src/lib/app-utils/contact-merge.js.map +0 -1
- package/src/lib/app-utils/crm-booking.d.ts +0 -75
- package/src/lib/app-utils/crm-booking.js +0 -133
- package/src/lib/app-utils/crm-booking.js.map +0 -1
- package/src/lib/app-utils/crm-csv.d.ts +0 -239
- package/src/lib/app-utils/crm-csv.js +0 -467
- package/src/lib/app-utils/crm-csv.js.map +0 -1
- package/src/lib/app-utils/crm-digest.d.ts +0 -185
- package/src/lib/app-utils/crm-digest.js +0 -272
- package/src/lib/app-utils/crm-digest.js.map +0 -1
- package/src/lib/app-utils/crm-inbound.d.ts +0 -245
- package/src/lib/app-utils/crm-inbound.js +0 -407
- package/src/lib/app-utils/crm-inbound.js.map +0 -1
- package/src/lib/app-utils/crm-reports.d.ts +0 -479
- package/src/lib/app-utils/crm-reports.js +0 -680
- package/src/lib/app-utils/crm-reports.js.map +0 -1
- package/src/lib/app-utils/dataset-csv.js.map +0 -1
- package/src/lib/app-utils/dataset-query.d.ts +0 -57
- package/src/lib/app-utils/dataset-query.js.map +0 -1
- package/src/lib/app-utils/email-topics.js.map +0 -1
- package/src/lib/app-utils/form-dataset-binding.d.ts +0 -50
- package/src/lib/app-utils/form-dataset-binding.js +0 -74
- package/src/lib/app-utils/form-dataset-binding.js.map +0 -1
- package/src/lib/app-utils/list-assignment-policy.js.map +0 -1
- package/src/lib/app-utils/list-import.d.ts +0 -158
- package/src/lib/app-utils/list-import.js +0 -332
- package/src/lib/app-utils/list-import.js.map +0 -1
- package/src/lib/app-utils/marketplace-listing-visibility.d.ts +0 -122
- package/src/lib/app-utils/marketplace-listing-visibility.js +0 -147
- package/src/lib/app-utils/marketplace-listing-visibility.js.map +0 -1
- package/src/lib/app-utils/marketplace-overrides.js.map +0 -1
- package/src/lib/app-utils/marketplace-provenance.js.map +0 -1
- package/src/lib/app-utils/marketplace-theme.js.map +0 -1
- package/src/lib/app-utils/marketplace-update-state.d.ts +0 -119
- package/src/lib/app-utils/marketplace-update-state.js +0 -132
- package/src/lib/app-utils/marketplace-update-state.js.map +0 -1
- package/src/lib/app-utils/publisher-agreement.d.ts +0 -289
- package/src/lib/app-utils/publisher-agreement.js +0 -321
- package/src/lib/app-utils/publisher-agreement.js.map +0 -1
- package/src/lib/app-utils/wistia-embed.d.ts +0 -104
- package/src/lib/app-utils/wistia-embed.js +0 -138
- package/src/lib/app-utils/wistia-embed.js.map +0 -1
- package/src/lib/app-utils/workflows.d.ts +0 -136
- package/src/lib/app-utils/workflows.js +0 -346
- package/src/lib/app-utils/workflows.js.map +0 -1
- package/src/lib/plugin-manager/commerce-zone-props.d.ts +0 -172
- package/src/lib/plugin-manager/commerce-zone-props.js +0 -31
- package/src/lib/plugin-manager/commerce-zone-props.js.map +0 -1
- package/src/lib/plugin-manager/plugin-metered-lines.d.ts +0 -97
- package/src/lib/plugin-manager/plugin-metered-lines.js +0 -123
- package/src/lib/plugin-manager/plugin-metered-lines.js.map +0 -1
|
@@ -1,180 +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
|
-
*/ import { buildRoute, Route } from "./console-routes.js";
|
|
17
|
-
/** The CRM's nav slug — the `[pluginSlug]` segment the shell resolves. */ export const CRM_CONSOLE_SLUG = 'crm';
|
|
18
|
-
/**
|
|
19
|
-
* The hub section each kind's record lives under, which is also the list a
|
|
20
|
-
* kind-only link lands on. Named here rather than in the plugin's section
|
|
21
|
-
* registry so the console app can address a record without the plugin.
|
|
22
|
-
*/ export const CRM_RECORD_SECTIONS = {
|
|
23
|
-
contact: 'contacts',
|
|
24
|
-
lead: 'leads',
|
|
25
|
-
company: 'companies',
|
|
26
|
-
deal: 'deals'
|
|
27
|
-
};
|
|
28
|
-
/** `/{orgSlug}/hosts/{host}/crm` — the CRM hub on the site being read. */ export function crmHubHref(context) {
|
|
29
|
-
return buildRoute(Route.HOST_PLUGIN, {
|
|
30
|
-
orgSlug: context.orgSlug,
|
|
31
|
-
host: context.host,
|
|
32
|
-
pluginSlug: CRM_CONSOLE_SLUG
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
/** One section of the hub — the Leads list, the Deals board. */ export function crmSectionHref(context, section) {
|
|
36
|
-
return `${crmHubHref(context)}/${section}`;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* One record's own page. The id is URL-encoded because a Firestore id is
|
|
40
|
-
* opaque — the console mints its own, but an import or an API caller may
|
|
41
|
-
* not, and a slash in an id would otherwise read as a further segment.
|
|
42
|
-
*/ export function crmRecordHref(context, kind, id) {
|
|
43
|
-
return `${crmSectionHref(context, CRM_RECORD_SECTIONS[kind])}/${encodeURIComponent(id)}`;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* The query key the Contacts list reads to OPEN the one person with an
|
|
47
|
-
* address (AGL-2612). A surface that holds only an email — an order, a
|
|
48
|
-
* booking, a site user — links to the list with this key, the list filters
|
|
49
|
-
* on the address and moves on to the record when exactly one matches. The
|
|
50
|
-
* plugin re-exports this constant as `CONTACTS_LIST_EMAIL_PARAM` so its
|
|
51
|
-
* parser and the console's builders read one string.
|
|
52
|
-
*/ export const CRM_CONTACTS_EMAIL_PARAM = 'email';
|
|
53
|
-
/** The Contacts list asked to open the person with this address. */ export function crmContactByEmailHref(context, email) {
|
|
54
|
-
return `${crmSectionHref(context, CRM_RECORD_SECTIONS.contact)}?${new URLSearchParams({
|
|
55
|
-
[CRM_CONTACTS_EMAIL_PARAM]: email
|
|
56
|
-
}).toString()}`;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* `/{orgSlug}/crm` — the ORGANIZATION-level CRM hub (AGL-2630), the same
|
|
60
|
-
* sections mounted with no site.
|
|
61
|
-
*
|
|
62
|
-
* The org-level twin of {@link crmHubHref}, and separate from it because the
|
|
63
|
-
* two take different arguments: a site address needs the subdomain, and a
|
|
64
|
-
* surface standing at the org hub has none to give. A caller that faked one
|
|
65
|
-
* would put a site's name on a page about all of them.
|
|
66
|
-
*/ export function crmOrgHubHref(orgSlug) {
|
|
67
|
-
return buildRoute(Route.ORG_CRM, {
|
|
68
|
-
orgSlug
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
/** One section of the org-level hub — the cross-site Deals board. */ export function crmOrgSectionHref(orgSlug, section) {
|
|
72
|
-
return `${crmOrgHubHref(orgSlug)}/${section}`;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* One record's page at the org level.
|
|
76
|
-
*
|
|
77
|
-
* A LEAD IS NO LONGER EXCLUDED (AGL-3275). It was, by the type rather than a
|
|
78
|
-
* runtime check, because a lead's id is a person key — the same on every site
|
|
79
|
-
* that met the person — while `hosts/{hostId}/leads` was host-scoped by path,
|
|
80
|
-
* so two sites held two documents carrying one id and an org-level address
|
|
81
|
-
* had to name the site to tell them apart. One org collection makes the
|
|
82
|
-
* person key unambiguous, so a lead addresses like every other record.
|
|
83
|
-
*/ export function crmOrgRecordHref(orgSlug, kind, id) {
|
|
84
|
-
return `${crmOrgSectionHref(orgSlug, CRM_RECORD_SECTIONS[kind])}/${encodeURIComponent(id)}`;
|
|
85
|
-
}
|
|
86
|
-
// `crmOrgLeadHref` is gone with the host-path fallback (AGL-3277). It took a
|
|
87
|
-
// site it had already stopped using; `crmOrgRecordHref(orgSlug, 'lead', id)`
|
|
88
|
-
// is the whole of what it did.
|
|
89
|
-
/**
|
|
90
|
-
* The query keys a site record page reads on arrival, so a CRM timeline can
|
|
91
|
-
* open the submission or the order it names rather than the list it sits
|
|
92
|
-
* in. Each page parses its own key from `useSearchParams`; the CRM writes
|
|
93
|
-
* them through `siteRecordLinks`, and the constant is shared so neither
|
|
94
|
-
* side can misspell the other.
|
|
95
|
-
*/ export const INBOX_SUBMISSION_PARAM = 'submission';
|
|
96
|
-
export const ORDERS_ORDER_PARAM = 'order';
|
|
97
|
-
/**
|
|
98
|
-
* The orders list narrowed to one buyer. The same word as the CRM's own
|
|
99
|
-
* email key, deliberately: a reader who edits one URL into the other is
|
|
100
|
-
* not surprised.
|
|
101
|
-
*/ export const ORDERS_CUSTOMER_PARAM = 'email';
|
|
102
|
-
/**
|
|
103
|
-
* The Bookings page narrowed to one booker (AGL-2660) — the same key as the
|
|
104
|
-
* orders list and the CRM, for the same reason: one address, one word.
|
|
105
|
-
*/ export const BOOKINGS_BOOKER_PARAM = 'email';
|
|
106
|
-
/**
|
|
107
|
-
* Where the site records a contact's captured history names are read
|
|
108
|
-
* (AGL-2622): the Inbox for a submission, the Orders section of the
|
|
109
|
-
* Products hub for an order, the Bookings page and the Users page for the
|
|
110
|
-
* rest. Built from the route table so a section that moves is found here
|
|
111
|
-
* by its route name rather than by searching for a string.
|
|
112
|
-
*/ export function siteRecordLinks(context) {
|
|
113
|
-
const { orgSlug, host } = context;
|
|
114
|
-
const inbox = `${buildRoute(Route.HOST_INBOX, {
|
|
115
|
-
orgSlug,
|
|
116
|
-
host
|
|
117
|
-
})}/submissions`;
|
|
118
|
-
const orders = `${buildRoute(Route.HOST_PRODUCTS, {
|
|
119
|
-
orgSlug,
|
|
120
|
-
host
|
|
121
|
-
})}/orders`;
|
|
122
|
-
const withQuery = (base, key, value)=>`${base}?${new URLSearchParams({
|
|
123
|
-
[key]: value
|
|
124
|
-
}).toString()}`;
|
|
125
|
-
return {
|
|
126
|
-
/** The Inbox's Submissions tab, with the reader open on one submission. */ submission: (submissionId)=>withQuery(inbox, INBOX_SUBMISSION_PARAM, submissionId),
|
|
127
|
-
/** The Orders list. */ orders: ()=>orders,
|
|
128
|
-
/** The Orders list with one order's dialog open. */ order: (orderId)=>withQuery(orders, ORDERS_ORDER_PARAM, orderId),
|
|
129
|
-
/** The Orders list narrowed to one buyer's address. */ ordersByCustomer: (email)=>withQuery(orders, ORDERS_CUSTOMER_PARAM, email),
|
|
130
|
-
/** The Bookings page; a booking has no page of its own. */ bookings: ()=>buildRoute(Route.HOST_BOOKINGS, {
|
|
131
|
-
orgSlug,
|
|
132
|
-
host
|
|
133
|
-
}),
|
|
134
|
-
/** The Bookings page narrowed to one booker's address (AGL-2660). */ bookingsByBooker: (email)=>withQuery(buildRoute(Route.HOST_BOOKINGS, {
|
|
135
|
-
orgSlug,
|
|
136
|
-
host
|
|
137
|
-
}), BOOKINGS_BOOKER_PARAM, email),
|
|
138
|
-
/** The Users page, where a site account's row and drawer are. */ members: ()=>buildRoute(Route.HOST_USERS, {
|
|
139
|
-
orgSlug,
|
|
140
|
-
host
|
|
141
|
-
})
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* What the link on a captured timeline entry says. Only the doors that
|
|
146
|
-
* leave a record the console can open are named; a newsletter opt-in, an
|
|
147
|
-
* API create, an import or a by-hand add leave nothing to open, so they
|
|
148
|
-
* carry no link and no label.
|
|
149
|
-
*/ export const INTERACTION_LINK_LABELS = {
|
|
150
|
-
form: 'Open submission',
|
|
151
|
-
order: 'Open order',
|
|
152
|
-
booking: 'Open bookings',
|
|
153
|
-
member: 'Open site users'
|
|
154
|
-
};
|
|
155
|
-
/**
|
|
156
|
-
* The console page a captured interaction points back at, or `null` when
|
|
157
|
-
* the door left nothing to open.
|
|
158
|
-
*
|
|
159
|
-
* A submission and an order are addressed by the `refId` the capture door
|
|
160
|
-
* stamped — `formSubmissions/{id}`, `orders/{id}` — and an interaction that
|
|
161
|
-
* predates the stamp lands on nothing rather than on a list that would read
|
|
162
|
-
* as "the record is gone". A booking and a member sign-up land on their
|
|
163
|
-
* pages, which list them; neither page addresses one row.
|
|
164
|
-
*/ export function contactInteractionHref(interaction, context) {
|
|
165
|
-
const links = siteRecordLinks(context);
|
|
166
|
-
switch(interaction.type){
|
|
167
|
-
case 'form':
|
|
168
|
-
return interaction.refId ? links.submission(interaction.refId) : null;
|
|
169
|
-
case 'order':
|
|
170
|
-
return interaction.refId ? links.order(interaction.refId) : null;
|
|
171
|
-
case 'booking':
|
|
172
|
-
return links.bookings();
|
|
173
|
-
case 'member':
|
|
174
|
-
return links.members();
|
|
175
|
-
default:
|
|
176
|
-
return null;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
//# sourceMappingURL=console-record-links.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/console-record-links.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 { buildRoute, Route } from './console-routes'\nimport type { ContactInteraction, ContactSource } from './contacts'\n\n/**\n * Where the console's records live, for a surface that is not the one the\n * record belongs to (AGL-2622).\n *\n * ## Why these addresses are built here and not where they are used\n *\n * A CRM record is reached from six surfaces that are not the CRM — the\n * top-bar search, an Inbox row, a form's page, an order, a booking, a site\n * user — and a CRM timeline points back at four of them. Two of those\n * readers are the console APP, which the module boundaries forbid from\n * importing a feature plugin at all: a plugin reaches the app only through\n * the generated loader manifests, so the app cannot ask the CRM for its own\n * route builder. The CRM plugin's `crmRoutes(basePath)` stays the builder\n * inside the plugin family; this module is the same address spelled once\n * for the console side, in the shared library both may import, and the\n * plugin's builder is pinned against it by a spec so the two cannot drift.\n *\n * ## Why the arguments are the two route params and not a host document\n *\n * Every site console page is addressed by `/{orgSlug}/hosts/{host}/…`, and\n * both segments are already in the URL a surface is rendered on. Building\n * from them costs nothing; resolving them from a host id costs two document\n * reads (`hostIndex`, then the org) on every open of a card, to render a\n * link. `useConsoleHubPath` in the marketing plugin makes the same choice\n * for the same reason.\n */\nexport interface SiteConsoleContext {\n orgSlug: string\n host: string\n}\n\n/** The CRM's nav slug — the `[pluginSlug]` segment the shell resolves. */\nexport const CRM_CONSOLE_SLUG = 'crm'\n\n/** The four record kinds a surface outside the CRM may name. */\nexport type CrmRecordKind = 'contact' | 'lead' | 'company' | 'deal'\n\n/**\n * The hub section each kind's record lives under, which is also the list a\n * kind-only link lands on. Named here rather than in the plugin's section\n * registry so the console app can address a record without the plugin.\n */\nexport const CRM_RECORD_SECTIONS: Record<CrmRecordKind, string> = {\n contact: 'contacts',\n lead: 'leads',\n company: 'companies',\n deal: 'deals',\n}\n\n/** `/{orgSlug}/hosts/{host}/crm` — the CRM hub on the site being read. */\nexport function crmHubHref(context: SiteConsoleContext): string {\n return buildRoute(Route.HOST_PLUGIN, {\n orgSlug: context.orgSlug,\n host: context.host,\n pluginSlug: CRM_CONSOLE_SLUG,\n })\n}\n\n/** One section of the hub — the Leads list, the Deals board. */\nexport function crmSectionHref(\n context: SiteConsoleContext,\n section: string,\n): string {\n return `${crmHubHref(context)}/${section}`\n}\n\n/**\n * One record's own page. The id is URL-encoded because a Firestore id is\n * opaque — the console mints its own, but an import or an API caller may\n * not, and a slash in an id would otherwise read as a further segment.\n */\nexport function crmRecordHref(\n context: SiteConsoleContext,\n kind: CrmRecordKind,\n id: string,\n): string {\n return `${crmSectionHref(context, CRM_RECORD_SECTIONS[kind])}/${encodeURIComponent(id)}`\n}\n\n/**\n * The query key the Contacts list reads to OPEN the one person with an\n * address (AGL-2612). A surface that holds only an email — an order, a\n * booking, a site user — links to the list with this key, the list filters\n * on the address and moves on to the record when exactly one matches. The\n * plugin re-exports this constant as `CONTACTS_LIST_EMAIL_PARAM` so its\n * parser and the console's builders read one string.\n */\nexport const CRM_CONTACTS_EMAIL_PARAM = 'email'\n\n/** The Contacts list asked to open the person with this address. */\nexport function crmContactByEmailHref(\n context: SiteConsoleContext,\n email: string,\n): string {\n return `${crmSectionHref(context, CRM_RECORD_SECTIONS.contact)}?${new URLSearchParams(\n { [CRM_CONTACTS_EMAIL_PARAM]: email },\n ).toString()}`\n}\n\n/**\n * `/{orgSlug}/crm` — the ORGANIZATION-level CRM hub (AGL-2630), the same\n * sections mounted with no site.\n *\n * The org-level twin of {@link crmHubHref}, and separate from it because the\n * two take different arguments: a site address needs the subdomain, and a\n * surface standing at the org hub has none to give. A caller that faked one\n * would put a site's name on a page about all of them.\n */\nexport function crmOrgHubHref(orgSlug: string): string {\n return buildRoute(Route.ORG_CRM, { orgSlug })\n}\n\n/** One section of the org-level hub — the cross-site Deals board. */\nexport function crmOrgSectionHref(orgSlug: string, section: string): string {\n return `${crmOrgHubHref(orgSlug)}/${section}`\n}\n\n/**\n * One record's page at the org level.\n *\n * A LEAD IS NO LONGER EXCLUDED (AGL-3275). It was, by the type rather than a\n * runtime check, because a lead's id is a person key — the same on every site\n * that met the person — while `hosts/{hostId}/leads` was host-scoped by path,\n * so two sites held two documents carrying one id and an org-level address\n * had to name the site to tell them apart. One org collection makes the\n * person key unambiguous, so a lead addresses like every other record.\n */\nexport function crmOrgRecordHref(\n orgSlug: string,\n kind: CrmRecordKind,\n id: string,\n): string {\n return `${crmOrgSectionHref(orgSlug, CRM_RECORD_SECTIONS[kind])}/${encodeURIComponent(id)}`\n}\n\n// `crmOrgLeadHref` is gone with the host-path fallback (AGL-3277). It took a\n// site it had already stopped using; `crmOrgRecordHref(orgSlug, 'lead', id)`\n// is the whole of what it did.\n\n/**\n * The query keys a site record page reads on arrival, so a CRM timeline can\n * open the submission or the order it names rather than the list it sits\n * in. Each page parses its own key from `useSearchParams`; the CRM writes\n * them through `siteRecordLinks`, and the constant is shared so neither\n * side can misspell the other.\n */\nexport const INBOX_SUBMISSION_PARAM = 'submission'\nexport const ORDERS_ORDER_PARAM = 'order'\n/**\n * The orders list narrowed to one buyer. The same word as the CRM's own\n * email key, deliberately: a reader who edits one URL into the other is\n * not surprised.\n */\nexport const ORDERS_CUSTOMER_PARAM = 'email'\n/**\n * The Bookings page narrowed to one booker (AGL-2660) — the same key as the\n * orders list and the CRM, for the same reason: one address, one word.\n */\nexport const BOOKINGS_BOOKER_PARAM = 'email'\n\n/**\n * Where the site records a contact's captured history names are read\n * (AGL-2622): the Inbox for a submission, the Orders section of the\n * Products hub for an order, the Bookings page and the Users page for the\n * rest. Built from the route table so a section that moves is found here\n * by its route name rather than by searching for a string.\n */\nexport function siteRecordLinks(context: SiteConsoleContext) {\n const { orgSlug, host } = context\n const inbox = `${buildRoute(Route.HOST_INBOX, { orgSlug, host })}/submissions`\n const orders = `${buildRoute(Route.HOST_PRODUCTS, { orgSlug, host })}/orders`\n const withQuery = (base: string, key: string, value: string) =>\n `${base}?${new URLSearchParams({ [key]: value }).toString()}`\n return {\n /** The Inbox's Submissions tab, with the reader open on one submission. */\n submission: (submissionId: string) =>\n withQuery(inbox, INBOX_SUBMISSION_PARAM, submissionId),\n /** The Orders list. */\n orders: () => orders,\n /** The Orders list with one order's dialog open. */\n order: (orderId: string) => withQuery(orders, ORDERS_ORDER_PARAM, orderId),\n /** The Orders list narrowed to one buyer's address. */\n ordersByCustomer: (email: string) =>\n withQuery(orders, ORDERS_CUSTOMER_PARAM, email),\n /** The Bookings page; a booking has no page of its own. */\n bookings: () => buildRoute(Route.HOST_BOOKINGS, { orgSlug, host }),\n /** The Bookings page narrowed to one booker's address (AGL-2660). */\n bookingsByBooker: (email: string) =>\n withQuery(\n buildRoute(Route.HOST_BOOKINGS, { orgSlug, host }),\n BOOKINGS_BOOKER_PARAM,\n email,\n ),\n /** The Users page, where a site account's row and drawer are. */\n members: () => buildRoute(Route.HOST_USERS, { orgSlug, host }),\n }\n}\n\nexport type SiteRecordLinks = ReturnType<typeof siteRecordLinks>\n\n/**\n * What the link on a captured timeline entry says. Only the doors that\n * leave a record the console can open are named; a newsletter opt-in, an\n * API create, an import or a by-hand add leave nothing to open, so they\n * carry no link and no label.\n */\nexport const INTERACTION_LINK_LABELS: Partial<Record<ContactSource, string>> = {\n form: 'Open submission',\n order: 'Open order',\n booking: 'Open bookings',\n member: 'Open site users',\n}\n\n/**\n * The console page a captured interaction points back at, or `null` when\n * the door left nothing to open.\n *\n * A submission and an order are addressed by the `refId` the capture door\n * stamped — `formSubmissions/{id}`, `orders/{id}` — and an interaction that\n * predates the stamp lands on nothing rather than on a list that would read\n * as \"the record is gone\". A booking and a member sign-up land on their\n * pages, which list them; neither page addresses one row.\n */\nexport function contactInteractionHref(\n interaction: Pick<ContactInteraction, 'type' | 'refId'>,\n context: SiteConsoleContext,\n): string | null {\n const links = siteRecordLinks(context)\n switch (interaction.type) {\n case 'form':\n return interaction.refId ? links.submission(interaction.refId) : null\n case 'order':\n return interaction.refId ? links.order(interaction.refId) : null\n case 'booking':\n return links.bookings()\n case 'member':\n return links.members()\n default:\n return null\n }\n}\n"],"names":["buildRoute","Route","CRM_CONSOLE_SLUG","CRM_RECORD_SECTIONS","contact","lead","company","deal","crmHubHref","context","HOST_PLUGIN","orgSlug","host","pluginSlug","crmSectionHref","section","crmRecordHref","kind","id","encodeURIComponent","CRM_CONTACTS_EMAIL_PARAM","crmContactByEmailHref","email","URLSearchParams","toString","crmOrgHubHref","ORG_CRM","crmOrgSectionHref","crmOrgRecordHref","INBOX_SUBMISSION_PARAM","ORDERS_ORDER_PARAM","ORDERS_CUSTOMER_PARAM","BOOKINGS_BOOKER_PARAM","siteRecordLinks","inbox","HOST_INBOX","orders","HOST_PRODUCTS","withQuery","base","key","value","submission","submissionId","order","orderId","ordersByCustomer","bookings","HOST_BOOKINGS","bookingsByBooker","members","HOST_USERS","INTERACTION_LINK_LABELS","form","booking","member","contactInteractionHref","interaction","links","type","refId"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,UAAU,EAAEC,KAAK,QAAQ,sBAAkB;AAkCpD,wEAAwE,GACxE,OAAO,MAAMC,mBAAmB,MAAK;AAKrC;;;;CAIC,GACD,OAAO,MAAMC,sBAAqD;IAChEC,SAAS;IACTC,MAAM;IACNC,SAAS;IACTC,MAAM;AACR,EAAC;AAED,wEAAwE,GACxE,OAAO,SAASC,WAAWC,OAA2B;IACpD,OAAOT,WAAWC,MAAMS,WAAW,EAAE;QACnCC,SAASF,QAAQE,OAAO;QACxBC,MAAMH,QAAQG,IAAI;QAClBC,YAAYX;IACd;AACF;AAEA,8DAA8D,GAC9D,OAAO,SAASY,eACdL,OAA2B,EAC3BM,OAAe;IAEf,OAAO,GAAGP,WAAWC,SAAS,CAAC,EAAEM,SAAS;AAC5C;AAEA;;;;CAIC,GACD,OAAO,SAASC,cACdP,OAA2B,EAC3BQ,IAAmB,EACnBC,EAAU;IAEV,OAAO,GAAGJ,eAAeL,SAASN,mBAAmB,CAACc,KAAK,EAAE,CAAC,EAAEE,mBAAmBD,KAAK;AAC1F;AAEA;;;;;;;CAOC,GACD,OAAO,MAAME,2BAA2B,QAAO;AAE/C,kEAAkE,GAClE,OAAO,SAASC,sBACdZ,OAA2B,EAC3Ba,KAAa;IAEb,OAAO,GAAGR,eAAeL,SAASN,oBAAoBC,OAAO,EAAE,CAAC,EAAE,IAAImB,gBACpE;QAAE,CAACH,yBAAyB,EAAEE;IAAM,GACpCE,QAAQ,IAAI;AAChB;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASC,cAAcd,OAAe;IAC3C,OAAOX,WAAWC,MAAMyB,OAAO,EAAE;QAAEf;IAAQ;AAC7C;AAEA,mEAAmE,GACnE,OAAO,SAASgB,kBAAkBhB,OAAe,EAAEI,OAAe;IAChE,OAAO,GAAGU,cAAcd,SAAS,CAAC,EAAEI,SAAS;AAC/C;AAEA;;;;;;;;;CASC,GACD,OAAO,SAASa,iBACdjB,OAAe,EACfM,IAAmB,EACnBC,EAAU;IAEV,OAAO,GAAGS,kBAAkBhB,SAASR,mBAAmB,CAACc,KAAK,EAAE,CAAC,EAAEE,mBAAmBD,KAAK;AAC7F;AAEA,6EAA6E;AAC7E,6EAA6E;AAC7E,+BAA+B;AAE/B;;;;;;CAMC,GACD,OAAO,MAAMW,yBAAyB,aAAY;AAClD,OAAO,MAAMC,qBAAqB,QAAO;AACzC;;;;CAIC,GACD,OAAO,MAAMC,wBAAwB,QAAO;AAC5C;;;CAGC,GACD,OAAO,MAAMC,wBAAwB,QAAO;AAE5C;;;;;;CAMC,GACD,OAAO,SAASC,gBAAgBxB,OAA2B;IACzD,MAAM,EAAEE,OAAO,EAAEC,IAAI,EAAE,GAAGH;IAC1B,MAAMyB,QAAQ,GAAGlC,WAAWC,MAAMkC,UAAU,EAAE;QAAExB;QAASC;IAAK,GAAG,YAAY,CAAC;IAC9E,MAAMwB,SAAS,GAAGpC,WAAWC,MAAMoC,aAAa,EAAE;QAAE1B;QAASC;IAAK,GAAG,OAAO,CAAC;IAC7E,MAAM0B,YAAY,CAACC,MAAcC,KAAaC,QAC5C,GAAGF,KAAK,CAAC,EAAE,IAAIhB,gBAAgB;YAAE,CAACiB,IAAI,EAAEC;QAAM,GAAGjB,QAAQ,IAAI;IAC/D,OAAO;QACL,yEAAyE,GACzEkB,YAAY,CAACC,eACXL,UAAUJ,OAAOL,wBAAwBc;QAC3C,qBAAqB,GACrBP,QAAQ,IAAMA;QACd,kDAAkD,GAClDQ,OAAO,CAACC,UAAoBP,UAAUF,QAAQN,oBAAoBe;QAClE,qDAAqD,GACrDC,kBAAkB,CAACxB,QACjBgB,UAAUF,QAAQL,uBAAuBT;QAC3C,yDAAyD,GACzDyB,UAAU,IAAM/C,WAAWC,MAAM+C,aAAa,EAAE;gBAAErC;gBAASC;YAAK;QAChE,mEAAmE,GACnEqC,kBAAkB,CAAC3B,QACjBgB,UACEtC,WAAWC,MAAM+C,aAAa,EAAE;gBAAErC;gBAASC;YAAK,IAChDoB,uBACAV;QAEJ,+DAA+D,GAC/D4B,SAAS,IAAMlD,WAAWC,MAAMkD,UAAU,EAAE;gBAAExC;gBAASC;YAAK;IAC9D;AACF;AAIA;;;;;CAKC,GACD,OAAO,MAAMwC,0BAAkE;IAC7EC,MAAM;IACNT,OAAO;IACPU,SAAS;IACTC,QAAQ;AACV,EAAC;AAED;;;;;;;;;CASC,GACD,OAAO,SAASC,uBACdC,WAAuD,EACvDhD,OAA2B;IAE3B,MAAMiD,QAAQzB,gBAAgBxB;IAC9B,OAAQgD,YAAYE,IAAI;QACtB,KAAK;YACH,OAAOF,YAAYG,KAAK,GAAGF,MAAMhB,UAAU,CAACe,YAAYG,KAAK,IAAI;QACnE,KAAK;YACH,OAAOH,YAAYG,KAAK,GAAGF,MAAMd,KAAK,CAACa,YAAYG,KAAK,IAAI;QAC9D,KAAK;YACH,OAAOF,MAAMX,QAAQ;QACvB,KAAK;YACH,OAAOW,MAAMR,OAAO;QACtB;YACE,OAAO;IACX;AACF"}
|
|
@@ -1,68 +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 ConsentGroup } from './consent-groups';
|
|
18
|
-
/**
|
|
19
|
-
* The holder of nothing: the group a contact is flattened through when no
|
|
20
|
-
* site has captured it and no facet exists — a row written by a path that
|
|
21
|
-
* predates attribution, read at the org level (AGL-2630).
|
|
22
|
-
*
|
|
23
|
-
* An empty `groupId` reads an empty facet (`readContactFacet` answers the
|
|
24
|
-
* empty facet for a key the map lacks) and REFUSES a write
|
|
25
|
-
* (`contactFacetPath` throws on an empty holder), which is the right pair:
|
|
26
|
-
* the row still shows its shared identity, and nothing edits a facet
|
|
27
|
-
* nobody holds. Exported so a surface can test for it rather than for an
|
|
28
|
-
* empty string.
|
|
29
|
-
*/
|
|
30
|
-
export declare const NO_HOLDER_GROUP: ConsentGroup;
|
|
31
|
-
/**
|
|
32
|
-
* The group a LEAD is read and acted on through (AGL-3278).
|
|
33
|
-
*
|
|
34
|
-
* The same question {@link contactPrimaryGroup} answers, with a shorter
|
|
35
|
-
* answer: a lead is one flat document — no facets, one profile, one
|
|
36
|
-
* status — so there is nothing to choose between and the holder is simply
|
|
37
|
-
* the site that captured the person first. What it is FOR is the same: at
|
|
38
|
-
* the organization level the record page has no viewing site, and it needs
|
|
39
|
-
* one to read the consent basis against, to file an activity under, to
|
|
40
|
-
* offer a booking on and to convert as.
|
|
41
|
-
*
|
|
42
|
-
* A lead no site has captured — a row imported before attribution — reads
|
|
43
|
-
* through {@link NO_HOLDER_GROUP}, whose empty `hostId` is how a surface
|
|
44
|
-
* asks "is there a site here at all" without testing for an empty string.
|
|
45
|
-
*/
|
|
46
|
-
export declare function leadPrimaryGroup(lead: Record<string, unknown> | null | undefined, org: Record<string, unknown> | null | undefined): ConsentGroup;
|
|
47
|
-
/**
|
|
48
|
-
* The group a CROSS-HOLDER reader flattens one contact through (AGL-2630).
|
|
49
|
-
*
|
|
50
|
-
* Under a site there is one answer for every row — the site's own group,
|
|
51
|
-
* `consentGroupForHost` — and the reader never asks this. At the
|
|
52
|
-
* organization level there is no viewing site, and a contact captured by
|
|
53
|
-
* three sites has up to three facets; the org-wide member reading them all
|
|
54
|
-
* needs ONE to show the row's profile, owner and stage under, and to write
|
|
55
|
-
* an edit back to. This picks the person's PRIMARY holder: the first
|
|
56
|
-
* capturing site, in capture order, whose group actually holds a facet;
|
|
57
|
-
* then any facet at all, resolved back to its declared group or to the
|
|
58
|
-
* site whose id it is keyed by; then the first capturing site even with no
|
|
59
|
-
* facet yet (the facet is written on the first edit). A row nobody captured
|
|
60
|
-
* and nobody wrote a facet for reads through {@link NO_HOLDER_GROUP}.
|
|
61
|
-
*
|
|
62
|
-
* Capture order rather than sorted order, deliberately: `capturedByHostIds`
|
|
63
|
-
* is maintained by `arrayUnion`, so its first entry is the site that met
|
|
64
|
-
* the person first, and that site's profile is the one a person reading
|
|
65
|
-
* across brands would expect to see. `contactCaptureHostIds` sorts the same
|
|
66
|
-
* array for RENDERING, where a stable order matters more than a first.
|
|
67
|
-
*/
|
|
68
|
-
export declare function contactPrimaryGroup(row: Record<string, unknown> | null | undefined, org: Record<string, unknown> | null | undefined): ConsentGroup;
|
|
@@ -1,129 +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
|
-
* WHICH HOLDER A CROSS-SITE READER SEES A CONTACT THROUGH (AGL-2630).
|
|
18
|
-
*
|
|
19
|
-
* A contact document carries one facet per holder, and every field but the
|
|
20
|
-
* shared identity lives in one of them. A surface standing on a site reads
|
|
21
|
-
* that site's group; a surface standing at the organization — the org-level
|
|
22
|
-
* Contacts list, and the whole-collection export that writes the same file
|
|
23
|
-
* — has no site to read as and needs one answer per row.
|
|
24
|
-
*
|
|
25
|
-
* In the library rather than in the CRM plugin because both of those
|
|
26
|
-
* readers need it and one of them is an app: an app may not import a
|
|
27
|
-
* feature plugin (AGL-2662).
|
|
28
|
-
*/ import { CONTACT_FACETS_FIELD } from "./contacts.js";
|
|
29
|
-
import { CAPTURED_BY_HOST_FIELD } from "./marketing-consent.js";
|
|
30
|
-
import { consentGroupForHost, consentGroupsAwaitConfirmation, readConsentGroups, soloConsentGroup } from "./consent-groups.js";
|
|
31
|
-
/**
|
|
32
|
-
* The holder of nothing: the group a contact is flattened through when no
|
|
33
|
-
* site has captured it and no facet exists — a row written by a path that
|
|
34
|
-
* predates attribution, read at the org level (AGL-2630).
|
|
35
|
-
*
|
|
36
|
-
* An empty `groupId` reads an empty facet (`readContactFacet` answers the
|
|
37
|
-
* empty facet for a key the map lacks) and REFUSES a write
|
|
38
|
-
* (`contactFacetPath` throws on an empty holder), which is the right pair:
|
|
39
|
-
* the row still shows its shared identity, and nothing edits a facet
|
|
40
|
-
* nobody holds. Exported so a surface can test for it rather than for an
|
|
41
|
-
* empty string.
|
|
42
|
-
*/ export const NO_HOLDER_GROUP = Object.freeze({
|
|
43
|
-
hostId: '',
|
|
44
|
-
groupId: '',
|
|
45
|
-
name: null,
|
|
46
|
-
hostIds: [],
|
|
47
|
-
declared: false,
|
|
48
|
-
awaitsConfirmation: false
|
|
49
|
-
});
|
|
50
|
-
/**
|
|
51
|
-
* The sites that captured this person, in CAPTURE order — the order
|
|
52
|
-
* `arrayUnion` left, so the first entry is the site that met them first.
|
|
53
|
-
*
|
|
54
|
-
* `contactCaptureHostIds` sorts the same array for RENDERING, where a
|
|
55
|
-
* stable order matters more than a first. Both readers below want the
|
|
56
|
-
* first, so neither may use the sorted one.
|
|
57
|
-
*/ function captureOrder(record) {
|
|
58
|
-
const raw = (record != null ? record : {})[CAPTURED_BY_HOST_FIELD];
|
|
59
|
-
if (!Array.isArray(raw)) return [];
|
|
60
|
-
return raw.map((id)=>String(id != null ? id : '').trim()).filter(Boolean);
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* The group a LEAD is read and acted on through (AGL-3278).
|
|
64
|
-
*
|
|
65
|
-
* The same question {@link contactPrimaryGroup} answers, with a shorter
|
|
66
|
-
* answer: a lead is one flat document — no facets, one profile, one
|
|
67
|
-
* status — so there is nothing to choose between and the holder is simply
|
|
68
|
-
* the site that captured the person first. What it is FOR is the same: at
|
|
69
|
-
* the organization level the record page has no viewing site, and it needs
|
|
70
|
-
* one to read the consent basis against, to file an activity under, to
|
|
71
|
-
* offer a booking on and to convert as.
|
|
72
|
-
*
|
|
73
|
-
* A lead no site has captured — a row imported before attribution — reads
|
|
74
|
-
* through {@link NO_HOLDER_GROUP}, whose empty `hostId` is how a surface
|
|
75
|
-
* asks "is there a site here at all" without testing for an empty string.
|
|
76
|
-
*/ export function leadPrimaryGroup(lead, org) {
|
|
77
|
-
const captured = captureOrder(lead);
|
|
78
|
-
return captured.length ? consentGroupForHost(org, captured[0]) : NO_HOLDER_GROUP;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* The group a CROSS-HOLDER reader flattens one contact through (AGL-2630).
|
|
82
|
-
*
|
|
83
|
-
* Under a site there is one answer for every row — the site's own group,
|
|
84
|
-
* `consentGroupForHost` — and the reader never asks this. At the
|
|
85
|
-
* organization level there is no viewing site, and a contact captured by
|
|
86
|
-
* three sites has up to three facets; the org-wide member reading them all
|
|
87
|
-
* needs ONE to show the row's profile, owner and stage under, and to write
|
|
88
|
-
* an edit back to. This picks the person's PRIMARY holder: the first
|
|
89
|
-
* capturing site, in capture order, whose group actually holds a facet;
|
|
90
|
-
* then any facet at all, resolved back to its declared group or to the
|
|
91
|
-
* site whose id it is keyed by; then the first capturing site even with no
|
|
92
|
-
* facet yet (the facet is written on the first edit). A row nobody captured
|
|
93
|
-
* and nobody wrote a facet for reads through {@link NO_HOLDER_GROUP}.
|
|
94
|
-
*
|
|
95
|
-
* Capture order rather than sorted order, deliberately: `capturedByHostIds`
|
|
96
|
-
* is maintained by `arrayUnion`, so its first entry is the site that met
|
|
97
|
-
* the person first, and that site's profile is the one a person reading
|
|
98
|
-
* across brands would expect to see. `contactCaptureHostIds` sorts the same
|
|
99
|
-
* array for RENDERING, where a stable order matters more than a first.
|
|
100
|
-
*/ export function contactPrimaryGroup(row, org) {
|
|
101
|
-
const record = row != null ? row : {};
|
|
102
|
-
const facets = record[CONTACT_FACETS_FIELD];
|
|
103
|
-
const facetKeys = facets && typeof facets === 'object' && !Array.isArray(facets) ? Object.keys(facets) : [];
|
|
104
|
-
const captured = captureOrder(record);
|
|
105
|
-
for (const hostId of captured){
|
|
106
|
-
const group = consentGroupForHost(org, hostId);
|
|
107
|
-
if (facetKeys.includes(group.groupId)) return group;
|
|
108
|
-
}
|
|
109
|
-
for (const key of facetKeys){
|
|
110
|
-
const declared = readConsentGroups(org)[key];
|
|
111
|
-
if (declared) {
|
|
112
|
-
return {
|
|
113
|
-
hostId: declared.hostIds[0],
|
|
114
|
-
groupId: key,
|
|
115
|
-
name: declared.name,
|
|
116
|
-
hostIds: [
|
|
117
|
-
...declared.hostIds
|
|
118
|
-
],
|
|
119
|
-
declared: true,
|
|
120
|
-
awaitsConfirmation: consentGroupsAwaitConfirmation(org)
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
return soloConsentGroup(key);
|
|
124
|
-
}
|
|
125
|
-
if (captured.length) return consentGroupForHost(org, captured[0]);
|
|
126
|
-
return NO_HOLDER_GROUP;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
//# sourceMappingURL=contact-holder.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/contact-holder.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 * WHICH HOLDER A CROSS-SITE READER SEES A CONTACT THROUGH (AGL-2630).\n *\n * A contact document carries one facet per holder, and every field but the\n * shared identity lives in one of them. A surface standing on a site reads\n * that site's group; a surface standing at the organization — the org-level\n * Contacts list, and the whole-collection export that writes the same file\n * — has no site to read as and needs one answer per row.\n *\n * In the library rather than in the CRM plugin because both of those\n * readers need it and one of them is an app: an app may not import a\n * feature plugin (AGL-2662).\n */\n\nimport { CONTACT_FACETS_FIELD } from './contacts'\nimport { CAPTURED_BY_HOST_FIELD } from './marketing-consent'\nimport {\n type ConsentGroup,\n consentGroupForHost,\n consentGroupsAwaitConfirmation,\n readConsentGroups,\n soloConsentGroup,\n} from './consent-groups'\n\n/**\n * The holder of nothing: the group a contact is flattened through when no\n * site has captured it and no facet exists — a row written by a path that\n * predates attribution, read at the org level (AGL-2630).\n *\n * An empty `groupId` reads an empty facet (`readContactFacet` answers the\n * empty facet for a key the map lacks) and REFUSES a write\n * (`contactFacetPath` throws on an empty holder), which is the right pair:\n * the row still shows its shared identity, and nothing edits a facet\n * nobody holds. Exported so a surface can test for it rather than for an\n * empty string.\n */\nexport const NO_HOLDER_GROUP: ConsentGroup = Object.freeze({\n hostId: '',\n groupId: '',\n name: null,\n hostIds: [],\n declared: false,\n awaitsConfirmation: false,\n}) as ConsentGroup\n\n/**\n * The sites that captured this person, in CAPTURE order — the order\n * `arrayUnion` left, so the first entry is the site that met them first.\n *\n * `contactCaptureHostIds` sorts the same array for RENDERING, where a\n * stable order matters more than a first. Both readers below want the\n * first, so neither may use the sorted one.\n */\nfunction captureOrder(\n record: Record<string, unknown> | null | undefined,\n): string[] {\n const raw = (record ?? {})[CAPTURED_BY_HOST_FIELD]\n if (!Array.isArray(raw)) return []\n return raw.map((id) => String(id ?? '').trim()).filter(Boolean)\n}\n\n/**\n * The group a LEAD is read and acted on through (AGL-3278).\n *\n * The same question {@link contactPrimaryGroup} answers, with a shorter\n * answer: a lead is one flat document — no facets, one profile, one\n * status — so there is nothing to choose between and the holder is simply\n * the site that captured the person first. What it is FOR is the same: at\n * the organization level the record page has no viewing site, and it needs\n * one to read the consent basis against, to file an activity under, to\n * offer a booking on and to convert as.\n *\n * A lead no site has captured — a row imported before attribution — reads\n * through {@link NO_HOLDER_GROUP}, whose empty `hostId` is how a surface\n * asks \"is there a site here at all\" without testing for an empty string.\n */\nexport function leadPrimaryGroup(\n lead: Record<string, unknown> | null | undefined,\n org: Record<string, unknown> | null | undefined,\n): ConsentGroup {\n const captured = captureOrder(lead)\n return captured.length ? consentGroupForHost(org, captured[0]) : NO_HOLDER_GROUP\n}\n\n/**\n * The group a CROSS-HOLDER reader flattens one contact through (AGL-2630).\n *\n * Under a site there is one answer for every row — the site's own group,\n * `consentGroupForHost` — and the reader never asks this. At the\n * organization level there is no viewing site, and a contact captured by\n * three sites has up to three facets; the org-wide member reading them all\n * needs ONE to show the row's profile, owner and stage under, and to write\n * an edit back to. This picks the person's PRIMARY holder: the first\n * capturing site, in capture order, whose group actually holds a facet;\n * then any facet at all, resolved back to its declared group or to the\n * site whose id it is keyed by; then the first capturing site even with no\n * facet yet (the facet is written on the first edit). A row nobody captured\n * and nobody wrote a facet for reads through {@link NO_HOLDER_GROUP}.\n *\n * Capture order rather than sorted order, deliberately: `capturedByHostIds`\n * is maintained by `arrayUnion`, so its first entry is the site that met\n * the person first, and that site's profile is the one a person reading\n * across brands would expect to see. `contactCaptureHostIds` sorts the same\n * array for RENDERING, where a stable order matters more than a first.\n */\nexport function contactPrimaryGroup(\n row: Record<string, unknown> | null | undefined,\n org: Record<string, unknown> | null | undefined,\n): ConsentGroup {\n const record = row ?? {}\n const facets = record[CONTACT_FACETS_FIELD]\n const facetKeys =\n facets && typeof facets === 'object' && !Array.isArray(facets)\n ? Object.keys(facets as Record<string, unknown>)\n : []\n const captured = captureOrder(record)\n for (const hostId of captured) {\n const group = consentGroupForHost(org, hostId)\n if (facetKeys.includes(group.groupId)) return group\n }\n for (const key of facetKeys) {\n const declared = readConsentGroups(org)[key]\n if (declared) {\n return {\n hostId: declared.hostIds[0],\n groupId: key,\n name: declared.name,\n hostIds: [...declared.hostIds],\n declared: true,\n awaitsConfirmation: consentGroupsAwaitConfirmation(org),\n }\n }\n return soloConsentGroup(key)\n }\n if (captured.length) return consentGroupForHost(org, captured[0])\n return NO_HOLDER_GROUP\n}"],"names":["CONTACT_FACETS_FIELD","CAPTURED_BY_HOST_FIELD","consentGroupForHost","consentGroupsAwaitConfirmation","readConsentGroups","soloConsentGroup","NO_HOLDER_GROUP","Object","freeze","hostId","groupId","name","hostIds","declared","awaitsConfirmation","captureOrder","record","raw","Array","isArray","map","id","String","trim","filter","Boolean","leadPrimaryGroup","lead","org","captured","length","contactPrimaryGroup","row","facets","facetKeys","keys","group","includes","key"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;CAYC,GAED,SAASA,oBAAoB,QAAQ,gBAAY;AACjD,SAASC,sBAAsB,QAAQ,yBAAqB;AAC5D,SAEEC,mBAAmB,EACnBC,8BAA8B,EAC9BC,iBAAiB,EACjBC,gBAAgB,QACX,sBAAkB;AAEzB;;;;;;;;;;;CAWC,GACD,OAAO,MAAMC,kBAAgCC,OAAOC,MAAM,CAAC;IACzDC,QAAQ;IACRC,SAAS;IACTC,MAAM;IACNC,SAAS,EAAE;IACXC,UAAU;IACVC,oBAAoB;AACtB,GAAkB;AAElB;;;;;;;CAOC,GACD,SAASC,aACPC,MAAkD;IAElD,MAAMC,MAAM,CAACD,iBAAAA,SAAU,CAAC,EAAE,CAACf,uBAAuB;IAClD,IAAI,CAACiB,MAAMC,OAAO,CAACF,MAAM,OAAO,EAAE;IAClC,OAAOA,IAAIG,GAAG,CAAC,CAACC,KAAOC,OAAOD,aAAAA,KAAM,IAAIE,IAAI,IAAIC,MAAM,CAACC;AACzD;AAEA;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASC,iBACdC,IAAgD,EAChDC,GAA+C;IAE/C,MAAMC,WAAWd,aAAaY;IAC9B,OAAOE,SAASC,MAAM,GAAG5B,oBAAoB0B,KAAKC,QAAQ,CAAC,EAAE,IAAIvB;AACnE;AAEA;;;;;;;;;;;;;;;;;;;;CAoBC,GACD,OAAO,SAASyB,oBACdC,GAA+C,EAC/CJ,GAA+C;IAE/C,MAAMZ,SAASgB,cAAAA,MAAO,CAAC;IACvB,MAAMC,SAASjB,MAAM,CAAChB,qBAAqB;IAC3C,MAAMkC,YACJD,UAAU,OAAOA,WAAW,YAAY,CAACf,MAAMC,OAAO,CAACc,UACnD1B,OAAO4B,IAAI,CAACF,UACZ,EAAE;IACR,MAAMJ,WAAWd,aAAaC;IAC9B,KAAK,MAAMP,UAAUoB,SAAU;QAC7B,MAAMO,QAAQlC,oBAAoB0B,KAAKnB;QACvC,IAAIyB,UAAUG,QAAQ,CAACD,MAAM1B,OAAO,GAAG,OAAO0B;IAChD;IACA,KAAK,MAAME,OAAOJ,UAAW;QAC3B,MAAMrB,WAAWT,kBAAkBwB,IAAI,CAACU,IAAI;QAC5C,IAAIzB,UAAU;YACZ,OAAO;gBACLJ,QAAQI,SAASD,OAAO,CAAC,EAAE;gBAC3BF,SAAS4B;gBACT3B,MAAME,SAASF,IAAI;gBACnBC,SAAS;uBAAIC,SAASD,OAAO;iBAAC;gBAC9BC,UAAU;gBACVC,oBAAoBX,+BAA+ByB;YACrD;QACF;QACA,OAAOvB,iBAAiBiC;IAC1B;IACA,IAAIT,SAASC,MAAM,EAAE,OAAO5B,oBAAoB0B,KAAKC,QAAQ,CAAC,EAAE;IAChE,OAAOvB;AACT"}
|
|
@@ -1,136 +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
|
-
* MERGING TWO CONTACT DOCUMENTS INTO ONE (AGL-2625) — the pure half.
|
|
19
|
-
*
|
|
20
|
-
* Contacts are keyed by email, so exact duplicates cannot exist; one human
|
|
21
|
-
* with `jane@acme.com` and `jane@gmail.com` is two documents, with tags,
|
|
22
|
-
* deals, tasks and a timeline split between them. A merge folds the second
|
|
23
|
-
* into the first: the SURVIVOR keeps its address as the identity, the MERGED
|
|
24
|
-
* record's address becomes an alternate on it, and every field is combined
|
|
25
|
-
* by one rule the dialog can show before the write happens.
|
|
26
|
-
*
|
|
27
|
-
* ## The rule
|
|
28
|
-
*
|
|
29
|
-
* - A scalar — a name, a phone, a title, a stage, an owner — is the
|
|
30
|
-
* survivor's where the survivor has one, and fills from the merged record
|
|
31
|
-
* where the survivor is empty. Nothing the survivor holds is overwritten.
|
|
32
|
-
* - A list — tags, campaign filings, the timeline, the sites that captured
|
|
33
|
-
* the person, the forms, the companies — is the UNION, deduplicated and
|
|
34
|
-
* bounded where the write paths bound it.
|
|
35
|
-
* - A figure that counts something — orders, lifetime value, refunds — is
|
|
36
|
-
* the SUM: two records of one person's purchases are one person's
|
|
37
|
-
* purchases. A "first" is the earlier, a "last" is the later.
|
|
38
|
-
* - Notes are appended, survivor first: a note is a list of sentences, and
|
|
39
|
-
* dropping the merged record's would be the one silent loss in a merge
|
|
40
|
-
* that is otherwise lossless.
|
|
41
|
-
* - A recorded REFUSAL of marketing mail on either record stands on the
|
|
42
|
-
* survivor. The merge asserts the two are one person, and that person
|
|
43
|
-
* said no.
|
|
44
|
-
*
|
|
45
|
-
* Applied per holder: each group's facet on the merged record is folded
|
|
46
|
-
* into the same group's facet on the survivor, and a group only the merged
|
|
47
|
-
* record had comes across whole. No holder's records reach another holder's
|
|
48
|
-
* facet, which is the guarantee the facet shape exists for.
|
|
49
|
-
*
|
|
50
|
-
* ## Why this is a plan and not a write
|
|
51
|
-
*
|
|
52
|
-
* The console shows the two records side by side and says which value wins
|
|
53
|
-
* before anything is committed; the server performs the write. Both read
|
|
54
|
-
* this function, so the preview cannot show one outcome and the write land
|
|
55
|
-
* another. The plan is plain values — no sentinels — so it can be rendered,
|
|
56
|
-
* and it is shaped for a merge-`set`, which deep-merges the facet map one
|
|
57
|
-
* holder at a time and replaces an array whole: exactly the two behaviors
|
|
58
|
-
* the rule above needs.
|
|
59
|
-
*/
|
|
60
|
-
import { type ContactInteraction } from './contacts';
|
|
61
|
-
export interface ContactMergePlan {
|
|
62
|
-
/**
|
|
63
|
-
* What the survivor becomes, as a merge-`set` payload: every derived
|
|
64
|
-
* field with its full value, and only the groups the merged record held
|
|
65
|
-
* under `facets`. Plain values throughout — the writer adds its own
|
|
66
|
-
* `updatedAt`.
|
|
67
|
-
*/
|
|
68
|
-
survivor: Record<string, unknown>;
|
|
69
|
-
/** Every address the survivor answers to afterwards, primary first. */
|
|
70
|
-
emails: string[];
|
|
71
|
-
/** The merged record's addresses — what its leads and index entries are keyed by. */
|
|
72
|
-
mergedEmails: string[];
|
|
73
|
-
/**
|
|
74
|
-
* The companies that lose a contact: those BOTH records were filed under,
|
|
75
|
-
* which counted two people and now count one. A company only one record
|
|
76
|
-
* named keeps its count — the survivor still names it.
|
|
77
|
-
*/
|
|
78
|
-
companyCounts: Array<{
|
|
79
|
-
companyId: string;
|
|
80
|
-
delta: -1;
|
|
81
|
-
}>;
|
|
82
|
-
/** The union of both records' scope tokens — who may read the survivor. */
|
|
83
|
-
visibleTo: string[];
|
|
84
|
-
}
|
|
85
|
-
type Doc = Record<string, unknown>;
|
|
86
|
-
/**
|
|
87
|
-
* Both timelines as one: deduplicated by event, newest first, and capped
|
|
88
|
-
* the way every capture caps it — so a merge of two full timelines keeps
|
|
89
|
-
* the fifty most recent visits rather than growing the document past what
|
|
90
|
-
* a capture may write.
|
|
91
|
-
*/
|
|
92
|
-
export declare function mergeInteractions(survivor: readonly ContactInteraction[] | undefined, merged: readonly ContactInteraction[] | undefined): ContactInteraction[];
|
|
93
|
-
/**
|
|
94
|
-
* One holder's facet after the merge.
|
|
95
|
-
*
|
|
96
|
-
* `survivor` is that holder's facet on the surviving record — possibly
|
|
97
|
-
* absent, when only the merged record was held by this group — and `merged`
|
|
98
|
-
* the same holder's facet on the record being folded in.
|
|
99
|
-
*/
|
|
100
|
-
export declare function mergeContactFacet(survivor: Doc | undefined, merged: Doc | undefined): Doc;
|
|
101
|
-
/**
|
|
102
|
-
* The plan for folding `merged` into `survivor`.
|
|
103
|
-
*
|
|
104
|
-
* Both are the stored documents as read. The survivor's `email` is the
|
|
105
|
-
* identity that stands; the merged record's becomes an alternate.
|
|
106
|
-
*/
|
|
107
|
-
export declare function planContactMerge(survivor: Doc, merged: Doc): ContactMergePlan;
|
|
108
|
-
/** Where a previewed value comes from. */
|
|
109
|
-
export type ContactMergeSource = 'survivor' | 'merged' | 'both' | 'none';
|
|
110
|
-
/** One line of the side-by-side the dialog shows. */
|
|
111
|
-
export interface ContactMergePreviewRow {
|
|
112
|
-
key: string;
|
|
113
|
-
label: string;
|
|
114
|
-
/** The surviving record's value, as text. */
|
|
115
|
-
survivor: string;
|
|
116
|
-
/** The merged record's value, as text. */
|
|
117
|
-
merged: string;
|
|
118
|
-
/** What the survivor carries afterwards. */
|
|
119
|
-
result: string;
|
|
120
|
-
from: ContactMergeSource;
|
|
121
|
-
}
|
|
122
|
-
export interface ContactMergePreviewOptions {
|
|
123
|
-
/** The owner's display name for a uid; the uid itself when absent. */
|
|
124
|
-
memberName?: (uid: string) => string;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* The merge as the viewing group would see it, field by field.
|
|
128
|
-
*
|
|
129
|
-
* Reads through ONE group's facet, the way the record page does, so a
|
|
130
|
-
* holder previewing a merge sees its own values and never another holder's.
|
|
131
|
-
* Every row carries the survivor's value, the merged record's, and the
|
|
132
|
-
* result the plan would write, so the dialog is a rendering and not a second
|
|
133
|
-
* opinion.
|
|
134
|
-
*/
|
|
135
|
-
export declare function contactMergePreview(survivor: Doc, merged: Doc, groupId: string, options?: ContactMergePreviewOptions): ContactMergePreviewRow[];
|
|
136
|
-
export {};
|