@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.
Files changed (455) hide show
  1. package/package.json +12 -12
  2. package/src/lib/app-utils/actions.d.ts +26 -433
  3. package/src/lib/app-utils/actions.js +108 -633
  4. package/src/lib/app-utils/actions.js.map +1 -1
  5. package/src/lib/app-utils/activity-presenter.d.ts +3 -3
  6. package/src/lib/app-utils/activity-presenter.js +36 -52
  7. package/src/lib/app-utils/activity-presenter.js.map +1 -1
  8. package/src/lib/app-utils/analytics-events.d.ts +1 -1
  9. package/src/lib/app-utils/analytics-events.js.map +1 -1
  10. package/src/lib/app-utils/analytics-provider.d.ts +182 -0
  11. package/src/lib/app-utils/analytics-provider.js +133 -0
  12. package/src/lib/app-utils/analytics-provider.js.map +1 -0
  13. package/src/lib/app-utils/api-plugins.d.ts +46 -0
  14. package/src/lib/app-utils/api-plugins.js +19 -0
  15. package/src/lib/app-utils/api-plugins.js.map +1 -1
  16. package/src/lib/app-utils/{marketplace-overrides.d.ts → artifact-overrides.d.ts} +9 -6
  17. package/src/lib/app-utils/{marketplace-overrides.js → artifact-overrides.js} +10 -7
  18. package/src/lib/app-utils/artifact-overrides.js.map +1 -0
  19. package/src/lib/app-utils/{marketplace-provenance.d.ts → artifact-provenance.d.ts} +12 -10
  20. package/src/lib/app-utils/{marketplace-provenance.js → artifact-provenance.js} +9 -7
  21. package/src/lib/app-utils/artifact-provenance.js.map +1 -0
  22. package/src/lib/app-utils/binding-token-catalog.d.ts +5 -13
  23. package/src/lib/app-utils/binding-token-catalog.js +17 -41
  24. package/src/lib/app-utils/binding-token-catalog.js.map +1 -1
  25. package/src/lib/app-utils/brand-support-line.d.ts +36 -0
  26. package/src/lib/app-utils/brand-support-line.js +38 -0
  27. package/src/lib/app-utils/brand-support-line.js.map +1 -0
  28. package/src/lib/app-utils/collection-entries.d.ts +2 -2
  29. package/src/lib/app-utils/collection-entries.js.map +1 -1
  30. package/src/lib/app-utils/consent-group-change.d.ts +4 -0
  31. package/src/lib/app-utils/consent-group-change.js.map +1 -1
  32. package/src/lib/app-utils/consent-groups.d.ts +1 -1
  33. package/src/lib/app-utils/consent-groups.js.map +1 -1
  34. package/src/lib/app-utils/console-routes.d.ts +15 -42
  35. package/src/lib/app-utils/console-routes.js +10 -39
  36. package/src/lib/app-utils/console-routes.js.map +1 -1
  37. package/src/lib/app-utils/contacts.d.ts +24 -2
  38. package/src/lib/app-utils/contacts.js +21 -5
  39. package/src/lib/app-utils/contacts.js.map +1 -1
  40. package/src/lib/app-utils/container-membership.d.ts +93 -0
  41. package/src/lib/app-utils/container-membership.js +165 -0
  42. package/src/lib/app-utils/container-membership.js.map +1 -0
  43. package/src/lib/app-utils/crm-task-reminders.d.ts +23 -6
  44. package/src/lib/app-utils/crm-task-reminders.js +32 -11
  45. package/src/lib/app-utils/crm-task-reminders.js.map +1 -1
  46. package/src/lib/app-utils/crm.d.ts +24 -4
  47. package/src/lib/app-utils/crm.js +23 -0
  48. package/src/lib/app-utils/crm.js.map +1 -1
  49. package/src/lib/app-utils/cross-pool-desync.d.ts +39 -0
  50. package/src/lib/app-utils/cross-pool-desync.js +47 -0
  51. package/src/lib/app-utils/cross-pool-desync.js.map +1 -0
  52. package/src/lib/app-utils/csv-upload.d.ts +29 -0
  53. package/src/lib/app-utils/csv-upload.js +29 -0
  54. package/src/lib/app-utils/csv-upload.js.map +1 -0
  55. package/src/lib/app-utils/{dataset-csv.d.ts → csv.d.ts} +10 -43
  56. package/src/lib/app-utils/{dataset-csv.js → csv.js} +10 -81
  57. package/src/lib/app-utils/csv.js.map +1 -0
  58. package/src/lib/app-utils/dataset-models.d.ts +5 -5
  59. package/src/lib/app-utils/dataset-models.js +19 -2
  60. package/src/lib/app-utils/dataset-models.js.map +1 -1
  61. package/src/lib/app-utils/datasets.d.ts +65 -30
  62. package/src/lib/app-utils/datasets.js +74 -24
  63. package/src/lib/app-utils/datasets.js.map +1 -1
  64. package/src/lib/app-utils/docs-deflection.d.ts +6 -6
  65. package/src/lib/app-utils/docs-deflection.js.map +1 -1
  66. package/src/lib/app-utils/docs-help.generated.d.ts +14 -8
  67. package/src/lib/app-utils/docs-help.generated.js +23 -6
  68. package/src/lib/app-utils/docs-help.generated.js.map +1 -1
  69. package/src/lib/app-utils/docs-index.generated.d.ts +2 -2
  70. package/src/lib/app-utils/docs-index.generated.js +570 -346
  71. package/src/lib/app-utils/docs-index.generated.js.map +1 -1
  72. package/src/lib/app-utils/docs-retrieval.d.ts +3 -3
  73. package/src/lib/app-utils/docs-retrieval.js +14 -10
  74. package/src/lib/app-utils/docs-retrieval.js.map +1 -1
  75. package/src/lib/app-utils/duplicate-resource.d.ts +4 -1
  76. package/src/lib/app-utils/duplicate-resource.js +7 -4
  77. package/src/lib/app-utils/duplicate-resource.js.map +1 -1
  78. package/src/lib/app-utils/dynamic-list-rule.d.ts +1 -1
  79. package/src/lib/app-utils/dynamic-list-rule.js +3 -3
  80. package/src/lib/app-utils/dynamic-list-rule.js.map +1 -1
  81. package/src/lib/app-utils/element-ui.d.ts +1 -1
  82. package/src/lib/app-utils/element-ui.js +1 -1
  83. package/src/lib/app-utils/element-ui.js.map +1 -1
  84. package/src/lib/app-utils/email-starter-policy.js +3 -3
  85. package/src/lib/app-utils/email-starter-policy.js.map +1 -1
  86. package/src/lib/app-utils/email-text.d.ts +80 -0
  87. package/src/lib/app-utils/email-text.js +189 -0
  88. package/src/lib/app-utils/email-text.js.map +1 -0
  89. package/src/lib/app-utils/{list-assignment-policy.d.ts → enrollment-basis.d.ts} +4 -0
  90. package/src/lib/app-utils/{list-assignment-policy.js → enrollment-basis.js} +5 -1
  91. package/src/lib/app-utils/enrollment-basis.js.map +1 -0
  92. package/src/lib/app-utils/entity-picker-context.d.ts +10 -5
  93. package/src/lib/app-utils/entity-picker-context.js.map +1 -1
  94. package/src/lib/app-utils/error-beacon.d.ts +75 -6
  95. package/src/lib/app-utils/error-beacon.js +160 -21
  96. package/src/lib/app-utils/error-beacon.js.map +1 -1
  97. package/src/lib/app-utils/expand-repeatables.d.ts +10 -10
  98. package/src/lib/app-utils/expand-repeatables.js +14 -14
  99. package/src/lib/app-utils/expand-repeatables.js.map +1 -1
  100. package/src/lib/app-utils/forms.js +2 -2
  101. package/src/lib/app-utils/forms.js.map +1 -1
  102. package/src/lib/app-utils/health-report.d.ts +2 -3
  103. package/src/lib/app-utils/health-report.js +8 -6
  104. package/src/lib/app-utils/health-report.js.map +1 -1
  105. package/src/lib/app-utils/host-events.d.ts +82 -0
  106. package/src/lib/app-utils/host-events.js +62 -0
  107. package/src/lib/app-utils/host-events.js.map +1 -0
  108. package/src/lib/app-utils/inbound-mail-domain.d.ts +27 -0
  109. package/src/lib/app-utils/inbound-mail-domain.js +31 -0
  110. package/src/lib/app-utils/inbound-mail-domain.js.map +1 -0
  111. package/src/lib/app-utils/lockdown.d.ts +11 -0
  112. package/src/lib/app-utils/lockdown.js +33 -3
  113. package/src/lib/app-utils/lockdown.js.map +1 -1
  114. package/src/lib/app-utils/margin-utilization.d.ts +4 -69
  115. package/src/lib/app-utils/margin-utilization.js +82 -69
  116. package/src/lib/app-utils/margin-utilization.js.map +1 -1
  117. package/src/lib/app-utils/member-email-aliases.d.ts +25 -0
  118. package/src/lib/app-utils/member-email-aliases.js +29 -0
  119. package/src/lib/app-utils/member-email-aliases.js.map +1 -1
  120. package/src/lib/app-utils/node-definition-sanitizer.d.ts +16 -16
  121. package/src/lib/app-utils/node-definition-sanitizer.js +24 -20
  122. package/src/lib/app-utils/node-definition-sanitizer.js.map +1 -1
  123. package/src/lib/app-utils/node-interactions.d.ts +7 -7
  124. package/src/lib/app-utils/node-interactions.js.map +1 -1
  125. package/src/lib/app-utils/notifications.d.ts +147 -47
  126. package/src/lib/app-utils/notifications.js +182 -44
  127. package/src/lib/app-utils/notifications.js.map +1 -1
  128. package/src/lib/app-utils/operator-alerts.d.ts +15 -1
  129. package/src/lib/app-utils/operator-alerts.js +47 -10
  130. package/src/lib/app-utils/operator-alerts.js.map +1 -1
  131. package/src/lib/app-utils/payments-configured.d.ts +8 -21
  132. package/src/lib/app-utils/payments-configured.js +8 -23
  133. package/src/lib/app-utils/payments-configured.js.map +1 -1
  134. package/src/lib/app-utils/plan-entitlements.d.ts +207 -306
  135. package/src/lib/app-utils/plan-entitlements.js +345 -528
  136. package/src/lib/app-utils/plan-entitlements.js.map +1 -1
  137. package/src/lib/app-utils/platform-brand.d.ts +10 -0
  138. package/src/lib/app-utils/platform-brand.js +14 -3
  139. package/src/lib/app-utils/platform-brand.js.map +1 -1
  140. package/src/lib/app-utils/platform-marketing-consent.d.ts +56 -2
  141. package/src/lib/app-utils/platform-marketing-consent.js +6 -5
  142. package/src/lib/app-utils/platform-marketing-consent.js.map +1 -1
  143. package/src/lib/app-utils/plugin-api-rate-limit.d.ts +7 -1
  144. package/src/lib/app-utils/plugin-api-rate-limit.js +11 -3
  145. package/src/lib/app-utils/plugin-api-rate-limit.js.map +1 -1
  146. package/src/lib/app-utils/plugin-bundle-checks.js +2 -2
  147. package/src/lib/app-utils/plugin-bundle-checks.js.map +1 -1
  148. package/src/lib/app-utils/plugin-host-events.generated.d.ts +12 -0
  149. package/src/lib/app-utils/plugin-host-events.generated.js +169 -0
  150. package/src/lib/app-utils/plugin-host-events.generated.js.map +1 -0
  151. package/src/lib/app-utils/plugin-release-flags.generated.d.ts +12 -0
  152. package/src/lib/app-utils/plugin-release-flags.generated.js +106 -0
  153. package/src/lib/app-utils/plugin-release-flags.generated.js.map +1 -0
  154. package/src/lib/app-utils/plugin-starter-templates.generated.d.ts +12 -0
  155. package/src/lib/app-utils/plugin-starter-templates.generated.js +711 -0
  156. package/src/lib/app-utils/plugin-starter-templates.generated.js.map +1 -0
  157. package/src/lib/app-utils/realm-host-surface.generated.js +2 -0
  158. package/src/lib/app-utils/realm-host-surface.generated.js.map +1 -1
  159. package/src/lib/app-utils/release-flags.d.ts +14 -5
  160. package/src/lib/app-utils/release-flags.js +21 -125
  161. package/src/lib/app-utils/release-flags.js.map +1 -1
  162. package/src/lib/app-utils/repeat-query.d.ts +56 -0
  163. package/src/lib/app-utils/{dataset-query.js → repeat-query.js} +16 -16
  164. package/src/lib/app-utils/repeat-query.js.map +1 -0
  165. package/src/lib/app-utils/repeat-sources.d.ts +9 -0
  166. package/src/lib/app-utils/repeat-sources.js.map +1 -1
  167. package/src/lib/app-utils/retained-refusals.d.ts +73 -0
  168. package/src/lib/app-utils/retained-refusals.js +186 -0
  169. package/src/lib/app-utils/retained-refusals.js.map +1 -0
  170. package/src/lib/app-utils/scope-tokens.d.ts +27 -0
  171. package/src/lib/app-utils/scope-tokens.js +61 -0
  172. package/src/lib/app-utils/scope-tokens.js.map +1 -1
  173. package/src/lib/app-utils/screen-link-context.js +3 -3
  174. package/src/lib/app-utils/screen-link-context.js.map +1 -1
  175. package/src/lib/app-utils/screen-route.js +1 -1
  176. package/src/lib/app-utils/screen-route.js.map +1 -1
  177. package/src/lib/app-utils/seo-audit.d.ts +132 -0
  178. package/src/lib/app-utils/seo-audit.js +246 -0
  179. package/src/lib/app-utils/seo-audit.js.map +1 -0
  180. package/src/lib/app-utils/seo-keywords.d.ts +48 -0
  181. package/src/lib/app-utils/seo-keywords.js +60 -0
  182. package/src/lib/app-utils/seo-keywords.js.map +1 -0
  183. package/src/lib/app-utils/seo-page-facts.d.ts +66 -0
  184. package/src/lib/app-utils/seo-page-facts.js +155 -0
  185. package/src/lib/app-utils/seo-page-facts.js.map +1 -0
  186. package/src/lib/app-utils/seo-site-scan.d.ts +126 -0
  187. package/src/lib/app-utils/seo-site-scan.js +162 -0
  188. package/src/lib/app-utils/seo-site-scan.js.map +1 -0
  189. package/src/lib/app-utils/seo-title-variables.js +1 -1
  190. package/src/lib/app-utils/seo-title-variables.js.map +1 -1
  191. package/src/lib/app-utils/server.d.ts +13 -18
  192. package/src/lib/app-utils/server.js +33 -51
  193. package/src/lib/app-utils/server.js.map +1 -1
  194. package/src/lib/app-utils/site-interactions.d.ts +501 -0
  195. package/src/lib/app-utils/site-interactions.js +554 -0
  196. package/src/lib/app-utils/site-interactions.js.map +1 -0
  197. package/src/lib/app-utils/{marketplace-theme.d.ts → site-theme.d.ts} +13 -2
  198. package/src/lib/app-utils/{marketplace-theme.js → site-theme.js} +2 -2
  199. package/src/lib/app-utils/site-theme.js.map +1 -0
  200. package/src/lib/app-utils/sitemap.d.ts +4 -3
  201. package/src/lib/app-utils/sitemap.js +9 -7
  202. package/src/lib/app-utils/sitemap.js.map +1 -1
  203. package/src/lib/app-utils/stale-build-error.d.ts +51 -0
  204. package/src/lib/app-utils/stale-build-error.js +100 -1
  205. package/src/lib/app-utils/stale-build-error.js.map +1 -1
  206. package/src/lib/app-utils/starter-template-nodes.d.ts +137 -0
  207. package/src/lib/app-utils/starter-template-nodes.js +129 -0
  208. package/src/lib/app-utils/starter-template-nodes.js.map +1 -0
  209. package/src/lib/app-utils/starter-templates.d.ts +11 -34
  210. package/src/lib/app-utils/starter-templates.js +19 -230
  211. package/src/lib/app-utils/starter-templates.js.map +1 -1
  212. package/src/lib/app-utils/{email-topics.d.ts → subscription-topics.d.ts} +64 -48
  213. package/src/lib/app-utils/{email-topics.js → subscription-topics.js} +39 -109
  214. package/src/lib/app-utils/subscription-topics.js.map +1 -0
  215. package/src/lib/app-utils/tax-jurisdiction-figures.d.ts +118 -0
  216. package/src/lib/app-utils/tax-jurisdiction-figures.js +123 -0
  217. package/src/lib/app-utils/tax-jurisdiction-figures.js.map +1 -0
  218. package/src/lib/app-utils/theme-library.d.ts +10 -3
  219. package/src/lib/app-utils/theme-library.js +13 -4
  220. package/src/lib/app-utils/theme-library.js.map +1 -1
  221. package/src/lib/app-utils/usage-budget.d.ts +73 -188
  222. package/src/lib/app-utils/usage-budget.js +58 -194
  223. package/src/lib/app-utils/usage-budget.js.map +1 -1
  224. package/src/lib/app-utils/{campaign-attribution.d.ts → utm-attribution.d.ts} +11 -6
  225. package/src/lib/app-utils/{campaign-attribution.js → utm-attribution.js} +13 -8
  226. package/src/lib/app-utils/utm-attribution.js.map +1 -0
  227. package/src/lib/app-utils/{campaign-forwarding.d.ts → utm-forwarding.d.ts} +14 -14
  228. package/src/lib/app-utils/{campaign-forwarding.js → utm-forwarding.js} +26 -26
  229. package/src/lib/app-utils/utm-forwarding.js.map +1 -0
  230. package/src/lib/app-utils/{campaign-touch.d.ts → utm-touch.d.ts} +25 -17
  231. package/src/lib/app-utils/{campaign-touch.js → utm-touch.js} +38 -30
  232. package/src/lib/app-utils/utm-touch.js.map +1 -0
  233. package/src/lib/app-utils/variables.d.ts +9 -9
  234. package/src/lib/app-utils/variables.js.map +1 -1
  235. package/src/lib/app-utils/video-object.js +6 -5
  236. package/src/lib/app-utils/video-object.js.map +1 -1
  237. package/src/lib/app-utils/visitor-consent.d.ts +41 -164
  238. package/src/lib/app-utils/visitor-consent.js +66 -277
  239. package/src/lib/app-utils/visitor-consent.js.map +1 -1
  240. package/src/lib/app-utils/visitor-record-ceiling.d.ts +32 -0
  241. package/src/lib/app-utils/visitor-record-ceiling.js +39 -0
  242. package/src/lib/app-utils/visitor-record-ceiling.js.map +1 -1
  243. package/src/lib/app-utils/web-vitals-rum.d.ts +7 -7
  244. package/src/lib/app-utils/web-vitals-rum.js +31 -63
  245. package/src/lib/app-utils/web-vitals-rum.js.map +1 -1
  246. package/src/lib/app-utils/where-used.d.ts +11 -6
  247. package/src/lib/app-utils/where-used.js +3 -8
  248. package/src/lib/app-utils/where-used.js.map +1 -1
  249. package/src/lib/foundation/definitions/components.types.d.ts +1 -1
  250. package/src/lib/foundation/definitions/components.types.js +1 -1
  251. package/src/lib/foundation/definitions/components.types.js.map +1 -1
  252. package/src/lib/foundation/definitions/org-billing.types.d.ts +11 -137
  253. package/src/lib/foundation/definitions/org-billing.types.js.map +1 -1
  254. package/src/lib/foundation/definitions/organization.types.d.ts +1 -3
  255. package/src/lib/foundation/definitions/organization.types.js.map +1 -1
  256. package/src/lib/foundation/definitions/platform.types.d.ts +11 -5
  257. package/src/lib/foundation/definitions/platform.types.js.map +1 -1
  258. package/src/lib/foundation/definitions/write-deny-coverage.util.d.ts +16 -0
  259. package/src/lib/foundation/definitions/write-deny-coverage.util.js +20 -0
  260. package/src/lib/foundation/definitions/write-deny-coverage.util.js.map +1 -1
  261. package/src/lib/foundation/index.d.ts +1 -1
  262. package/src/lib/foundation/index.js.map +1 -1
  263. package/src/lib/plugin-manager/besigner-documents.d.ts +96 -0
  264. package/src/lib/plugin-manager/besigner-documents.js +61 -0
  265. package/src/lib/plugin-manager/besigner-documents.js.map +1 -0
  266. package/src/lib/plugin-manager/computed-variables.d.ts +71 -0
  267. package/src/lib/plugin-manager/computed-variables.js +74 -0
  268. package/src/lib/plugin-manager/computed-variables.js.map +1 -0
  269. package/src/lib/plugin-manager/custom-fields.d.ts +29 -2
  270. package/src/lib/plugin-manager/custom-fields.js +47 -1
  271. package/src/lib/plugin-manager/custom-fields.js.map +1 -1
  272. package/src/lib/plugin-manager/feature-plugins.d.ts +372 -99
  273. package/src/lib/plugin-manager/feature-plugins.js +126 -51
  274. package/src/lib/plugin-manager/feature-plugins.js.map +1 -1
  275. package/src/lib/plugin-manager/first-party-plugins.generated.d.ts +134 -0
  276. package/src/lib/plugin-manager/first-party-plugins.generated.js +840 -10
  277. package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -1
  278. package/src/lib/plugin-manager/index.d.ts +0 -1
  279. package/src/lib/plugin-manager/index.js +0 -1
  280. package/src/lib/plugin-manager/index.js.map +1 -1
  281. package/src/lib/plugin-manager/plugin-activity-actions.d.ts +12 -0
  282. package/src/lib/plugin-manager/plugin-activity-actions.js +25 -0
  283. package/src/lib/plugin-manager/plugin-activity-actions.js.map +1 -1
  284. package/src/lib/plugin-manager/plugin-contact-capture.d.ts +9 -4
  285. package/src/lib/plugin-manager/plugin-contact-capture.js.map +1 -1
  286. package/src/lib/plugin-manager/plugin-containers.d.ts +68 -0
  287. package/src/lib/plugin-manager/plugin-containers.generated.d.ts +10 -0
  288. package/src/lib/plugin-manager/plugin-containers.generated.js +20 -0
  289. package/src/lib/plugin-manager/plugin-containers.generated.js.map +1 -0
  290. package/src/lib/plugin-manager/plugin-containers.js +27 -0
  291. package/src/lib/plugin-manager/plugin-containers.js.map +1 -0
  292. package/src/lib/plugin-manager/plugin-contributions.d.ts +1 -1
  293. package/src/lib/plugin-manager/plugin-contributions.js.map +1 -1
  294. package/src/lib/plugin-manager/plugin-declarations-repair.d.ts +36 -0
  295. package/src/lib/plugin-manager/plugin-declarations-repair.js +64 -0
  296. package/src/lib/plugin-manager/plugin-declarations-repair.js.map +1 -0
  297. package/src/lib/plugin-manager/plugin-dependents.d.ts +101 -0
  298. package/src/lib/plugin-manager/plugin-dependents.js +75 -0
  299. package/src/lib/plugin-manager/plugin-dependents.js.map +1 -0
  300. package/src/lib/plugin-manager/plugin-distribution.d.ts +55 -0
  301. package/src/lib/plugin-manager/plugin-distribution.js +45 -0
  302. package/src/lib/plugin-manager/plugin-distribution.js.map +1 -0
  303. package/src/lib/plugin-manager/plugin-entitlements.d.ts +8 -0
  304. package/src/lib/plugin-manager/plugin-entitlements.js.map +1 -1
  305. package/src/lib/plugin-manager/plugin-host-collections.d.ts +17 -0
  306. package/src/lib/plugin-manager/plugin-host-collections.js +6 -0
  307. package/src/lib/plugin-manager/plugin-host-collections.js.map +1 -1
  308. package/src/lib/plugin-manager/plugin-host-resources.d.ts +133 -0
  309. package/src/lib/plugin-manager/plugin-host-resources.js +52 -0
  310. package/src/lib/plugin-manager/plugin-host-resources.js.map +1 -0
  311. package/src/lib/plugin-manager/plugin-membership-detach.js +1 -1
  312. package/src/lib/plugin-manager/plugin-membership-detach.js.map +1 -1
  313. package/src/lib/plugin-manager/plugin-org-erasure.d.ts +28 -2
  314. package/src/lib/plugin-manager/plugin-org-erasure.js +61 -2
  315. package/src/lib/plugin-manager/plugin-org-erasure.js.map +1 -1
  316. package/src/lib/plugin-manager/plugin-plan-entitlements.d.ts +123 -0
  317. package/src/lib/plugin-manager/plugin-plan-entitlements.js +101 -0
  318. package/src/lib/plugin-manager/plugin-plan-entitlements.js.map +1 -0
  319. package/src/lib/plugin-manager/plugin-record-email-state.d.ts +69 -0
  320. package/src/lib/plugin-manager/plugin-record-email-state.js +32 -0
  321. package/src/lib/plugin-manager/plugin-record-email-state.js.map +1 -1
  322. package/src/lib/plugin-manager/plugin-record-index.d.ts +95 -0
  323. package/src/lib/plugin-manager/plugin-record-index.js +51 -0
  324. package/src/lib/plugin-manager/plugin-record-index.js.map +1 -0
  325. package/src/lib/plugin-manager/plugin-record-lists.d.ts +115 -0
  326. package/src/lib/plugin-manager/plugin-record-lists.js +75 -0
  327. package/src/lib/plugin-manager/plugin-record-lists.js.map +1 -0
  328. package/src/lib/plugin-manager/plugin-record-timeline.d.ts +42 -8
  329. package/src/lib/plugin-manager/plugin-record-timeline.js.map +1 -1
  330. package/src/lib/plugin-manager/plugin-record-written.d.ts +58 -0
  331. package/src/lib/plugin-manager/plugin-record-written.js +42 -0
  332. package/src/lib/plugin-manager/plugin-record-written.js.map +1 -0
  333. package/src/lib/plugin-manager/plugin-revenue-sources.d.ts +213 -0
  334. package/src/lib/plugin-manager/plugin-revenue-sources.js +194 -0
  335. package/src/lib/plugin-manager/plugin-revenue-sources.js.map +1 -0
  336. package/src/lib/plugin-manager/plugin-site-beacons.d.ts +71 -0
  337. package/src/lib/plugin-manager/plugin-site-beacons.js +54 -0
  338. package/src/lib/plugin-manager/plugin-site-beacons.js.map +1 -0
  339. package/src/lib/plugin-manager/plugin-site-bundle.d.ts +145 -0
  340. package/src/lib/plugin-manager/plugin-site-bundle.js +78 -0
  341. package/src/lib/plugin-manager/plugin-site-bundle.js.map +1 -0
  342. package/src/lib/plugin-manager/plugin-site-cache.d.ts +12 -0
  343. package/src/lib/plugin-manager/plugin-site-cache.js.map +1 -1
  344. package/src/lib/plugin-manager/plugin-site-export.d.ts +81 -0
  345. package/src/lib/plugin-manager/plugin-site-export.js +40 -0
  346. package/src/lib/plugin-manager/plugin-site-export.js.map +1 -0
  347. package/src/lib/plugin-manager/plugin-sitemap-sections.d.ts +88 -0
  348. package/src/lib/plugin-manager/plugin-sitemap-sections.js +29 -0
  349. package/src/lib/plugin-manager/plugin-sitemap-sections.js.map +1 -0
  350. package/src/lib/plugin-manager/plugin-subscription-topics.generated.d.ts +11 -0
  351. package/src/lib/plugin-manager/plugin-subscription-topics.generated.js +41 -0
  352. package/src/lib/plugin-manager/plugin-subscription-topics.generated.js.map +1 -0
  353. package/src/lib/plugin-manager/plugin-tax-profile.d.ts +20 -4
  354. package/src/lib/plugin-manager/plugin-tax-profile.js.map +1 -1
  355. package/src/lib/plugin-manager/plugin-tax-return-sources.d.ts +255 -0
  356. package/src/lib/plugin-manager/plugin-tax-return-sources.js +191 -0
  357. package/src/lib/plugin-manager/plugin-tax-return-sources.js.map +1 -0
  358. package/src/lib/plugin-manager/plugin-template-sources.d.ts +75 -0
  359. package/src/lib/plugin-manager/plugin-template-sources.js +37 -0
  360. package/src/lib/plugin-manager/plugin-template-sources.js.map +1 -0
  361. package/src/lib/plugin-manager/plugin-usage-axes.d.ts +319 -0
  362. package/src/lib/plugin-manager/plugin-usage-axes.js +186 -0
  363. package/src/lib/plugin-manager/plugin-usage-axes.js.map +1 -0
  364. package/src/lib/plugin-manager/plugin-usage-meters.d.ts +108 -0
  365. package/src/lib/plugin-manager/plugin-usage-meters.js +105 -0
  366. package/src/lib/plugin-manager/plugin-usage-meters.js.map +1 -0
  367. package/src/lib/plugin-manager/plugin-zones.d.ts +4 -5
  368. package/src/lib/plugin-manager/plugin-zones.js.map +1 -1
  369. package/src/lib/plugin-manager/realm-host-aglyn.generated.js +2 -0
  370. package/src/lib/plugin-manager/realm-host-aglyn.generated.js.map +1 -1
  371. package/src/lib/plugin-manager/record-captured-contact.d.ts +1 -14
  372. package/src/lib/plugin-manager/record-captured-contact.js +10 -32
  373. package/src/lib/plugin-manager/record-captured-contact.js.map +1 -1
  374. package/src/lib/plugin-manager/repeat-rows.d.ts +124 -0
  375. package/src/lib/plugin-manager/repeat-rows.js +108 -0
  376. package/src/lib/plugin-manager/repeat-rows.js.map +1 -0
  377. package/src/lib/plugin-manager/submission-record-target.d.ts +144 -0
  378. package/src/lib/plugin-manager/submission-record-target.js +125 -0
  379. package/src/lib/plugin-manager/submission-record-target.js.map +1 -0
  380. package/src/lib/plugin-manager/usage-alert-contributors.d.ts +76 -6
  381. package/src/lib/plugin-manager/usage-alert-contributors.js +23 -10
  382. package/src/lib/plugin-manager/usage-alert-contributors.js.map +1 -1
  383. package/src/lib/plugin-manager/video-embed-provider.d.ts +108 -0
  384. package/src/lib/plugin-manager/video-embed-provider.js +165 -0
  385. package/src/lib/plugin-manager/video-embed-provider.js.map +1 -0
  386. package/src/lib/types/nodes.d.ts +2 -2
  387. package/src/lib/types/nodes.js.map +1 -1
  388. package/src/lib/app-utils/assist-credits.d.ts +0 -482
  389. package/src/lib/app-utils/assist-credits.js +0 -509
  390. package/src/lib/app-utils/assist-credits.js.map +0 -1
  391. package/src/lib/app-utils/campaign-attribution.js.map +0 -1
  392. package/src/lib/app-utils/campaign-forwarding.js.map +0 -1
  393. package/src/lib/app-utils/campaign-membership.d.ts +0 -121
  394. package/src/lib/app-utils/campaign-membership.js +0 -189
  395. package/src/lib/app-utils/campaign-membership.js.map +0 -1
  396. package/src/lib/app-utils/campaign-touch.js.map +0 -1
  397. package/src/lib/app-utils/console-record-links.d.ts +0 -163
  398. package/src/lib/app-utils/console-record-links.js +0 -180
  399. package/src/lib/app-utils/console-record-links.js.map +0 -1
  400. package/src/lib/app-utils/contact-holder.d.ts +0 -68
  401. package/src/lib/app-utils/contact-holder.js +0 -129
  402. package/src/lib/app-utils/contact-holder.js.map +0 -1
  403. package/src/lib/app-utils/contact-merge.d.ts +0 -136
  404. package/src/lib/app-utils/contact-merge.js +0 -412
  405. package/src/lib/app-utils/contact-merge.js.map +0 -1
  406. package/src/lib/app-utils/crm-booking.d.ts +0 -75
  407. package/src/lib/app-utils/crm-booking.js +0 -133
  408. package/src/lib/app-utils/crm-booking.js.map +0 -1
  409. package/src/lib/app-utils/crm-csv.d.ts +0 -239
  410. package/src/lib/app-utils/crm-csv.js +0 -467
  411. package/src/lib/app-utils/crm-csv.js.map +0 -1
  412. package/src/lib/app-utils/crm-digest.d.ts +0 -185
  413. package/src/lib/app-utils/crm-digest.js +0 -272
  414. package/src/lib/app-utils/crm-digest.js.map +0 -1
  415. package/src/lib/app-utils/crm-inbound.d.ts +0 -245
  416. package/src/lib/app-utils/crm-inbound.js +0 -407
  417. package/src/lib/app-utils/crm-inbound.js.map +0 -1
  418. package/src/lib/app-utils/crm-reports.d.ts +0 -479
  419. package/src/lib/app-utils/crm-reports.js +0 -680
  420. package/src/lib/app-utils/crm-reports.js.map +0 -1
  421. package/src/lib/app-utils/dataset-csv.js.map +0 -1
  422. package/src/lib/app-utils/dataset-query.d.ts +0 -57
  423. package/src/lib/app-utils/dataset-query.js.map +0 -1
  424. package/src/lib/app-utils/email-topics.js.map +0 -1
  425. package/src/lib/app-utils/form-dataset-binding.d.ts +0 -50
  426. package/src/lib/app-utils/form-dataset-binding.js +0 -74
  427. package/src/lib/app-utils/form-dataset-binding.js.map +0 -1
  428. package/src/lib/app-utils/list-assignment-policy.js.map +0 -1
  429. package/src/lib/app-utils/list-import.d.ts +0 -158
  430. package/src/lib/app-utils/list-import.js +0 -332
  431. package/src/lib/app-utils/list-import.js.map +0 -1
  432. package/src/lib/app-utils/marketplace-listing-visibility.d.ts +0 -122
  433. package/src/lib/app-utils/marketplace-listing-visibility.js +0 -147
  434. package/src/lib/app-utils/marketplace-listing-visibility.js.map +0 -1
  435. package/src/lib/app-utils/marketplace-overrides.js.map +0 -1
  436. package/src/lib/app-utils/marketplace-provenance.js.map +0 -1
  437. package/src/lib/app-utils/marketplace-theme.js.map +0 -1
  438. package/src/lib/app-utils/marketplace-update-state.d.ts +0 -119
  439. package/src/lib/app-utils/marketplace-update-state.js +0 -132
  440. package/src/lib/app-utils/marketplace-update-state.js.map +0 -1
  441. package/src/lib/app-utils/publisher-agreement.d.ts +0 -289
  442. package/src/lib/app-utils/publisher-agreement.js +0 -321
  443. package/src/lib/app-utils/publisher-agreement.js.map +0 -1
  444. package/src/lib/app-utils/wistia-embed.d.ts +0 -104
  445. package/src/lib/app-utils/wistia-embed.js +0 -138
  446. package/src/lib/app-utils/wistia-embed.js.map +0 -1
  447. package/src/lib/app-utils/workflows.d.ts +0 -136
  448. package/src/lib/app-utils/workflows.js +0 -346
  449. package/src/lib/app-utils/workflows.js.map +0 -1
  450. package/src/lib/plugin-manager/commerce-zone-props.d.ts +0 -172
  451. package/src/lib/plugin-manager/commerce-zone-props.js +0 -31
  452. package/src/lib/plugin-manager/commerce-zone-props.js.map +0 -1
  453. package/src/lib/plugin-manager/plugin-metered-lines.d.ts +0 -97
  454. package/src/lib/plugin-manager/plugin-metered-lines.js +0 -123
  455. 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 {};