@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
@@ -19,11 +19,14 @@ import { _ as _extends } from "@swc/helpers/_/_extends";
19
19
  // it, the console's seed route materializes them, and the AI plugin's server
20
20
  // shows them to a model — and neither barrel works in both: the full
21
21
  // `@aglyn/aglyn` barrel breaks the RSC/server-route graph, while the server
22
- // entry drags `node:fs` into the client bundle. The canvas constants are a
23
- // leaf with no imports of their own, and `screen-route` imports only a TYPE
24
- // from foundation, so both are safe on either side.
25
- import { CANVAS_ROOT_ELEMENT_ID } from "../foundation/constants/canvas.js";
22
+ // entry drags `node:fs` into the client bundle. The starter kit imports only
23
+ // the canvas constants, a leaf with no imports of their own; the compiled
24
+ // plugin starters are data behind a type-only import; and `screen-route`
25
+ // imports only a TYPE from foundation — so all three are safe on either side.
26
+ import { PLUGIN_STARTER_TEMPLATES } from "./plugin-starter-templates.generated.js";
26
27
  import { normalizeScreenSlug, SCREEN_ROOT_PATH } from "./screen-route.js";
28
+ import { buildStarterNodes as buildNodes, starterHeroSection as heroSection, starterSection as section, starterText as text } from "./starter-template-nodes.js";
29
+ export { buildStarterNodes, starterHeroSection, starterSection, starterText } from "./starter-template-nodes.js";
27
30
  /**
28
31
  * Deterministic document id for a seeded starter screen (AGL-687).
29
32
  *
@@ -79,112 +82,6 @@ import { normalizeScreenSlug, SCREEN_ROOT_PATH } from "./screen-route.js";
79
82
  /** Every document a starter COULD materialize as, in bundle order. */ export function buildAllStarterTemplateDocs() {
80
83
  return STARTER_TEMPLATES.flatMap(buildStarterTemplateDocs);
81
84
  }
82
- /** Builds the flat, persisted node map from a nested spec. */ function buildNodes(children) {
83
- const map = {
84
- [CANVAS_ROOT_ELEMENT_ID]: {
85
- $id: CANVAS_ROOT_ELEMENT_ID,
86
- componentId: 'div',
87
- nodes: children.map((child)=>child.id)
88
- }
89
- };
90
- const walk = (spec, parentId)=>{
91
- var _spec_pluginId, _spec_props, _spec_children, _spec_children1;
92
- map[spec.id] = _extends({
93
- $id: spec.id,
94
- componentId: spec.componentId,
95
- pluginId: (_spec_pluginId = spec.pluginId) != null ? _spec_pluginId : 'mui',
96
- parentId,
97
- props: (_spec_props = spec.props) != null ? _spec_props : {}
98
- }, spec.sx ? {
99
- sx: spec.sx
100
- } : {}, {
101
- nodes: ((_spec_children = spec.children) != null ? _spec_children : []).map((child)=>child.id)
102
- });
103
- for (const child of (_spec_children1 = spec.children) != null ? _spec_children1 : [])walk(child, spec.id);
104
- };
105
- for (const child of children)walk(child, CANVAS_ROOT_ELEMENT_ID);
106
- return map;
107
- }
108
- const text = (id, variant, children, extra)=>({
109
- id,
110
- componentId: 'muiTypography',
111
- props: _extends({
112
- variant,
113
- children
114
- }, extra)
115
- });
116
- /**
117
- * One page band: a `Container` at a stock width, carrying the band's own
118
- * vertical rhythm (AGL-1932).
119
- *
120
- * The layout standard (AGL-1298): every section is a Container. Full-bleed is
121
- * the Container's own full-width attribute, never the absence of a Container,
122
- * and anything else is one of three stock widths. A template that seeds no
123
- * Container hands every customer a site that starts outside the standard.
124
- *
125
- * How the three widths are chosen here, stated so the next audit does not
126
- * have to guess:
127
- *
128
- * - `xl` — a marketing band: hero, feature row, product grid, gallery. The
129
- * default width, and what an unremarkable page should be.
130
- * - `lg` — the deliberate middle case: wide but text-led and interactive.
131
- * Cart and account are the honest instances, not decoration.
132
- * - `md` — long-form prose and narrow form columns, on READING grounds: at
133
- * `xl` a paragraph runs 110–120 characters a line. This is the case the
134
- * `Prose Container` preset exists for.
135
- *
136
- * Horizontal padding is the Container's own gutters, so bands no longer carry
137
- * horizontal padding at all. Only the vertical rhythm rides here, which is
138
- * rhythm rather than width.
139
- *
140
- * Written as the two longhands rather than MUI's `py` (AGL-2207/2208): the
141
- * Styles panel's Padding control is named for the four sides, so a band
142
- * seeded with `py` handed the customer a document whose padding the panel
143
- * showed as empty and no click could clear.
144
- */ const section = (id, maxWidth, verticalPadding, children)=>({
145
- id,
146
- componentId: 'muiContainer',
147
- props: {
148
- maxWidth
149
- },
150
- sx: {
151
- paddingTop: verticalPadding,
152
- paddingBottom: verticalPadding
153
- },
154
- children
155
- });
156
- const heroSection = (prefix, headline, tagline)=>// The Container is a NEW node (`…heroSection`); `…hero` keeps its id and
157
- // stays the Stack. Node ids here are persisted identifiers, so bands are
158
- // wrapped rather than re-pointed.
159
- section(`${prefix}heroSection`, 'xl', 10, [
160
- {
161
- id: `${prefix}hero`,
162
- componentId: 'muiStack',
163
- props: {
164
- spacing: 2
165
- },
166
- sx: {
167
- alignItems: 'center'
168
- },
169
- children: [
170
- text(`${prefix}heroTitle`, 'h2', headline, {
171
- align: 'center'
172
- }),
173
- text(`${prefix}heroSub`, 'h6', tagline, {
174
- align: 'center'
175
- }),
176
- {
177
- id: `${prefix}heroCta`,
178
- componentId: 'muiButton',
179
- props: {
180
- variant: 'contained',
181
- size: 'large',
182
- children: 'Get in touch'
183
- }
184
- }
185
- ]
186
- }
187
- ]);
188
85
  const featureColumn = (id, title, body)=>({
189
86
  id,
190
87
  componentId: 'muiStack',
@@ -245,111 +142,6 @@ const contactForm = (prefix)=>({
245
142
  }
246
143
  ]
247
144
  });
248
- const commerceBlock = (id, componentId, props)=>({
249
- id,
250
- componentId,
251
- pluginId: 'commerce',
252
- props
253
- });
254
- /** Shared screens for the shop starters (AGL-300). */ function shopScreens(prefix, digital) {
255
- return [
256
- {
257
- key: 'home',
258
- displayName: 'Home',
259
- // The site root, spelled the way the routing map spells it. `''` here
260
- // read as "no address" everywhere downstream and put the shop's home
261
- // page at `/home` (AGL-1575).
262
- slug: SCREEN_ROOT_PATH,
263
- seo: {
264
- title: digital ? 'Digital shop' : 'Shop',
265
- description: 'Browse our products.'
266
- },
267
- nodes: buildNodes([
268
- heroSection(`${prefix}h_`, digital ? 'Downloads that level you up' : 'Gear you can trust', digital ? 'Instant delivery. Lifetime updates.' : 'Quality parts, shipped fast.'),
269
- section(`${prefix}h_gridSection`, 'xl', 6, [
270
- commerceBlock(`${prefix}h_grid`, 'product-grid', {
271
- source: 'all',
272
- sort: 'newest',
273
- columns: 3,
274
- maxItems: 6
275
- })
276
- ]),
277
- // A newsletter capture is a short text-led band, not a gallery.
278
- section(`${prefix}h_newsSection`, 'md', 6, [
279
- commerceBlock(`${prefix}h_news`, 'newsletter-signup', {
280
- heading: 'Get updates and offers'
281
- })
282
- ])
283
- ])
284
- },
285
- {
286
- key: 'shop',
287
- displayName: 'Shop',
288
- slug: 'shop',
289
- seo: {
290
- title: 'All products'
291
- },
292
- nodes: buildNodes([
293
- section(`${prefix}s_section`, 'xl', 6, [
294
- text(`${prefix}s_title`, 'h3', 'All products'),
295
- commerceBlock(`${prefix}s_grid`, 'product-grid', {
296
- source: 'all',
297
- columns: 4,
298
- showFilters: true
299
- })
300
- ])
301
- ])
302
- },
303
- {
304
- key: 'product',
305
- displayName: 'Product page',
306
- slug: 'product',
307
- seo: {
308
- title: 'Product'
309
- },
310
- nodes: buildNodes([
311
- section(`${prefix}p_section`, 'xl', 6, [
312
- commerceBlock(`${prefix}p_detail`, 'product-detail', {})
313
- ])
314
- ])
315
- },
316
- {
317
- key: 'cart',
318
- displayName: 'Cart',
319
- slug: 'cart',
320
- seo: {
321
- title: 'Your cart'
322
- },
323
- // LG, the deliberate middle case: a cart is a wide table but it is read
324
- // line by line, so a full XL band spreads it further than the eye
325
- // tracks. Same for the account screen below.
326
- nodes: buildNodes([
327
- section(`${prefix}c_section`, 'lg', 6, [
328
- text(`${prefix}c_title`, 'h3', 'Your cart'),
329
- commerceBlock(`${prefix}c_cart`, 'cart', {
330
- variant: 'inline',
331
- showCoupon: true
332
- })
333
- ])
334
- ])
335
- },
336
- {
337
- key: 'account',
338
- displayName: 'Account',
339
- slug: 'account',
340
- seo: {
341
- title: 'Your account'
342
- },
343
- nodes: buildNodes([
344
- section(`${prefix}a_section`, 'lg', 6, [
345
- commerceBlock(`${prefix}a_account`, 'customer-account', {
346
- signedOutHeading: 'Your account'
347
- })
348
- ])
349
- ])
350
- }
351
- ];
352
- }
353
145
  /**
354
146
  * The home page every new site is born with (AGL-3408).
355
147
  *
@@ -399,7 +191,7 @@ const commerceBlock = (id, componentId, props)=>({
399
191
  ])
400
192
  };
401
193
  }
402
- export const STARTER_TEMPLATES = [
194
+ /** The platform's own starters, which name no plugin's elements. */ const PLATFORM_STARTER_TEMPLATES = [
403
195
  {
404
196
  id: 'landing',
405
197
  displayName: 'Landing Page',
@@ -608,21 +400,18 @@ export const STARTER_TEMPLATES = [
608
400
  ])
609
401
  }
610
402
  ]
611
- },
612
- {
613
- id: 'physical-shop',
614
- displayName: 'Shop (physical products)',
615
- description: 'Storefront starter: home with featured products, filterable shop, ' + 'product page, cart, and customer accounts. After applying, set the ' + 'Product page as the product template in Store settings.',
616
- category: 'Commerce',
617
- screens: shopScreens('ps_', false)
618
- },
619
- {
620
- id: 'digital-shop',
621
- displayName: 'Shop (digital products)',
622
- description: 'Digital storefront starter: downloads-focused home, shop, product ' + 'page, cart, and accounts with a newsletter capture. Set the Product ' + 'page as the product template in Store settings after applying.',
623
- category: 'Commerce',
624
- screens: shopScreens('ds_', true)
625
403
  }
626
404
  ];
405
+ /**
406
+ * Every starter in this build, in gallery order: the platform's own, then
407
+ * each plugin's in config order (AGL-3080). A plugin whose elements a starter
408
+ * is built around — a storefront's product grid and cart — declares it under
409
+ * `starterTemplates` in plugins.config.json, and the manifest generator
410
+ * compiles what it returns, so the gallery, the seed route and a model
411
+ * shown examples all read one list without loading any plugin.
412
+ */ export const STARTER_TEMPLATES = [
413
+ ...PLATFORM_STARTER_TEMPLATES,
414
+ ...PLUGIN_STARTER_TEMPLATES
415
+ ];
627
416
 
628
417
  //# sourceMappingURL=starter-templates.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/starter-templates.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// Leaf imports only, deliberately (AGL-687). This module is imported from\n// BOTH graphs — the console's client gallery renders virtual starters from\n// it, the console's seed route materializes them, and the AI plugin's server\n// shows them to a model — and neither barrel works in both: the full\n// `@aglyn/aglyn` barrel breaks the RSC/server-route graph, while the server\n// entry drags `node:fs` into the client bundle. The canvas constants are a\n// leaf with no imports of their own, and `screen-route` imports only a TYPE\n// from foundation, so both are safe on either side.\nimport { CANVAS_ROOT_ELEMENT_ID } from '../foundation/constants/canvas'\nimport { normalizeScreenSlug, SCREEN_ROOT_PATH } from './screen-route'\n\n/**\n * First-party starter definitions (AGL-78/79), SEED INPUT (AGL-687).\n *\n * These used to be rendered straight into the gallery and instantiated from\n * code, which made a starter a second kind of template: no version history,\n * no placeholders, no editor, changeable only by shipping a release. Now\n * they are seeded into each host's own template library as ordinary\n * `hosts/{hostId}/templates` documents (see the console's\n * `utils/server/seed-starter-templates.ts` for why copy-on-use rather than a\n * global read-only collection), and nothing reads this file at render time.\n *\n * They are also the page examples the AI plugin's template generator shows a\n * model (AGL-2909), which is why they live in the core package rather than\n * beside the console gallery that renders them.\n *\n * Node ids stay template-local (unique within each screen's version doc);\n * `createPageFromTemplate` re-keys screen and version ids at instantiation.\n *\n * PERSISTED IDENTIFIERS: `StarterTemplate.id`, `StarterTemplateScreen.key`\n * and every node id below appear in stored documents (seeded template doc\n * ids are derived from the first two). They must never be renamed.\n */\nexport interface StarterTemplateScreen {\n /**\n * Stable, starter-local key. Part of the seeded document id, so it is a\n * persisted identifier — never rename one.\n */\n key: string\n displayName: string\n description?: string\n /**\n * Routing-map slug. `SCREEN_ROOT_PATH` (`'/'`) asks for the site root — the\n * home page — and anything else is a single path segment.\n *\n * It used to be `''` that meant home, which no normalizer agreed with: both\n * the apply path and the seed below read an empty string as \"no address\n * authored\" and derived one from the display name, so the shop starters'\n * home page was published at `/home` and the site 404'd at its own URL\n * (AGL-1575).\n */\n slug: string\n seo?: { title?: string; description?: string }\n /** Flat node map including the canvas root. */\n nodes: Record<string, any>\n}\n\nexport interface StarterTemplate {\n id: string\n displayName: string\n description: string\n category: string\n screens: StarterTemplateScreen[]\n}\n\n/** A materialized starter template document, keyed by its deterministic id. */\nexport interface StarterTemplateDoc {\n id: string\n /** Which starter this page belongs to — lets one starter be selected. */\n starterId: string\n data: Record<string, unknown>\n}\n\n/**\n * Deterministic document id for a seeded starter screen (AGL-687).\n *\n * Derived from the starter id and the screen key — never randomly generated\n * — so re-running the seed addresses the same documents instead of stacking\n * duplicate copies of every starter on every run.\n */\nexport function starterTemplateDocId(\n starterId: string,\n screenKey: string,\n): string {\n return `starter-${starterId}-${screenKey}`\n}\n\n/**\n * Expands one starter into the template documents it seeds as.\n *\n * One page template per screen, matching what a marketplace install of a\n * multi-screen site template already produces (AGL-669) — the alternative,\n * a bespoke multi-page template shape, would be a third lifecycle on top of\n * the two this issue exists to merge. The bundle's name/description/order\n * ride `source` so the gallery can still present the starter as one card.\n */\nexport function buildStarterTemplateDocs(\n starter: StarterTemplate,\n): StarterTemplateDoc[] {\n return starter.screens.map((screen, index) => {\n // Normalized on the way into the document so the persisted address is in\n // the routing-map format the tenant matches against — in particular the\n // root, which the previous `screen.slug ? …` guard dropped entirely when\n // home was spelled `''` (AGL-1575). A slug that sanitizes away carries no\n // field, and the apply path derives one from the display name.\n const slug = normalizeScreenSlug(screen.slug)\n return {\n id: starterTemplateDocId(starter.id, screen.key),\n starterId: starter.id,\n data: {\n kind: 'page',\n displayName: screen.displayName,\n // Only the screen's own description, never the starter blurb: a\n // template's `description` is carried onto the page it creates, and a\n // screen description is the live site's meta-description fallback.\n // The bundle blurb lives on `source.starterDescription` instead.\n ...(screen.description ? { description: screen.description } : {}),\n category: starter.category,\n ...(slug ? { slug } : {}),\n ...(screen.seo ? { seo: screen.seo } : {}),\n nodes: screen.nodes,\n source: {\n type: 'starter',\n starterId: starter.id,\n starterName: starter.displayName,\n starterDescription: starter.description,\n starterOrder: index,\n },\n },\n }\n })\n}\n\n/** Every document a starter COULD materialize as, in bundle order. */\nexport function buildAllStarterTemplateDocs(): StarterTemplateDoc[] {\n return STARTER_TEMPLATES.flatMap(buildStarterTemplateDocs)\n}\n\ntype NodeSpec = {\n id: string\n componentId: string\n /** Bundle owning the component; defaults to 'mui' (AGL-300). */\n pluginId?: string\n props?: Record<string, unknown>\n /**\n * Node-level styles — a SIBLING of props, never `props.sx` (AGL-1346).\n *\n * Both records render (`Leaf` composes `(sx, props.sx, node.sx)`, later\n * wins), but the Styles panel edits `node.sx`. A starter that seeded its\n * styling into `props.sx` handed the author a document full of values\n * the panel could show but no click could change or clear.\n */\n sx?: Record<string, unknown>\n children?: NodeSpec[]\n}\n\n/** Builds the flat, persisted node map from a nested spec. */\nfunction buildNodes(children: NodeSpec[]): Record<string, any> {\n const map: Record<string, any> = {\n [CANVAS_ROOT_ELEMENT_ID]: {\n $id: CANVAS_ROOT_ELEMENT_ID,\n componentId: 'div',\n nodes: children.map((child) => child.id),\n },\n }\n const walk = (spec: NodeSpec, parentId: string) => {\n map[spec.id] = {\n $id: spec.id,\n componentId: spec.componentId,\n pluginId: spec.pluginId ?? 'mui',\n parentId,\n props: spec.props ?? {},\n ...(spec.sx ? { sx: spec.sx } : {}),\n nodes: (spec.children ?? []).map((child) => child.id),\n }\n for (const child of spec.children ?? []) walk(child, spec.id)\n }\n for (const child of children) walk(child, CANVAS_ROOT_ELEMENT_ID)\n return map\n}\n\nconst text = (\n id: string,\n variant: string,\n children: string,\n extra?: Record<string, unknown>,\n): NodeSpec => ({\n id,\n componentId: 'muiTypography',\n props: { variant, children, ...extra },\n})\n\n/**\n * The stock widths a starter band may be (AGL-1932, AGL-1298).\n *\n * Three cases, and only three, because the standard has three. There is no\n * pixel case: `1328` is a CONTENT width, not a breakpoint, and the ban on\n * bespoke numbers is the half of AGL-1298 these templates used to violate\n * four times over.\n */\ntype SectionWidth = 'md' | 'lg' | 'xl'\n\n/**\n * One page band: a `Container` at a stock width, carrying the band's own\n * vertical rhythm (AGL-1932).\n *\n * The layout standard (AGL-1298): every section is a Container. Full-bleed is\n * the Container's own full-width attribute, never the absence of a Container,\n * and anything else is one of three stock widths. A template that seeds no\n * Container hands every customer a site that starts outside the standard.\n *\n * How the three widths are chosen here, stated so the next audit does not\n * have to guess:\n *\n * - `xl` — a marketing band: hero, feature row, product grid, gallery. The\n * default width, and what an unremarkable page should be.\n * - `lg` — the deliberate middle case: wide but text-led and interactive.\n * Cart and account are the honest instances, not decoration.\n * - `md` — long-form prose and narrow form columns, on READING grounds: at\n * `xl` a paragraph runs 110–120 characters a line. This is the case the\n * `Prose Container` preset exists for.\n *\n * Horizontal padding is the Container's own gutters, so bands no longer carry\n * horizontal padding at all. Only the vertical rhythm rides here, which is\n * rhythm rather than width.\n *\n * Written as the two longhands rather than MUI's `py` (AGL-2207/2208): the\n * Styles panel's Padding control is named for the four sides, so a band\n * seeded with `py` handed the customer a document whose padding the panel\n * showed as empty and no click could clear.\n */\nconst section = (\n id: string,\n maxWidth: SectionWidth,\n verticalPadding: number,\n children: NodeSpec[],\n): NodeSpec => ({\n id,\n componentId: 'muiContainer',\n props: { maxWidth },\n sx: { paddingTop: verticalPadding, paddingBottom: verticalPadding },\n children,\n})\n\nconst heroSection = (prefix: string, headline: string, tagline: string) =>\n // The Container is a NEW node (`…heroSection`); `…hero` keeps its id and\n // stays the Stack. Node ids here are persisted identifiers, so bands are\n // wrapped rather than re-pointed.\n section(`${prefix}heroSection`, 'xl', 10, [\n {\n id: `${prefix}hero`,\n componentId: 'muiStack',\n props: { spacing: 2 },\n sx: { alignItems: 'center' },\n children: [\n text(`${prefix}heroTitle`, 'h2', headline, { align: 'center' }),\n text(`${prefix}heroSub`, 'h6', tagline, { align: 'center' }),\n {\n id: `${prefix}heroCta`,\n componentId: 'muiButton',\n props: {\n variant: 'contained',\n size: 'large',\n children: 'Get in touch',\n },\n },\n ],\n },\n ])\n\nconst featureColumn = (id: string, title: string, body: string): NodeSpec => ({\n id,\n componentId: 'muiStack',\n props: { spacing: 1 },\n // `flex: 1` is a column's share of its row, not a width cap — it survives\n // the sweep deliberately. Only `maxWidth` in raw pixels was the violation.\n sx: {\n flex: 1,\n paddingTop: 2,\n paddingRight: 2,\n paddingBottom: 2,\n paddingLeft: 2,\n },\n children: [text(`${id}T`, 'h5', title), text(`${id}B`, 'body1', body)],\n})\n\nconst contactForm = (prefix: string): NodeSpec => ({\n id: `${prefix}form`,\n componentId: 'form',\n props: {\n formName: 'Contact',\n submitLabel: 'Send message',\n successMessage: 'Thanks — we will get back to you soon.',\n },\n children: [\n {\n id: `${prefix}fName`,\n componentId: 'formField',\n props: { fieldName: 'name', label: 'Name', required: true },\n },\n {\n id: `${prefix}fEmail`,\n componentId: 'formField',\n props: {\n fieldName: 'email',\n label: 'Email',\n fieldType: 'email',\n required: true,\n },\n },\n {\n id: `${prefix}fMessage`,\n componentId: 'formField',\n props: {\n fieldName: 'message',\n label: 'Message',\n fieldType: 'textarea',\n required: true,\n },\n },\n ],\n})\n\n\nconst commerceBlock = (\n id: string,\n componentId: string,\n props?: Record<string, unknown>,\n): NodeSpec => ({ id, componentId, pluginId: 'commerce', props })\n\n/** Shared screens for the shop starters (AGL-300). */\nfunction shopScreens(prefix: string, digital: boolean): StarterTemplateScreen[] {\n return [\n {\n key: 'home',\n displayName: 'Home',\n // The site root, spelled the way the routing map spells it. `''` here\n // read as \"no address\" everywhere downstream and put the shop's home\n // page at `/home` (AGL-1575).\n slug: SCREEN_ROOT_PATH,\n seo: {\n title: digital ? 'Digital shop' : 'Shop',\n description: 'Browse our products.',\n },\n nodes: buildNodes([\n heroSection(\n `${prefix}h_`,\n digital ? 'Downloads that level you up' : 'Gear you can trust',\n digital\n ? 'Instant delivery. Lifetime updates.'\n : 'Quality parts, shipped fast.',\n ),\n section(`${prefix}h_gridSection`, 'xl', 6, [\n commerceBlock(`${prefix}h_grid`, 'product-grid', {\n source: 'all',\n sort: 'newest',\n columns: 3,\n maxItems: 6,\n }),\n ]),\n // A newsletter capture is a short text-led band, not a gallery.\n section(`${prefix}h_newsSection`, 'md', 6, [\n commerceBlock(`${prefix}h_news`, 'newsletter-signup', {\n heading: 'Get updates and offers',\n }),\n ]),\n ]),\n },\n {\n key: 'shop',\n displayName: 'Shop',\n slug: 'shop',\n seo: { title: 'All products' },\n nodes: buildNodes([\n section(`${prefix}s_section`, 'xl', 6, [\n text(`${prefix}s_title`, 'h3', 'All products'),\n commerceBlock(`${prefix}s_grid`, 'product-grid', {\n source: 'all',\n columns: 4,\n showFilters: true,\n }),\n ]),\n ]),\n },\n {\n key: 'product',\n displayName: 'Product page',\n slug: 'product',\n seo: { title: 'Product' },\n nodes: buildNodes([\n section(`${prefix}p_section`, 'xl', 6, [\n commerceBlock(`${prefix}p_detail`, 'product-detail', {}),\n ]),\n ]),\n },\n {\n key: 'cart',\n displayName: 'Cart',\n slug: 'cart',\n seo: { title: 'Your cart' },\n // LG, the deliberate middle case: a cart is a wide table but it is read\n // line by line, so a full XL band spreads it further than the eye\n // tracks. Same for the account screen below.\n nodes: buildNodes([\n section(`${prefix}c_section`, 'lg', 6, [\n text(`${prefix}c_title`, 'h3', 'Your cart'),\n commerceBlock(`${prefix}c_cart`, 'cart', {\n variant: 'inline',\n showCoupon: true,\n }),\n ]),\n ]),\n },\n {\n key: 'account',\n displayName: 'Account',\n slug: 'account',\n seo: { title: 'Your account' },\n nodes: buildNodes([\n section(`${prefix}a_section`, 'lg', 6, [\n commerceBlock(`${prefix}a_account`, 'customer-account', {\n signedOutHeading: 'Your account',\n }),\n ]),\n ]),\n },\n ]\n}\n\n/**\n * The home page every new site is born with (AGL-3408).\n *\n * A site used to be created with an empty routing map, so the address the\n * create dialog calls live answered with the tenant's 404 until somebody\n * built and published a page. `claimHostForOrg` now writes this screen, its\n * first version and its `/` route in the same transaction that creates the\n * host, which makes \"a site with no home page\" a state no new site starts in.\n *\n * It is PUBLIC from the first request, so the copy speaks to a visitor, never\n * to the owner — no \"edit this in the besigner\". The site's name is written in\n * as text, not bound: there is no page-content token for it, and a heading\n * that followed a rename is not worth one.\n *\n * Deliberately not a starter: it is not offered in the gallery, and applying a\n * starter may take the root back from it (see `defaultHomeScreenId`).\n *\n * PERSISTED IDENTIFIERS: every node id below is stored on every new site.\n */\nexport function buildDefaultHomeScreen(siteName: string): StarterTemplateScreen {\n const name = siteName.trim() || 'Welcome'\n return {\n key: 'home',\n displayName: 'Home',\n slug: SCREEN_ROOT_PATH,\n nodes: buildNodes([\n section('dh_heroSection', 'md', 12, [\n {\n id: 'dh_hero',\n componentId: 'muiStack',\n props: { spacing: 2 },\n sx: { alignItems: 'center' },\n children: [\n text('dh_heroTitle', 'h2', name, { align: 'center' }),\n text(\n 'dh_heroSub',\n 'h6',\n 'Welcome — our new website is on its way.',\n { align: 'center', color: 'text.secondary' },\n ),\n ],\n },\n ]),\n ]),\n }\n}\n\nexport const STARTER_TEMPLATES: StarterTemplate[] = [\n {\n id: 'landing',\n displayName: 'Landing Page',\n description:\n 'One-page launch site: hero, three selling points, and a contact form.',\n category: 'Marketing',\n screens: [\n {\n key: 'landing',\n displayName: 'Landing',\n slug: 'landing',\n seo: {\n title: 'Welcome',\n description: 'Everything you need to know, on one page.',\n },\n nodes: buildNodes([\n heroSection(\n 'l_',\n 'A headline that sells your idea',\n 'One clear sentence about the value you deliver.',\n ),\n section('l_featuresSection', 'xl', 6, [\n {\n id: 'l_features',\n componentId: 'muiStack',\n props: { direction: 'row', spacing: 2 },\n children: [\n featureColumn(\n 'l_f1',\n 'Fast',\n 'Explain the first reason customers pick you.',\n ),\n featureColumn(\n 'l_f2',\n 'Simple',\n 'Explain the second reason customers pick you.',\n ),\n featureColumn(\n 'l_f3',\n 'Reliable',\n 'Explain the third reason customers pick you.',\n ),\n ],\n },\n ]),\n // Was `maxWidth: 560`. A band, not an inner measure: it sat at the\n // top level carrying the section's own gutters and rhythm, so the\n // pixel value was capping the BAND. MD is the stock width for a\n // narrow, form-led column.\n section('l_contactSection', 'md', 6, [\n {\n id: 'l_contact',\n componentId: 'muiStack',\n props: { spacing: 2 },\n children: [\n text('l_contactTitle', 'h4', 'Get in touch'),\n contactForm('l_'),\n ],\n },\n ]),\n ]),\n },\n ],\n },\n {\n id: 'business',\n displayName: 'Business',\n description:\n 'Company site: home with services, an about page, and a contact page.',\n category: 'Business',\n screens: [\n {\n key: 'home',\n displayName: 'Business Home',\n slug: 'home',\n seo: { title: 'Home' },\n nodes: buildNodes([\n heroSection(\n 'b_',\n 'Your business, done right',\n 'Tell visitors what you do and who you do it for.',\n ),\n section('b_servicesSection', 'xl', 6, [\n {\n id: 'b_services',\n componentId: 'muiStack',\n props: { direction: 'row', spacing: 2 },\n children: [\n featureColumn('b_s1', 'Service one', 'Describe this service.'),\n featureColumn('b_s2', 'Service two', 'Describe this service.'),\n featureColumn(\n 'b_s3',\n 'Service three',\n 'Describe this service.',\n ),\n ],\n },\n ]),\n ]),\n },\n {\n key: 'about-us',\n displayName: 'About Us',\n slug: 'about-us',\n seo: { title: 'About us' },\n nodes: buildNodes([\n // Was `maxWidth: 720` — the one unambiguous PROSE band in the set,\n // and the case the Prose Container preset exists for. MD (900px)\n // lands near the 65–75 characters a line that reads comfortably.\n section('a_wrapSection', 'md', 8, [\n {\n id: 'a_wrap',\n componentId: 'muiStack',\n props: { spacing: 2 },\n children: [\n text('a_title', 'h3', 'About us'),\n text(\n 'a_body',\n 'body1',\n 'Share your story: how you started, what you believe, and ' +\n 'why customers trust you.',\n ),\n ],\n },\n ]),\n ]),\n },\n {\n key: 'contact-us',\n displayName: 'Contact Us',\n slug: 'contact-us',\n seo: { title: 'Contact' },\n nodes: buildNodes([\n // Was `maxWidth: 560`. Same reading as the landing page's contact\n // band: text plus a form column, so MD.\n section('c_wrapSection', 'md', 8, [\n {\n id: 'c_wrap',\n componentId: 'muiStack',\n props: { spacing: 2 },\n children: [\n text('c_title', 'h3', 'Contact us'),\n text(\n 'c_body',\n 'body1',\n 'Questions or quotes — send a message and we reply within ' +\n 'one business day.',\n ),\n contactForm('c_'),\n ],\n },\n ]),\n ]),\n },\n ],\n },\n {\n id: 'portfolio',\n displayName: 'Portfolio',\n description: 'Personal portfolio: intro, work grid, and contact form.',\n category: 'Personal',\n screens: [\n {\n key: 'portfolio',\n displayName: 'Portfolio',\n slug: 'portfolio',\n seo: { title: 'Portfolio' },\n nodes: buildNodes([\n heroSection(\n 'p_',\n 'Hi, I make things',\n 'Designer / developer / photographer — introduce yourself here.',\n ),\n section('p_gridSection', 'xl', 6, [\n {\n id: 'p_grid',\n componentId: 'muiStack',\n props: { direction: 'row', spacing: 2 },\n children: [\n {\n id: 'p_img1',\n componentId: 'image',\n // `height` is an image's own intrinsic sizing prop, not a\n // band cap — out of scope for the container standard.\n props: { alt: 'Project one', height: '220px' },\n },\n {\n id: 'p_img2',\n componentId: 'image',\n props: { alt: 'Project two', height: '220px' },\n },\n {\n id: 'p_img3',\n componentId: 'image',\n props: { alt: 'Project three', height: '220px' },\n },\n ],\n },\n ]),\n // Was `maxWidth: 560`, the third of the three contact bands.\n section('p_contactSection', 'md', 6, [\n {\n id: 'p_contact',\n componentId: 'muiStack',\n props: { spacing: 2 },\n children: [\n text('p_contactTitle', 'h4', 'Work with me'),\n contactForm('p_'),\n ],\n },\n ]),\n ]),\n },\n ],\n },\n {\n id: 'physical-shop',\n displayName: 'Shop (physical products)',\n description:\n 'Storefront starter: home with featured products, filterable shop, ' +\n 'product page, cart, and customer accounts. After applying, set the ' +\n 'Product page as the product template in Store settings.',\n category: 'Commerce',\n screens: shopScreens('ps_', false),\n },\n {\n id: 'digital-shop',\n displayName: 'Shop (digital products)',\n description:\n 'Digital storefront starter: downloads-focused home, shop, product ' +\n 'page, cart, and accounts with a newsletter capture. Set the Product ' +\n 'page as the product template in Store settings after applying.',\n category: 'Commerce',\n screens: shopScreens('ds_', true),\n },\n]\n"],"names":["CANVAS_ROOT_ELEMENT_ID","normalizeScreenSlug","SCREEN_ROOT_PATH","starterTemplateDocId","starterId","screenKey","buildStarterTemplateDocs","starter","screens","map","screen","index","slug","id","key","data","kind","displayName","description","category","seo","nodes","source","type","starterName","starterDescription","starterOrder","buildAllStarterTemplateDocs","STARTER_TEMPLATES","flatMap","buildNodes","children","$id","componentId","child","walk","spec","parentId","pluginId","props","sx","text","variant","extra","section","maxWidth","verticalPadding","paddingTop","paddingBottom","heroSection","prefix","headline","tagline","spacing","alignItems","align","size","featureColumn","title","body","flex","paddingRight","paddingLeft","contactForm","formName","submitLabel","successMessage","fieldName","label","required","fieldType","commerceBlock","shopScreens","digital","sort","columns","maxItems","heading","showFilters","showCoupon","signedOutHeading","buildDefaultHomeScreen","siteName","name","trim","color","direction","alt","height"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/starter-templates.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// Leaf imports only, deliberately (AGL-687). This module is imported from\n// BOTH graphs — the console's client gallery renders virtual starters from\n// it, the console's seed route materializes them, and the AI plugin's server\n// shows them to a model — and neither barrel works in both: the full\n// `@aglyn/aglyn` barrel breaks the RSC/server-route graph, while the server\n// entry drags `node:fs` into the client bundle. The starter kit imports only\n// the canvas constants, a leaf with no imports of their own; the compiled\n// plugin starters are data behind a type-only import; and `screen-route`\n// imports only a TYPE from foundation — so all three are safe on either side.\nimport { PLUGIN_STARTER_TEMPLATES } from './plugin-starter-templates.generated'\nimport { normalizeScreenSlug, SCREEN_ROOT_PATH } from './screen-route'\nimport {\n buildStarterNodes as buildNodes,\n starterHeroSection as heroSection,\n starterSection as section,\n starterText as text,\n type StarterNodeSpec as NodeSpec,\n type StarterTemplate,\n type StarterTemplateScreen,\n} from './starter-template-nodes'\n\nexport type {\n StarterNodeSpec,\n StarterSectionWidth,\n StarterTemplate,\n StarterTemplateScreen,\n} from './starter-template-nodes'\nexport {\n buildStarterNodes,\n starterHeroSection,\n starterSection,\n starterText,\n} from './starter-template-nodes'\n\n/**\n * First-party starter definitions (AGL-78/79), SEED INPUT (AGL-687).\n *\n * These used to be rendered straight into the gallery and instantiated from\n * code, which made a starter a second kind of template: no version history,\n * no placeholders, no editor, changeable only by shipping a release. Now\n * they are seeded into each host's own template library as ordinary\n * `hosts/{hostId}/templates` documents (see the console's\n * `utils/server/seed-starter-templates.ts` for why copy-on-use rather than a\n * global read-only collection), and nothing reads this file at render time.\n *\n * They are also the page examples the AI plugin's template generator shows a\n * model (AGL-2909), which is why they live in the core package rather than\n * beside the console gallery that renders them.\n *\n * Node ids stay template-local (unique within each screen's version doc);\n * `createPageFromTemplate` re-keys screen and version ids at instantiation.\n *\n * PERSISTED IDENTIFIERS: `StarterTemplate.id`, `StarterTemplateScreen.key`\n * and every node id below appear in stored documents (seeded template doc\n * ids are derived from the first two). They must never be renamed.\n */\nexport interface StarterTemplateDoc {\n id: string\n /** Which starter this page belongs to — lets one starter be selected. */\n starterId: string\n data: Record<string, unknown>\n}\n\n/**\n * Deterministic document id for a seeded starter screen (AGL-687).\n *\n * Derived from the starter id and the screen key — never randomly generated\n * — so re-running the seed addresses the same documents instead of stacking\n * duplicate copies of every starter on every run.\n */\nexport function starterTemplateDocId(\n starterId: string,\n screenKey: string,\n): string {\n return `starter-${starterId}-${screenKey}`\n}\n\n/**\n * Expands one starter into the template documents it seeds as.\n *\n * One page template per screen, matching what a marketplace install of a\n * multi-screen site template already produces (AGL-669) — the alternative,\n * a bespoke multi-page template shape, would be a third lifecycle on top of\n * the two this issue exists to merge. The bundle's name/description/order\n * ride `source` so the gallery can still present the starter as one card.\n */\nexport function buildStarterTemplateDocs(\n starter: StarterTemplate,\n): StarterTemplateDoc[] {\n return starter.screens.map((screen, index) => {\n // Normalized on the way into the document so the persisted address is in\n // the routing-map format the tenant matches against — in particular the\n // root, which the previous `screen.slug ? …` guard dropped entirely when\n // home was spelled `''` (AGL-1575). A slug that sanitizes away carries no\n // field, and the apply path derives one from the display name.\n const slug = normalizeScreenSlug(screen.slug)\n return {\n id: starterTemplateDocId(starter.id, screen.key),\n starterId: starter.id,\n data: {\n kind: 'page',\n displayName: screen.displayName,\n // Only the screen's own description, never the starter blurb: a\n // template's `description` is carried onto the page it creates, and a\n // screen description is the live site's meta-description fallback.\n // The bundle blurb lives on `source.starterDescription` instead.\n ...(screen.description ? { description: screen.description } : {}),\n category: starter.category,\n ...(slug ? { slug } : {}),\n ...(screen.seo ? { seo: screen.seo } : {}),\n nodes: screen.nodes,\n source: {\n type: 'starter',\n starterId: starter.id,\n starterName: starter.displayName,\n starterDescription: starter.description,\n starterOrder: index,\n },\n },\n }\n })\n}\n\n/** Every document a starter COULD materialize as, in bundle order. */\nexport function buildAllStarterTemplateDocs(): StarterTemplateDoc[] {\n return STARTER_TEMPLATES.flatMap(buildStarterTemplateDocs)\n}\n\nconst featureColumn = (id: string, title: string, body: string): NodeSpec => ({\n id,\n componentId: 'muiStack',\n props: { spacing: 1 },\n // `flex: 1` is a column's share of its row, not a width cap — it survives\n // the sweep deliberately. Only `maxWidth` in raw pixels was the violation.\n sx: {\n flex: 1,\n paddingTop: 2,\n paddingRight: 2,\n paddingBottom: 2,\n paddingLeft: 2,\n },\n children: [text(`${id}T`, 'h5', title), text(`${id}B`, 'body1', body)],\n})\n\nconst contactForm = (prefix: string): NodeSpec => ({\n id: `${prefix}form`,\n componentId: 'form',\n props: {\n formName: 'Contact',\n submitLabel: 'Send message',\n successMessage: 'Thanks — we will get back to you soon.',\n },\n children: [\n {\n id: `${prefix}fName`,\n componentId: 'formField',\n props: { fieldName: 'name', label: 'Name', required: true },\n },\n {\n id: `${prefix}fEmail`,\n componentId: 'formField',\n props: {\n fieldName: 'email',\n label: 'Email',\n fieldType: 'email',\n required: true,\n },\n },\n {\n id: `${prefix}fMessage`,\n componentId: 'formField',\n props: {\n fieldName: 'message',\n label: 'Message',\n fieldType: 'textarea',\n required: true,\n },\n },\n ],\n})\n\n\n/**\n * The home page every new site is born with (AGL-3408).\n *\n * A site used to be created with an empty routing map, so the address the\n * create dialog calls live answered with the tenant's 404 until somebody\n * built and published a page. `claimHostForOrg` now writes this screen, its\n * first version and its `/` route in the same transaction that creates the\n * host, which makes \"a site with no home page\" a state no new site starts in.\n *\n * It is PUBLIC from the first request, so the copy speaks to a visitor, never\n * to the owner — no \"edit this in the besigner\". The site's name is written in\n * as text, not bound: there is no page-content token for it, and a heading\n * that followed a rename is not worth one.\n *\n * Deliberately not a starter: it is not offered in the gallery, and applying a\n * starter may take the root back from it (see `defaultHomeScreenId`).\n *\n * PERSISTED IDENTIFIERS: every node id below is stored on every new site.\n */\nexport function buildDefaultHomeScreen(siteName: string): StarterTemplateScreen {\n const name = siteName.trim() || 'Welcome'\n return {\n key: 'home',\n displayName: 'Home',\n slug: SCREEN_ROOT_PATH,\n nodes: buildNodes([\n section('dh_heroSection', 'md', 12, [\n {\n id: 'dh_hero',\n componentId: 'muiStack',\n props: { spacing: 2 },\n sx: { alignItems: 'center' },\n children: [\n text('dh_heroTitle', 'h2', name, { align: 'center' }),\n text(\n 'dh_heroSub',\n 'h6',\n 'Welcome — our new website is on its way.',\n { align: 'center', color: 'text.secondary' },\n ),\n ],\n },\n ]),\n ]),\n }\n}\n\n/** The platform's own starters, which name no plugin's elements. */\nconst PLATFORM_STARTER_TEMPLATES: StarterTemplate[] = [\n {\n id: 'landing',\n displayName: 'Landing Page',\n description:\n 'One-page launch site: hero, three selling points, and a contact form.',\n category: 'Marketing',\n screens: [\n {\n key: 'landing',\n displayName: 'Landing',\n slug: 'landing',\n seo: {\n title: 'Welcome',\n description: 'Everything you need to know, on one page.',\n },\n nodes: buildNodes([\n heroSection(\n 'l_',\n 'A headline that sells your idea',\n 'One clear sentence about the value you deliver.',\n ),\n section('l_featuresSection', 'xl', 6, [\n {\n id: 'l_features',\n componentId: 'muiStack',\n props: { direction: 'row', spacing: 2 },\n children: [\n featureColumn(\n 'l_f1',\n 'Fast',\n 'Explain the first reason customers pick you.',\n ),\n featureColumn(\n 'l_f2',\n 'Simple',\n 'Explain the second reason customers pick you.',\n ),\n featureColumn(\n 'l_f3',\n 'Reliable',\n 'Explain the third reason customers pick you.',\n ),\n ],\n },\n ]),\n // Was `maxWidth: 560`. A band, not an inner measure: it sat at the\n // top level carrying the section's own gutters and rhythm, so the\n // pixel value was capping the BAND. MD is the stock width for a\n // narrow, form-led column.\n section('l_contactSection', 'md', 6, [\n {\n id: 'l_contact',\n componentId: 'muiStack',\n props: { spacing: 2 },\n children: [\n text('l_contactTitle', 'h4', 'Get in touch'),\n contactForm('l_'),\n ],\n },\n ]),\n ]),\n },\n ],\n },\n {\n id: 'business',\n displayName: 'Business',\n description:\n 'Company site: home with services, an about page, and a contact page.',\n category: 'Business',\n screens: [\n {\n key: 'home',\n displayName: 'Business Home',\n slug: 'home',\n seo: { title: 'Home' },\n nodes: buildNodes([\n heroSection(\n 'b_',\n 'Your business, done right',\n 'Tell visitors what you do and who you do it for.',\n ),\n section('b_servicesSection', 'xl', 6, [\n {\n id: 'b_services',\n componentId: 'muiStack',\n props: { direction: 'row', spacing: 2 },\n children: [\n featureColumn('b_s1', 'Service one', 'Describe this service.'),\n featureColumn('b_s2', 'Service two', 'Describe this service.'),\n featureColumn(\n 'b_s3',\n 'Service three',\n 'Describe this service.',\n ),\n ],\n },\n ]),\n ]),\n },\n {\n key: 'about-us',\n displayName: 'About Us',\n slug: 'about-us',\n seo: { title: 'About us' },\n nodes: buildNodes([\n // Was `maxWidth: 720` — the one unambiguous PROSE band in the set,\n // and the case the Prose Container preset exists for. MD (900px)\n // lands near the 65–75 characters a line that reads comfortably.\n section('a_wrapSection', 'md', 8, [\n {\n id: 'a_wrap',\n componentId: 'muiStack',\n props: { spacing: 2 },\n children: [\n text('a_title', 'h3', 'About us'),\n text(\n 'a_body',\n 'body1',\n 'Share your story: how you started, what you believe, and ' +\n 'why customers trust you.',\n ),\n ],\n },\n ]),\n ]),\n },\n {\n key: 'contact-us',\n displayName: 'Contact Us',\n slug: 'contact-us',\n seo: { title: 'Contact' },\n nodes: buildNodes([\n // Was `maxWidth: 560`. Same reading as the landing page's contact\n // band: text plus a form column, so MD.\n section('c_wrapSection', 'md', 8, [\n {\n id: 'c_wrap',\n componentId: 'muiStack',\n props: { spacing: 2 },\n children: [\n text('c_title', 'h3', 'Contact us'),\n text(\n 'c_body',\n 'body1',\n 'Questions or quotes — send a message and we reply within ' +\n 'one business day.',\n ),\n contactForm('c_'),\n ],\n },\n ]),\n ]),\n },\n ],\n },\n {\n id: 'portfolio',\n displayName: 'Portfolio',\n description: 'Personal portfolio: intro, work grid, and contact form.',\n category: 'Personal',\n screens: [\n {\n key: 'portfolio',\n displayName: 'Portfolio',\n slug: 'portfolio',\n seo: { title: 'Portfolio' },\n nodes: buildNodes([\n heroSection(\n 'p_',\n 'Hi, I make things',\n 'Designer / developer / photographer — introduce yourself here.',\n ),\n section('p_gridSection', 'xl', 6, [\n {\n id: 'p_grid',\n componentId: 'muiStack',\n props: { direction: 'row', spacing: 2 },\n children: [\n {\n id: 'p_img1',\n componentId: 'image',\n // `height` is an image's own intrinsic sizing prop, not a\n // band cap — out of scope for the container standard.\n props: { alt: 'Project one', height: '220px' },\n },\n {\n id: 'p_img2',\n componentId: 'image',\n props: { alt: 'Project two', height: '220px' },\n },\n {\n id: 'p_img3',\n componentId: 'image',\n props: { alt: 'Project three', height: '220px' },\n },\n ],\n },\n ]),\n // Was `maxWidth: 560`, the third of the three contact bands.\n section('p_contactSection', 'md', 6, [\n {\n id: 'p_contact',\n componentId: 'muiStack',\n props: { spacing: 2 },\n children: [\n text('p_contactTitle', 'h4', 'Work with me'),\n contactForm('p_'),\n ],\n },\n ]),\n ]),\n },\n ],\n },\n]\n\n/**\n * Every starter in this build, in gallery order: the platform's own, then\n * each plugin's in config order (AGL-3080). A plugin whose elements a starter\n * is built around — a storefront's product grid and cart — declares it under\n * `starterTemplates` in plugins.config.json, and the manifest generator\n * compiles what it returns, so the gallery, the seed route and a model\n * shown examples all read one list without loading any plugin.\n */\nexport const STARTER_TEMPLATES: StarterTemplate[] = [\n ...PLATFORM_STARTER_TEMPLATES,\n ...PLUGIN_STARTER_TEMPLATES,\n]\n"],"names":["PLUGIN_STARTER_TEMPLATES","normalizeScreenSlug","SCREEN_ROOT_PATH","buildStarterNodes","buildNodes","starterHeroSection","heroSection","starterSection","section","starterText","text","starterTemplateDocId","starterId","screenKey","buildStarterTemplateDocs","starter","screens","map","screen","index","slug","id","key","data","kind","displayName","description","category","seo","nodes","source","type","starterName","starterDescription","starterOrder","buildAllStarterTemplateDocs","STARTER_TEMPLATES","flatMap","featureColumn","title","body","componentId","props","spacing","sx","flex","paddingTop","paddingRight","paddingBottom","paddingLeft","children","contactForm","prefix","formName","submitLabel","successMessage","fieldName","label","required","fieldType","buildDefaultHomeScreen","siteName","name","trim","alignItems","align","color","PLATFORM_STARTER_TEMPLATES","direction","alt","height"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED,0EAA0E;AAC1E,2EAA2E;AAC3E,6EAA6E;AAC7E,qEAAqE;AACrE,4EAA4E;AAC5E,6EAA6E;AAC7E,0EAA0E;AAC1E,yEAAyE;AACzE,8EAA8E;AAC9E,SAASA,wBAAwB,QAAQ,0CAAsC;AAC/E,SAASC,mBAAmB,EAAEC,gBAAgB,QAAQ,oBAAgB;AACtE,SACEC,qBAAqBC,UAAU,EAC/BC,sBAAsBC,WAAW,EACjCC,kBAAkBC,OAAO,EACzBC,eAAeC,IAAI,QAId,8BAA0B;AAQjC,SACEP,iBAAiB,EACjBE,kBAAkB,EAClBE,cAAc,EACdE,WAAW,QACN,8BAA0B;AA+BjC;;;;;;CAMC,GACD,OAAO,SAASE,qBACdC,SAAiB,EACjBC,SAAiB;IAEjB,OAAO,CAAC,QAAQ,EAAED,UAAU,CAAC,EAAEC,WAAW;AAC5C;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASC,yBACdC,OAAwB;IAExB,OAAOA,QAAQC,OAAO,CAACC,GAAG,CAAC,CAACC,QAAQC;QAClC,yEAAyE;QACzE,wEAAwE;QACxE,yEAAyE;QACzE,0EAA0E;QAC1E,+DAA+D;QAC/D,MAAMC,OAAOnB,oBAAoBiB,OAAOE,IAAI;QAC5C,OAAO;YACLC,IAAIV,qBAAqBI,QAAQM,EAAE,EAAEH,OAAOI,GAAG;YAC/CV,WAAWG,QAAQM,EAAE;YACrBE,MAAM;gBACJC,MAAM;gBACNC,aAAaP,OAAOO,WAAW;eAK3BP,OAAOQ,WAAW,GAAG;gBAAEA,aAAaR,OAAOQ,WAAW;YAAC,IAAI,CAAC;gBAChEC,UAAUZ,QAAQY,QAAQ;eACtBP,OAAO;gBAAEA;YAAK,IAAI,CAAC,GACnBF,OAAOU,GAAG,GAAG;gBAAEA,KAAKV,OAAOU,GAAG;YAAC,IAAI,CAAC;gBACxCC,OAAOX,OAAOW,KAAK;gBACnBC,QAAQ;oBACNC,MAAM;oBACNnB,WAAWG,QAAQM,EAAE;oBACrBW,aAAajB,QAAQU,WAAW;oBAChCQ,oBAAoBlB,QAAQW,WAAW;oBACvCQ,cAAcf;gBAChB;;QAEJ;IACF;AACF;AAEA,oEAAoE,GACpE,OAAO,SAASgB;IACd,OAAOC,kBAAkBC,OAAO,CAACvB;AACnC;AAEA,MAAMwB,gBAAgB,CAACjB,IAAYkB,OAAeC,OAA4B,CAAA;QAC5EnB;QACAoB,aAAa;QACbC,OAAO;YAAEC,SAAS;QAAE;QACpB,0EAA0E;QAC1E,2EAA2E;QAC3EC,IAAI;YACFC,MAAM;YACNC,YAAY;YACZC,cAAc;YACdC,eAAe;YACfC,aAAa;QACf;QACAC,UAAU;YAACxC,KAAK,GAAGW,GAAG,CAAC,CAAC,EAAE,MAAMkB;YAAQ7B,KAAK,GAAGW,GAAG,CAAC,CAAC,EAAE,SAASmB;SAAM;IACxE,CAAA;AAEA,MAAMW,cAAc,CAACC,SAA8B,CAAA;QACjD/B,IAAI,GAAG+B,OAAO,IAAI,CAAC;QACnBX,aAAa;QACbC,OAAO;YACLW,UAAU;YACVC,aAAa;YACbC,gBAAgB;QAClB;QACAL,UAAU;YACR;gBACE7B,IAAI,GAAG+B,OAAO,KAAK,CAAC;gBACpBX,aAAa;gBACbC,OAAO;oBAAEc,WAAW;oBAAQC,OAAO;oBAAQC,UAAU;gBAAK;YAC5D;YACA;gBACErC,IAAI,GAAG+B,OAAO,MAAM,CAAC;gBACrBX,aAAa;gBACbC,OAAO;oBACLc,WAAW;oBACXC,OAAO;oBACPE,WAAW;oBACXD,UAAU;gBACZ;YACF;YACA;gBACErC,IAAI,GAAG+B,OAAO,QAAQ,CAAC;gBACvBX,aAAa;gBACbC,OAAO;oBACLc,WAAW;oBACXC,OAAO;oBACPE,WAAW;oBACXD,UAAU;gBACZ;YACF;SACD;IACH,CAAA;AAGA;;;;;;;;;;;;;;;;;;CAkBC,GACD,OAAO,SAASE,uBAAuBC,QAAgB;IACrD,MAAMC,OAAOD,SAASE,IAAI,MAAM;IAChC,OAAO;QACLzC,KAAK;QACLG,aAAa;QACbL,MAAMlB;QACN2B,OAAOzB,WAAW;YAChBI,QAAQ,kBAAkB,MAAM,IAAI;gBAClC;oBACEa,IAAI;oBACJoB,aAAa;oBACbC,OAAO;wBAAEC,SAAS;oBAAE;oBACpBC,IAAI;wBAAEoB,YAAY;oBAAS;oBAC3Bd,UAAU;wBACRxC,KAAK,gBAAgB,MAAMoD,MAAM;4BAAEG,OAAO;wBAAS;wBACnDvD,KACE,cACA,MACA,4CACA;4BAAEuD,OAAO;4BAAUC,OAAO;wBAAiB;qBAE9C;gBACH;aACD;SACF;IACH;AACF;AAEA,kEAAkE,GAClE,MAAMC,6BAAgD;IACpD;QACE9C,IAAI;QACJI,aAAa;QACbC,aACE;QACFC,UAAU;QACVX,SAAS;YACP;gBACEM,KAAK;gBACLG,aAAa;gBACbL,MAAM;gBACNQ,KAAK;oBACHW,OAAO;oBACPb,aAAa;gBACf;gBACAG,OAAOzB,WAAW;oBAChBE,YACE,MACA,mCACA;oBAEFE,QAAQ,qBAAqB,MAAM,GAAG;wBACpC;4BACEa,IAAI;4BACJoB,aAAa;4BACbC,OAAO;gCAAE0B,WAAW;gCAAOzB,SAAS;4BAAE;4BACtCO,UAAU;gCACRZ,cACE,QACA,QACA;gCAEFA,cACE,QACA,UACA;gCAEFA,cACE,QACA,YACA;6BAEH;wBACH;qBACD;oBACD,mEAAmE;oBACnE,kEAAkE;oBAClE,gEAAgE;oBAChE,2BAA2B;oBAC3B9B,QAAQ,oBAAoB,MAAM,GAAG;wBACnC;4BACEa,IAAI;4BACJoB,aAAa;4BACbC,OAAO;gCAAEC,SAAS;4BAAE;4BACpBO,UAAU;gCACRxC,KAAK,kBAAkB,MAAM;gCAC7ByC,YAAY;6BACb;wBACH;qBACD;iBACF;YACH;SACD;IACH;IACA;QACE9B,IAAI;QACJI,aAAa;QACbC,aACE;QACFC,UAAU;QACVX,SAAS;YACP;gBACEM,KAAK;gBACLG,aAAa;gBACbL,MAAM;gBACNQ,KAAK;oBAAEW,OAAO;gBAAO;gBACrBV,OAAOzB,WAAW;oBAChBE,YACE,MACA,6BACA;oBAEFE,QAAQ,qBAAqB,MAAM,GAAG;wBACpC;4BACEa,IAAI;4BACJoB,aAAa;4BACbC,OAAO;gCAAE0B,WAAW;gCAAOzB,SAAS;4BAAE;4BACtCO,UAAU;gCACRZ,cAAc,QAAQ,eAAe;gCACrCA,cAAc,QAAQ,eAAe;gCACrCA,cACE,QACA,iBACA;6BAEH;wBACH;qBACD;iBACF;YACH;YACA;gBACEhB,KAAK;gBACLG,aAAa;gBACbL,MAAM;gBACNQ,KAAK;oBAAEW,OAAO;gBAAW;gBACzBV,OAAOzB,WAAW;oBAChB,mEAAmE;oBACnE,iEAAiE;oBACjE,iEAAiE;oBACjEI,QAAQ,iBAAiB,MAAM,GAAG;wBAChC;4BACEa,IAAI;4BACJoB,aAAa;4BACbC,OAAO;gCAAEC,SAAS;4BAAE;4BACpBO,UAAU;gCACRxC,KAAK,WAAW,MAAM;gCACtBA,KACE,UACA,SACA,8DACE;6BAEL;wBACH;qBACD;iBACF;YACH;YACA;gBACEY,KAAK;gBACLG,aAAa;gBACbL,MAAM;gBACNQ,KAAK;oBAAEW,OAAO;gBAAU;gBACxBV,OAAOzB,WAAW;oBAChB,kEAAkE;oBAClE,wCAAwC;oBACxCI,QAAQ,iBAAiB,MAAM,GAAG;wBAChC;4BACEa,IAAI;4BACJoB,aAAa;4BACbC,OAAO;gCAAEC,SAAS;4BAAE;4BACpBO,UAAU;gCACRxC,KAAK,WAAW,MAAM;gCACtBA,KACE,UACA,SACA,8DACE;gCAEJyC,YAAY;6BACb;wBACH;qBACD;iBACF;YACH;SACD;IACH;IACA;QACE9B,IAAI;QACJI,aAAa;QACbC,aAAa;QACbC,UAAU;QACVX,SAAS;YACP;gBACEM,KAAK;gBACLG,aAAa;gBACbL,MAAM;gBACNQ,KAAK;oBAAEW,OAAO;gBAAY;gBAC1BV,OAAOzB,WAAW;oBAChBE,YACE,MACA,qBACA;oBAEFE,QAAQ,iBAAiB,MAAM,GAAG;wBAChC;4BACEa,IAAI;4BACJoB,aAAa;4BACbC,OAAO;gCAAE0B,WAAW;gCAAOzB,SAAS;4BAAE;4BACtCO,UAAU;gCACR;oCACE7B,IAAI;oCACJoB,aAAa;oCACb,0DAA0D;oCAC1D,sDAAsD;oCACtDC,OAAO;wCAAE2B,KAAK;wCAAeC,QAAQ;oCAAQ;gCAC/C;gCACA;oCACEjD,IAAI;oCACJoB,aAAa;oCACbC,OAAO;wCAAE2B,KAAK;wCAAeC,QAAQ;oCAAQ;gCAC/C;gCACA;oCACEjD,IAAI;oCACJoB,aAAa;oCACbC,OAAO;wCAAE2B,KAAK;wCAAiBC,QAAQ;oCAAQ;gCACjD;6BACD;wBACH;qBACD;oBACD,6DAA6D;oBAC7D9D,QAAQ,oBAAoB,MAAM,GAAG;wBACnC;4BACEa,IAAI;4BACJoB,aAAa;4BACbC,OAAO;gCAAEC,SAAS;4BAAE;4BACpBO,UAAU;gCACRxC,KAAK,kBAAkB,MAAM;gCAC7ByC,YAAY;6BACb;wBACH;qBACD;iBACF;YACH;SACD;IACH;CACD;AAED;;;;;;;CAOC,GACD,OAAO,MAAMf,oBAAuC;OAC/C+B;OACAnE;CACJ,CAAA"}
@@ -15,12 +15,21 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  /**
18
- * EMAIL TOPICS — the streams a recipient can leave one at a time.
18
+ * SUBSCRIPTION TOPICS — the streams a recipient can leave one at a time.
19
+ *
20
+ * The mail rail's per-stream consent: every marketing-purpose message names
21
+ * the stream it belongs to, its unsubscribe link carries that stream, and the
22
+ * send path refuses a recipient who left it. That obligation is owed on every
23
+ * such message whichever plugin sends it — a campaign, a newsletter, a
24
+ * restock alert, an automation, the operator's own product updates — so the
25
+ * state and the policy are the platform's. What a plugin brings is the
26
+ * STREAMS it sends under, which it declares (`plugins.config.json` →
27
+ * `subscriptionTopics`, compiled into {@link DECLARED_SUBSCRIPTION_TOPICS}).
19
28
  *
20
29
  * ## The gap this closes
21
30
  *
22
31
  * `docs/specs/email-competitive-gaps.md` §1f records the only row in that
23
- * table where every competitor has something and we have nothing: "Preference
32
+ * table where every competitor has something and we had nothing: "Preference
24
33
  * center / subscription topics — unsubscribe is all-or-nothing per site".
25
34
  * A recipient who wanted the newsletter but not the sales mail had exactly one
26
35
  * lever, and pulling it took the newsletter too. The lever people reach for
@@ -29,12 +38,11 @@
29
38
  *
30
39
  * ## Scope: definitions are ORG-shared, opt-outs are PER-SITE
31
40
  *
32
- * The topic CATALOG lives at `orgs/{orgId}/emailTopics`, which is where
33
- * `lists` live (AGL-254) and for the same reason: a topic is authored
34
- * editorial content — a name and a sentence of description — that an agency
35
- * writes once and points several sites at. Following `lists` also means the
36
- * console surface that manages topics inherits a scoping question that has
37
- * already been answered, rather than inventing a second answer.
41
+ * The topic CATALOG an org authors — renaming, re-describing, archiving a
42
+ * built-in stream, adding its own — is stored by the plugin that manages it,
43
+ * under the organization, where lists live and for the same reason: a topic is
44
+ * authored editorial content that an agency writes once and points several
45
+ * sites at.
38
46
  *
39
47
  * A recipient's OPT-OUT is per site, at `hosts/{hostId}/topicOptOuts`. It sits
40
48
  * beside `hosts/{hostId}/suppressions`, which is per site, and it answers the
@@ -45,19 +53,18 @@
45
53
  * the unauthenticated preference page honest — the signed link names a host
46
54
  * and nothing else, so a per-site read is exactly what the link authorizes.
47
55
  *
48
- * ## Why the defaults are code and not seeded documents
56
+ * ## Why the built-ins are declared and not seeded documents
49
57
  *
50
- * Every tenant that exists today has an empty `emailTopics` collection. A
51
- * seeding migration would have to run against every org, would leave any org
58
+ * A seeding migration would have to run against every org, would leave any org
52
59
  * created while it was mid-flight with none, and — like every backfill — is a
53
- * thing that gets written and then not run. So {@link DEFAULT_EMAIL_TOPICS} is
54
- * the floor of the catalog rather than its initial contents: it is present for
55
- * every org from the moment this ships, with no write anywhere, and a stored
56
- * document at the same id renames, re-describes or archives one. The catalog a
57
- * reader sees is {@link mergeEmailTopics} of the two.
60
+ * thing that gets written and then not run. So the declared streams are the
61
+ * floor of the catalog rather than its initial contents: present for every
62
+ * org from the moment a plugin declares one, with no write anywhere, and a
63
+ * stored document at the same id renames, re-describes or archives one. The
64
+ * catalog a reader sees is {@link mergeSubscriptionTopics} of the two.
58
65
  */
59
66
  /** One subscribable stream. */
60
- export interface EmailTopic {
67
+ export interface SubscriptionTopic {
61
68
  /**
62
69
  * The stored id. Rides in the unsubscribe link's `tid` and is covered by
63
70
  * its signature, so it is treated as persisted — rename the {@link name},
@@ -157,7 +164,7 @@ export declare const DOUBLE_OPT_IN_EXPIRY_MS: number;
157
164
  * stored on a topic is a real answer and not an absence, which is what lets a
158
165
  * merchant confirm everything except their order-related stream.
159
166
  */
160
- export declare function topicRequiresDoubleOptIn(topic: Pick<EmailTopic, 'doubleOptIn'> | null | undefined, siteDefault?: boolean): boolean;
167
+ export declare function topicRequiresDoubleOptIn(topic: Pick<SubscriptionTopic, 'doubleOptIn'> | null | undefined, siteDefault?: boolean): boolean;
161
168
  /** What one person's record says about one stream on one site. */
162
169
  export type TopicSubscriptionState =
163
170
  /** They may be mailed about this. */
@@ -210,37 +217,46 @@ export declare function readTopicSubscriptionState(entry: TopicSubscriptionEntry
210
217
  * and collapsing them is how an expiry comes to admit somebody.
211
218
  */
212
219
  export declare function doubleOptInExpired(pendingAtMs: number | null | undefined, nowMs: number): boolean;
213
- /** `orgs/{orgId}/emailTopics` — the catalog, org-shared like `lists`. */
214
- export declare const EMAIL_TOPICS_COLLECTION = "emailTopics";
215
220
  /** `hosts/{hostId}/topicOptOuts/{emailKey}` — one document per recipient. */
216
221
  export declare const TOPIC_OPT_OUTS_SUBCOLLECTION = "topicOptOuts";
217
- /** Sales, discounts, seasonal campaigns — and the cart a shopper left. */
218
- export declare const EMAIL_TOPIC_MARKETING = "marketing";
219
- /** Regular news and stories, including a site's posts to its members. */
220
- export declare const EMAIL_TOPIC_NEWSLETTER = "newsletter";
221
- /** New products, restocks, and changes to what a site offers. */
222
- export declare const EMAIL_TOPIC_PRODUCT_UPDATES = "product-updates";
223
- /** One person here writing to another about working together. */
224
- export declare const EMAIL_TOPIC_SALES = "sales";
222
+ /** One stream a plugin declares, as compiled from `plugins.config.json`. */
223
+ export interface DeclaredSubscriptionTopic {
224
+ /** The plugin that sends under it. */
225
+ pluginId: string;
226
+ /**
227
+ * A wire value: a Firestore path component and a colon-joined component of
228
+ * the unsubscribe link's signed subject. Changing one orphans every opt-out
229
+ * already recorded against it.
230
+ */
231
+ id: string;
232
+ name: string;
233
+ description: string;
234
+ /** Its place on the preference page. */
235
+ order: number;
236
+ /** The stream a message belongs to when it names none. */
237
+ default?: true;
238
+ }
225
239
  /**
226
- * The catalog every org has before anyone opens the console.
227
- *
228
- * Four, not twelve. A preference page whose value is "leave one stream without
229
- * leaving all of them" stops working the moment the list is long enough that
230
- * reading it is a chore, and a merchant who needs a fifth can add one. The ids
231
- * are the generic names an unsubscribing recipient can recognize without
232
- * knowing anything about the sender's internal vocabulary.
240
+ * The catalog every org has before anyone opens the console: the streams the
241
+ * plugins declare, in preference-page order.
242
+ *
243
+ * A handful, not a dozen. A preference page whose value is "leave one stream
244
+ * without leaving all of them" stops working the moment the list is long
245
+ * enough that reading it is a chore, and a merchant who needs another can add
246
+ * one. The ids are the generic names an unsubscribing recipient can recognize
247
+ * without knowing anything about the sender's internal vocabulary.
233
248
  */
234
- export declare const DEFAULT_EMAIL_TOPICS: readonly EmailTopic[];
249
+ export declare const DECLARED_SUBSCRIPTION_TOPICS: readonly SubscriptionTopic[];
235
250
  /**
236
- * The topic a campaign carries when its author picked none.
251
+ * The stream a message belongs to when its author picked none: the one a
252
+ * plugin declares `default`, or `''` when none does.
237
253
  *
238
- * Every campaign resolves to SOME topic, because a campaign with no topic
239
- * would mint an unsubscribe link the preference page cannot place — it could
240
- * offer the catalog but not say which entry this message was, which is the one
241
- * thing the recipient came to the page knowing.
254
+ * Every campaign resolves to SOME topic while one is declared, because a
255
+ * campaign with no topic would mint an unsubscribe link the preference page
256
+ * cannot place — it could offer the catalog but not say which entry this
257
+ * message was, which is the one thing the recipient came to the page knowing.
242
258
  */
243
- export declare const DEFAULT_CAMPAIGN_TOPIC_ID = "marketing";
259
+ export declare const DEFAULT_SUBSCRIPTION_TOPIC_ID: string;
244
260
  /**
245
261
  * WHICH STREAM AN AUTOMATED EMAIL BELONGS TO — the one answer, named once.
246
262
  *
@@ -259,7 +275,7 @@ export declare const DEFAULT_CAMPAIGN_TOPIC_ID = "marketing";
259
275
  * which is not "the default topic", and must not be signed into a
260
276
  * link as one.
261
277
  */
262
- export declare function flowEmailTopicId(topicId: string | null | undefined, scope?: 'scheduled' | 'immediate'): string;
278
+ export declare function flowSubscriptionTopicId(topicId: string | null | undefined, scope?: 'scheduled' | 'immediate'): string;
263
279
  /**
264
280
  * Whether `value` may be a topic id.
265
281
  *
@@ -270,9 +286,9 @@ export declare function flowEmailTopicId(topicId: string | null | undefined, sco
270
286
  * parameter tuples. See `signatureMatches` in the email plugin's
271
287
  * `unsubscribe-link.ts` for what that ambiguity would buy.
272
288
  */
273
- export declare function isEmailTopicId(value: unknown): value is string;
289
+ export declare function isSubscriptionTopicId(value: unknown): value is string;
274
290
  /** Coerces one stored document into a topic, or `null` if it is not one. */
275
- export declare function normalizeEmailTopic(id: unknown, data: Record<string, unknown> | null | undefined): EmailTopic | null;
291
+ export declare function normalizeSubscriptionTopic(id: unknown, data: Record<string, unknown> | null | undefined): SubscriptionTopic | null;
276
292
  /**
277
293
  * The catalog a reader sees: the built-in floor, overlaid by whatever the org
278
294
  * has stored, plus the org's own topics.
@@ -286,7 +302,7 @@ export declare function normalizeEmailTopic(id: unknown, data: Record<string, un
286
302
  * alphabetically after, so the preference page's checkbox order is stable
287
303
  * across renders and across sites.
288
304
  */
289
- export declare function mergeEmailTopics(stored: readonly EmailTopic[] | null | undefined): EmailTopic[];
305
+ export declare function mergeSubscriptionTopics(stored: readonly SubscriptionTopic[] | null | undefined): SubscriptionTopic[];
290
306
  /**
291
307
  * The catalog minus retired topics — what a composer's picker and a
292
308
  * preference page's checkboxes offer.
@@ -296,7 +312,7 @@ export declare function mergeEmailTopics(stored: readonly EmailTopic[] | null |
296
312
  * belongs to that topic, and re-pointing it at something else would attribute
297
313
  * the unsubscribes to the wrong stream.
298
314
  */
299
- export declare function activeEmailTopics(topics: readonly EmailTopic[]): EmailTopic[];
315
+ export declare function activeSubscriptionTopics(topics: readonly SubscriptionTopic[]): SubscriptionTopic[];
300
316
  /**
301
317
  * The topic a campaign belongs to, given what it stored and what the org
302
318
  * offers.
@@ -307,4 +323,4 @@ export declare function activeEmailTopics(topics: readonly EmailTopic[]): EmailT
307
323
  * page that names A topic, not on one that says the message came from
308
324
  * nowhere.
309
325
  */
310
- export declare function resolveCampaignTopic(topicId: string | null | undefined, topics: readonly EmailTopic[]): EmailTopic;
326
+ export declare function resolveSubscriptionTopic(topicId: string | null | undefined, topics: readonly SubscriptionTopic[]): SubscriptionTopic;