@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
@@ -0,0 +1,213 @@
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
+ * WHAT A PLUGIN EARNED THE OPERATOR, ON THE STAFF REVENUE REPORT (AGL-3080).
19
+ *
20
+ * The operator's revenue report states what the deployment actually kept in a
21
+ * period. Its own subscription invoices are platform billing and the report
22
+ * folds them itself. A plugin that sells through the platform's account — a
23
+ * storefront's application fee, a marketplace's commission — earns the
24
+ * operator a take the report cannot compute without knowing that plugin's
25
+ * storage and its fee rules, and it has no business restating either.
26
+ *
27
+ * So the division is: the REPORT is the platform's — the period, the two
28
+ * bases, the gap, the sweep ceiling, the read budget for names and the page.
29
+ * What a plugin's sales earned, net of what is not the operator's, and who
30
+ * produced it, are the plugin's. A source answers one period with a
31
+ * {@link RevenueSourceAnswer}: its earned line, its gross-to-net lines, its
32
+ * qualifications, its attribution tables and its own settled figures.
33
+ *
34
+ * ## ⛔ AN UNREAD SOURCE IS NEVER A ZERO
35
+ *
36
+ * A source that answered nothing reads, on a total, exactly like one that
37
+ * earned nothing, and a revenue total quoted short is a figure somebody
38
+ * repeats. So, as the tax return's sources do:
39
+ *
40
+ * - every plugin that earns through the platform declares
41
+ * `"revenueSource": true` in `plugins.config.json`, compiled into
42
+ * {@link PLUGIN_REVENUE_SOURCES}; a declared plugin with no registration, a
43
+ * source that threw and a malformed answer each come back
44
+ * `outcome: 'refused'`, and the page says whose earnings are missing;
45
+ * - a source whose own read could not run answers with `failure` and figures
46
+ * it does NOT claim, and one whose sweep stopped at the ceiling answers
47
+ * `truncated` — the page names both rather than quoting the total.
48
+ *
49
+ * {@link readRevenueSources} never throws and never drops a declared source.
50
+ * The reader is the staff revenue route, which awaits `ensureAll` on the
51
+ * `consoleApi` surface before it asks.
52
+ */
53
+ import { PLUGIN_REVENUE_SOURCES } from './first-party-plugins.generated';
54
+ export { PLUGIN_REVENUE_SOURCES };
55
+ /**
56
+ * Pages a query to exhaustion under the operator's ceiling. The ceiling is the
57
+ * platform's policy about its own request, so a source is handed the sweep
58
+ * rather than choosing one; `truncated` means the ceiling stopped it.
59
+ */
60
+ export type RevenueSweep = <Doc>(query: unknown, orderField: unknown) => Promise<{
61
+ docs: Doc[];
62
+ truncated: boolean;
63
+ }>;
64
+ /** One attributed row: who produced a gain, and the loss beside it. */
65
+ export interface RevenueAttributionRow {
66
+ key: string;
67
+ /** Display name, filled in by a bounded lookup; the id until then. */
68
+ name: string;
69
+ /** Secondary identity — plugin id, publisher, subdomain. */
70
+ detail: string;
71
+ /** Revenue earned, net of its own reversals. */
72
+ gainCents: number;
73
+ /** Money handed back. Already deducted from `gainCents`. */
74
+ lossCents: number;
75
+ count: number;
76
+ }
77
+ /** A capped attribution: shown rows plus the remainder, as figures. */
78
+ export interface RevenueAttribution {
79
+ rows: RevenueAttributionRow[];
80
+ omittedRows: number;
81
+ omittedGainCents: number;
82
+ omittedLossCents: number;
83
+ }
84
+ /** What the report asks every source, once per period. */
85
+ export interface RevenueSourceRequest {
86
+ /** `2026-08` or `2026-Q3`, echoed for the record. */
87
+ period: string;
88
+ /** Half-open UTC bounds of the period. */
89
+ start: Date;
90
+ end: Date;
91
+ /** Rows per attribution table the page shows; the rest is carried as figures. */
92
+ attributionLimit: number;
93
+ sweep: RevenueSweep;
94
+ /**
95
+ * Display names for organizations — which the report has already read, so
96
+ * naming a publisher costs nothing.
97
+ */
98
+ orgNames(orgIds: readonly string[]): Promise<ReadonlyMap<string, string>>;
99
+ /**
100
+ * Names the rows a source will SHOW from a collection's documents, in place:
101
+ * `name` from `nameField`, `detail` from `detailField`, and `(deleted)` for a
102
+ * document that is gone. Called AFTER capping, so the read is bounded by what
103
+ * is displayed rather than by how many sales the period holds.
104
+ */
105
+ nameRows(rows: RevenueAttributionRow[], from: {
106
+ collection: string;
107
+ nameField: string;
108
+ detailField: string;
109
+ }): Promise<void>;
110
+ }
111
+ /** A line of the report's gross-versus-net reconciliation. */
112
+ export interface RevenueSourceLine {
113
+ label: string;
114
+ cents: number;
115
+ /** Subtracted on the way from gross to what the operator kept. */
116
+ deduction: boolean;
117
+ /** Whose money it is — the sentence that says why it is or is not revenue. */
118
+ note: string;
119
+ }
120
+ /** A table of who produced a source's earnings. */
121
+ export interface RevenueAttributionTable extends RevenueAttribution {
122
+ id: string;
123
+ heading: string;
124
+ /** The column naming what a row is: `Listing`, `Storefront`. */
125
+ unit: string;
126
+ /** The column counting what was summed: `Sales`, `Orders`. */
127
+ countLabel: string;
128
+ empty: string;
129
+ /** Draw the rows as ranked bars above the table, saying this when there are none. */
130
+ chartEmpty?: string;
131
+ }
132
+ /** What a source answers for one period. */
133
+ export interface RevenueSourceAnswer {
134
+ /** Stable key, unique on the report. */
135
+ id: string;
136
+ /** How the report names it when its read stopped short: `marketplace`. */
137
+ name: string;
138
+ /** Its line of "where the money came from", net of everything not the operator's. */
139
+ earned: {
140
+ label: string;
141
+ cents: number;
142
+ note: string;
143
+ };
144
+ grossToNet: RevenueSourceLine[];
145
+ /** Qualifications worth stating beside the figures. Only those that apply. */
146
+ notes: Array<{
147
+ label: string;
148
+ tone: 'warning' | 'neutral';
149
+ }>;
150
+ /** Each sums to `earned`. */
151
+ attribution: RevenueAttributionTable[];
152
+ /** A sentence under the source's attribution tables. */
153
+ attributionNote?: string;
154
+ /** The sweep stopped at the ceiling: every figure is a LOWER BOUND. */
155
+ truncated: boolean;
156
+ /**
157
+ * The source's read could not run at all, so its figures are not counted —
158
+ * never a cap, which is a different state with a different remedy.
159
+ */
160
+ failure: {
161
+ title: string;
162
+ detail: string;
163
+ } | null;
164
+ /** The source's own settled figures, carried whole for the audit. */
165
+ summary: unknown;
166
+ }
167
+ /** One source on the report: its answer, or why there is none. */
168
+ export type RevenueSection = ({
169
+ outcome: 'answered';
170
+ pluginId: string;
171
+ } & RevenueSourceAnswer) | {
172
+ outcome: 'refused';
173
+ pluginId: string;
174
+ /** The plugin id: a refused source never said what it calls itself. */
175
+ id: string;
176
+ reason: string;
177
+ };
178
+ export interface RevenueSource {
179
+ /** This plugin's earnings for one period. May throw: the report refuses it. */
180
+ read(request: RevenueSourceRequest): Promise<RevenueSourceAnswer>;
181
+ }
182
+ /** Every source answers; one per plugin. */
183
+ export declare const REVENUE_SOURCES: import("./plugin-services").PluginServiceContract<RevenueSource>;
184
+ /** Installs a plugin's source; registering again replaces it. */
185
+ export declare function registerRevenueSource(source: RevenueSource, options?: {
186
+ pluginId?: string;
187
+ }): void;
188
+ /** The plugins with a registered source, in the order they answer. */
189
+ export declare function listRevenueSources(): string[];
190
+ /**
191
+ * Group, sort and cap — every attribution table's shared half.
192
+ *
193
+ * A row whose key is missing is NOT dropped. It is grouped under an explicit
194
+ * unattributed key, because a sale nobody can attribute still happened and
195
+ * dropping it would make the rows sum below the total — the one property that
196
+ * makes any of these tables worth reading. The cap carries its remainder as
197
+ * FIGURES, so the table stays a complete accounting even when it is not a
198
+ * complete list.
199
+ */
200
+ export declare function groupRevenueAttribution(entries: ReadonlyArray<{
201
+ key: string;
202
+ detail: string;
203
+ gain: number;
204
+ loss: number;
205
+ }>, limit: number, unattributedLabel: string): RevenueAttribution;
206
+ /**
207
+ * Every source's answer for one period — declared sources first, in the
208
+ * compiled order, then any other registered source.
209
+ *
210
+ * NEVER THROWS and never drops a declared source. `declared` is the compiled
211
+ * {@link PLUGIN_REVENUE_SOURCES} unless a spec passes its own.
212
+ */
213
+ export declare function readRevenueSources(request: RevenueSourceRequest, declared?: readonly string[]): Promise<RevenueSection[]>;
@@ -0,0 +1,194 @@
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
+ */ /**
18
+ * WHAT A PLUGIN EARNED THE OPERATOR, ON THE STAFF REVENUE REPORT (AGL-3080).
19
+ *
20
+ * The operator's revenue report states what the deployment actually kept in a
21
+ * period. Its own subscription invoices are platform billing and the report
22
+ * folds them itself. A plugin that sells through the platform's account — a
23
+ * storefront's application fee, a marketplace's commission — earns the
24
+ * operator a take the report cannot compute without knowing that plugin's
25
+ * storage and its fee rules, and it has no business restating either.
26
+ *
27
+ * So the division is: the REPORT is the platform's — the period, the two
28
+ * bases, the gap, the sweep ceiling, the read budget for names and the page.
29
+ * What a plugin's sales earned, net of what is not the operator's, and who
30
+ * produced it, are the plugin's. A source answers one period with a
31
+ * {@link RevenueSourceAnswer}: its earned line, its gross-to-net lines, its
32
+ * qualifications, its attribution tables and its own settled figures.
33
+ *
34
+ * ## ⛔ AN UNREAD SOURCE IS NEVER A ZERO
35
+ *
36
+ * A source that answered nothing reads, on a total, exactly like one that
37
+ * earned nothing, and a revenue total quoted short is a figure somebody
38
+ * repeats. So, as the tax return's sources do:
39
+ *
40
+ * - every plugin that earns through the platform declares
41
+ * `"revenueSource": true` in `plugins.config.json`, compiled into
42
+ * {@link PLUGIN_REVENUE_SOURCES}; a declared plugin with no registration, a
43
+ * source that threw and a malformed answer each come back
44
+ * `outcome: 'refused'`, and the page says whose earnings are missing;
45
+ * - a source whose own read could not run answers with `failure` and figures
46
+ * it does NOT claim, and one whose sweep stopped at the ceiling answers
47
+ * `truncated` — the page names both rather than quoting the total.
48
+ *
49
+ * {@link readRevenueSources} never throws and never drops a declared source.
50
+ * The reader is the staff revenue route, which awaits `ensureAll` on the
51
+ * `consoleApi` surface before it asks.
52
+ */ import { PLUGIN_REVENUE_SOURCES } from "./first-party-plugins.generated.js";
53
+ import { definePluginServiceContract, registerPluginService, resolvePluginServices } from "./plugin-services.js";
54
+ export { PLUGIN_REVENUE_SOURCES };
55
+ /** Every source answers; one per plugin. */ export const REVENUE_SOURCES = definePluginServiceContract('core.revenue-sources', {
56
+ multiple: true
57
+ });
58
+ /** Installs a plugin's source; registering again replaces it. */ export function registerRevenueSource(source, options) {
59
+ if (typeof (source == null ? void 0 : source.read) !== 'function') {
60
+ throw new Error('a revenue source needs a read function');
61
+ }
62
+ registerPluginService(REVENUE_SOURCES, source, _extends({}, (options == null ? void 0 : options.pluginId) ? {
63
+ pluginId: options.pluginId
64
+ } : {}));
65
+ }
66
+ /** The plugins with a registered source, in the order they answer. */ export function listRevenueSources() {
67
+ return resolvePluginServices(REVENUE_SOURCES).map((entry)=>entry.pluginId);
68
+ }
69
+ /**
70
+ * Group, sort and cap — every attribution table's shared half.
71
+ *
72
+ * A row whose key is missing is NOT dropped. It is grouped under an explicit
73
+ * unattributed key, because a sale nobody can attribute still happened and
74
+ * dropping it would make the rows sum below the total — the one property that
75
+ * makes any of these tables worth reading. The cap carries its remainder as
76
+ * FIGURES, so the table stays a complete accounting even when it is not a
77
+ * complete list.
78
+ */ export function groupRevenueAttribution(entries, limit, unattributedLabel) {
79
+ const byKey = new Map();
80
+ for (const entry of entries != null ? entries : []){
81
+ var _byKey_get, _entry_detail;
82
+ const key = entry.key || unattributedLabel;
83
+ const row = (_byKey_get = byKey.get(key)) != null ? _byKey_get : {
84
+ key,
85
+ name: key === unattributedLabel ? unattributedLabel : key,
86
+ detail: (_entry_detail = entry.detail) != null ? _entry_detail : '',
87
+ gainCents: 0,
88
+ lossCents: 0,
89
+ count: 0
90
+ };
91
+ row.gainCents += entry.gain;
92
+ row.lossCents += entry.loss;
93
+ row.count += 1;
94
+ if (!row.detail && entry.detail) row.detail = entry.detail;
95
+ byKey.set(key, row);
96
+ }
97
+ const rows = [
98
+ ...byKey.values()
99
+ ].sort((a, b)=>b.gainCents - a.gainCents || b.lossCents - a.lossCents || a.key.localeCompare(b.key));
100
+ const kept = rows.slice(0, Math.max(0, limit));
101
+ const dropped = rows.slice(Math.max(0, limit));
102
+ return {
103
+ rows: kept,
104
+ omittedRows: dropped.length,
105
+ omittedGainCents: dropped.reduce((sum, row)=>sum + row.gainCents, 0),
106
+ omittedLossCents: dropped.reduce((sum, row)=>sum + row.lossCents, 0)
107
+ };
108
+ }
109
+ const isText = (value)=>typeof value === 'string' && value.trim().length > 0;
110
+ /** What is wrong with an answer, or null when it can be printed. */ function malformed(answer) {
111
+ var _answer_earned, _answer_earned1;
112
+ if (!answer || typeof answer !== 'object') return 'no report';
113
+ if (!isText(answer.id) || !isText(answer.name)) return 'a report with no id or name';
114
+ const cents = (_answer_earned = answer.earned) == null ? void 0 : _answer_earned.cents;
115
+ if (typeof cents !== 'number' || !Number.isFinite(cents)) return 'no earned figure';
116
+ if (!isText((_answer_earned1 = answer.earned) == null ? void 0 : _answer_earned1.label)) return 'an earned figure with no label';
117
+ if (typeof answer.truncated !== 'boolean') return 'no truncation flag';
118
+ for (const key of [
119
+ 'grossToNet',
120
+ 'notes',
121
+ 'attribution'
122
+ ]){
123
+ if (!Array.isArray(answer[key])) return `no ${key}`;
124
+ }
125
+ const badLine = answer.grossToNet.find((line)=>typeof (line == null ? void 0 : line.cents) !== 'number' || !Number.isFinite(line.cents));
126
+ if (badLine) return 'a gross-to-net line with no figure';
127
+ return null;
128
+ }
129
+ /**
130
+ * Every source's answer for one period — declared sources first, in the
131
+ * compiled order, then any other registered source.
132
+ *
133
+ * NEVER THROWS and never drops a declared source. `declared` is the compiled
134
+ * {@link PLUGIN_REVENUE_SOURCES} unless a spec passes its own.
135
+ */ export async function readRevenueSources(request, declared = PLUGIN_REVENUE_SOURCES) {
136
+ const registered = resolvePluginServices(REVENUE_SOURCES);
137
+ const order = [
138
+ ...declared,
139
+ ...registered.map((entry)=>entry.pluginId).filter((pluginId)=>!declared.includes(pluginId))
140
+ ].filter((pluginId, index, all)=>all.indexOf(pluginId) === index);
141
+ const answers = await Promise.all(order.map(async (pluginId)=>{
142
+ var _registered_find;
143
+ const source = (_registered_find = registered.find((entry)=>entry.pluginId === pluginId)) == null ? void 0 : _registered_find.impl;
144
+ if (!source) {
145
+ console.error(`[revenue] "${pluginId}" declares a revenue source and none is ` + 'registered in this process; its earnings cannot be read.');
146
+ return {
147
+ outcome: 'refused',
148
+ pluginId,
149
+ id: pluginId,
150
+ reason: `The “${pluginId}” plugin earns through the platform and registered ` + 'nothing to read its earnings with.'
151
+ };
152
+ }
153
+ try {
154
+ const answer = await source.read(request);
155
+ const problem = malformed(answer);
156
+ if (problem) {
157
+ return {
158
+ outcome: 'refused',
159
+ pluginId,
160
+ id: pluginId,
161
+ reason: `The “${pluginId}” plugin answered ${problem}.`
162
+ };
163
+ }
164
+ return _extends({}, answer, {
165
+ outcome: 'answered',
166
+ pluginId
167
+ });
168
+ } catch (error) {
169
+ console.error(`[revenue] "${pluginId}" failed to read its earnings`, error);
170
+ return {
171
+ outcome: 'refused',
172
+ pluginId,
173
+ id: pluginId,
174
+ reason: `The “${pluginId}” plugin could not read its earnings for this period.`
175
+ };
176
+ }
177
+ }));
178
+ const seen = new Set();
179
+ return answers.map((section)=>{
180
+ if (section.outcome !== 'answered') return section;
181
+ if (!seen.has(section.id)) {
182
+ seen.add(section.id);
183
+ return section;
184
+ }
185
+ return {
186
+ outcome: 'refused',
187
+ pluginId: section.pluginId,
188
+ id: section.pluginId,
189
+ reason: `The “${section.pluginId}” plugin answered as “${section.id}”, which ` + 'another source already is.'
190
+ };
191
+ });
192
+ }
193
+
194
+ //# sourceMappingURL=plugin-revenue-sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-revenue-sources.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * WHAT A PLUGIN EARNED THE OPERATOR, ON THE STAFF REVENUE REPORT (AGL-3080).\n *\n * The operator's revenue report states what the deployment actually kept in a\n * period. Its own subscription invoices are platform billing and the report\n * folds them itself. A plugin that sells through the platform's account — a\n * storefront's application fee, a marketplace's commission — earns the\n * operator a take the report cannot compute without knowing that plugin's\n * storage and its fee rules, and it has no business restating either.\n *\n * So the division is: the REPORT is the platform's — the period, the two\n * bases, the gap, the sweep ceiling, the read budget for names and the page.\n * What a plugin's sales earned, net of what is not the operator's, and who\n * produced it, are the plugin's. A source answers one period with a\n * {@link RevenueSourceAnswer}: its earned line, its gross-to-net lines, its\n * qualifications, its attribution tables and its own settled figures.\n *\n * ## ⛔ AN UNREAD SOURCE IS NEVER A ZERO\n *\n * A source that answered nothing reads, on a total, exactly like one that\n * earned nothing, and a revenue total quoted short is a figure somebody\n * repeats. So, as the tax return's sources do:\n *\n * - every plugin that earns through the platform declares\n * `\"revenueSource\": true` in `plugins.config.json`, compiled into\n * {@link PLUGIN_REVENUE_SOURCES}; a declared plugin with no registration, a\n * source that threw and a malformed answer each come back\n * `outcome: 'refused'`, and the page says whose earnings are missing;\n * - a source whose own read could not run answers with `failure` and figures\n * it does NOT claim, and one whose sweep stopped at the ceiling answers\n * `truncated` — the page names both rather than quoting the total.\n *\n * {@link readRevenueSources} never throws and never drops a declared source.\n * The reader is the staff revenue route, which awaits `ensureAll` on the\n * `consoleApi` surface before it asks.\n */\n\nimport { PLUGIN_REVENUE_SOURCES } from './first-party-plugins.generated'\nimport {\n definePluginServiceContract,\n registerPluginService,\n resolvePluginServices,\n} from './plugin-services'\n\nexport { PLUGIN_REVENUE_SOURCES }\n\n/**\n * Pages a query to exhaustion under the operator's ceiling. The ceiling is the\n * platform's policy about its own request, so a source is handed the sweep\n * rather than choosing one; `truncated` means the ceiling stopped it.\n */\nexport type RevenueSweep = <Doc>(\n query: unknown,\n orderField: unknown,\n) => Promise<{ docs: Doc[]; truncated: boolean }>\n\n/** One attributed row: who produced a gain, and the loss beside it. */\nexport interface RevenueAttributionRow {\n key: string\n /** Display name, filled in by a bounded lookup; the id until then. */\n name: string\n /** Secondary identity — plugin id, publisher, subdomain. */\n detail: string\n /** Revenue earned, net of its own reversals. */\n gainCents: number\n /** Money handed back. Already deducted from `gainCents`. */\n lossCents: number\n count: number\n}\n\n/** A capped attribution: shown rows plus the remainder, as figures. */\nexport interface RevenueAttribution {\n rows: RevenueAttributionRow[]\n omittedRows: number\n omittedGainCents: number\n omittedLossCents: number\n}\n\n/** What the report asks every source, once per period. */\nexport interface RevenueSourceRequest {\n /** `2026-08` or `2026-Q3`, echoed for the record. */\n period: string\n /** Half-open UTC bounds of the period. */\n start: Date\n end: Date\n /** Rows per attribution table the page shows; the rest is carried as figures. */\n attributionLimit: number\n sweep: RevenueSweep\n /**\n * Display names for organizations — which the report has already read, so\n * naming a publisher costs nothing.\n */\n orgNames(orgIds: readonly string[]): Promise<ReadonlyMap<string, string>>\n /**\n * Names the rows a source will SHOW from a collection's documents, in place:\n * `name` from `nameField`, `detail` from `detailField`, and `(deleted)` for a\n * document that is gone. Called AFTER capping, so the read is bounded by what\n * is displayed rather than by how many sales the period holds.\n */\n nameRows(\n rows: RevenueAttributionRow[],\n from: { collection: string; nameField: string; detailField: string },\n ): Promise<void>\n}\n\n/** A line of the report's gross-versus-net reconciliation. */\nexport interface RevenueSourceLine {\n label: string\n cents: number\n /** Subtracted on the way from gross to what the operator kept. */\n deduction: boolean\n /** Whose money it is — the sentence that says why it is or is not revenue. */\n note: string\n}\n\n/** A table of who produced a source's earnings. */\nexport interface RevenueAttributionTable extends RevenueAttribution {\n id: string\n heading: string\n /** The column naming what a row is: `Listing`, `Storefront`. */\n unit: string\n /** The column counting what was summed: `Sales`, `Orders`. */\n countLabel: string\n empty: string\n /** Draw the rows as ranked bars above the table, saying this when there are none. */\n chartEmpty?: string\n}\n\n/** What a source answers for one period. */\nexport interface RevenueSourceAnswer {\n /** Stable key, unique on the report. */\n id: string\n /** How the report names it when its read stopped short: `marketplace`. */\n name: string\n /** Its line of \"where the money came from\", net of everything not the operator's. */\n earned: { label: string; cents: number; note: string }\n grossToNet: RevenueSourceLine[]\n /** Qualifications worth stating beside the figures. Only those that apply. */\n notes: Array<{ label: string; tone: 'warning' | 'neutral' }>\n /** Each sums to `earned`. */\n attribution: RevenueAttributionTable[]\n /** A sentence under the source's attribution tables. */\n attributionNote?: string\n /** The sweep stopped at the ceiling: every figure is a LOWER BOUND. */\n truncated: boolean\n /**\n * The source's read could not run at all, so its figures are not counted —\n * never a cap, which is a different state with a different remedy.\n */\n failure: { title: string; detail: string } | null\n /** The source's own settled figures, carried whole for the audit. */\n summary: unknown\n}\n\n/** One source on the report: its answer, or why there is none. */\nexport type RevenueSection =\n | ({ outcome: 'answered'; pluginId: string } & RevenueSourceAnswer)\n | {\n outcome: 'refused'\n pluginId: string\n /** The plugin id: a refused source never said what it calls itself. */\n id: string\n reason: string\n }\n\nexport interface RevenueSource {\n /** This plugin's earnings for one period. May throw: the report refuses it. */\n read(request: RevenueSourceRequest): Promise<RevenueSourceAnswer>\n}\n\n/** Every source answers; one per plugin. */\nexport const REVENUE_SOURCES = definePluginServiceContract<RevenueSource>(\n 'core.revenue-sources',\n { multiple: true },\n)\n\n/** Installs a plugin's source; registering again replaces it. */\nexport function registerRevenueSource(\n source: RevenueSource,\n options?: { pluginId?: string },\n): void {\n if (typeof source?.read !== 'function') {\n throw new Error('a revenue source needs a read function')\n }\n registerPluginService(REVENUE_SOURCES, source, {\n ...(options?.pluginId ? { pluginId: options.pluginId } : {}),\n })\n}\n\n/** The plugins with a registered source, in the order they answer. */\nexport function listRevenueSources(): string[] {\n return resolvePluginServices(REVENUE_SOURCES).map((entry) => entry.pluginId)\n}\n\n/**\n * Group, sort and cap — every attribution table's shared half.\n *\n * A row whose key is missing is NOT dropped. It is grouped under an explicit\n * unattributed key, because a sale nobody can attribute still happened and\n * dropping it would make the rows sum below the total — the one property that\n * makes any of these tables worth reading. The cap carries its remainder as\n * FIGURES, so the table stays a complete accounting even when it is not a\n * complete list.\n */\nexport function groupRevenueAttribution(\n entries: ReadonlyArray<{ key: string; detail: string; gain: number; loss: number }>,\n limit: number,\n unattributedLabel: string,\n): RevenueAttribution {\n const byKey = new Map<string, RevenueAttributionRow>()\n for (const entry of entries ?? []) {\n const key = entry.key || unattributedLabel\n const row = byKey.get(key) ?? {\n key,\n name: key === unattributedLabel ? unattributedLabel : key,\n detail: entry.detail ?? '',\n gainCents: 0,\n lossCents: 0,\n count: 0,\n }\n row.gainCents += entry.gain\n row.lossCents += entry.loss\n row.count += 1\n if (!row.detail && entry.detail) row.detail = entry.detail\n byKey.set(key, row)\n }\n const rows = [...byKey.values()].sort(\n (a, b) =>\n b.gainCents - a.gainCents ||\n b.lossCents - a.lossCents ||\n a.key.localeCompare(b.key),\n )\n const kept = rows.slice(0, Math.max(0, limit))\n const dropped = rows.slice(Math.max(0, limit))\n return {\n rows: kept,\n omittedRows: dropped.length,\n omittedGainCents: dropped.reduce((sum, row) => sum + row.gainCents, 0),\n omittedLossCents: dropped.reduce((sum, row) => sum + row.lossCents, 0),\n }\n}\n\nconst isText = (value: unknown): value is string =>\n typeof value === 'string' && value.trim().length > 0\n\n/** What is wrong with an answer, or null when it can be printed. */\nfunction malformed(answer: RevenueSourceAnswer): string | null {\n if (!answer || typeof answer !== 'object') return 'no report'\n if (!isText(answer.id) || !isText(answer.name)) return 'a report with no id or name'\n const cents = answer.earned?.cents\n if (typeof cents !== 'number' || !Number.isFinite(cents)) return 'no earned figure'\n if (!isText(answer.earned?.label)) return 'an earned figure with no label'\n if (typeof answer.truncated !== 'boolean') return 'no truncation flag'\n for (const key of ['grossToNet', 'notes', 'attribution'] as const) {\n if (!Array.isArray(answer[key])) return `no ${key}`\n }\n const badLine = answer.grossToNet.find(\n (line) => typeof line?.cents !== 'number' || !Number.isFinite(line.cents),\n )\n if (badLine) return 'a gross-to-net line with no figure'\n return null\n}\n\n/**\n * Every source's answer for one period — declared sources first, in the\n * compiled order, then any other registered source.\n *\n * NEVER THROWS and never drops a declared source. `declared` is the compiled\n * {@link PLUGIN_REVENUE_SOURCES} unless a spec passes its own.\n */\nexport async function readRevenueSources(\n request: RevenueSourceRequest,\n declared: readonly string[] = PLUGIN_REVENUE_SOURCES,\n): Promise<RevenueSection[]> {\n const registered = resolvePluginServices(REVENUE_SOURCES)\n const order = [\n ...declared,\n ...registered\n .map((entry) => entry.pluginId)\n .filter((pluginId) => !declared.includes(pluginId)),\n ].filter((pluginId, index, all) => all.indexOf(pluginId) === index)\n\n const answers = await Promise.all(\n order.map(async (pluginId): Promise<RevenueSection> => {\n const source = registered.find((entry) => entry.pluginId === pluginId)?.impl\n if (!source) {\n console.error(\n `[revenue] \"${pluginId}\" declares a revenue source and none is ` +\n 'registered in this process; its earnings cannot be read.',\n )\n return {\n outcome: 'refused',\n pluginId,\n id: pluginId,\n reason:\n `The “${pluginId}” plugin earns through the platform and registered ` +\n 'nothing to read its earnings with.',\n }\n }\n try {\n const answer = await source.read(request)\n const problem = malformed(answer)\n if (problem) {\n return {\n outcome: 'refused',\n pluginId,\n id: pluginId,\n reason: `The “${pluginId}” plugin answered ${problem}.`,\n }\n }\n return { ...answer, outcome: 'answered', pluginId }\n } catch (error) {\n console.error(`[revenue] \"${pluginId}\" failed to read its earnings`, error)\n return {\n outcome: 'refused',\n pluginId,\n id: pluginId,\n reason: `The “${pluginId}” plugin could not read its earnings for this period.`,\n }\n }\n }),\n )\n\n const seen = new Set<string>()\n return answers.map((section) => {\n if (section.outcome !== 'answered') return section\n if (!seen.has(section.id)) {\n seen.add(section.id)\n return section\n }\n return {\n outcome: 'refused',\n pluginId: section.pluginId,\n id: section.pluginId,\n reason:\n `The “${section.pluginId}” plugin answered as “${section.id}”, which ` +\n 'another source already is.',\n }\n })\n}\n"],"names":["PLUGIN_REVENUE_SOURCES","definePluginServiceContract","registerPluginService","resolvePluginServices","REVENUE_SOURCES","multiple","registerRevenueSource","source","options","read","Error","pluginId","listRevenueSources","map","entry","groupRevenueAttribution","entries","limit","unattributedLabel","byKey","Map","key","row","get","name","detail","gainCents","lossCents","count","gain","loss","set","rows","values","sort","a","b","localeCompare","kept","slice","Math","max","dropped","omittedRows","length","omittedGainCents","reduce","sum","omittedLossCents","isText","value","trim","malformed","answer","id","cents","earned","Number","isFinite","label","truncated","Array","isArray","badLine","grossToNet","find","line","readRevenueSources","request","declared","registered","order","filter","includes","index","all","indexOf","answers","Promise","impl","console","error","outcome","reason","problem","seen","Set","section","has","add"],"mappings":"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"}
@@ -0,0 +1,71 @@
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
+ * A plugin's own beacons, posted to the platform's site collector.
19
+ *
20
+ * A published page has one place to report what visitors did — the
21
+ * collector behind `sendAnalyticsBeacon` — and that endpoint owns what every
22
+ * beacon owes before anything is counted: the host must exist, a platform,
23
+ * org or site lockdown refuses it silently, and the per-address rate limit
24
+ * applies. What a plugin's site runtime reports beyond a pageview (an
25
+ * announcement bar seen, a popup dismissed) is the plugin's to count, in its
26
+ * own documents.
27
+ *
28
+ * So the plugin registers a beacon by the body FIELD that marks it as its
29
+ * own, and the collector hands a beacon carrying that field to the plugin
30
+ * after its own gates, then answers 204 without counting a pageview. The
31
+ * field is the beacon's whole claim: one owner per field, refused naming
32
+ * both, and the incumbent keeps serving.
33
+ *
34
+ * Registered from the plugin's `serverDeclarations`, so every server process
35
+ * has it from boot; keep the registration light and import the counting
36
+ * code on the first beacon.
37
+ */
38
+ /** What the collector hands the owner, after the host and lockdown gates. */
39
+ export interface PluginSiteBeaconRequest {
40
+ hostId: string;
41
+ /** The collector's day bucket, `YYYY-MM-DD` in UTC. */
42
+ day: string;
43
+ /**
44
+ * When the site's analytics document for {@link day} expires: the
45
+ * platform's retention. An owner that writes into that document stamps it,
46
+ * so a document created by its beacons alone is still swept.
47
+ */
48
+ dayExpiresAt: Date;
49
+ /** The beacon as the browser sent it. Untrusted: validate every field read. */
50
+ body: Readonly<Record<string, unknown>>;
51
+ }
52
+ export interface PluginSiteBeacon {
53
+ /** The body field whose non-empty string marks a beacon as this plugin's. */
54
+ field: string;
55
+ /** Counts one beacon. A throw is logged by the collector, never surfaced. */
56
+ count(request: PluginSiteBeaconRequest): Promise<void>;
57
+ }
58
+ export declare const PLUGIN_SITE_BEACONS: import("./plugin-services").PluginServiceContract<PluginSiteBeacon>;
59
+ /**
60
+ * Registers a beacon. The owner is the loader's marker inside a register fn,
61
+ * else `options.pluginId`; with neither the registration throws. A field
62
+ * another plugin claims throws naming both.
63
+ */
64
+ export declare function registerPluginSiteBeacon(beacon: PluginSiteBeacon, options?: {
65
+ pluginId?: string;
66
+ }): void;
67
+ /** The owner of a beacon body, or `null` when no registered field marks it. */
68
+ export declare function pluginSiteBeaconFor(body: Readonly<Record<string, unknown>>): {
69
+ pluginId: string;
70
+ beacon: PluginSiteBeacon;
71
+ } | null;
@@ -0,0 +1,54 @@
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 { getRegisteringPluginId } from "../app-utils/registering-plugin.js";
18
+ import { definePluginServiceContract, registerPluginService, resolvePluginServices } from "./plugin-services.js";
19
+ export const PLUGIN_SITE_BEACONS = definePluginServiceContract('core.site-beacons', {
20
+ multiple: true
21
+ });
22
+ /**
23
+ * Registers a beacon. The owner is the loader's marker inside a register fn,
24
+ * else `options.pluginId`; with neither the registration throws. A field
25
+ * another plugin claims throws naming both.
26
+ */ export function registerPluginSiteBeacon(beacon, options) {
27
+ var _beacon_field, _ref, _getRegisteringPluginId;
28
+ const field = String((_beacon_field = beacon.field) != null ? _beacon_field : '').trim();
29
+ if (!field) throw new Error('a site beacon needs the body field that marks it');
30
+ const pluginId = ((_ref = (_getRegisteringPluginId = getRegisteringPluginId()) != null ? _getRegisteringPluginId : options == null ? void 0 : options.pluginId) != null ? _ref : '').trim();
31
+ if (!pluginId) throw new Error(`the site beacon "${field}" was registered with no owner`);
32
+ const incumbent = resolvePluginServices(PLUGIN_SITE_BEACONS).find((entry)=>entry.key === field);
33
+ if (incumbent && incumbent.pluginId !== pluginId) {
34
+ throw new Error(`site beacon field "${field}" is already counted by "${incumbent.pluginId}"; refused "${pluginId}"`);
35
+ }
36
+ registerPluginService(PLUGIN_SITE_BEACONS, _extends({}, beacon, {
37
+ field
38
+ }), {
39
+ pluginId,
40
+ key: field
41
+ });
42
+ }
43
+ /** The owner of a beacon body, or `null` when no registered field marks it. */ export function pluginSiteBeaconFor(body) {
44
+ for (const entry of resolvePluginServices(PLUGIN_SITE_BEACONS)){
45
+ const value = body[entry.impl.field];
46
+ if (typeof value === 'string' && value) return {
47
+ pluginId: entry.pluginId,
48
+ beacon: entry.impl
49
+ };
50
+ }
51
+ return null;
52
+ }
53
+
54
+ //# sourceMappingURL=plugin-site-beacons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-site-beacons.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 { getRegisteringPluginId } from '../app-utils/registering-plugin'\nimport {\n definePluginServiceContract,\n registerPluginService,\n resolvePluginServices,\n} from './plugin-services'\n\n/**\n * A plugin's own beacons, posted to the platform's site collector.\n *\n * A published page has one place to report what visitors did — the\n * collector behind `sendAnalyticsBeacon` — and that endpoint owns what every\n * beacon owes before anything is counted: the host must exist, a platform,\n * org or site lockdown refuses it silently, and the per-address rate limit\n * applies. What a plugin's site runtime reports beyond a pageview (an\n * announcement bar seen, a popup dismissed) is the plugin's to count, in its\n * own documents.\n *\n * So the plugin registers a beacon by the body FIELD that marks it as its\n * own, and the collector hands a beacon carrying that field to the plugin\n * after its own gates, then answers 204 without counting a pageview. The\n * field is the beacon's whole claim: one owner per field, refused naming\n * both, and the incumbent keeps serving.\n *\n * Registered from the plugin's `serverDeclarations`, so every server process\n * has it from boot; keep the registration light and import the counting\n * code on the first beacon.\n */\n\n/** What the collector hands the owner, after the host and lockdown gates. */\nexport interface PluginSiteBeaconRequest {\n hostId: string\n /** The collector's day bucket, `YYYY-MM-DD` in UTC. */\n day: string\n /**\n * When the site's analytics document for {@link day} expires: the\n * platform's retention. An owner that writes into that document stamps it,\n * so a document created by its beacons alone is still swept.\n */\n dayExpiresAt: Date\n /** The beacon as the browser sent it. Untrusted: validate every field read. */\n body: Readonly<Record<string, unknown>>\n}\n\nexport interface PluginSiteBeacon {\n /** The body field whose non-empty string marks a beacon as this plugin's. */\n field: string\n /** Counts one beacon. A throw is logged by the collector, never surfaced. */\n count(request: PluginSiteBeaconRequest): Promise<void>\n}\n\nexport const PLUGIN_SITE_BEACONS = definePluginServiceContract<PluginSiteBeacon>(\n 'core.site-beacons',\n { multiple: true },\n)\n\n/**\n * Registers a beacon. The owner is the loader's marker inside a register fn,\n * else `options.pluginId`; with neither the registration throws. A field\n * another plugin claims throws naming both.\n */\nexport function registerPluginSiteBeacon(\n beacon: PluginSiteBeacon,\n options?: { pluginId?: string },\n): void {\n const field = String(beacon.field ?? '').trim()\n if (!field) throw new Error('a site beacon needs the body field that marks it')\n const pluginId = (getRegisteringPluginId() ?? options?.pluginId ?? '').trim()\n if (!pluginId) throw new Error(`the site beacon \"${field}\" was registered with no owner`)\n const incumbent = resolvePluginServices(PLUGIN_SITE_BEACONS).find((entry) => entry.key === field)\n if (incumbent && incumbent.pluginId !== pluginId) {\n throw new Error(\n `site beacon field \"${field}\" is already counted by \"${incumbent.pluginId}\"; refused \"${pluginId}\"`,\n )\n }\n registerPluginService(PLUGIN_SITE_BEACONS, { ...beacon, field }, { pluginId, key: field })\n}\n\n/** The owner of a beacon body, or `null` when no registered field marks it. */\nexport function pluginSiteBeaconFor(\n body: Readonly<Record<string, unknown>>,\n): { pluginId: string; beacon: PluginSiteBeacon } | null {\n for (const entry of resolvePluginServices(PLUGIN_SITE_BEACONS)) {\n const value = body[entry.impl.field]\n if (typeof value === 'string' && value) return { pluginId: entry.pluginId, beacon: entry.impl }\n }\n return null\n}\n"],"names":["getRegisteringPluginId","definePluginServiceContract","registerPluginService","resolvePluginServices","PLUGIN_SITE_BEACONS","multiple","registerPluginSiteBeacon","beacon","options","field","String","trim","Error","pluginId","incumbent","find","entry","key","pluginSiteBeaconFor","body","value","impl"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,sBAAsB,QAAQ,qCAAiC;AACxE,SACEC,2BAA2B,EAC3BC,qBAAqB,EACrBC,qBAAqB,QAChB,uBAAmB;AA8C1B,OAAO,MAAMC,sBAAsBH,4BACjC,qBACA;IAAEI,UAAU;AAAK,GAClB;AAED;;;;CAIC,GACD,OAAO,SAASC,yBACdC,MAAwB,EACxBC,OAA+B;QAEVD,eAEHP,MAAAA;IAFlB,MAAMS,QAAQC,QAAOH,gBAAAA,OAAOE,KAAK,YAAZF,gBAAgB,IAAII,IAAI;IAC7C,IAAI,CAACF,OAAO,MAAM,IAAIG,MAAM;IAC5B,MAAMC,WAAW,EAACb,QAAAA,0BAAAA,oCAAAA,0BAA4BQ,2BAAAA,QAASK,QAAQ,YAA7Cb,OAAiD,IAAIW,IAAI;IAC3E,IAAI,CAACE,UAAU,MAAM,IAAID,MAAM,CAAC,iBAAiB,EAAEH,MAAM,8BAA8B,CAAC;IACxF,MAAMK,YAAYX,sBAAsBC,qBAAqBW,IAAI,CAAC,CAACC,QAAUA,MAAMC,GAAG,KAAKR;IAC3F,IAAIK,aAAaA,UAAUD,QAAQ,KAAKA,UAAU;QAChD,MAAM,IAAID,MACR,CAAC,mBAAmB,EAAEH,MAAM,yBAAyB,EAAEK,UAAUD,QAAQ,CAAC,YAAY,EAAEA,SAAS,CAAC,CAAC;IAEvG;IACAX,sBAAsBE,qBAAqB,aAAKG;QAAQE;QAAS;QAAEI;QAAUI,KAAKR;IAAM;AAC1F;AAEA,6EAA6E,GAC7E,OAAO,SAASS,oBACdC,IAAuC;IAEvC,KAAK,MAAMH,SAASb,sBAAsBC,qBAAsB;QAC9D,MAAMgB,QAAQD,IAAI,CAACH,MAAMK,IAAI,CAACZ,KAAK,CAAC;QACpC,IAAI,OAAOW,UAAU,YAAYA,OAAO,OAAO;YAAEP,UAAUG,MAAMH,QAAQ;YAAEN,QAAQS,MAAMK,IAAI;QAAC;IAChG;IACA,OAAO;AACT"}