@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,145 @@
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 SECTION of the whole-site backup (AGL-3080): what it carries in
19
+ * the bundle and restores from it, when a host collection's `siteExport`
20
+ * cannot say so.
21
+ *
22
+ * A plain host collection is copied by the export and restore routes
23
+ * themselves (`plugin-site-export.ts`). Some plugin data is not that shape:
24
+ * it lives under the ORGANIZATION and is narrowed to the site being backed up,
25
+ * it carries a subcollection, a restore has to validate it against its own
26
+ * model and derive what the model implies, and its count is sold as an add-on
27
+ * rather than read off the plan. Only the plugin knows any of that. So the
28
+ * plugin declares the section and answers for it: the export asks it for the
29
+ * site's share, and the restore asks it — before the first write — whether
30
+ * the bundle would cross what the organization has paid for, then hands it the
31
+ * bundle's items and the restore's writer.
32
+ *
33
+ * ## Declared, then registered — and an absent section is refused
34
+ *
35
+ * The plugin declares the section in `plugins.config.json`
36
+ * (`siteBundleSections`: the bundle key and the most items it carries), which
37
+ * the generator compiles, and registers the answer from its
38
+ * `serverDeclarations` entry. A backup that silently lacks a section is worse
39
+ * than a failed one — the file looks whole until the day it is restored — so
40
+ * a section declared and not registered is not read as "nothing to carry":
41
+ * {@link resolveSiteBundleSections} runs the app's declarations step again,
42
+ * and throws if the section is still missing, which fails the export or the
43
+ * restore out loud.
44
+ *
45
+ * ## What the restore owns
46
+ *
47
+ * The section writes through {@link SiteBundleImportRequest.write}, never
48
+ * with a writer of its own: the restore's chunked batches, its document count
49
+ * and its all-or-nothing refusal are the restore's, and a write that went
50
+ * around them would land after a refusal or be missing from the total. The
51
+ * restore's own stamps (`createdAt`, `updatedAt`) come from
52
+ * {@link SiteBundleImportRequest.stamps}, so a restored document is dated the
53
+ * way every other one is.
54
+ *
55
+ * Reached by its own subpath, never the barrel: its readers are the two
56
+ * console routes and the plugins that answer them.
57
+ */
58
+ /** A section as declared: its key in the bundle and the most items it carries. */
59
+ export interface PluginSiteBundleSectionDeclaration {
60
+ /** The bundle's top-level key for this section's items, e.g. `datasets`. */
61
+ key: string;
62
+ /** The most items one bundle carries; a restore reads no more. */
63
+ limit: number;
64
+ }
65
+ /** A declaration with the plugin that made it. */
66
+ export type ResolvedPluginSiteBundleSectionDeclaration = PluginSiteBundleSectionDeclaration & {
67
+ pluginId: string;
68
+ };
69
+ /** One item of a section, as the bundle carries it: a document with its `$id`. */
70
+ export type SiteBundleItem = Record<string, any>;
71
+ /** Whose backup this is. */
72
+ export interface SiteBundleRequest {
73
+ hostId: string;
74
+ /**
75
+ * The site's organization, or `null` for a site with none — which holds no
76
+ * organization data, a known-empty answer rather than a failure.
77
+ */
78
+ orgId: string | null;
79
+ /** The section's declared limit: the most items one bundle carries. */
80
+ limit: number;
81
+ }
82
+ /** The restore's question: this bundle's items, for this site. */
83
+ export interface SiteBundleRestoreRequest extends SiteBundleRequest {
84
+ /** The organization's document, for the plan and add-ons a count is met against. */
85
+ org: unknown;
86
+ /** The bundle's items under the section's key, already capped at its declared limit. */
87
+ items: readonly SiteBundleItem[];
88
+ }
89
+ /** What the restore hands a section to write with. */
90
+ export interface SiteBundleImportRequest extends SiteBundleRestoreRequest {
91
+ /**
92
+ * Writes one document, whole (`merge: false`), by its full path
93
+ * (`orgs/{orgId}/…`), on the restore's batches and counted in its total.
94
+ */
95
+ write(documentPath: string, data: Record<string, unknown>): Promise<void>;
96
+ /** The restore's own stamps for a document it writes: its creation and update times. */
97
+ stamps(): Record<string, unknown>;
98
+ /**
99
+ * Loads every plugin's console server surface, for a section that checks
100
+ * what it restores against something other plugins register there (a
101
+ * custom field type). Costs a load, so a section asks only when it needs to.
102
+ */
103
+ loadPluginSurfaces(): Promise<void>;
104
+ }
105
+ /** A row the restore reports without refusing: a document restored as it was, and why it is worth a look. */
106
+ export type SiteBundleReportRow = Record<string, unknown>;
107
+ /** A plugin's answers for one section. */
108
+ export interface PluginSiteBundleSection {
109
+ /** The site's share, read whole or not at all: throw rather than return a short list. */
110
+ export(request: SiteBundleRequest): Promise<SiteBundleItem[]>;
111
+ /**
112
+ * Before the restore writes anything: the sentence it answers 403 with when
113
+ * restoring these items would cross what the organization may hold, or
114
+ * `null`. A bundle refused here writes nothing at all.
115
+ */
116
+ refusal?(request: SiteBundleRestoreRequest): Promise<string | null>;
117
+ /** Writes the items back through `request.write`; answers the rows worth reporting. */
118
+ import(request: SiteBundleImportRequest): Promise<readonly SiteBundleReportRow[]>;
119
+ }
120
+ /** Every declared section, in config order — the order the bundle carries them. */
121
+ export declare function listDeclaredSiteBundleSections(): readonly ResolvedPluginSiteBundleSectionDeclaration[];
122
+ /**
123
+ * Registers a plugin's answers for a section it declared. The owner is the
124
+ * plugin whose register fn is running, or the `pluginId` passed from a boot
125
+ * declaration. Refused: no owner, a key nobody declared (only a declared
126
+ * section is ever read, so an undeclared one would be carried by nothing),
127
+ * and a key another plugin declared. The same plugin registering again
128
+ * replaces its answers.
129
+ */
130
+ export declare function registerPluginSiteBundleSection(key: string, section: PluginSiteBundleSection, options?: {
131
+ pluginId?: string;
132
+ }): void;
133
+ /** A declared section with the answers its plugin registered. */
134
+ export type ResolvedSiteBundleSection = ResolvedPluginSiteBundleSectionDeclaration & {
135
+ section: PluginSiteBundleSection;
136
+ };
137
+ /**
138
+ * Every declared section with its answers, in config order. A declared
139
+ * section with nothing registered runs the app's declarations step once and
140
+ * asks again; still missing, this THROWS naming it — an export that carried
141
+ * the rest would be a backup missing a section with nothing to say so.
142
+ */
143
+ export declare function resolveSiteBundleSections(): Promise<ResolvedSiteBundleSection[]>;
144
+ /** Only for specs: forgets every registered section. */
145
+ export declare function resetSiteBundleSectionsForTests(): void;
@@ -0,0 +1,78 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ var _globalScope_SECTIONS_KEY;
3
+ /**
4
+ * @license
5
+ * Copyright 2026 Aglyn LLC
6
+ *
7
+ * Licensed under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License.
9
+ * You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */ import { getRegisteringPluginId } from "../app-utils/registering-plugin.js";
19
+ import { PLUGIN_SITE_BUNDLE_SECTIONS_DECLARED } from "./first-party-plugins.generated.js";
20
+ import { runPluginDeclarationsRepair } from "./plugin-declarations-repair.js";
21
+ /**
22
+ * One table per process, on `globalThis` (AGL-3412): a plugin registers from
23
+ * its declarations at boot, which Next compiles apart from the routes that
24
+ * read, and a module-scoped map would be filled in one copy and read empty in
25
+ * the other.
26
+ */ const SECTIONS_KEY = Symbol.for('@aglyn/aglyn:site-bundle-sections');
27
+ const globalScope = globalThis;
28
+ const sections = (_globalScope_SECTIONS_KEY = globalScope[SECTIONS_KEY]) != null ? _globalScope_SECTIONS_KEY : globalScope[SECTIONS_KEY] = new Map();
29
+ /** Every declared section, in config order — the order the bundle carries them. */ export function listDeclaredSiteBundleSections() {
30
+ return PLUGIN_SITE_BUNDLE_SECTIONS_DECLARED;
31
+ }
32
+ /**
33
+ * Registers a plugin's answers for a section it declared. The owner is the
34
+ * plugin whose register fn is running, or the `pluginId` passed from a boot
35
+ * declaration. Refused: no owner, a key nobody declared (only a declared
36
+ * section is ever read, so an undeclared one would be carried by nothing),
37
+ * and a key another plugin declared. The same plugin registering again
38
+ * replaces its answers.
39
+ */ export function registerPluginSiteBundleSection(key, section, options) {
40
+ var _ref, _getRegisteringPluginId;
41
+ const name = key.trim();
42
+ const pluginId = ((_ref = (_getRegisteringPluginId = getRegisteringPluginId()) != null ? _getRegisteringPluginId : options == null ? void 0 : options.pluginId) != null ? _ref : '').trim();
43
+ if (!pluginId) {
44
+ throw new Error(`site bundle section "${name}" registered with no owner: pass { pluginId } ` + 'when registering outside a plugin register fn');
45
+ }
46
+ const declared = listDeclaredSiteBundleSections().find((one)=>one.key === name);
47
+ if (!declared) {
48
+ throw new Error(`site bundle section "${name}" is not declared in plugins.config.json ` + '(siteBundleSections), so no export would ever carry it');
49
+ }
50
+ if (declared.pluginId !== pluginId) {
51
+ throw new Error(`site bundle section "${name}" is declared by "${declared.pluginId}"; ` + `refused "${pluginId}"`);
52
+ }
53
+ sections.set(name, {
54
+ pluginId,
55
+ section
56
+ });
57
+ }
58
+ /**
59
+ * Every declared section with its answers, in config order. A declared
60
+ * section with nothing registered runs the app's declarations step once and
61
+ * asks again; still missing, this THROWS naming it — an export that carried
62
+ * the rest would be a backup missing a section with nothing to say so.
63
+ */ export async function resolveSiteBundleSections() {
64
+ const missing = ()=>listDeclaredSiteBundleSections().filter((declared)=>!sections.has(declared.key));
65
+ if (missing().length) await runPluginDeclarationsRepair();
66
+ const absent = missing();
67
+ if (absent.length) {
68
+ throw new Error(`[plugins] site bundle section(s) ${absent.map((one)=>`"${one.key}" (${one.pluginId})`).join(', ')} ` + 'declared and not registered in this process');
69
+ }
70
+ return listDeclaredSiteBundleSections().map((declared)=>_extends({}, declared, {
71
+ section: sections.get(declared.key).section
72
+ }));
73
+ }
74
+ /** Only for specs: forgets every registered section. */ export function resetSiteBundleSectionsForTests() {
75
+ sections.clear();
76
+ }
77
+
78
+ //# sourceMappingURL=plugin-site-bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-site-bundle.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 { PLUGIN_SITE_BUNDLE_SECTIONS_DECLARED } from './first-party-plugins.generated'\nimport { runPluginDeclarationsRepair } from './plugin-declarations-repair'\n\n/**\n * A plugin's SECTION of the whole-site backup (AGL-3080): what it carries in\n * the bundle and restores from it, when a host collection's `siteExport`\n * cannot say so.\n *\n * A plain host collection is copied by the export and restore routes\n * themselves (`plugin-site-export.ts`). Some plugin data is not that shape:\n * it lives under the ORGANIZATION and is narrowed to the site being backed up,\n * it carries a subcollection, a restore has to validate it against its own\n * model and derive what the model implies, and its count is sold as an add-on\n * rather than read off the plan. Only the plugin knows any of that. So the\n * plugin declares the section and answers for it: the export asks it for the\n * site's share, and the restore asks it — before the first write — whether\n * the bundle would cross what the organization has paid for, then hands it the\n * bundle's items and the restore's writer.\n *\n * ## Declared, then registered — and an absent section is refused\n *\n * The plugin declares the section in `plugins.config.json`\n * (`siteBundleSections`: the bundle key and the most items it carries), which\n * the generator compiles, and registers the answer from its\n * `serverDeclarations` entry. A backup that silently lacks a section is worse\n * than a failed one — the file looks whole until the day it is restored — so\n * a section declared and not registered is not read as \"nothing to carry\":\n * {@link resolveSiteBundleSections} runs the app's declarations step again,\n * and throws if the section is still missing, which fails the export or the\n * restore out loud.\n *\n * ## What the restore owns\n *\n * The section writes through {@link SiteBundleImportRequest.write}, never\n * with a writer of its own: the restore's chunked batches, its document count\n * and its all-or-nothing refusal are the restore's, and a write that went\n * around them would land after a refusal or be missing from the total. The\n * restore's own stamps (`createdAt`, `updatedAt`) come from\n * {@link SiteBundleImportRequest.stamps}, so a restored document is dated the\n * way every other one is.\n *\n * Reached by its own subpath, never the barrel: its readers are the two\n * console routes and the plugins that answer them.\n */\n\n/** A section as declared: its key in the bundle and the most items it carries. */\nexport interface PluginSiteBundleSectionDeclaration {\n /** The bundle's top-level key for this section's items, e.g. `datasets`. */\n key: string\n /** The most items one bundle carries; a restore reads no more. */\n limit: number\n}\n\n/** A declaration with the plugin that made it. */\nexport type ResolvedPluginSiteBundleSectionDeclaration =\n PluginSiteBundleSectionDeclaration & { pluginId: string }\n\n/** One item of a section, as the bundle carries it: a document with its `$id`. */\nexport type SiteBundleItem = Record<string, any>\n\n/** Whose backup this is. */\nexport interface SiteBundleRequest {\n hostId: string\n /**\n * The site's organization, or `null` for a site with none — which holds no\n * organization data, a known-empty answer rather than a failure.\n */\n orgId: string | null\n /** The section's declared limit: the most items one bundle carries. */\n limit: number\n}\n\n/** The restore's question: this bundle's items, for this site. */\nexport interface SiteBundleRestoreRequest extends SiteBundleRequest {\n /** The organization's document, for the plan and add-ons a count is met against. */\n org: unknown\n /** The bundle's items under the section's key, already capped at its declared limit. */\n items: readonly SiteBundleItem[]\n}\n\n/** What the restore hands a section to write with. */\nexport interface SiteBundleImportRequest extends SiteBundleRestoreRequest {\n /**\n * Writes one document, whole (`merge: false`), by its full path\n * (`orgs/{orgId}/…`), on the restore's batches and counted in its total.\n */\n write(documentPath: string, data: Record<string, unknown>): Promise<void>\n /** The restore's own stamps for a document it writes: its creation and update times. */\n stamps(): Record<string, unknown>\n /**\n * Loads every plugin's console server surface, for a section that checks\n * what it restores against something other plugins register there (a\n * custom field type). Costs a load, so a section asks only when it needs to.\n */\n loadPluginSurfaces(): Promise<void>\n}\n\n/** A row the restore reports without refusing: a document restored as it was, and why it is worth a look. */\nexport type SiteBundleReportRow = Record<string, unknown>\n\n/** A plugin's answers for one section. */\nexport interface PluginSiteBundleSection {\n /** The site's share, read whole or not at all: throw rather than return a short list. */\n export(request: SiteBundleRequest): Promise<SiteBundleItem[]>\n /**\n * Before the restore writes anything: the sentence it answers 403 with when\n * restoring these items would cross what the organization may hold, or\n * `null`. A bundle refused here writes nothing at all.\n */\n refusal?(request: SiteBundleRestoreRequest): Promise<string | null>\n /** Writes the items back through `request.write`; answers the rows worth reporting. */\n import(request: SiteBundleImportRequest): Promise<readonly SiteBundleReportRow[]>\n}\n\ninterface Registered {\n pluginId: string\n section: PluginSiteBundleSection\n}\n\n/**\n * One table per process, on `globalThis` (AGL-3412): a plugin registers from\n * its declarations at boot, which Next compiles apart from the routes that\n * read, and a module-scoped map would be filled in one copy and read empty in\n * the other.\n */\nconst SECTIONS_KEY = Symbol.for('@aglyn/aglyn:site-bundle-sections')\n\nconst globalScope = globalThis as typeof globalThis & {\n [SECTIONS_KEY]?: Map<string, Registered>\n}\n\nconst sections: Map<string, Registered> =\n globalScope[SECTIONS_KEY] ?? (globalScope[SECTIONS_KEY] = new Map())\n\n/** Every declared section, in config order — the order the bundle carries them. */\nexport function listDeclaredSiteBundleSections(): readonly ResolvedPluginSiteBundleSectionDeclaration[] {\n return PLUGIN_SITE_BUNDLE_SECTIONS_DECLARED\n}\n\n/**\n * Registers a plugin's answers for a section it declared. The owner is the\n * plugin whose register fn is running, or the `pluginId` passed from a boot\n * declaration. Refused: no owner, a key nobody declared (only a declared\n * section is ever read, so an undeclared one would be carried by nothing),\n * and a key another plugin declared. The same plugin registering again\n * replaces its answers.\n */\nexport function registerPluginSiteBundleSection(\n key: string,\n section: PluginSiteBundleSection,\n options?: { pluginId?: string },\n): void {\n const name = key.trim()\n const pluginId = (getRegisteringPluginId() ?? options?.pluginId ?? '').trim()\n if (!pluginId) {\n throw new Error(\n `site bundle section \"${name}\" registered with no owner: pass { pluginId } ` +\n 'when registering outside a plugin register fn',\n )\n }\n const declared = listDeclaredSiteBundleSections().find((one) => one.key === name)\n if (!declared) {\n throw new Error(\n `site bundle section \"${name}\" is not declared in plugins.config.json ` +\n '(siteBundleSections), so no export would ever carry it',\n )\n }\n if (declared.pluginId !== pluginId) {\n throw new Error(\n `site bundle section \"${name}\" is declared by \"${declared.pluginId}\"; ` +\n `refused \"${pluginId}\"`,\n )\n }\n sections.set(name, { pluginId, section })\n}\n\n/** A declared section with the answers its plugin registered. */\nexport type ResolvedSiteBundleSection = ResolvedPluginSiteBundleSectionDeclaration & {\n section: PluginSiteBundleSection\n}\n\n/**\n * Every declared section with its answers, in config order. A declared\n * section with nothing registered runs the app's declarations step once and\n * asks again; still missing, this THROWS naming it — an export that carried\n * the rest would be a backup missing a section with nothing to say so.\n */\nexport async function resolveSiteBundleSections(): Promise<ResolvedSiteBundleSection[]> {\n const missing = () =>\n listDeclaredSiteBundleSections().filter((declared) => !sections.has(declared.key))\n if (missing().length) await runPluginDeclarationsRepair()\n const absent = missing()\n if (absent.length) {\n throw new Error(\n `[plugins] site bundle section(s) ${absent.map((one) => `\"${one.key}\" (${one.pluginId})`).join(', ')} ` +\n 'declared and not registered in this process',\n )\n }\n return listDeclaredSiteBundleSections().map((declared) => ({\n ...declared,\n section: (sections.get(declared.key) as Registered).section,\n }))\n}\n\n/** Only for specs: forgets every registered section. */\nexport function resetSiteBundleSectionsForTests(): void {\n sections.clear()\n}\n"],"names":["globalScope","getRegisteringPluginId","PLUGIN_SITE_BUNDLE_SECTIONS_DECLARED","runPluginDeclarationsRepair","SECTIONS_KEY","Symbol","for","globalThis","sections","Map","listDeclaredSiteBundleSections","registerPluginSiteBundleSection","key","section","options","name","trim","pluginId","Error","declared","find","one","set","resolveSiteBundleSections","missing","filter","has","length","absent","map","join","get","resetSiteBundleSectionsForTests","clear"],"mappings":";IAsJEA;AAtJF;;;;;;;;;;;;;;;CAeC,GAED,SAASC,sBAAsB,QAAQ,qCAAiC;AACxE,SAASC,oCAAoC,QAAQ,qCAAiC;AACtF,SAASC,2BAA2B,QAAQ,kCAA8B;AAsH1E;;;;;CAKC,GACD,MAAMC,eAAeC,OAAOC,GAAG,CAAC;AAEhC,MAAMN,cAAcO;AAIpB,MAAMC,YACJR,4BAAAA,WAAW,CAACI,aAAa,YAAzBJ,4BAA8BA,WAAW,CAACI,aAAa,GAAG,IAAIK;AAEhE,iFAAiF,GACjF,OAAO,SAASC;IACd,OAAOR;AACT;AAEA;;;;;;;CAOC,GACD,OAAO,SAASS,gCACdC,GAAW,EACXC,OAAgC,EAChCC,OAA+B;QAGbb,MAAAA;IADlB,MAAMc,OAAOH,IAAII,IAAI;IACrB,MAAMC,WAAW,EAAChB,QAAAA,0BAAAA,oCAAAA,0BAA4Ba,2BAAAA,QAASG,QAAQ,YAA7ChB,OAAiD,IAAIe,IAAI;IAC3E,IAAI,CAACC,UAAU;QACb,MAAM,IAAIC,MACR,CAAC,qBAAqB,EAAEH,KAAK,8CAA8C,CAAC,GAC1E;IAEN;IACA,MAAMI,WAAWT,iCAAiCU,IAAI,CAAC,CAACC,MAAQA,IAAIT,GAAG,KAAKG;IAC5E,IAAI,CAACI,UAAU;QACb,MAAM,IAAID,MACR,CAAC,qBAAqB,EAAEH,KAAK,yCAAyC,CAAC,GACrE;IAEN;IACA,IAAII,SAASF,QAAQ,KAAKA,UAAU;QAClC,MAAM,IAAIC,MACR,CAAC,qBAAqB,EAAEH,KAAK,kBAAkB,EAAEI,SAASF,QAAQ,CAAC,GAAG,CAAC,GACrE,CAAC,SAAS,EAAEA,SAAS,CAAC,CAAC;IAE7B;IACAT,SAASc,GAAG,CAACP,MAAM;QAAEE;QAAUJ;IAAQ;AACzC;AAOA;;;;;CAKC,GACD,OAAO,eAAeU;IACpB,MAAMC,UAAU,IACdd,iCAAiCe,MAAM,CAAC,CAACN,WAAa,CAACX,SAASkB,GAAG,CAACP,SAASP,GAAG;IAClF,IAAIY,UAAUG,MAAM,EAAE,MAAMxB;IAC5B,MAAMyB,SAASJ;IACf,IAAII,OAAOD,MAAM,EAAE;QACjB,MAAM,IAAIT,MACR,CAAC,iCAAiC,EAAEU,OAAOC,GAAG,CAAC,CAACR,MAAQ,CAAC,CAAC,EAAEA,IAAIT,GAAG,CAAC,GAAG,EAAES,IAAIJ,QAAQ,CAAC,CAAC,CAAC,EAAEa,IAAI,CAAC,MAAM,CAAC,CAAC,GACrG;IAEN;IACA,OAAOpB,iCAAiCmB,GAAG,CAAC,CAACV,WAAc,aACtDA;YACHN,SAAS,AAACL,SAASuB,GAAG,CAACZ,SAASP,GAAG,EAAiBC,OAAO;;AAE/D;AAEA,sDAAsD,GACtD,OAAO,SAASmB;IACdxB,SAASyB,KAAK;AAChB"}
@@ -27,6 +27,18 @@ export interface PluginSiteCacheRequest {
27
27
  * `'marketplace listing revoked'`, not `'revoke'`.
28
28
  */
29
29
  reason: string;
30
+ /**
31
+ * Narrows a site's drop to the pages that changed: its site-absolute
32
+ * addresses (`/`, `/contact`), keyed by site id. A site named here loses
33
+ * only those pages, and one named with an empty list loses none; a site
34
+ * not named here loses every page it serves.
35
+ *
36
+ * For a change the plugin can place exactly — a document it publishes that
37
+ * renders on the pages that place it — rather than one that reaches every
38
+ * page, like a revoked bundle. The plugin knows which pages; the app knows
39
+ * how to drop one, on every address the site answers at.
40
+ */
41
+ paths?: Readonly<Record<string, readonly string[]>>;
30
42
  }
31
43
  export interface PluginSiteCacheResult {
32
44
  /** Sites whose cached pages were dropped. */
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-site-cache.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * HOW A PLUGIN DROPS A SITE'S CACHED PAGES (AGL-3080).\n *\n * The shell hands this one down rather than up. Every other contract in this\n * directory is a plugin telling the shell something; this is the shell\n * telling plugins it can do something — purge the rendered HTML of a site —\n * because purging it takes the tenant's cache tags and revalidation paths,\n * which live in the app and are not a plugin's to know.\n *\n * ## The case, and why it is a kill switch rather than a nicety\n *\n * A marketplace plugin can be REVOKED. Revoking writes a stop on the\n * version, and the tenant refuses revoked bytes at render time — but a page\n * already rendered and cached does not re-render to find that out. So the\n * revoke has a second half: drop the cached pages of every site running it.\n * Without it a revoked plugin keeps executing in visitors' browsers for as\n * long as the cache holds, which is the whole failure the stop exists to\n * prevent.\n *\n * ## ⛔ AN ABSENT IMPLEMENTATION IS AN ANSWER, AND IT IS `complete: false`\n *\n * The registry is filled by the APP at boot. A process that has not filled\n * it resolves \"no cache to drop\" — indistinguishable, from the inside, from\n * a workspace whose sites were all already fresh. That is the AGL-3025 shape\n * and on this path it means a revoked plugin quietly kept serving.\n *\n * So there is no silent branch. {@link dropPluginSiteCache} always answers a\n * {@link PluginSiteCacheResult}, and `complete` is false whenever the drop\n * did not certainly happen — nothing registered, or the implementation\n * threw. A caller acts on that: the revoke itself must still stand (a plugin\n * left un-revoked because a cache purge failed is strictly worse), but the\n * reader has to be told the purge did not run, and the log has to carry it.\n *\n * ## The split, in one line\n *\n * The plugin knows WHICH sites — that is its own install pins, its own\n * collection. The shell knows HOW to drop one, and owns the fan-out policy:\n * the cap, the concurrency, and saying out loud when a cap truncated the\n * list. Neither half is guessable from the other side.\n */\n\nimport {\n definePluginServiceContract,\n registerPluginService,\n resolvePluginService,\n} from './plugin-services'\nimport { getRegisteringPluginId } from '../app-utils/registering-plugin'\n\n/** What the caller wants dropped, and why. */\nexport interface PluginSiteCacheRequest {\n /**\n * The sites whose rendered pages must go. Duplicates are the caller's to\n * avoid or not — the implementation is free to collapse them.\n */\n hostIds: readonly string[]\n /**\n * Why, in a few words, for the fan-out's own logging: a truncated purge\n * is only debuggable if the record says what it was purging for.\n * `'marketplace listing revoked'`, not `'revoke'`.\n */\n reason: string\n}\n\nexport interface PluginSiteCacheResult {\n /** Sites whose cached pages were dropped. */\n dropped: number\n /**\n * Sites deliberately left holding cached pages because the fan-out hit\n * its cap. Not an error — a decision the shell made and logged — but a\n * number a caller may want to surface, because those sites are still\n * serving what was just stopped.\n */\n skipped: number\n /**\n * Whether the drop certainly happened. FALSE when no implementation is\n * registered or one threw, and a caller must not read `dropped: 0` as\n * \"there was nothing to drop\" without checking this first.\n */\n complete: boolean\n}\n\nexport interface PluginSiteCache {\n drop(request: PluginSiteCacheRequest): Promise<PluginSiteCacheResult>\n}\n\n/**\n * One implementation: the app's. Two would be two cache layers disagreeing\n * about whether a page is gone, and the second to register would be the one\n * nobody knew about.\n */\nexport const PLUGIN_SITE_CACHE = definePluginServiceContract<PluginSiteCache>(\n 'core.site-cache',\n { multiple: false },\n)\n\n/**\n * Installs the app's implementation. Called once, at server boot, by the app\n * that owns the tenant's cache.\n *\n * `pluginId` is required from outside a plugin's register fn, as it is for\n * every service: the app passes its own marker, and the contract refuses an\n * anonymous registration rather than accepting one nothing can be traced to.\n */\nexport function registerPluginSiteCache(\n cache: PluginSiteCache,\n options?: { pluginId?: string },\n): void {\n if (typeof cache?.drop !== 'function') {\n throw new Error('a site cache needs a drop function')\n }\n registerPluginService(PLUGIN_SITE_CACHE, cache, {\n ...(options?.pluginId ? { pluginId: options.pluginId } : {}),\n })\n}\n\n/** Whether an implementation is installed — for a caller that wants to say so. */\nexport function hasPluginSiteCache(): boolean {\n return Boolean(resolvePluginService(PLUGIN_SITE_CACHE))\n}\n\n/**\n * Drops the cached pages of the named sites.\n *\n * NEVER THROWS and never silently succeeds: a failure comes back as\n * `complete: false` with the reason logged, because the callers are stop\n * paths that must complete their own work either way. Read `complete`\n * before reading `dropped`.\n */\nexport async function dropPluginSiteCache(\n request: PluginSiteCacheRequest,\n): Promise<PluginSiteCacheResult> {\n const hostIds = [...new Set(request.hostIds.filter(Boolean))]\n if (!hostIds.length) {\n // Nothing asked for is the one case where \"nothing dropped\" is complete\n // on its own terms, whether or not anything is registered.\n return { dropped: 0, skipped: 0, complete: true }\n }\n const cache = resolvePluginService(PLUGIN_SITE_CACHE)\n if (!cache) {\n console.error(\n `[site-cache] no implementation is installed, so ${hostIds.length} ` +\n `site(s) keep their cached pages after: ${request.reason}. The app ` +\n 'registers this at boot; a process that has not is serving stopped ' +\n 'content.',\n )\n return { dropped: 0, skipped: 0, complete: false }\n }\n try {\n return await cache.drop({ ...request, hostIds })\n } catch (error) {\n console.error(\n `[site-cache] the drop failed after: ${request.reason}`,\n error,\n )\n return { dropped: 0, skipped: 0, complete: false }\n }\n}\n"],"names":["definePluginServiceContract","registerPluginService","resolvePluginService","PLUGIN_SITE_CACHE","multiple","registerPluginSiteCache","cache","options","drop","Error","pluginId","hasPluginSiteCache","Boolean","dropPluginSiteCache","request","hostIds","Set","filter","length","dropped","skipped","complete","console","error","reason"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCC,GAED,SACEA,2BAA2B,EAC3BC,qBAAqB,EACrBC,oBAAoB,QACf,uBAAmB;AAwC1B;;;;CAIC,GACD,OAAO,MAAMC,oBAAoBH,4BAC/B,mBACA;IAAEI,UAAU;AAAM,GACnB;AAED;;;;;;;CAOC,GACD,OAAO,SAASC,wBACdC,KAAsB,EACtBC,OAA+B;IAE/B,IAAI,QAAOD,yBAAAA,MAAOE,IAAI,MAAK,YAAY;QACrC,MAAM,IAAIC,MAAM;IAClB;IACAR,sBAAsBE,mBAAmBG,OAAO,aAC1CC,CAAAA,2BAAAA,QAASG,QAAQ,IAAG;QAAEA,UAAUH,QAAQG,QAAQ;IAAC,IAAI,CAAC;AAE9D;AAEA,gFAAgF,GAChF,OAAO,SAASC;IACd,OAAOC,QAAQV,qBAAqBC;AACtC;AAEA;;;;;;;CAOC,GACD,OAAO,eAAeU,oBACpBC,OAA+B;IAE/B,MAAMC,UAAU;WAAI,IAAIC,IAAIF,QAAQC,OAAO,CAACE,MAAM,CAACL;KAAU;IAC7D,IAAI,CAACG,QAAQG,MAAM,EAAE;QACnB,wEAAwE;QACxE,2DAA2D;QAC3D,OAAO;YAAEC,SAAS;YAAGC,SAAS;YAAGC,UAAU;QAAK;IAClD;IACA,MAAMf,QAAQJ,qBAAqBC;IACnC,IAAI,CAACG,OAAO;QACVgB,QAAQC,KAAK,CACX,CAAC,gDAAgD,EAAER,QAAQG,MAAM,CAAC,CAAC,CAAC,GAClE,CAAC,uCAAuC,EAAEJ,QAAQU,MAAM,CAAC,UAAU,CAAC,GACpE,uEACA;QAEJ,OAAO;YAAEL,SAAS;YAAGC,SAAS;YAAGC,UAAU;QAAM;IACnD;IACA,IAAI;QACF,OAAO,MAAMf,MAAME,IAAI,CAAC,aAAKM;YAASC;;IACxC,EAAE,OAAOQ,OAAO;QACdD,QAAQC,KAAK,CACX,CAAC,oCAAoC,EAAET,QAAQU,MAAM,EAAE,EACvDD;QAEF,OAAO;YAAEJ,SAAS;YAAGC,SAAS;YAAGC,UAAU;QAAM;IACnD;AACF"}
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-site-cache.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * HOW A PLUGIN DROPS A SITE'S CACHED PAGES (AGL-3080).\n *\n * The shell hands this one down rather than up. Every other contract in this\n * directory is a plugin telling the shell something; this is the shell\n * telling plugins it can do something — purge the rendered HTML of a site —\n * because purging it takes the tenant's cache tags and revalidation paths,\n * which live in the app and are not a plugin's to know.\n *\n * ## The case, and why it is a kill switch rather than a nicety\n *\n * A marketplace plugin can be REVOKED. Revoking writes a stop on the\n * version, and the tenant refuses revoked bytes at render time — but a page\n * already rendered and cached does not re-render to find that out. So the\n * revoke has a second half: drop the cached pages of every site running it.\n * Without it a revoked plugin keeps executing in visitors' browsers for as\n * long as the cache holds, which is the whole failure the stop exists to\n * prevent.\n *\n * ## ⛔ AN ABSENT IMPLEMENTATION IS AN ANSWER, AND IT IS `complete: false`\n *\n * The registry is filled by the APP at boot. A process that has not filled\n * it resolves \"no cache to drop\" — indistinguishable, from the inside, from\n * a workspace whose sites were all already fresh. That is the AGL-3025 shape\n * and on this path it means a revoked plugin quietly kept serving.\n *\n * So there is no silent branch. {@link dropPluginSiteCache} always answers a\n * {@link PluginSiteCacheResult}, and `complete` is false whenever the drop\n * did not certainly happen — nothing registered, or the implementation\n * threw. A caller acts on that: the revoke itself must still stand (a plugin\n * left un-revoked because a cache purge failed is strictly worse), but the\n * reader has to be told the purge did not run, and the log has to carry it.\n *\n * ## The split, in one line\n *\n * The plugin knows WHICH sites — that is its own install pins, its own\n * collection. The shell knows HOW to drop one, and owns the fan-out policy:\n * the cap, the concurrency, and saying out loud when a cap truncated the\n * list. Neither half is guessable from the other side.\n */\n\nimport {\n definePluginServiceContract,\n registerPluginService,\n resolvePluginService,\n} from './plugin-services'\nimport { getRegisteringPluginId } from '../app-utils/registering-plugin'\n\n/** What the caller wants dropped, and why. */\nexport interface PluginSiteCacheRequest {\n /**\n * The sites whose rendered pages must go. Duplicates are the caller's to\n * avoid or not — the implementation is free to collapse them.\n */\n hostIds: readonly string[]\n /**\n * Why, in a few words, for the fan-out's own logging: a truncated purge\n * is only debuggable if the record says what it was purging for.\n * `'marketplace listing revoked'`, not `'revoke'`.\n */\n reason: string\n /**\n * Narrows a site's drop to the pages that changed: its site-absolute\n * addresses (`/`, `/contact`), keyed by site id. A site named here loses\n * only those pages, and one named with an empty list loses none; a site\n * not named here loses every page it serves.\n *\n * For a change the plugin can place exactly — a document it publishes that\n * renders on the pages that place it — rather than one that reaches every\n * page, like a revoked bundle. The plugin knows which pages; the app knows\n * how to drop one, on every address the site answers at.\n */\n paths?: Readonly<Record<string, readonly string[]>>\n}\n\nexport interface PluginSiteCacheResult {\n /** Sites whose cached pages were dropped. */\n dropped: number\n /**\n * Sites deliberately left holding cached pages because the fan-out hit\n * its cap. Not an error — a decision the shell made and logged — but a\n * number a caller may want to surface, because those sites are still\n * serving what was just stopped.\n */\n skipped: number\n /**\n * Whether the drop certainly happened. FALSE when no implementation is\n * registered or one threw, and a caller must not read `dropped: 0` as\n * \"there was nothing to drop\" without checking this first.\n */\n complete: boolean\n}\n\nexport interface PluginSiteCache {\n drop(request: PluginSiteCacheRequest): Promise<PluginSiteCacheResult>\n}\n\n/**\n * One implementation: the app's. Two would be two cache layers disagreeing\n * about whether a page is gone, and the second to register would be the one\n * nobody knew about.\n */\nexport const PLUGIN_SITE_CACHE = definePluginServiceContract<PluginSiteCache>(\n 'core.site-cache',\n { multiple: false },\n)\n\n/**\n * Installs the app's implementation. Called once, at server boot, by the app\n * that owns the tenant's cache.\n *\n * `pluginId` is required from outside a plugin's register fn, as it is for\n * every service: the app passes its own marker, and the contract refuses an\n * anonymous registration rather than accepting one nothing can be traced to.\n */\nexport function registerPluginSiteCache(\n cache: PluginSiteCache,\n options?: { pluginId?: string },\n): void {\n if (typeof cache?.drop !== 'function') {\n throw new Error('a site cache needs a drop function')\n }\n registerPluginService(PLUGIN_SITE_CACHE, cache, {\n ...(options?.pluginId ? { pluginId: options.pluginId } : {}),\n })\n}\n\n/** Whether an implementation is installed — for a caller that wants to say so. */\nexport function hasPluginSiteCache(): boolean {\n return Boolean(resolvePluginService(PLUGIN_SITE_CACHE))\n}\n\n/**\n * Drops the cached pages of the named sites.\n *\n * NEVER THROWS and never silently succeeds: a failure comes back as\n * `complete: false` with the reason logged, because the callers are stop\n * paths that must complete their own work either way. Read `complete`\n * before reading `dropped`.\n */\nexport async function dropPluginSiteCache(\n request: PluginSiteCacheRequest,\n): Promise<PluginSiteCacheResult> {\n const hostIds = [...new Set(request.hostIds.filter(Boolean))]\n if (!hostIds.length) {\n // Nothing asked for is the one case where \"nothing dropped\" is complete\n // on its own terms, whether or not anything is registered.\n return { dropped: 0, skipped: 0, complete: true }\n }\n const cache = resolvePluginService(PLUGIN_SITE_CACHE)\n if (!cache) {\n console.error(\n `[site-cache] no implementation is installed, so ${hostIds.length} ` +\n `site(s) keep their cached pages after: ${request.reason}. The app ` +\n 'registers this at boot; a process that has not is serving stopped ' +\n 'content.',\n )\n return { dropped: 0, skipped: 0, complete: false }\n }\n try {\n return await cache.drop({ ...request, hostIds })\n } catch (error) {\n console.error(\n `[site-cache] the drop failed after: ${request.reason}`,\n error,\n )\n return { dropped: 0, skipped: 0, complete: false }\n }\n}\n"],"names":["definePluginServiceContract","registerPluginService","resolvePluginService","PLUGIN_SITE_CACHE","multiple","registerPluginSiteCache","cache","options","drop","Error","pluginId","hasPluginSiteCache","Boolean","dropPluginSiteCache","request","hostIds","Set","filter","length","dropped","skipped","complete","console","error","reason"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCC,GAED,SACEA,2BAA2B,EAC3BC,qBAAqB,EACrBC,oBAAoB,QACf,uBAAmB;AAoD1B;;;;CAIC,GACD,OAAO,MAAMC,oBAAoBH,4BAC/B,mBACA;IAAEI,UAAU;AAAM,GACnB;AAED;;;;;;;CAOC,GACD,OAAO,SAASC,wBACdC,KAAsB,EACtBC,OAA+B;IAE/B,IAAI,QAAOD,yBAAAA,MAAOE,IAAI,MAAK,YAAY;QACrC,MAAM,IAAIC,MAAM;IAClB;IACAR,sBAAsBE,mBAAmBG,OAAO,aAC1CC,CAAAA,2BAAAA,QAASG,QAAQ,IAAG;QAAEA,UAAUH,QAAQG,QAAQ;IAAC,IAAI,CAAC;AAE9D;AAEA,gFAAgF,GAChF,OAAO,SAASC;IACd,OAAOC,QAAQV,qBAAqBC;AACtC;AAEA;;;;;;;CAOC,GACD,OAAO,eAAeU,oBACpBC,OAA+B;IAE/B,MAAMC,UAAU;WAAI,IAAIC,IAAIF,QAAQC,OAAO,CAACE,MAAM,CAACL;KAAU;IAC7D,IAAI,CAACG,QAAQG,MAAM,EAAE;QACnB,wEAAwE;QACxE,2DAA2D;QAC3D,OAAO;YAAEC,SAAS;YAAGC,SAAS;YAAGC,UAAU;QAAK;IAClD;IACA,MAAMf,QAAQJ,qBAAqBC;IACnC,IAAI,CAACG,OAAO;QACVgB,QAAQC,KAAK,CACX,CAAC,gDAAgD,EAAER,QAAQG,MAAM,CAAC,CAAC,CAAC,GAClE,CAAC,uCAAuC,EAAEJ,QAAQU,MAAM,CAAC,UAAU,CAAC,GACpE,uEACA;QAEJ,OAAO;YAAEL,SAAS;YAAGC,SAAS;YAAGC,UAAU;QAAM;IACnD;IACA,IAAI;QACF,OAAO,MAAMf,MAAME,IAAI,CAAC,aAAKM;YAASC;;IACxC,EAAE,OAAOQ,OAAO;QACdD,QAAQC,KAAK,CACX,CAAC,oCAAoC,EAAET,QAAQU,MAAM,EAAE,EACvDD;QAEF,OAAO;YAAEJ,SAAS;YAAGC,SAAS;YAAGC,UAAU;QAAM;IACnD;AACF"}
@@ -0,0 +1,81 @@
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 host collection in the platform's whole-site backup (AGL-3080).
19
+ *
20
+ * `/api/hosts/export` writes one JSON bundle of everything designable on a
21
+ * site and `/api/hosts/import` restores it (AGL-163). The platform's own
22
+ * documents — screens, layouts, components, authors, content collections,
23
+ * media — are the routes' to carry. A plugin whose site documents belong in
24
+ * a backup declares so beside the collection, in the `hostCollections` block
25
+ * of `plugins.config.json` (a host collection's `siteExport`), and both
26
+ * routes walk the declarations: the export reads up to `limit` live documents
27
+ * into the bundle under the collection's own name, and the restore writes each
28
+ * one back through `fields` and counts the result against the collection's
29
+ * declared `resource`.
30
+ *
31
+ * ## `fields` is the round trip, not the create
32
+ *
33
+ * A restore writes with `merge: false`, so the list is every key a live
34
+ * document carries — which can be narrower than what a create admits, and is
35
+ * often wider — and a key left off is ERASED from every restored document
36
+ * (AGL-1382). Nothing the restore stamps (`createdAt`, `updatedAt`,
37
+ * `deletedAt`) or scopes (`visibleTo`) is on it; the generator refuses them.
38
+ *
39
+ * ## Compiled, and counted
40
+ *
41
+ * A backup that silently lacks a collection is worse than a failed one: the
42
+ * file looks whole until the day it is restored. So the declarations are
43
+ * compiled, present the moment this module is imported, and a runtime
44
+ * `registerPluginHostCollections` carrying a `siteExport` throws. A restore
45
+ * creates documents with the Admin SDK, past the rules, so the generator also
46
+ * refuses a `siteExport` on a collection with no `resource`: the resource's
47
+ * plan counter or flat platform cap is what the restore is met against.
48
+ *
49
+ * Reached by its own subpath, never the barrel: its readers are the two
50
+ * console routes.
51
+ */
52
+ export interface PluginHostCollectionSiteExport {
53
+ /** The most live documents one bundle carries; a restore writes no more. */
54
+ limit: number;
55
+ /** The keys a restore writes back. Anything else a bundle carries is dropped. */
56
+ fields: readonly string[];
57
+ }
58
+ /** What a restore of a declared collection is counted against. */
59
+ export type PluginSiteExportCount =
60
+ /** A plan counter, an `OrgEntitlements` key core resolves. */
61
+ {
62
+ quotaKey: string;
63
+ }
64
+ /**
65
+ * A flat platform cap, resolved from the name the resource declares, or
66
+ * `null` for a name core does not hold — which a restore refuses.
67
+ */
68
+ | {
69
+ max: number | null;
70
+ };
71
+ /** A declared collection with the plugin that made it and its count. */
72
+ export interface ResolvedPluginSiteExportCollection extends PluginHostCollectionSiteExport {
73
+ pluginId: string;
74
+ /** The subcollection under `hosts/{hostId}`, and its key in the bundle. */
75
+ collection: string;
76
+ /** Plural, for a restore's refusal: "this backup holds 40 {label}". */
77
+ label: string;
78
+ count: PluginSiteExportCount;
79
+ }
80
+ /** Every collection a plugin declares for the site backup, in config order. */
81
+ export declare function listPluginSiteExportCollections(): ResolvedPluginSiteExportCollection[];
@@ -0,0 +1,40 @@
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 { PLUGIN_HOST_COLLECTIONS_DECLARED } from "./first-party-plugins.generated.js";
17
+ import { hostResourcePlatformCap } from "./plugin-host-resources.js";
18
+ /** Every collection a plugin declares for the site backup, in config order. */ export function listPluginSiteExportCollections() {
19
+ const out = [];
20
+ for (const row of PLUGIN_HOST_COLLECTIONS_DECLARED){
21
+ var _resource_platformCap;
22
+ const { siteExport, resource } = row;
23
+ if (!siteExport || !resource) continue;
24
+ out.push({
25
+ pluginId: row.pluginId,
26
+ collection: row.name,
27
+ limit: siteExport.limit,
28
+ fields: siteExport.fields,
29
+ label: resource.label,
30
+ count: resource.quotaKey ? {
31
+ quotaKey: resource.quotaKey
32
+ } : {
33
+ max: hostResourcePlatformCap((_resource_platformCap = resource.platformCap) != null ? _resource_platformCap : '')
34
+ }
35
+ });
36
+ }
37
+ return out;
38
+ }
39
+
40
+ //# sourceMappingURL=plugin-site-export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-site-export.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 { PLUGIN_HOST_COLLECTIONS_DECLARED } from './first-party-plugins.generated'\nimport { hostResourcePlatformCap } from './plugin-host-resources'\n\n/**\n * A plugin's host collection in the platform's whole-site backup (AGL-3080).\n *\n * `/api/hosts/export` writes one JSON bundle of everything designable on a\n * site and `/api/hosts/import` restores it (AGL-163). The platform's own\n * documents — screens, layouts, components, authors, content collections,\n * media — are the routes' to carry. A plugin whose site documents belong in\n * a backup declares so beside the collection, in the `hostCollections` block\n * of `plugins.config.json` (a host collection's `siteExport`), and both\n * routes walk the declarations: the export reads up to `limit` live documents\n * into the bundle under the collection's own name, and the restore writes each\n * one back through `fields` and counts the result against the collection's\n * declared `resource`.\n *\n * ## `fields` is the round trip, not the create\n *\n * A restore writes with `merge: false`, so the list is every key a live\n * document carries — which can be narrower than what a create admits, and is\n * often wider — and a key left off is ERASED from every restored document\n * (AGL-1382). Nothing the restore stamps (`createdAt`, `updatedAt`,\n * `deletedAt`) or scopes (`visibleTo`) is on it; the generator refuses them.\n *\n * ## Compiled, and counted\n *\n * A backup that silently lacks a collection is worse than a failed one: the\n * file looks whole until the day it is restored. So the declarations are\n * compiled, present the moment this module is imported, and a runtime\n * `registerPluginHostCollections` carrying a `siteExport` throws. A restore\n * creates documents with the Admin SDK, past the rules, so the generator also\n * refuses a `siteExport` on a collection with no `resource`: the resource's\n * plan counter or flat platform cap is what the restore is met against.\n *\n * Reached by its own subpath, never the barrel: its readers are the two\n * console routes.\n */\nexport interface PluginHostCollectionSiteExport {\n /** The most live documents one bundle carries; a restore writes no more. */\n limit: number\n /** The keys a restore writes back. Anything else a bundle carries is dropped. */\n fields: readonly string[]\n}\n\n/** What a restore of a declared collection is counted against. */\nexport type PluginSiteExportCount =\n /** A plan counter, an `OrgEntitlements` key core resolves. */\n | { quotaKey: string }\n /**\n * A flat platform cap, resolved from the name the resource declares, or\n * `null` for a name core does not hold — which a restore refuses.\n */\n | { max: number | null }\n\n/** A declared collection with the plugin that made it and its count. */\nexport interface ResolvedPluginSiteExportCollection extends PluginHostCollectionSiteExport {\n pluginId: string\n /** The subcollection under `hosts/{hostId}`, and its key in the bundle. */\n collection: string\n /** Plural, for a restore's refusal: \"this backup holds 40 {label}\". */\n label: string\n count: PluginSiteExportCount\n}\n\n/** Every collection a plugin declares for the site backup, in config order. */\nexport function listPluginSiteExportCollections(): ResolvedPluginSiteExportCollection[] {\n const out: ResolvedPluginSiteExportCollection[] = []\n for (const row of PLUGIN_HOST_COLLECTIONS_DECLARED) {\n const { siteExport, resource } = row\n if (!siteExport || !resource) continue\n out.push({\n pluginId: row.pluginId,\n collection: row.name,\n limit: siteExport.limit,\n fields: siteExport.fields,\n label: resource.label,\n count: resource.quotaKey\n ? { quotaKey: resource.quotaKey }\n : { max: hostResourcePlatformCap(resource.platformCap ?? '') },\n })\n }\n return out\n}\n"],"names":["PLUGIN_HOST_COLLECTIONS_DECLARED","hostResourcePlatformCap","listPluginSiteExportCollections","out","row","resource","siteExport","push","pluginId","collection","name","limit","fields","label","count","quotaKey","max","platformCap"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,gCAAgC,QAAQ,qCAAiC;AAClF,SAASC,uBAAuB,QAAQ,6BAAyB;AAgEjE,6EAA6E,GAC7E,OAAO,SAASC;IACd,MAAMC,MAA4C,EAAE;IACpD,KAAK,MAAMC,OAAOJ,iCAAkC;YAWbK;QAVrC,MAAM,EAAEC,UAAU,EAAED,QAAQ,EAAE,GAAGD;QACjC,IAAI,CAACE,cAAc,CAACD,UAAU;QAC9BF,IAAII,IAAI,CAAC;YACPC,UAAUJ,IAAII,QAAQ;YACtBC,YAAYL,IAAIM,IAAI;YACpBC,OAAOL,WAAWK,KAAK;YACvBC,QAAQN,WAAWM,MAAM;YACzBC,OAAOR,SAASQ,KAAK;YACrBC,OAAOT,SAASU,QAAQ,GACpB;gBAAEA,UAAUV,SAASU,QAAQ;YAAC,IAC9B;gBAAEC,KAAKf,yBAAwBI,wBAAAA,SAASY,WAAW,YAApBZ,wBAAwB;YAAI;QACjE;IACF;IACA,OAAOF;AACT"}
@@ -0,0 +1,88 @@
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 child sitemap a plugin's documents fill, declared by that plugin
19
+ * (AGL-3080).
20
+ *
21
+ * The tenant's `/sitemap.xml` is an index over one child per section (AGL-2520):
22
+ * the site's pages, its content collections and its authors are the platform's
23
+ * and are built by the route itself. A plugin that serves pages of its own — a
24
+ * product at `/products/{slug}` — had its section written into that route by
25
+ * hand: the collection, the filter, the store setting that switches it on, the
26
+ * address and the date field were all core's knowledge of one plugin's model.
27
+ *
28
+ * So the plugin declares the section, and the route builds every declared one
29
+ * the same way: counted for the index, paged by document id for the child.
30
+ *
31
+ * ## Compiled, because the reader is a published page's
32
+ *
33
+ * The sitemap is what a search engine is told the site holds. A section
34
+ * registered at runtime would be missing from any process that had not loaded
35
+ * the plugin, and a crawler reads a missing section as pages that no longer
36
+ * exist — the products drop out of the index silently, on a live site. So
37
+ * sections are compiled from `plugins.config.json` by
38
+ * `tools/scripts/generate-plugin-manifests.mjs`, present the moment this
39
+ * module is imported, and there is no registrar.
40
+ *
41
+ * ## What a declaration can say
42
+ *
43
+ * Only what a sitemap needs and a query can express: one equality filter, the
44
+ * setting that must be set for the pages to render at all, the address with
45
+ * `{slug}` in it, a field that drops a row (a soft delete), and the date
46
+ * fields to try in order. A row without a slug addresses nothing and is left
47
+ * out. Anything richer belongs to the plugin's own page, not to its sitemap.
48
+ *
49
+ * Reached by its own subpath, never the barrel.
50
+ */
51
+ export interface PluginSitemapSectionDeclaration {
52
+ /** The section's path segment: `/sitemaps/{section}/{page}.xml`. */
53
+ section: string;
54
+ /** The subcollection under `hosts/{hostId}` whose documents are the pages. */
55
+ collection: string;
56
+ /** The one equality a document must meet to be a page. */
57
+ where?: {
58
+ field: string;
59
+ equals: string | number | boolean;
60
+ };
61
+ /**
62
+ * A `collection/doc` under the host and a field on it that must be set for
63
+ * the section to exist: the template the pages render through. Unset, the
64
+ * section is left out rather than listing addresses that 404.
65
+ */
66
+ enabledBy?: {
67
+ doc: string;
68
+ field: string;
69
+ };
70
+ /** The page's site path, with `{slug}` standing for the document's slug. */
71
+ path: string;
72
+ /** The field holding the slug; `slug` when absent. */
73
+ slugField?: string;
74
+ /** A field whose truthy value leaves the row out, for a soft delete the filter cannot see. */
75
+ skipWhen?: string;
76
+ /** The fields a row's `lastmod` is read from, first present wins. */
77
+ lastmod?: readonly string[];
78
+ }
79
+ /** A declaration with the plugin that made it. */
80
+ export type ResolvedPluginSitemapSection = PluginSitemapSectionDeclaration & {
81
+ pluginId: string;
82
+ };
83
+ /** Every declared section, in config order — the order the index lists them. */
84
+ export declare function listPluginSitemapSections(): readonly ResolvedPluginSitemapSection[];
85
+ /** One declared section by its name, or `null`. */
86
+ export declare function pluginSitemapSection(section: string): ResolvedPluginSitemapSection | null;
87
+ /** The site path of one row, or `null` for a row with no slug. */
88
+ export declare function pluginSitemapSectionPath(declaration: PluginSitemapSectionDeclaration, slug: unknown): string | null;
@@ -0,0 +1,29 @@
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 { PLUGIN_SITEMAP_SECTIONS_DECLARED } from "./first-party-plugins.generated.js";
17
+ /** Every declared section, in config order — the order the index lists them. */ export function listPluginSitemapSections() {
18
+ return PLUGIN_SITEMAP_SECTIONS_DECLARED;
19
+ }
20
+ /** One declared section by its name, or `null`. */ export function pluginSitemapSection(section) {
21
+ var _PLUGIN_SITEMAP_SECTIONS_DECLARED_find;
22
+ return (_PLUGIN_SITEMAP_SECTIONS_DECLARED_find = PLUGIN_SITEMAP_SECTIONS_DECLARED.find((one)=>one.section === section)) != null ? _PLUGIN_SITEMAP_SECTIONS_DECLARED_find : null;
23
+ }
24
+ /** The site path of one row, or `null` for a row with no slug. */ export function pluginSitemapSectionPath(declaration, slug) {
25
+ if (typeof slug !== 'string' || !slug) return null;
26
+ return declaration.path.replace('{slug}', slug);
27
+ }
28
+
29
+ //# sourceMappingURL=plugin-sitemap-sections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-sitemap-sections.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 { PLUGIN_SITEMAP_SECTIONS_DECLARED } from './first-party-plugins.generated'\n\n/**\n * A child sitemap a plugin's documents fill, declared by that plugin\n * (AGL-3080).\n *\n * The tenant's `/sitemap.xml` is an index over one child per section (AGL-2520):\n * the site's pages, its content collections and its authors are the platform's\n * and are built by the route itself. A plugin that serves pages of its own — a\n * product at `/products/{slug}` — had its section written into that route by\n * hand: the collection, the filter, the store setting that switches it on, the\n * address and the date field were all core's knowledge of one plugin's model.\n *\n * So the plugin declares the section, and the route builds every declared one\n * the same way: counted for the index, paged by document id for the child.\n *\n * ## Compiled, because the reader is a published page's\n *\n * The sitemap is what a search engine is told the site holds. A section\n * registered at runtime would be missing from any process that had not loaded\n * the plugin, and a crawler reads a missing section as pages that no longer\n * exist — the products drop out of the index silently, on a live site. So\n * sections are compiled from `plugins.config.json` by\n * `tools/scripts/generate-plugin-manifests.mjs`, present the moment this\n * module is imported, and there is no registrar.\n *\n * ## What a declaration can say\n *\n * Only what a sitemap needs and a query can express: one equality filter, the\n * setting that must be set for the pages to render at all, the address with\n * `{slug}` in it, a field that drops a row (a soft delete), and the date\n * fields to try in order. A row without a slug addresses nothing and is left\n * out. Anything richer belongs to the plugin's own page, not to its sitemap.\n *\n * Reached by its own subpath, never the barrel.\n */\nexport interface PluginSitemapSectionDeclaration {\n /** The section's path segment: `/sitemaps/{section}/{page}.xml`. */\n section: string\n /** The subcollection under `hosts/{hostId}` whose documents are the pages. */\n collection: string\n /** The one equality a document must meet to be a page. */\n where?: { field: string; equals: string | number | boolean }\n /**\n * A `collection/doc` under the host and a field on it that must be set for\n * the section to exist: the template the pages render through. Unset, the\n * section is left out rather than listing addresses that 404.\n */\n enabledBy?: { doc: string; field: string }\n /** The page's site path, with `{slug}` standing for the document's slug. */\n path: string\n /** The field holding the slug; `slug` when absent. */\n slugField?: string\n /** A field whose truthy value leaves the row out, for a soft delete the filter cannot see. */\n skipWhen?: string\n /** The fields a row's `lastmod` is read from, first present wins. */\n lastmod?: readonly string[]\n}\n\n/** A declaration with the plugin that made it. */\nexport type ResolvedPluginSitemapSection = PluginSitemapSectionDeclaration & {\n pluginId: string\n}\n\n/** Every declared section, in config order — the order the index lists them. */\nexport function listPluginSitemapSections(): readonly ResolvedPluginSitemapSection[] {\n return PLUGIN_SITEMAP_SECTIONS_DECLARED\n}\n\n/** One declared section by its name, or `null`. */\nexport function pluginSitemapSection(\n section: string,\n): ResolvedPluginSitemapSection | null {\n return PLUGIN_SITEMAP_SECTIONS_DECLARED.find((one) => one.section === section) ?? null\n}\n\n/** The site path of one row, or `null` for a row with no slug. */\nexport function pluginSitemapSectionPath(\n declaration: PluginSitemapSectionDeclaration,\n slug: unknown,\n): string | null {\n if (typeof slug !== 'string' || !slug) return null\n return declaration.path.replace('{slug}', slug)\n}\n"],"names":["PLUGIN_SITEMAP_SECTIONS_DECLARED","listPluginSitemapSections","pluginSitemapSection","section","find","one","pluginSitemapSectionPath","declaration","slug","path","replace"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,gCAAgC,QAAQ,qCAAiC;AAgElF,8EAA8E,GAC9E,OAAO,SAASC;IACd,OAAOD;AACT;AAEA,iDAAiD,GACjD,OAAO,SAASE,qBACdC,OAAe;QAERH;IAAP,QAAOA,yCAAAA,iCAAiCI,IAAI,CAAC,CAACC,MAAQA,IAAIF,OAAO,KAAKA,oBAA/DH,yCAA2E;AACpF;AAEA,gEAAgE,GAChE,OAAO,SAASM,yBACdC,WAA4C,EAC5CC,IAAa;IAEb,IAAI,OAAOA,SAAS,YAAY,CAACA,MAAM,OAAO;IAC9C,OAAOD,YAAYE,IAAI,CAACC,OAAO,CAAC,UAAUF;AAC5C"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * GENERATED FILE — do not edit. Regenerate with:
3
+ * node tools/scripts/generate-plugin-manifests.mjs
4
+ *
5
+ * The subscription topics plugins declare (AGL-3080): each plugin's
6
+ * `subscriptionTopics` block in plugins.config.json, in preference-page
7
+ * order. Core's `app-utils/subscription-topics.ts` reads them as the
8
+ * built-in floor of every org's topic catalog; core names no stream.
9
+ */
10
+ import type { DeclaredSubscriptionTopic } from '../app-utils/subscription-topics';
11
+ export declare const PLUGIN_SUBSCRIPTION_TOPICS_DECLARED: readonly DeclaredSubscriptionTopic[];
@@ -0,0 +1,41 @@
1
+ /**
2
+ * GENERATED FILE — do not edit. Regenerate with:
3
+ * node tools/scripts/generate-plugin-manifests.mjs
4
+ *
5
+ * The subscription topics plugins declare (AGL-3080): each plugin's
6
+ * `subscriptionTopics` block in plugins.config.json, in preference-page
7
+ * order. Core's `app-utils/subscription-topics.ts` reads them as the
8
+ * built-in floor of every org's topic catalog; core names no stream.
9
+ */ export const PLUGIN_SUBSCRIPTION_TOPICS_DECLARED = [
10
+ {
11
+ "pluginId": "marketing",
12
+ "id": "marketing",
13
+ "name": "Promotions and offers",
14
+ "description": "Sales, discounts and seasonal campaigns.",
15
+ "order": 10,
16
+ "default": true
17
+ },
18
+ {
19
+ "pluginId": "commerce",
20
+ "id": "newsletter",
21
+ "name": "Newsletter",
22
+ "description": "Regular news and stories from us.",
23
+ "order": 20
24
+ },
25
+ {
26
+ "pluginId": "commerce",
27
+ "id": "product-updates",
28
+ "name": "Product updates",
29
+ "description": "New products, restocks and changes to what we offer.",
30
+ "order": 30
31
+ },
32
+ {
33
+ "pluginId": "outreach",
34
+ "id": "sales",
35
+ "name": "Sales outreach",
36
+ "description": "Messages from a person here about working together.",
37
+ "order": 40
38
+ }
39
+ ];
40
+
41
+ //# sourceMappingURL=plugin-subscription-topics.generated.js.map