@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
|
@@ -17,8 +17,11 @@ import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
|
17
17
|
*/ import { screenRoutePathToUrl } from "./screen-route.js";
|
|
18
18
|
import { nodesReferenceScreen } from "./screen-link-value.js";
|
|
19
19
|
import { isScreenIndexable, isSearchDiscouraged, statusPageScreenIds } from "./search-indexing.js";
|
|
20
|
-
import { SEO_AUDIT_MAX_PAGES,
|
|
20
|
+
import { SEO_AUDIT_MAX_PAGES, readSeoKeywordLines, seoNormalizePath } from "./seo-audit.js";
|
|
21
|
+
import { SEO_MAX_KEYWORDS, seoQuotedKeywords } from "./seo-keywords.js";
|
|
21
22
|
import { seoPageFacts } from "./seo-page-facts.js";
|
|
23
|
+
import { expandRepeatables, repeatKeys } from "./expand-repeatables.js";
|
|
24
|
+
import { composeReferencedComponents, hostComponentReader } from "./load-referenced-components.js";
|
|
22
25
|
import { resolveSeoTitleVariables } from "./seo-title-variables.js";
|
|
23
26
|
import { decodeStoredNodes } from "./stored-nodes.js";
|
|
24
27
|
/**
|
|
@@ -35,13 +38,82 @@ import { decodeStoredNodes } from "./stored-nodes.js";
|
|
|
35
38
|
* template screen ids, which the tenant runtime resolves; so this module stays
|
|
36
39
|
* pure enough to import from anywhere, and a spec hands it a fake.
|
|
37
40
|
*
|
|
41
|
+
* Each page is checked as it publishes (AGL-3501): {@link composeSeoPages}
|
|
42
|
+
* grafts the reusable components it places, with each placement's values,
|
|
43
|
+
* and expands its repeats over their rows when the caller hands over the
|
|
44
|
+
* repeat-rows reader — the composition the tenant runs before it renders.
|
|
45
|
+
*
|
|
38
46
|
* Reads: one projected query of the screens, one of the layouts, and one
|
|
39
47
|
* version document per checked page and per layout — at most
|
|
40
|
-
* {@link SEO_AUDIT_MAX_PAGES} + {@link SEO_SCAN_LAYOUT_LIMIT} + 2
|
|
48
|
+
* {@link SEO_AUDIT_MAX_PAGES} + {@link SEO_SCAN_LAYOUT_LIMIT} + 2 — then one
|
|
49
|
+
* document per distinct component those place, and one repeat-rows request
|
|
50
|
+
* for every key they repeat over.
|
|
41
51
|
*/ /** Shared layouts read for the links they carry. */ export const SEO_SCAN_LAYOUT_LIMIT = 20;
|
|
42
52
|
/** Version documents read at once. */ const READ_CHUNK = 10;
|
|
43
53
|
/** Screen documents the projected query reads. */ const SCREEN_SCAN_LIMIT = 1000;
|
|
44
54
|
const str = (value)=>typeof value === 'string' ? value.trim() : '';
|
|
55
|
+
/** A component reader that reads each document once however many pages place it. */ function onceEach(read) {
|
|
56
|
+
const reads = new Map();
|
|
57
|
+
return (componentId)=>{
|
|
58
|
+
let pending = reads.get(componentId);
|
|
59
|
+
if (!pending) {
|
|
60
|
+
pending = read(componentId);
|
|
61
|
+
reads.set(componentId, pending);
|
|
62
|
+
}
|
|
63
|
+
return pending;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Node maps of `hostId` as they publish (AGL-3501): each reusable component
|
|
68
|
+
* placed grafted from its published definition with the placement's values
|
|
69
|
+
* (`load-referenced-components.ts`, the graft the tenant runs), then each
|
|
70
|
+
* repeat expanded over its rows when `readRepeatRows` is given — one request
|
|
71
|
+
* for every key the maps repeat over.
|
|
72
|
+
*
|
|
73
|
+
* A component that does not load leaves its placement as authored, as on the
|
|
74
|
+
* page; rows that cannot be read leave each repeat once, as written, and say
|
|
75
|
+
* so through `rowsUnread` rather than failing the check.
|
|
76
|
+
*/ export async function composeSeoPages(store, hostId, maps, options = {}) {
|
|
77
|
+
const read = onceEach(hostComponentReader(store, hostId));
|
|
78
|
+
const skipped = new Map();
|
|
79
|
+
const grafted = await Promise.all(maps.map((nodes)=>nodes ? composeReferencedComponents(nodes, read, {
|
|
80
|
+
onSkipped: (list)=>list.forEach((entry)=>skipped.set(entry.id, entry))
|
|
81
|
+
}) : null));
|
|
82
|
+
if (skipped.size) {
|
|
83
|
+
console.warn(JSON.stringify({
|
|
84
|
+
tag: 'AGL-3501:seo-components-skipped',
|
|
85
|
+
hostId,
|
|
86
|
+
skipped: [
|
|
87
|
+
...skipped.values()
|
|
88
|
+
]
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
const keys = [
|
|
92
|
+
...new Set(grafted.flatMap((nodes)=>nodes ? repeatKeys(nodes) : []))
|
|
93
|
+
].sort();
|
|
94
|
+
if (!keys.length || !options.readRepeatRows) return {
|
|
95
|
+
composed: grafted,
|
|
96
|
+
rowsUnread: false
|
|
97
|
+
};
|
|
98
|
+
let rows;
|
|
99
|
+
try {
|
|
100
|
+
rows = await options.readRepeatRows(keys);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.warn(JSON.stringify({
|
|
103
|
+
tag: 'AGL-3501:seo-repeat-rows-unread',
|
|
104
|
+
hostId,
|
|
105
|
+
error: String(error)
|
|
106
|
+
}));
|
|
107
|
+
return {
|
|
108
|
+
composed: grafted,
|
|
109
|
+
rowsUnread: true
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
composed: grafted.map((nodes)=>nodes ? expandRepeatables(nodes, rows) : null),
|
|
114
|
+
rowsUnread: false
|
|
115
|
+
};
|
|
116
|
+
}
|
|
45
117
|
/** The site as the check reads it, from its host document. */ export function seoAuditSiteOf(host) {
|
|
46
118
|
var _ref, _ref1;
|
|
47
119
|
var _host_seo, _host_seo1;
|
|
@@ -74,7 +146,9 @@ async function inChunks(items, run) {
|
|
|
74
146
|
*
|
|
75
147
|
* `keywords` are the target keyword lines a person typed (`/path: a, b`);
|
|
76
148
|
* `templateScreenIds` are the screens a collection, the store or the host
|
|
77
|
-
* renders other URLs through, which are not pages of their own
|
|
149
|
+
* renders other URLs through, which are not pages of their own;
|
|
150
|
+
* `readRepeatRows` reads the rows the pages repeat over
|
|
151
|
+
* ({@link composeSeoPages}).
|
|
78
152
|
*/ export async function scanSeoSite(store, hostId, host, options = {}) {
|
|
79
153
|
var _host_screens, _options_templateScreenIds;
|
|
80
154
|
var _host_seo;
|
|
@@ -108,14 +182,41 @@ async function inChunks(items, run) {
|
|
|
108
182
|
var _screens_get;
|
|
109
183
|
versions.set(screenId, await readVersionNodes(hostRef.collection('screens').doc(screenId), str((_screens_get = screens.get(screenId)) == null ? void 0 : _screens_get.versionId)));
|
|
110
184
|
});
|
|
111
|
-
const
|
|
185
|
+
const storedLayouts = [];
|
|
112
186
|
await inChunks(layoutDocs.docs.filter((doc)=>str(doc.get('versionId'))), async (doc)=>{
|
|
113
187
|
const version = await readVersionNodes(doc.ref, str(doc.get('versionId')));
|
|
114
|
-
if (version)
|
|
188
|
+
if (version) storedLayouts.push(version.nodes);
|
|
115
189
|
});
|
|
116
|
-
|
|
190
|
+
// Checked as they publish: a heading, an image or a link a component
|
|
191
|
+
// renders is the page's, and so is a row a repeat shows.
|
|
192
|
+
const { composed, rowsUnread } = await composeSeoPages(store, hostId, [
|
|
193
|
+
...checked.map(({ screenId })=>{
|
|
194
|
+
var _ref;
|
|
195
|
+
var _versions_get;
|
|
196
|
+
return (_ref = (_versions_get = versions.get(screenId)) == null ? void 0 : _versions_get.nodes) != null ? _ref : null;
|
|
197
|
+
}),
|
|
198
|
+
...storedLayouts
|
|
199
|
+
], options);
|
|
200
|
+
const composedPages = new Map(checked.map(({ screenId }, index)=>[
|
|
201
|
+
screenId,
|
|
202
|
+
composed[index]
|
|
203
|
+
]));
|
|
204
|
+
const layoutNodes = composed.slice(checked.length);
|
|
205
|
+
const keywordLines = readSeoKeywordLines(options.keywords);
|
|
206
|
+
const keywordsByPath = keywordLines.keywords;
|
|
117
207
|
const checkedPaths = new Set(checked.map((page)=>seoNormalizePath(page.path)));
|
|
118
|
-
const notes =
|
|
208
|
+
const notes = [
|
|
209
|
+
...[
|
|
210
|
+
...new Set([
|
|
211
|
+
...Object.keys(keywordsByPath),
|
|
212
|
+
...Object.keys(keywordLines.unchecked)
|
|
213
|
+
])
|
|
214
|
+
].filter((path)=>!checkedPaths.has(path)).map((path)=>`Keywords for ${path} were not used: no checked page is published at that address.`),
|
|
215
|
+
...Object.entries(keywordLines.unchecked).filter(([path])=>checkedPaths.has(path)).map(([path, unchecked])=>`Only the first ${SEO_MAX_KEYWORDS} keywords for ${path} were checked, so ${seoQuotedKeywords(unchecked)} ${unchecked.length === 1 ? 'was' : 'were'} not.`),
|
|
216
|
+
...rowsUnread ? [
|
|
217
|
+
'Lists that repeat over your datasets were checked without their rows, which could not be read just now.'
|
|
218
|
+
] : []
|
|
219
|
+
];
|
|
119
220
|
const siteName = str((_host_seo = host.seo) == null ? void 0 : _host_seo.title) || str(host.displayName);
|
|
120
221
|
const pages = checked.map(({ screenId, path })=>{
|
|
121
222
|
var _screens_get, _versions_get, _screen_seo, _keywordsByPath_seoNormalizePath, _ref;
|
|
@@ -124,9 +225,8 @@ async function inChunks(items, run) {
|
|
|
124
225
|
const version = (_versions_get = versions.get(screenId)) != null ? _versions_get : null;
|
|
125
226
|
const storedSeo = (_screen_seo = screen.seo) != null ? _screen_seo : {};
|
|
126
227
|
const linkedFrom = layoutNodes.some((nodes)=>nodesReferenceScreen(nodes, screenId)) || checked.some((other)=>{
|
|
127
|
-
var
|
|
128
|
-
|
|
129
|
-
return other.screenId !== screenId && nodesReferenceScreen((_ref = (_versions_get = versions.get(other.screenId)) == null ? void 0 : _versions_get.nodes) != null ? _ref : null, screenId);
|
|
228
|
+
var _composedPages_get;
|
|
229
|
+
return other.screenId !== screenId && nodesReferenceScreen((_composedPages_get = composedPages.get(other.screenId)) != null ? _composedPages_get : null, screenId);
|
|
130
230
|
});
|
|
131
231
|
return {
|
|
132
232
|
screenId,
|
|
@@ -144,8 +244,9 @@ async function inChunks(items, run) {
|
|
|
144
244
|
}),
|
|
145
245
|
storedSeo,
|
|
146
246
|
description: str(screen.description),
|
|
147
|
-
facts: seoPageFacts(
|
|
148
|
-
rootId: version == null ? void 0 : version.rootId
|
|
247
|
+
facts: seoPageFacts(composedPages.get(screenId), {
|
|
248
|
+
rootId: version == null ? void 0 : version.rootId,
|
|
249
|
+
pageNodes: version == null ? void 0 : version.nodes
|
|
149
250
|
}),
|
|
150
251
|
linkedFrom,
|
|
151
252
|
keywords: (_keywordsByPath_seoNormalizePath = keywordsByPath[seoNormalizePath(path)]) != null ? _keywordsByPath_seoNormalizePath : [],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/seo-site-scan.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { screenRoutePathToUrl } from './screen-route'\nimport { nodesReferenceScreen } from './screen-link-value'\nimport {\n isScreenIndexable,\n isSearchDiscouraged,\n statusPageScreenIds,\n type SearchIndexingScreen,\n} from './search-indexing'\nimport {\n SEO_AUDIT_MAX_PAGES,\n parseSeoKeywordLines,\n seoNormalizePath,\n type SeoAuditPage,\n type SeoAuditSite,\n} from './seo-audit'\nimport { seoPageFacts } from './seo-page-facts'\nimport type { PageMarkdownNodes } from './page-markdown'\nimport { resolveSeoTitleVariables } from './seo-title-variables'\nimport { decodeStoredNodes } from './stored-nodes'\n\n/**\n * Read a site for the SEO check (`seo-audit.ts`) the way its sitemap lists\n * it: every screen the routing map publishes, less the template screens, the\n * status pages and every screen that is not public — through the same shared\n * predicates the tenant's `sitemap.xml` and `/llms.txt` apply, so the check\n * covers exactly the pages a crawler is handed. Then each page's published\n * version, and the shared layouts, for the links that decide which pages\n * nothing points to.\n *\n * It knows nothing about the Firestore SDK. A caller hands it a\n * {@link SeoScanStore} — the Admin SDK's `Firestore` satisfies it — and the\n * template screen ids, which the tenant runtime resolves; so this module stays\n * pure enough to import from anywhere, and a spec hands it a fake.\n *\n * Reads: one projected query of the screens, one of the layouts, and one\n * version document per checked page and per layout — at most\n * {@link SEO_AUDIT_MAX_PAGES} + {@link SEO_SCAN_LAYOUT_LIMIT} + 2.\n */\n\n/** Shared layouts read for the links they carry. */\nexport const SEO_SCAN_LAYOUT_LIMIT = 20\n\n/** Version documents read at once. */\nconst READ_CHUNK = 10\n\n/** Screen documents the projected query reads. */\nconst SCREEN_SCAN_LIMIT = 1000\n\n/* ---- The store, structurally ---------------------------------------------- */\n\nexport interface SeoScanSnapshot {\n readonly exists: boolean\n get(field: string): unknown\n}\n\nexport interface SeoScanQueryDocument {\n readonly id: string\n data(): unknown\n get(field: string): unknown\n readonly ref: SeoScanDocumentRef\n}\n\nexport interface SeoScanQuery {\n limit(count: number): SeoScanQuery\n get(): Promise<{ readonly docs: readonly SeoScanQueryDocument[] }>\n}\n\nexport interface SeoScanCollection {\n select(...fields: string[]): SeoScanQuery\n doc(id: string): SeoScanDocumentRef\n}\n\nexport interface SeoScanDocumentRef {\n collection(name: string): SeoScanCollection\n get(): Promise<SeoScanSnapshot>\n}\n\n/** What the scan reads through; the Admin SDK's `Firestore` is one. */\nexport interface SeoScanStore {\n collection(name: string): SeoScanCollection\n}\n\n/* ---- What it reads --------------------------------------------------------- */\n\n/** The host document fields the scan and the site findings read. */\nexport interface SeoSiteHost {\n displayName?: string\n screens?: Record<string, string>\n errorScreens?: Record<string, string>\n notFoundScreenId?: string | null\n seo?: {\n title?: string\n separator?: string\n discourageSearchEngines?: boolean\n entity?: { name?: string; description?: string }\n agent?: { whenToUse?: string }\n }\n}\n\n/** The screen document fields the scan reads. */\ninterface SeoScreenDocument {\n displayName?: string\n description?: string\n versionId?: string\n visibility?: unknown\n deletedAt?: unknown\n seo?: {\n title?: string\n description?: string\n breadcrumb?: string\n image?: string\n imageAlt?: string\n }\n}\n\nexport interface SeoScannedPage extends SeoAuditPage {\n /** The listing as the screen document stores it: a title's variables unresolved. */\n storedSeo: NonNullable<SeoScreenDocument['seo']>\n /** The page's node map as checked. */\n nodes: Record<string, unknown> | null\n}\n\nexport interface SeoSiteScan {\n pages: SeoScannedPage[]\n /** Published pages past {@link SEO_AUDIT_MAX_PAGES}. */\n skipped: number\n /** Customer-safe lines: a keyword line naming a page the site does not publish. */\n notes: string[]\n}\n\nconst str = (value: unknown): string => (typeof value === 'string' ? value.trim() : '')\n\n/** The site as the check reads it, from its host document. */\nexport function seoAuditSiteOf(host: SeoSiteHost): SeoAuditSite {\n return {\n discouraged: isSearchDiscouraged(host),\n entity: host.seo?.entity ?? {},\n agent: host.seo?.agent ?? {},\n }\n}\n\n/** A version's node map and root, or `null` when it cannot be read. */\nasync function readVersionNodes(\n parent: SeoScanDocumentRef,\n versionId: string,\n): Promise<{ nodes: Record<string, unknown>; rootId?: string } | null> {\n if (!versionId) return null\n const snapshot = await parent.collection('versions').doc(versionId).get()\n if (!snapshot.exists) return null\n const nodes = decodeStoredNodes<Record<string, unknown>>(snapshot.get('nodes'))\n if (!nodes) return null\n const rootId = snapshot.get('rootId')\n return { nodes, ...(typeof rootId === 'string' ? { rootId } : {}) }\n}\n\nasync function inChunks<T>(items: readonly T[], run: (item: T) => Promise<void>): Promise<void> {\n for (let start = 0; start < items.length; start += READ_CHUNK) {\n await Promise.all(items.slice(start, start + READ_CHUNK).map(run))\n }\n}\n\n/**\n * Read `hostId`'s published pages for the check.\n *\n * `keywords` are the target keyword lines a person typed (`/path: a, b`);\n * `templateScreenIds` are the screens a collection, the store or the host\n * renders other URLs through, which are not pages of their own.\n */\nexport async function scanSeoSite(\n store: SeoScanStore,\n hostId: string,\n host: SeoSiteHost,\n options: { keywords?: unknown; templateScreenIds?: Iterable<string> } = {},\n): Promise<SeoSiteScan> {\n const hostRef = store.collection('hosts').doc(hostId)\n const routing = host.screens ?? {}\n const [screenDocs, layoutDocs] = await Promise.all([\n hostRef\n .collection('screens')\n .select('visibility', 'seo', 'description', 'displayName', 'versionId', 'deletedAt')\n .limit(SCREEN_SCAN_LIMIT)\n .get(),\n hostRef.collection('layouts').select('versionId').limit(SEO_SCAN_LAYOUT_LIMIT).get(),\n ])\n const screens = new Map(screenDocs.docs.map((doc) => [doc.id, (doc.data() ?? {}) as SeoScreenDocument]))\n const excluded = new Set<string>([...statusPageScreenIds(host), ...(options.templateScreenIds ?? [])])\n const published = Object.entries(routing)\n .filter(([screenId]) => !excluded.has(screenId))\n .filter(([screenId]) => {\n const screen = screens.get(screenId)\n return Boolean(screen) && !screen?.deletedAt && isScreenIndexable(screen as SearchIndexingScreen)\n })\n .map(([screenId, route]) => ({ screenId, path: screenRoutePathToUrl(String(route)) }))\n .sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0))\n const checked = published.slice(0, SEO_AUDIT_MAX_PAGES)\n\n const versions = new Map<string, { nodes: Record<string, unknown>; rootId?: string } | null>()\n await inChunks(checked, async ({ screenId }) => {\n versions.set(\n screenId,\n await readVersionNodes(hostRef.collection('screens').doc(screenId), str(screens.get(screenId)?.versionId)),\n )\n })\n const layoutNodes: Record<string, unknown>[] = []\n await inChunks(\n layoutDocs.docs.filter((doc) => str(doc.get('versionId'))),\n async (doc) => {\n const version = await readVersionNodes(doc.ref, str(doc.get('versionId')))\n if (version) layoutNodes.push(version.nodes)\n },\n )\n\n const keywordsByPath = parseSeoKeywordLines(options.keywords)\n const checkedPaths = new Set(checked.map((page) => seoNormalizePath(page.path)))\n const notes = Object.keys(keywordsByPath)\n .filter((path) => !checkedPaths.has(path))\n .map((path) => `Keywords for ${path} were not used: no checked page is published at that address.`)\n\n const siteName = str(host.seo?.title) || str(host.displayName)\n const pages: SeoScannedPage[] = checked.map(({ screenId, path }) => {\n const screen = screens.get(screenId) ?? {}\n const version = versions.get(screenId) ?? null\n const storedSeo = screen.seo ?? {}\n const linkedFrom =\n layoutNodes.some((nodes) => nodesReferenceScreen(nodes, screenId)) ||\n checked.some(\n (other) =>\n other.screenId !== screenId &&\n nodesReferenceScreen(versions.get(other.screenId)?.nodes ?? null, screenId),\n )\n return {\n screenId,\n path,\n name: str(screen.displayName) || path,\n versionId: str(screen.versionId) || null,\n // Judged as the head renders it: `{{page.name}} – {{site.name}}` on two\n // pages is two different titles, and its length is the rendered one.\n seo: {\n ...storedSeo,\n title: resolveSeoTitleVariables(storedSeo.title, {\n 'page.name': str(screen.displayName),\n 'site.name': siteName,\n 'site.separator': str(host.seo?.separator),\n }),\n },\n storedSeo,\n description: str(screen.description),\n facts: seoPageFacts(version?.nodes as PageMarkdownNodes | undefined, { rootId: version?.rootId }),\n linkedFrom,\n keywords: keywordsByPath[seoNormalizePath(path)] ?? [],\n nodes: version?.nodes ?? null,\n }\n })\n return { pages, skipped: Math.max(0, published.length - checked.length), notes }\n}\n"],"names":["screenRoutePathToUrl","nodesReferenceScreen","isScreenIndexable","isSearchDiscouraged","statusPageScreenIds","SEO_AUDIT_MAX_PAGES","parseSeoKeywordLines","seoNormalizePath","seoPageFacts","resolveSeoTitleVariables","decodeStoredNodes","SEO_SCAN_LAYOUT_LIMIT","READ_CHUNK","SCREEN_SCAN_LIMIT","str","value","trim","seoAuditSiteOf","host","discouraged","entity","seo","agent","readVersionNodes","parent","versionId","snapshot","collection","doc","get","exists","nodes","rootId","inChunks","items","run","start","length","Promise","all","slice","map","scanSeoSite","store","hostId","options","hostRef","routing","screens","screenDocs","layoutDocs","select","limit","Map","docs","id","data","excluded","Set","templateScreenIds","published","Object","entries","filter","screenId","has","screen","Boolean","deletedAt","route","path","String","sort","a","b","checked","versions","set","layoutNodes","version","ref","push","keywordsByPath","keywords","checkedPaths","page","notes","keys","siteName","title","displayName","pages","storedSeo","linkedFrom","some","other","name","separator","description","facts","skipped","Math","max"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/seo-site-scan.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { screenRoutePathToUrl } from './screen-route'\nimport { nodesReferenceScreen } from './screen-link-value'\nimport {\n isScreenIndexable,\n isSearchDiscouraged,\n statusPageScreenIds,\n type SearchIndexingScreen,\n} from './search-indexing'\nimport {\n SEO_AUDIT_MAX_PAGES,\n readSeoKeywordLines,\n seoNormalizePath,\n type SeoAuditPage,\n type SeoAuditSite,\n} from './seo-audit'\nimport { SEO_MAX_KEYWORDS, seoQuotedKeywords } from './seo-keywords'\nimport { seoPageFacts } from './seo-page-facts'\nimport type { AglynNodeSchema } from '../foundation'\nimport { expandRepeatables, repeatKeys, type RepeatableDataset } from './expand-repeatables'\nimport {\n composeReferencedComponents,\n hostComponentReader,\n type ReadComponentDocument,\n type SkippedComponent,\n type StoredComponentDocument,\n} from './load-referenced-components'\nimport type { PageMarkdownNodes } from './page-markdown'\nimport { resolveSeoTitleVariables } from './seo-title-variables'\nimport { decodeStoredNodes } from './stored-nodes'\n\n/**\n * Read a site for the SEO check (`seo-audit.ts`) the way its sitemap lists\n * it: every screen the routing map publishes, less the template screens, the\n * status pages and every screen that is not public — through the same shared\n * predicates the tenant's `sitemap.xml` and `/llms.txt` apply, so the check\n * covers exactly the pages a crawler is handed. Then each page's published\n * version, and the shared layouts, for the links that decide which pages\n * nothing points to.\n *\n * It knows nothing about the Firestore SDK. A caller hands it a\n * {@link SeoScanStore} — the Admin SDK's `Firestore` satisfies it — and the\n * template screen ids, which the tenant runtime resolves; so this module stays\n * pure enough to import from anywhere, and a spec hands it a fake.\n *\n * Each page is checked as it publishes (AGL-3501): {@link composeSeoPages}\n * grafts the reusable components it places, with each placement's values,\n * and expands its repeats over their rows when the caller hands over the\n * repeat-rows reader — the composition the tenant runs before it renders.\n *\n * Reads: one projected query of the screens, one of the layouts, and one\n * version document per checked page and per layout — at most\n * {@link SEO_AUDIT_MAX_PAGES} + {@link SEO_SCAN_LAYOUT_LIMIT} + 2 — then one\n * document per distinct component those place, and one repeat-rows request\n * for every key they repeat over.\n */\n\n/** Shared layouts read for the links they carry. */\nexport const SEO_SCAN_LAYOUT_LIMIT = 20\n\n/** Version documents read at once. */\nconst READ_CHUNK = 10\n\n/** Screen documents the projected query reads. */\nconst SCREEN_SCAN_LIMIT = 1000\n\n/* ---- The store, structurally ---------------------------------------------- */\n\nexport interface SeoScanSnapshot {\n readonly exists: boolean\n get(field: string): unknown\n}\n\nexport interface SeoScanQueryDocument {\n readonly id: string\n data(): unknown\n get(field: string): unknown\n readonly ref: SeoScanDocumentRef\n}\n\nexport interface SeoScanQuery {\n limit(count: number): SeoScanQuery\n get(): Promise<{ readonly docs: readonly SeoScanQueryDocument[] }>\n}\n\nexport interface SeoScanCollection {\n select(...fields: string[]): SeoScanQuery\n doc(id: string): SeoScanDocumentRef\n}\n\nexport interface SeoScanDocumentRef {\n collection(name: string): SeoScanCollection\n get(): Promise<SeoScanSnapshot>\n}\n\n/** What the scan reads through; the Admin SDK's `Firestore` is one. */\nexport interface SeoScanStore {\n collection(name: string): SeoScanCollection\n}\n\n/* ---- What it reads --------------------------------------------------------- */\n\n/** The host document fields the scan and the site findings read. */\nexport interface SeoSiteHost {\n displayName?: string\n screens?: Record<string, string>\n errorScreens?: Record<string, string>\n notFoundScreenId?: string | null\n seo?: {\n title?: string\n separator?: string\n discourageSearchEngines?: boolean\n entity?: { name?: string; description?: string }\n agent?: { whenToUse?: string }\n }\n}\n\n/** The screen document fields the scan reads. */\ninterface SeoScreenDocument {\n displayName?: string\n description?: string\n versionId?: string\n visibility?: unknown\n deletedAt?: unknown\n seo?: {\n title?: string\n description?: string\n breadcrumb?: string\n image?: string\n imageAlt?: string\n }\n}\n\nexport interface SeoScannedPage extends SeoAuditPage {\n /** The listing as the screen document stores it: a title's variables unresolved. */\n storedSeo: NonNullable<SeoScreenDocument['seo']>\n /** The page's own node map, as its published version stores it — not composed. */\n nodes: Record<string, unknown> | null\n}\n\nexport interface SeoSiteScan {\n pages: SeoScannedPage[]\n /** Published pages past {@link SEO_AUDIT_MAX_PAGES}. */\n skipped: number\n /** Customer-safe lines: a keyword line naming a page the site does not publish. */\n notes: string[]\n}\n\nconst str = (value: unknown): string => (typeof value === 'string' ? value.trim() : '')\n\n/* ---- The page as it publishes --------------------------------------------- */\n\n/**\n * The rows a site's repeats render, by key — the repeat-rows contract\n * (`plugin-manager/repeat-rows`), which is server-only and so handed in\n * rather than imported here.\n */\nexport type SeoRepeatRowsReader = (keys: readonly string[]) => Promise<Record<string, RepeatableDataset>>\n\nexport interface SeoCompositionOptions {\n /** Without it a repeat is read once, as written, its `{{item.*}}` tokens left out of the facts. */\n readRepeatRows?: SeoRepeatRowsReader\n}\n\nexport interface SeoComposedPages {\n /** Each node map as it publishes, in the order given; `null` stays `null`. */\n composed: (Record<string, unknown> | null)[]\n /** The repeats' rows were asked for and could not be read, so each repeat was read once, as written. */\n rowsUnread: boolean\n}\n\n/** A component reader that reads each document once however many pages place it. */\nfunction onceEach(read: ReadComponentDocument): ReadComponentDocument {\n const reads = new Map<string, Promise<StoredComponentDocument | null | undefined>>()\n return (componentId) => {\n let pending = reads.get(componentId)\n if (!pending) {\n pending = read(componentId)\n reads.set(componentId, pending)\n }\n return pending\n }\n}\n\n/**\n * Node maps of `hostId` as they publish (AGL-3501): each reusable component\n * placed grafted from its published definition with the placement's values\n * (`load-referenced-components.ts`, the graft the tenant runs), then each\n * repeat expanded over its rows when `readRepeatRows` is given — one request\n * for every key the maps repeat over.\n *\n * A component that does not load leaves its placement as authored, as on the\n * page; rows that cannot be read leave each repeat once, as written, and say\n * so through `rowsUnread` rather than failing the check.\n */\nexport async function composeSeoPages(\n store: SeoScanStore,\n hostId: string,\n maps: readonly (Record<string, unknown> | null | undefined)[],\n options: SeoCompositionOptions = {},\n): Promise<SeoComposedPages> {\n const read = onceEach(hostComponentReader(store, hostId))\n const skipped = new Map<string, SkippedComponent>()\n const grafted = await Promise.all(\n maps.map((nodes) =>\n nodes\n ? composeReferencedComponents(nodes, read, {\n onSkipped: (list) => list.forEach((entry) => skipped.set(entry.id, entry)),\n })\n : null,\n ),\n )\n if (skipped.size) {\n console.warn(JSON.stringify({ tag: 'AGL-3501:seo-components-skipped', hostId, skipped: [...skipped.values()] }))\n }\n\n const keys = [...new Set(grafted.flatMap((nodes) => (nodes ? repeatKeys(nodes) : [])))].sort()\n if (!keys.length || !options.readRepeatRows) return { composed: grafted, rowsUnread: false }\n let rows: Record<string, RepeatableDataset>\n try {\n rows = await options.readRepeatRows(keys)\n } catch (error) {\n console.warn(JSON.stringify({ tag: 'AGL-3501:seo-repeat-rows-unread', hostId, error: String(error) }))\n return { composed: grafted, rowsUnread: true }\n }\n return {\n composed: grafted.map((nodes) =>\n nodes ? expandRepeatables(nodes as Record<string, AglynNodeSchema>, rows) : null,\n ),\n rowsUnread: false,\n }\n}\n\n/** The site as the check reads it, from its host document. */\nexport function seoAuditSiteOf(host: SeoSiteHost): SeoAuditSite {\n return {\n discouraged: isSearchDiscouraged(host),\n entity: host.seo?.entity ?? {},\n agent: host.seo?.agent ?? {},\n }\n}\n\n/** A version's node map and root, or `null` when it cannot be read. */\nasync function readVersionNodes(\n parent: SeoScanDocumentRef,\n versionId: string,\n): Promise<{ nodes: Record<string, unknown>; rootId?: string } | null> {\n if (!versionId) return null\n const snapshot = await parent.collection('versions').doc(versionId).get()\n if (!snapshot.exists) return null\n const nodes = decodeStoredNodes<Record<string, unknown>>(snapshot.get('nodes'))\n if (!nodes) return null\n const rootId = snapshot.get('rootId')\n return { nodes, ...(typeof rootId === 'string' ? { rootId } : {}) }\n}\n\nasync function inChunks<T>(items: readonly T[], run: (item: T) => Promise<void>): Promise<void> {\n for (let start = 0; start < items.length; start += READ_CHUNK) {\n await Promise.all(items.slice(start, start + READ_CHUNK).map(run))\n }\n}\n\n/**\n * Read `hostId`'s published pages for the check.\n *\n * `keywords` are the target keyword lines a person typed (`/path: a, b`);\n * `templateScreenIds` are the screens a collection, the store or the host\n * renders other URLs through, which are not pages of their own;\n * `readRepeatRows` reads the rows the pages repeat over\n * ({@link composeSeoPages}).\n */\nexport async function scanSeoSite(\n store: SeoScanStore,\n hostId: string,\n host: SeoSiteHost,\n options: { keywords?: unknown; templateScreenIds?: Iterable<string> } & SeoCompositionOptions = {},\n): Promise<SeoSiteScan> {\n const hostRef = store.collection('hosts').doc(hostId)\n const routing = host.screens ?? {}\n const [screenDocs, layoutDocs] = await Promise.all([\n hostRef\n .collection('screens')\n .select('visibility', 'seo', 'description', 'displayName', 'versionId', 'deletedAt')\n .limit(SCREEN_SCAN_LIMIT)\n .get(),\n hostRef.collection('layouts').select('versionId').limit(SEO_SCAN_LAYOUT_LIMIT).get(),\n ])\n const screens = new Map(screenDocs.docs.map((doc) => [doc.id, (doc.data() ?? {}) as SeoScreenDocument]))\n const excluded = new Set<string>([...statusPageScreenIds(host), ...(options.templateScreenIds ?? [])])\n const published = Object.entries(routing)\n .filter(([screenId]) => !excluded.has(screenId))\n .filter(([screenId]) => {\n const screen = screens.get(screenId)\n return Boolean(screen) && !screen?.deletedAt && isScreenIndexable(screen as SearchIndexingScreen)\n })\n .map(([screenId, route]) => ({ screenId, path: screenRoutePathToUrl(String(route)) }))\n .sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0))\n const checked = published.slice(0, SEO_AUDIT_MAX_PAGES)\n\n const versions = new Map<string, { nodes: Record<string, unknown>; rootId?: string } | null>()\n await inChunks(checked, async ({ screenId }) => {\n versions.set(\n screenId,\n await readVersionNodes(hostRef.collection('screens').doc(screenId), str(screens.get(screenId)?.versionId)),\n )\n })\n const storedLayouts: Record<string, unknown>[] = []\n await inChunks(\n layoutDocs.docs.filter((doc) => str(doc.get('versionId'))),\n async (doc) => {\n const version = await readVersionNodes(doc.ref, str(doc.get('versionId')))\n if (version) storedLayouts.push(version.nodes)\n },\n )\n\n // Checked as they publish: a heading, an image or a link a component\n // renders is the page's, and so is a row a repeat shows.\n const { composed, rowsUnread } = await composeSeoPages(\n store,\n hostId,\n [...checked.map(({ screenId }) => versions.get(screenId)?.nodes ?? null), ...storedLayouts],\n options,\n )\n const composedPages = new Map(checked.map(({ screenId }, index) => [screenId, composed[index]]))\n const layoutNodes = composed.slice(checked.length)\n\n const keywordLines = readSeoKeywordLines(options.keywords)\n const keywordsByPath = keywordLines.keywords\n const checkedPaths = new Set(checked.map((page) => seoNormalizePath(page.path)))\n const notes = [\n ...[...new Set([...Object.keys(keywordsByPath), ...Object.keys(keywordLines.unchecked)])]\n .filter((path) => !checkedPaths.has(path))\n .map((path) => `Keywords for ${path} were not used: no checked page is published at that address.`),\n ...Object.entries(keywordLines.unchecked)\n .filter(([path]) => checkedPaths.has(path))\n .map(\n ([path, unchecked]) =>\n `Only the first ${SEO_MAX_KEYWORDS} keywords for ${path} were checked, so ${seoQuotedKeywords(unchecked)} ${unchecked.length === 1 ? 'was' : 'were'} not.`,\n ),\n ...(rowsUnread\n ? ['Lists that repeat over your datasets were checked without their rows, which could not be read just now.']\n : []),\n ]\n\n const siteName = str(host.seo?.title) || str(host.displayName)\n const pages: SeoScannedPage[] = checked.map(({ screenId, path }) => {\n const screen = screens.get(screenId) ?? {}\n const version = versions.get(screenId) ?? null\n const storedSeo = screen.seo ?? {}\n const linkedFrom =\n layoutNodes.some((nodes) => nodesReferenceScreen(nodes, screenId)) ||\n checked.some(\n (other) =>\n other.screenId !== screenId && nodesReferenceScreen(composedPages.get(other.screenId) ?? null, screenId),\n )\n return {\n screenId,\n path,\n name: str(screen.displayName) || path,\n versionId: str(screen.versionId) || null,\n // Judged as the head renders it: `{{page.name}} – {{site.name}}` on two\n // pages is two different titles, and its length is the rendered one.\n seo: {\n ...storedSeo,\n title: resolveSeoTitleVariables(storedSeo.title, {\n 'page.name': str(screen.displayName),\n 'site.name': siteName,\n 'site.separator': str(host.seo?.separator),\n }),\n },\n storedSeo,\n description: str(screen.description),\n facts: seoPageFacts(composedPages.get(screenId) as PageMarkdownNodes | null | undefined, {\n rootId: version?.rootId,\n pageNodes: version?.nodes as PageMarkdownNodes | undefined,\n }),\n linkedFrom,\n keywords: keywordsByPath[seoNormalizePath(path)] ?? [],\n nodes: version?.nodes ?? null,\n }\n })\n return { pages, skipped: Math.max(0, published.length - checked.length), notes }\n}\n"],"names":["screenRoutePathToUrl","nodesReferenceScreen","isScreenIndexable","isSearchDiscouraged","statusPageScreenIds","SEO_AUDIT_MAX_PAGES","readSeoKeywordLines","seoNormalizePath","SEO_MAX_KEYWORDS","seoQuotedKeywords","seoPageFacts","expandRepeatables","repeatKeys","composeReferencedComponents","hostComponentReader","resolveSeoTitleVariables","decodeStoredNodes","SEO_SCAN_LAYOUT_LIMIT","READ_CHUNK","SCREEN_SCAN_LIMIT","str","value","trim","onceEach","read","reads","Map","componentId","pending","get","set","composeSeoPages","store","hostId","maps","options","skipped","grafted","Promise","all","map","nodes","onSkipped","list","forEach","entry","id","size","console","warn","JSON","stringify","tag","values","keys","Set","flatMap","sort","length","readRepeatRows","composed","rowsUnread","rows","error","String","seoAuditSiteOf","host","discouraged","entity","seo","agent","readVersionNodes","parent","versionId","snapshot","collection","doc","exists","rootId","inChunks","items","run","start","slice","scanSeoSite","hostRef","routing","screens","screenDocs","layoutDocs","select","limit","docs","data","excluded","templateScreenIds","published","Object","entries","filter","screenId","has","screen","Boolean","deletedAt","route","path","a","b","checked","versions","storedLayouts","version","ref","push","composedPages","index","layoutNodes","keywordLines","keywords","keywordsByPath","checkedPaths","page","notes","unchecked","siteName","title","displayName","pages","storedSeo","linkedFrom","some","other","name","separator","description","facts","pageNodes","Math","max"],"mappings":"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"}
|
|
@@ -45,6 +45,7 @@ export * from './link-references';
|
|
|
45
45
|
export * from './analytics-path-key';
|
|
46
46
|
export * from './contacts';
|
|
47
47
|
export * from './email-state';
|
|
48
|
+
export * from './picklists';
|
|
48
49
|
export * from './crm';
|
|
49
50
|
export * from './crm-email-templates';
|
|
50
51
|
export * from './person-erasure';
|
|
@@ -84,6 +85,7 @@ export * from './host-permissions';
|
|
|
84
85
|
export * from './password-policy';
|
|
85
86
|
export * from './idp-profile';
|
|
86
87
|
export * from './onboarding-deep-link';
|
|
88
|
+
export * from './upgrade-proposal';
|
|
87
89
|
export * from './utm-attribution';
|
|
88
90
|
export * from './container-membership';
|
|
89
91
|
export * from './deployment-shape';
|
|
@@ -92,7 +94,8 @@ export * from './docs-help';
|
|
|
92
94
|
export * from './platform-brand';
|
|
93
95
|
export * from './plan-entitlements';
|
|
94
96
|
export * from './bandwidth-cap';
|
|
95
|
-
export * from './
|
|
97
|
+
export * from './media-bandwidth';
|
|
98
|
+
export * from './utc-month';
|
|
96
99
|
export * from './forms';
|
|
97
100
|
export * from './form-contract';
|
|
98
101
|
export * from './visitor-record-ceiling';
|
|
@@ -112,7 +115,6 @@ export * from './org-override-reason';
|
|
|
112
115
|
export * from './host-tokens';
|
|
113
116
|
export * from './variables';
|
|
114
117
|
export * from './host-events';
|
|
115
|
-
export * from './datasets';
|
|
116
118
|
export * from './expand-repeatables';
|
|
117
119
|
export * from './org-roles';
|
|
118
120
|
export * from './markdown-lite';
|
|
@@ -135,7 +137,6 @@ export * from './api-plugins';
|
|
|
135
137
|
export * from './plugin-api-rate-limit';
|
|
136
138
|
export * from './plugin-api-cross-origin';
|
|
137
139
|
export * from './site-interactions';
|
|
138
|
-
export * from './actions';
|
|
139
140
|
export * from './element-animation';
|
|
140
141
|
export * from './attribution-guard';
|
|
141
142
|
export * from './node-interactions';
|
|
@@ -145,10 +146,10 @@ export * from './sanitize-svg';
|
|
|
145
146
|
export * from './media-folders';
|
|
146
147
|
export * from './media-metadata';
|
|
147
148
|
export * from './media-ref';
|
|
149
|
+
export * from './rendered-widths';
|
|
148
150
|
export * from './paid-media-source';
|
|
149
151
|
export * from './author-css';
|
|
150
152
|
export * from './author-html';
|
|
151
|
-
export * from './dataset-models';
|
|
152
153
|
export * from './csv';
|
|
153
154
|
export * from './csv-upload';
|
|
154
155
|
export * from './artifact-provenance';
|
|
@@ -65,6 +65,10 @@ export * from "./contacts.js";
|
|
|
65
65
|
// A lead's or a contact's email state (AGL-3245): the last verdict on its
|
|
66
66
|
// address, in words a person can act on, mirrored from the senders' lists.
|
|
67
67
|
export * from "./email-state.js";
|
|
68
|
+
// A field whose choices an admin keeps (AGL-3510): standard values built in,
|
|
69
|
+
// the organization's own beside them, and the judge every write asks. Pure,
|
|
70
|
+
// and named for no plugin — a plugin's registry of picklists sits on top.
|
|
71
|
+
export * from "./picklists.js";
|
|
68
72
|
// The records that sit beside a contact — companies, pipelines, deals, tasks,
|
|
69
73
|
// activities, field definitions (AGL-2595). Pure like `contacts`, and beside
|
|
70
74
|
// it because `ContactFacet` names its lifecycle stage and custom-value types;
|
|
@@ -165,6 +169,9 @@ export * from "./host-permissions.js";
|
|
|
165
169
|
export * from "./password-policy.js";
|
|
166
170
|
export * from "./idp-profile.js";
|
|
167
171
|
export * from "./onboarding-deep-link.js";
|
|
172
|
+
// The platform team's ask that a workspace buy a plan (AGL-3466), beside the
|
|
173
|
+
// plan intent its button carries into Billing.
|
|
174
|
+
export * from "./upgrade-proposal.js";
|
|
168
175
|
// Where an account came from (AGL-1731). Beside the plan intent because
|
|
169
176
|
// they are the same hop — the marketing CTA's query string — and both are
|
|
170
177
|
// remembered on `users/{uid}` across the verification wall.
|
|
@@ -189,7 +196,10 @@ export * from "./plan-entitlements.js";
|
|
|
189
196
|
// The free plan's bandwidth hard cap (AGL-1967/2070/2155). After
|
|
190
197
|
// `plan-entitlements`, which owns the predicate it keys off.
|
|
191
198
|
export * from "./bandwidth-cap.js";
|
|
192
|
-
|
|
199
|
+
// Video and file delivery as bandwidth (AGL-3474), in the band's own units.
|
|
200
|
+
export * from "./media-bandwidth.js";
|
|
201
|
+
// The month every monthly counter is keyed by, and the boundary it lifts on.
|
|
202
|
+
export * from "./utc-month.js";
|
|
193
203
|
export * from "./forms.js";
|
|
194
204
|
// What a form's DESIGN must still satisfy for its submissions to arrive.
|
|
195
205
|
// After `forms`, whose field walk it reads the drawn fields with.
|
|
@@ -236,7 +246,6 @@ export * from "./variables.js";
|
|
|
236
246
|
// What happened on a site that an automation can start on: the platform's
|
|
237
247
|
// own event and the ones plugins declare (AGL-3080).
|
|
238
248
|
export * from "./host-events.js";
|
|
239
|
-
export * from "./datasets.js";
|
|
240
249
|
export * from "./expand-repeatables.js";
|
|
241
250
|
export * from "./org-roles.js";
|
|
242
251
|
export * from "./markdown-lite.js";
|
|
@@ -264,9 +273,9 @@ export * from "./plugin-api-rate-limit.js";
|
|
|
264
273
|
// two gates exempt exactly the same machine surfaces.
|
|
265
274
|
export * from "./plugin-api-cross-origin.js";
|
|
266
275
|
// What a published page does when a visitor does something (AGL-3080): the
|
|
267
|
-
// platform's interaction vocabulary, which
|
|
276
|
+
// platform's interaction vocabulary, which the workflows plugin builds its
|
|
277
|
+
// automations on.
|
|
268
278
|
export * from "./site-interactions.js";
|
|
269
|
-
export * from "./actions.js";
|
|
270
279
|
export * from "./element-animation.js";
|
|
271
280
|
export * from "./attribution-guard.js";
|
|
272
281
|
export * from "./node-interactions.js";
|
|
@@ -276,12 +285,12 @@ export * from "./sanitize-svg.js";
|
|
|
276
285
|
export * from "./media-folders.js";
|
|
277
286
|
export * from "./media-metadata.js";
|
|
278
287
|
export * from "./media-ref.js";
|
|
288
|
+
export * from "./rendered-widths.js";
|
|
279
289
|
// After `media-ref`, whose reference grammar it reads stored URLs with.
|
|
280
290
|
export * from "./paid-media-source.js";
|
|
281
291
|
export * from "./author-css.js";
|
|
282
292
|
// The isomorphic HTML rule (AGL-1901), after the CSS one it depends on.
|
|
283
293
|
export * from "./author-html.js";
|
|
284
|
-
export * from "./dataset-models.js";
|
|
285
294
|
export * from "./csv.js";
|
|
286
295
|
export * from "./csv-upload.js";
|
|
287
296
|
export * from "./artifact-provenance.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/server.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2022 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 * Server-safe app-utils: every app-util EXCEPT the client-only React\n * contexts (see ./contexts). Nothing here calls `createContext` at module\n * scope, so this barrel — re-exported by `@aglyn/aglyn/server` — is safe to\n * import from tenant Server Components (AGL-405). The full `./index` barrel\n * re-adds the contexts for client consumers.\n */\nexport * from './binding-token-catalog'\nexport * from './binding-tokens'\nexport * from './breadcrumb-json-ld'\n// What a search listing holds and how long each field may be (AGL-2910):\n// the SEO editors and anything that proposes a value read one catalog.\nexport * from './seo-listing-fields'\n// `VideoObject` for the Video elements a page actually ships (AGL-2747).\n// Beside the other structured-data builders, and server-only like them: only\n// the route emits JSON-LD, and a crawler-facing block has no client caller.\nexport * from './video-object'\nexport * from './collection-delete'\nexport * from './collection-entries'\nexport * from './collection-kind'\nexport * from './collection-slug'\nexport * from './content-authors'\n// NOT re-exported: `./local-business` and `./site-entity-json-ld` (AGL-3383).\n// This barrel is the whole namespace a realm bundle is handed and part of the\n// runtime a published page loads (`check:tenant-wire-weight`); the site\n// entity's JSON-LD and the LocalBusiness allow-list are read only by the\n// tenant page's server render and the console's Setup → SEO card, which import\n// them by path (`@aglyn/aglyn/app-utils/...`).\nexport * from './content-query-fields'\nexport * from './content-schema-type'\nexport * from './content-author-profile'\nexport * from './url-slug'\nexport * from './child-contract'\nexport * from './child-contract-compose'\n// The one reading of `restrictChildren`/`restrictParent`, shared by the\n// besigner's drop check and the AI plugin's node-tree validator (AGL-2905).\nexport * from './lineal-order'\n// What a portable node tree must satisfy before it lands on a canvas that did\n// not author it (AGL-2939): a tree installed from another workspace and a tree\n// a model generated both pass through it.\nexport * from './node-definition-sanitizer'\nexport * from './console-routes'\n// What a stored screen-link value means, with no React attached — the\n// where-used scan reads these on the server (AGL-703).\nexport * from './screen-link-value'\n// Which entries a page's links name (AGL-3118). The tenant render reads\n// exactly those entry documents, so the walk runs on the server.\nexport * from './link-references'\nexport * from './analytics-path-key'\nexport * from './contacts'\n// A lead's or a contact's email state (AGL-3245): the last verdict on its\n// address, in words a person can act on, mirrored from the senders' lists.\nexport * from './email-state'\n// The records that sit beside a contact — companies, pipelines, deals, tasks,\n// activities, field definitions (AGL-2595). Pure like `contacts`, and beside\n// it because `ContactFacet` names its lifecycle stage and custom-value types;\n// the scope stamp every CRM creator writes lives here too.\nexport * from './crm'\n// Email templates, snippets and the merge-field resolver (AGL-2658): the\n// letter a rep keeps under a name, and the one grammar the send route and\n// the dialog fill it in by. Pure like `crm`, and beside it because a\n// template is scoped the way a task is.\nexport * from './crm-email-templates'\n// A person's privacy erasure from one workspace (AGL-2623): the request's\n// shape and id, the marker a record carries while it waits, and the lists\n// the dialog and the docs share. Pure like `crm`; the sweep is server-side.\nexport * from './person-erasure'\n// A task's reminder at its own time (AGL-2659): which reminder a save\n// leaves, whether one is owed, and the words the notification and the mail\n// say. Pure like `crm`, read by the hourly route and by every writer of the\n// field.\nexport * from './crm-task-reminders'\n// Reading a received email (AGL-2657): the address in a header, the thread\n// a subject belongs to, the reply above the quoted history — and the domain\n// the platform receives mail on. Pure; every surface that reads mail it was\n// sent reads it this way.\nexport * from './email-text'\nexport * from './inbound-mail-domain'\n// A member's own addresses in a workspace (AGL-2975): the ones they have\n// confirmed count as theirs wherever the roster is asked who wrote a\n// message. Pure; the store and the confirmation link are server-side.\nexport * from './member-email-aliases'\n// The next activity a record carries (AGL-2661): what `nextTaskAtMs` IS given\n// a record's open tasks, the view clause a list filters on, the report figure.\n// Pure like `crm`; the admin library's `recomputeCrmNextTaskAt` is the writer.\nexport * from './crm-next-activity'\n// The CSV cell grammar the exports write with (AGL-2621), and the target a\n// mapped column names for a custom field — named rather than starred, because\n// an importer built on this file exports the shared ceilings under its own\n// names.\nexport {\n csvCell,\n csvDocument,\n customImportTarget,\n customImportTargetKey,\n importNoMailServerSentence,\n} from './csv-import'\nexport type {\n ImportChunkResult,\n ImportDroppedValue,\n ImportSkippedRow,\n} from './csv-import'\n// What a VALUE under a custom contact field may be, and the coercion every\n// door applies to one (AGL-2601): a mapped form field, an API `custom` body,\n// and the carry-over that keeps a mapping across a publish. Pure like `crm`.\nexport * from './contact-custom-fields'\n// The consent JOIN (`docs/specs/email-overhaul.md` §3f). Pure, and it composes\n// `contacts` for the normalizer, so it sits directly beside it. No Node\n// builtin, which is what keeps it out of the `/server`-only group `person-key`\n// belongs to.\nexport * from './consent-groups'\nexport * from './marketing-consent'\n// A refusal kept after the record it was written on is deleted (AGL-3338),\n// read back through the same parser as the record's own.\nexport * from './retained-refusals'\n// The ENROLLMENT-time half of the same question, beside its reader for the\n// same reason: `marketing-consent` decides whether a recorded basis lets us\n// mail somebody, and this decides what basis putting them on a list may\n// record. Two enrollment surfaces import it — the Inbox assignment route and\n// the Emails console's audience card — and neither could import the other.\nexport * from './enrollment-basis'\n// Reading the FILE a merchant arrives with (`docs/specs/email-competitive-gaps.md`\n// G5/P4), directly after the policy it hands its addresses to: parsing and\n// mechanical screening only, so that an import asks the enrollment question\n// through the same module the one-address add path asks it through rather\n// than answering it a second way.\n// The dynamic-list rule (§3b/§3c), beside it for the same reasons: pure, and\n// it composes `contacts` for the segment vocabulary rather than restating it.\nexport * from './dynamic-list-rule'\n// The subscribable streams a recipient can leave one at a time\n// (`docs/specs/email-competitive-gaps.md` §1f). Pure, and read from all three\n// sides of the feature: the composer picks one, the send path signs it into\n// the unsubscribe link, and the unauthenticated preference page renders the\n// catalog. No Node builtin, so it stays out of the `/server`-only group.\nexport * from './subscription-topics'\nexport * from './compose-layout-nodes'\n// Layout properties applied through the chain (AGL-2893).\nexport * from './compose-layout-props'\n// A screen's per-page restyling of its layout's elements (AGL-3286).\nexport * from './layout-style-overrides'\nexport * from './document-landmark'\nexport * from './functions'\nexport * from './compose-reusable-components'\n// Where a reusable component is placed — pages or emails (AGL-3287).\nexport * from './reusable-component-kind'\nexport * from './compress'\nexport * from './merge-node-sx'\nexport * from './palette-sx'\nexport * from './scheme-sx'\n// An element pinned to one color scheme (AGL-3284).\nexport * from './element-color-scheme'\nexport * from './create-resource-uid'\nexport * from './decompress'\nexport * from './stored-nodes'\nexport * from './strip-undefined'\nexport * from './organizations'\nexport * from './org-permissions'\n// The AI verdict on either membership axis (AGL-2927). After both modules it\n// composes: the org catalog for org-wide members, the host role for site\n// collaborators.\nexport * from './host-permissions'\nexport * from './password-policy'\nexport * from './idp-profile'\nexport * from './onboarding-deep-link'\n// Where an account came from (AGL-1731). Beside the plan intent because\n// they are the same hop — the marketing CTA's query string — and both are\n// remembered on `users/{uid}` across the verification wall.\nexport * from './utm-attribution'\n// What a record is filed under: the edge between a container a plugin keeps\n// (a campaign) and the forms, screens and contacts it gathers. Beside the\n// attribution above because the two answer opposite questions: attribution\n// records where somebody CAME from, this records what a merchant DECLARED\n// belongs together.\nexport * from './container-membership'\nexport * from './deployment-shape'\n// Which browser origins may complete a signed direct-to-GCS upload (AGL-1452).\n// GCS matches the origin list EXACTLY, so every serving console name needs its\n// own entry — the rule nobody could be expected to remember at attach time.\nexport * from './upload-cors'\n// The docs-help subset the first-party plugin consoles read (AGL-2213) — the\n// console's own registry lives in apps/console/constants and a lib cannot\n// import an app.\nexport * from './docs-help'\nexport * from './platform-brand'\nexport * from './plan-entitlements'\n// The free plan's bandwidth hard cap (AGL-1967/2070/2155). After\n// `plan-entitlements`, which owns the predicate it keys off.\nexport * from './bandwidth-cap'\nexport * from './form-abuse-ceiling'\nexport * from './forms'\n// What a form's DESIGN must still satisfy for its submissions to arrive.\n// After `forms`, whose field walk it reads the drawn fields with.\nexport * from './form-contract'\nexport * from './visitor-record-ceiling'\nexport * from './health-report'\n// Did a webhook delivery actually DO anything (AGL-1954)? After\n// `health-report`, whose billing verdict consumes the counts this produces.\nexport * from './webhook-delivery'\nexport * from './support-tiers'\nexport * from './release-flags'\n// Who runs THIS deployment, and where its notices go (AGL-2016). Ordered\n// before the four surfaces that print it, all of which used to declare their\n// own `support@aglyn.com` literal.\nexport * from './operator-identity'\nexport * from './lockdown'\nexport * from './media-quarantine'\nexport * from './media-takedown-reach'\nexport * from './upload-inspection'\nexport * from './abuse-report'\n// The other three quarters of §512 (AGL-1983): the put-back procedure that\n// answers a notice, and the strike ledger that conditions the safe harbour.\nexport * from './dmca-counter-notice'\nexport * from './repeat-infringer'\n// `addBusinessDays` briefly existed TWICE — once here in './support-tiers'\n// and once in './dmca-counter-notice' — and two `export *` made the name\n// ambiguous, TS2308'ing this barrel and every tsconfig that reads it. The\n// interleave was fixed twice in parallel: once by naming a winner here, and\n// once by deleting the second definition so './dmca-counter-notice' imports\n// this one. Only the deletion survives, so the disambiguating re-export that\n// stood on this line is gone with it — `export *` is unambiguous again.\n//\n// The concern that argued for keeping two copies is worth answering rather\n// than dropping: a later tweak to the SUPPORT SLA window must never silently\n// move the §512(g)(2)(C) put-back deadline. It cannot. This function embeds\n// no window — it is \"add N business days\", and N is the argument. The two\n// windows live in their own constants (`SUPPORT_*` there,\n// `COUNTER_NOTICE_*_BUSINESS_DAYS` in the DMCA module) and never meet. What\n// SHOULD stay shared is the day arithmetic itself: two copies of a weekend\n// rule are two chances to disagree about which day a deadline falls on.\nexport * from './org-override-reason'\nexport * from './host-tokens'\nexport * from './variables'\n// What happened on a site that an automation can start on: the platform's\n// own event and the ones plugins declare (AGL-3080).\nexport * from './host-events'\nexport * from './datasets'\nexport * from './expand-repeatables'\nexport * from './org-roles'\nexport * from './markdown-lite'\nexport * from './notifications'\n// The operator alert registry (AGL-3377); OPERATOR_ALERT_NOTIFICATION_TYPES\n// lives here now, derived from it.\nexport * from './operator-alerts'\nexport * from './definition-canvas-tree'\nexport * from './ensure-canvas-root'\nexport * from './repair-canvas-nodes'\nexport * from './detect-template-placeholders'\nexport * from './guarded-version-save'\nexport * from './local-storage-budget'\nexport * from './measure-node-map'\nexport * from './resolve-named-tokens'\nexport * from './screen-route'\nexport * from './host-naming'\nexport * from './name-search'\nexport * from './artifact-list-keys'\nexport * from './name-match'\nexport * from './api-plugins'\nexport * from './plugin-api-rate-limit'\n// The same-origin gate on visitor-facing plugin writes (AGL-1880). After\n// `plugin-api-rate-limit`, whose `isMachinePluginApiPath` it reuses so the\n// two gates exempt exactly the same machine surfaces.\nexport * from './plugin-api-cross-origin'\n// What a published page does when a visitor does something (AGL-3080): the\n// platform's interaction vocabulary, which `./actions` builds its automations on.\nexport * from './site-interactions'\nexport * from './actions'\nexport * from './element-animation'\nexport * from './attribution-guard'\nexport * from './node-interactions'\nexport * from './element-ui'\nexport * from './image-upload-types'\nexport * from './sanitize-svg'\nexport * from './media-folders'\nexport * from './media-metadata'\nexport * from './media-ref'\n// After `media-ref`, whose reference grammar it reads stored URLs with.\nexport * from './paid-media-source'\nexport * from './author-css'\n// The isomorphic HTML rule (AGL-1901), after the CSS one it depends on.\nexport * from './author-html'\nexport * from './dataset-models'\nexport * from './csv'\nexport * from './csv-upload'\nexport * from './artifact-provenance'\nexport * from './repeat-query'\nexport * from './plugin-manifest'\n// After `plugin-manifest`, whose revocation predicates it asks the kill\n// question with, and after `media-ref`, whose grammar decides what counts as a\n// first-party image.\nexport * from './email-starter-policy'\nexport * from './safe-json-ld'\n// Agent readiness (AGL-2716): content negotiation, the Markdown rendering of a\n// page, `/llms.txt` and the per-site OpenAPI document. All pure, all server-safe.\nexport * from './accept-negotiation'\nexport * from './agent-api-catalog'\nexport * from './agent-openapi'\nexport * from './author-html-markdown'\nexport * from './llms-txt'\nexport * from './page-markdown'\nexport * from './request-geo'\nexport * from './request-ip'\nexport * from './search-indexing'\nexport * from './seo-title'\nexport * from './sitemap'\nexport * from './visitor-consent'\nexport * from './social-image'\nexport * from './scope-tokens'\nexport * from './org-billing-doc'\nexport * from './stripe-deployment-mode'\nexport * from './deferred-image'\n"],"names":["csvCell","csvDocument","customImportTarget","customImportTargetKey","importNoMailServerSentence"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/server.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2022 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 * Server-safe app-utils: every app-util EXCEPT the client-only React\n * contexts (see ./contexts). Nothing here calls `createContext` at module\n * scope, so this barrel — re-exported by `@aglyn/aglyn/server` — is safe to\n * import from tenant Server Components (AGL-405). The full `./index` barrel\n * re-adds the contexts for client consumers.\n */\nexport * from './binding-token-catalog'\nexport * from './binding-tokens'\nexport * from './breadcrumb-json-ld'\n// What a search listing holds and how long each field may be (AGL-2910):\n// the SEO editors and anything that proposes a value read one catalog.\nexport * from './seo-listing-fields'\n// `VideoObject` for the Video elements a page actually ships (AGL-2747).\n// Beside the other structured-data builders, and server-only like them: only\n// the route emits JSON-LD, and a crawler-facing block has no client caller.\nexport * from './video-object'\nexport * from './collection-delete'\nexport * from './collection-entries'\nexport * from './collection-kind'\nexport * from './collection-slug'\nexport * from './content-authors'\n// NOT re-exported: `./local-business` and `./site-entity-json-ld` (AGL-3383).\n// This barrel is the whole namespace a realm bundle is handed and part of the\n// runtime a published page loads (`check:tenant-wire-weight`); the site\n// entity's JSON-LD and the LocalBusiness allow-list are read only by the\n// tenant page's server render and the console's Setup → SEO card, which import\n// them by path (`@aglyn/aglyn/app-utils/...`).\nexport * from './content-query-fields'\nexport * from './content-schema-type'\nexport * from './content-author-profile'\nexport * from './url-slug'\nexport * from './child-contract'\nexport * from './child-contract-compose'\n// The one reading of `restrictChildren`/`restrictParent`, shared by the\n// besigner's drop check and the AI plugin's node-tree validator (AGL-2905).\nexport * from './lineal-order'\n// What a portable node tree must satisfy before it lands on a canvas that did\n// not author it (AGL-2939): a tree installed from another workspace and a tree\n// a model generated both pass through it.\nexport * from './node-definition-sanitizer'\nexport * from './console-routes'\n// What a stored screen-link value means, with no React attached — the\n// where-used scan reads these on the server (AGL-703).\nexport * from './screen-link-value'\n// Which entries a page's links name (AGL-3118). The tenant render reads\n// exactly those entry documents, so the walk runs on the server.\nexport * from './link-references'\nexport * from './analytics-path-key'\nexport * from './contacts'\n// A lead's or a contact's email state (AGL-3245): the last verdict on its\n// address, in words a person can act on, mirrored from the senders' lists.\nexport * from './email-state'\n// A field whose choices an admin keeps (AGL-3510): standard values built in,\n// the organization's own beside them, and the judge every write asks. Pure,\n// and named for no plugin — a plugin's registry of picklists sits on top.\nexport * from './picklists'\n// The records that sit beside a contact — companies, pipelines, deals, tasks,\n// activities, field definitions (AGL-2595). Pure like `contacts`, and beside\n// it because `ContactFacet` names its lifecycle stage and custom-value types;\n// the scope stamp every CRM creator writes lives here too.\nexport * from './crm'\n// Email templates, snippets and the merge-field resolver (AGL-2658): the\n// letter a rep keeps under a name, and the one grammar the send route and\n// the dialog fill it in by. Pure like `crm`, and beside it because a\n// template is scoped the way a task is.\nexport * from './crm-email-templates'\n// A person's privacy erasure from one workspace (AGL-2623): the request's\n// shape and id, the marker a record carries while it waits, and the lists\n// the dialog and the docs share. Pure like `crm`; the sweep is server-side.\nexport * from './person-erasure'\n// A task's reminder at its own time (AGL-2659): which reminder a save\n// leaves, whether one is owed, and the words the notification and the mail\n// say. Pure like `crm`, read by the hourly route and by every writer of the\n// field.\nexport * from './crm-task-reminders'\n// Reading a received email (AGL-2657): the address in a header, the thread\n// a subject belongs to, the reply above the quoted history — and the domain\n// the platform receives mail on. Pure; every surface that reads mail it was\n// sent reads it this way.\nexport * from './email-text'\nexport * from './inbound-mail-domain'\n// A member's own addresses in a workspace (AGL-2975): the ones they have\n// confirmed count as theirs wherever the roster is asked who wrote a\n// message. Pure; the store and the confirmation link are server-side.\nexport * from './member-email-aliases'\n// The next activity a record carries (AGL-2661): what `nextTaskAtMs` IS given\n// a record's open tasks, the view clause a list filters on, the report figure.\n// Pure like `crm`; the admin library's `recomputeCrmNextTaskAt` is the writer.\nexport * from './crm-next-activity'\n// The CSV cell grammar the exports write with (AGL-2621), and the target a\n// mapped column names for a custom field — named rather than starred, because\n// an importer built on this file exports the shared ceilings under its own\n// names.\nexport {\n csvCell,\n csvDocument,\n customImportTarget,\n customImportTargetKey,\n importNoMailServerSentence,\n} from './csv-import'\nexport type {\n ImportChunkResult,\n ImportDroppedValue,\n ImportSkippedRow,\n} from './csv-import'\n// What a VALUE under a custom contact field may be, and the coercion every\n// door applies to one (AGL-2601): a mapped form field, an API `custom` body,\n// and the carry-over that keeps a mapping across a publish. Pure like `crm`.\nexport * from './contact-custom-fields'\n// The consent JOIN (`docs/specs/email-overhaul.md` §3f). Pure, and it composes\n// `contacts` for the normalizer, so it sits directly beside it. No Node\n// builtin, which is what keeps it out of the `/server`-only group `person-key`\n// belongs to.\nexport * from './consent-groups'\nexport * from './marketing-consent'\n// A refusal kept after the record it was written on is deleted (AGL-3338),\n// read back through the same parser as the record's own.\nexport * from './retained-refusals'\n// The ENROLLMENT-time half of the same question, beside its reader for the\n// same reason: `marketing-consent` decides whether a recorded basis lets us\n// mail somebody, and this decides what basis putting them on a list may\n// record. Two enrollment surfaces import it — the Inbox assignment route and\n// the Emails console's audience card — and neither could import the other.\nexport * from './enrollment-basis'\n// Reading the FILE a merchant arrives with (`docs/specs/email-competitive-gaps.md`\n// G5/P4), directly after the policy it hands its addresses to: parsing and\n// mechanical screening only, so that an import asks the enrollment question\n// through the same module the one-address add path asks it through rather\n// than answering it a second way.\n// The dynamic-list rule (§3b/§3c), beside it for the same reasons: pure, and\n// it composes `contacts` for the segment vocabulary rather than restating it.\nexport * from './dynamic-list-rule'\n// The subscribable streams a recipient can leave one at a time\n// (`docs/specs/email-competitive-gaps.md` §1f). Pure, and read from all three\n// sides of the feature: the composer picks one, the send path signs it into\n// the unsubscribe link, and the unauthenticated preference page renders the\n// catalog. No Node builtin, so it stays out of the `/server`-only group.\nexport * from './subscription-topics'\nexport * from './compose-layout-nodes'\n// Layout properties applied through the chain (AGL-2893).\nexport * from './compose-layout-props'\n// A screen's per-page restyling of its layout's elements (AGL-3286).\nexport * from './layout-style-overrides'\nexport * from './document-landmark'\nexport * from './functions'\nexport * from './compose-reusable-components'\n// Where a reusable component is placed — pages or emails (AGL-3287).\nexport * from './reusable-component-kind'\nexport * from './compress'\nexport * from './merge-node-sx'\nexport * from './palette-sx'\nexport * from './scheme-sx'\n// An element pinned to one color scheme (AGL-3284).\nexport * from './element-color-scheme'\nexport * from './create-resource-uid'\nexport * from './decompress'\nexport * from './stored-nodes'\nexport * from './strip-undefined'\nexport * from './organizations'\nexport * from './org-permissions'\n// The AI verdict on either membership axis (AGL-2927). After both modules it\n// composes: the org catalog for org-wide members, the host role for site\n// collaborators.\nexport * from './host-permissions'\nexport * from './password-policy'\nexport * from './idp-profile'\nexport * from './onboarding-deep-link'\n// The platform team's ask that a workspace buy a plan (AGL-3466), beside the\n// plan intent its button carries into Billing.\nexport * from './upgrade-proposal'\n// Where an account came from (AGL-1731). Beside the plan intent because\n// they are the same hop — the marketing CTA's query string — and both are\n// remembered on `users/{uid}` across the verification wall.\nexport * from './utm-attribution'\n// What a record is filed under: the edge between a container a plugin keeps\n// (a campaign) and the forms, screens and contacts it gathers. Beside the\n// attribution above because the two answer opposite questions: attribution\n// records where somebody CAME from, this records what a merchant DECLARED\n// belongs together.\nexport * from './container-membership'\nexport * from './deployment-shape'\n// Which browser origins may complete a signed direct-to-GCS upload (AGL-1452).\n// GCS matches the origin list EXACTLY, so every serving console name needs its\n// own entry — the rule nobody could be expected to remember at attach time.\nexport * from './upload-cors'\n// The docs-help subset the first-party plugin consoles read (AGL-2213) — the\n// console's own registry lives in apps/console/constants and a lib cannot\n// import an app.\nexport * from './docs-help'\nexport * from './platform-brand'\nexport * from './plan-entitlements'\n// The free plan's bandwidth hard cap (AGL-1967/2070/2155). After\n// `plan-entitlements`, which owns the predicate it keys off.\nexport * from './bandwidth-cap'\n// Video and file delivery as bandwidth (AGL-3474), in the band's own units.\nexport * from './media-bandwidth'\n// The month every monthly counter is keyed by, and the boundary it lifts on.\nexport * from './utc-month'\nexport * from './forms'\n// What a form's DESIGN must still satisfy for its submissions to arrive.\n// After `forms`, whose field walk it reads the drawn fields with.\nexport * from './form-contract'\nexport * from './visitor-record-ceiling'\nexport * from './health-report'\n// Did a webhook delivery actually DO anything (AGL-1954)? After\n// `health-report`, whose billing verdict consumes the counts this produces.\nexport * from './webhook-delivery'\nexport * from './support-tiers'\nexport * from './release-flags'\n// Who runs THIS deployment, and where its notices go (AGL-2016). Ordered\n// before the four surfaces that print it, all of which used to declare their\n// own `support@aglyn.com` literal.\nexport * from './operator-identity'\nexport * from './lockdown'\nexport * from './media-quarantine'\nexport * from './media-takedown-reach'\nexport * from './upload-inspection'\nexport * from './abuse-report'\n// The other three quarters of §512 (AGL-1983): the put-back procedure that\n// answers a notice, and the strike ledger that conditions the safe harbour.\nexport * from './dmca-counter-notice'\nexport * from './repeat-infringer'\n// `addBusinessDays` briefly existed TWICE — once here in './support-tiers'\n// and once in './dmca-counter-notice' — and two `export *` made the name\n// ambiguous, TS2308'ing this barrel and every tsconfig that reads it. The\n// interleave was fixed twice in parallel: once by naming a winner here, and\n// once by deleting the second definition so './dmca-counter-notice' imports\n// this one. Only the deletion survives, so the disambiguating re-export that\n// stood on this line is gone with it — `export *` is unambiguous again.\n//\n// The concern that argued for keeping two copies is worth answering rather\n// than dropping: a later tweak to the SUPPORT SLA window must never silently\n// move the §512(g)(2)(C) put-back deadline. It cannot. This function embeds\n// no window — it is \"add N business days\", and N is the argument. The two\n// windows live in their own constants (`SUPPORT_*` there,\n// `COUNTER_NOTICE_*_BUSINESS_DAYS` in the DMCA module) and never meet. What\n// SHOULD stay shared is the day arithmetic itself: two copies of a weekend\n// rule are two chances to disagree about which day a deadline falls on.\nexport * from './org-override-reason'\nexport * from './host-tokens'\nexport * from './variables'\n// What happened on a site that an automation can start on: the platform's\n// own event and the ones plugins declare (AGL-3080).\nexport * from './host-events'\nexport * from './expand-repeatables'\nexport * from './org-roles'\nexport * from './markdown-lite'\nexport * from './notifications'\n// The operator alert registry (AGL-3377); OPERATOR_ALERT_NOTIFICATION_TYPES\n// lives here now, derived from it.\nexport * from './operator-alerts'\nexport * from './definition-canvas-tree'\nexport * from './ensure-canvas-root'\nexport * from './repair-canvas-nodes'\nexport * from './detect-template-placeholders'\nexport * from './guarded-version-save'\nexport * from './local-storage-budget'\nexport * from './measure-node-map'\nexport * from './resolve-named-tokens'\nexport * from './screen-route'\nexport * from './host-naming'\nexport * from './name-search'\nexport * from './artifact-list-keys'\nexport * from './name-match'\nexport * from './api-plugins'\nexport * from './plugin-api-rate-limit'\n// The same-origin gate on visitor-facing plugin writes (AGL-1880). After\n// `plugin-api-rate-limit`, whose `isMachinePluginApiPath` it reuses so the\n// two gates exempt exactly the same machine surfaces.\nexport * from './plugin-api-cross-origin'\n// What a published page does when a visitor does something (AGL-3080): the\n// platform's interaction vocabulary, which the workflows plugin builds its\n// automations on.\nexport * from './site-interactions'\nexport * from './element-animation'\nexport * from './attribution-guard'\nexport * from './node-interactions'\nexport * from './element-ui'\nexport * from './image-upload-types'\nexport * from './sanitize-svg'\nexport * from './media-folders'\nexport * from './media-metadata'\nexport * from './media-ref'\nexport * from './rendered-widths'\n// After `media-ref`, whose reference grammar it reads stored URLs with.\nexport * from './paid-media-source'\nexport * from './author-css'\n// The isomorphic HTML rule (AGL-1901), after the CSS one it depends on.\nexport * from './author-html'\nexport * from './csv'\nexport * from './csv-upload'\nexport * from './artifact-provenance'\nexport * from './repeat-query'\nexport * from './plugin-manifest'\n// After `plugin-manifest`, whose revocation predicates it asks the kill\n// question with, and after `media-ref`, whose grammar decides what counts as a\n// first-party image.\nexport * from './email-starter-policy'\nexport * from './safe-json-ld'\n// Agent readiness (AGL-2716): content negotiation, the Markdown rendering of a\n// page, `/llms.txt` and the per-site OpenAPI document. All pure, all server-safe.\nexport * from './accept-negotiation'\nexport * from './agent-api-catalog'\nexport * from './agent-openapi'\nexport * from './author-html-markdown'\nexport * from './llms-txt'\nexport * from './page-markdown'\nexport * from './request-geo'\nexport * from './request-ip'\nexport * from './search-indexing'\nexport * from './seo-title'\nexport * from './sitemap'\nexport * from './visitor-consent'\nexport * from './social-image'\nexport * from './scope-tokens'\nexport * from './org-billing-doc'\nexport * from './stripe-deployment-mode'\nexport * from './deferred-image'\n"],"names":["csvCell","csvDocument","customImportTarget","customImportTargetKey","importNoMailServerSentence"],"mappings":"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"}
|