@aglyn/aglyn 1.0.0-beta.221 → 1.0.0-beta.222

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 (346) hide show
  1. package/package.json +15 -11
  2. package/src/lib/app-utils/agent-openapi.js +1 -1
  3. package/src/lib/app-utils/agent-openapi.js.map +1 -1
  4. package/src/lib/app-utils/analytics-events.d.ts +3 -2
  5. package/src/lib/app-utils/analytics-events.js +3 -2
  6. package/src/lib/app-utils/analytics-events.js.map +1 -1
  7. package/src/lib/app-utils/api-plugins.d.ts +30 -0
  8. package/src/lib/app-utils/api-plugins.js +24 -1
  9. package/src/lib/app-utils/api-plugins.js.map +1 -1
  10. package/src/lib/app-utils/author-html.d.ts +1 -1
  11. package/src/lib/app-utils/author-html.js.map +1 -1
  12. package/src/lib/app-utils/bandwidth-cap.d.ts +12 -1
  13. package/src/lib/app-utils/bandwidth-cap.js +17 -1
  14. package/src/lib/app-utils/bandwidth-cap.js.map +1 -1
  15. package/src/lib/app-utils/compose-reusable-components.d.ts +19 -0
  16. package/src/lib/app-utils/compose-reusable-components.js +116 -26
  17. package/src/lib/app-utils/compose-reusable-components.js.map +1 -1
  18. package/src/lib/app-utils/console-routes.d.ts +4 -0
  19. package/src/lib/app-utils/console-routes.js +3 -0
  20. package/src/lib/app-utils/console-routes.js.map +1 -1
  21. package/src/lib/app-utils/contacts.d.ts +71 -0
  22. package/src/lib/app-utils/contacts.js +55 -0
  23. package/src/lib/app-utils/contacts.js.map +1 -1
  24. package/src/lib/app-utils/contexts.d.ts +1 -0
  25. package/src/lib/app-utils/contexts.js +1 -0
  26. package/src/lib/app-utils/contexts.js.map +1 -1
  27. package/src/lib/app-utils/crm-email-templates.js +21 -4
  28. package/src/lib/app-utils/crm-email-templates.js.map +1 -1
  29. package/src/lib/app-utils/crm-kinds.d.ts +2 -0
  30. package/src/lib/app-utils/crm-kinds.js +1 -0
  31. package/src/lib/app-utils/crm-kinds.js.map +1 -1
  32. package/src/lib/app-utils/crm.d.ts +1199 -67
  33. package/src/lib/app-utils/crm.js +1951 -310
  34. package/src/lib/app-utils/crm.js.map +1 -1
  35. package/src/lib/app-utils/csv-import.d.ts +10 -38
  36. package/src/lib/app-utils/csv-import.js +17 -42
  37. package/src/lib/app-utils/csv-import.js.map +1 -1
  38. package/src/lib/app-utils/csv.d.ts +32 -11
  39. package/src/lib/app-utils/csv.js +43 -5
  40. package/src/lib/app-utils/csv.js.map +1 -1
  41. package/src/lib/app-utils/default-site.d.ts +116 -0
  42. package/src/lib/app-utils/default-site.js +1024 -0
  43. package/src/lib/app-utils/default-site.js.map +1 -0
  44. package/src/lib/app-utils/docs-help.generated.d.ts +22 -22
  45. package/src/lib/app-utils/docs-help.generated.js +44 -10
  46. package/src/lib/app-utils/docs-help.generated.js.map +1 -1
  47. package/src/lib/app-utils/docs-index.generated.js +738 -150
  48. package/src/lib/app-utils/docs-index.generated.js.map +1 -1
  49. package/src/lib/app-utils/draft-placeholders.d.ts +76 -0
  50. package/src/lib/app-utils/draft-placeholders.js +115 -0
  51. package/src/lib/app-utils/draft-placeholders.js.map +1 -0
  52. package/src/lib/app-utils/entity-picker-context.d.ts +19 -15
  53. package/src/lib/app-utils/entity-picker-context.js +4 -4
  54. package/src/lib/app-utils/entity-picker-context.js.map +1 -1
  55. package/src/lib/app-utils/expand-repeatables.d.ts +66 -10
  56. package/src/lib/app-utils/expand-repeatables.js +88 -14
  57. package/src/lib/app-utils/expand-repeatables.js.map +1 -1
  58. package/src/lib/app-utils/forms.d.ts +33 -22
  59. package/src/lib/app-utils/forms.js +47 -28
  60. package/src/lib/app-utils/forms.js.map +1 -1
  61. package/src/lib/app-utils/full-use-cost.d.ts +277 -0
  62. package/src/lib/app-utils/full-use-cost.js +421 -0
  63. package/src/lib/app-utils/full-use-cost.js.map +1 -0
  64. package/src/lib/app-utils/health-report.js +11 -0
  65. package/src/lib/app-utils/health-report.js.map +1 -1
  66. package/src/lib/app-utils/llms-txt.d.ts +20 -0
  67. package/src/lib/app-utils/llms-txt.js +7 -1
  68. package/src/lib/app-utils/llms-txt.js.map +1 -1
  69. package/src/lib/app-utils/media-asset-facts.d.ts +16 -1
  70. package/src/lib/app-utils/media-asset-facts.js +40 -13
  71. package/src/lib/app-utils/media-asset-facts.js.map +1 -1
  72. package/src/lib/app-utils/media-bandwidth.d.ts +52 -0
  73. package/src/lib/app-utils/media-bandwidth.js +94 -0
  74. package/src/lib/app-utils/media-bandwidth.js.map +1 -0
  75. package/src/lib/app-utils/media-ref.d.ts +241 -33
  76. package/src/lib/app-utils/media-ref.js +324 -43
  77. package/src/lib/app-utils/media-ref.js.map +1 -1
  78. package/src/lib/app-utils/media-src.d.ts +8 -8
  79. package/src/lib/app-utils/media-src.js +27 -11
  80. package/src/lib/app-utils/media-src.js.map +1 -1
  81. package/src/lib/app-utils/media-takedown-reach.d.ts +4 -1
  82. package/src/lib/app-utils/media-takedown-reach.js +6 -3
  83. package/src/lib/app-utils/media-takedown-reach.js.map +1 -1
  84. package/src/lib/app-utils/notifications.d.ts +1 -1
  85. package/src/lib/app-utils/notifications.js +2 -0
  86. package/src/lib/app-utils/notifications.js.map +1 -1
  87. package/src/lib/app-utils/organizations.d.ts +51 -2
  88. package/src/lib/app-utils/organizations.js +56 -3
  89. package/src/lib/app-utils/organizations.js.map +1 -1
  90. package/src/lib/app-utils/page-record-sources.d.ts +87 -0
  91. package/src/lib/app-utils/page-record-sources.js +53 -0
  92. package/src/lib/app-utils/page-record-sources.js.map +1 -0
  93. package/src/lib/app-utils/paid-media-source.d.ts +3 -7
  94. package/src/lib/app-utils/paid-media-source.js +5 -19
  95. package/src/lib/app-utils/paid-media-source.js.map +1 -1
  96. package/src/lib/app-utils/person-erasure.d.ts +5 -2
  97. package/src/lib/app-utils/person-erasure.js.map +1 -1
  98. package/src/lib/app-utils/picklists.d.ts +187 -0
  99. package/src/lib/app-utils/picklists.js +320 -0
  100. package/src/lib/app-utils/picklists.js.map +1 -0
  101. package/src/lib/app-utils/plan-entitlements.d.ts +220 -50
  102. package/src/lib/app-utils/plan-entitlements.js +309 -115
  103. package/src/lib/app-utils/plan-entitlements.js.map +1 -1
  104. package/src/lib/app-utils/realm-host-surface.generated.js +2 -0
  105. package/src/lib/app-utils/realm-host-surface.generated.js.map +1 -1
  106. package/src/lib/app-utils/release-flags.d.ts +1 -1
  107. package/src/lib/app-utils/release-flags.js +11 -0
  108. package/src/lib/app-utils/release-flags.js.map +1 -1
  109. package/src/lib/app-utils/rendered-widths.d.ts +121 -0
  110. package/src/lib/app-utils/rendered-widths.js +211 -0
  111. package/src/lib/app-utils/rendered-widths.js.map +1 -0
  112. package/src/lib/app-utils/repeat-sources.d.ts +2 -1
  113. package/src/lib/app-utils/repeat-sources.js.map +1 -1
  114. package/src/lib/app-utils/screen-route.d.ts +154 -36
  115. package/src/lib/app-utils/screen-route.js +185 -40
  116. package/src/lib/app-utils/screen-route.js.map +1 -1
  117. package/src/lib/app-utils/seo-audit.d.ts +11 -1
  118. package/src/lib/app-utils/seo-audit.js +33 -13
  119. package/src/lib/app-utils/seo-audit.js.map +1 -1
  120. package/src/lib/app-utils/seo-keywords.d.ts +11 -0
  121. package/src/lib/app-utils/seo-keywords.js +19 -5
  122. package/src/lib/app-utils/seo-keywords.js.map +1 -1
  123. package/src/lib/app-utils/seo-page-facts.d.ts +47 -4
  124. package/src/lib/app-utils/seo-page-facts.js +136 -31
  125. package/src/lib/app-utils/seo-page-facts.js.map +1 -1
  126. package/src/lib/app-utils/seo-site-scan.d.ts +42 -4
  127. package/src/lib/app-utils/seo-site-scan.js +113 -12
  128. package/src/lib/app-utils/seo-site-scan.js.map +1 -1
  129. package/src/lib/app-utils/server.d.ts +5 -4
  130. package/src/lib/app-utils/server.js +14 -5
  131. package/src/lib/app-utils/server.js.map +1 -1
  132. package/src/lib/app-utils/site-icon-set.d.ts +195 -0
  133. package/src/lib/app-utils/site-icon-set.js +351 -0
  134. package/src/lib/app-utils/site-icon-set.js.map +1 -0
  135. package/src/lib/app-utils/site-interactions.d.ts +101 -4
  136. package/src/lib/app-utils/site-interactions.js +120 -4
  137. package/src/lib/app-utils/site-interactions.js.map +1 -1
  138. package/src/lib/app-utils/starter-template-nodes.d.ts +7 -0
  139. package/src/lib/app-utils/starter-template-nodes.js +3 -0
  140. package/src/lib/app-utils/starter-template-nodes.js.map +1 -1
  141. package/src/lib/app-utils/starter-templates.d.ts +5 -19
  142. package/src/lib/app-utils/starter-templates.js +5 -49
  143. package/src/lib/app-utils/starter-templates.js.map +1 -1
  144. package/src/lib/app-utils/transfer-launcher-context.d.ts +136 -0
  145. package/src/lib/app-utils/transfer-launcher-context.js +23 -0
  146. package/src/lib/app-utils/transfer-launcher-context.js.map +1 -0
  147. package/src/lib/app-utils/transfer-resume-import.d.ts +39 -0
  148. package/src/lib/app-utils/transfer-resume-import.js +128 -0
  149. package/src/lib/app-utils/transfer-resume-import.js.map +1 -0
  150. package/src/lib/app-utils/upgrade-proposal.d.ts +66 -0
  151. package/src/lib/app-utils/upgrade-proposal.js +95 -0
  152. package/src/lib/app-utils/upgrade-proposal.js.map +1 -0
  153. package/src/lib/app-utils/utc-month.d.ts +33 -0
  154. package/src/lib/app-utils/utc-month.js +35 -0
  155. package/src/lib/app-utils/utc-month.js.map +1 -0
  156. package/src/lib/app-utils/visitor-record-ceiling.d.ts +4 -4
  157. package/src/lib/app-utils/visitor-record-ceiling.js +4 -4
  158. package/src/lib/app-utils/visitor-record-ceiling.js.map +1 -1
  159. package/src/lib/app-utils/wire-nodes.d.ts +39 -19
  160. package/src/lib/app-utils/wire-nodes.js +120 -34
  161. package/src/lib/app-utils/wire-nodes.js.map +1 -1
  162. package/src/lib/data-transfer/access.d.ts +74 -0
  163. package/src/lib/data-transfer/access.js +93 -0
  164. package/src/lib/data-transfer/access.js.map +1 -0
  165. package/src/lib/data-transfer/derive.d.ts +246 -0
  166. package/src/lib/data-transfer/derive.js +1007 -0
  167. package/src/lib/data-transfer/derive.js.map +1 -0
  168. package/src/lib/data-transfer/export-file.d.ts +46 -0
  169. package/src/lib/data-transfer/export-file.js +146 -0
  170. package/src/lib/data-transfer/export-file.js.map +1 -0
  171. package/src/lib/data-transfer/field-catalog.d.ts +134 -0
  172. package/src/lib/data-transfer/field-catalog.js +278 -0
  173. package/src/lib/data-transfer/field-catalog.js.map +1 -0
  174. package/src/lib/data-transfer/header-match.d.ts +129 -0
  175. package/src/lib/data-transfer/header-match.js +367 -0
  176. package/src/lib/data-transfer/header-match.js.map +1 -0
  177. package/src/lib/data-transfer/index.d.ts +34 -0
  178. package/src/lib/data-transfer/index.js +40 -0
  179. package/src/lib/data-transfer/index.js.map +1 -0
  180. package/src/lib/data-transfer/job.d.ts +190 -0
  181. package/src/lib/data-transfer/job.js +229 -0
  182. package/src/lib/data-transfer/job.js.map +1 -0
  183. package/src/lib/data-transfer/lookup.d.ts +45 -0
  184. package/src/lib/data-transfer/lookup.js +71 -0
  185. package/src/lib/data-transfer/lookup.js.map +1 -0
  186. package/src/lib/data-transfer/match.d.ts +99 -0
  187. package/src/lib/data-transfer/match.js +244 -0
  188. package/src/lib/data-transfer/match.js.map +1 -0
  189. package/src/lib/data-transfer/package-plan.d.ts +205 -0
  190. package/src/lib/data-transfer/package-plan.js +475 -0
  191. package/src/lib/data-transfer/package-plan.js.map +1 -0
  192. package/src/lib/data-transfer/package.d.ts +181 -0
  193. package/src/lib/data-transfer/package.js +426 -0
  194. package/src/lib/data-transfer/package.js.map +1 -0
  195. package/src/lib/data-transfer/picklist-map.d.ts +139 -0
  196. package/src/lib/data-transfer/picklist-map.js +271 -0
  197. package/src/lib/data-transfer/picklist-map.js.map +1 -0
  198. package/src/lib/data-transfer/plan.d.ts +176 -0
  199. package/src/lib/data-transfer/plan.js +451 -0
  200. package/src/lib/data-transfer/plan.js.map +1 -0
  201. package/src/lib/data-transfer/policy.d.ts +170 -0
  202. package/src/lib/data-transfer/policy.js +378 -0
  203. package/src/lib/data-transfer/policy.js.map +1 -0
  204. package/src/lib/data-transfer/resource.d.ts +211 -0
  205. package/src/lib/data-transfer/resource.js +241 -0
  206. package/src/lib/data-transfer/resource.js.map +1 -0
  207. package/src/lib/data-transfer/review.d.ts +70 -0
  208. package/src/lib/data-transfer/review.js +233 -0
  209. package/src/lib/data-transfer/review.js.map +1 -0
  210. package/src/lib/data-transfer/similarity.d.ts +40 -0
  211. package/src/lib/data-transfer/similarity.js +106 -0
  212. package/src/lib/data-transfer/similarity.js.map +1 -0
  213. package/src/lib/data-transfer/site-package.d.ts +365 -0
  214. package/src/lib/data-transfer/site-package.js +1077 -0
  215. package/src/lib/data-transfer/site-package.js.map +1 -0
  216. package/src/lib/data-transfer/source.d.ts +74 -0
  217. package/src/lib/data-transfer/source.js +293 -0
  218. package/src/lib/data-transfer/source.js.map +1 -0
  219. package/src/lib/data-transfer/transfer-api.d.ts +898 -0
  220. package/src/lib/data-transfer/transfer-api.js +107 -0
  221. package/src/lib/data-transfer/transfer-api.js.map +1 -0
  222. package/src/lib/foundation/definitions/org-billing.types.d.ts +31 -0
  223. package/src/lib/foundation/definitions/org-billing.types.js.map +1 -1
  224. package/src/lib/foundation/definitions/organization.types.d.ts +42 -1
  225. package/src/lib/foundation/definitions/organization.types.js.map +1 -1
  226. package/src/lib/foundation/definitions/platform.types.d.ts +6 -4
  227. package/src/lib/foundation/definitions/platform.types.js.map +1 -1
  228. package/src/lib/foundation/index.d.ts +1 -1
  229. package/src/lib/foundation/index.js.map +1 -1
  230. package/src/lib/plugin-manager/feature-plugins.d.ts +91 -2
  231. package/src/lib/plugin-manager/feature-plugins.js +48 -3
  232. package/src/lib/plugin-manager/feature-plugins.js.map +1 -1
  233. package/src/lib/plugin-manager/first-party-plugins.generated.d.ts +50 -0
  234. package/src/lib/plugin-manager/first-party-plugins.generated.js +1129 -28
  235. package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -1
  236. package/src/lib/plugin-manager/index.d.ts +0 -1
  237. package/src/lib/plugin-manager/index.js +0 -1
  238. package/src/lib/plugin-manager/index.js.map +1 -1
  239. package/src/lib/plugin-manager/interaction-recipes.d.ts +142 -0
  240. package/src/lib/plugin-manager/interaction-recipes.js +104 -0
  241. package/src/lib/plugin-manager/interaction-recipes.js.map +1 -0
  242. package/src/lib/plugin-manager/interaction-step-checks.d.ts +66 -0
  243. package/src/lib/plugin-manager/interaction-step-checks.js +86 -0
  244. package/src/lib/plugin-manager/interaction-step-checks.js.map +1 -0
  245. package/src/lib/plugin-manager/plugin-artifact-types.d.ts +235 -0
  246. package/src/lib/plugin-manager/plugin-artifact-types.js +99 -0
  247. package/src/lib/plugin-manager/plugin-artifact-types.js.map +1 -0
  248. package/src/lib/plugin-manager/plugin-contact-capture.d.ts +8 -0
  249. package/src/lib/plugin-manager/plugin-contact-capture.js.map +1 -1
  250. package/src/lib/plugin-manager/plugin-conversion-credit.d.ts +216 -0
  251. package/src/lib/plugin-manager/plugin-conversion-credit.js +91 -0
  252. package/src/lib/plugin-manager/plugin-conversion-credit.js.map +1 -0
  253. package/src/lib/plugin-manager/plugin-entity-pickers.d.ts +83 -0
  254. package/src/lib/plugin-manager/plugin-entity-pickers.js +87 -0
  255. package/src/lib/plugin-manager/plugin-entity-pickers.js.map +1 -0
  256. package/src/lib/plugin-manager/plugin-host-resources.d.ts +6 -0
  257. package/src/lib/plugin-manager/plugin-host-resources.js +6 -1
  258. package/src/lib/plugin-manager/plugin-host-resources.js.map +1 -1
  259. package/src/lib/plugin-manager/plugin-intake-gates.d.ts +75 -0
  260. package/src/lib/plugin-manager/plugin-intake-gates.js +49 -0
  261. package/src/lib/plugin-manager/plugin-intake-gates.js.map +1 -0
  262. package/src/lib/plugin-manager/plugin-jobs.d.ts +5 -5
  263. package/src/lib/plugin-manager/plugin-jobs.js +7 -7
  264. package/src/lib/plugin-manager/plugin-jobs.js.map +1 -1
  265. package/src/lib/plugin-manager/plugin-live-paths.d.ts +70 -0
  266. package/src/lib/plugin-manager/plugin-live-paths.js +66 -0
  267. package/src/lib/plugin-manager/plugin-live-paths.js.map +1 -0
  268. package/src/lib/plugin-manager/plugin-org-erasure.d.ts +3 -2
  269. package/src/lib/plugin-manager/plugin-org-erasure.js +30 -5
  270. package/src/lib/plugin-manager/plugin-org-erasure.js.map +1 -1
  271. package/src/lib/plugin-manager/plugin-person-erasure.d.ts +68 -9
  272. package/src/lib/plugin-manager/plugin-person-erasure.js +196 -51
  273. package/src/lib/plugin-manager/plugin-person-erasure.js.map +1 -1
  274. package/src/lib/plugin-manager/plugin-person-records.d.ts +275 -0
  275. package/src/lib/plugin-manager/plugin-person-records.js +107 -0
  276. package/src/lib/plugin-manager/plugin-person-records.js.map +1 -0
  277. package/src/lib/plugin-manager/plugin-record-counts.d.ts +76 -0
  278. package/src/lib/plugin-manager/plugin-record-counts.js +49 -0
  279. package/src/lib/plugin-manager/plugin-record-counts.js.map +1 -0
  280. package/src/lib/plugin-manager/plugin-record-email-state.d.ts +26 -0
  281. package/src/lib/plugin-manager/plugin-record-email-state.js +16 -0
  282. package/src/lib/plugin-manager/plugin-record-email-state.js.map +1 -1
  283. package/src/lib/plugin-manager/plugin-record-index.d.ts +10 -0
  284. package/src/lib/plugin-manager/plugin-record-index.js.map +1 -1
  285. package/src/lib/plugin-manager/plugin-record-lists.d.ts +86 -6
  286. package/src/lib/plugin-manager/plugin-record-lists.js +42 -5
  287. package/src/lib/plugin-manager/plugin-record-lists.js.map +1 -1
  288. package/src/lib/plugin-manager/plugin-record-origin.d.ts +79 -0
  289. package/src/lib/plugin-manager/plugin-record-origin.js +46 -0
  290. package/src/lib/plugin-manager/plugin-record-origin.js.map +1 -0
  291. package/src/lib/plugin-manager/plugin-record-pages.d.ts +37 -0
  292. package/src/lib/plugin-manager/plugin-record-pages.js +52 -0
  293. package/src/lib/plugin-manager/plugin-record-pages.js.map +1 -0
  294. package/src/lib/plugin-manager/plugin-record-timeline.d.ts +60 -0
  295. package/src/lib/plugin-manager/plugin-record-timeline.js +16 -0
  296. package/src/lib/plugin-manager/plugin-record-timeline.js.map +1 -1
  297. package/src/lib/plugin-manager/plugin-resource-drafts.d.ts +5 -5
  298. package/src/lib/plugin-manager/plugin-resource-drafts.js.map +1 -1
  299. package/src/lib/plugin-manager/plugin-revocations.d.ts +64 -0
  300. package/src/lib/plugin-manager/plugin-revocations.js +47 -0
  301. package/src/lib/plugin-manager/plugin-revocations.js.map +1 -0
  302. package/src/lib/plugin-manager/plugin-send-tallies.d.ts +69 -0
  303. package/src/lib/plugin-manager/plugin-send-tallies.js +45 -0
  304. package/src/lib/plugin-manager/plugin-send-tallies.js.map +1 -0
  305. package/src/lib/plugin-manager/plugin-site-bundle.d.ts +40 -0
  306. package/src/lib/plugin-manager/plugin-site-bundle.js +4 -0
  307. package/src/lib/plugin-manager/plugin-site-bundle.js.map +1 -1
  308. package/src/lib/plugin-manager/plugin-site-export.d.ts +57 -1
  309. package/src/lib/plugin-manager/plugin-site-export.js +23 -10
  310. package/src/lib/plugin-manager/plugin-site-export.js.map +1 -1
  311. package/src/lib/plugin-manager/plugin-sitemap-readers.d.ts +146 -0
  312. package/src/lib/plugin-manager/plugin-sitemap-readers.js +110 -0
  313. package/src/lib/plugin-manager/plugin-sitemap-readers.js.map +1 -0
  314. package/src/lib/plugin-manager/plugin-transfer-resources.d.ts +714 -0
  315. package/src/lib/plugin-manager/plugin-transfer-resources.js +443 -0
  316. package/src/lib/plugin-manager/plugin-transfer-resources.js.map +1 -0
  317. package/src/lib/plugin-manager/plugin-usage-axes.d.ts +54 -5
  318. package/src/lib/plugin-manager/plugin-usage-axes.js +11 -3
  319. package/src/lib/plugin-manager/plugin-usage-axes.js.map +1 -1
  320. package/src/lib/plugin-manager/plugin-user-erasure.js +9 -1
  321. package/src/lib/plugin-manager/plugin-user-erasure.js.map +1 -1
  322. package/src/lib/plugin-manager/plugin-visitor-doors.d.ts +104 -0
  323. package/src/lib/plugin-manager/plugin-visitor-doors.js +108 -0
  324. package/src/lib/plugin-manager/plugin-visitor-doors.js.map +1 -0
  325. package/src/lib/plugin-manager/realm-host-aglyn.generated.js +2 -0
  326. package/src/lib/plugin-manager/realm-host-aglyn.generated.js.map +1 -1
  327. package/src/lib/plugin-manager/repeat-rows.d.ts +5 -6
  328. package/src/lib/plugin-manager/repeat-rows.js.map +1 -1
  329. package/src/lib/app-utils/actions.d.ts +0 -310
  330. package/src/lib/app-utils/actions.js +0 -506
  331. package/src/lib/app-utils/actions.js.map +0 -1
  332. package/src/lib/app-utils/automation-placeholders.d.ts +0 -72
  333. package/src/lib/app-utils/automation-placeholders.js +0 -207
  334. package/src/lib/app-utils/automation-placeholders.js.map +0 -1
  335. package/src/lib/app-utils/dataset-models.d.ts +0 -339
  336. package/src/lib/app-utils/dataset-models.js +0 -722
  337. package/src/lib/app-utils/dataset-models.js.map +0 -1
  338. package/src/lib/app-utils/datasets.d.ts +0 -171
  339. package/src/lib/app-utils/datasets.js +0 -227
  340. package/src/lib/app-utils/datasets.js.map +0 -1
  341. package/src/lib/app-utils/form-abuse-ceiling.d.ts +0 -146
  342. package/src/lib/app-utils/form-abuse-ceiling.js +0 -158
  343. package/src/lib/app-utils/form-abuse-ceiling.js.map +0 -1
  344. package/src/lib/plugin-manager/order-fulfilment.d.ts +0 -142
  345. package/src/lib/plugin-manager/order-fulfilment.js +0 -104
  346. package/src/lib/plugin-manager/order-fulfilment.js.map +0 -1
@@ -0,0 +1,275 @@
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
+ * THE PEOPLE A WORKSPACE KEEPS, asked for by the plugins that do not keep
19
+ * them (AGL-3080).
20
+ *
21
+ * `plugin-contact-capture` is how a silo hands somebody it MET to the plugin
22
+ * that keeps people. This is the other half: a plugin that has an address, or
23
+ * a record the owner handed it, and needs the person behind it.
24
+ *
25
+ * - a flow email asking whether the person agreed to marketing mail;
26
+ * - a campaign filling in the name a merge tag reads;
27
+ * - a refund taking money back off what a customer is worth;
28
+ * - an automation filing somebody under a campaign;
29
+ * - a sales sequence reading the people a rep enrolls.
30
+ *
31
+ * Each of those used to open the owner's collection itself — its path, its
32
+ * address index, which site may see which document — and broke the day the
33
+ * owner changed one. None of it is visible to `check:lib-boundaries`, because
34
+ * a collection name is not an import.
35
+ *
36
+ * So the plugin that keeps people registers ONE service here, and every rule
37
+ * stays the owner's: how an address is keyed, what an alternate address a
38
+ * merge folded in still answers to, which site may see which record, and what
39
+ * a refund or a filing writes.
40
+ *
41
+ * ## What a record is
42
+ *
43
+ * A {@link PluginPersonRecord} is a kind and an id in the owner's own words —
44
+ * the words `plugin-record-routes` addresses the record by — the person's
45
+ * primary address, and the record as the owner stores it. The fields the
46
+ * PLATFORM defines on a person record (the consent basis
47
+ * `marketing-consent.ts` reads, the `emailState` verdict, the `visibleTo`
48
+ * scope) are read off it with the platform's own readers; anything else is
49
+ * the owner's and is documented with its registration.
50
+ *
51
+ * ## Not registered is an answer
52
+ *
53
+ * Every reader answers `null` when no plugin keeps people in this process,
54
+ * which is a workspace with no record system and is not "nobody found". A
55
+ * caller treats the two differently: a send with no record system has no
56
+ * basis to read, which is not the same as a person who declined.
57
+ *
58
+ * A single-implementation contract: a workspace keeps one set of people, so
59
+ * a second plugin's service is refused naming both and the incumbent keeps
60
+ * serving. Registered from the owner's server declarations, so it is in place
61
+ * in a process that never loaded the owner's API surface.
62
+ *
63
+ * ## The caller proves who is asking
64
+ *
65
+ * Like the capture and timeline seams, the registry authenticates nobody. A
66
+ * caller decides in its own terms, before it asks, that the read or the write
67
+ * is the workspace's to make.
68
+ *
69
+ * Server-side: reached by its own subpath, never through
70
+ * `plugin-manager/index.ts`.
71
+ */
72
+ /** A person record, by the owner's word for its kind and its id. */
73
+ export interface PluginPersonRecordRef {
74
+ /** The owner's word for the record — the kind `plugin-record-routes` addresses it by. */
75
+ kind: string;
76
+ id: string;
77
+ }
78
+ /** One person record, as the plugin that keeps people shares it. */
79
+ export interface PluginPersonRecord extends PluginPersonRecordRef {
80
+ /** The record's primary address, normalized, or `null` when it holds none. */
81
+ email: string | null;
82
+ /**
83
+ * The record as the owner stores it. The platform's own fields on it are
84
+ * read with the platform's readers; the rest is the owner's, documented
85
+ * with its registration.
86
+ */
87
+ data: Readonly<Record<string, unknown>>;
88
+ }
89
+ /** Who to find by address, and where. */
90
+ export interface PluginPersonFindRequest {
91
+ /**
92
+ * The organization whose people are searched. A caller that knows only the
93
+ * site names `hostId` instead, and the owner reads the organization off it.
94
+ */
95
+ orgId?: string | null;
96
+ /** The site asking. Required with {@link onlyVisibleToSite}. */
97
+ hostId?: string | null;
98
+ /** Raw: the owner normalizes it, alternate addresses included. */
99
+ email: unknown;
100
+ /**
101
+ * Answer only a record `hostId` may see. A record the address names but the
102
+ * site cannot see is `null`, never a reason to look further — one address
103
+ * names one person.
104
+ */
105
+ onlyVisibleToSite?: boolean;
106
+ /**
107
+ * Look at every kind of record the owner keeps a person as, in the owner's
108
+ * order, instead of only the one a known person is held as. A send deciding
109
+ * whether it may mail somebody asks for this: a person not yet qualified is
110
+ * still a person whose answer counts.
111
+ */
112
+ anyKind?: boolean;
113
+ }
114
+ /** Records to read, by the refs the owner handed out. */
115
+ export interface PluginPersonReadRequest {
116
+ orgId: string;
117
+ records: readonly PluginPersonRecordRef[];
118
+ }
119
+ /**
120
+ * File a person under containers (`plugin-containers.ts`) — the merchant's
121
+ * own act, through an automation step or an enrollment. Filing is not
122
+ * consent.
123
+ */
124
+ export interface PluginPersonFileRequest {
125
+ /** The site filing them: the person is filed under the containers as this site holds them. */
126
+ hostId: string;
127
+ orgId?: string | null;
128
+ record: PluginPersonRecordRef;
129
+ /** The container kind, as `plugin-containers.ts` declares it. */
130
+ containerKind: string;
131
+ ids: readonly string[];
132
+ }
133
+ /**
134
+ * Money handed back to a person a silo took it from: a refund, or a dispute
135
+ * lost. The owner records it beside what the person is worth; it never
136
+ * creates a person to hold it.
137
+ */
138
+ export interface PluginPersonRefundRequest {
139
+ /** The site the money was taken on. */
140
+ hostId: string;
141
+ /** The buyer's address as the sale recorded it. Raw: the owner normalizes it. */
142
+ email: unknown;
143
+ /** Cents reversed by THIS refund, never the sale's total. */
144
+ amountCents: number;
145
+ /** The silo's own document the money went back on — what a timeline entry points at. */
146
+ refId: string;
147
+ /** True only for the refund that moved the sale into fully refunded. */
148
+ closedTheSale: boolean;
149
+ /** `chargeback` for a dispute lost; a refund otherwise. */
150
+ reason?: 'refund' | 'chargeback';
151
+ }
152
+ /**
153
+ * What became of a refund. `recorded`; `no-email` for a sale that never
154
+ * named its buyer; `no-person` for an address the workspace holds nobody at;
155
+ * `gone` for a person removed between the sale and the refund.
156
+ */
157
+ export type PluginPersonRefundOutcome = 'recorded' | 'no-email' | 'no-person' | 'gone';
158
+ /**
159
+ * The people a saved selection the owner keeps names — a saved view of one of
160
+ * its lists — taken for one site, as the people a sequence or a send works
161
+ * through.
162
+ */
163
+ export interface PluginPersonViewRequest {
164
+ orgId: string;
165
+ /** The site the people are taken for: only records it holds are answered. */
166
+ hostId: string;
167
+ /** The view, by the id the owner's record list handed out (`plugin-record-lists`). */
168
+ viewId: string;
169
+ /** The member asking: a view they may not list does not exist for them. */
170
+ viewerUid: string;
171
+ /** The most people answered. */
172
+ limit: number;
173
+ }
174
+ export type PluginPersonViewPeople = {
175
+ ok: true;
176
+ people: PluginPersonRecordRef[];
177
+ /** How many the view selects, as far as the owner read it. */
178
+ total: number;
179
+ /** The view selects more than `limit`, or more than the owner read. */
180
+ truncated: boolean;
181
+ } | {
182
+ ok: false;
183
+ /**
184
+ * `not-found`: no such view, or not this member's to list.
185
+ * `not-people`: a view of something that is not people.
186
+ * `unsupported`: the view narrows by something the owner cannot apply
187
+ * outside its own list, so taking it would select more people than the
188
+ * view shows; `unsupported` names what, in the owner's words.
189
+ */
190
+ reason: 'not-found' | 'not-people' | 'unsupported';
191
+ unsupported?: string[];
192
+ };
193
+ /** Records to ask about, by the refs the owner handed out. */
194
+ export interface PluginPersonWroteInRequest {
195
+ orgId: string;
196
+ records: readonly PluginPersonRecordRef[];
197
+ }
198
+ export interface PluginPersonRecords {
199
+ /** The person an address belongs to, or `null`. A read; may throw, and the caller decides which way a failure falls. */
200
+ find(request: PluginPersonFindRequest): Promise<PluginPersonRecord | null>;
201
+ /** The records named, in the order asked; `null` for one that is gone. */
202
+ read(request: PluginPersonReadRequest): Promise<Array<PluginPersonRecord | null>>;
203
+ /**
204
+ * Files the person under the containers. Optional: an owner that keeps no
205
+ * containers answers nothing. `filed: false` is a record the owner could
206
+ * not find for the site.
207
+ */
208
+ fileUnder?(request: PluginPersonFileRequest): Promise<{
209
+ filed: boolean;
210
+ }>;
211
+ /** Records money handed back. Optional. Never throws: the money has already moved. */
212
+ recordRefund?(request: PluginPersonRefundRequest): Promise<PluginPersonRefundOutcome>;
213
+ /** The people a saved view selects for a site. Optional: an owner that keeps no views answers nothing. */
214
+ peopleInView?(request: PluginPersonViewRequest): Promise<PluginPersonViewPeople>;
215
+ /**
216
+ * Whether each person has ever written to the workspace — an email they
217
+ * sent, on their record — in the order asked; `null` for one the owner
218
+ * could not answer. Optional.
219
+ */
220
+ wroteIn?(request: PluginPersonWroteInRequest): Promise<Array<boolean | null>>;
221
+ }
222
+ export declare const PLUGIN_PERSON_RECORDS: import("./plugin-services").PluginServiceContract<PluginPersonRecords>;
223
+ /**
224
+ * Registers the plugin that keeps people. The owner is the loader's marker
225
+ * when a register fn is running, else `options.pluginId`; with neither the
226
+ * registration throws, and a second plugin's service is refused naming both —
227
+ * the incumbent keeps serving.
228
+ */
229
+ export declare function registerPluginPersonRecords(records: PluginPersonRecords, options?: {
230
+ pluginId?: string;
231
+ }): void;
232
+ export interface ResolvedPluginPersonRecords {
233
+ /** The plugin that keeps people. */
234
+ pluginId: string;
235
+ records: PluginPersonRecords;
236
+ }
237
+ /** The service with its owner, or `null` when no plugin keeps people here. */
238
+ export declare function pluginPersonRecords(): ResolvedPluginPersonRecords | null;
239
+ /**
240
+ * The person an address belongs to, or `null` — for nobody found, and for a
241
+ * workspace no plugin keeps people for. A failed read is the owner's to
242
+ * throw and the caller's to decide which way it falls.
243
+ */
244
+ export declare function findPluginPerson(request: PluginPersonFindRequest): Promise<PluginPersonRecord | null>;
245
+ /**
246
+ * The records named, in the order asked, `null` for each that is gone — or
247
+ * `null` whole when no plugin keeps people here, which is not "all gone".
248
+ */
249
+ export declare function readPluginPeople(request: PluginPersonReadRequest): Promise<Array<PluginPersonRecord | null> | null>;
250
+ /**
251
+ * Files the person under the containers through whichever plugin keeps
252
+ * people, or answers `null` when none does or the one that does keeps no
253
+ * containers. A failed write throws, as the caller's own write would have.
254
+ */
255
+ export declare function filePluginPersonUnder(request: PluginPersonFileRequest): Promise<{
256
+ filed: boolean;
257
+ } | null>;
258
+ /**
259
+ * Hands a refund to whichever plugin keeps people, or answers `null` when
260
+ * none does. Never throws: every caller has already moved the money and
261
+ * recorded it on its own document, and a person's figure is derived from it.
262
+ */
263
+ export declare function recordPluginPersonRefund(request: PluginPersonRefundRequest): Promise<PluginPersonRefundOutcome | null>;
264
+ /**
265
+ * The people a saved view selects for a site, or `null` when no plugin keeps
266
+ * people here or the one that does keeps no views. A failed read throws.
267
+ */
268
+ export declare function pluginPeopleInView(request: PluginPersonViewRequest): Promise<PluginPersonViewPeople | null>;
269
+ /**
270
+ * Whether each person has ever written to the workspace, in the order asked
271
+ * — `null` for each the owner could not answer, and `null` whole when no
272
+ * plugin keeps people here or the one that does cannot say. Never throws: a
273
+ * caller reads an unknown as unknown.
274
+ */
275
+ export declare function pluginPeopleWroteIn(request: PluginPersonWroteInRequest): Promise<Array<boolean | null> | null>;
@@ -0,0 +1,107 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Aglyn LLC
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */ import { definePluginServiceContract, registerPluginService, resolvePluginServices } from "./plugin-services.js";
18
+ export const PLUGIN_PERSON_RECORDS = definePluginServiceContract('core.person-records', {
19
+ multiple: false
20
+ });
21
+ /**
22
+ * Registers the plugin that keeps people. The owner is the loader's marker
23
+ * when a register fn is running, else `options.pluginId`; with neither the
24
+ * registration throws, and a second plugin's service is refused naming both —
25
+ * the incumbent keeps serving.
26
+ */ export function registerPluginPersonRecords(records, options) {
27
+ registerPluginService(PLUGIN_PERSON_RECORDS, records, _extends({}, (options == null ? void 0 : options.pluginId) ? {
28
+ pluginId: options.pluginId
29
+ } : {}));
30
+ }
31
+ /** The service with its owner, or `null` when no plugin keeps people here. */ export function pluginPersonRecords() {
32
+ const entry = resolvePluginServices(PLUGIN_PERSON_RECORDS)[0];
33
+ return entry ? {
34
+ pluginId: entry.pluginId,
35
+ records: entry.impl
36
+ } : null;
37
+ }
38
+ /**
39
+ * The person an address belongs to, or `null` — for nobody found, and for a
40
+ * workspace no plugin keeps people for. A failed read is the owner's to
41
+ * throw and the caller's to decide which way it falls.
42
+ */ export async function findPluginPerson(request) {
43
+ const resolved = pluginPersonRecords();
44
+ if (!resolved) return null;
45
+ return await resolved.records.find(request);
46
+ }
47
+ /**
48
+ * The records named, in the order asked, `null` for each that is gone — or
49
+ * `null` whole when no plugin keeps people here, which is not "all gone".
50
+ */ export async function readPluginPeople(request) {
51
+ const resolved = pluginPersonRecords();
52
+ if (!resolved) return null;
53
+ if (!request.records.length) return [];
54
+ return await resolved.records.read(request);
55
+ }
56
+ /**
57
+ * Files the person under the containers through whichever plugin keeps
58
+ * people, or answers `null` when none does or the one that does keeps no
59
+ * containers. A failed write throws, as the caller's own write would have.
60
+ */ export async function filePluginPersonUnder(request) {
61
+ const resolved = pluginPersonRecords();
62
+ if (!(resolved == null ? void 0 : resolved.records.fileUnder)) return null;
63
+ if (!request.ids.length) return {
64
+ filed: false
65
+ };
66
+ return await resolved.records.fileUnder(request);
67
+ }
68
+ /**
69
+ * Hands a refund to whichever plugin keeps people, or answers `null` when
70
+ * none does. Never throws: every caller has already moved the money and
71
+ * recorded it on its own document, and a person's figure is derived from it.
72
+ */ export async function recordPluginPersonRefund(request) {
73
+ const resolved = pluginPersonRecords();
74
+ if (!(resolved == null ? void 0 : resolved.records.recordRefund)) return null;
75
+ try {
76
+ return await resolved.records.recordRefund(request);
77
+ } catch (error) {
78
+ console.error('[person-records] the record system could not record a refund', error);
79
+ return null;
80
+ }
81
+ }
82
+ /**
83
+ * The people a saved view selects for a site, or `null` when no plugin keeps
84
+ * people here or the one that does keeps no views. A failed read throws.
85
+ */ export async function pluginPeopleInView(request) {
86
+ const resolved = pluginPersonRecords();
87
+ if (!(resolved == null ? void 0 : resolved.records.peopleInView)) return null;
88
+ return await resolved.records.peopleInView(request);
89
+ }
90
+ /**
91
+ * Whether each person has ever written to the workspace, in the order asked
92
+ * — `null` for each the owner could not answer, and `null` whole when no
93
+ * plugin keeps people here or the one that does cannot say. Never throws: a
94
+ * caller reads an unknown as unknown.
95
+ */ export async function pluginPeopleWroteIn(request) {
96
+ const resolved = pluginPersonRecords();
97
+ if (!(resolved == null ? void 0 : resolved.records.wroteIn)) return null;
98
+ if (!request.records.length) return [];
99
+ try {
100
+ return await resolved.records.wroteIn(request);
101
+ } catch (error) {
102
+ console.error('[person-records] the record system could not say who wrote in', error);
103
+ return null;
104
+ }
105
+ }
106
+
107
+ //# sourceMappingURL=plugin-person-records.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-person-records.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 {\n definePluginServiceContract,\n registerPluginService,\n resolvePluginServices,\n} from './plugin-services'\n\n/**\n * THE PEOPLE A WORKSPACE KEEPS, asked for by the plugins that do not keep\n * them (AGL-3080).\n *\n * `plugin-contact-capture` is how a silo hands somebody it MET to the plugin\n * that keeps people. This is the other half: a plugin that has an address, or\n * a record the owner handed it, and needs the person behind it.\n *\n * - a flow email asking whether the person agreed to marketing mail;\n * - a campaign filling in the name a merge tag reads;\n * - a refund taking money back off what a customer is worth;\n * - an automation filing somebody under a campaign;\n * - a sales sequence reading the people a rep enrolls.\n *\n * Each of those used to open the owner's collection itself — its path, its\n * address index, which site may see which document — and broke the day the\n * owner changed one. None of it is visible to `check:lib-boundaries`, because\n * a collection name is not an import.\n *\n * So the plugin that keeps people registers ONE service here, and every rule\n * stays the owner's: how an address is keyed, what an alternate address a\n * merge folded in still answers to, which site may see which record, and what\n * a refund or a filing writes.\n *\n * ## What a record is\n *\n * A {@link PluginPersonRecord} is a kind and an id in the owner's own words —\n * the words `plugin-record-routes` addresses the record by — the person's\n * primary address, and the record as the owner stores it. The fields the\n * PLATFORM defines on a person record (the consent basis\n * `marketing-consent.ts` reads, the `emailState` verdict, the `visibleTo`\n * scope) are read off it with the platform's own readers; anything else is\n * the owner's and is documented with its registration.\n *\n * ## Not registered is an answer\n *\n * Every reader answers `null` when no plugin keeps people in this process,\n * which is a workspace with no record system and is not \"nobody found\". A\n * caller treats the two differently: a send with no record system has no\n * basis to read, which is not the same as a person who declined.\n *\n * A single-implementation contract: a workspace keeps one set of people, so\n * a second plugin's service is refused naming both and the incumbent keeps\n * serving. Registered from the owner's server declarations, so it is in place\n * in a process that never loaded the owner's API surface.\n *\n * ## The caller proves who is asking\n *\n * Like the capture and timeline seams, the registry authenticates nobody. A\n * caller decides in its own terms, before it asks, that the read or the write\n * is the workspace's to make.\n *\n * Server-side: reached by its own subpath, never through\n * `plugin-manager/index.ts`.\n */\n\n/** A person record, by the owner's word for its kind and its id. */\nexport interface PluginPersonRecordRef {\n /** The owner's word for the record — the kind `plugin-record-routes` addresses it by. */\n kind: string\n id: string\n}\n\n/** One person record, as the plugin that keeps people shares it. */\nexport interface PluginPersonRecord extends PluginPersonRecordRef {\n /** The record's primary address, normalized, or `null` when it holds none. */\n email: string | null\n /**\n * The record as the owner stores it. The platform's own fields on it are\n * read with the platform's readers; the rest is the owner's, documented\n * with its registration.\n */\n data: Readonly<Record<string, unknown>>\n}\n\n/** Who to find by address, and where. */\nexport interface PluginPersonFindRequest {\n /**\n * The organization whose people are searched. A caller that knows only the\n * site names `hostId` instead, and the owner reads the organization off it.\n */\n orgId?: string | null\n /** The site asking. Required with {@link onlyVisibleToSite}. */\n hostId?: string | null\n /** Raw: the owner normalizes it, alternate addresses included. */\n email: unknown\n /**\n * Answer only a record `hostId` may see. A record the address names but the\n * site cannot see is `null`, never a reason to look further — one address\n * names one person.\n */\n onlyVisibleToSite?: boolean\n /**\n * Look at every kind of record the owner keeps a person as, in the owner's\n * order, instead of only the one a known person is held as. A send deciding\n * whether it may mail somebody asks for this: a person not yet qualified is\n * still a person whose answer counts.\n */\n anyKind?: boolean\n}\n\n/** Records to read, by the refs the owner handed out. */\nexport interface PluginPersonReadRequest {\n orgId: string\n records: readonly PluginPersonRecordRef[]\n}\n\n/**\n * File a person under containers (`plugin-containers.ts`) — the merchant's\n * own act, through an automation step or an enrollment. Filing is not\n * consent.\n */\nexport interface PluginPersonFileRequest {\n /** The site filing them: the person is filed under the containers as this site holds them. */\n hostId: string\n orgId?: string | null\n record: PluginPersonRecordRef\n /** The container kind, as `plugin-containers.ts` declares it. */\n containerKind: string\n ids: readonly string[]\n}\n\n/**\n * Money handed back to a person a silo took it from: a refund, or a dispute\n * lost. The owner records it beside what the person is worth; it never\n * creates a person to hold it.\n */\nexport interface PluginPersonRefundRequest {\n /** The site the money was taken on. */\n hostId: string\n /** The buyer's address as the sale recorded it. Raw: the owner normalizes it. */\n email: unknown\n /** Cents reversed by THIS refund, never the sale's total. */\n amountCents: number\n /** The silo's own document the money went back on — what a timeline entry points at. */\n refId: string\n /** True only for the refund that moved the sale into fully refunded. */\n closedTheSale: boolean\n /** `chargeback` for a dispute lost; a refund otherwise. */\n reason?: 'refund' | 'chargeback'\n}\n\n/**\n * What became of a refund. `recorded`; `no-email` for a sale that never\n * named its buyer; `no-person` for an address the workspace holds nobody at;\n * `gone` for a person removed between the sale and the refund.\n */\nexport type PluginPersonRefundOutcome = 'recorded' | 'no-email' | 'no-person' | 'gone'\n\n/**\n * The people a saved selection the owner keeps names — a saved view of one of\n * its lists — taken for one site, as the people a sequence or a send works\n * through.\n */\nexport interface PluginPersonViewRequest {\n orgId: string\n /** The site the people are taken for: only records it holds are answered. */\n hostId: string\n /** The view, by the id the owner's record list handed out (`plugin-record-lists`). */\n viewId: string\n /** The member asking: a view they may not list does not exist for them. */\n viewerUid: string\n /** The most people answered. */\n limit: number\n}\n\nexport type PluginPersonViewPeople =\n | {\n ok: true\n people: PluginPersonRecordRef[]\n /** How many the view selects, as far as the owner read it. */\n total: number\n /** The view selects more than `limit`, or more than the owner read. */\n truncated: boolean\n }\n | {\n ok: false\n /**\n * `not-found`: no such view, or not this member's to list.\n * `not-people`: a view of something that is not people.\n * `unsupported`: the view narrows by something the owner cannot apply\n * outside its own list, so taking it would select more people than the\n * view shows; `unsupported` names what, in the owner's words.\n */\n reason: 'not-found' | 'not-people' | 'unsupported'\n unsupported?: string[]\n }\n\n/** Records to ask about, by the refs the owner handed out. */\nexport interface PluginPersonWroteInRequest {\n orgId: string\n records: readonly PluginPersonRecordRef[]\n}\n\nexport interface PluginPersonRecords {\n /** The person an address belongs to, or `null`. A read; may throw, and the caller decides which way a failure falls. */\n find(request: PluginPersonFindRequest): Promise<PluginPersonRecord | null>\n /** The records named, in the order asked; `null` for one that is gone. */\n read(request: PluginPersonReadRequest): Promise<Array<PluginPersonRecord | null>>\n /**\n * Files the person under the containers. Optional: an owner that keeps no\n * containers answers nothing. `filed: false` is a record the owner could\n * not find for the site.\n */\n fileUnder?(request: PluginPersonFileRequest): Promise<{ filed: boolean }>\n /** Records money handed back. Optional. Never throws: the money has already moved. */\n recordRefund?(request: PluginPersonRefundRequest): Promise<PluginPersonRefundOutcome>\n /** The people a saved view selects for a site. Optional: an owner that keeps no views answers nothing. */\n peopleInView?(request: PluginPersonViewRequest): Promise<PluginPersonViewPeople>\n /**\n * Whether each person has ever written to the workspace — an email they\n * sent, on their record — in the order asked; `null` for one the owner\n * could not answer. Optional.\n */\n wroteIn?(request: PluginPersonWroteInRequest): Promise<Array<boolean | null>>\n}\n\nexport const PLUGIN_PERSON_RECORDS = definePluginServiceContract<PluginPersonRecords>(\n 'core.person-records',\n { multiple: false },\n)\n\n/**\n * Registers the plugin that keeps people. The owner is the loader's marker\n * when a register fn is running, else `options.pluginId`; with neither the\n * registration throws, and a second plugin's service is refused naming both —\n * the incumbent keeps serving.\n */\nexport function registerPluginPersonRecords(\n records: PluginPersonRecords,\n options?: { pluginId?: string },\n): void {\n registerPluginService(PLUGIN_PERSON_RECORDS, records, {\n ...(options?.pluginId ? { pluginId: options.pluginId } : {}),\n })\n}\n\nexport interface ResolvedPluginPersonRecords {\n /** The plugin that keeps people. */\n pluginId: string\n records: PluginPersonRecords\n}\n\n/** The service with its owner, or `null` when no plugin keeps people here. */\nexport function pluginPersonRecords(): ResolvedPluginPersonRecords | null {\n const entry = resolvePluginServices(PLUGIN_PERSON_RECORDS)[0]\n return entry ? { pluginId: entry.pluginId, records: entry.impl } : null\n}\n\n/**\n * The person an address belongs to, or `null` — for nobody found, and for a\n * workspace no plugin keeps people for. A failed read is the owner's to\n * throw and the caller's to decide which way it falls.\n */\nexport async function findPluginPerson(\n request: PluginPersonFindRequest,\n): Promise<PluginPersonRecord | null> {\n const resolved = pluginPersonRecords()\n if (!resolved) return null\n return await resolved.records.find(request)\n}\n\n/**\n * The records named, in the order asked, `null` for each that is gone — or\n * `null` whole when no plugin keeps people here, which is not \"all gone\".\n */\nexport async function readPluginPeople(\n request: PluginPersonReadRequest,\n): Promise<Array<PluginPersonRecord | null> | null> {\n const resolved = pluginPersonRecords()\n if (!resolved) return null\n if (!request.records.length) return []\n return await resolved.records.read(request)\n}\n\n/**\n * Files the person under the containers through whichever plugin keeps\n * people, or answers `null` when none does or the one that does keeps no\n * containers. A failed write throws, as the caller's own write would have.\n */\nexport async function filePluginPersonUnder(\n request: PluginPersonFileRequest,\n): Promise<{ filed: boolean } | null> {\n const resolved = pluginPersonRecords()\n if (!resolved?.records.fileUnder) return null\n if (!request.ids.length) return { filed: false }\n return await resolved.records.fileUnder(request)\n}\n\n/**\n * Hands a refund to whichever plugin keeps people, or answers `null` when\n * none does. Never throws: every caller has already moved the money and\n * recorded it on its own document, and a person's figure is derived from it.\n */\nexport async function recordPluginPersonRefund(\n request: PluginPersonRefundRequest,\n): Promise<PluginPersonRefundOutcome | null> {\n const resolved = pluginPersonRecords()\n if (!resolved?.records.recordRefund) return null\n try {\n return await resolved.records.recordRefund(request)\n } catch (error) {\n console.error('[person-records] the record system could not record a refund', error)\n return null\n }\n}\n\n/**\n * The people a saved view selects for a site, or `null` when no plugin keeps\n * people here or the one that does keeps no views. A failed read throws.\n */\nexport async function pluginPeopleInView(\n request: PluginPersonViewRequest,\n): Promise<PluginPersonViewPeople | null> {\n const resolved = pluginPersonRecords()\n if (!resolved?.records.peopleInView) return null\n return await resolved.records.peopleInView(request)\n}\n\n/**\n * Whether each person has ever written to the workspace, in the order asked\n * — `null` for each the owner could not answer, and `null` whole when no\n * plugin keeps people here or the one that does cannot say. Never throws: a\n * caller reads an unknown as unknown.\n */\nexport async function pluginPeopleWroteIn(\n request: PluginPersonWroteInRequest,\n): Promise<Array<boolean | null> | null> {\n const resolved = pluginPersonRecords()\n if (!resolved?.records.wroteIn) return null\n if (!request.records.length) return []\n try {\n return await resolved.records.wroteIn(request)\n } catch (error) {\n console.error('[person-records] the record system could not say who wrote in', error)\n return null\n }\n}\n"],"names":["definePluginServiceContract","registerPluginService","resolvePluginServices","PLUGIN_PERSON_RECORDS","multiple","registerPluginPersonRecords","records","options","pluginId","pluginPersonRecords","entry","impl","findPluginPerson","request","resolved","find","readPluginPeople","length","read","filePluginPersonUnder","fileUnder","ids","filed","recordPluginPersonRefund","recordRefund","error","console","pluginPeopleInView","peopleInView","pluginPeopleWroteIn","wroteIn"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED,SACEA,2BAA2B,EAC3BC,qBAAqB,EACrBC,qBAAqB,QAChB,uBAAmB;AA2N1B,OAAO,MAAMC,wBAAwBH,4BACnC,uBACA;IAAEI,UAAU;AAAM,GACnB;AAED;;;;;CAKC,GACD,OAAO,SAASC,4BACdC,OAA4B,EAC5BC,OAA+B;IAE/BN,sBAAsBE,uBAAuBG,SAAS,aAChDC,CAAAA,2BAAAA,QAASC,QAAQ,IAAG;QAAEA,UAAUD,QAAQC,QAAQ;IAAC,IAAI,CAAC;AAE9D;AAQA,4EAA4E,GAC5E,OAAO,SAASC;IACd,MAAMC,QAAQR,sBAAsBC,sBAAsB,CAAC,EAAE;IAC7D,OAAOO,QAAQ;QAAEF,UAAUE,MAAMF,QAAQ;QAAEF,SAASI,MAAMC,IAAI;IAAC,IAAI;AACrE;AAEA;;;;CAIC,GACD,OAAO,eAAeC,iBACpBC,OAAgC;IAEhC,MAAMC,WAAWL;IACjB,IAAI,CAACK,UAAU,OAAO;IACtB,OAAO,MAAMA,SAASR,OAAO,CAACS,IAAI,CAACF;AACrC;AAEA;;;CAGC,GACD,OAAO,eAAeG,iBACpBH,OAAgC;IAEhC,MAAMC,WAAWL;IACjB,IAAI,CAACK,UAAU,OAAO;IACtB,IAAI,CAACD,QAAQP,OAAO,CAACW,MAAM,EAAE,OAAO,EAAE;IACtC,OAAO,MAAMH,SAASR,OAAO,CAACY,IAAI,CAACL;AACrC;AAEA;;;;CAIC,GACD,OAAO,eAAeM,sBACpBN,OAAgC;IAEhC,MAAMC,WAAWL;IACjB,IAAI,EAACK,4BAAAA,SAAUR,OAAO,CAACc,SAAS,GAAE,OAAO;IACzC,IAAI,CAACP,QAAQQ,GAAG,CAACJ,MAAM,EAAE,OAAO;QAAEK,OAAO;IAAM;IAC/C,OAAO,MAAMR,SAASR,OAAO,CAACc,SAAS,CAACP;AAC1C;AAEA;;;;CAIC,GACD,OAAO,eAAeU,yBACpBV,OAAkC;IAElC,MAAMC,WAAWL;IACjB,IAAI,EAACK,4BAAAA,SAAUR,OAAO,CAACkB,YAAY,GAAE,OAAO;IAC5C,IAAI;QACF,OAAO,MAAMV,SAASR,OAAO,CAACkB,YAAY,CAACX;IAC7C,EAAE,OAAOY,OAAO;QACdC,QAAQD,KAAK,CAAC,gEAAgEA;QAC9E,OAAO;IACT;AACF;AAEA;;;CAGC,GACD,OAAO,eAAeE,mBACpBd,OAAgC;IAEhC,MAAMC,WAAWL;IACjB,IAAI,EAACK,4BAAAA,SAAUR,OAAO,CAACsB,YAAY,GAAE,OAAO;IAC5C,OAAO,MAAMd,SAASR,OAAO,CAACsB,YAAY,CAACf;AAC7C;AAEA;;;;;CAKC,GACD,OAAO,eAAegB,oBACpBhB,OAAmC;IAEnC,MAAMC,WAAWL;IACjB,IAAI,EAACK,4BAAAA,SAAUR,OAAO,CAACwB,OAAO,GAAE,OAAO;IACvC,IAAI,CAACjB,QAAQP,OAAO,CAACW,MAAM,EAAE,OAAO,EAAE;IACtC,IAAI;QACF,OAAO,MAAMH,SAASR,OAAO,CAACwB,OAAO,CAACjB;IACxC,EAAE,OAAOY,OAAO;QACdC,QAAQD,KAAK,CAAC,iEAAiEA;QAC/E,OAAO;IACT;AACF"}
@@ -0,0 +1,76 @@
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 { DocumentData, Firestore, Query } from 'firebase/firestore';
18
+ /**
19
+ * How many of a plugin's records one site produced, COUNTED in the console
20
+ * for another plugin's figure (AGL-3080) — the count's half of
21
+ * `plugin-record-lists`.
22
+ *
23
+ * A plugin that reports a share of another plugin's records — a campaign's
24
+ * conversions out of every form submission, booking, lead or contact the site
25
+ * holds — used to count the owner's collection from the browser itself: the
26
+ * path, which ones a site may be credited with, the filter the owner's
27
+ * security rules require. Each breaks the day the owner changes one.
28
+ *
29
+ * So the owner publishes a COUNT SOURCE for each record kind it keeps: the
30
+ * query whose aggregate count is how many records of the kind one site
31
+ * produced, provable by the signed-in member's read. The reader runs its own
32
+ * aggregation over it (`getCountFromServer`) and never learns where the
33
+ * records are stored. Which records a site "produced" is the owner's to say:
34
+ * a site's own submissions, the leads it captured, or — for a kind the
35
+ * organization holds once for all its sites — every one, which the reader
36
+ * must then present as a total across sites.
37
+ *
38
+ * ## Not registered is an answer
39
+ *
40
+ * No source for a kind means no plugin keeps it in this console. A reader
41
+ * withholds the figure rather than counting the collection itself.
42
+ *
43
+ * One source per kind; a second plugin claiming a kind another counts is
44
+ * refused, naming both.
45
+ */
46
+ /** Which site's records a reader counts. */
47
+ export interface PluginRecordCountRequest {
48
+ hostId: string;
49
+ /** The site's organization, where the kind is held by the organization. */
50
+ orgId?: string | null;
51
+ }
52
+ export interface PluginRecordCountSource {
53
+ /**
54
+ * The query whose count is how many records of the kind the site
55
+ * produced, or `null` where the site has none to count (an organization
56
+ * not yet resolved).
57
+ */
58
+ query(firestore: Firestore, request: PluginRecordCountRequest): Query<DocumentData> | null;
59
+ /**
60
+ * Whether the count is the ORGANIZATION's, shared by every site in it,
61
+ * rather than this site's alone — a reader dividing a site's figure by it
62
+ * must say the total crosses sites.
63
+ */
64
+ crossesSites?: boolean;
65
+ }
66
+ export declare const PLUGIN_RECORD_COUNTS: import("./plugin-services").PluginServiceContract<PluginRecordCountSource>;
67
+ /**
68
+ * Publishes the count source for one record kind. The owner is the loader's
69
+ * marker when a register fn is running, else `options.pluginId`; with neither
70
+ * the registration throws. A kind another plugin counts throws naming both.
71
+ */
72
+ export declare function registerPluginRecordCountSource(kind: string, source: PluginRecordCountSource, options?: {
73
+ pluginId?: string;
74
+ }): void;
75
+ /** The count source for a kind, or `null` when no plugin counts it here. */
76
+ export declare function pluginRecordCountSource(kind: string): PluginRecordCountSource | null;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ import { getRegisteringPluginId } from "../app-utils/registering-plugin.js";
17
+ import { definePluginServiceContract, registerPluginService, resolvePluginServices } from "./plugin-services.js";
18
+ export const PLUGIN_RECORD_COUNTS = definePluginServiceContract('core.record-counts', {
19
+ multiple: true
20
+ });
21
+ /**
22
+ * Publishes the count source for one record kind. The owner is the loader's
23
+ * marker when a register fn is running, else `options.pluginId`; with neither
24
+ * the registration throws. A kind another plugin counts throws naming both.
25
+ */ export function registerPluginRecordCountSource(kind, source, options) {
26
+ var _ref, _getRegisteringPluginId;
27
+ const key = kind.trim();
28
+ if (!key) throw new Error('a record count source needs a record kind');
29
+ const pluginId = ((_ref = (_getRegisteringPluginId = getRegisteringPluginId()) != null ? _getRegisteringPluginId : options == null ? void 0 : options.pluginId) != null ? _ref : '').trim();
30
+ if (!pluginId) {
31
+ throw new Error(`the record count source for "${key}" was registered with no owner`);
32
+ }
33
+ const incumbent = resolvePluginServices(PLUGIN_RECORD_COUNTS).find((entry)=>entry.key === key);
34
+ if (incumbent && incumbent.pluginId !== pluginId) {
35
+ throw new Error(`record kind "${key}" is already counted by "${incumbent.pluginId}"; refused "${pluginId}"`);
36
+ }
37
+ registerPluginService(PLUGIN_RECORD_COUNTS, source, {
38
+ pluginId,
39
+ key
40
+ });
41
+ }
42
+ /** The count source for a kind, or `null` when no plugin counts it here. */ export function pluginRecordCountSource(kind) {
43
+ var _ref;
44
+ var _resolvePluginServices_find;
45
+ const key = kind.trim();
46
+ return (_ref = (_resolvePluginServices_find = resolvePluginServices(PLUGIN_RECORD_COUNTS).find((one)=>one.key === key)) == null ? void 0 : _resolvePluginServices_find.impl) != null ? _ref : null;
47
+ }
48
+
49
+ //# sourceMappingURL=plugin-record-counts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-record-counts.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { DocumentData, Firestore, Query } from 'firebase/firestore'\nimport { getRegisteringPluginId } from '../app-utils/registering-plugin'\nimport {\n definePluginServiceContract,\n registerPluginService,\n resolvePluginServices,\n} from './plugin-services'\n\n/**\n * How many of a plugin's records one site produced, COUNTED in the console\n * for another plugin's figure (AGL-3080) — the count's half of\n * `plugin-record-lists`.\n *\n * A plugin that reports a share of another plugin's records — a campaign's\n * conversions out of every form submission, booking, lead or contact the site\n * holds — used to count the owner's collection from the browser itself: the\n * path, which ones a site may be credited with, the filter the owner's\n * security rules require. Each breaks the day the owner changes one.\n *\n * So the owner publishes a COUNT SOURCE for each record kind it keeps: the\n * query whose aggregate count is how many records of the kind one site\n * produced, provable by the signed-in member's read. The reader runs its own\n * aggregation over it (`getCountFromServer`) and never learns where the\n * records are stored. Which records a site \"produced\" is the owner's to say:\n * a site's own submissions, the leads it captured, or — for a kind the\n * organization holds once for all its sites — every one, which the reader\n * must then present as a total across sites.\n *\n * ## Not registered is an answer\n *\n * No source for a kind means no plugin keeps it in this console. A reader\n * withholds the figure rather than counting the collection itself.\n *\n * One source per kind; a second plugin claiming a kind another counts is\n * refused, naming both.\n */\n\n/** Which site's records a reader counts. */\nexport interface PluginRecordCountRequest {\n hostId: string\n /** The site's organization, where the kind is held by the organization. */\n orgId?: string | null\n}\n\nexport interface PluginRecordCountSource {\n /**\n * The query whose count is how many records of the kind the site\n * produced, or `null` where the site has none to count (an organization\n * not yet resolved).\n */\n query(firestore: Firestore, request: PluginRecordCountRequest): Query<DocumentData> | null\n /**\n * Whether the count is the ORGANIZATION's, shared by every site in it,\n * rather than this site's alone — a reader dividing a site's figure by it\n * must say the total crosses sites.\n */\n crossesSites?: boolean\n}\n\nexport const PLUGIN_RECORD_COUNTS = definePluginServiceContract<PluginRecordCountSource>(\n 'core.record-counts',\n { multiple: true },\n)\n\n/**\n * Publishes the count source for one record kind. The owner is the loader's\n * marker when a register fn is running, else `options.pluginId`; with neither\n * the registration throws. A kind another plugin counts throws naming both.\n */\nexport function registerPluginRecordCountSource(\n kind: string,\n source: PluginRecordCountSource,\n options?: { pluginId?: string },\n): void {\n const key = kind.trim()\n if (!key) throw new Error('a record count source needs a record kind')\n const pluginId = (getRegisteringPluginId() ?? options?.pluginId ?? '').trim()\n if (!pluginId) {\n throw new Error(`the record count source for \"${key}\" was registered with no owner`)\n }\n const incumbent = resolvePluginServices(PLUGIN_RECORD_COUNTS).find((entry) => entry.key === key)\n if (incumbent && incumbent.pluginId !== pluginId) {\n throw new Error(\n `record kind \"${key}\" is already counted by \"${incumbent.pluginId}\"; refused \"${pluginId}\"`,\n )\n }\n registerPluginService(PLUGIN_RECORD_COUNTS, source, { pluginId, key })\n}\n\n/** The count source for a kind, or `null` when no plugin counts it here. */\nexport function pluginRecordCountSource(kind: string): PluginRecordCountSource | null {\n const key = kind.trim()\n return resolvePluginServices(PLUGIN_RECORD_COUNTS).find((one) => one.key === key)?.impl ?? null\n}\n"],"names":["getRegisteringPluginId","definePluginServiceContract","registerPluginService","resolvePluginServices","PLUGIN_RECORD_COUNTS","multiple","registerPluginRecordCountSource","kind","source","options","key","trim","Error","pluginId","incumbent","find","entry","pluginRecordCountSource","one","impl"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAGD,SAASA,sBAAsB,QAAQ,qCAAiC;AACxE,SACEC,2BAA2B,EAC3BC,qBAAqB,EACrBC,qBAAqB,QAChB,uBAAmB;AAqD1B,OAAO,MAAMC,uBAAuBH,4BAClC,sBACA;IAAEI,UAAU;AAAK,GAClB;AAED;;;;CAIC,GACD,OAAO,SAASC,gCACdC,IAAY,EACZC,MAA+B,EAC/BC,OAA+B;QAIbT,MAAAA;IAFlB,MAAMU,MAAMH,KAAKI,IAAI;IACrB,IAAI,CAACD,KAAK,MAAM,IAAIE,MAAM;IAC1B,MAAMC,WAAW,EAACb,QAAAA,0BAAAA,oCAAAA,0BAA4BS,2BAAAA,QAASI,QAAQ,YAA7Cb,OAAiD,IAAIW,IAAI;IAC3E,IAAI,CAACE,UAAU;QACb,MAAM,IAAID,MAAM,CAAC,6BAA6B,EAAEF,IAAI,8BAA8B,CAAC;IACrF;IACA,MAAMI,YAAYX,sBAAsBC,sBAAsBW,IAAI,CAAC,CAACC,QAAUA,MAAMN,GAAG,KAAKA;IAC5F,IAAII,aAAaA,UAAUD,QAAQ,KAAKA,UAAU;QAChD,MAAM,IAAID,MACR,CAAC,aAAa,EAAEF,IAAI,yBAAyB,EAAEI,UAAUD,QAAQ,CAAC,YAAY,EAAEA,SAAS,CAAC,CAAC;IAE/F;IACAX,sBAAsBE,sBAAsBI,QAAQ;QAAEK;QAAUH;IAAI;AACtE;AAEA,0EAA0E,GAC1E,OAAO,SAASO,wBAAwBV,IAAY;;QAE3CJ;IADP,MAAMO,MAAMH,KAAKI,IAAI;IACrB,gBAAOR,8BAAAA,sBAAsBC,sBAAsBW,IAAI,CAAC,CAACG,MAAQA,IAAIR,GAAG,KAAKA,yBAAtEP,4BAA4EgB,IAAI,mBAAI;AAC7F"}
@@ -104,6 +104,20 @@ export interface PluginRecordEmailReachRequest {
104
104
  /** The addresses delivered to, as the send addressed them. */
105
105
  emails: readonly string[];
106
106
  }
107
+ /**
108
+ * The people who wrote back to mail the workspace sent them (AGL-3080), so
109
+ * the record system can say a person is engaged — a lead nobody had worked is
110
+ * being worked now. Only a real reply: an opt-out answered with "remove me"
111
+ * is a refusal, filed through the suppression lists, and is not handed here.
112
+ */
113
+ export interface PluginRecordEmailReplyRequest {
114
+ /** The organization whose records the reply is about. */
115
+ orgId: string;
116
+ /** The site the mail went out as; only records it holds are moved. */
117
+ hostId: string;
118
+ /** The addresses that wrote back, as the mail addressed them. */
119
+ emails: readonly string[];
120
+ }
107
121
  export interface PluginRecordEmailStateWriter {
108
122
  /** Never throws: a list is the control, the stamp is what a person reads. */
109
123
  stamp(request: PluginRecordEmailStateRequest): Promise<PluginRecordEmailStateReport>;
@@ -120,6 +134,11 @@ export interface PluginRecordEmailStateWriter {
120
134
  * already gone.
121
135
  */
122
136
  reached?(request: PluginRecordEmailReachRequest): Promise<PluginRecordEmailStateReport>;
137
+ /**
138
+ * Notes that these people replied. Optional: a record system with no stage
139
+ * for it answers nothing. Never throws: the reply has already arrived.
140
+ */
141
+ replied?(request: PluginRecordEmailReplyRequest): Promise<PluginRecordEmailStateReport>;
123
142
  }
124
143
  export declare const PLUGIN_RECORD_EMAIL_STATE: import("./plugin-services").PluginServiceContract<PluginRecordEmailStateWriter>;
125
144
  /**
@@ -159,3 +178,10 @@ export declare function stampRecordEmailEngagement(request: PluginRecordEmailEng
159
178
  * send has already delivered, and its bookkeeping must not fail it.
160
179
  */
161
180
  export declare function stampRecordEmailReach(request: PluginRecordEmailReachRequest): Promise<PluginRecordEmailStateReport | null>;
181
+ /**
182
+ * Hands the addresses that wrote back to whichever plugin keeps the records
183
+ * (AGL-3080). Answers `null` when no plugin keeps records, or the one that
184
+ * does keeps no such stage. Never throws: the reply is already filed, and its
185
+ * bookkeeping must not fail the sync that read it.
186
+ */
187
+ export declare function stampRecordEmailReply(request: PluginRecordEmailReplyRequest): Promise<PluginRecordEmailStateReport | null>;
@@ -81,5 +81,21 @@ export const PLUGIN_RECORD_EMAIL_STATE = definePluginServiceContract('core.recor
81
81
  return null;
82
82
  }
83
83
  }
84
+ /**
85
+ * Hands the addresses that wrote back to whichever plugin keeps the records
86
+ * (AGL-3080). Answers `null` when no plugin keeps records, or the one that
87
+ * does keeps no such stage. Never throws: the reply is already filed, and its
88
+ * bookkeeping must not fail the sync that read it.
89
+ */ export async function stampRecordEmailReply(request) {
90
+ if (!request.emails.length) return null;
91
+ const resolved = pluginRecordEmailStateWriter();
92
+ if (!(resolved == null ? void 0 : resolved.writer.replied)) return null;
93
+ try {
94
+ return await resolved.writer.replied(request);
95
+ } catch (error) {
96
+ console.error('[record-email-state] the record system could not note a reply', error);
97
+ return null;
98
+ }
99
+ }
84
100
 
85
101
  //# sourceMappingURL=plugin-record-email-state.js.map