@aglyn/aglyn 1.0.0-beta.220 → 1.0.0-beta.222
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +15 -11
- package/src/lib/app-utils/agent-openapi.js +1 -1
- package/src/lib/app-utils/agent-openapi.js.map +1 -1
- package/src/lib/app-utils/analytics-events.d.ts +3 -2
- package/src/lib/app-utils/analytics-events.js +3 -2
- package/src/lib/app-utils/analytics-events.js.map +1 -1
- package/src/lib/app-utils/api-plugins.d.ts +30 -0
- package/src/lib/app-utils/api-plugins.js +24 -1
- package/src/lib/app-utils/api-plugins.js.map +1 -1
- package/src/lib/app-utils/author-html.d.ts +1 -1
- package/src/lib/app-utils/author-html.js.map +1 -1
- package/src/lib/app-utils/bandwidth-cap.d.ts +12 -1
- package/src/lib/app-utils/bandwidth-cap.js +17 -1
- package/src/lib/app-utils/bandwidth-cap.js.map +1 -1
- package/src/lib/app-utils/compose-reusable-components.d.ts +19 -0
- package/src/lib/app-utils/compose-reusable-components.js +116 -26
- package/src/lib/app-utils/compose-reusable-components.js.map +1 -1
- package/src/lib/app-utils/console-routes.d.ts +4 -0
- package/src/lib/app-utils/console-routes.js +3 -0
- package/src/lib/app-utils/console-routes.js.map +1 -1
- package/src/lib/app-utils/contacts.d.ts +71 -0
- package/src/lib/app-utils/contacts.js +55 -0
- package/src/lib/app-utils/contacts.js.map +1 -1
- package/src/lib/app-utils/contexts.d.ts +1 -0
- package/src/lib/app-utils/contexts.js +1 -0
- package/src/lib/app-utils/contexts.js.map +1 -1
- package/src/lib/app-utils/crm-email-templates.js +21 -4
- package/src/lib/app-utils/crm-email-templates.js.map +1 -1
- package/src/lib/app-utils/crm-kinds.d.ts +2 -0
- package/src/lib/app-utils/crm-kinds.js +1 -0
- package/src/lib/app-utils/crm-kinds.js.map +1 -1
- package/src/lib/app-utils/crm.d.ts +1199 -67
- package/src/lib/app-utils/crm.js +1951 -310
- package/src/lib/app-utils/crm.js.map +1 -1
- package/src/lib/app-utils/csv-import.d.ts +10 -38
- package/src/lib/app-utils/csv-import.js +17 -42
- package/src/lib/app-utils/csv-import.js.map +1 -1
- package/src/lib/app-utils/csv.d.ts +32 -11
- package/src/lib/app-utils/csv.js +43 -5
- package/src/lib/app-utils/csv.js.map +1 -1
- package/src/lib/app-utils/default-site.d.ts +116 -0
- package/src/lib/app-utils/default-site.js +1024 -0
- package/src/lib/app-utils/default-site.js.map +1 -0
- package/src/lib/app-utils/docs-help.generated.d.ts +23 -23
- package/src/lib/app-utils/docs-help.generated.js +47 -10
- package/src/lib/app-utils/docs-help.generated.js.map +1 -1
- package/src/lib/app-utils/docs-index.generated.js +746 -151
- package/src/lib/app-utils/docs-index.generated.js.map +1 -1
- package/src/lib/app-utils/draft-placeholders.d.ts +76 -0
- package/src/lib/app-utils/draft-placeholders.js +115 -0
- package/src/lib/app-utils/draft-placeholders.js.map +1 -0
- package/src/lib/app-utils/entity-picker-context.d.ts +19 -15
- package/src/lib/app-utils/entity-picker-context.js +4 -4
- package/src/lib/app-utils/entity-picker-context.js.map +1 -1
- package/src/lib/app-utils/expand-repeatables.d.ts +66 -10
- package/src/lib/app-utils/expand-repeatables.js +88 -14
- package/src/lib/app-utils/expand-repeatables.js.map +1 -1
- package/src/lib/app-utils/forms.d.ts +33 -22
- package/src/lib/app-utils/forms.js +47 -28
- package/src/lib/app-utils/forms.js.map +1 -1
- package/src/lib/app-utils/full-use-cost.d.ts +277 -0
- package/src/lib/app-utils/full-use-cost.js +421 -0
- package/src/lib/app-utils/full-use-cost.js.map +1 -0
- package/src/lib/app-utils/health-report.js +33 -0
- package/src/lib/app-utils/health-report.js.map +1 -1
- package/src/lib/app-utils/leaving-notice.d.ts +96 -0
- package/src/lib/app-utils/leaving-notice.js +157 -0
- package/src/lib/app-utils/leaving-notice.js.map +1 -0
- package/src/lib/app-utils/llms-txt.d.ts +20 -0
- package/src/lib/app-utils/llms-txt.js +7 -1
- package/src/lib/app-utils/llms-txt.js.map +1 -1
- package/src/lib/app-utils/media-asset-facts.d.ts +16 -1
- package/src/lib/app-utils/media-asset-facts.js +40 -13
- package/src/lib/app-utils/media-asset-facts.js.map +1 -1
- package/src/lib/app-utils/media-bandwidth.d.ts +52 -0
- package/src/lib/app-utils/media-bandwidth.js +94 -0
- package/src/lib/app-utils/media-bandwidth.js.map +1 -0
- package/src/lib/app-utils/media-ref.d.ts +241 -33
- package/src/lib/app-utils/media-ref.js +324 -43
- package/src/lib/app-utils/media-ref.js.map +1 -1
- package/src/lib/app-utils/media-src.d.ts +8 -8
- package/src/lib/app-utils/media-src.js +27 -11
- package/src/lib/app-utils/media-src.js.map +1 -1
- package/src/lib/app-utils/media-takedown-reach.d.ts +4 -1
- package/src/lib/app-utils/media-takedown-reach.js +6 -3
- package/src/lib/app-utils/media-takedown-reach.js.map +1 -1
- package/src/lib/app-utils/notifications.d.ts +1 -1
- package/src/lib/app-utils/notifications.js +2 -0
- package/src/lib/app-utils/notifications.js.map +1 -1
- package/src/lib/app-utils/operator-alerts.js +17 -0
- package/src/lib/app-utils/operator-alerts.js.map +1 -1
- package/src/lib/app-utils/organizations.d.ts +51 -2
- package/src/lib/app-utils/organizations.js +56 -3
- package/src/lib/app-utils/organizations.js.map +1 -1
- package/src/lib/app-utils/page-record-sources.d.ts +87 -0
- package/src/lib/app-utils/page-record-sources.js +53 -0
- package/src/lib/app-utils/page-record-sources.js.map +1 -0
- package/src/lib/app-utils/paid-media-source.d.ts +3 -7
- package/src/lib/app-utils/paid-media-source.js +5 -19
- package/src/lib/app-utils/paid-media-source.js.map +1 -1
- package/src/lib/app-utils/person-erasure.d.ts +5 -2
- package/src/lib/app-utils/person-erasure.js.map +1 -1
- package/src/lib/app-utils/picklists.d.ts +187 -0
- package/src/lib/app-utils/picklists.js +320 -0
- package/src/lib/app-utils/picklists.js.map +1 -0
- package/src/lib/app-utils/plan-entitlements.d.ts +220 -50
- package/src/lib/app-utils/plan-entitlements.js +309 -115
- package/src/lib/app-utils/plan-entitlements.js.map +1 -1
- package/src/lib/app-utils/realm-host-surface.generated.js +2 -0
- package/src/lib/app-utils/realm-host-surface.generated.js.map +1 -1
- package/src/lib/app-utils/release-flags.d.ts +1 -1
- package/src/lib/app-utils/release-flags.js +11 -0
- package/src/lib/app-utils/release-flags.js.map +1 -1
- package/src/lib/app-utils/rendered-widths.d.ts +121 -0
- package/src/lib/app-utils/rendered-widths.js +211 -0
- package/src/lib/app-utils/rendered-widths.js.map +1 -0
- package/src/lib/app-utils/repeat-sources.d.ts +2 -1
- package/src/lib/app-utils/repeat-sources.js.map +1 -1
- package/src/lib/app-utils/screen-link-context-value.d.ts +7 -0
- package/src/lib/app-utils/screen-link-context-value.js.map +1 -1
- package/src/lib/app-utils/screen-link-context.js +14 -2
- package/src/lib/app-utils/screen-link-context.js.map +1 -1
- package/src/lib/app-utils/screen-route.d.ts +157 -36
- package/src/lib/app-utils/screen-route.js +191 -41
- package/src/lib/app-utils/screen-route.js.map +1 -1
- package/src/lib/app-utils/seo-audit.d.ts +11 -1
- package/src/lib/app-utils/seo-audit.js +33 -13
- package/src/lib/app-utils/seo-audit.js.map +1 -1
- package/src/lib/app-utils/seo-keywords.d.ts +11 -0
- package/src/lib/app-utils/seo-keywords.js +19 -5
- package/src/lib/app-utils/seo-keywords.js.map +1 -1
- package/src/lib/app-utils/seo-page-facts.d.ts +47 -4
- package/src/lib/app-utils/seo-page-facts.js +136 -31
- package/src/lib/app-utils/seo-page-facts.js.map +1 -1
- package/src/lib/app-utils/seo-site-scan.d.ts +42 -4
- package/src/lib/app-utils/seo-site-scan.js +113 -12
- package/src/lib/app-utils/seo-site-scan.js.map +1 -1
- package/src/lib/app-utils/server.d.ts +5 -4
- package/src/lib/app-utils/server.js +14 -5
- package/src/lib/app-utils/server.js.map +1 -1
- package/src/lib/app-utils/site-icon-set.d.ts +195 -0
- package/src/lib/app-utils/site-icon-set.js +351 -0
- package/src/lib/app-utils/site-icon-set.js.map +1 -0
- package/src/lib/app-utils/site-interactions.d.ts +101 -4
- package/src/lib/app-utils/site-interactions.js +120 -4
- package/src/lib/app-utils/site-interactions.js.map +1 -1
- package/src/lib/app-utils/starter-template-nodes.d.ts +7 -0
- package/src/lib/app-utils/starter-template-nodes.js +3 -0
- package/src/lib/app-utils/starter-template-nodes.js.map +1 -1
- package/src/lib/app-utils/starter-templates.d.ts +5 -19
- package/src/lib/app-utils/starter-templates.js +5 -49
- package/src/lib/app-utils/starter-templates.js.map +1 -1
- package/src/lib/app-utils/transfer-launcher-context.d.ts +136 -0
- package/src/lib/app-utils/transfer-launcher-context.js +23 -0
- package/src/lib/app-utils/transfer-launcher-context.js.map +1 -0
- package/src/lib/app-utils/transfer-resume-import.d.ts +39 -0
- package/src/lib/app-utils/transfer-resume-import.js +128 -0
- package/src/lib/app-utils/transfer-resume-import.js.map +1 -0
- package/src/lib/app-utils/upgrade-proposal.d.ts +66 -0
- package/src/lib/app-utils/upgrade-proposal.js +95 -0
- package/src/lib/app-utils/upgrade-proposal.js.map +1 -0
- package/src/lib/app-utils/utc-month.d.ts +33 -0
- package/src/lib/app-utils/utc-month.js +35 -0
- package/src/lib/app-utils/utc-month.js.map +1 -0
- package/src/lib/app-utils/visitor-record-ceiling.d.ts +4 -4
- package/src/lib/app-utils/visitor-record-ceiling.js +4 -4
- package/src/lib/app-utils/visitor-record-ceiling.js.map +1 -1
- package/src/lib/app-utils/wire-nodes.d.ts +39 -19
- package/src/lib/app-utils/wire-nodes.js +120 -34
- package/src/lib/app-utils/wire-nodes.js.map +1 -1
- package/src/lib/data-transfer/access.d.ts +74 -0
- package/src/lib/data-transfer/access.js +93 -0
- package/src/lib/data-transfer/access.js.map +1 -0
- package/src/lib/data-transfer/derive.d.ts +246 -0
- package/src/lib/data-transfer/derive.js +1007 -0
- package/src/lib/data-transfer/derive.js.map +1 -0
- package/src/lib/data-transfer/export-file.d.ts +46 -0
- package/src/lib/data-transfer/export-file.js +146 -0
- package/src/lib/data-transfer/export-file.js.map +1 -0
- package/src/lib/data-transfer/field-catalog.d.ts +134 -0
- package/src/lib/data-transfer/field-catalog.js +278 -0
- package/src/lib/data-transfer/field-catalog.js.map +1 -0
- package/src/lib/data-transfer/header-match.d.ts +129 -0
- package/src/lib/data-transfer/header-match.js +367 -0
- package/src/lib/data-transfer/header-match.js.map +1 -0
- package/src/lib/data-transfer/index.d.ts +34 -0
- package/src/lib/data-transfer/index.js +40 -0
- package/src/lib/data-transfer/index.js.map +1 -0
- package/src/lib/data-transfer/job.d.ts +190 -0
- package/src/lib/data-transfer/job.js +229 -0
- package/src/lib/data-transfer/job.js.map +1 -0
- package/src/lib/data-transfer/lookup.d.ts +45 -0
- package/src/lib/data-transfer/lookup.js +71 -0
- package/src/lib/data-transfer/lookup.js.map +1 -0
- package/src/lib/data-transfer/match.d.ts +99 -0
- package/src/lib/data-transfer/match.js +244 -0
- package/src/lib/data-transfer/match.js.map +1 -0
- package/src/lib/data-transfer/package-plan.d.ts +205 -0
- package/src/lib/data-transfer/package-plan.js +475 -0
- package/src/lib/data-transfer/package-plan.js.map +1 -0
- package/src/lib/data-transfer/package.d.ts +181 -0
- package/src/lib/data-transfer/package.js +426 -0
- package/src/lib/data-transfer/package.js.map +1 -0
- package/src/lib/data-transfer/picklist-map.d.ts +139 -0
- package/src/lib/data-transfer/picklist-map.js +271 -0
- package/src/lib/data-transfer/picklist-map.js.map +1 -0
- package/src/lib/data-transfer/plan.d.ts +176 -0
- package/src/lib/data-transfer/plan.js +451 -0
- package/src/lib/data-transfer/plan.js.map +1 -0
- package/src/lib/data-transfer/policy.d.ts +170 -0
- package/src/lib/data-transfer/policy.js +378 -0
- package/src/lib/data-transfer/policy.js.map +1 -0
- package/src/lib/data-transfer/resource.d.ts +211 -0
- package/src/lib/data-transfer/resource.js +241 -0
- package/src/lib/data-transfer/resource.js.map +1 -0
- package/src/lib/data-transfer/review.d.ts +70 -0
- package/src/lib/data-transfer/review.js +233 -0
- package/src/lib/data-transfer/review.js.map +1 -0
- package/src/lib/data-transfer/similarity.d.ts +40 -0
- package/src/lib/data-transfer/similarity.js +106 -0
- package/src/lib/data-transfer/similarity.js.map +1 -0
- package/src/lib/data-transfer/site-package.d.ts +365 -0
- package/src/lib/data-transfer/site-package.js +1077 -0
- package/src/lib/data-transfer/site-package.js.map +1 -0
- package/src/lib/data-transfer/source.d.ts +74 -0
- package/src/lib/data-transfer/source.js +293 -0
- package/src/lib/data-transfer/source.js.map +1 -0
- package/src/lib/data-transfer/transfer-api.d.ts +898 -0
- package/src/lib/data-transfer/transfer-api.js +107 -0
- package/src/lib/data-transfer/transfer-api.js.map +1 -0
- package/src/lib/foundation/definitions/org-billing.types.d.ts +31 -0
- package/src/lib/foundation/definitions/org-billing.types.js.map +1 -1
- package/src/lib/foundation/definitions/organization.types.d.ts +42 -1
- package/src/lib/foundation/definitions/organization.types.js.map +1 -1
- package/src/lib/foundation/definitions/platform.types.d.ts +6 -4
- package/src/lib/foundation/definitions/platform.types.js.map +1 -1
- package/src/lib/foundation/index.d.ts +1 -1
- package/src/lib/foundation/index.js.map +1 -1
- package/src/lib/plugin-manager/feature-plugins.d.ts +91 -2
- package/src/lib/plugin-manager/feature-plugins.js +48 -3
- package/src/lib/plugin-manager/feature-plugins.js.map +1 -1
- package/src/lib/plugin-manager/first-party-plugins.generated.d.ts +56 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.js +1132 -27
- package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -1
- package/src/lib/plugin-manager/index.d.ts +0 -1
- package/src/lib/plugin-manager/index.js +0 -1
- package/src/lib/plugin-manager/index.js.map +1 -1
- package/src/lib/plugin-manager/interaction-recipes.d.ts +142 -0
- package/src/lib/plugin-manager/interaction-recipes.js +104 -0
- package/src/lib/plugin-manager/interaction-recipes.js.map +1 -0
- package/src/lib/plugin-manager/interaction-step-checks.d.ts +66 -0
- package/src/lib/plugin-manager/interaction-step-checks.js +86 -0
- package/src/lib/plugin-manager/interaction-step-checks.js.map +1 -0
- package/src/lib/plugin-manager/plugin-artifact-types.d.ts +235 -0
- package/src/lib/plugin-manager/plugin-artifact-types.js +99 -0
- package/src/lib/plugin-manager/plugin-artifact-types.js.map +1 -0
- package/src/lib/plugin-manager/plugin-contact-capture.d.ts +8 -0
- package/src/lib/plugin-manager/plugin-contact-capture.js.map +1 -1
- package/src/lib/plugin-manager/plugin-conversion-credit.d.ts +216 -0
- package/src/lib/plugin-manager/plugin-conversion-credit.js +91 -0
- package/src/lib/plugin-manager/plugin-conversion-credit.js.map +1 -0
- package/src/lib/plugin-manager/plugin-entity-pickers.d.ts +83 -0
- package/src/lib/plugin-manager/plugin-entity-pickers.js +87 -0
- package/src/lib/plugin-manager/plugin-entity-pickers.js.map +1 -0
- package/src/lib/plugin-manager/plugin-host-resources.d.ts +6 -0
- package/src/lib/plugin-manager/plugin-host-resources.js +6 -1
- package/src/lib/plugin-manager/plugin-host-resources.js.map +1 -1
- package/src/lib/plugin-manager/plugin-intake-gates.d.ts +75 -0
- package/src/lib/plugin-manager/plugin-intake-gates.js +49 -0
- package/src/lib/plugin-manager/plugin-intake-gates.js.map +1 -0
- package/src/lib/plugin-manager/plugin-jobs.d.ts +5 -5
- package/src/lib/plugin-manager/plugin-jobs.js +7 -7
- package/src/lib/plugin-manager/plugin-jobs.js.map +1 -1
- package/src/lib/plugin-manager/plugin-live-paths.d.ts +70 -0
- package/src/lib/plugin-manager/plugin-live-paths.js +66 -0
- package/src/lib/plugin-manager/plugin-live-paths.js.map +1 -0
- package/src/lib/plugin-manager/plugin-org-erasure.d.ts +3 -2
- package/src/lib/plugin-manager/plugin-org-erasure.js +30 -5
- package/src/lib/plugin-manager/plugin-org-erasure.js.map +1 -1
- package/src/lib/plugin-manager/plugin-person-erasure.d.ts +68 -9
- package/src/lib/plugin-manager/plugin-person-erasure.js +196 -51
- package/src/lib/plugin-manager/plugin-person-erasure.js.map +1 -1
- package/src/lib/plugin-manager/plugin-person-records.d.ts +275 -0
- package/src/lib/plugin-manager/plugin-person-records.js +107 -0
- package/src/lib/plugin-manager/plugin-person-records.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-counts.d.ts +76 -0
- package/src/lib/plugin-manager/plugin-record-counts.js +49 -0
- package/src/lib/plugin-manager/plugin-record-counts.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-email-state.d.ts +26 -0
- package/src/lib/plugin-manager/plugin-record-email-state.js +16 -0
- package/src/lib/plugin-manager/plugin-record-email-state.js.map +1 -1
- package/src/lib/plugin-manager/plugin-record-index.d.ts +10 -0
- package/src/lib/plugin-manager/plugin-record-index.js.map +1 -1
- package/src/lib/plugin-manager/plugin-record-lists.d.ts +86 -6
- package/src/lib/plugin-manager/plugin-record-lists.js +42 -5
- package/src/lib/plugin-manager/plugin-record-lists.js.map +1 -1
- package/src/lib/plugin-manager/plugin-record-origin.d.ts +79 -0
- package/src/lib/plugin-manager/plugin-record-origin.js +46 -0
- package/src/lib/plugin-manager/plugin-record-origin.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-pages.d.ts +37 -0
- package/src/lib/plugin-manager/plugin-record-pages.js +52 -0
- package/src/lib/plugin-manager/plugin-record-pages.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-timeline.d.ts +60 -0
- package/src/lib/plugin-manager/plugin-record-timeline.js +16 -0
- package/src/lib/plugin-manager/plugin-record-timeline.js.map +1 -1
- package/src/lib/plugin-manager/plugin-resource-drafts.d.ts +5 -5
- package/src/lib/plugin-manager/plugin-resource-drafts.js.map +1 -1
- package/src/lib/plugin-manager/plugin-revocations.d.ts +64 -0
- package/src/lib/plugin-manager/plugin-revocations.js +47 -0
- package/src/lib/plugin-manager/plugin-revocations.js.map +1 -0
- package/src/lib/plugin-manager/plugin-send-tallies.d.ts +69 -0
- package/src/lib/plugin-manager/plugin-send-tallies.js +45 -0
- package/src/lib/plugin-manager/plugin-send-tallies.js.map +1 -0
- package/src/lib/plugin-manager/plugin-server-steps.d.ts +170 -0
- package/src/lib/plugin-manager/plugin-server-steps.js +116 -0
- package/src/lib/plugin-manager/plugin-server-steps.js.map +1 -0
- package/src/lib/plugin-manager/plugin-site-bundle.d.ts +40 -0
- package/src/lib/plugin-manager/plugin-site-bundle.js +4 -0
- package/src/lib/plugin-manager/plugin-site-bundle.js.map +1 -1
- package/src/lib/plugin-manager/plugin-site-export.d.ts +57 -1
- package/src/lib/plugin-manager/plugin-site-export.js +23 -10
- package/src/lib/plugin-manager/plugin-site-export.js.map +1 -1
- package/src/lib/plugin-manager/plugin-sitemap-readers.d.ts +146 -0
- package/src/lib/plugin-manager/plugin-sitemap-readers.js +110 -0
- package/src/lib/plugin-manager/plugin-sitemap-readers.js.map +1 -0
- package/src/lib/plugin-manager/plugin-transfer-resources.d.ts +714 -0
- package/src/lib/plugin-manager/plugin-transfer-resources.js +443 -0
- package/src/lib/plugin-manager/plugin-transfer-resources.js.map +1 -0
- package/src/lib/plugin-manager/plugin-usage-axes.d.ts +54 -5
- package/src/lib/plugin-manager/plugin-usage-axes.js +11 -3
- package/src/lib/plugin-manager/plugin-usage-axes.js.map +1 -1
- package/src/lib/plugin-manager/plugin-user-erasure.js +9 -1
- package/src/lib/plugin-manager/plugin-user-erasure.js.map +1 -1
- package/src/lib/plugin-manager/plugin-visitor-doors.d.ts +104 -0
- package/src/lib/plugin-manager/plugin-visitor-doors.js +108 -0
- package/src/lib/plugin-manager/plugin-visitor-doors.js.map +1 -0
- package/src/lib/plugin-manager/realm-host-aglyn.generated.js +2 -0
- package/src/lib/plugin-manager/realm-host-aglyn.generated.js.map +1 -1
- package/src/lib/plugin-manager/repeat-rows.d.ts +5 -6
- package/src/lib/plugin-manager/repeat-rows.js.map +1 -1
- package/src/lib/app-utils/actions.d.ts +0 -310
- package/src/lib/app-utils/actions.js +0 -506
- package/src/lib/app-utils/actions.js.map +0 -1
- package/src/lib/app-utils/automation-placeholders.d.ts +0 -72
- package/src/lib/app-utils/automation-placeholders.js +0 -207
- package/src/lib/app-utils/automation-placeholders.js.map +0 -1
- package/src/lib/app-utils/dataset-models.d.ts +0 -339
- package/src/lib/app-utils/dataset-models.js +0 -722
- package/src/lib/app-utils/dataset-models.js.map +0 -1
- package/src/lib/app-utils/datasets.d.ts +0 -171
- package/src/lib/app-utils/datasets.js +0 -227
- package/src/lib/app-utils/datasets.js.map +0 -1
- package/src/lib/app-utils/form-abuse-ceiling.d.ts +0 -146
- package/src/lib/app-utils/form-abuse-ceiling.js +0 -158
- package/src/lib/app-utils/form-abuse-ceiling.js.map +0 -1
- package/src/lib/plugin-manager/order-fulfilment.d.ts +0 -142
- package/src/lib/plugin-manager/order-fulfilment.js +0 -104
- package/src/lib/plugin-manager/order-fulfilment.js.map +0 -1
|
@@ -36,9 +36,10 @@
|
|
|
36
36
|
* - a BAND names the rollup fields that measure it and the entitlement that
|
|
37
37
|
* says what the plan includes. The utilization table reads it beside
|
|
38
38
|
* core's own bands. A METERED band is also billed past what the plan
|
|
39
|
-
* includes, at
|
|
40
|
-
*
|
|
41
|
-
* staff usage rows read it
|
|
39
|
+
* includes, at its published billed rate (cost + 30% kept after card
|
|
40
|
+
* fees), beside storage and bandwidth: the invoice sweep, the Billing
|
|
41
|
+
* card's estimate, the monthly summary and the staff usage rows read it
|
|
42
|
+
* from here.
|
|
42
43
|
* - a SPEND LINE names the month document holding what the plugin's usage
|
|
43
44
|
* came to at the rates it bills, the deployment variable naming the month
|
|
44
45
|
* it is first charged for, and the unit a customer sees it in. The usage
|
|
@@ -133,6 +134,17 @@ export interface PluginUsageBandDeclaration {
|
|
|
133
134
|
* workspace's sites.
|
|
134
135
|
*/
|
|
135
136
|
hostCounter?: string;
|
|
137
|
+
/**
|
|
138
|
+
* The WORKSPACE-wide monthly counter the band is enforced against:
|
|
139
|
+
* `orgs/{orgId}/counters/{orgCounter}`, field `{month}` (AGL-3472). Declared
|
|
140
|
+
* by a band whose runtime counts every unit on the org's counter as well as
|
|
141
|
+
* on the site's, in one write, so a workspace-wide band is held to every
|
|
142
|
+
* site's use rather than handed to each site whole. The Billing card meters
|
|
143
|
+
* the band once for the organization from it, where a band without one is
|
|
144
|
+
* metered per site. The usage sweep and alerts still sum `hostCounter`,
|
|
145
|
+
* which the same write moves.
|
|
146
|
+
*/
|
|
147
|
+
orgCounter?: string;
|
|
136
148
|
/**
|
|
137
149
|
* The workspace is WARNED as it approaches and reaches this band, by the
|
|
138
150
|
* usage-alerts sweep, from its `hostCounter` against what the plan includes
|
|
@@ -149,10 +161,37 @@ export interface PluginUsageBandDeclaration {
|
|
|
149
161
|
reached: string;
|
|
150
162
|
approach: string;
|
|
151
163
|
};
|
|
164
|
+
/**
|
|
165
|
+
* The console's quota banner WARNS an organization-wide reader on every
|
|
166
|
+
* console page as the workspace approaches and reaches this band
|
|
167
|
+
* (AGL-2898, AGL-3080). `standing` is a console API path the plugin
|
|
168
|
+
* serves, asked `?orgId=` with the reader's token, that answers the
|
|
169
|
+
* band's standing in its own unit under `member` — `{ used, limit }`,
|
|
170
|
+
* `limit: null` for a plan with no band, which is no row — and
|
|
171
|
+
* `stopsAtBand`: whether reaching it stops the feature (the reading when
|
|
172
|
+
* the route does not say) or bills past it. `approach` is the sentence
|
|
173
|
+
* above 80%; `reached.stops` and `reached.bills` the two at the band.
|
|
174
|
+
* `linksUsage` says the sentences name Billing → Usage, and the banner
|
|
175
|
+
* offers the link.
|
|
176
|
+
*
|
|
177
|
+
* A route, not a counter: a band's meter may be one no client may read,
|
|
178
|
+
* and the route answers in the unit the customer was sold.
|
|
179
|
+
*/
|
|
180
|
+
consoleWarning?: {
|
|
181
|
+
standing: string;
|
|
182
|
+
member: string;
|
|
183
|
+
approach: string;
|
|
184
|
+
reached: {
|
|
185
|
+
stops: string;
|
|
186
|
+
bills: string;
|
|
187
|
+
};
|
|
188
|
+
linksUsage?: boolean;
|
|
189
|
+
};
|
|
152
190
|
/**
|
|
153
191
|
* The band is one of the INFRASTRUCTURE meters (AGL-1280): what the
|
|
154
|
-
* workspace uses past it is billed at
|
|
155
|
-
* storage and bandwidth, on the same
|
|
192
|
+
* workspace uses past it is billed at its published billed rate (cost +
|
|
193
|
+
* 30% kept after card fees), beside storage and bandwidth, on the same
|
|
194
|
+
* invoice line and the same estimate.
|
|
156
195
|
* A metered band names one rollup field and the `hostCounter` it is
|
|
157
196
|
* measured by.
|
|
158
197
|
*/
|
|
@@ -265,6 +304,16 @@ export type ResolvedPluginCountedBand = ResolvedPluginUsageBand & {
|
|
|
265
304
|
* band's counter is read with the infrastructure meters instead.
|
|
266
305
|
*/
|
|
267
306
|
export declare function countedPluginBands(): readonly ResolvedPluginCountedBand[];
|
|
307
|
+
/** A declared band kept on a workspace-wide counter. */
|
|
308
|
+
export type ResolvedPluginOrgCountedBand = ResolvedPluginUsageBand & {
|
|
309
|
+
orgCounter: string;
|
|
310
|
+
};
|
|
311
|
+
/**
|
|
312
|
+
* Every band with a workspace-wide counter (`orgCounter`), in band order: the
|
|
313
|
+
* bands the Billing card meters once for the organization, from the counter
|
|
314
|
+
* the band is enforced against.
|
|
315
|
+
*/
|
|
316
|
+
export declare function orgCountedPluginBands(): readonly ResolvedPluginOrgCountedBand[];
|
|
268
317
|
/** The rollup field a metered band records its count under. */
|
|
269
318
|
export declare function meteredBandField(band: ResolvedPluginMeteredBand): string;
|
|
270
319
|
/**
|
|
@@ -35,9 +35,10 @@
|
|
|
35
35
|
* - a BAND names the rollup fields that measure it and the entitlement that
|
|
36
36
|
* says what the plan includes. The utilization table reads it beside
|
|
37
37
|
* core's own bands. A METERED band is also billed past what the plan
|
|
38
|
-
* includes, at
|
|
39
|
-
*
|
|
40
|
-
* staff usage rows read it
|
|
38
|
+
* includes, at its published billed rate (cost + 30% kept after card
|
|
39
|
+
* fees), beside storage and bandwidth: the invoice sweep, the Billing
|
|
40
|
+
* card's estimate, the monthly summary and the staff usage rows read it
|
|
41
|
+
* from here.
|
|
41
42
|
* - a SPEND LINE names the month document holding what the plugin's usage
|
|
42
43
|
* came to at the rates it bills, the deployment variable naming the month
|
|
43
44
|
* it is first charged for, and the unit a customer sees it in. The usage
|
|
@@ -86,6 +87,13 @@ export function pluginUsageBands() {
|
|
|
86
87
|
*/ export function countedPluginBands() {
|
|
87
88
|
return PLUGIN_USAGE_BANDS_DECLARED.filter((band)=>Boolean(band.hostCounter && !band.metered));
|
|
88
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Every band with a workspace-wide counter (`orgCounter`), in band order: the
|
|
92
|
+
* bands the Billing card meters once for the organization, from the counter
|
|
93
|
+
* the band is enforced against.
|
|
94
|
+
*/ export function orgCountedPluginBands() {
|
|
95
|
+
return PLUGIN_USAGE_BANDS_DECLARED.filter((band)=>Boolean(band.orgCounter));
|
|
96
|
+
}
|
|
89
97
|
/** The rollup field a metered band records its count under. */ export function meteredBandField(band) {
|
|
90
98
|
return band.fields[0];
|
|
91
99
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-usage-axes.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * WHAT A PLUGIN'S USAGE COSTS, AND HOW MUCH OF ITS BAND IT SPENT (AGL-3080).\n *\n * The platform keeps one cost model (`orgMonthlyCogsUsd`) and one\n * utilization table (`margin-utilization.ts`), and both read the monthly\n * usage rollup. Several of the rollup's meters are a plugin's: the AI\n * plugin's provider spend, the CRM's records, the forms plugin's\n * submissions, the workflows plugin's runs. Core used to name each of them —\n * its rollup field, the unit rate that prices it, the band it is measured\n * against — so a plugin that metered something new could not reach the\n * discount guardrail without a core edit, and core could not be taken\n * without the plugins it named.\n *\n * So a plugin declares its meters, and core composes them:\n *\n * - a COST AXIS names the rollup fields a meter is recorded under and the\n * `ORG_COGS_UNIT_RATES_USD` key that prices one unit, or no key when the\n * field is already dollars. `orgMonthlyCogsUsd` prices it beside core's\n * own axes, and `orgCogsInputFrom` forwards its fields.\n * - a BAND names the rollup fields that measure it and the entitlement that\n * says what the plan includes. The utilization table reads it beside\n * core's own bands. A METERED band is also billed past what the plan\n * includes, at cost × `METERED_MARKUP`, beside storage and bandwidth: the\n * invoice sweep, the Billing card's estimate, the monthly summary and the\n * staff usage rows read it from here.\n * - a SPEND LINE names the month document holding what the plugin's usage\n * came to at the rates it bills, the deployment variable naming the month\n * it is first charged for, and the unit a customer sees it in. The usage\n * budget shows it beside the metered figure and counts it once charged.\n * - a METER names what the plugin measures in the monthly usage sweep\n * (`plugin-usage-meters.ts`), so the sweep can refuse to bill a month the\n * registered meter is missing from.\n *\n * ## What core keeps\n *\n * The MONEY. Every unit rate stays in `ORG_COGS_UNIT_RATES_USD`, beside the\n * billed table it is reconciled against (`METERED_UNIT_RATES_USD`, which a\n * metered band names its rate in), and every included figure stays in\n * `PLAN_ENTITLEMENTS`. A declaration names fields and keys; it carries no\n * price. The one number a declaration may carry is a band's unit cost, where\n * the band is sold in a unit OF cost (a credit is a fixed quantity of\n * dollars), and that number is the plugin's own definition of its unit.\n *\n * ## Compiled, never registered\n *\n * The cost model's readers include the staff org page, which prices a rollup\n * in the browser, and the discount guardrail, whose every wrong answer is in\n * the approving direction: a cost axis a registry had not filled would price\n * at nothing and approve a discount the margin cannot carry. So these are\n * compiled from each plugin's `usage-axes` declaration by the manifest\n * generator, like the plan figures, and a rate key core does not have is an\n * error rather than a zero.\n */\n\nimport type { ReleaseFlagKey } from '../app-utils/release-flags'\nimport {\n PLUGIN_COST_AXES_DECLARED,\n PLUGIN_SPEND_LINES_DECLARED,\n PLUGIN_USAGE_BANDS_DECLARED,\n} from './first-party-plugins.generated'\n\n/** A meter a plugin contributes to the platform's cost model. */\nexport interface PluginCostAxisDeclaration {\n /** The breakdown key every staff reader shows it under. */\n id: string\n /** Where it sorts among the cost model's axes; core's own are multiples of 10. */\n order: number\n /** Rollup fields summed for the axis. */\n fields: readonly string[]\n /**\n * Read only when every one of `fields` is absent from a rollup — the\n * narrower field an older rollup recorded the same meter under.\n */\n fallbackFields?: readonly string[]\n /**\n * Rollup fields recorded beside the meter so its sum is legible, forwarded\n * by `orgCogsInputFrom` and never priced.\n */\n recordedFields?: readonly string[]\n /**\n * Rollup fields the plugin's usage sweep writes beside the meter for its\n * staff surfaces to read — served on the staff usage rows, `null` where a\n * rollup never wrote one, and never forwarded to the cost model.\n */\n staffFields?: readonly string[]\n /**\n * The `ORG_COGS_UNIT_RATES_USD` key pricing one unit. Absent when the\n * fields are already dollars, which then enter the model at ×1.\n */\n rate?: string\n /**\n * The month's LIVE reading, when the rollup's figure is a snapshot a meter\n * keeps adding to: `orgs/{orgId}/{collection}/{month}`, the first of\n * `fields` that is a positive number. It replaces the axis's first rollup\n * field wherever a reader fetches it.\n */\n live?: { collection: string; fields: readonly string[] }\n}\n\n/** A band a plugin contributes to the utilization table. */\nexport interface PluginUsageBandDeclaration {\n /** The band's key, and the column the staff table shows it under. */\n id: string\n label: string\n order: number\n /** Rollup fields summed for what the org used. */\n fields: readonly string[]\n fallbackFields?: readonly string[]\n /** The resolved entitlement holding what the plan includes. */\n entitlement: string\n /** The entitlement is per SITE and the org-wide band is it × `hostLimit`. */\n perHost?: boolean\n /**\n * The band is sold in a unit of cost and the rollup records dollars: what\n * was used is `ceil(dollars / unitCostUsd)`, rounded UP so spend already\n * made never reads as less of the band.\n */\n unitCostUsd?: number\n /**\n * The per-site monthly counter the band is measured by:\n * `hosts/{hostId}/counters/{hostCounter}`, field `{month}`, summed over the\n * workspace's sites.\n */\n hostCounter?: string\n /**\n * The workspace is WARNED as it approaches and reaches this band, by the\n * usage-alerts sweep, from its `hostCounter` against what the plan includes\n * of `entitlement`, once per threshold per month. `label` names the band in\n * the title (\"monthly workflow runs\") and `noun` in the opening sentence\n * (\"workflow runs\"); `outcome` is what happens at the band — `stops`,\n * `bills` or `continues` — and `reached` and `approach` are the sentences\n * that say so, at the band and approaching it.\n */\n alert?: {\n label: string\n noun: string\n outcome: 'stops' | 'bills' | 'continues'\n reached: string\n approach: string\n }\n /**\n * The band is one of the INFRASTRUCTURE meters (AGL-1280): what the\n * workspace uses past it is billed at our cost × `METERED_MARKUP`, beside\n * storage and bandwidth, on the same invoice line and the same estimate.\n * A metered band names one rollup field and the `hostCounter` it is\n * measured by.\n */\n metered?: PluginMeteredBand\n}\n\n/** How a metered band is priced, quoted and withheld. */\nexport interface PluginMeteredBand {\n /**\n * The `METERED_UNIT_RATES_USD` key holding our cost per unit — never a\n * number: the rate table is the platform's, beside the markup it is\n * published with.\n */\n rate: string\n /** The count a published price is quoted per: `1000` reads \"per 1,000\". */\n quotedPer: number\n /** The band in running prose, plural and lowercase: \"form submissions\". */\n noun: string\n /**\n * A release flag the overage waits behind: while it is off for the\n * workspace, the units are counted and the charge is recorded as withheld\n * rather than billed — nobody is charged for what they cannot reach\n * (AGL-1604). The rollup records the verdict as `{field}Billed` and what\n * was forgone, at cost, as `{field}OverageWithheldUsd`.\n */\n withheldUntil?: ReleaseFlagKey\n}\n\n/**\n * A line of a workspace's monthly SPEND a plugin contributes to its usage\n * budget (`usage-budget.ts`): what the plugin's usage came to this month, in\n * the dollars it is billed at, shown on the customer's budget card and\n * counted toward the budget from the month the plugin starts charging for it.\n */\nexport interface PluginSpendLineDeclaration {\n /** The line's key. */\n id: string\n /** What the budget card and the budget alert call it. */\n label: string\n /**\n * Where the month's figure is read: `orgs/{orgId}/{collection}/{month}`,\n * field `field`, in dollars.\n */\n live: { collection: string; field: string }\n /**\n * The deployment variable naming the first month (`YYYY-MM`) the line is\n * charged for. Until it names this month or an earlier one — and on any\n * value that is not a month — the line is shown and never counted.\n */\n billedFromEnv: string\n /**\n * The unit the customer is shown the line in, when the stored dollars are\n * not theirs to see: `ceil(dollars / costUsd)` of `label`, and the dollar\n * figure never crosses to the browser.\n */\n unit?: { costUsd: number; label: string }\n}\n\n/**\n * A meter the plugin measures in the platform's monthly usage sweep and\n * registers at runtime (`plugin-usage-meters.ts`). Declared as well as\n * registered so the sweep can refuse to bill a workspace's month without it.\n */\nexport interface PluginUsageMeterDeclaration {\n /** As `registerPluginUsageMeter` names it. */\n id: string\n}\n\nexport type ResolvedPluginCostAxis = PluginCostAxisDeclaration & { pluginId: string }\nexport type ResolvedPluginUsageBand = PluginUsageBandDeclaration & { pluginId: string }\nexport type ResolvedPluginSpendLine = PluginSpendLineDeclaration & { pluginId: string }\nexport type ResolvedPluginUsageMeter = PluginUsageMeterDeclaration & { pluginId: string }\n\n/** What a plugin's `usageAxes` function answers. */\nexport interface PluginUsageAxesDeclaration {\n costAxes?: readonly PluginCostAxisDeclaration[]\n bands?: readonly PluginUsageBandDeclaration[]\n spendLines?: readonly PluginSpendLineDeclaration[]\n meters?: readonly PluginUsageMeterDeclaration[]\n}\n\nexport function pluginCostAxes(): readonly ResolvedPluginCostAxis[] {\n return PLUGIN_COST_AXES_DECLARED\n}\n\nexport function pluginUsageBands(): readonly ResolvedPluginUsageBand[] {\n return PLUGIN_USAGE_BANDS_DECLARED\n}\n\n/** A declared band that is metered, with its one field and its counter. */\nexport type ResolvedPluginMeteredBand = ResolvedPluginUsageBand & {\n metered: PluginMeteredBand\n hostCounter: string\n}\n\n/**\n * Every band billed at cost past what the plan includes, in band order — the\n * infrastructure meters a plugin adds beside storage and bandwidth.\n */\nexport function meteredPluginBands(): readonly ResolvedPluginMeteredBand[] {\n return PLUGIN_USAGE_BANDS_DECLARED.filter(\n (band): band is ResolvedPluginMeteredBand =>\n Boolean(band.metered && band.hostCounter),\n )\n}\n\n/** A declared band measured by a per-site counter and never billed past it. */\nexport type ResolvedPluginCountedBand = ResolvedPluginUsageBand & {\n hostCounter: string\n}\n\n/**\n * Every band measured by a per-site counter and not metered, in band order:\n * the usage sweep sums each across the workspace's sites and records it under\n * the band's first field, and the staff usage rows show the count. A metered\n * band's counter is read with the infrastructure meters instead.\n */\nexport function countedPluginBands(): readonly ResolvedPluginCountedBand[] {\n return PLUGIN_USAGE_BANDS_DECLARED.filter(\n (band): band is ResolvedPluginCountedBand =>\n Boolean(band.hostCounter && !band.metered),\n )\n}\n\n/** The rollup field a metered band records its count under. */\nexport function meteredBandField(band: ResolvedPluginMeteredBand): string {\n return band.fields[0]!\n}\n\n/**\n * Where the rollup records a withheld band's verdict (`metered.withheldUntil`):\n * whether the month billed the band's overage, and what was forgone, at cost,\n * when it did not. Without the second a withheld month reads as a month that\n * stayed inside the band.\n */\nexport function meteredBandVerdictFields(band: ResolvedPluginMeteredBand): {\n billed: string\n withheldUsd: string\n} {\n const field = meteredBandField(band)\n return { billed: `${field}Billed`, withheldUsd: `${field}OverageWithheldUsd` }\n}\n\nexport function pluginSpendLines(): readonly ResolvedPluginSpendLine[] {\n return PLUGIN_SPEND_LINES_DECLARED\n}\n\n/** A positive finite number, or 0 — the reading every meter is priced from. */\nfunction meterValue(value: unknown): number {\n const parsed = Number(value ?? 0)\n return Number.isFinite(parsed) && parsed > 0 ? parsed : 0\n}\n\n/**\n * What a rollup recorded for a declared meter: `fields` summed, or\n * `fallbackFields` summed when the rollup carries none of `fields` at all.\n *\n * \"Carries none\" is `null` or absent, never zero. A rollup that measured\n * zero has answered, and must not fall back to a figure recorded under an\n * older, narrower basis.\n */\nexport function declaredMeterReading(\n source: Readonly<Record<string, unknown>> | null | undefined,\n declared: {\n fields: readonly string[]\n fallbackFields?: readonly string[]\n },\n): number {\n const present = declared.fields.some((field) => source?.[field] != null)\n const fields =\n !present && declared.fallbackFields?.length\n ? declared.fallbackFields\n : declared.fields\n return fields.reduce((sum, field) => sum + meterValue(source?.[field]), 0)\n}\n\n/**\n * The live reading a cost axis names: the first of its `live.fields` that is\n * a positive number on the month's document, or `undefined` when none is.\n * `undefined` is \"keep the rollup's snapshot\", never zero.\n */\nexport function liveMeterReading(\n document: { get(field: string): unknown } | null | undefined,\n live: { fields: readonly string[] },\n): number | undefined {\n for (const field of live.fields) {\n const value = meterValue(document?.get(field))\n if (value > 0) return value\n }\n return undefined\n}\n\n/** Every rollup field the declared cost axes read or record, in order. */\nexport function pluginCostAxisFields(): string[] {\n const fields: string[] = []\n for (const axis of PLUGIN_COST_AXES_DECLARED) {\n for (const field of [\n ...axis.fields,\n ...(axis.fallbackFields ?? []),\n ...(axis.recordedFields ?? []),\n ]) {\n if (!fields.includes(field)) fields.push(field)\n }\n }\n return fields\n}\n\n/**\n * A month's rollup as a staff reader is served it, one entry per field the\n * declared cost axes read, record or serve to staff (`get` reads one rollup\n * field).\n *\n * A field an axis prices reads zero where the rollup lacks it, as the cost\n * model reads it — except where the axis falls back to an older basis when\n * the rollup carries none of its fields: there absence is the answer that\n * selects the fallback, so it is served as `null`, and a reader pricing the\n * served row reads the month the way the sweep did. A field an axis only\n * records or serves reads `null` when the rollup never wrote it: \"not\n * recorded\" and \"recorded zero\" are different answers, and a projection\n * that collapses them invents history (AGL-2321).\n */\nexport function pluginCostAxisProjection(\n get: (field: string) => unknown,\n): Record<string, number | null> {\n const out: Record<string, number | null> = {}\n for (const axis of PLUGIN_COST_AXES_DECLARED) {\n const absentIsNull = [\n ...(axis.fallbackFields?.length ? axis.fields : []),\n ...(axis.recordedFields ?? []),\n ...(axis.staffFields ?? []),\n ]\n for (const field of [\n ...axis.fields,\n ...(axis.fallbackFields ?? []),\n ...(axis.recordedFields ?? []),\n ...(axis.staffFields ?? []),\n ]) {\n if (field in out) continue\n const value = get(field)\n out[field] =\n value != null ? Number(value) : absentIsNull.includes(field) ? null : 0\n }\n }\n return out\n}\n"],"names":["PLUGIN_COST_AXES_DECLARED","PLUGIN_SPEND_LINES_DECLARED","PLUGIN_USAGE_BANDS_DECLARED","pluginCostAxes","pluginUsageBands","meteredPluginBands","filter","band","Boolean","metered","hostCounter","countedPluginBands","meteredBandField","fields","meteredBandVerdictFields","field","billed","withheldUsd","pluginSpendLines","meterValue","value","parsed","Number","isFinite","declaredMeterReading","source","declared","present","some","fallbackFields","length","reduce","sum","liveMeterReading","document","live","get","undefined","pluginCostAxisFields","axis","recordedFields","includes","push","pluginCostAxisProjection","out","absentIsNull","staffFields"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-usage-axes.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * WHAT A PLUGIN'S USAGE COSTS, AND HOW MUCH OF ITS BAND IT SPENT (AGL-3080).\n *\n * The platform keeps one cost model (`orgMonthlyCogsUsd`) and one\n * utilization table (`margin-utilization.ts`), and both read the monthly\n * usage rollup. Several of the rollup's meters are a plugin's: the AI\n * plugin's provider spend, the CRM's records, the forms plugin's\n * submissions, the workflows plugin's runs. Core used to name each of them —\n * its rollup field, the unit rate that prices it, the band it is measured\n * against — so a plugin that metered something new could not reach the\n * discount guardrail without a core edit, and core could not be taken\n * without the plugins it named.\n *\n * So a plugin declares its meters, and core composes them:\n *\n * - a COST AXIS names the rollup fields a meter is recorded under and the\n * `ORG_COGS_UNIT_RATES_USD` key that prices one unit, or no key when the\n * field is already dollars. `orgMonthlyCogsUsd` prices it beside core's\n * own axes, and `orgCogsInputFrom` forwards its fields.\n * - a BAND names the rollup fields that measure it and the entitlement that\n * says what the plan includes. The utilization table reads it beside\n * core's own bands. A METERED band is also billed past what the plan\n * includes, at its published billed rate (cost + 30% kept after card\n * fees), beside storage and bandwidth: the invoice sweep, the Billing\n * card's estimate, the monthly summary and the staff usage rows read it\n * from here.\n * - a SPEND LINE names the month document holding what the plugin's usage\n * came to at the rates it bills, the deployment variable naming the month\n * it is first charged for, and the unit a customer sees it in. The usage\n * budget shows it beside the metered figure and counts it once charged.\n * - a METER names what the plugin measures in the monthly usage sweep\n * (`plugin-usage-meters.ts`), so the sweep can refuse to bill a month the\n * registered meter is missing from.\n *\n * ## What core keeps\n *\n * The MONEY. Every unit rate stays in `ORG_COGS_UNIT_RATES_USD`, beside the\n * billed table it is reconciled against (`METERED_UNIT_RATES_USD`, which a\n * metered band names its rate in), and every included figure stays in\n * `PLAN_ENTITLEMENTS`. A declaration names fields and keys; it carries no\n * price. The one number a declaration may carry is a band's unit cost, where\n * the band is sold in a unit OF cost (a credit is a fixed quantity of\n * dollars), and that number is the plugin's own definition of its unit.\n *\n * ## Compiled, never registered\n *\n * The cost model's readers include the staff org page, which prices a rollup\n * in the browser, and the discount guardrail, whose every wrong answer is in\n * the approving direction: a cost axis a registry had not filled would price\n * at nothing and approve a discount the margin cannot carry. So these are\n * compiled from each plugin's `usage-axes` declaration by the manifest\n * generator, like the plan figures, and a rate key core does not have is an\n * error rather than a zero.\n */\n\nimport type { ReleaseFlagKey } from '../app-utils/release-flags'\nimport {\n PLUGIN_COST_AXES_DECLARED,\n PLUGIN_SPEND_LINES_DECLARED,\n PLUGIN_USAGE_BANDS_DECLARED,\n} from './first-party-plugins.generated'\n\n/** A meter a plugin contributes to the platform's cost model. */\nexport interface PluginCostAxisDeclaration {\n /** The breakdown key every staff reader shows it under. */\n id: string\n /** Where it sorts among the cost model's axes; core's own are multiples of 10. */\n order: number\n /** Rollup fields summed for the axis. */\n fields: readonly string[]\n /**\n * Read only when every one of `fields` is absent from a rollup — the\n * narrower field an older rollup recorded the same meter under.\n */\n fallbackFields?: readonly string[]\n /**\n * Rollup fields recorded beside the meter so its sum is legible, forwarded\n * by `orgCogsInputFrom` and never priced.\n */\n recordedFields?: readonly string[]\n /**\n * Rollup fields the plugin's usage sweep writes beside the meter for its\n * staff surfaces to read — served on the staff usage rows, `null` where a\n * rollup never wrote one, and never forwarded to the cost model.\n */\n staffFields?: readonly string[]\n /**\n * The `ORG_COGS_UNIT_RATES_USD` key pricing one unit. Absent when the\n * fields are already dollars, which then enter the model at ×1.\n */\n rate?: string\n /**\n * The month's LIVE reading, when the rollup's figure is a snapshot a meter\n * keeps adding to: `orgs/{orgId}/{collection}/{month}`, the first of\n * `fields` that is a positive number. It replaces the axis's first rollup\n * field wherever a reader fetches it.\n */\n live?: { collection: string; fields: readonly string[] }\n}\n\n/** A band a plugin contributes to the utilization table. */\nexport interface PluginUsageBandDeclaration {\n /** The band's key, and the column the staff table shows it under. */\n id: string\n label: string\n order: number\n /** Rollup fields summed for what the org used. */\n fields: readonly string[]\n fallbackFields?: readonly string[]\n /** The resolved entitlement holding what the plan includes. */\n entitlement: string\n /** The entitlement is per SITE and the org-wide band is it × `hostLimit`. */\n perHost?: boolean\n /**\n * The band is sold in a unit of cost and the rollup records dollars: what\n * was used is `ceil(dollars / unitCostUsd)`, rounded UP so spend already\n * made never reads as less of the band.\n */\n unitCostUsd?: number\n /**\n * The per-site monthly counter the band is measured by:\n * `hosts/{hostId}/counters/{hostCounter}`, field `{month}`, summed over the\n * workspace's sites.\n */\n hostCounter?: string\n /**\n * The WORKSPACE-wide monthly counter the band is enforced against:\n * `orgs/{orgId}/counters/{orgCounter}`, field `{month}` (AGL-3472). Declared\n * by a band whose runtime counts every unit on the org's counter as well as\n * on the site's, in one write, so a workspace-wide band is held to every\n * site's use rather than handed to each site whole. The Billing card meters\n * the band once for the organization from it, where a band without one is\n * metered per site. The usage sweep and alerts still sum `hostCounter`,\n * which the same write moves.\n */\n orgCounter?: string\n /**\n * The workspace is WARNED as it approaches and reaches this band, by the\n * usage-alerts sweep, from its `hostCounter` against what the plan includes\n * of `entitlement`, once per threshold per month. `label` names the band in\n * the title (\"monthly workflow runs\") and `noun` in the opening sentence\n * (\"workflow runs\"); `outcome` is what happens at the band — `stops`,\n * `bills` or `continues` — and `reached` and `approach` are the sentences\n * that say so, at the band and approaching it.\n */\n alert?: {\n label: string\n noun: string\n outcome: 'stops' | 'bills' | 'continues'\n reached: string\n approach: string\n }\n /**\n * The console's quota banner WARNS an organization-wide reader on every\n * console page as the workspace approaches and reaches this band\n * (AGL-2898, AGL-3080). `standing` is a console API path the plugin\n * serves, asked `?orgId=` with the reader's token, that answers the\n * band's standing in its own unit under `member` — `{ used, limit }`,\n * `limit: null` for a plan with no band, which is no row — and\n * `stopsAtBand`: whether reaching it stops the feature (the reading when\n * the route does not say) or bills past it. `approach` is the sentence\n * above 80%; `reached.stops` and `reached.bills` the two at the band.\n * `linksUsage` says the sentences name Billing → Usage, and the banner\n * offers the link.\n *\n * A route, not a counter: a band's meter may be one no client may read,\n * and the route answers in the unit the customer was sold.\n */\n consoleWarning?: {\n standing: string\n member: string\n approach: string\n reached: { stops: string; bills: string }\n linksUsage?: boolean\n }\n /**\n * The band is one of the INFRASTRUCTURE meters (AGL-1280): what the\n * workspace uses past it is billed at its published billed rate (cost +\n * 30% kept after card fees), beside storage and bandwidth, on the same\n * invoice line and the same estimate.\n * A metered band names one rollup field and the `hostCounter` it is\n * measured by.\n */\n metered?: PluginMeteredBand\n}\n\n/** How a metered band is priced, quoted and withheld. */\nexport interface PluginMeteredBand {\n /**\n * The `METERED_UNIT_RATES_USD` key holding our cost per unit — never a\n * number: the rate table is the platform's, beside the markup it is\n * published with.\n */\n rate: string\n /** The count a published price is quoted per: `1000` reads \"per 1,000\". */\n quotedPer: number\n /** The band in running prose, plural and lowercase: \"form submissions\". */\n noun: string\n /**\n * A release flag the overage waits behind: while it is off for the\n * workspace, the units are counted and the charge is recorded as withheld\n * rather than billed — nobody is charged for what they cannot reach\n * (AGL-1604). The rollup records the verdict as `{field}Billed` and what\n * was forgone, at cost, as `{field}OverageWithheldUsd`.\n */\n withheldUntil?: ReleaseFlagKey\n}\n\n/**\n * A line of a workspace's monthly SPEND a plugin contributes to its usage\n * budget (`usage-budget.ts`): what the plugin's usage came to this month, in\n * the dollars it is billed at, shown on the customer's budget card and\n * counted toward the budget from the month the plugin starts charging for it.\n */\nexport interface PluginSpendLineDeclaration {\n /** The line's key. */\n id: string\n /** What the budget card and the budget alert call it. */\n label: string\n /**\n * Where the month's figure is read: `orgs/{orgId}/{collection}/{month}`,\n * field `field`, in dollars.\n */\n live: { collection: string; field: string }\n /**\n * The deployment variable naming the first month (`YYYY-MM`) the line is\n * charged for. Until it names this month or an earlier one — and on any\n * value that is not a month — the line is shown and never counted.\n */\n billedFromEnv: string\n /**\n * The unit the customer is shown the line in, when the stored dollars are\n * not theirs to see: `ceil(dollars / costUsd)` of `label`, and the dollar\n * figure never crosses to the browser.\n */\n unit?: { costUsd: number; label: string }\n}\n\n/**\n * A meter the plugin measures in the platform's monthly usage sweep and\n * registers at runtime (`plugin-usage-meters.ts`). Declared as well as\n * registered so the sweep can refuse to bill a workspace's month without it.\n */\nexport interface PluginUsageMeterDeclaration {\n /** As `registerPluginUsageMeter` names it. */\n id: string\n}\n\nexport type ResolvedPluginCostAxis = PluginCostAxisDeclaration & { pluginId: string }\nexport type ResolvedPluginUsageBand = PluginUsageBandDeclaration & { pluginId: string }\nexport type ResolvedPluginSpendLine = PluginSpendLineDeclaration & { pluginId: string }\nexport type ResolvedPluginUsageMeter = PluginUsageMeterDeclaration & { pluginId: string }\n\n/** What a plugin's `usageAxes` function answers. */\nexport interface PluginUsageAxesDeclaration {\n costAxes?: readonly PluginCostAxisDeclaration[]\n bands?: readonly PluginUsageBandDeclaration[]\n spendLines?: readonly PluginSpendLineDeclaration[]\n meters?: readonly PluginUsageMeterDeclaration[]\n}\n\nexport function pluginCostAxes(): readonly ResolvedPluginCostAxis[] {\n return PLUGIN_COST_AXES_DECLARED\n}\n\nexport function pluginUsageBands(): readonly ResolvedPluginUsageBand[] {\n return PLUGIN_USAGE_BANDS_DECLARED\n}\n\n/** A declared band that is metered, with its one field and its counter. */\nexport type ResolvedPluginMeteredBand = ResolvedPluginUsageBand & {\n metered: PluginMeteredBand\n hostCounter: string\n}\n\n/**\n * Every band billed at cost past what the plan includes, in band order — the\n * infrastructure meters a plugin adds beside storage and bandwidth.\n */\nexport function meteredPluginBands(): readonly ResolvedPluginMeteredBand[] {\n return PLUGIN_USAGE_BANDS_DECLARED.filter(\n (band): band is ResolvedPluginMeteredBand =>\n Boolean(band.metered && band.hostCounter),\n )\n}\n\n/** A declared band measured by a per-site counter and never billed past it. */\nexport type ResolvedPluginCountedBand = ResolvedPluginUsageBand & {\n hostCounter: string\n}\n\n/**\n * Every band measured by a per-site counter and not metered, in band order:\n * the usage sweep sums each across the workspace's sites and records it under\n * the band's first field, and the staff usage rows show the count. A metered\n * band's counter is read with the infrastructure meters instead.\n */\nexport function countedPluginBands(): readonly ResolvedPluginCountedBand[] {\n return PLUGIN_USAGE_BANDS_DECLARED.filter(\n (band): band is ResolvedPluginCountedBand =>\n Boolean(band.hostCounter && !band.metered),\n )\n}\n\n/** A declared band kept on a workspace-wide counter. */\nexport type ResolvedPluginOrgCountedBand = ResolvedPluginUsageBand & {\n orgCounter: string\n}\n\n/**\n * Every band with a workspace-wide counter (`orgCounter`), in band order: the\n * bands the Billing card meters once for the organization, from the counter\n * the band is enforced against.\n */\nexport function orgCountedPluginBands(): readonly ResolvedPluginOrgCountedBand[] {\n return PLUGIN_USAGE_BANDS_DECLARED.filter(\n (band): band is ResolvedPluginOrgCountedBand => Boolean(band.orgCounter),\n )\n}\n\n/** The rollup field a metered band records its count under. */\nexport function meteredBandField(band: ResolvedPluginMeteredBand): string {\n return band.fields[0]!\n}\n\n/**\n * Where the rollup records a withheld band's verdict (`metered.withheldUntil`):\n * whether the month billed the band's overage, and what was forgone, at cost,\n * when it did not. Without the second a withheld month reads as a month that\n * stayed inside the band.\n */\nexport function meteredBandVerdictFields(band: ResolvedPluginMeteredBand): {\n billed: string\n withheldUsd: string\n} {\n const field = meteredBandField(band)\n return { billed: `${field}Billed`, withheldUsd: `${field}OverageWithheldUsd` }\n}\n\nexport function pluginSpendLines(): readonly ResolvedPluginSpendLine[] {\n return PLUGIN_SPEND_LINES_DECLARED\n}\n\n/** A positive finite number, or 0 — the reading every meter is priced from. */\nfunction meterValue(value: unknown): number {\n const parsed = Number(value ?? 0)\n return Number.isFinite(parsed) && parsed > 0 ? parsed : 0\n}\n\n/**\n * What a rollup recorded for a declared meter: `fields` summed, or\n * `fallbackFields` summed when the rollup carries none of `fields` at all.\n *\n * \"Carries none\" is `null` or absent, never zero. A rollup that measured\n * zero has answered, and must not fall back to a figure recorded under an\n * older, narrower basis.\n */\nexport function declaredMeterReading(\n source: Readonly<Record<string, unknown>> | null | undefined,\n declared: {\n fields: readonly string[]\n fallbackFields?: readonly string[]\n },\n): number {\n const present = declared.fields.some((field) => source?.[field] != null)\n const fields =\n !present && declared.fallbackFields?.length\n ? declared.fallbackFields\n : declared.fields\n return fields.reduce((sum, field) => sum + meterValue(source?.[field]), 0)\n}\n\n/**\n * The live reading a cost axis names: the first of its `live.fields` that is\n * a positive number on the month's document, or `undefined` when none is.\n * `undefined` is \"keep the rollup's snapshot\", never zero.\n */\nexport function liveMeterReading(\n document: { get(field: string): unknown } | null | undefined,\n live: { fields: readonly string[] },\n): number | undefined {\n for (const field of live.fields) {\n const value = meterValue(document?.get(field))\n if (value > 0) return value\n }\n return undefined\n}\n\n/** Every rollup field the declared cost axes read or record, in order. */\nexport function pluginCostAxisFields(): string[] {\n const fields: string[] = []\n for (const axis of PLUGIN_COST_AXES_DECLARED) {\n for (const field of [\n ...axis.fields,\n ...(axis.fallbackFields ?? []),\n ...(axis.recordedFields ?? []),\n ]) {\n if (!fields.includes(field)) fields.push(field)\n }\n }\n return fields\n}\n\n/**\n * A month's rollup as a staff reader is served it, one entry per field the\n * declared cost axes read, record or serve to staff (`get` reads one rollup\n * field).\n *\n * A field an axis prices reads zero where the rollup lacks it, as the cost\n * model reads it — except where the axis falls back to an older basis when\n * the rollup carries none of its fields: there absence is the answer that\n * selects the fallback, so it is served as `null`, and a reader pricing the\n * served row reads the month the way the sweep did. A field an axis only\n * records or serves reads `null` when the rollup never wrote it: \"not\n * recorded\" and \"recorded zero\" are different answers, and a projection\n * that collapses them invents history (AGL-2321).\n */\nexport function pluginCostAxisProjection(\n get: (field: string) => unknown,\n): Record<string, number | null> {\n const out: Record<string, number | null> = {}\n for (const axis of PLUGIN_COST_AXES_DECLARED) {\n const absentIsNull = [\n ...(axis.fallbackFields?.length ? axis.fields : []),\n ...(axis.recordedFields ?? []),\n ...(axis.staffFields ?? []),\n ]\n for (const field of [\n ...axis.fields,\n ...(axis.fallbackFields ?? []),\n ...(axis.recordedFields ?? []),\n ...(axis.staffFields ?? []),\n ]) {\n if (field in out) continue\n const value = get(field)\n out[field] =\n value != null ? Number(value) : absentIsNull.includes(field) ? null : 0\n }\n }\n return out\n}\n"],"names":["PLUGIN_COST_AXES_DECLARED","PLUGIN_SPEND_LINES_DECLARED","PLUGIN_USAGE_BANDS_DECLARED","pluginCostAxes","pluginUsageBands","meteredPluginBands","filter","band","Boolean","metered","hostCounter","countedPluginBands","orgCountedPluginBands","orgCounter","meteredBandField","fields","meteredBandVerdictFields","field","billed","withheldUsd","pluginSpendLines","meterValue","value","parsed","Number","isFinite","declaredMeterReading","source","declared","present","some","fallbackFields","length","reduce","sum","liveMeterReading","document","live","get","undefined","pluginCostAxisFields","axis","recordedFields","includes","push","pluginCostAxisProjection","out","absentIsNull","staffFields"],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
var _globalScope_ERASERS_KEY;
|
|
1
2
|
/**
|
|
2
3
|
* @license
|
|
3
4
|
* Copyright 2026 Aglyn LLC
|
|
@@ -34,7 +35,14 @@
|
|
|
34
35
|
* Registered from a plugin's `serverDeclarations` entry, so the eraser is in
|
|
35
36
|
* place in a server process that never loaded the plugin's API surface.
|
|
36
37
|
*/ import { getRegisteringPluginId } from "../app-utils/registering-plugin.js";
|
|
37
|
-
|
|
38
|
+
/**
|
|
39
|
+
* One list per process, on `globalThis` (AGL-3464): the app registers its
|
|
40
|
+
* plugins' erasers from `instrumentation.ts`, which Next compiles apart from
|
|
41
|
+
* the route that runs the erasure, and a module-scoped list is filled in one
|
|
42
|
+
* copy and read empty in the other — the AGL-3412 shape.
|
|
43
|
+
*/ const ERASERS_KEY = Symbol.for('@aglyn/aglyn:plugin-user-erasers');
|
|
44
|
+
const globalScope = globalThis;
|
|
45
|
+
const registrations = (_globalScope_ERASERS_KEY = globalScope[ERASERS_KEY]) != null ? _globalScope_ERASERS_KEY : globalScope[ERASERS_KEY] = [];
|
|
38
46
|
/**
|
|
39
47
|
* Registers a plugin's eraser. Owner = the loader's marker inside a register
|
|
40
48
|
* fn, else `options.pluginId`; an eraser with neither throws. One eraser per
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-user-erasure.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * A plugin's share of an account erasure (AGL-2939).\n *\n * The account erasure deletes what core stores about a person: the user\n * document and its subcollections, the memberships, the public profile, the\n * delivery log and the auth record. A plugin that keeps data ABOUT a person\n * where none of that reaches — documents under an org keyed by the uid, a\n * collection carrying the uid as a field — registers an eraser here, and\n * the erasure runs every eraser with the person's uid and the workspaces\n * they belonged to.\n *\n * Erasers run in registration order and are ISOLATED: a throw is logged\n * against its plugin, recorded as `null`, and does not stop the next one.\n * An erasure runs against a legal clock, and one plugin's outage must not\n * keep every other plugin's data past it. The `null` is how the erasure's\n * audit record says that plugin's data may remain, which a report of zero\n * would hide.\n *\n * Registered from a plugin's `serverDeclarations` entry, so the eraser is in\n * place in a server process that never loaded the plugin's API surface.\n */\n\nimport { getRegisteringPluginId } from '../app-utils/registering-plugin'\n\n/** What an eraser is asked to erase. */\nexport interface PluginUserErasureRequest {\n /** The account being erased. */\n uid: string\n /**\n * Every workspace the person belonged to when the erasure began. Their\n * memberships are removed before the erasers run, so this is the only\n * record of them an eraser gets.\n */\n orgIds: readonly string[]\n}\n\n/**\n * What an eraser reports for the erasure's audit record: counts and flags,\n * never the erased content, because the record outlives the data by design.\n * A `null` field is a figure the eraser could not measure, which is not zero.\n */\nexport type PluginUserErasureReport = Readonly<Record<string, number | boolean | null>>\n\nexport type PluginUserEraser = (\n request: PluginUserErasureRequest,\n) => Promise<PluginUserErasureReport>\n\ninterface Registration {\n pluginId: string\n eraser: PluginUserEraser\n}\n\nconst registrations: Registration[] = []\n\n/**\n * Registers a plugin's eraser. Owner = the loader's marker inside a register\n * fn, else `options.pluginId`; an eraser with neither throws. One eraser per\n * plugin: registering again replaces the plugin's earlier eraser in place,\n * so a module evaluated twice does not erase twice.\n */\nexport function registerPluginUserEraser(\n eraser: PluginUserEraser,\n options?: { pluginId?: string },\n): void {\n const pluginId = (getRegisteringPluginId() ?? options?.pluginId ?? '').trim()\n if (!pluginId) {\n throw new Error(\n 'a plugin user eraser was registered with no owner: pass { pluginId } ' +\n 'when registering outside a plugin register fn',\n )\n }\n const index = registrations.findIndex((entry) => entry.pluginId === pluginId)\n if (index >= 0) registrations[index] = { pluginId, eraser }\n else registrations.push({ pluginId, eraser })\n}\n\n/**\n * Runs every eraser, in registration order, and answers each plugin's\n * report by plugin id: the eraser's own report, or `null` for one that\n * threw.\n */\nexport async function runPluginUserErasers(\n request: PluginUserErasureRequest,\n): Promise<Record<string, PluginUserErasureReport | null>> {\n const reports: Record<string, PluginUserErasureReport | null> = {}\n for (const { pluginId, eraser } of [...registrations]) {\n try {\n reports[pluginId] = await eraser(request)\n } catch (error) {\n reports[pluginId] = null\n console.error(`[plugins] ${pluginId} failed to erase user ${request.uid}`, error)\n }\n }\n return reports\n}\n\n/** The plugins with an eraser, in the order they run. */\nexport function listPluginUserErasers(): string[] {\n return registrations.map((entry) => entry.pluginId)\n}\n\n/** Test seam: forget every eraser. */\nexport function resetPluginUserErasersForTests(): void {\n registrations.length = 0\n}\n"],"names":["getRegisteringPluginId","registrations","registerPluginUserEraser","eraser","options","pluginId","trim","Error","index","findIndex","entry","push","runPluginUserErasers","request","reports","error","console","uid","listPluginUserErasers","map","resetPluginUserErasersForTests","length"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-user-erasure.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * A plugin's share of an account erasure (AGL-2939).\n *\n * The account erasure deletes what core stores about a person: the user\n * document and its subcollections, the memberships, the public profile, the\n * delivery log and the auth record. A plugin that keeps data ABOUT a person\n * where none of that reaches — documents under an org keyed by the uid, a\n * collection carrying the uid as a field — registers an eraser here, and\n * the erasure runs every eraser with the person's uid and the workspaces\n * they belonged to.\n *\n * Erasers run in registration order and are ISOLATED: a throw is logged\n * against its plugin, recorded as `null`, and does not stop the next one.\n * An erasure runs against a legal clock, and one plugin's outage must not\n * keep every other plugin's data past it. The `null` is how the erasure's\n * audit record says that plugin's data may remain, which a report of zero\n * would hide.\n *\n * Registered from a plugin's `serverDeclarations` entry, so the eraser is in\n * place in a server process that never loaded the plugin's API surface.\n */\n\nimport { getRegisteringPluginId } from '../app-utils/registering-plugin'\n\n/** What an eraser is asked to erase. */\nexport interface PluginUserErasureRequest {\n /** The account being erased. */\n uid: string\n /**\n * Every workspace the person belonged to when the erasure began. Their\n * memberships are removed before the erasers run, so this is the only\n * record of them an eraser gets.\n */\n orgIds: readonly string[]\n}\n\n/**\n * What an eraser reports for the erasure's audit record: counts and flags,\n * never the erased content, because the record outlives the data by design.\n * A `null` field is a figure the eraser could not measure, which is not zero.\n */\nexport type PluginUserErasureReport = Readonly<Record<string, number | boolean | null>>\n\nexport type PluginUserEraser = (\n request: PluginUserErasureRequest,\n) => Promise<PluginUserErasureReport>\n\ninterface Registration {\n pluginId: string\n eraser: PluginUserEraser\n}\n\n/**\n * One list per process, on `globalThis` (AGL-3464): the app registers its\n * plugins' erasers from `instrumentation.ts`, which Next compiles apart from\n * the route that runs the erasure, and a module-scoped list is filled in one\n * copy and read empty in the other — the AGL-3412 shape.\n */\nconst ERASERS_KEY = Symbol.for('@aglyn/aglyn:plugin-user-erasers')\n\nconst globalScope = globalThis as typeof globalThis & {\n [ERASERS_KEY]?: Registration[]\n}\n\nconst registrations: Registration[] =\n globalScope[ERASERS_KEY] ?? (globalScope[ERASERS_KEY] = [])\n\n/**\n * Registers a plugin's eraser. Owner = the loader's marker inside a register\n * fn, else `options.pluginId`; an eraser with neither throws. One eraser per\n * plugin: registering again replaces the plugin's earlier eraser in place,\n * so a module evaluated twice does not erase twice.\n */\nexport function registerPluginUserEraser(\n eraser: PluginUserEraser,\n options?: { pluginId?: string },\n): void {\n const pluginId = (getRegisteringPluginId() ?? options?.pluginId ?? '').trim()\n if (!pluginId) {\n throw new Error(\n 'a plugin user eraser was registered with no owner: pass { pluginId } ' +\n 'when registering outside a plugin register fn',\n )\n }\n const index = registrations.findIndex((entry) => entry.pluginId === pluginId)\n if (index >= 0) registrations[index] = { pluginId, eraser }\n else registrations.push({ pluginId, eraser })\n}\n\n/**\n * Runs every eraser, in registration order, and answers each plugin's\n * report by plugin id: the eraser's own report, or `null` for one that\n * threw.\n */\nexport async function runPluginUserErasers(\n request: PluginUserErasureRequest,\n): Promise<Record<string, PluginUserErasureReport | null>> {\n const reports: Record<string, PluginUserErasureReport | null> = {}\n for (const { pluginId, eraser } of [...registrations]) {\n try {\n reports[pluginId] = await eraser(request)\n } catch (error) {\n reports[pluginId] = null\n console.error(`[plugins] ${pluginId} failed to erase user ${request.uid}`, error)\n }\n }\n return reports\n}\n\n/** The plugins with an eraser, in the order they run. */\nexport function listPluginUserErasers(): string[] {\n return registrations.map((entry) => entry.pluginId)\n}\n\n/** Test seam: forget every eraser. */\nexport function resetPluginUserErasersForTests(): void {\n registrations.length = 0\n}\n"],"names":["globalScope","getRegisteringPluginId","ERASERS_KEY","Symbol","for","globalThis","registrations","registerPluginUserEraser","eraser","options","pluginId","trim","Error","index","findIndex","entry","push","runPluginUserErasers","request","reports","error","console","uid","listPluginUserErasers","map","resetPluginUserErasersForTests","length"],"mappings":"IAkFEA;AAlFF;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;;;CAoBC,GAED,SAASC,sBAAsB,QAAQ,qCAAiC;AA8BxE;;;;;CAKC,GACD,MAAMC,cAAcC,OAAOC,GAAG,CAAC;AAE/B,MAAMJ,cAAcK;AAIpB,MAAMC,iBACJN,2BAAAA,WAAW,CAACE,YAAY,YAAxBF,2BAA6BA,WAAW,CAACE,YAAY,GAAG,EAAE;AAE5D;;;;;CAKC,GACD,OAAO,SAASK,yBACdC,MAAwB,EACxBC,OAA+B;QAEbR,MAAAA;IAAlB,MAAMS,WAAW,EAACT,QAAAA,0BAAAA,oCAAAA,0BAA4BQ,2BAAAA,QAASC,QAAQ,YAA7CT,OAAiD,IAAIU,IAAI;IAC3E,IAAI,CAACD,UAAU;QACb,MAAM,IAAIE,MACR,0EACE;IAEN;IACA,MAAMC,QAAQP,cAAcQ,SAAS,CAAC,CAACC,QAAUA,MAAML,QAAQ,KAAKA;IACpE,IAAIG,SAAS,GAAGP,aAAa,CAACO,MAAM,GAAG;QAAEH;QAAUF;IAAO;SACrDF,cAAcU,IAAI,CAAC;QAAEN;QAAUF;IAAO;AAC7C;AAEA;;;;CAIC,GACD,OAAO,eAAeS,qBACpBC,OAAiC;IAEjC,MAAMC,UAA0D,CAAC;IACjE,KAAK,MAAM,EAAET,QAAQ,EAAEF,MAAM,EAAE,IAAI;WAAIF;KAAc,CAAE;QACrD,IAAI;YACFa,OAAO,CAACT,SAAS,GAAG,MAAMF,OAAOU;QACnC,EAAE,OAAOE,OAAO;YACdD,OAAO,CAACT,SAAS,GAAG;YACpBW,QAAQD,KAAK,CAAC,CAAC,UAAU,EAAEV,SAAS,sBAAsB,EAAEQ,QAAQI,GAAG,EAAE,EAAEF;QAC7E;IACF;IACA,OAAOD;AACT;AAEA,uDAAuD,GACvD,OAAO,SAASI;IACd,OAAOjB,cAAckB,GAAG,CAAC,CAACT,QAAUA,MAAML,QAAQ;AACpD;AAEA,oCAAoC,GACpC,OAAO,SAASe;IACdnB,cAAcoB,MAAM,GAAG;AACzB"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
/** A noun in its two counts: `{ one: 'submission', other: 'submissions' }`. */
|
|
18
|
+
export interface VisitorDoorNoun {
|
|
19
|
+
one: string;
|
|
20
|
+
other: string;
|
|
21
|
+
}
|
|
22
|
+
export interface VisitorDoorDeclaration {
|
|
23
|
+
/** The door's name, as lockdown and the intake gates name it: `form`. */
|
|
24
|
+
door: string;
|
|
25
|
+
/** The site counter the door's ceiling refusals are kept in, by month. */
|
|
26
|
+
refusedCounter: string;
|
|
27
|
+
/** The site counter the door's honeypot catches are kept in, by month. */
|
|
28
|
+
caughtCounter: string;
|
|
29
|
+
words: {
|
|
30
|
+
/** The owner's notice title: "Form submissions are paused". */
|
|
31
|
+
pausedTitle: string;
|
|
32
|
+
/** What the door takes in: submission / submissions. */
|
|
33
|
+
noun: VisitorDoorNoun;
|
|
34
|
+
/** The same to staff, who see every door: form submission(s). */
|
|
35
|
+
staffNoun: VisitorDoorNoun;
|
|
36
|
+
/** Why it usually happens and what to do — the notice's last sentence. */
|
|
37
|
+
cause: string;
|
|
38
|
+
/** The staff flag's label for a door refusing now: "forms paused". */
|
|
39
|
+
pausedChip: string;
|
|
40
|
+
/** What the honeypot catches: bot submission(s). */
|
|
41
|
+
caught: VisitorDoorNoun;
|
|
42
|
+
/** What caught them: "the honeypot". */
|
|
43
|
+
caughtBy: string;
|
|
44
|
+
/** The staff flag's noun for a catch: bot hit(s). */
|
|
45
|
+
caughtChip: VisitorDoorNoun;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** A declaration with the plugin that keeps the door. */
|
|
49
|
+
export type ResolvedVisitorDoor = VisitorDoorDeclaration & {
|
|
50
|
+
pluginId: string;
|
|
51
|
+
};
|
|
52
|
+
/** A door's counts for one site and month, as a staff join reads them. */
|
|
53
|
+
export interface VisitorDoorCounts {
|
|
54
|
+
/** The month the counts are for — `utcMonthKey()`. */
|
|
55
|
+
month: string;
|
|
56
|
+
/** Refused by the ceiling this month. */
|
|
57
|
+
refused: number;
|
|
58
|
+
/** The ceiling the counter recorded when it tripped, when known. */
|
|
59
|
+
ceiling: number | null;
|
|
60
|
+
/** Caught by the honeypot this month. */
|
|
61
|
+
caught: number;
|
|
62
|
+
}
|
|
63
|
+
/** What the site's owner is shown while a door is refusing. */
|
|
64
|
+
export interface VisitorDoorPausedNotice {
|
|
65
|
+
title: string;
|
|
66
|
+
/** What happened, how many, and that none of it is billed. */
|
|
67
|
+
message: string;
|
|
68
|
+
/** When it lifts, as a sentence — never a raw month key. */
|
|
69
|
+
until: string;
|
|
70
|
+
}
|
|
71
|
+
/** Every declared door, in the order the plugins are configured. */
|
|
72
|
+
export declare function pluginVisitorDoors(): readonly ResolvedVisitorDoor[];
|
|
73
|
+
/**
|
|
74
|
+
* The owner's notice for a door refusing this month, or `null` below one
|
|
75
|
+
* refusal. `ceiling` is the one the counter recorded, when it did.
|
|
76
|
+
*/
|
|
77
|
+
export declare function visitorDoorPausedNotice(door: VisitorDoorDeclaration, input: {
|
|
78
|
+
refused: number;
|
|
79
|
+
ceiling?: number;
|
|
80
|
+
now?: Date;
|
|
81
|
+
}): VisitorDoorPausedNotice | null;
|
|
82
|
+
/**
|
|
83
|
+
* The month's honeypot catches as one sentence, or `null` below one catch.
|
|
84
|
+
* It reports protection WORKING — caught and dropped, nothing stored or
|
|
85
|
+
* billed — so it never reads as an alarm.
|
|
86
|
+
*/
|
|
87
|
+
export declare function visitorDoorCaughtNotice(door: VisitorDoorDeclaration, input: {
|
|
88
|
+
caught: number;
|
|
89
|
+
}): string | null;
|
|
90
|
+
/** One staff flag: the chip's terse label, and the sentence behind it. */
|
|
91
|
+
export interface VisitorDoorStaffFlag {
|
|
92
|
+
label: string;
|
|
93
|
+
detail: string;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The staff Sites card's flags for one door on one site: a refusing door, and
|
|
97
|
+
* the month's catches, each only from one up. Terse labels on purpose — the
|
|
98
|
+
* owner's wording is for owners — with the ceiling and the date it lifts in
|
|
99
|
+
* the detail.
|
|
100
|
+
*/
|
|
101
|
+
export declare function visitorDoorStaffFlags(door: VisitorDoorDeclaration, counts: Pick<VisitorDoorCounts, 'refused' | 'ceiling' | 'caught'> | null | undefined, now?: Date): {
|
|
102
|
+
refused: VisitorDoorStaffFlag | null;
|
|
103
|
+
caught: VisitorDoorStaffFlag | null;
|
|
104
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ /**
|
|
17
|
+
* A PLUGIN'S PUBLIC DOOR, AS ITS OWNER AND STAFF SEE IT WHEN IT IS FLOODED
|
|
18
|
+
* (AGL-1666, AGL-1831, AGL-3080).
|
|
19
|
+
*
|
|
20
|
+
* A plugin that keeps a public door a visitor writes through — the forms
|
|
21
|
+
* plugin's `/api/forms/submit` — caps a flood with a monthly ceiling and
|
|
22
|
+
* drops what its honeypot catches, and counts both per site in
|
|
23
|
+
* `hosts/{hostId}/counters/{counter}`, keyed by `utcMonthKey`. The site's
|
|
24
|
+
* owner reads those counts where the door's traffic lands (the Inbox), and
|
|
25
|
+
* staff read them on the organization's Sites card. Neither surface may name
|
|
26
|
+
* the plugin, and neither loads it: so the plugin DECLARES its door in
|
|
27
|
+
* `plugins.config.json` (`visitorDoors`) — the two counters and the words —
|
|
28
|
+
* the manifest generator compiles it, and the surfaces read every declared
|
|
29
|
+
* door the same way.
|
|
30
|
+
*
|
|
31
|
+
* The sentences are built here, from the declared nouns, because their
|
|
32
|
+
* discipline is the platform's and not a door's: nothing renders below one
|
|
33
|
+
* refusal or one catch (a counter document persists from its first trip, and
|
|
34
|
+
* "0 refused" every month trains a reader to ignore the row that will one day
|
|
35
|
+
* be real); a refusal is never billed and the owner is told so first; and the
|
|
36
|
+
* date a monthly ceiling lifts is rendered in UTC, the zone its key rolls
|
|
37
|
+
* over in.
|
|
38
|
+
*/ import { PLUGIN_VISITOR_DOORS_DECLARED } from "./first-party-plugins.generated.js";
|
|
39
|
+
import { nextUtcMonthStart } from "../app-utils/utc-month.js";
|
|
40
|
+
/** Every declared door, in the order the plugins are configured. */ export function pluginVisitorDoors() {
|
|
41
|
+
return PLUGIN_VISITOR_DOORS_DECLARED;
|
|
42
|
+
}
|
|
43
|
+
const count = (value)=>Math.floor(Number(value) || 0);
|
|
44
|
+
const said = (noun, n)=>n === 1 ? noun.one : noun.other;
|
|
45
|
+
const capitalized = (text)=>text.charAt(0).toUpperCase() + text.slice(1);
|
|
46
|
+
/** The day a monthly ceiling lifts, in UTC: a reader-zone date would be a day early in the Americas. */ function liftsOn(now) {
|
|
47
|
+
return nextUtcMonthStart(now).toLocaleDateString(undefined, {
|
|
48
|
+
year: 'numeric',
|
|
49
|
+
month: 'long',
|
|
50
|
+
day: 'numeric',
|
|
51
|
+
timeZone: 'UTC'
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The owner's notice for a door refusing this month, or `null` below one
|
|
56
|
+
* refusal. `ceiling` is the one the counter recorded, when it did.
|
|
57
|
+
*/ export function visitorDoorPausedNotice(door, input) {
|
|
58
|
+
var _input_now;
|
|
59
|
+
const refused = count(input.refused);
|
|
60
|
+
if (refused < 1) return null;
|
|
61
|
+
const { words } = door;
|
|
62
|
+
const ceiling = typeof input.ceiling === 'number' && Number.isFinite(input.ceiling) ? Math.floor(input.ceiling) : undefined;
|
|
63
|
+
return {
|
|
64
|
+
title: words.pausedTitle,
|
|
65
|
+
message: `${refused.toLocaleString()} ${said(words.noun, refused)} ` + `to this site ${refused === 1 ? 'has' : 'have'} been refused this month` + (ceiling ? ` after it passed ${ceiling.toLocaleString()} ${words.noun.other}` : '') + `. Refused ${words.noun.other} are not stored and are not billed. ${words.cause}`,
|
|
66
|
+
until: `${capitalized(words.noun.other)} start being accepted again on ${liftsOn((_input_now = input.now) != null ? _input_now : new Date())}.`
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The month's honeypot catches as one sentence, or `null` below one catch.
|
|
71
|
+
* It reports protection WORKING — caught and dropped, nothing stored or
|
|
72
|
+
* billed — so it never reads as an alarm.
|
|
73
|
+
*/ export function visitorDoorCaughtNotice(door, input) {
|
|
74
|
+
const caught = count(input.caught);
|
|
75
|
+
if (caught < 1) return null;
|
|
76
|
+
const { words } = door;
|
|
77
|
+
return `${caught.toLocaleString()} ${said(words.caught, caught)} ` + `${caught === 1 ? 'was' : 'were'} caught and dropped by ${words.caughtBy} ` + 'this month — nothing was stored or billed.';
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The staff Sites card's flags for one door on one site: a refusing door, and
|
|
81
|
+
* the month's catches, each only from one up. Terse labels on purpose — the
|
|
82
|
+
* owner's wording is for owners — with the ceiling and the date it lifts in
|
|
83
|
+
* the detail.
|
|
84
|
+
*/ export function visitorDoorStaffFlags(door, counts, now = new Date()) {
|
|
85
|
+
if (!counts) return {
|
|
86
|
+
refused: null,
|
|
87
|
+
caught: null
|
|
88
|
+
};
|
|
89
|
+
const refused = count(counts.refused);
|
|
90
|
+
const caught = count(counts.caught);
|
|
91
|
+
const { words } = door;
|
|
92
|
+
const ceiling = typeof counts.ceiling === 'number' && Number.isFinite(counts.ceiling) ? Math.floor(counts.ceiling) : null;
|
|
93
|
+
const caughtDetail = visitorDoorCaughtNotice(door, {
|
|
94
|
+
caught
|
|
95
|
+
});
|
|
96
|
+
return {
|
|
97
|
+
refused: refused >= 1 ? {
|
|
98
|
+
label: `${words.pausedChip} · ${refused.toLocaleString()} refused`,
|
|
99
|
+
detail: `${refused.toLocaleString()} ${said(words.staffNoun, refused)} refused this month` + (ceiling ? ` — the site passed its ${ceiling.toLocaleString()}-${words.noun.one} ceiling` : '') + `. Nothing refused is stored or billed. Accepting again on ${liftsOn(now)}.`
|
|
100
|
+
} : null,
|
|
101
|
+
caught: caught >= 1 && caughtDetail ? {
|
|
102
|
+
label: `${caught.toLocaleString()} ${said(words.caughtChip, caught)} caught`,
|
|
103
|
+
detail: caughtDetail
|
|
104
|
+
} : null
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
//# sourceMappingURL=plugin-visitor-doors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-visitor-doors.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * A PLUGIN'S PUBLIC DOOR, AS ITS OWNER AND STAFF SEE IT WHEN IT IS FLOODED\n * (AGL-1666, AGL-1831, AGL-3080).\n *\n * A plugin that keeps a public door a visitor writes through — the forms\n * plugin's `/api/forms/submit` — caps a flood with a monthly ceiling and\n * drops what its honeypot catches, and counts both per site in\n * `hosts/{hostId}/counters/{counter}`, keyed by `utcMonthKey`. The site's\n * owner reads those counts where the door's traffic lands (the Inbox), and\n * staff read them on the organization's Sites card. Neither surface may name\n * the plugin, and neither loads it: so the plugin DECLARES its door in\n * `plugins.config.json` (`visitorDoors`) — the two counters and the words —\n * the manifest generator compiles it, and the surfaces read every declared\n * door the same way.\n *\n * The sentences are built here, from the declared nouns, because their\n * discipline is the platform's and not a door's: nothing renders below one\n * refusal or one catch (a counter document persists from its first trip, and\n * \"0 refused\" every month trains a reader to ignore the row that will one day\n * be real); a refusal is never billed and the owner is told so first; and the\n * date a monthly ceiling lifts is rendered in UTC, the zone its key rolls\n * over in.\n */\n\nimport { PLUGIN_VISITOR_DOORS_DECLARED } from './first-party-plugins.generated'\nimport { nextUtcMonthStart } from '../app-utils/utc-month'\n\n/** A noun in its two counts: `{ one: 'submission', other: 'submissions' }`. */\nexport interface VisitorDoorNoun {\n one: string\n other: string\n}\n\nexport interface VisitorDoorDeclaration {\n /** The door's name, as lockdown and the intake gates name it: `form`. */\n door: string\n /** The site counter the door's ceiling refusals are kept in, by month. */\n refusedCounter: string\n /** The site counter the door's honeypot catches are kept in, by month. */\n caughtCounter: string\n words: {\n /** The owner's notice title: \"Form submissions are paused\". */\n pausedTitle: string\n /** What the door takes in: submission / submissions. */\n noun: VisitorDoorNoun\n /** The same to staff, who see every door: form submission(s). */\n staffNoun: VisitorDoorNoun\n /** Why it usually happens and what to do — the notice's last sentence. */\n cause: string\n /** The staff flag's label for a door refusing now: \"forms paused\". */\n pausedChip: string\n /** What the honeypot catches: bot submission(s). */\n caught: VisitorDoorNoun\n /** What caught them: \"the honeypot\". */\n caughtBy: string\n /** The staff flag's noun for a catch: bot hit(s). */\n caughtChip: VisitorDoorNoun\n }\n}\n\n/** A declaration with the plugin that keeps the door. */\nexport type ResolvedVisitorDoor = VisitorDoorDeclaration & { pluginId: string }\n\n/** A door's counts for one site and month, as a staff join reads them. */\nexport interface VisitorDoorCounts {\n /** The month the counts are for — `utcMonthKey()`. */\n month: string\n /** Refused by the ceiling this month. */\n refused: number\n /** The ceiling the counter recorded when it tripped, when known. */\n ceiling: number | null\n /** Caught by the honeypot this month. */\n caught: number\n}\n\n/** What the site's owner is shown while a door is refusing. */\nexport interface VisitorDoorPausedNotice {\n title: string\n /** What happened, how many, and that none of it is billed. */\n message: string\n /** When it lifts, as a sentence — never a raw month key. */\n until: string\n}\n\n/** Every declared door, in the order the plugins are configured. */\nexport function pluginVisitorDoors(): readonly ResolvedVisitorDoor[] {\n return PLUGIN_VISITOR_DOORS_DECLARED\n}\n\nconst count = (value: unknown): number => Math.floor(Number(value) || 0)\nconst said = (noun: VisitorDoorNoun, n: number): string => (n === 1 ? noun.one : noun.other)\nconst capitalized = (text: string): string => text.charAt(0).toUpperCase() + text.slice(1)\n\n/** The day a monthly ceiling lifts, in UTC: a reader-zone date would be a day early in the Americas. */\nfunction liftsOn(now: Date): string {\n return nextUtcMonthStart(now).toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n timeZone: 'UTC',\n })\n}\n\n/**\n * The owner's notice for a door refusing this month, or `null` below one\n * refusal. `ceiling` is the one the counter recorded, when it did.\n */\nexport function visitorDoorPausedNotice(\n door: VisitorDoorDeclaration,\n input: { refused: number; ceiling?: number; now?: Date },\n): VisitorDoorPausedNotice | null {\n const refused = count(input.refused)\n if (refused < 1) return null\n const { words } = door\n const ceiling =\n typeof input.ceiling === 'number' && Number.isFinite(input.ceiling)\n ? Math.floor(input.ceiling)\n : undefined\n return {\n title: words.pausedTitle,\n message:\n `${refused.toLocaleString()} ${said(words.noun, refused)} ` +\n `to this site ${refused === 1 ? 'has' : 'have'} been refused this month` +\n (ceiling ? ` after it passed ${ceiling.toLocaleString()} ${words.noun.other}` : '') +\n `. Refused ${words.noun.other} are not stored and are not billed. ${words.cause}`,\n until: `${capitalized(words.noun.other)} start being accepted again on ${liftsOn(input.now ?? new Date())}.`,\n }\n}\n\n/**\n * The month's honeypot catches as one sentence, or `null` below one catch.\n * It reports protection WORKING — caught and dropped, nothing stored or\n * billed — so it never reads as an alarm.\n */\nexport function visitorDoorCaughtNotice(\n door: VisitorDoorDeclaration,\n input: { caught: number },\n): string | null {\n const caught = count(input.caught)\n if (caught < 1) return null\n const { words } = door\n return (\n `${caught.toLocaleString()} ${said(words.caught, caught)} ` +\n `${caught === 1 ? 'was' : 'were'} caught and dropped by ${words.caughtBy} ` +\n 'this month — nothing was stored or billed.'\n )\n}\n\n/** One staff flag: the chip's terse label, and the sentence behind it. */\nexport interface VisitorDoorStaffFlag {\n label: string\n detail: string\n}\n\n/**\n * The staff Sites card's flags for one door on one site: a refusing door, and\n * the month's catches, each only from one up. Terse labels on purpose — the\n * owner's wording is for owners — with the ceiling and the date it lifts in\n * the detail.\n */\nexport function visitorDoorStaffFlags(\n door: VisitorDoorDeclaration,\n counts: Pick<VisitorDoorCounts, 'refused' | 'ceiling' | 'caught'> | null | undefined,\n now: Date = new Date(),\n): { refused: VisitorDoorStaffFlag | null; caught: VisitorDoorStaffFlag | null } {\n if (!counts) return { refused: null, caught: null }\n const refused = count(counts.refused)\n const caught = count(counts.caught)\n const { words } = door\n const ceiling =\n typeof counts.ceiling === 'number' && Number.isFinite(counts.ceiling)\n ? Math.floor(counts.ceiling)\n : null\n const caughtDetail = visitorDoorCaughtNotice(door, { caught })\n return {\n refused:\n refused >= 1\n ? {\n label: `${words.pausedChip} · ${refused.toLocaleString()} refused`,\n detail:\n `${refused.toLocaleString()} ${said(words.staffNoun, refused)} refused this month` +\n (ceiling ? ` — the site passed its ${ceiling.toLocaleString()}-${words.noun.one} ceiling` : '') +\n `. Nothing refused is stored or billed. Accepting again on ${liftsOn(now)}.`,\n }\n : null,\n caught:\n caught >= 1 && caughtDetail\n ? { label: `${caught.toLocaleString()} ${said(words.caughtChip, caught)} caught`, detail: caughtDetail }\n : null,\n }\n}\n"],"names":["PLUGIN_VISITOR_DOORS_DECLARED","nextUtcMonthStart","pluginVisitorDoors","count","value","Math","floor","Number","said","noun","n","one","other","capitalized","text","charAt","toUpperCase","slice","liftsOn","now","toLocaleDateString","undefined","year","month","day","timeZone","visitorDoorPausedNotice","door","input","refused","words","ceiling","isFinite","title","pausedTitle","message","toLocaleString","cause","until","Date","visitorDoorCaughtNotice","caught","caughtBy","visitorDoorStaffFlags","counts","caughtDetail","label","pausedChip","detail","staffNoun","caughtChip"],"mappings":"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"}
|
|
@@ -79,12 +79,14 @@ export const AGLYN_HOST_SURFACE = Object.freeze({
|
|
|
79
79
|
FieldComponentType: m10.FieldComponentType,
|
|
80
80
|
FieldValidatorType: m10.FieldValidatorType,
|
|
81
81
|
LinealDirectiveFlag: m10.LinealDirectiveFlag,
|
|
82
|
+
CONSOLE_HOST_GATED_WIDGET_SLOTS: m11.CONSOLE_HOST_GATED_WIDGET_SLOTS,
|
|
82
83
|
CONSOLE_SEARCH_LOAD_POINT: m11.CONSOLE_SEARCH_LOAD_POINT,
|
|
83
84
|
CONSOLE_STAFF_WIDGET_SLOTS: m11.CONSOLE_STAFF_WIDGET_SLOTS,
|
|
84
85
|
CONSOLE_WIDGET_SLOTS: m11.CONSOLE_WIDGET_SLOTS,
|
|
85
86
|
MUI_BUNDLE_ID: m11.MUI_BUNDLE_ID,
|
|
86
87
|
THEME_PRESETS_LOAD_POINT: m11.THEME_PRESETS_LOAD_POINT,
|
|
87
88
|
defineUiFeatureBundle: m11.defineUiFeatureBundle,
|
|
89
|
+
isConsoleHostGatedWidgetSlot: m11.isConsoleHostGatedWidgetSlot,
|
|
88
90
|
isConsoleStaffWidgetSlot: m11.isConsoleStaffWidgetSlot,
|
|
89
91
|
listConsoleExtensions: m11.listConsoleExtensions,
|
|
90
92
|
listConsoleNavItems: m11.listConsoleNavItems,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/realm-host-aglyn.generated.ts"],"sourcesContent":["/**\n * GENERATED FILE — do not edit. Regenerate with:\n * node tools/scripts/generate-realm-host-exports.mjs\n *\n * The realm plugin surface of `@aglyn/aglyn` (AGL-3392): what a signed\n * bundle reads from core. Imported only by the lazily loaded host module.\n */\n/* eslint-disable */\n\nimport * as m0 from \"../aglyn\"\nimport * as m1 from \"../app-utils/binding-tokens\"\nimport * as m2 from \"../app-utils/enabled-plugins-context\"\nimport * as m3 from \"../app-utils/functions\"\nimport * as m4 from \"../app-utils/node-identity\"\nimport * as m5 from \"../app-utils/screen-link-context-value\"\nimport * as m6 from \"../app-utils/site-context\"\nimport * as m7 from \"../app-utils/variables\"\nimport * as m8 from \"../foundation/constants/components\"\nimport * as m9 from \"../foundation/constants/shared\"\nimport * as m10 from \"../foundation/definitions/components.types\"\nimport * as m11 from \"./feature-plugins\"\nimport * as m12 from \"../types/nodes\"\n\nexport const AGLYN_HOST_SURFACE: Readonly<Record<string, unknown>> = Object.freeze({\n Aglyn: m0.Aglyn,\n aglyn: m0.aglyn,\n canvas: m0.canvas,\n components: m0.components,\n emitter: m0.emitter,\n logger: m0.logger,\n plugins: m0.plugins,\n FUNCTION_TOKEN_PATTERN: m1.FUNCTION_TOKEN_PATTERN,\n MISSING_BINDING_LABEL: m1.MISSING_BINDING_LABEL,\n NAME_TOKEN_PATTERN: m1.NAME_TOKEN_PATTERN,\n VARIABLE_ID_TOKEN_PATTERN: m1.VARIABLE_ID_TOKEN_PATTERN,\n bindingTokenNeedsDeep: m1.bindingTokenNeedsDeep,\n displayBindingTokens: m1.displayBindingTokens,\n editableBindingTokens: m1.editableBindingTokens,\n formatFunctionIdToken: m1.formatFunctionIdToken,\n formatVariableIdToken: m1.formatVariableIdToken,\n keyById: m1.keyById,\n nodesReferenceBinding: m1.nodesReferenceBinding,\n normalizeBindingTokens: m1.normalizeBindingTokens,\n rewriteBindingTokensDeep: m1.rewriteBindingTokensDeep,\n textReferencesBinding: m1.textReferencesBinding,\n CATEGORY_REQUIRED_CAPABILITY: m2.CATEGORY_REQUIRED_CAPABILITY,\n EnabledPluginsContext: m2.EnabledPluginsContext,\n isCategoryCapabilityEnabled: m2.isCategoryCapabilityEnabled,\n isFromEnabledPlugin: m2.isFromEnabledPlugin,\n isSwitchedOffForRenderedSite: m2.isSwitchedOffForRenderedSite,\n useEnabledPlugins: m2.useEnabledPlugins,\n FUNCTION_BUILTIN_NAMES: m3.FUNCTION_BUILTIN_NAMES,\n FUNCTION_MAX_OPERATIONS: m3.FUNCTION_MAX_OPERATIONS,\n evaluateExpression: m3.evaluateExpression,\n evaluateHostFunction: m3.evaluateHostFunction,\n expressionIdentifiers: m3.expressionIdentifiers,\n formatFunctionParameterOptions: m3.formatFunctionParameterOptions,\n functionReferencedNames: m3.functionReferencedNames,\n parseFunctionParameterOptions: m3.parseFunctionParameterOptions,\n NodeIdentityContext: m4.NodeIdentityContext,\n useNodeId: m4.useNodeId,\n ScreenLinkContext: m5.ScreenLinkContext,\n PREVIEW_REFUSED_STATUS: m6.PREVIEW_REFUSED_STATUS,\n PREVIEW_WRITE_BLOCKED_EVENT: m6.PREVIEW_WRITE_BLOCKED_EVENT,\n SiteContext: m6.SiteContext,\n isPreviewRefusal: m6.isPreviewRefusal,\n useSite: m6.useSite,\n useSiteFetch: m6.useSiteFetch,\n HOST_VARIABLE_TYPE_LABELS: m7.HOST_VARIABLE_TYPE_LABELS,\n VARIABLE_NAME_PATTERN: m7.VARIABLE_NAME_PATTERN,\n attachFunctionDefinitions: m7.attachFunctionDefinitions,\n formatVariableValue: m7.formatVariableValue,\n functionGlobals: m7.functionGlobals,\n hasBindings: m7.hasBindings,\n resolveBindings: m7.resolveBindings,\n resolveNodesBindings: m7.resolveNodesBindings,\n COMPONENT_CATEGORY_ORDER: m8.COMPONENT_CATEGORY_ORDER,\n ComponentCategory: m8.ComponentCategory,\n REUSABLE_COMPONENT_CATEGORY: m8.REUSABLE_COMPONENT_CATEGORY,\n REUSABLE_EMAIL_BLOCK_CATEGORY: m8.REUSABLE_EMAIL_BLOCK_CATEGORY,\n FEATURE_FLAG: m9.FEATURE_FLAG,\n RICH_TEXT_COMMANDS: m9.RICH_TEXT_COMMANDS,\n FieldComponentType: m10.FieldComponentType,\n FieldValidatorType: m10.FieldValidatorType,\n LinealDirectiveFlag: m10.LinealDirectiveFlag,\n CONSOLE_SEARCH_LOAD_POINT: m11.CONSOLE_SEARCH_LOAD_POINT,\n CONSOLE_STAFF_WIDGET_SLOTS: m11.CONSOLE_STAFF_WIDGET_SLOTS,\n CONSOLE_WIDGET_SLOTS: m11.CONSOLE_WIDGET_SLOTS,\n MUI_BUNDLE_ID: m11.MUI_BUNDLE_ID,\n THEME_PRESETS_LOAD_POINT: m11.THEME_PRESETS_LOAD_POINT,\n defineUiFeatureBundle: m11.defineUiFeatureBundle,\n isConsoleStaffWidgetSlot: m11.isConsoleStaffWidgetSlot,\n listConsoleExtensions: m11.listConsoleExtensions,\n listConsoleNavItems: m11.listConsoleNavItems,\n listConsoleOrgNavItems: m11.listConsoleOrgNavItems,\n listConsoleProviders: m11.listConsoleProviders,\n listConsoleSearchSources: m11.listConsoleSearchSources,\n listConsoleStaffPages: m11.listConsoleStaffPages,\n listConsoleThemePresets: m11.listConsoleThemePresets,\n listConsoleWidgets: m11.listConsoleWidgets,\n registerConsoleExtension: m11.registerConsoleExtension,\n resolveConsoleOrgPluginPage: m11.resolveConsoleOrgPluginPage,\n resolveConsolePluginPage: m11.resolveConsolePluginPage,\n resolveConsoleStaffPage: m11.resolveConsoleStaffPage,\n unregisterConsoleExtension: m11.unregisterConsoleExtension,\n NodeType: m12.NodeType,\n})\n"],"names":["m0","m1","m2","m3","m4","m5","m6","m7","m8","m9","m10","m11","m12","AGLYN_HOST_SURFACE","Object","freeze","Aglyn","aglyn","canvas","components","emitter","logger","plugins","FUNCTION_TOKEN_PATTERN","MISSING_BINDING_LABEL","NAME_TOKEN_PATTERN","VARIABLE_ID_TOKEN_PATTERN","bindingTokenNeedsDeep","displayBindingTokens","editableBindingTokens","formatFunctionIdToken","formatVariableIdToken","keyById","nodesReferenceBinding","normalizeBindingTokens","rewriteBindingTokensDeep","textReferencesBinding","CATEGORY_REQUIRED_CAPABILITY","EnabledPluginsContext","isCategoryCapabilityEnabled","isFromEnabledPlugin","isSwitchedOffForRenderedSite","useEnabledPlugins","FUNCTION_BUILTIN_NAMES","FUNCTION_MAX_OPERATIONS","evaluateExpression","evaluateHostFunction","expressionIdentifiers","formatFunctionParameterOptions","functionReferencedNames","parseFunctionParameterOptions","NodeIdentityContext","useNodeId","ScreenLinkContext","PREVIEW_REFUSED_STATUS","PREVIEW_WRITE_BLOCKED_EVENT","SiteContext","isPreviewRefusal","useSite","useSiteFetch","HOST_VARIABLE_TYPE_LABELS","VARIABLE_NAME_PATTERN","attachFunctionDefinitions","formatVariableValue","functionGlobals","hasBindings","resolveBindings","resolveNodesBindings","COMPONENT_CATEGORY_ORDER","ComponentCategory","REUSABLE_COMPONENT_CATEGORY","REUSABLE_EMAIL_BLOCK_CATEGORY","FEATURE_FLAG","RICH_TEXT_COMMANDS","FieldComponentType","FieldValidatorType","LinealDirectiveFlag","CONSOLE_SEARCH_LOAD_POINT","CONSOLE_STAFF_WIDGET_SLOTS","CONSOLE_WIDGET_SLOTS","MUI_BUNDLE_ID","THEME_PRESETS_LOAD_POINT","defineUiFeatureBundle","isConsoleStaffWidgetSlot","listConsoleExtensions","listConsoleNavItems","listConsoleOrgNavItems","listConsoleProviders","listConsoleSearchSources","listConsoleStaffPages","listConsoleThemePresets","listConsoleWidgets","registerConsoleExtension","resolveConsoleOrgPluginPage","resolveConsolePluginPage","resolveConsoleStaffPage","unregisterConsoleExtension","NodeType"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/realm-host-aglyn.generated.ts"],"sourcesContent":["/**\n * GENERATED FILE — do not edit. Regenerate with:\n * node tools/scripts/generate-realm-host-exports.mjs\n *\n * The realm plugin surface of `@aglyn/aglyn` (AGL-3392): what a signed\n * bundle reads from core. Imported only by the lazily loaded host module.\n */\n/* eslint-disable */\n\nimport * as m0 from \"../aglyn\"\nimport * as m1 from \"../app-utils/binding-tokens\"\nimport * as m2 from \"../app-utils/enabled-plugins-context\"\nimport * as m3 from \"../app-utils/functions\"\nimport * as m4 from \"../app-utils/node-identity\"\nimport * as m5 from \"../app-utils/screen-link-context-value\"\nimport * as m6 from \"../app-utils/site-context\"\nimport * as m7 from \"../app-utils/variables\"\nimport * as m8 from \"../foundation/constants/components\"\nimport * as m9 from \"../foundation/constants/shared\"\nimport * as m10 from \"../foundation/definitions/components.types\"\nimport * as m11 from \"./feature-plugins\"\nimport * as m12 from \"../types/nodes\"\n\nexport const AGLYN_HOST_SURFACE: Readonly<Record<string, unknown>> = Object.freeze({\n Aglyn: m0.Aglyn,\n aglyn: m0.aglyn,\n canvas: m0.canvas,\n components: m0.components,\n emitter: m0.emitter,\n logger: m0.logger,\n plugins: m0.plugins,\n FUNCTION_TOKEN_PATTERN: m1.FUNCTION_TOKEN_PATTERN,\n MISSING_BINDING_LABEL: m1.MISSING_BINDING_LABEL,\n NAME_TOKEN_PATTERN: m1.NAME_TOKEN_PATTERN,\n VARIABLE_ID_TOKEN_PATTERN: m1.VARIABLE_ID_TOKEN_PATTERN,\n bindingTokenNeedsDeep: m1.bindingTokenNeedsDeep,\n displayBindingTokens: m1.displayBindingTokens,\n editableBindingTokens: m1.editableBindingTokens,\n formatFunctionIdToken: m1.formatFunctionIdToken,\n formatVariableIdToken: m1.formatVariableIdToken,\n keyById: m1.keyById,\n nodesReferenceBinding: m1.nodesReferenceBinding,\n normalizeBindingTokens: m1.normalizeBindingTokens,\n rewriteBindingTokensDeep: m1.rewriteBindingTokensDeep,\n textReferencesBinding: m1.textReferencesBinding,\n CATEGORY_REQUIRED_CAPABILITY: m2.CATEGORY_REQUIRED_CAPABILITY,\n EnabledPluginsContext: m2.EnabledPluginsContext,\n isCategoryCapabilityEnabled: m2.isCategoryCapabilityEnabled,\n isFromEnabledPlugin: m2.isFromEnabledPlugin,\n isSwitchedOffForRenderedSite: m2.isSwitchedOffForRenderedSite,\n useEnabledPlugins: m2.useEnabledPlugins,\n FUNCTION_BUILTIN_NAMES: m3.FUNCTION_BUILTIN_NAMES,\n FUNCTION_MAX_OPERATIONS: m3.FUNCTION_MAX_OPERATIONS,\n evaluateExpression: m3.evaluateExpression,\n evaluateHostFunction: m3.evaluateHostFunction,\n expressionIdentifiers: m3.expressionIdentifiers,\n formatFunctionParameterOptions: m3.formatFunctionParameterOptions,\n functionReferencedNames: m3.functionReferencedNames,\n parseFunctionParameterOptions: m3.parseFunctionParameterOptions,\n NodeIdentityContext: m4.NodeIdentityContext,\n useNodeId: m4.useNodeId,\n ScreenLinkContext: m5.ScreenLinkContext,\n PREVIEW_REFUSED_STATUS: m6.PREVIEW_REFUSED_STATUS,\n PREVIEW_WRITE_BLOCKED_EVENT: m6.PREVIEW_WRITE_BLOCKED_EVENT,\n SiteContext: m6.SiteContext,\n isPreviewRefusal: m6.isPreviewRefusal,\n useSite: m6.useSite,\n useSiteFetch: m6.useSiteFetch,\n HOST_VARIABLE_TYPE_LABELS: m7.HOST_VARIABLE_TYPE_LABELS,\n VARIABLE_NAME_PATTERN: m7.VARIABLE_NAME_PATTERN,\n attachFunctionDefinitions: m7.attachFunctionDefinitions,\n formatVariableValue: m7.formatVariableValue,\n functionGlobals: m7.functionGlobals,\n hasBindings: m7.hasBindings,\n resolveBindings: m7.resolveBindings,\n resolveNodesBindings: m7.resolveNodesBindings,\n COMPONENT_CATEGORY_ORDER: m8.COMPONENT_CATEGORY_ORDER,\n ComponentCategory: m8.ComponentCategory,\n REUSABLE_COMPONENT_CATEGORY: m8.REUSABLE_COMPONENT_CATEGORY,\n REUSABLE_EMAIL_BLOCK_CATEGORY: m8.REUSABLE_EMAIL_BLOCK_CATEGORY,\n FEATURE_FLAG: m9.FEATURE_FLAG,\n RICH_TEXT_COMMANDS: m9.RICH_TEXT_COMMANDS,\n FieldComponentType: m10.FieldComponentType,\n FieldValidatorType: m10.FieldValidatorType,\n LinealDirectiveFlag: m10.LinealDirectiveFlag,\n CONSOLE_HOST_GATED_WIDGET_SLOTS: m11.CONSOLE_HOST_GATED_WIDGET_SLOTS,\n CONSOLE_SEARCH_LOAD_POINT: m11.CONSOLE_SEARCH_LOAD_POINT,\n CONSOLE_STAFF_WIDGET_SLOTS: m11.CONSOLE_STAFF_WIDGET_SLOTS,\n CONSOLE_WIDGET_SLOTS: m11.CONSOLE_WIDGET_SLOTS,\n MUI_BUNDLE_ID: m11.MUI_BUNDLE_ID,\n THEME_PRESETS_LOAD_POINT: m11.THEME_PRESETS_LOAD_POINT,\n defineUiFeatureBundle: m11.defineUiFeatureBundle,\n isConsoleHostGatedWidgetSlot: m11.isConsoleHostGatedWidgetSlot,\n isConsoleStaffWidgetSlot: m11.isConsoleStaffWidgetSlot,\n listConsoleExtensions: m11.listConsoleExtensions,\n listConsoleNavItems: m11.listConsoleNavItems,\n listConsoleOrgNavItems: m11.listConsoleOrgNavItems,\n listConsoleProviders: m11.listConsoleProviders,\n listConsoleSearchSources: m11.listConsoleSearchSources,\n listConsoleStaffPages: m11.listConsoleStaffPages,\n listConsoleThemePresets: m11.listConsoleThemePresets,\n listConsoleWidgets: m11.listConsoleWidgets,\n registerConsoleExtension: m11.registerConsoleExtension,\n resolveConsoleOrgPluginPage: m11.resolveConsoleOrgPluginPage,\n resolveConsolePluginPage: m11.resolveConsolePluginPage,\n resolveConsoleStaffPage: m11.resolveConsoleStaffPage,\n unregisterConsoleExtension: m11.unregisterConsoleExtension,\n NodeType: m12.NodeType,\n})\n"],"names":["m0","m1","m2","m3","m4","m5","m6","m7","m8","m9","m10","m11","m12","AGLYN_HOST_SURFACE","Object","freeze","Aglyn","aglyn","canvas","components","emitter","logger","plugins","FUNCTION_TOKEN_PATTERN","MISSING_BINDING_LABEL","NAME_TOKEN_PATTERN","VARIABLE_ID_TOKEN_PATTERN","bindingTokenNeedsDeep","displayBindingTokens","editableBindingTokens","formatFunctionIdToken","formatVariableIdToken","keyById","nodesReferenceBinding","normalizeBindingTokens","rewriteBindingTokensDeep","textReferencesBinding","CATEGORY_REQUIRED_CAPABILITY","EnabledPluginsContext","isCategoryCapabilityEnabled","isFromEnabledPlugin","isSwitchedOffForRenderedSite","useEnabledPlugins","FUNCTION_BUILTIN_NAMES","FUNCTION_MAX_OPERATIONS","evaluateExpression","evaluateHostFunction","expressionIdentifiers","formatFunctionParameterOptions","functionReferencedNames","parseFunctionParameterOptions","NodeIdentityContext","useNodeId","ScreenLinkContext","PREVIEW_REFUSED_STATUS","PREVIEW_WRITE_BLOCKED_EVENT","SiteContext","isPreviewRefusal","useSite","useSiteFetch","HOST_VARIABLE_TYPE_LABELS","VARIABLE_NAME_PATTERN","attachFunctionDefinitions","formatVariableValue","functionGlobals","hasBindings","resolveBindings","resolveNodesBindings","COMPONENT_CATEGORY_ORDER","ComponentCategory","REUSABLE_COMPONENT_CATEGORY","REUSABLE_EMAIL_BLOCK_CATEGORY","FEATURE_FLAG","RICH_TEXT_COMMANDS","FieldComponentType","FieldValidatorType","LinealDirectiveFlag","CONSOLE_HOST_GATED_WIDGET_SLOTS","CONSOLE_SEARCH_LOAD_POINT","CONSOLE_STAFF_WIDGET_SLOTS","CONSOLE_WIDGET_SLOTS","MUI_BUNDLE_ID","THEME_PRESETS_LOAD_POINT","defineUiFeatureBundle","isConsoleHostGatedWidgetSlot","isConsoleStaffWidgetSlot","listConsoleExtensions","listConsoleNavItems","listConsoleOrgNavItems","listConsoleProviders","listConsoleSearchSources","listConsoleStaffPages","listConsoleThemePresets","listConsoleWidgets","registerConsoleExtension","resolveConsoleOrgPluginPage","resolveConsolePluginPage","resolveConsoleStaffPage","unregisterConsoleExtension","NodeType"],"mappings":"AAAA;;;;;;CAMC,GACD,kBAAkB,GAElB,YAAYA,QAAQ,cAAU;AAC9B,YAAYC,QAAQ,iCAA6B;AACjD,YAAYC,QAAQ,0CAAsC;AAC1D,YAAYC,QAAQ,4BAAwB;AAC5C,YAAYC,QAAQ,gCAA4B;AAChD,YAAYC,QAAQ,4CAAwC;AAC5D,YAAYC,QAAQ,+BAA2B;AAC/C,YAAYC,QAAQ,4BAAwB;AAC5C,YAAYC,QAAQ,wCAAoC;AACxD,YAAYC,QAAQ,oCAAgC;AACpD,YAAYC,SAAS,gDAA4C;AACjE,YAAYC,SAAS,uBAAmB;AACxC,YAAYC,SAAS,oBAAgB;AAErC,OAAO,MAAMC,qBAAwDC,OAAOC,MAAM,CAAC;IACjFC,OAAOhB,GAAGgB,KAAK;IACfC,OAAOjB,GAAGiB,KAAK;IACfC,QAAQlB,GAAGkB,MAAM;IACjBC,YAAYnB,GAAGmB,UAAU;IACzBC,SAASpB,GAAGoB,OAAO;IACnBC,QAAQrB,GAAGqB,MAAM;IACjBC,SAAStB,GAAGsB,OAAO;IACnBC,wBAAwBtB,GAAGsB,sBAAsB;IACjDC,uBAAuBvB,GAAGuB,qBAAqB;IAC/CC,oBAAoBxB,GAAGwB,kBAAkB;IACzCC,2BAA2BzB,GAAGyB,yBAAyB;IACvDC,uBAAuB1B,GAAG0B,qBAAqB;IAC/CC,sBAAsB3B,GAAG2B,oBAAoB;IAC7CC,uBAAuB5B,GAAG4B,qBAAqB;IAC/CC,uBAAuB7B,GAAG6B,qBAAqB;IAC/CC,uBAAuB9B,GAAG8B,qBAAqB;IAC/CC,SAAS/B,GAAG+B,OAAO;IACnBC,uBAAuBhC,GAAGgC,qBAAqB;IAC/CC,wBAAwBjC,GAAGiC,sBAAsB;IACjDC,0BAA0BlC,GAAGkC,wBAAwB;IACrDC,uBAAuBnC,GAAGmC,qBAAqB;IAC/CC,8BAA8BnC,GAAGmC,4BAA4B;IAC7DC,uBAAuBpC,GAAGoC,qBAAqB;IAC/CC,6BAA6BrC,GAAGqC,2BAA2B;IAC3DC,qBAAqBtC,GAAGsC,mBAAmB;IAC3CC,8BAA8BvC,GAAGuC,4BAA4B;IAC7DC,mBAAmBxC,GAAGwC,iBAAiB;IACvCC,wBAAwBxC,GAAGwC,sBAAsB;IACjDC,yBAAyBzC,GAAGyC,uBAAuB;IACnDC,oBAAoB1C,GAAG0C,kBAAkB;IACzCC,sBAAsB3C,GAAG2C,oBAAoB;IAC7CC,uBAAuB5C,GAAG4C,qBAAqB;IAC/CC,gCAAgC7C,GAAG6C,8BAA8B;IACjEC,yBAAyB9C,GAAG8C,uBAAuB;IACnDC,+BAA+B/C,GAAG+C,6BAA6B;IAC/DC,qBAAqB/C,GAAG+C,mBAAmB;IAC3CC,WAAWhD,GAAGgD,SAAS;IACvBC,mBAAmBhD,GAAGgD,iBAAiB;IACvCC,wBAAwBhD,GAAGgD,sBAAsB;IACjDC,6BAA6BjD,GAAGiD,2BAA2B;IAC3DC,aAAalD,GAAGkD,WAAW;IAC3BC,kBAAkBnD,GAAGmD,gBAAgB;IACrCC,SAASpD,GAAGoD,OAAO;IACnBC,cAAcrD,GAAGqD,YAAY;IAC7BC,2BAA2BrD,GAAGqD,yBAAyB;IACvDC,uBAAuBtD,GAAGsD,qBAAqB;IAC/CC,2BAA2BvD,GAAGuD,yBAAyB;IACvDC,qBAAqBxD,GAAGwD,mBAAmB;IAC3CC,iBAAiBzD,GAAGyD,eAAe;IACnCC,aAAa1D,GAAG0D,WAAW;IAC3BC,iBAAiB3D,GAAG2D,eAAe;IACnCC,sBAAsB5D,GAAG4D,oBAAoB;IAC7CC,0BAA0B5D,GAAG4D,wBAAwB;IACrDC,mBAAmB7D,GAAG6D,iBAAiB;IACvCC,6BAA6B9D,GAAG8D,2BAA2B;IAC3DC,+BAA+B/D,GAAG+D,6BAA6B;IAC/DC,cAAc/D,GAAG+D,YAAY;IAC7BC,oBAAoBhE,GAAGgE,kBAAkB;IACzCC,oBAAoBhE,IAAIgE,kBAAkB;IAC1CC,oBAAoBjE,IAAIiE,kBAAkB;IAC1CC,qBAAqBlE,IAAIkE,mBAAmB;IAC5CC,iCAAiClE,IAAIkE,+BAA+B;IACpEC,2BAA2BnE,IAAImE,yBAAyB;IACxDC,4BAA4BpE,IAAIoE,0BAA0B;IAC1DC,sBAAsBrE,IAAIqE,oBAAoB;IAC9CC,eAAetE,IAAIsE,aAAa;IAChCC,0BAA0BvE,IAAIuE,wBAAwB;IACtDC,uBAAuBxE,IAAIwE,qBAAqB;IAChDC,8BAA8BzE,IAAIyE,4BAA4B;IAC9DC,0BAA0B1E,IAAI0E,wBAAwB;IACtDC,uBAAuB3E,IAAI2E,qBAAqB;IAChDC,qBAAqB5E,IAAI4E,mBAAmB;IAC5CC,wBAAwB7E,IAAI6E,sBAAsB;IAClDC,sBAAsB9E,IAAI8E,oBAAoB;IAC9CC,0BAA0B/E,IAAI+E,wBAAwB;IACtDC,uBAAuBhF,IAAIgF,qBAAqB;IAChDC,yBAAyBjF,IAAIiF,uBAAuB;IACpDC,oBAAoBlF,IAAIkF,kBAAkB;IAC1CC,0BAA0BnF,IAAImF,wBAAwB;IACtDC,6BAA6BpF,IAAIoF,2BAA2B;IAC5DC,0BAA0BrF,IAAIqF,wBAAwB;IACtDC,yBAAyBtF,IAAIsF,uBAAuB;IACpDC,4BAA4BvF,IAAIuF,0BAA0B;IAC1DC,UAAUvF,IAAIuF,QAAQ;AACxB,GAAE"}
|
|
@@ -35,8 +35,8 @@ import type { RepeatableDataset } from '../app-utils/expand-repeatables';
|
|
|
35
35
|
* entry, which every app runs at boot, so every process that composes a page
|
|
36
36
|
* has it before the first request. But a registry is only safe where an empty
|
|
37
37
|
* one cannot be mistaken for an answer, and here it can: a page whose repeat
|
|
38
|
-
* found no reader would render
|
|
39
|
-
*
|
|
38
|
+
* found no reader would render no copies where the author put a list, and
|
|
39
|
+
* nothing anywhere would be red. That is the AGL-3025 shape on the most
|
|
40
40
|
* public surface the product has.
|
|
41
41
|
*
|
|
42
42
|
* So the plugin that answers also DECLARES that it does, in
|
|
@@ -45,8 +45,7 @@ import type { RepeatableDataset } from '../app-utils/expand-repeatables';
|
|
|
45
45
|
* that is a broken boot:
|
|
46
46
|
*
|
|
47
47
|
* - nothing declared — this deployment ships no plugin that keeps rows, and a
|
|
48
|
-
* repeat renders
|
|
49
|
-
* nothing does;
|
|
48
|
+
* repeat renders no copies, exactly as a key naming nothing does (AGL-3496);
|
|
50
49
|
* - declared and registered — the reader answers;
|
|
51
50
|
* - declared and NOT registered — the boot failed. The app's declarations
|
|
52
51
|
* step is run again ({@link runPluginDeclarationsRepair}); if the reader is
|
|
@@ -55,8 +54,8 @@ import type { RepeatableDataset } from '../app-utils/expand-repeatables';
|
|
|
55
54
|
* the right way round for a page that would otherwise go out wrong.
|
|
56
55
|
*
|
|
57
56
|
* Per-key failures are the reader's to absorb, as they always were: a deleted
|
|
58
|
-
* or unreadable entry
|
|
59
|
-
* nothing else.
|
|
57
|
+
* or unreadable entry renders no copies of its element (AGL-3496) — never its
|
|
58
|
+
* raw `{{item.*}}` template — and costs the page nothing else.
|
|
60
59
|
*
|
|
61
60
|
* Reached by path, never through a barrel: only the server composition asks.
|
|
62
61
|
*/
|