@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,20 @@
1
+ /**
2
+ * GENERATED FILE — do not edit. Regenerate with:
3
+ * node tools/scripts/generate-plugin-manifests.mjs
4
+ *
5
+ * The container kinds plugins declare (AGL-3080): each plugin's
6
+ * `containers` block in plugins.config.json. Core's `plugin-containers.ts`
7
+ * reads them; core names no kind.
8
+ */ export const PLUGIN_CONTAINER_KINDS_DECLARED = [
9
+ {
10
+ "pluginId": "marketing",
11
+ "kind": "campaign",
12
+ "label": "Campaign",
13
+ "pluralLabel": "Campaigns",
14
+ "ownerLabel": "Marketing",
15
+ "orgCollection": "emailCampaigns",
16
+ "nameField": "name"
17
+ }
18
+ ];
19
+
20
+ //# sourceMappingURL=plugin-containers.generated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-containers.generated.ts"],"sourcesContent":["/**\n * GENERATED FILE — do not edit. Regenerate with:\n * node tools/scripts/generate-plugin-manifests.mjs\n *\n * The container kinds plugins declare (AGL-3080): each plugin's\n * `containers` block in plugins.config.json. Core's `plugin-containers.ts`\n * reads them; core names no kind.\n */\n\nimport type { PluginContainerKind } from './plugin-containers'\n\nexport const PLUGIN_CONTAINER_KINDS_DECLARED: readonly PluginContainerKind[] = [\n {\n \"pluginId\": \"marketing\",\n \"kind\": \"campaign\",\n \"label\": \"Campaign\",\n \"pluralLabel\": \"Campaigns\",\n \"ownerLabel\": \"Marketing\",\n \"orgCollection\": \"emailCampaigns\",\n \"nameField\": \"name\"\n }\n]\n"],"names":["PLUGIN_CONTAINER_KINDS_DECLARED"],"mappings":"AAAA;;;;;;;CAOC,GAID,OAAO,MAAMA,kCAAkE;IAC7E;QACE,YAAY;QACZ,QAAQ;QACR,SAAS;QACT,eAAe;QACf,cAAc;QACd,iBAAiB;QACjB,aAAa;IACf;CACD,CAAA"}
@@ -0,0 +1,27 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Aglyn LLC
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */ import { PLUGIN_CONTAINER_KINDS_DECLARED } from "./plugin-containers.generated.js";
18
+ /** Every declared container kind, in catalog order. */ export function listPluginContainerKinds() {
19
+ return PLUGIN_CONTAINER_KINDS_DECLARED.map((row)=>_extends({}, row));
20
+ }
21
+ /** One declared kind, or `null` when no plugin keeps it. */ export function pluginContainerKind(kind) {
22
+ const key = String(kind != null ? kind : '').trim();
23
+ const row = PLUGIN_CONTAINER_KINDS_DECLARED.find((one)=>one.kind === key);
24
+ return row ? _extends({}, row) : null;
25
+ }
26
+
27
+ //# sourceMappingURL=plugin-containers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-containers.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_CONTAINER_KINDS_DECLARED } from './plugin-containers.generated'\n\n/**\n * CONTAINER KINDS: the documents other records are FILED UNDER, declared by\n * the plugin that keeps them.\n *\n * A container is a document other records join by naming its id in a\n * membership array on their OWN documents — a form, a screen, a lead or a\n * contact filed under a campaign. `app-utils/container-membership.ts` says\n * why the edge lives on the member, and holds the helpers every member's\n * writer and reader share.\n *\n * The plugin that keeps a kind declares it in the `containers` block of\n * `plugins.config.json`, compiled into `plugin-containers.generated.ts`, so\n * no surface that files a record has to know which plugin that is or where\n * the containers are stored:\n *\n * - `kind` names the membership field: a member holds its containers in\n * `<kind>Ids` (`containerMembershipField`). The name is the contract,\n * which is what lets a record page in one plugin file itself under a kind\n * another plugin keeps without importing it.\n * - `orgCollection` is where the containers are stored, under the\n * organization (`orgs/{orgId}/{orgCollection}`), one of the owner's own\n * declared org collections. A container is placed on sites by the core's\n * scope field (`visibleTo`) and retired by `deletedAt`, like every other\n * org record a site hub lists.\n * - `label` / `pluralLabel` / `ownerLabel` are what a picker calls one, several,\n * and the plugin a merchant creates one in.\n *\n * Compiled rather than registered: the readers include a form submission\n * that loads no plugin, and a registry that request had not filled would\n * read every record as filed under nothing.\n */\n\n/** One container kind, as its plugin declares it. */\nexport interface PluginContainerKind {\n /** The plugin that keeps the containers. */\n pluginId: string\n /** The kind, lowerCamelCase; its members hold it in `<kind>Ids`. */\n kind: string\n /** What one container is called. */\n label: string\n /** What several are called. */\n pluralLabel: string\n /** The owner's catalog label: where a merchant creates one. */\n ownerLabel: string\n /** The org collection the containers are stored in. */\n orgCollection: string\n /** The field a container's name is stored in. */\n nameField: string\n}\n\n/** Every declared container kind, in catalog order. */\nexport function listPluginContainerKinds(): PluginContainerKind[] {\n return PLUGIN_CONTAINER_KINDS_DECLARED.map((row) => ({ ...row }))\n}\n\n/** One declared kind, or `null` when no plugin keeps it. */\nexport function pluginContainerKind(kind: string): PluginContainerKind | null {\n const key = String(kind ?? '').trim()\n const row = PLUGIN_CONTAINER_KINDS_DECLARED.find((one) => one.kind === key)\n return row ? { ...row } : null\n}\n"],"names":["PLUGIN_CONTAINER_KINDS_DECLARED","listPluginContainerKinds","map","row","pluginContainerKind","kind","key","String","trim","find","one"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,+BAA+B,QAAQ,mCAA+B;AAoD/E,qDAAqD,GACrD,OAAO,SAASC;IACd,OAAOD,gCAAgCE,GAAG,CAAC,CAACC,MAAS,aAAKA;AAC5D;AAEA,0DAA0D,GAC1D,OAAO,SAASC,oBAAoBC,IAAY;IAC9C,MAAMC,MAAMC,OAAOF,eAAAA,OAAQ,IAAIG,IAAI;IACnC,MAAML,MAAMH,gCAAgCS,IAAI,CAAC,CAACC,MAAQA,IAAIL,IAAI,KAAKC;IACvE,OAAOH,MAAM,aAAKA,OAAQ;AAC5B"}
@@ -83,7 +83,7 @@ export interface PluginSiteContributions {
83
83
  export interface PluginConsoleContributions {
84
84
  /**
85
85
  * The widget slots its widgets fill: the `CONSOLE_WIDGET_SLOTS` zones, the
86
- * panels the shell draws as slots (the assistant dock `assistPanel`, the
86
+ * panels the shell draws as slots (the console dock `consoleDock`, the
87
87
  * besigner's `besignerInspector`), and zones another plugin hosts. A screen
88
88
  * that renders one of them loads the plugin.
89
89
  */
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-contributions.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * What a plugin contributes, and where (AGL-3116).\n *\n * A plugin loads only where something uses it. Installing one loads nothing:\n * a published page fetches a plugin's code when the page places one of its\n * elements or the site runs one of its features, and a console screen\n * fetches it when the screen renders one of its slots or routes, or when the\n * plugin draws something the shell renders on every screen.\n *\n * The loaders cannot learn that by running a plugin, because running it is\n * the cost being avoided. So each plugin DECLARES its contributions:\n * first-party plugins in `plugins.config.json`, marketplace plugins in the\n * manifest they publish (`contributes`). The declaration is the whole of what\n * a loader reads, and it is data: this module is dependency-free so the\n * server, both apps, the verifier and the build tools share one reading.\n *\n * A declared surface only narrows where to look. Presence is the rule: a\n * plugin that declares a component loads on the pages that place it, not on\n * every page of the site that installed it.\n *\n * ## A plugin that declares nothing\n *\n * Every marketplace version published before this contract has no\n * `contributes`. Such a plugin keeps working under one default:\n *\n * - **On a published page it loads only where its element is placed**: a\n * node whose `pluginId` names the plugin (its manifest id or its listing\n * id). That is the one presence signal a page carries without running the\n * bundle, and it is the only way a page can show an element the plugin\n * registers. A site runtime of an undeclared plugin does not load, and the\n * publish pipeline refuses a bundle that registers one without declaring\n * it, so the only plugins this default governs are the ones already\n * published.\n * - **In the console it loads with the workspace shell**, as it always did,\n * because a nav tab or a provider is only discoverable by running\n * `register()`. Nothing on a published page depends on this.\n */\n\n/** What a plugin adds to a published site. */\nexport interface PluginSiteContributions {\n /**\n * Canvas component ids the plugin registers: the elements a page places. A\n * published page loads the plugin only when its node tree places one.\n */\n components?: string[]\n /**\n * Site features: runtimes the plugin mounts on every page of a site that\n * switched it on (an announcement bar, an experiment runner), named by the\n * `runtimeId` it registers. A plugin with a feature loads on every page of\n * such a site, which is what a feature is.\n */\n features?: string[]\n /**\n * The elements that run a site function in the visitor's browser (AGL-3393),\n * each keyed by its component id and naming the prop that holds the\n * function's name. Compose hands such a node the function's definition and\n * the site variables it reads; no other node is given either.\n *\n * Declared DATA rather than read off a registered schema: compose runs where\n * no plugin code loads — the tenant's server components — so the only thing\n * it can consult is a declaration. A first-party plugin declares it in\n * `plugins.config.json`, a marketplace plugin in its manifest, and both reach\n * compose as the same map. Every key must also be one of `components`.\n */\n functionBindings?: Record<string, string>\n}\n\n/** What a plugin adds to the console. */\nexport interface PluginConsoleContributions {\n /**\n * The widget slots its widgets fill: the `CONSOLE_WIDGET_SLOTS` zones, the\n * panels the shell draws as slots (the assistant dock `assistPanel`, the\n * besigner's `besignerInspector`), and zones another plugin hosts. A screen\n * that renders one of them loads the plugin.\n */\n slots?: string[]\n /** Site-level console routes it serves (`/forms`), beneath `/hosts/[host]`. */\n routes?: string[]\n /** Organization-level console routes it serves (`/outreach`). */\n orgRoutes?: string[]\n /**\n * The shell draws something of it on every screen of a workspace: a nav\n * tab, an organization tab, a staff tab or a provider. Such a plugin loads\n * with the shell, because every screen renders it.\n */\n shell?: boolean\n}\n\nexport interface PluginContributions {\n site?: PluginSiteContributions\n console?: PluginConsoleContributions\n}\n\n/** Bound on each declared list, so a manifest cannot hand a loader a novel. */\nexport const PLUGIN_MAX_CONTRIBUTIONS = 128\n\n/**\n * A component, feature or slot id: an identifier with the separators ids in\n * the platform use (`muiTypography`, `marketplacePlugin`, `ai.assist`).\n */\nconst CONTRIBUTION_ID = /^[A-Za-z_][A-Za-z0-9_.:-]{0,79}$/\n\n/**\n * A console route: one or more path segments, as a nav item's `href` names\n * them. Never a URL, never `..`.\n */\nconst CONTRIBUTION_ROUTE = /^(\\/[A-Za-z0-9_-]+){1,8}$/\n\n/** A prop name a function binding may name: a plain identifier. */\nconst BINDING_PROP = /^[A-Za-z_$][A-Za-z0-9_$]{0,63}$/\n\ntype Sanitized =\n | { ok: true; contributions: PluginContributions }\n | { ok: false; error: string }\n\n/**\n * Validates a declared `contributes` block.\n *\n * Malformed input is REFUSED rather than trimmed: a loader reads this to\n * decide where a plugin runs, so a declaration that silently lost an entry\n * would stop the plugin loading where it is used, and nobody would see why.\n * Duplicates are collapsed and empty lists dropped, because neither changes\n * what the declaration means.\n *\n * `{}` is valid and means \"contributes nothing anywhere\", which is a\n * different statement from an absent block (see the module note).\n */\nexport function sanitizePluginContributions(input: unknown): Sanitized {\n if (!isPlainObject(input)) {\n return { ok: false, error: 'contributes must be an object' }\n }\n const out: PluginContributions = {}\n for (const key of Object.keys(input)) {\n if (key !== 'site' && key !== 'console') {\n return { ok: false, error: `contributes.${key} is not a known surface` }\n }\n }\n\n if (input['site'] !== undefined) {\n const site = input['site']\n if (!isPlainObject(site)) {\n return { ok: false, error: 'contributes.site must be an object' }\n }\n const next: PluginSiteContributions = {}\n for (const key of Object.keys(site)) {\n if (key === 'functionBindings') continue\n if (key !== 'components' && key !== 'features') {\n return { ok: false, error: `contributes.site.${key} is not a known contribution` }\n }\n const list = idList(site[key], `contributes.site.${key}`, CONTRIBUTION_ID)\n if (list.ok === false) return { ok: false, error: list.error }\n if (list.values.length) next[key] = list.values\n }\n if (site['functionBindings'] !== undefined) {\n const bindings = functionBindingMap(\n site['functionBindings'],\n next.components ?? [],\n )\n if (bindings.ok === false) return { ok: false, error: bindings.error }\n if (Object.keys(bindings.value).length) {\n next.functionBindings = bindings.value\n }\n }\n if (Object.keys(next).length) out.site = next\n }\n\n if (input['console'] !== undefined) {\n const consoleInput = input['console']\n if (!isPlainObject(consoleInput)) {\n return { ok: false, error: 'contributes.console must be an object' }\n }\n const next: PluginConsoleContributions = {}\n for (const key of Object.keys(consoleInput)) {\n if (key === 'shell') {\n if (typeof consoleInput['shell'] !== 'boolean') {\n return { ok: false, error: 'contributes.console.shell must be true or false' }\n }\n if (consoleInput['shell']) next.shell = true\n continue\n }\n if (key !== 'slots' && key !== 'routes' && key !== 'orgRoutes') {\n return {\n ok: false,\n error: `contributes.console.${key} is not a known contribution`,\n }\n }\n const list = idList(\n consoleInput[key],\n `contributes.console.${key}`,\n key === 'slots' ? CONTRIBUTION_ID : CONTRIBUTION_ROUTE,\n )\n if (list.ok === false) return { ok: false, error: list.error }\n if (list.values.length) next[key] = list.values\n }\n if (Object.keys(next).length) out.console = next\n }\n\n return { ok: true, contributions: out }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction idList(\n value: unknown,\n where: string,\n pattern: RegExp,\n): { ok: true; values: string[] } | { ok: false; error: string } {\n if (!Array.isArray(value)) return { ok: false, error: `${where} must be a list` }\n if (value.length > PLUGIN_MAX_CONTRIBUTIONS) {\n return { ok: false, error: `${where} lists more than ${PLUGIN_MAX_CONTRIBUTIONS}` }\n }\n const values: string[] = []\n for (const entry of value) {\n if (typeof entry !== 'string' || !pattern.test(entry)) {\n return { ok: false, error: `${where} has an invalid entry \"${String(entry)}\"` }\n }\n if (!values.includes(entry)) values.push(entry)\n }\n return { ok: true, values }\n}\n\n/**\n * `contributes.site.functionBindings`, validated against the components the\n * same block declares: a binding on an element the plugin does not register\n * would hand a function's definition, and the variable values it reads, to\n * whichever element happens to own that id.\n */\nfunction functionBindingMap(\n value: unknown,\n components: readonly string[],\n): { ok: true; value: Record<string, string> } | { ok: false; error: string } {\n const where = 'contributes.site.functionBindings'\n if (!isPlainObject(value)) {\n return { ok: false, error: `${where} must be an object` }\n }\n const entries = Object.entries(value)\n if (entries.length > PLUGIN_MAX_CONTRIBUTIONS) {\n return { ok: false, error: `${where} lists more than ${PLUGIN_MAX_CONTRIBUTIONS}` }\n }\n const out: Record<string, string> = {}\n for (const [componentId, prop] of entries) {\n if (!components.includes(componentId)) {\n return {\n ok: false,\n error: `${where} names \"${componentId}\", which contributes.site.components does not declare`,\n }\n }\n if (typeof prop !== 'string' || !BINDING_PROP.test(prop)) {\n return {\n ok: false,\n error: `${where}.${componentId} must name a prop, not \"${String(prop)}\"`,\n }\n }\n out[componentId] = prop\n }\n return { ok: true, value: out }\n}\n\n/**\n * A declared `contributes` block as a loader may trust it: the sanitized\n * block, or `undefined` for one that is absent or does not validate.\n *\n * Loaders read this from stored documents (a pinned version's manifest), and\n * a malformed stored block is treated as UNDECLARED — the default applies —\n * never as \"contributes nothing\", which would stop a plugin that is in use.\n */\nexport function readPluginContributions(\n input: unknown,\n): PluginContributions | undefined {\n if (input === undefined || input === null) return undefined\n const verdict = sanitizePluginContributions(input)\n return verdict.ok ? verdict.contributions : undefined\n}\n\n/**\n * What the surface a plugin is being registered into actually uses\n * (AGL-3141).\n *\n * The loaders carry this from the surface that computed it to each plugin's\n * register function, unchanged. A plugin that can register a part of itself\n * reads it; one that cannot ignores it, and the platform's behavior is the\n * same either way.\n *\n * An absent field means \"everything of that kind\". A surface that cannot say\n * what it uses must be handed all of it, because an element the surface\n * places and the set omits has no registered component and renders NOTHING,\n * silently (the blank-canvas invariant, AGL-52). Narrowing is an optimization\n * and must fail toward the whole.\n */\nexport interface PluginUse {\n /**\n * Canvas component ids the surface places, read from the FULL composed\n * document the way `pagePresence` reads it — withheld lazy-panel subtrees\n * included, because an element inside a panel the visitor opens later is\n * still this page's element.\n */\n componentIds?: readonly string[]\n}\n\n/** A node as presence reads it: the two ids a placed element carries. */\nexport interface PresenceNode {\n componentId?: string\n pluginId?: string\n}\n\n/** What a published page places: its component ids and the plugin ids stamped on its nodes. */\nexport interface PagePresence {\n componentIds: ReadonlySet<string>\n pluginIds: ReadonlySet<string>\n}\n\n/**\n * The component ids and plugin ids a node tree places.\n *\n * Read from the FULL composed document — layouts, grafted reusable\n * components and withheld lazy panels included — because an element inside\n * a panel the visitor opens later is still this page's element.\n */\nexport function pagePresence(\n nodes: Record<string, PresenceNode | null | undefined> | null | undefined,\n): PagePresence {\n const componentIds = new Set<string>()\n const pluginIds = new Set<string>()\n for (const node of Object.values(nodes ?? {})) {\n if (typeof node?.componentId === 'string' && node.componentId) {\n componentIds.add(node.componentId)\n }\n if (typeof node?.pluginId === 'string' && node.pluginId) {\n pluginIds.add(node.pluginId)\n }\n }\n return { componentIds, pluginIds }\n}\n\n/** A plugin as the presence rules see it. */\nexport interface PresenceSubject {\n /** The plugin's own id (a manifest `id`, or a first-party catalog id). */\n pluginId?: string\n /** A marketplace plugin's listing id, which its elements may carry instead. */\n listingId?: string\n /**\n * A marketplace plugin's identity, `<publisher handle>.<manifest id>`\n * (AGL-3390): the `pluginId` its namespaced elements carry.\n */\n identity?: string\n /** Its declaration; `undefined` when it declares nothing. */\n contributes?: PluginContributions\n}\n\n/**\n * Whether a published page uses a plugin, so the page must load it.\n *\n * - An element of it is placed: a node stamped with the plugin's id, or,\n * for a declared plugin, a node whose component id it declares.\n * - It declares a site feature. The caller only asks about plugins the site\n * has switched on, and a feature runs on every page of such a site.\n *\n * A plugin that declares nothing is present only through its stamped\n * elements — the default in the module note.\n */\nexport function isPluginUsedOnPage(\n subject: PresenceSubject,\n page: PagePresence,\n): boolean {\n if (subject.pluginId && page.pluginIds.has(subject.pluginId)) return true\n if (subject.listingId && page.pluginIds.has(subject.listingId)) return true\n if (subject.identity && page.pluginIds.has(subject.identity)) return true\n const site = subject.contributes?.site\n if (!site) return false\n if (site.features?.length) return true\n return (site.components ?? []).some((id) => page.componentIds.has(id))\n}\n\n/**\n * Whether a plugin declares anything a site draws: an element an author can\n * place, or a feature that runs on the site's pages. The editor loads exactly\n * these (AGL-3391). A plugin that declares nothing is not among them: its\n * site half is only discoverable by running `register()`, and the console\n * shell already does that for it.\n */\nexport function declaresSiteElements(\n contributes: PluginContributions | undefined,\n): boolean {\n const site = contributes?.site\n return Boolean(site?.components?.length || site?.features?.length)\n}\n\n/**\n * Every id a plugin's elements and presets may carry as their `pluginId`: its\n * own id and, for a marketplace plugin, its listing id and its identity. A\n * surface that filters registry entries by plugin set needs all of them, or it\n * hides the elements of a plugin it just loaded.\n */\nexport function presenceIds(subject: PresenceSubject): string[] {\n const ids: string[] = []\n for (const id of [subject.identity, subject.pluginId, subject.listingId]) {\n if (id && !ids.includes(id)) ids.push(id)\n }\n return ids\n}\n\n/**\n * Function bindings (AGL-3393): component id → the prop naming the site\n * function that element runs.\n */\nexport type FunctionBindings = Readonly<Record<string, string>>\n\n/**\n * The function bindings a set of plugins declares, merged into one map.\n *\n * Where two plugins bind the same component id the FIRST one listed wins, so a\n * caller that passes first-party declarations ahead of marketplace ones keeps\n * a marketplace manifest from rebinding a first-party element. Marketplace ids\n * are namespaced by their publisher (see {@link isNamespacedComponentId}), so\n * a collision is a mistake, never a feature.\n */\nexport function mergeFunctionBindings(\n ...sources: ReadonlyArray<\n FunctionBindings | { contributes?: PluginContributions } | null | undefined\n >\n): FunctionBindings {\n const merged: Record<string, string> = {}\n for (const source of sources) {\n if (!source) continue\n const declared: FunctionBindings | undefined =\n 'contributes' in source\n ? (source.contributes as PluginContributions | undefined)?.site\n ?.functionBindings\n : (source as FunctionBindings)\n for (const [componentId, prop] of Object.entries(declared ?? {})) {\n if (typeof prop !== 'string') continue\n if (!Object.prototype.hasOwnProperty.call(merged, componentId)) {\n merged[componentId] = prop\n }\n }\n }\n return merged\n}\n\n/**\n * Whether a component id belongs to a marketplace plugin's namespace\n * (AGL-3387): `<publisher handle>.<plugin id>.<role>`. A `.` is reserved for\n * those ids — no first-party component carries one, which the manifest\n * generator enforces — so compose can tell, without loading anything, that a\n * tree places an element only an installed plugin can declare.\n */\nexport function isNamespacedComponentId(componentId: unknown): boolean {\n return typeof componentId === 'string' && componentId.includes('.')\n}\n\n/**\n * Where a plugin's console code loads, resolved with the default applied: a\n * plugin that declares nothing loads with the shell, as it always did.\n */\nexport interface ConsoleLoadPoints {\n shell: boolean\n slots: readonly string[]\n routes: readonly string[]\n orgRoutes: readonly string[]\n}\n\nexport function consoleLoadPoints(\n contributes: PluginContributions | undefined,\n): ConsoleLoadPoints {\n if (!contributes) return { shell: true, slots: [], routes: [], orgRoutes: [] }\n const declared = contributes.console ?? {}\n return {\n shell: Boolean(declared.shell),\n slots: declared.slots ?? [],\n routes: declared.routes ?? [],\n orgRoutes: declared.orgRoutes ?? [],\n }\n}\n\n/**\n * Whether a declared route serves `href`: the route itself, or a path beneath\n * it on a segment boundary, the way the shell's page resolver matches a nav\n * item that owns its subtree. `/products` serves `/products/orders` and never\n * `/products-archive`.\n */\nexport function routeServes(route: string, href: string): boolean {\n return href === route || href.startsWith(`${route}/`)\n}\n\n/**\n * A place in the console that loads plugins, as the surface drawing it names\n * itself (AGL-3142).\n *\n * - `shell`: the workspace chrome every screen has. It draws whatever a\n * plugin adds to every screen — a nav tab, an organization tab, a staff\n * tab, a provider — so a plugin that declares any of those loads here, and\n * so does one that declares nothing at all.\n * - `slots`: the zones a screen renders. The zones it names, not the plugins\n * it expects in them: a screen must never hold a plugin id.\n * - `route`: the path the reader has open, plugin-relative (`/products`,\n * `/products/orders`), on the level its route tree serves — `site` beneath\n * `/hosts/[host]`, `org` beneath the organization.\n * - `editor`: the Besigner, which draws a site's elements and offers them in\n * its Elements panel (AGL-3391). A plugin loads here when it declares site\n * elements or site features, whether or not the page open uses them, since\n * the author is choosing what to place.\n */\nexport type ConsoleLoadWhere =\n | { at: 'shell' }\n | { at: 'slots'; slots: readonly string[] }\n | { at: 'route'; href: string; level: 'site' | 'org' }\n | { at: 'editor' }\n\n/**\n * Whether a console surface uses a plugin, so it must load it.\n *\n * The console twin of {@link isPluginUsedOnPage}, and the same rule: a\n * declaration says where a plugin's code belongs, and the surface that draws\n * that place is the one that fetches it. A screen asks about the zones it\n * renders and the path it serves; it never asks about a plugin by name.\n *\n * A plugin that declares nothing loads with the shell — the default in the\n * module note, and the reason the shell branch reads\n * {@link consoleLoadPoints} rather than the raw block. Its nav tab or its\n * provider is only discoverable by running `register()`, so narrowing it\n * anywhere else would take a tab away with no way to notice.\n */\nexport function isPluginUsedInConsole(\n contributes: PluginContributions | undefined,\n where: ConsoleLoadWhere,\n): boolean {\n if (where.at === 'editor') return declaresSiteElements(contributes)\n const points = consoleLoadPoints(contributes)\n if (where.at === 'shell') return points.shell\n if (where.at === 'slots') {\n return points.slots.some((slot) => where.slots.includes(slot))\n }\n const routes = where.level === 'org' ? points.orgRoutes : points.routes\n return routes.some((route) => routeServes(route, where.href))\n}\n"],"names":["PLUGIN_MAX_CONTRIBUTIONS","CONTRIBUTION_ID","CONTRIBUTION_ROUTE","BINDING_PROP","sanitizePluginContributions","input","isPlainObject","ok","error","out","key","Object","keys","undefined","site","next","list","idList","values","length","bindings","functionBindingMap","components","value","functionBindings","consoleInput","shell","console","contributions","Boolean","Array","isArray","where","pattern","entry","test","String","includes","push","entries","componentId","prop","readPluginContributions","verdict","pagePresence","nodes","componentIds","Set","pluginIds","node","add","pluginId","isPluginUsedOnPage","subject","page","has","listingId","identity","contributes","features","some","id","declaresSiteElements","presenceIds","ids","mergeFunctionBindings","sources","merged","source","declared","prototype","hasOwnProperty","call","isNamespacedComponentId","consoleLoadPoints","slots","routes","orgRoutes","routeServes","route","href","startsWith","isPluginUsedInConsole","at","points","slot","level"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-contributions.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * What a plugin contributes, and where (AGL-3116).\n *\n * A plugin loads only where something uses it. Installing one loads nothing:\n * a published page fetches a plugin's code when the page places one of its\n * elements or the site runs one of its features, and a console screen\n * fetches it when the screen renders one of its slots or routes, or when the\n * plugin draws something the shell renders on every screen.\n *\n * The loaders cannot learn that by running a plugin, because running it is\n * the cost being avoided. So each plugin DECLARES its contributions:\n * first-party plugins in `plugins.config.json`, marketplace plugins in the\n * manifest they publish (`contributes`). The declaration is the whole of what\n * a loader reads, and it is data: this module is dependency-free so the\n * server, both apps, the verifier and the build tools share one reading.\n *\n * A declared surface only narrows where to look. Presence is the rule: a\n * plugin that declares a component loads on the pages that place it, not on\n * every page of the site that installed it.\n *\n * ## A plugin that declares nothing\n *\n * Every marketplace version published before this contract has no\n * `contributes`. Such a plugin keeps working under one default:\n *\n * - **On a published page it loads only where its element is placed**: a\n * node whose `pluginId` names the plugin (its manifest id or its listing\n * id). That is the one presence signal a page carries without running the\n * bundle, and it is the only way a page can show an element the plugin\n * registers. A site runtime of an undeclared plugin does not load, and the\n * publish pipeline refuses a bundle that registers one without declaring\n * it, so the only plugins this default governs are the ones already\n * published.\n * - **In the console it loads with the workspace shell**, as it always did,\n * because a nav tab or a provider is only discoverable by running\n * `register()`. Nothing on a published page depends on this.\n */\n\n/** What a plugin adds to a published site. */\nexport interface PluginSiteContributions {\n /**\n * Canvas component ids the plugin registers: the elements a page places. A\n * published page loads the plugin only when its node tree places one.\n */\n components?: string[]\n /**\n * Site features: runtimes the plugin mounts on every page of a site that\n * switched it on (an announcement bar, an experiment runner), named by the\n * `runtimeId` it registers. A plugin with a feature loads on every page of\n * such a site, which is what a feature is.\n */\n features?: string[]\n /**\n * The elements that run a site function in the visitor's browser (AGL-3393),\n * each keyed by its component id and naming the prop that holds the\n * function's name. Compose hands such a node the function's definition and\n * the site variables it reads; no other node is given either.\n *\n * Declared DATA rather than read off a registered schema: compose runs where\n * no plugin code loads — the tenant's server components — so the only thing\n * it can consult is a declaration. A first-party plugin declares it in\n * `plugins.config.json`, a marketplace plugin in its manifest, and both reach\n * compose as the same map. Every key must also be one of `components`.\n */\n functionBindings?: Record<string, string>\n}\n\n/** What a plugin adds to the console. */\nexport interface PluginConsoleContributions {\n /**\n * The widget slots its widgets fill: the `CONSOLE_WIDGET_SLOTS` zones, the\n * panels the shell draws as slots (the console dock `consoleDock`, the\n * besigner's `besignerInspector`), and zones another plugin hosts. A screen\n * that renders one of them loads the plugin.\n */\n slots?: string[]\n /** Site-level console routes it serves (`/forms`), beneath `/hosts/[host]`. */\n routes?: string[]\n /** Organization-level console routes it serves (`/outreach`). */\n orgRoutes?: string[]\n /**\n * The shell draws something of it on every screen of a workspace: a nav\n * tab, an organization tab, a staff tab or a provider. Such a plugin loads\n * with the shell, because every screen renders it.\n */\n shell?: boolean\n}\n\nexport interface PluginContributions {\n site?: PluginSiteContributions\n console?: PluginConsoleContributions\n}\n\n/** Bound on each declared list, so a manifest cannot hand a loader a novel. */\nexport const PLUGIN_MAX_CONTRIBUTIONS = 128\n\n/**\n * A component, feature or slot id: an identifier with the separators ids in\n * the platform use (`muiTypography`, `marketplacePlugin`, `ai.assist`).\n */\nconst CONTRIBUTION_ID = /^[A-Za-z_][A-Za-z0-9_.:-]{0,79}$/\n\n/**\n * A console route: one or more path segments, as a nav item's `href` names\n * them. Never a URL, never `..`.\n */\nconst CONTRIBUTION_ROUTE = /^(\\/[A-Za-z0-9_-]+){1,8}$/\n\n/** A prop name a function binding may name: a plain identifier. */\nconst BINDING_PROP = /^[A-Za-z_$][A-Za-z0-9_$]{0,63}$/\n\ntype Sanitized =\n | { ok: true; contributions: PluginContributions }\n | { ok: false; error: string }\n\n/**\n * Validates a declared `contributes` block.\n *\n * Malformed input is REFUSED rather than trimmed: a loader reads this to\n * decide where a plugin runs, so a declaration that silently lost an entry\n * would stop the plugin loading where it is used, and nobody would see why.\n * Duplicates are collapsed and empty lists dropped, because neither changes\n * what the declaration means.\n *\n * `{}` is valid and means \"contributes nothing anywhere\", which is a\n * different statement from an absent block (see the module note).\n */\nexport function sanitizePluginContributions(input: unknown): Sanitized {\n if (!isPlainObject(input)) {\n return { ok: false, error: 'contributes must be an object' }\n }\n const out: PluginContributions = {}\n for (const key of Object.keys(input)) {\n if (key !== 'site' && key !== 'console') {\n return { ok: false, error: `contributes.${key} is not a known surface` }\n }\n }\n\n if (input['site'] !== undefined) {\n const site = input['site']\n if (!isPlainObject(site)) {\n return { ok: false, error: 'contributes.site must be an object' }\n }\n const next: PluginSiteContributions = {}\n for (const key of Object.keys(site)) {\n if (key === 'functionBindings') continue\n if (key !== 'components' && key !== 'features') {\n return { ok: false, error: `contributes.site.${key} is not a known contribution` }\n }\n const list = idList(site[key], `contributes.site.${key}`, CONTRIBUTION_ID)\n if (list.ok === false) return { ok: false, error: list.error }\n if (list.values.length) next[key] = list.values\n }\n if (site['functionBindings'] !== undefined) {\n const bindings = functionBindingMap(\n site['functionBindings'],\n next.components ?? [],\n )\n if (bindings.ok === false) return { ok: false, error: bindings.error }\n if (Object.keys(bindings.value).length) {\n next.functionBindings = bindings.value\n }\n }\n if (Object.keys(next).length) out.site = next\n }\n\n if (input['console'] !== undefined) {\n const consoleInput = input['console']\n if (!isPlainObject(consoleInput)) {\n return { ok: false, error: 'contributes.console must be an object' }\n }\n const next: PluginConsoleContributions = {}\n for (const key of Object.keys(consoleInput)) {\n if (key === 'shell') {\n if (typeof consoleInput['shell'] !== 'boolean') {\n return { ok: false, error: 'contributes.console.shell must be true or false' }\n }\n if (consoleInput['shell']) next.shell = true\n continue\n }\n if (key !== 'slots' && key !== 'routes' && key !== 'orgRoutes') {\n return {\n ok: false,\n error: `contributes.console.${key} is not a known contribution`,\n }\n }\n const list = idList(\n consoleInput[key],\n `contributes.console.${key}`,\n key === 'slots' ? CONTRIBUTION_ID : CONTRIBUTION_ROUTE,\n )\n if (list.ok === false) return { ok: false, error: list.error }\n if (list.values.length) next[key] = list.values\n }\n if (Object.keys(next).length) out.console = next\n }\n\n return { ok: true, contributions: out }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction idList(\n value: unknown,\n where: string,\n pattern: RegExp,\n): { ok: true; values: string[] } | { ok: false; error: string } {\n if (!Array.isArray(value)) return { ok: false, error: `${where} must be a list` }\n if (value.length > PLUGIN_MAX_CONTRIBUTIONS) {\n return { ok: false, error: `${where} lists more than ${PLUGIN_MAX_CONTRIBUTIONS}` }\n }\n const values: string[] = []\n for (const entry of value) {\n if (typeof entry !== 'string' || !pattern.test(entry)) {\n return { ok: false, error: `${where} has an invalid entry \"${String(entry)}\"` }\n }\n if (!values.includes(entry)) values.push(entry)\n }\n return { ok: true, values }\n}\n\n/**\n * `contributes.site.functionBindings`, validated against the components the\n * same block declares: a binding on an element the plugin does not register\n * would hand a function's definition, and the variable values it reads, to\n * whichever element happens to own that id.\n */\nfunction functionBindingMap(\n value: unknown,\n components: readonly string[],\n): { ok: true; value: Record<string, string> } | { ok: false; error: string } {\n const where = 'contributes.site.functionBindings'\n if (!isPlainObject(value)) {\n return { ok: false, error: `${where} must be an object` }\n }\n const entries = Object.entries(value)\n if (entries.length > PLUGIN_MAX_CONTRIBUTIONS) {\n return { ok: false, error: `${where} lists more than ${PLUGIN_MAX_CONTRIBUTIONS}` }\n }\n const out: Record<string, string> = {}\n for (const [componentId, prop] of entries) {\n if (!components.includes(componentId)) {\n return {\n ok: false,\n error: `${where} names \"${componentId}\", which contributes.site.components does not declare`,\n }\n }\n if (typeof prop !== 'string' || !BINDING_PROP.test(prop)) {\n return {\n ok: false,\n error: `${where}.${componentId} must name a prop, not \"${String(prop)}\"`,\n }\n }\n out[componentId] = prop\n }\n return { ok: true, value: out }\n}\n\n/**\n * A declared `contributes` block as a loader may trust it: the sanitized\n * block, or `undefined` for one that is absent or does not validate.\n *\n * Loaders read this from stored documents (a pinned version's manifest), and\n * a malformed stored block is treated as UNDECLARED — the default applies —\n * never as \"contributes nothing\", which would stop a plugin that is in use.\n */\nexport function readPluginContributions(\n input: unknown,\n): PluginContributions | undefined {\n if (input === undefined || input === null) return undefined\n const verdict = sanitizePluginContributions(input)\n return verdict.ok ? verdict.contributions : undefined\n}\n\n/**\n * What the surface a plugin is being registered into actually uses\n * (AGL-3141).\n *\n * The loaders carry this from the surface that computed it to each plugin's\n * register function, unchanged. A plugin that can register a part of itself\n * reads it; one that cannot ignores it, and the platform's behavior is the\n * same either way.\n *\n * An absent field means \"everything of that kind\". A surface that cannot say\n * what it uses must be handed all of it, because an element the surface\n * places and the set omits has no registered component and renders NOTHING,\n * silently (the blank-canvas invariant, AGL-52). Narrowing is an optimization\n * and must fail toward the whole.\n */\nexport interface PluginUse {\n /**\n * Canvas component ids the surface places, read from the FULL composed\n * document the way `pagePresence` reads it — withheld lazy-panel subtrees\n * included, because an element inside a panel the visitor opens later is\n * still this page's element.\n */\n componentIds?: readonly string[]\n}\n\n/** A node as presence reads it: the two ids a placed element carries. */\nexport interface PresenceNode {\n componentId?: string\n pluginId?: string\n}\n\n/** What a published page places: its component ids and the plugin ids stamped on its nodes. */\nexport interface PagePresence {\n componentIds: ReadonlySet<string>\n pluginIds: ReadonlySet<string>\n}\n\n/**\n * The component ids and plugin ids a node tree places.\n *\n * Read from the FULL composed document — layouts, grafted reusable\n * components and withheld lazy panels included — because an element inside\n * a panel the visitor opens later is still this page's element.\n */\nexport function pagePresence(\n nodes: Record<string, PresenceNode | null | undefined> | null | undefined,\n): PagePresence {\n const componentIds = new Set<string>()\n const pluginIds = new Set<string>()\n for (const node of Object.values(nodes ?? {})) {\n if (typeof node?.componentId === 'string' && node.componentId) {\n componentIds.add(node.componentId)\n }\n if (typeof node?.pluginId === 'string' && node.pluginId) {\n pluginIds.add(node.pluginId)\n }\n }\n return { componentIds, pluginIds }\n}\n\n/** A plugin as the presence rules see it. */\nexport interface PresenceSubject {\n /** The plugin's own id (a manifest `id`, or a first-party catalog id). */\n pluginId?: string\n /** A marketplace plugin's listing id, which its elements may carry instead. */\n listingId?: string\n /**\n * A marketplace plugin's identity, `<publisher handle>.<manifest id>`\n * (AGL-3390): the `pluginId` its namespaced elements carry.\n */\n identity?: string\n /** Its declaration; `undefined` when it declares nothing. */\n contributes?: PluginContributions\n}\n\n/**\n * Whether a published page uses a plugin, so the page must load it.\n *\n * - An element of it is placed: a node stamped with the plugin's id, or,\n * for a declared plugin, a node whose component id it declares.\n * - It declares a site feature. The caller only asks about plugins the site\n * has switched on, and a feature runs on every page of such a site.\n *\n * A plugin that declares nothing is present only through its stamped\n * elements — the default in the module note.\n */\nexport function isPluginUsedOnPage(\n subject: PresenceSubject,\n page: PagePresence,\n): boolean {\n if (subject.pluginId && page.pluginIds.has(subject.pluginId)) return true\n if (subject.listingId && page.pluginIds.has(subject.listingId)) return true\n if (subject.identity && page.pluginIds.has(subject.identity)) return true\n const site = subject.contributes?.site\n if (!site) return false\n if (site.features?.length) return true\n return (site.components ?? []).some((id) => page.componentIds.has(id))\n}\n\n/**\n * Whether a plugin declares anything a site draws: an element an author can\n * place, or a feature that runs on the site's pages. The editor loads exactly\n * these (AGL-3391). A plugin that declares nothing is not among them: its\n * site half is only discoverable by running `register()`, and the console\n * shell already does that for it.\n */\nexport function declaresSiteElements(\n contributes: PluginContributions | undefined,\n): boolean {\n const site = contributes?.site\n return Boolean(site?.components?.length || site?.features?.length)\n}\n\n/**\n * Every id a plugin's elements and presets may carry as their `pluginId`: its\n * own id and, for a marketplace plugin, its listing id and its identity. A\n * surface that filters registry entries by plugin set needs all of them, or it\n * hides the elements of a plugin it just loaded.\n */\nexport function presenceIds(subject: PresenceSubject): string[] {\n const ids: string[] = []\n for (const id of [subject.identity, subject.pluginId, subject.listingId]) {\n if (id && !ids.includes(id)) ids.push(id)\n }\n return ids\n}\n\n/**\n * Function bindings (AGL-3393): component id → the prop naming the site\n * function that element runs.\n */\nexport type FunctionBindings = Readonly<Record<string, string>>\n\n/**\n * The function bindings a set of plugins declares, merged into one map.\n *\n * Where two plugins bind the same component id the FIRST one listed wins, so a\n * caller that passes first-party declarations ahead of marketplace ones keeps\n * a marketplace manifest from rebinding a first-party element. Marketplace ids\n * are namespaced by their publisher (see {@link isNamespacedComponentId}), so\n * a collision is a mistake, never a feature.\n */\nexport function mergeFunctionBindings(\n ...sources: ReadonlyArray<\n FunctionBindings | { contributes?: PluginContributions } | null | undefined\n >\n): FunctionBindings {\n const merged: Record<string, string> = {}\n for (const source of sources) {\n if (!source) continue\n const declared: FunctionBindings | undefined =\n 'contributes' in source\n ? (source.contributes as PluginContributions | undefined)?.site\n ?.functionBindings\n : (source as FunctionBindings)\n for (const [componentId, prop] of Object.entries(declared ?? {})) {\n if (typeof prop !== 'string') continue\n if (!Object.prototype.hasOwnProperty.call(merged, componentId)) {\n merged[componentId] = prop\n }\n }\n }\n return merged\n}\n\n/**\n * Whether a component id belongs to a marketplace plugin's namespace\n * (AGL-3387): `<publisher handle>.<plugin id>.<role>`. A `.` is reserved for\n * those ids — no first-party component carries one, which the manifest\n * generator enforces — so compose can tell, without loading anything, that a\n * tree places an element only an installed plugin can declare.\n */\nexport function isNamespacedComponentId(componentId: unknown): boolean {\n return typeof componentId === 'string' && componentId.includes('.')\n}\n\n/**\n * Where a plugin's console code loads, resolved with the default applied: a\n * plugin that declares nothing loads with the shell, as it always did.\n */\nexport interface ConsoleLoadPoints {\n shell: boolean\n slots: readonly string[]\n routes: readonly string[]\n orgRoutes: readonly string[]\n}\n\nexport function consoleLoadPoints(\n contributes: PluginContributions | undefined,\n): ConsoleLoadPoints {\n if (!contributes) return { shell: true, slots: [], routes: [], orgRoutes: [] }\n const declared = contributes.console ?? {}\n return {\n shell: Boolean(declared.shell),\n slots: declared.slots ?? [],\n routes: declared.routes ?? [],\n orgRoutes: declared.orgRoutes ?? [],\n }\n}\n\n/**\n * Whether a declared route serves `href`: the route itself, or a path beneath\n * it on a segment boundary, the way the shell's page resolver matches a nav\n * item that owns its subtree. `/products` serves `/products/orders` and never\n * `/products-archive`.\n */\nexport function routeServes(route: string, href: string): boolean {\n return href === route || href.startsWith(`${route}/`)\n}\n\n/**\n * A place in the console that loads plugins, as the surface drawing it names\n * itself (AGL-3142).\n *\n * - `shell`: the workspace chrome every screen has. It draws whatever a\n * plugin adds to every screen — a nav tab, an organization tab, a staff\n * tab, a provider — so a plugin that declares any of those loads here, and\n * so does one that declares nothing at all.\n * - `slots`: the zones a screen renders. The zones it names, not the plugins\n * it expects in them: a screen must never hold a plugin id.\n * - `route`: the path the reader has open, plugin-relative (`/products`,\n * `/products/orders`), on the level its route tree serves — `site` beneath\n * `/hosts/[host]`, `org` beneath the organization.\n * - `editor`: the Besigner, which draws a site's elements and offers them in\n * its Elements panel (AGL-3391). A plugin loads here when it declares site\n * elements or site features, whether or not the page open uses them, since\n * the author is choosing what to place.\n */\nexport type ConsoleLoadWhere =\n | { at: 'shell' }\n | { at: 'slots'; slots: readonly string[] }\n | { at: 'route'; href: string; level: 'site' | 'org' }\n | { at: 'editor' }\n\n/**\n * Whether a console surface uses a plugin, so it must load it.\n *\n * The console twin of {@link isPluginUsedOnPage}, and the same rule: a\n * declaration says where a plugin's code belongs, and the surface that draws\n * that place is the one that fetches it. A screen asks about the zones it\n * renders and the path it serves; it never asks about a plugin by name.\n *\n * A plugin that declares nothing loads with the shell — the default in the\n * module note, and the reason the shell branch reads\n * {@link consoleLoadPoints} rather than the raw block. Its nav tab or its\n * provider is only discoverable by running `register()`, so narrowing it\n * anywhere else would take a tab away with no way to notice.\n */\nexport function isPluginUsedInConsole(\n contributes: PluginContributions | undefined,\n where: ConsoleLoadWhere,\n): boolean {\n if (where.at === 'editor') return declaresSiteElements(contributes)\n const points = consoleLoadPoints(contributes)\n if (where.at === 'shell') return points.shell\n if (where.at === 'slots') {\n return points.slots.some((slot) => where.slots.includes(slot))\n }\n const routes = where.level === 'org' ? points.orgRoutes : points.routes\n return routes.some((route) => routeServes(route, where.href))\n}\n"],"names":["PLUGIN_MAX_CONTRIBUTIONS","CONTRIBUTION_ID","CONTRIBUTION_ROUTE","BINDING_PROP","sanitizePluginContributions","input","isPlainObject","ok","error","out","key","Object","keys","undefined","site","next","list","idList","values","length","bindings","functionBindingMap","components","value","functionBindings","consoleInput","shell","console","contributions","Boolean","Array","isArray","where","pattern","entry","test","String","includes","push","entries","componentId","prop","readPluginContributions","verdict","pagePresence","nodes","componentIds","Set","pluginIds","node","add","pluginId","isPluginUsedOnPage","subject","page","has","listingId","identity","contributes","features","some","id","declaresSiteElements","presenceIds","ids","mergeFunctionBindings","sources","merged","source","declared","prototype","hasOwnProperty","call","isNamespacedComponentId","consoleLoadPoints","slots","routes","orgRoutes","routeServes","route","href","startsWith","isPluginUsedInConsole","at","points","slot","level"],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * The app offers its boot step, so a reader that finds nobody can run it.
19
+ *
20
+ * Called at boot from the app's own instrumentation, beside the declarations
21
+ * themselves and BEFORE them — this is a plain assignment that cannot fail,
22
+ * and the failure it exists to repair is the one immediately after it.
23
+ *
24
+ * Idempotent and last-one-wins; an app registers exactly once per process.
25
+ */
26
+ export declare function registerPluginDeclarationsRepair(run: () => Promise<void>): void;
27
+ /** Only for specs: forgets the registered boot step. */
28
+ export declare function resetPluginDeclarationsRepairForTests(): void;
29
+ /**
30
+ * Runs the app's boot step, when it offered one. Answers whether one ran.
31
+ *
32
+ * Throws what the step throws; each caller decides what a failed repair
33
+ * costs it. The app's step memoizes its own promise, so this is one attempt
34
+ * per process rather than one per call.
35
+ */
36
+ export declare function runPluginDeclarationsRepair(): Promise<boolean>;
@@ -0,0 +1,64 @@
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
+ * The app's boot-time declarations step, offered to core so a reader that
18
+ * finds a declaration missing can run it (AGL-3080).
19
+ *
20
+ * Every app registers the plugins' declarations from its instrumentation, and
21
+ * wraps that in a `catch` so one bad declaration cannot cost every route. A
22
+ * boot that went wrong therefore leaves a process where whatever the
23
+ * declarations register is silently absent. Core cannot run the step itself:
24
+ * the generated manifest names every plugin, which is the one import core may
25
+ * not make. So the app hands the step over, and a core reader that finds
26
+ * nobody registered runs it and asks again.
27
+ *
28
+ * A leaf with no imports, so a client-safe module (the custom field registry)
29
+ * and a server one (contact capture) can both read it.
30
+ *
31
+ * Held on `globalThis` rather than in a module `let` (AGL-3412): the app
32
+ * offers it from `instrumentation.ts`, which Next compiles into a different
33
+ * module graph from the routes that read it, so a module-scoped slot is set
34
+ * in one copy and read as empty in the other.
35
+ */ const REPAIR_KEY = Symbol.for('@aglyn/aglyn:plugin-declarations-repair');
36
+ const globalScope = globalThis;
37
+ /**
38
+ * The app offers its boot step, so a reader that finds nobody can run it.
39
+ *
40
+ * Called at boot from the app's own instrumentation, beside the declarations
41
+ * themselves and BEFORE them — this is a plain assignment that cannot fail,
42
+ * and the failure it exists to repair is the one immediately after it.
43
+ *
44
+ * Idempotent and last-one-wins; an app registers exactly once per process.
45
+ */ export function registerPluginDeclarationsRepair(run) {
46
+ globalScope[REPAIR_KEY] = run;
47
+ }
48
+ /** Only for specs: forgets the registered boot step. */ export function resetPluginDeclarationsRepairForTests() {
49
+ globalScope[REPAIR_KEY] = null;
50
+ }
51
+ /**
52
+ * Runs the app's boot step, when it offered one. Answers whether one ran.
53
+ *
54
+ * Throws what the step throws; each caller decides what a failed repair
55
+ * costs it. The app's step memoizes its own promise, so this is one attempt
56
+ * per process rather than one per call.
57
+ */ export async function runPluginDeclarationsRepair() {
58
+ const repair = globalScope[REPAIR_KEY];
59
+ if (!repair) return false;
60
+ await repair();
61
+ return true;
62
+ }
63
+
64
+ //# sourceMappingURL=plugin-declarations-repair.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-declarations-repair.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 * The app's boot-time declarations step, offered to core so a reader that\n * finds a declaration missing can run it (AGL-3080).\n *\n * Every app registers the plugins' declarations from its instrumentation, and\n * wraps that in a `catch` so one bad declaration cannot cost every route. A\n * boot that went wrong therefore leaves a process where whatever the\n * declarations register is silently absent. Core cannot run the step itself:\n * the generated manifest names every plugin, which is the one import core may\n * not make. So the app hands the step over, and a core reader that finds\n * nobody registered runs it and asks again.\n *\n * A leaf with no imports, so a client-safe module (the custom field registry)\n * and a server one (contact capture) can both read it.\n *\n * Held on `globalThis` rather than in a module `let` (AGL-3412): the app\n * offers it from `instrumentation.ts`, which Next compiles into a different\n * module graph from the routes that read it, so a module-scoped slot is set\n * in one copy and read as empty in the other.\n */\nconst REPAIR_KEY = Symbol.for('@aglyn/aglyn:plugin-declarations-repair')\n\nconst globalScope = globalThis as typeof globalThis & {\n [REPAIR_KEY]?: (() => Promise<void>) | null\n}\n\n/**\n * The app offers its boot step, so a reader that finds nobody can run it.\n *\n * Called at boot from the app's own instrumentation, beside the declarations\n * themselves and BEFORE them — this is a plain assignment that cannot fail,\n * and the failure it exists to repair is the one immediately after it.\n *\n * Idempotent and last-one-wins; an app registers exactly once per process.\n */\nexport function registerPluginDeclarationsRepair(run: () => Promise<void>): void {\n globalScope[REPAIR_KEY] = run\n}\n\n/** Only for specs: forgets the registered boot step. */\nexport function resetPluginDeclarationsRepairForTests(): void {\n globalScope[REPAIR_KEY] = null\n}\n\n/**\n * Runs the app's boot step, when it offered one. Answers whether one ran.\n *\n * Throws what the step throws; each caller decides what a failed repair\n * costs it. The app's step memoizes its own promise, so this is one attempt\n * per process rather than one per call.\n */\nexport async function runPluginDeclarationsRepair(): Promise<boolean> {\n const repair = globalScope[REPAIR_KEY]\n if (!repair) return false\n await repair()\n return true\n}\n"],"names":["REPAIR_KEY","Symbol","for","globalScope","globalThis","registerPluginDeclarationsRepair","run","resetPluginDeclarationsRepairForTests","runPluginDeclarationsRepair","repair"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;;CAmBC,GACD,MAAMA,aAAaC,OAAOC,GAAG,CAAC;AAE9B,MAAMC,cAAcC;AAIpB;;;;;;;;CAQC,GACD,OAAO,SAASC,iCAAiCC,GAAwB;IACvEH,WAAW,CAACH,WAAW,GAAGM;AAC5B;AAEA,sDAAsD,GACtD,OAAO,SAASC;IACdJ,WAAW,CAACH,WAAW,GAAG;AAC5B;AAEA;;;;;;CAMC,GACD,OAAO,eAAeQ;IACpB,MAAMC,SAASN,WAAW,CAACH,WAAW;IACtC,IAAI,CAACS,QAAQ,OAAO;IACpB,MAAMA;IACN,OAAO;AACT"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import type { BindingRefVia } from '../app-utils/binding-tokens';
18
+ /**
19
+ * WHAT DEPENDS ON A THING, answered by the plugins whose records refer to it.
20
+ *
21
+ * The "Used by" scan (`/api/hosts/where-used`) tells a person what they would
22
+ * break by deleting or renaming one of a site's things — a variable, a
23
+ * function, a workflow. What refers to it from a published page is the
24
+ * platform's to find: the scan reads the published screens and layouts
25
+ * itself. What refers to it from inside a plugin's records — a step that
26
+ * calls a function, a variable whose value is computed from somewhere else —
27
+ * is that plugin's: its storage, its field names, and its rule for what
28
+ * counts as a reference.
29
+ *
30
+ * So a plugin that keeps referring records registers a DEPENDENTS SOURCE: the
31
+ * kinds of thing it finds references to, and a `find` that answers the
32
+ * referring records of one site. The scan asks every source registered for
33
+ * the kind and lists what they answer beside its own findings. That is also
34
+ * how one plugin learns what another plugin's records need of its own: the
35
+ * owner of a thing asks the scan, and whichever plugin keeps the references
36
+ * answers, with neither importing the other.
37
+ *
38
+ * Its siblings: `plugin-record-index` lists a plugin's records for another
39
+ * surface to work on; this answers which of them point at something.
40
+ *
41
+ * ## Not registered is an answer; failing is not
42
+ *
43
+ * No source for a kind means no plugin keeps records that refer to one in
44
+ * this process, and the answer is complete. A source that THROWS is a scan
45
+ * that did not finish: its answer is marked incomplete, exactly as a scan
46
+ * that stopped at its read cap is, so "nothing uses this" is never said on
47
+ * the strength of a reader that failed.
48
+ */
49
+ /** One record that refers to the thing asked about. */
50
+ export interface PluginDependent {
51
+ /** What kind of record refers to it, in the words the scan lists it under ("variable"). */
52
+ type: string;
53
+ id: string;
54
+ /** What a person calls it. */
55
+ name: string;
56
+ /**
57
+ * How it refers: `id` survives a rename, `name` is a name reference a
58
+ * rename breaks. Both when the record carries both and both match.
59
+ */
60
+ via: BindingRefVia[];
61
+ }
62
+ /** The thing a scan asks about, on one site. */
63
+ export interface PluginDependentsRequest {
64
+ hostId: string;
65
+ /** What kind of thing it is: "function", "workflow". */
66
+ kind: string;
67
+ /** Its document id. */
68
+ id: string;
69
+ /** Its current name, for records that refer to it by name. */
70
+ name?: string;
71
+ }
72
+ export interface PluginDependentsAnswer {
73
+ dependents: PluginDependent[];
74
+ /** The source read less than all of its records, so more may refer to it. */
75
+ truncated: boolean;
76
+ }
77
+ export interface PluginDependentsSource {
78
+ /** The kinds of thing this source finds references to. */
79
+ kinds: readonly string[];
80
+ find(request: PluginDependentsRequest): Promise<PluginDependentsAnswer>;
81
+ }
82
+ export declare const PLUGIN_DEPENDENTS_SOURCES: import("./plugin-services").PluginServiceContract<PluginDependentsSource>;
83
+ /**
84
+ * Registers a plugin's dependents source. The owner is the loader's marker
85
+ * when a register fn is running, else `options.pluginId`; with neither the
86
+ * registration throws. A plugin registering several sources tells them apart
87
+ * with `key`; registering the same key again replaces it in place.
88
+ */
89
+ export declare function registerPluginDependentsSource(source: PluginDependentsSource, options?: {
90
+ pluginId?: string;
91
+ key?: string;
92
+ }): void;
93
+ /**
94
+ * Every dependent the registered sources answer for one thing, in
95
+ * registration order, and whether the answer is COMPLETE: `false` when any
96
+ * source read only part of its records or failed to answer at all.
97
+ */
98
+ export declare function findPluginDependents(request: PluginDependentsRequest): Promise<{
99
+ dependents: PluginDependent[];
100
+ complete: boolean;
101
+ }>;
@@ -0,0 +1,75 @@
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 { _ as _extends } from "@swc/helpers/_/_extends";
17
+ import { getRegisteringPluginId } from "../app-utils/registering-plugin.js";
18
+ import { definePluginServiceContract, registerPluginService, resolvePluginServices } from "./plugin-services.js";
19
+ export const PLUGIN_DEPENDENTS_SOURCES = definePluginServiceContract('core.dependents-source', {
20
+ multiple: true
21
+ });
22
+ /**
23
+ * Registers a plugin's dependents source. The owner is the loader's marker
24
+ * when a register fn is running, else `options.pluginId`; with neither the
25
+ * registration throws. A plugin registering several sources tells them apart
26
+ * with `key`; registering the same key again replaces it in place.
27
+ */ export function registerPluginDependentsSource(source, options) {
28
+ var _ref, _getRegisteringPluginId, _ref1;
29
+ const pluginId = ((_ref = (_getRegisteringPluginId = getRegisteringPluginId()) != null ? _getRegisteringPluginId : options == null ? void 0 : options.pluginId) != null ? _ref : '').trim();
30
+ if (!pluginId) {
31
+ throw new Error('a dependents source was registered with no owner');
32
+ }
33
+ const kinds = source.kinds.map((kind)=>kind.trim()).filter(Boolean);
34
+ if (!kinds.length) {
35
+ throw new Error(`the dependents source of "${pluginId}" names no kind it answers for`);
36
+ }
37
+ registerPluginService(PLUGIN_DEPENDENTS_SOURCES, source, {
38
+ pluginId,
39
+ key: (_ref1 = options == null ? void 0 : options.key) != null ? _ref1 : kinds.join(',')
40
+ });
41
+ }
42
+ /**
43
+ * Every dependent the registered sources answer for one thing, in
44
+ * registration order, and whether the answer is COMPLETE: `false` when any
45
+ * source read only part of its records or failed to answer at all.
46
+ */ export async function findPluginDependents(request) {
47
+ const kind = request.kind.trim();
48
+ const sources = resolvePluginServices(PLUGIN_DEPENDENTS_SOURCES).filter((entry)=>entry.impl.kinds.some((one)=>one.trim() === kind));
49
+ const answers = await Promise.all(sources.map(async ({ pluginId, impl })=>{
50
+ try {
51
+ return await impl.find(_extends({}, request, {
52
+ kind
53
+ }));
54
+ } catch (error) {
55
+ console.error(`dependents source of "${pluginId}" failed for a ${kind}`, error);
56
+ return null;
57
+ }
58
+ }));
59
+ const dependents = [];
60
+ let complete = true;
61
+ for (const answer of answers){
62
+ if (!answer) {
63
+ complete = false;
64
+ continue;
65
+ }
66
+ if (answer.truncated) complete = false;
67
+ dependents.push(...answer.dependents);
68
+ }
69
+ return {
70
+ dependents,
71
+ complete
72
+ };
73
+ }
74
+
75
+ //# sourceMappingURL=plugin-dependents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-dependents.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { BindingRefVia } from '../app-utils/binding-tokens'\nimport { getRegisteringPluginId } from '../app-utils/registering-plugin'\nimport {\n definePluginServiceContract,\n registerPluginService,\n resolvePluginServices,\n} from './plugin-services'\n\n/**\n * WHAT DEPENDS ON A THING, answered by the plugins whose records refer to it.\n *\n * The \"Used by\" scan (`/api/hosts/where-used`) tells a person what they would\n * break by deleting or renaming one of a site's things — a variable, a\n * function, a workflow. What refers to it from a published page is the\n * platform's to find: the scan reads the published screens and layouts\n * itself. What refers to it from inside a plugin's records — a step that\n * calls a function, a variable whose value is computed from somewhere else —\n * is that plugin's: its storage, its field names, and its rule for what\n * counts as a reference.\n *\n * So a plugin that keeps referring records registers a DEPENDENTS SOURCE: the\n * kinds of thing it finds references to, and a `find` that answers the\n * referring records of one site. The scan asks every source registered for\n * the kind and lists what they answer beside its own findings. That is also\n * how one plugin learns what another plugin's records need of its own: the\n * owner of a thing asks the scan, and whichever plugin keeps the references\n * answers, with neither importing the other.\n *\n * Its siblings: `plugin-record-index` lists a plugin's records for another\n * surface to work on; this answers which of them point at something.\n *\n * ## Not registered is an answer; failing is not\n *\n * No source for a kind means no plugin keeps records that refer to one in\n * this process, and the answer is complete. A source that THROWS is a scan\n * that did not finish: its answer is marked incomplete, exactly as a scan\n * that stopped at its read cap is, so \"nothing uses this\" is never said on\n * the strength of a reader that failed.\n */\n\n/** One record that refers to the thing asked about. */\nexport interface PluginDependent {\n /** What kind of record refers to it, in the words the scan lists it under (\"variable\"). */\n type: string\n id: string\n /** What a person calls it. */\n name: string\n /**\n * How it refers: `id` survives a rename, `name` is a name reference a\n * rename breaks. Both when the record carries both and both match.\n */\n via: BindingRefVia[]\n}\n\n/** The thing a scan asks about, on one site. */\nexport interface PluginDependentsRequest {\n hostId: string\n /** What kind of thing it is: \"function\", \"workflow\". */\n kind: string\n /** Its document id. */\n id: string\n /** Its current name, for records that refer to it by name. */\n name?: string\n}\n\nexport interface PluginDependentsAnswer {\n dependents: PluginDependent[]\n /** The source read less than all of its records, so more may refer to it. */\n truncated: boolean\n}\n\nexport interface PluginDependentsSource {\n /** The kinds of thing this source finds references to. */\n kinds: readonly string[]\n find(request: PluginDependentsRequest): Promise<PluginDependentsAnswer>\n}\n\nexport const PLUGIN_DEPENDENTS_SOURCES = definePluginServiceContract<PluginDependentsSource>(\n 'core.dependents-source',\n { multiple: true },\n)\n\n/**\n * Registers a plugin's dependents source. The owner is the loader's marker\n * when a register fn is running, else `options.pluginId`; with neither the\n * registration throws. A plugin registering several sources tells them apart\n * with `key`; registering the same key again replaces it in place.\n */\nexport function registerPluginDependentsSource(\n source: PluginDependentsSource,\n options?: { pluginId?: string; key?: string },\n): void {\n const pluginId = (getRegisteringPluginId() ?? options?.pluginId ?? '').trim()\n if (!pluginId) {\n throw new Error('a dependents source was registered with no owner')\n }\n const kinds = source.kinds.map((kind) => kind.trim()).filter(Boolean)\n if (!kinds.length) {\n throw new Error(`the dependents source of \"${pluginId}\" names no kind it answers for`)\n }\n registerPluginService(PLUGIN_DEPENDENTS_SOURCES, source, {\n pluginId,\n key: options?.key ?? kinds.join(','),\n })\n}\n\n/**\n * Every dependent the registered sources answer for one thing, in\n * registration order, and whether the answer is COMPLETE: `false` when any\n * source read only part of its records or failed to answer at all.\n */\nexport async function findPluginDependents(\n request: PluginDependentsRequest,\n): Promise<{ dependents: PluginDependent[]; complete: boolean }> {\n const kind = request.kind.trim()\n const sources = resolvePluginServices(PLUGIN_DEPENDENTS_SOURCES).filter((entry) =>\n entry.impl.kinds.some((one) => one.trim() === kind),\n )\n const answers = await Promise.all(\n sources.map(async ({ pluginId, impl }) => {\n try {\n return await impl.find({ ...request, kind })\n } catch (error) {\n console.error(`dependents source of \"${pluginId}\" failed for a ${kind}`, error)\n return null\n }\n }),\n )\n const dependents: PluginDependent[] = []\n let complete = true\n for (const answer of answers) {\n if (!answer) {\n complete = false\n continue\n }\n if (answer.truncated) complete = false\n dependents.push(...answer.dependents)\n }\n return { dependents, complete }\n}\n"],"names":["getRegisteringPluginId","definePluginServiceContract","registerPluginService","resolvePluginServices","PLUGIN_DEPENDENTS_SOURCES","multiple","registerPluginDependentsSource","source","options","pluginId","trim","Error","kinds","map","kind","filter","Boolean","length","key","join","findPluginDependents","request","sources","entry","impl","some","one","answers","Promise","all","find","error","console","dependents","complete","answer","truncated","push"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC;AAGD,SAASA,sBAAsB,QAAQ,qCAAiC;AACxE,SACEC,2BAA2B,EAC3BC,qBAAqB,EACrBC,qBAAqB,QAChB,uBAAmB;AAuE1B,OAAO,MAAMC,4BAA4BH,4BACvC,0BACA;IAAEI,UAAU;AAAK,GAClB;AAED;;;;;CAKC,GACD,OAAO,SAASC,+BACdC,MAA8B,EAC9BC,OAA6C;QAE3BR,MAAAA;IAAlB,MAAMS,WAAW,EAACT,QAAAA,0BAAAA,oCAAAA,0BAA4BQ,2BAAAA,QAASC,QAAQ,YAA7CT,OAAiD,IAAIU,IAAI;IAC3E,IAAI,CAACD,UAAU;QACb,MAAM,IAAIE,MAAM;IAClB;IACA,MAAMC,QAAQL,OAAOK,KAAK,CAACC,GAAG,CAAC,CAACC,OAASA,KAAKJ,IAAI,IAAIK,MAAM,CAACC;IAC7D,IAAI,CAACJ,MAAMK,MAAM,EAAE;QACjB,MAAM,IAAIN,MAAM,CAAC,0BAA0B,EAAEF,SAAS,8BAA8B,CAAC;IACvF;IACAP,sBAAsBE,2BAA2BG,QAAQ;QACvDE;QACAS,GAAG,WAAEV,2BAAAA,QAASU,GAAG,oBAAIN,MAAMO,IAAI,CAAC;IAClC;AACF;AAEA;;;;CAIC,GACD,OAAO,eAAeC,qBACpBC,OAAgC;IAEhC,MAAMP,OAAOO,QAAQP,IAAI,CAACJ,IAAI;IAC9B,MAAMY,UAAUnB,sBAAsBC,2BAA2BW,MAAM,CAAC,CAACQ,QACvEA,MAAMC,IAAI,CAACZ,KAAK,CAACa,IAAI,CAAC,CAACC,MAAQA,IAAIhB,IAAI,OAAOI;IAEhD,MAAMa,UAAU,MAAMC,QAAQC,GAAG,CAC/BP,QAAQT,GAAG,CAAC,OAAO,EAAEJ,QAAQ,EAAEe,IAAI,EAAE;QACnC,IAAI;YACF,OAAO,MAAMA,KAAKM,IAAI,CAAC,aAAKT;gBAASP;;QACvC,EAAE,OAAOiB,OAAO;YACdC,QAAQD,KAAK,CAAC,CAAC,sBAAsB,EAAEtB,SAAS,eAAe,EAAEK,MAAM,EAAEiB;YACzE,OAAO;QACT;IACF;IAEF,MAAME,aAAgC,EAAE;IACxC,IAAIC,WAAW;IACf,KAAK,MAAMC,UAAUR,QAAS;QAC5B,IAAI,CAACQ,QAAQ;YACXD,WAAW;YACX;QACF;QACA,IAAIC,OAAOC,SAAS,EAAEF,WAAW;QACjCD,WAAWI,IAAI,IAAIF,OAAOF,UAAU;IACtC;IACA,OAAO;QAAEA;QAAYC;IAAS;AAChC"}
@@ -0,0 +1,55 @@
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
+ * Where published third-party plugin versions and their kill switches are
19
+ * stored, declared by the plugin that publishes them (AGL-3080).
20
+ *
21
+ * The realm loader is the platform's: it joins a workspace's install pins
22
+ * with the version each pin names, keeps only a version carrying the
23
+ * platform's trust grant, and drops one a kill switch has stopped. The
24
+ * documents it joins against are the distributing plugin's — a version is
25
+ * written under that plugin's listing when it is published, and its kill
26
+ * switch when staff revoke it. So the loader asks this declaration where they
27
+ * are, and names no plugin's collection itself.
28
+ *
29
+ * ## Compiled, never registered
30
+ *
31
+ * Every reader is a security gate on a server path that loads no plugin code:
32
+ * the published page's plugin join, both apps' remote server-bundle loaders,
33
+ * the console's realm gate. A runtime registry one of them had not filled
34
+ * would answer "nowhere" — and "nowhere" must mean "nothing loads", which is
35
+ * only safe because it is also what an unfilled registry would say. That is
36
+ * the AGL-3025 shape one step from the kill switch, so the plugin declares
37
+ * this as data in `plugins.config.json` and the generator compiles it.
38
+ *
39
+ * ## Absent is closed
40
+ *
41
+ * With no distributing plugin, {@link PLUGIN_DISTRIBUTION} is `null`, and
42
+ * every reader fails CLOSED: no version resolves, and every pin reads as
43
+ * revoked. A pin with no store to check it against cannot be vouched for.
44
+ */
45
+ export interface PluginDistribution {
46
+ /** The plugin that declared it. */
47
+ pluginId: string;
48
+ /** The top-level collection of listings, keyed by the id an install pins. */
49
+ listings: string;
50
+ /** The subcollection of a listing holding one document per version. */
51
+ versions: string;
52
+ /** The top-level collection of kill switches, keyed by the listing id. */
53
+ revocations: string;
54
+ }
55
+ export { PLUGIN_DISTRIBUTION } from './first-party-plugins.generated';