@aglyn/aglyn 1.0.0-beta.233 → 1.0.0-beta.235
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 +11 -11
- package/src/lib/app-utils/activity-labels.d.ts +117 -0
- package/src/lib/app-utils/activity-labels.js +343 -0
- package/src/lib/app-utils/activity-labels.js.map +1 -0
- package/src/lib/app-utils/admin-audit-index.d.ts +11 -0
- package/src/lib/app-utils/admin-audit-index.js +12 -1
- package/src/lib/app-utils/admin-audit-index.js.map +1 -1
- package/src/lib/app-utils/advertising-consent.d.ts +111 -0
- package/src/lib/app-utils/advertising-consent.js +216 -0
- package/src/lib/app-utils/advertising-consent.js.map +1 -0
- package/src/lib/app-utils/advertising-events.d.ts +98 -0
- package/src/lib/app-utils/advertising-events.js +340 -0
- package/src/lib/app-utils/advertising-events.js.map +1 -0
- package/src/lib/app-utils/advertising-tag-mounts.js +15 -8
- package/src/lib/app-utils/advertising-tag-mounts.js.map +1 -1
- package/src/lib/app-utils/advertising-tags.d.ts +54 -8
- package/src/lib/app-utils/advertising-tags.js +126 -28
- package/src/lib/app-utils/advertising-tags.js.map +1 -1
- package/src/lib/app-utils/analytics-events.d.ts +15 -86
- package/src/lib/app-utils/analytics-events.js +21 -6
- package/src/lib/app-utils/analytics-events.js.map +1 -1
- package/src/lib/app-utils/consent-banner-ui.d.ts +14 -0
- package/src/lib/app-utils/consent-banner-ui.js +23 -2
- package/src/lib/app-utils/consent-banner-ui.js.map +1 -1
- package/src/lib/app-utils/docs-help-section-excerpt-text.d.ts +14 -0
- package/src/lib/app-utils/docs-help-section-excerpt-text.js +31 -0
- package/src/lib/app-utils/docs-help-section-excerpt-text.js.map +1 -0
- package/src/lib/app-utils/docs-help-section-excerpt.d.ts +13 -0
- package/src/lib/app-utils/docs-help-section-excerpt.js +37 -0
- package/src/lib/app-utils/docs-help-section-excerpt.js.map +1 -0
- package/src/lib/app-utils/docs-help-sections.generated.d.ts +31 -0
- package/src/lib/app-utils/docs-help-sections.generated.js +660 -0
- package/src/lib/app-utils/docs-help-sections.generated.js.map +1 -0
- package/src/lib/app-utils/docs-help.d.ts +16 -4
- package/src/lib/app-utils/docs-help.generated.d.ts +171 -34
- package/src/lib/app-utils/docs-help.generated.js +1104 -3
- package/src/lib/app-utils/docs-help.generated.js.map +1 -1
- package/src/lib/app-utils/docs-help.js +25 -6
- package/src/lib/app-utils/docs-help.js.map +1 -1
- package/src/lib/app-utils/docs-index.generated.js +1008 -91
- package/src/lib/app-utils/docs-index.generated.js.map +1 -1
- package/src/lib/app-utils/health-report.js +12 -0
- package/src/lib/app-utils/health-report.js.map +1 -1
- package/src/lib/app-utils/plugin-release-flags.generated.d.ts +1 -1
- package/src/lib/app-utils/plugin-release-flags.generated.js +7 -1
- package/src/lib/app-utils/plugin-release-flags.generated.js.map +1 -1
- package/src/lib/app-utils/realm-host-surface.generated.js +1 -0
- package/src/lib/app-utils/realm-host-surface.generated.js.map +1 -1
- package/src/lib/app-utils/variables.d.ts +2 -0
- package/src/lib/app-utils/variables.js +3 -0
- package/src/lib/app-utils/variables.js.map +1 -1
- package/src/lib/app-utils/visitor-consent.d.ts +34 -0
- package/src/lib/app-utils/visitor-consent.js +49 -2
- package/src/lib/app-utils/visitor-consent.js.map +1 -1
- package/src/lib/app-utils/where-used-summary.d.ts +41 -0
- package/src/lib/app-utils/where-used-summary.js +33 -0
- package/src/lib/app-utils/where-used-summary.js.map +1 -0
- package/src/lib/app-utils/where-used.d.ts +2 -20
- package/src/lib/app-utils/where-used.js +13 -12
- package/src/lib/app-utils/where-used.js.map +1 -1
- package/src/lib/foundation/definitions/platform.types.d.ts +33 -0
- package/src/lib/foundation/definitions/platform.types.js.map +1 -1
- package/src/lib/plugin-manager/first-party-plugins.generated.d.ts +7 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.js +166 -2
- package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -1
- package/src/lib/plugin-manager/plugin-activity-actions.d.ts +51 -0
- package/src/lib/plugin-manager/plugin-activity-actions.js +43 -0
- package/src/lib/plugin-manager/plugin-activity-actions.js.map +1 -1
- package/src/lib/plugin-manager/plugin-advertising-conversions.d.ts +84 -0
- package/src/lib/plugin-manager/plugin-advertising-conversions.js +86 -0
- package/src/lib/plugin-manager/plugin-advertising-conversions.js.map +1 -0
- package/src/lib/plugin-manager/plugin-config.d.ts +23 -0
- package/src/lib/plugin-manager/plugin-config.js.map +1 -1
- package/src/lib/plugin-manager/plugin-local-deliveries.d.ts +161 -0
- package/src/lib/plugin-manager/plugin-local-deliveries.js +46 -0
- package/src/lib/plugin-manager/plugin-local-deliveries.js.map +1 -0
- package/src/lib/plugin-manager/plugin-media-ingest.d.ts +87 -0
- package/src/lib/plugin-manager/plugin-media-ingest.js +34 -0
- package/src/lib/plugin-manager/plugin-media-ingest.js.map +1 -0
- package/src/lib/plugin-manager/plugin-order-email-copies.d.ts +93 -0
- package/src/lib/plugin-manager/plugin-order-email-copies.js +104 -0
- package/src/lib/plugin-manager/plugin-order-email-copies.js.map +1 -0
- package/src/lib/plugin-manager/plugin-shipment-records.d.ts +7 -0
- package/src/lib/plugin-manager/plugin-shipment-records.js.map +1 -1
- package/src/lib/plugin-manager/plugin-site-csp.d.ts +58 -0
- package/src/lib/plugin-manager/plugin-site-csp.js +103 -0
- package/src/lib/plugin-manager/plugin-site-csp.js.map +1 -0
- package/src/lib/plugin-manager/realm-host-aglyn.generated.js +1 -0
- package/src/lib/plugin-manager/realm-host-aglyn.generated.js.map +1 -1
- package/src/lib/plugin-manager/site-page-hooks.d.ts +13 -0
- package/src/lib/plugin-manager/site-page-hooks.js +31 -0
- package/src/lib/plugin-manager/site-page-hooks.js.map +1 -1
- package/src/lib/plugin-manager/stock-photo-provider.d.ts +141 -0
- package/src/lib/plugin-manager/stock-photo-provider.js +59 -0
- package/src/lib/plugin-manager/stock-photo-provider.js.map +1 -0
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { PluginReleaseFlagDefinition } from './release-flags';
|
|
10
10
|
/** Every release flag a plugin declares. */
|
|
11
|
-
export type PluginReleaseFlagKey = 'release_member_accounts' | 'release_bookings' | 'release_commerce_v2' | 'release_marketplace' | 'release_crm' | 'release_outreach' | 'release_data_store' | 'release_email' | 'release_events' | 'release_inbox' | 'release_logic' | 'release_marketing' | 'release_redirects' | 'release_workflows' | 'release_accounting';
|
|
11
|
+
export type PluginReleaseFlagKey = 'release_member_accounts' | 'release_bookings' | 'release_commerce_v2' | 'release_marketplace' | 'release_crm' | 'release_outreach' | 'release_data_store' | 'release_email' | 'release_events' | 'release_inbox' | 'release_logic' | 'release_marketing' | 'release_redirects' | 'release_workflows' | 'release_accounting' | 'release_weglot';
|
|
12
12
|
export declare const PLUGIN_RELEASE_FLAGS: readonly PluginReleaseFlagDefinition[];
|
|
@@ -104,9 +104,15 @@
|
|
|
104
104
|
{
|
|
105
105
|
"key": "release_accounting",
|
|
106
106
|
"label": "Accounting",
|
|
107
|
-
"description": "QuickBooks Online and Xero sync for commerce: sales receipts or a daily summary journal, refunds, platform fees and Stripe payouts, with a mapping page and a sync log (AGL-3614). OFF by default; needs the deployment's Intuit or Xero app credentials and the accounting token key on the console.",
|
|
107
|
+
"description": "QuickBooks Online and Xero sync for commerce, and through Codat QuickBooks Desktop, NetSuite, Sage, FreshBooks, Zoho Books and Wave: sales receipts or a daily summary journal, refunds, platform fees and Stripe payouts, with a mapping page and a sync log (AGL-3614, AGL-3636). OFF by default; needs the deployment's Intuit or Xero app credentials or Codat API key, and the accounting token key, on the console.",
|
|
108
108
|
"defaultEnabled": false,
|
|
109
109
|
"navTabId": "nav-tab-org-accounting"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"key": "release_weglot",
|
|
113
|
+
"label": "Weglot translation",
|
|
114
|
+
"description": "Weglot's JavaScript translation on published sites, with the merchant's own Weglot key (AGL-3700). Platform-wide kill switch; each site still switches it on itself.",
|
|
115
|
+
"defaultEnabled": true
|
|
110
116
|
}
|
|
111
117
|
];
|
|
112
118
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/plugin-release-flags.generated.ts"],"sourcesContent":["/**\n * GENERATED FILE — do not edit. Regenerate with:\n * node tools/scripts/generate-plugin-manifests.mjs\n *\n * The release flags plugins declare (AGL-3080): each catalog row's\n * `releaseFlagDefinition` in plugins.config.json, in catalog order. Core's\n * `release-flags.ts` folds them into `RELEASE_FLAGS`.\n */\n\nimport type { PluginReleaseFlagDefinition } from './release-flags'\n\n/** Every release flag a plugin declares. */\nexport type PluginReleaseFlagKey =\n | 'release_member_accounts'\n | 'release_bookings'\n | 'release_commerce_v2'\n | 'release_marketplace'\n | 'release_crm'\n | 'release_outreach'\n | 'release_data_store'\n | 'release_email'\n | 'release_events'\n | 'release_inbox'\n | 'release_logic'\n | 'release_marketing'\n | 'release_redirects'\n | 'release_workflows'\n | 'release_accounting'\n\nexport const PLUGIN_RELEASE_FLAGS: readonly PluginReleaseFlagDefinition[] = [\n {\n \"key\": \"release_member_accounts\",\n \"label\": \"User Accounts\",\n \"description\": \"Visitor accounts on published sites: the /signin, /signup and /recover pages and the Members blocks (AGL-2486). Platform-wide kill switch only — whether a given SITE serves those pages is the per-site User Accounts toggle, which is off until a site opts in.\",\n \"defaultEnabled\": true\n },\n {\n \"key\": \"release_bookings\",\n \"label\": \"Bookings\",\n \"description\": \"Bookings & scheduling for host sites.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-bookings\"\n },\n {\n \"key\": \"release_commerce_v2\",\n \"label\": \"Commerce v2\",\n \"description\": \"Full ecommerce wave: catalog/variants, cart + checkout, digital goods, reservations, POS, and the repriced commerce tiers (AGL-276..331).\",\n \"defaultEnabled\": true\n },\n {\n \"key\": \"release_marketplace\",\n \"label\": \"Marketplace\",\n \"description\": \"Marketplace browsing, publishing and plugin installs.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-org-marketplace\"\n },\n {\n \"key\": \"release_crm\",\n \"label\": \"CRM\",\n \"description\": \"The CRM: contacts, leads, companies, deals, tasks, reports and fields.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-contacts\"\n },\n {\n \"key\": \"release_outreach\",\n \"label\": \"Sequences\",\n \"description\": \"One-to-one, multi-step email sequences sent from a rep’s own connected mailbox and logged in the CRM (AGL-2974). OFF by default and staff preview only. An organization also needs the `outreach` entitlement, which no plan carries, so a customer reaches it only through a per-org entitlement override.\",\n \"defaultEnabled\": false,\n \"navTabId\": \"nav-tab-org-outreach\"\n },\n {\n \"key\": \"release_data_store\",\n \"label\": \"Data store\",\n \"description\": \"Datasets, models and dynamic data bindings.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-data\"\n },\n {\n \"key\": \"release_email\",\n \"label\": \"Email\",\n \"description\": \"Designed emails, campaigns, and audience sending.\",\n \"defaultEnabled\": true\n },\n {\n \"key\": \"release_events\",\n \"label\": \"Events\",\n \"description\": \"Event calendar management (AGL-145 add-on surface).\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-events\"\n },\n {\n \"key\": \"release_inbox\",\n \"label\": \"Inbox\",\n \"description\": \"Form submissions, site members, and the lead inbox.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-inbox\"\n },\n {\n \"key\": \"release_logic\",\n \"label\": \"Logic\",\n \"description\": \"Variables, no-code functions, and reference health.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-logic\"\n },\n {\n \"key\": \"release_marketing\",\n \"label\": \"Marketing\",\n \"description\": \"Overlays, campaigns at-a-glance, and A/B experiments.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-marketing\"\n },\n {\n \"key\": \"release_redirects\",\n \"label\": \"Redirects\",\n \"description\": \"Redirect manager with usage analytics.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-redirects\"\n },\n {\n \"key\": \"release_workflows\",\n \"label\": \"Automation\",\n \"description\": \"Workflows, actions, webhooks and their run history.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-workflows\"\n },\n {\n \"key\": \"release_accounting\",\n \"label\": \"Accounting\",\n \"description\": \"QuickBooks Online and Xero sync for commerce: sales receipts or a daily summary journal, refunds, platform fees and Stripe payouts, with a mapping page and a sync log (AGL-3614). OFF by default; needs the deployment's Intuit or Xero app credentials and the accounting token key on the console.\",\n \"defaultEnabled\": false,\n \"navTabId\": \"nav-tab-org-accounting\"\n }\n]\n"],"names":["PLUGIN_RELEASE_FLAGS"],"mappings":"AAAA;;;;;;;CAOC,
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/plugin-release-flags.generated.ts"],"sourcesContent":["/**\n * GENERATED FILE — do not edit. Regenerate with:\n * node tools/scripts/generate-plugin-manifests.mjs\n *\n * The release flags plugins declare (AGL-3080): each catalog row's\n * `releaseFlagDefinition` in plugins.config.json, in catalog order. Core's\n * `release-flags.ts` folds them into `RELEASE_FLAGS`.\n */\n\nimport type { PluginReleaseFlagDefinition } from './release-flags'\n\n/** Every release flag a plugin declares. */\nexport type PluginReleaseFlagKey =\n | 'release_member_accounts'\n | 'release_bookings'\n | 'release_commerce_v2'\n | 'release_marketplace'\n | 'release_crm'\n | 'release_outreach'\n | 'release_data_store'\n | 'release_email'\n | 'release_events'\n | 'release_inbox'\n | 'release_logic'\n | 'release_marketing'\n | 'release_redirects'\n | 'release_workflows'\n | 'release_accounting'\n | 'release_weglot'\n\nexport const PLUGIN_RELEASE_FLAGS: readonly PluginReleaseFlagDefinition[] = [\n {\n \"key\": \"release_member_accounts\",\n \"label\": \"User Accounts\",\n \"description\": \"Visitor accounts on published sites: the /signin, /signup and /recover pages and the Members blocks (AGL-2486). Platform-wide kill switch only — whether a given SITE serves those pages is the per-site User Accounts toggle, which is off until a site opts in.\",\n \"defaultEnabled\": true\n },\n {\n \"key\": \"release_bookings\",\n \"label\": \"Bookings\",\n \"description\": \"Bookings & scheduling for host sites.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-bookings\"\n },\n {\n \"key\": \"release_commerce_v2\",\n \"label\": \"Commerce v2\",\n \"description\": \"Full ecommerce wave: catalog/variants, cart + checkout, digital goods, reservations, POS, and the repriced commerce tiers (AGL-276..331).\",\n \"defaultEnabled\": true\n },\n {\n \"key\": \"release_marketplace\",\n \"label\": \"Marketplace\",\n \"description\": \"Marketplace browsing, publishing and plugin installs.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-org-marketplace\"\n },\n {\n \"key\": \"release_crm\",\n \"label\": \"CRM\",\n \"description\": \"The CRM: contacts, leads, companies, deals, tasks, reports and fields.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-contacts\"\n },\n {\n \"key\": \"release_outreach\",\n \"label\": \"Sequences\",\n \"description\": \"One-to-one, multi-step email sequences sent from a rep’s own connected mailbox and logged in the CRM (AGL-2974). OFF by default and staff preview only. An organization also needs the `outreach` entitlement, which no plan carries, so a customer reaches it only through a per-org entitlement override.\",\n \"defaultEnabled\": false,\n \"navTabId\": \"nav-tab-org-outreach\"\n },\n {\n \"key\": \"release_data_store\",\n \"label\": \"Data store\",\n \"description\": \"Datasets, models and dynamic data bindings.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-data\"\n },\n {\n \"key\": \"release_email\",\n \"label\": \"Email\",\n \"description\": \"Designed emails, campaigns, and audience sending.\",\n \"defaultEnabled\": true\n },\n {\n \"key\": \"release_events\",\n \"label\": \"Events\",\n \"description\": \"Event calendar management (AGL-145 add-on surface).\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-events\"\n },\n {\n \"key\": \"release_inbox\",\n \"label\": \"Inbox\",\n \"description\": \"Form submissions, site members, and the lead inbox.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-inbox\"\n },\n {\n \"key\": \"release_logic\",\n \"label\": \"Logic\",\n \"description\": \"Variables, no-code functions, and reference health.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-logic\"\n },\n {\n \"key\": \"release_marketing\",\n \"label\": \"Marketing\",\n \"description\": \"Overlays, campaigns at-a-glance, and A/B experiments.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-marketing\"\n },\n {\n \"key\": \"release_redirects\",\n \"label\": \"Redirects\",\n \"description\": \"Redirect manager with usage analytics.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-redirects\"\n },\n {\n \"key\": \"release_workflows\",\n \"label\": \"Automation\",\n \"description\": \"Workflows, actions, webhooks and their run history.\",\n \"defaultEnabled\": true,\n \"navTabId\": \"nav-tab-workflows\"\n },\n {\n \"key\": \"release_accounting\",\n \"label\": \"Accounting\",\n \"description\": \"QuickBooks Online and Xero sync for commerce, and through Codat QuickBooks Desktop, NetSuite, Sage, FreshBooks, Zoho Books and Wave: sales receipts or a daily summary journal, refunds, platform fees and Stripe payouts, with a mapping page and a sync log (AGL-3614, AGL-3636). OFF by default; needs the deployment's Intuit or Xero app credentials or Codat API key, and the accounting token key, on the console.\",\n \"defaultEnabled\": false,\n \"navTabId\": \"nav-tab-org-accounting\"\n },\n {\n \"key\": \"release_weglot\",\n \"label\": \"Weglot translation\",\n \"description\": \"Weglot's JavaScript translation on published sites, with the merchant's own Weglot key (AGL-3700). Platform-wide kill switch; each site still switches it on itself.\",\n \"defaultEnabled\": true\n }\n]\n"],"names":["PLUGIN_RELEASE_FLAGS"],"mappings":"AAAA;;;;;;;CAOC,GAuBD,OAAO,MAAMA,uBAA+D;IAC1E;QACE,OAAO;QACP,SAAS;QACT,eAAe;QACf,kBAAkB;IACpB;IACA;QACE,OAAO;QACP,SAAS;QACT,eAAe;QACf,kBAAkB;QAClB,YAAY;IACd;IACA;QACE,OAAO;QACP,SAAS;QACT,eAAe;QACf,kBAAkB;IACpB;IACA;QACE,OAAO;QACP,SAAS;QACT,eAAe;QACf,kBAAkB;QAClB,YAAY;IACd;IACA;QACE,OAAO;QACP,SAAS;QACT,eAAe;QACf,kBAAkB;QAClB,YAAY;IACd;IACA;QACE,OAAO;QACP,SAAS;QACT,eAAe;QACf,kBAAkB;QAClB,YAAY;IACd;IACA;QACE,OAAO;QACP,SAAS;QACT,eAAe;QACf,kBAAkB;QAClB,YAAY;IACd;IACA;QACE,OAAO;QACP,SAAS;QACT,eAAe;QACf,kBAAkB;IACpB;IACA;QACE,OAAO;QACP,SAAS;QACT,eAAe;QACf,kBAAkB;QAClB,YAAY;IACd;IACA;QACE,OAAO;QACP,SAAS;QACT,eAAe;QACf,kBAAkB;QAClB,YAAY;IACd;IACA;QACE,OAAO;QACP,SAAS;QACT,eAAe;QACf,kBAAkB;QAClB,YAAY;IACd;IACA;QACE,OAAO;QACP,SAAS;QACT,eAAe;QACf,kBAAkB;QAClB,YAAY;IACd;IACA;QACE,OAAO;QACP,SAAS;QACT,eAAe;QACf,kBAAkB;QAClB,YAAY;IACd;IACA;QACE,OAAO;QACP,SAAS;QACT,eAAe;QACf,kBAAkB;QAClB,YAAY;IACd;IACA;QACE,OAAO;QACP,SAAS;QACT,eAAe;QACf,kBAAkB;QAClB,YAAY;IACd;IACA;QACE,OAAO;QACP,SAAS;QACT,eAAe;QACf,kBAAkB;IACpB;CACD,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/realm-host-surface.generated.ts"],"sourcesContent":["/**\n * GENERATED FILE — do not edit. Regenerate with:\n * node tools/scripts/generate-realm-host-exports.mjs\n *\n * The names each realm host module holds (AGL-3392), for the bundle\n * verifier: a bundle reading any other name from the host is refused,\n * because it would read `undefined` on every site.\n */\n/* eslint-disable */\n\nexport const REALM_HOST_SURFACE_NAMES: Readonly<\n Record<'aglyn' | 'mui' | 'muiStyles', ReadonlySet<string>>\n> = {\n aglyn: new Set([\"Aglyn\",\"CATEGORY_REQUIRED_CAPABILITY\",\"COMPONENT_CATEGORY_ORDER\",\"CONSOLE_HOST_GATED_WIDGET_SLOTS\",\"CONSOLE_SEARCH_LOAD_POINT\",\"CONSOLE_STAFF_WIDGET_SLOTS\",\"CONSOLE_WIDGET_SLOTS\",\"ComponentCategory\",\"EnabledPluginsContext\",\"FEATURE_FLAG\",\"FUNCTION_BUILTIN_NAMES\",\"FUNCTION_MAX_OPERATIONS\",\"FUNCTION_TOKEN_PATTERN\",\"FieldComponentType\",\"FieldValidatorType\",\"HOST_VARIABLE_TYPE_LABELS\",\"LinealDirectiveFlag\",\"MISSING_BINDING_LABEL\",\"MUI_BUNDLE_ID\",\"NAME_TOKEN_PATTERN\",\"NodeIdentityContext\",\"NodeType\",\"PREVIEW_REFUSED_STATUS\",\"PREVIEW_WRITE_BLOCKED_EVENT\",\"REUSABLE_COMPONENT_CATEGORY\",\"REUSABLE_EMAIL_BLOCK_CATEGORY\",\"RICH_TEXT_COMMANDS\",\"ScreenLinkContext\",\"SiteContext\",\"THEME_PRESETS_LOAD_POINT\",\"VARIABLE_ID_TOKEN_PATTERN\",\"VARIABLE_NAME_PATTERN\",\"aglyn\",\"attachFunctionDefinitions\",\"bindingTokenNeedsDeep\",\"canvas\",\"components\",\"defineUiFeatureBundle\",\"displayBindingTokens\",\"editableBindingTokens\",\"emitter\",\"evaluateExpression\",\"evaluateHostFunction\",\"expressionIdentifiers\",\"expressionSyntaxError\",\"formatFunctionIdToken\",\"formatFunctionParameterOptions\",\"formatVariableIdToken\",\"formatVariableValue\",\"functionGlobals\",\"functionReferencedNames\",\"hasBindings\",\"isCategoryCapabilityEnabled\",\"isConsoleHostGatedWidgetSlot\",\"isConsoleStaffWidgetSlot\",\"isFromEnabledPlugin\",\"isPreviewRefusal\",\"isSwitchedOffForRenderedSite\",\"keyById\",\"listConsoleExtensions\",\"listConsoleNavItems\",\"listConsoleOrgNavItems\",\"listConsoleProviders\",\"listConsolePublicPages\",\"listConsoleSearchSources\",\"listConsoleStaffPages\",\"listConsoleThemePresets\",\"listConsoleWidgets\",\"logger\",\"nodesReferenceBinding\",\"normalizeBindingTokens\",\"normalizeConsolePublicPath\",\"parseFunctionParameterOptions\",\"plugins\",\"registerConsoleExtension\",\"resolveBindings\",\"resolveConsoleOrgPluginPage\",\"resolveConsolePluginPage\",\"resolveConsolePublicPage\",\"resolveConsoleStaffPage\",\"resolveNodesBindings\",\"rewriteBindingTokensDeep\",\"textReferencesBinding\",\"unregisterConsoleExtension\",\"useEnabledPlugins\",\"useNodeId\",\"useSite\",\"useSiteFetch\"]),\n mui: new Set([\"Alert\",\"Box\",\"Button\",\"Card\",\"CardContent\",\"Checkbox\",\"Chip\",\"CircularProgress\",\"Collapse\",\"Divider\",\"FormControl\",\"FormControlLabel\",\"FormHelperText\",\"IconButton\",\"InputAdornment\",\"InputLabel\",\"Link\",\"List\",\"ListItem\",\"ListItemText\",\"MenuItem\",\"Paper\",\"Radio\",\"RadioGroup\",\"Select\",\"Stack\",\"SvgIcon\",\"Switch\",\"Table\",\"TableBody\",\"TableCell\",\"TableHead\",\"TableRow\",\"TextField\",\"Tooltip\",\"Typography\",\"createSvgIcon\",\"useMediaQuery\"]),\n muiStyles: new Set([\"alpha\",\"css\",\"darken\",\"emphasize\",\"getContrastRatio\",\"keyframes\",\"lighten\",\"styled\",\"useColorScheme\",\"useTheme\"]),\n}\n"],"names":["REALM_HOST_SURFACE_NAMES","aglyn","Set","mui","muiStyles"],"mappings":"AAAA;;;;;;;CAOC,GACD,kBAAkB,GAElB,OAAO,MAAMA,2BAET;IACFC,OAAO,IAAIC,IAAI;QAAC;QAAQ;QAA+B;QAA2B;QAAkC;QAA4B;QAA6B;QAAuB;QAAoB;QAAwB;QAAe;QAAyB;QAA0B;QAAyB;QAAqB;QAAqB;QAA4B;QAAsB;QAAwB;QAAgB;QAAqB;QAAsB;QAAW;QAAyB;QAA8B;QAA8B;QAAgC;QAAqB;QAAoB;QAAc;QAA2B;QAA4B;QAAwB;QAAQ;QAA4B;QAAwB;QAAS;QAAa;QAAwB;QAAuB;QAAwB;QAAU;QAAqB;QAAuB;QAAwB;QAAwB;QAAwB;QAAiC;QAAwB;QAAsB;QAAkB;QAA0B;QAAc;QAA8B;QAA+B;QAA2B;QAAsB;QAAmB;QAA+B;QAAU;QAAwB;QAAsB;QAAyB;QAAuB;QAAyB;QAA2B;QAAwB;QAA0B;QAAqB;QAAS;QAAwB;QAAyB;QAA6B;QAAgC;QAAU;QAA2B;QAAkB;QAA8B;QAA2B;QAA2B;QAA0B;QAAuB;QAA2B;QAAwB;QAA6B;QAAoB;QAAY;QAAU;KAAe;
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/realm-host-surface.generated.ts"],"sourcesContent":["/**\n * GENERATED FILE — do not edit. Regenerate with:\n * node tools/scripts/generate-realm-host-exports.mjs\n *\n * The names each realm host module holds (AGL-3392), for the bundle\n * verifier: a bundle reading any other name from the host is refused,\n * because it would read `undefined` on every site.\n */\n/* eslint-disable */\n\nexport const REALM_HOST_SURFACE_NAMES: Readonly<\n Record<'aglyn' | 'mui' | 'muiStyles', ReadonlySet<string>>\n> = {\n aglyn: new Set([\"Aglyn\",\"CATEGORY_REQUIRED_CAPABILITY\",\"COMPONENT_CATEGORY_ORDER\",\"CONSOLE_HOST_GATED_WIDGET_SLOTS\",\"CONSOLE_SEARCH_LOAD_POINT\",\"CONSOLE_STAFF_WIDGET_SLOTS\",\"CONSOLE_WIDGET_SLOTS\",\"ComponentCategory\",\"EnabledPluginsContext\",\"FEATURE_FLAG\",\"FUNCTION_BUILTIN_NAMES\",\"FUNCTION_MAX_OPERATIONS\",\"FUNCTION_TOKEN_PATTERN\",\"FieldComponentType\",\"FieldValidatorType\",\"HOST_VARIABLE_TYPE_LABELS\",\"LinealDirectiveFlag\",\"MISSING_BINDING_LABEL\",\"MUI_BUNDLE_ID\",\"NAME_TOKEN_PATTERN\",\"NodeIdentityContext\",\"NodeType\",\"PREVIEW_REFUSED_STATUS\",\"PREVIEW_WRITE_BLOCKED_EVENT\",\"REUSABLE_COMPONENT_CATEGORY\",\"REUSABLE_EMAIL_BLOCK_CATEGORY\",\"RICH_TEXT_COMMANDS\",\"ScreenLinkContext\",\"SiteContext\",\"THEME_PRESETS_LOAD_POINT\",\"VARIABLE_ID_TOKEN_PATTERN\",\"VARIABLE_NAME_PATTERN\",\"aglyn\",\"attachFunctionDefinitions\",\"bindingTokenNeedsDeep\",\"canvas\",\"components\",\"defineUiFeatureBundle\",\"displayBindingTokens\",\"editableBindingTokens\",\"emitter\",\"evaluateExpression\",\"evaluateHostFunction\",\"expressionIdentifiers\",\"expressionSyntaxError\",\"formatFunctionIdToken\",\"formatFunctionParameterOptions\",\"formatVariableIdToken\",\"formatVariableValue\",\"functionGlobals\",\"functionReferencedNames\",\"hasBindings\",\"isCategoryCapabilityEnabled\",\"isConsoleHostGatedWidgetSlot\",\"isConsoleStaffWidgetSlot\",\"isFromEnabledPlugin\",\"isPreviewRefusal\",\"isSwitchedOffForRenderedSite\",\"isVariableName\",\"keyById\",\"listConsoleExtensions\",\"listConsoleNavItems\",\"listConsoleOrgNavItems\",\"listConsoleProviders\",\"listConsolePublicPages\",\"listConsoleSearchSources\",\"listConsoleStaffPages\",\"listConsoleThemePresets\",\"listConsoleWidgets\",\"logger\",\"nodesReferenceBinding\",\"normalizeBindingTokens\",\"normalizeConsolePublicPath\",\"parseFunctionParameterOptions\",\"plugins\",\"registerConsoleExtension\",\"resolveBindings\",\"resolveConsoleOrgPluginPage\",\"resolveConsolePluginPage\",\"resolveConsolePublicPage\",\"resolveConsoleStaffPage\",\"resolveNodesBindings\",\"rewriteBindingTokensDeep\",\"textReferencesBinding\",\"unregisterConsoleExtension\",\"useEnabledPlugins\",\"useNodeId\",\"useSite\",\"useSiteFetch\"]),\n mui: new Set([\"Alert\",\"Box\",\"Button\",\"Card\",\"CardContent\",\"Checkbox\",\"Chip\",\"CircularProgress\",\"Collapse\",\"Divider\",\"FormControl\",\"FormControlLabel\",\"FormHelperText\",\"IconButton\",\"InputAdornment\",\"InputLabel\",\"Link\",\"List\",\"ListItem\",\"ListItemText\",\"MenuItem\",\"Paper\",\"Radio\",\"RadioGroup\",\"Select\",\"Stack\",\"SvgIcon\",\"Switch\",\"Table\",\"TableBody\",\"TableCell\",\"TableHead\",\"TableRow\",\"TextField\",\"Tooltip\",\"Typography\",\"createSvgIcon\",\"useMediaQuery\"]),\n muiStyles: new Set([\"alpha\",\"css\",\"darken\",\"emphasize\",\"getContrastRatio\",\"keyframes\",\"lighten\",\"styled\",\"useColorScheme\",\"useTheme\"]),\n}\n"],"names":["REALM_HOST_SURFACE_NAMES","aglyn","Set","mui","muiStyles"],"mappings":"AAAA;;;;;;;CAOC,GACD,kBAAkB,GAElB,OAAO,MAAMA,2BAET;IACFC,OAAO,IAAIC,IAAI;QAAC;QAAQ;QAA+B;QAA2B;QAAkC;QAA4B;QAA6B;QAAuB;QAAoB;QAAwB;QAAe;QAAyB;QAA0B;QAAyB;QAAqB;QAAqB;QAA4B;QAAsB;QAAwB;QAAgB;QAAqB;QAAsB;QAAW;QAAyB;QAA8B;QAA8B;QAAgC;QAAqB;QAAoB;QAAc;QAA2B;QAA4B;QAAwB;QAAQ;QAA4B;QAAwB;QAAS;QAAa;QAAwB;QAAuB;QAAwB;QAAU;QAAqB;QAAuB;QAAwB;QAAwB;QAAwB;QAAiC;QAAwB;QAAsB;QAAkB;QAA0B;QAAc;QAA8B;QAA+B;QAA2B;QAAsB;QAAmB;QAA+B;QAAiB;QAAU;QAAwB;QAAsB;QAAyB;QAAuB;QAAyB;QAA2B;QAAwB;QAA0B;QAAqB;QAAS;QAAwB;QAAyB;QAA6B;QAAgC;QAAU;QAA2B;QAAkB;QAA8B;QAA2B;QAA2B;QAA0B;QAAuB;QAA2B;QAAwB;QAA6B;QAAoB;QAAY;QAAU;KAAe;IACh/DC,KAAK,IAAID,IAAI;QAAC;QAAQ;QAAM;QAAS;QAAO;QAAc;QAAW;QAAO;QAAmB;QAAW;QAAU;QAAc;QAAmB;QAAiB;QAAa;QAAiB;QAAa;QAAO;QAAO;QAAW;QAAe;QAAW;QAAQ;QAAQ;QAAa;QAAS;QAAQ;QAAU;QAAS;QAAQ;QAAY;QAAY;QAAY;QAAW;QAAY;QAAU;QAAa;QAAgB;KAAgB;IAC/bE,WAAW,IAAIF,IAAI;QAAC;QAAQ;QAAM;QAAS;QAAY;QAAmB;QAAY;QAAU;QAAS;QAAiB;KAAW;AACvI,EAAC"}
|
|
@@ -41,6 +41,8 @@ export interface HostVariable {
|
|
|
41
41
|
value?: string;
|
|
42
42
|
}
|
|
43
43
|
export declare const VARIABLE_NAME_PATTERN: RegExp;
|
|
44
|
+
/** Whether `name` may name a variable or a function's parameter (`VARIABLE_NAME_PATTERN`). */
|
|
45
|
+
export declare function isVariableName(name: string): boolean;
|
|
44
46
|
/** Human-readable rendering of a variable's value for text interpolation. */
|
|
45
47
|
export declare function formatVariableValue(variable: HostVariable): string;
|
|
46
48
|
/** A function definition lookup keyed by function name (AGL-93). */
|
|
@@ -29,6 +29,9 @@ export const HOST_VARIABLE_TYPE_LABELS = {
|
|
|
29
29
|
collection: 'Collection list (values)'
|
|
30
30
|
};
|
|
31
31
|
export const VARIABLE_NAME_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]{0,39}$/;
|
|
32
|
+
/** Whether `name` may name a variable or a function's parameter (`VARIABLE_NAME_PATTERN`). */ export function isVariableName(name) {
|
|
33
|
+
return VARIABLE_NAME_PATTERN.test(name);
|
|
34
|
+
}
|
|
32
35
|
/** Human-readable rendering of a variable's value for text interpolation. */ export function formatVariableValue(variable) {
|
|
33
36
|
var _variable_value;
|
|
34
37
|
const raw = (_variable_value = variable.value) != null ? _variable_value : '';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/variables.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Token grammar shared with the picker/besigner (AGL-185/194): id-form\n// tokens only — legacy name resolution retired after the production\n// content migration ran clean.\nimport {\n FUNCTION_TOKEN_PATTERN,\n VARIABLE_ID_TOKEN_PATTERN,\n} from './binding-tokens'\nimport {\n evaluateExpression,\n evaluateHostFunction,\n functionReferencedNames,\n type HostFunction,\n} from './functions'\n\n/**\n * Host variables (Component Builder, AGL-91): typed values authored in the\n * console and bound into component text props with `{{name}}` — and, since\n * AGL-93, function results with `{{fn:name(args)}}`. Pure data module\n * shared by the console editor UI and the tenant compose pipeline.\n */\n\n/** Types from the mockup's Edit Variable dialog (\"Function\" lands with AGL-92). */\nexport type HostVariableType =\n | 'date'\n | 'time'\n | 'text'\n | 'number'\n | 'boolean'\n | 'dictionary'\n | 'collection'\n\nexport const HOST_VARIABLE_TYPE_LABELS: Record<HostVariableType, string> = {\n date: 'Date',\n time: 'Time',\n text: 'Plain text',\n number: 'Number',\n boolean: 'True/false (boolean)',\n dictionary: 'Dictionary (key: value)',\n collection: 'Collection list (values)',\n}\n\n/**\n * `hosts/{hostId}/variables/{id}` doc, as far as binding reads it.\n *\n * A COMPUTED variable also carries the reference its computing plugin reads\n * — which record produces its value — and `value` is then the fallback the\n * page shows when that record is gone or fails. Binding never reads the\n * reference; the plugin that computes the value types and reads its own\n * (`plugin-manager/computed-variables`).\n */\nexport interface HostVariable {\n /** Binding identifier — `{{name}}`. */\n name: string\n type: HostVariableType\n /** Persisted as a string; formatted per type at resolve time. */\n value?: string\n}\n\nexport const VARIABLE_NAME_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]{0,39}$/\n\n/** Human-readable rendering of a variable's value for text interpolation. */\nexport function formatVariableValue(variable: HostVariable): string {\n const raw = variable.value ?? ''\n switch (variable.type) {\n case 'boolean':\n return raw === 'true' ? 'true' : 'false'\n case 'number': {\n const parsed = Number(raw)\n return Number.isFinite(parsed) ? String(parsed) : ''\n }\n case 'date': {\n const parsed = new Date(raw)\n return Number.isNaN(parsed.getTime())\n ? raw\n : parsed.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n timeZone: 'UTC',\n })\n }\n case 'dictionary':\n case 'collection': {\n // Stored as JSON; render collections comma-joined and dictionaries\n // as `key: value` pairs so a bare {{name}} stays readable.\n try {\n const parsed = JSON.parse(raw)\n if (Array.isArray(parsed)) return parsed.map(String).join(', ')\n if (parsed && typeof parsed === 'object') {\n return Object.entries(parsed)\n .map(([key, value]) => `${key}: ${value}`)\n .join(', ')\n }\n } catch {\n // fall through to the raw string\n }\n return raw\n }\n case 'time':\n case 'text':\n default:\n return raw\n }\n}\n\n/** A function definition lookup keyed by function name (AGL-93). */\nexport type HostFunctionLookup = Record<string, HostFunction>\n\n/**\n * Variable values as an expression scope (numbers stay numeric). Keyed by\n * each doc's NAME regardless of how the lookup map is keyed (AGL-194:\n * maps are id-keyed now, but expressions reference variables by name).\n */\nfunction variableScope(\n variables: Record<string, HostVariable>,\n): Record<string, number | string | boolean> {\n const scope: Record<string, number | string | boolean> = {}\n for (const variable of Object.values(variables)) {\n if (!variable?.name) continue\n if (variable.type === 'number') {\n scope[variable.name] = Number(variable.value ?? 0)\n } else if (variable.type === 'boolean') {\n scope[variable.name] = variable.value === 'true'\n } else {\n scope[variable.name] = variable.value ?? ''\n }\n }\n return scope\n}\n\n/**\n * Replaces binding tokens with values (AGL-91/93/185/194): id forms\n * `{{var:id}}` / `{{fn:id(args)}}` resolve through id-keyed lookup maps.\n * Function args are expressions over literals and variable NAMES (the\n * scope keys by each doc's name). Unknown function refs keep the literal\n * token; unknown variable ids render empty; bare `{{name}}` strings are\n * plain text since the legacy fallback retired.\n */\nexport function resolveBindings(\n text: string,\n variables: Record<string, HostVariable>,\n functions: HostFunctionLookup = {},\n): string {\n const withVariableIds = text.replace(\n VARIABLE_ID_TOKEN_PATTERN,\n (_token, id) => {\n const variable = variables[String(id)]\n // Unknown ids render EMPTY, not literal (AGL-186): a raw doc id is\n // meaningless to visitors, unlike a readable legacy {{name}} token.\n return variable ? formatVariableValue(variable) : ''\n },\n )\n const withFunctions = withVariableIds.replace(\n FUNCTION_TOKEN_PATTERN,\n (token, rawName, rawArgs) => {\n const definition = functions[String(rawName).trim()]\n if (!definition) return token\n try {\n const scope = variableScope(variables)\n const argValues = String(rawArgs)\n .split(',')\n .map((argument) => argument.trim())\n .filter((argument) => argument.length > 0)\n .map((argument) => evaluateExpression(argument, scope))\n const args: Record<string, unknown> = {}\n definition.parameters?.forEach((parameter, index) => {\n args[parameter.name] = argValues[index]\n })\n // The site's variables are the function's outer scope (AGL-3202),\n // so `{{fn:id(25)}}` can price 25 sites without every rate being\n // passed in by position. Arguments still win over a variable of the\n // same name, as every parameter does.\n const result = evaluateHostFunction(definition, args, {\n globals: scope,\n })\n return result.ok ? String(result.value) : token\n } catch {\n return token\n }\n },\n )\n // Legacy {{name}} resolution retired (AGL-194): the production content\n // migration ran clean, so bare-name tokens are plain text now. Typing\n // them in the editor still works — save-time normalization converts\n // known names to id tokens before they persist.\n return withFunctions\n}\n\n/** Fast pre-check so binding-free content skips the walk entirely. */\nexport function hasBindings(text: string): boolean {\n return /\\{\\{/.test(text)\n}\n\n/**\n * The site variables ONE function reads, by name (AGL-3202).\n *\n * A widget runs in the visitor's browser, so whatever it may read has to be\n * on the page. Handing it the whole variable list would publish every value\n * a site holds to every page that places a calculator; this hands over the\n * names the function's own expressions use and nothing else. A name the\n * function declares itself is not a variable read — its parameter or local\n * shadows the variable — so it is not shipped either.\n */\nexport function functionGlobals(\n definition: HostFunction,\n variables: Record<string, HostVariable>,\n): Record<string, number | string | boolean> {\n const scope = variableScope(variables)\n const globals: Record<string, number | string | boolean> = {}\n for (const name of functionReferencedNames(definition)) {\n if (Object.prototype.hasOwnProperty.call(scope, name)) {\n globals[name] = scope[name]\n }\n }\n return globals\n}\n\n/**\n * Injects each function-running element's definition into its props at\n * compose time (AGL-93): the client runs the shared evaluator locally, so the\n * published page carries the definition instead of calling home. Unknown\n * names leave the node untouched (the element renders its editor\n * placeholder).\n *\n * Which elements run a function is DECLARED (AGL-3393): `bindings` maps a\n * component id to the prop that names its function, collected from each\n * plugin's `contributes.site.functionBindings`. Core names no element, so a\n * marketplace plugin's element is bound exactly as a first-party one is, and\n * an element nobody declared is never handed a definition.\n *\n * With `variables`, the site variables that function reads ride along as\n * `globals` (AGL-3202) — see {@link functionGlobals} for why it is only\n * those. The key is omitted when the function reads none, so a page built\n * before this existed serializes exactly as it did.\n */\nexport function attachFunctionDefinitions<T extends Record<string, any>>(\n nodes: T,\n functions: HostFunctionLookup,\n variables: Record<string, HostVariable>,\n bindings: Readonly<Record<string, string>>,\n): T {\n if (!Object.keys(functions).length || !Object.keys(bindings).length) {\n return nodes\n }\n const next: Record<string, any> = {}\n for (const [id, node] of Object.entries(nodes)) {\n const componentId = node?.componentId\n const prop =\n typeof componentId === 'string' &&\n Object.prototype.hasOwnProperty.call(bindings, componentId)\n ? bindings[componentId]\n : undefined\n const name = prop ? node?.props?.[prop] : undefined\n const definition = name ? functions[String(name).trim()] : undefined\n if (!definition) {\n next[id] = node\n continue\n }\n const globals = functionGlobals(definition, variables)\n next[id] = {\n ...node,\n props: {\n ...node.props,\n definition,\n ...(Object.keys(globals).length ? { globals } : {}),\n },\n }\n }\n return next as T\n}\n\n/**\n * Applies `resolveBindings` to every string prop across a normalized nodes\n * map (mutating a shallow copy). String props only — objects/arrays (sx,\n * option lists) pass through untouched; unsafe values in hrefs remain\n * covered by the render-time SAFE_HREF/sanitizer checks.\n */\nexport function resolveNodesBindings<T extends Record<string, any>>(\n nodes: T,\n variables: Record<string, HostVariable>,\n functions: HostFunctionLookup = {},\n): T {\n if (!Object.keys(variables).length && !Object.keys(functions).length) {\n return nodes\n }\n const next: Record<string, any> = {}\n for (const [id, node] of Object.entries(nodes)) {\n const props = node?.props\n if (!props) {\n next[id] = node\n continue\n }\n let changed = false\n const nextProps: Record<string, unknown> = { ...props }\n for (const [key, value] of Object.entries(props)) {\n if (typeof value === 'string' && hasBindings(value)) {\n nextProps[key] = resolveBindings(value, variables, functions)\n changed = true\n }\n }\n next[id] = changed ? { ...node, props: nextProps } : node\n }\n return next as T\n}\n"],"names":["FUNCTION_TOKEN_PATTERN","VARIABLE_ID_TOKEN_PATTERN","evaluateExpression","evaluateHostFunction","functionReferencedNames","HOST_VARIABLE_TYPE_LABELS","date","time","text","number","boolean","dictionary","collection","VARIABLE_NAME_PATTERN","formatVariableValue","variable","raw","value","type","parsed","Number","isFinite","String","Date","isNaN","getTime","toLocaleDateString","undefined","year","month","day","timeZone","JSON","parse","Array","isArray","map","join","Object","entries","key","variableScope","variables","scope","values","name","resolveBindings","functions","withVariableIds","replace","_token","id","withFunctions","token","rawName","rawArgs","definition","trim","argValues","split","argument","filter","length","args","parameters","forEach","parameter","index","result","globals","ok","hasBindings","test","functionGlobals","prototype","hasOwnProperty","call","attachFunctionDefinitions","nodes","bindings","keys","next","node","componentId","prop","props","resolveNodesBindings","changed","nextProps"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/variables.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Token grammar shared with the picker/besigner (AGL-185/194): id-form\n// tokens only — legacy name resolution retired after the production\n// content migration ran clean.\nimport {\n FUNCTION_TOKEN_PATTERN,\n VARIABLE_ID_TOKEN_PATTERN,\n} from './binding-tokens'\nimport {\n evaluateExpression,\n evaluateHostFunction,\n functionReferencedNames,\n type HostFunction,\n} from './functions'\n\n/**\n * Host variables (Component Builder, AGL-91): typed values authored in the\n * console and bound into component text props with `{{name}}` — and, since\n * AGL-93, function results with `{{fn:name(args)}}`. Pure data module\n * shared by the console editor UI and the tenant compose pipeline.\n */\n\n/** Types from the mockup's Edit Variable dialog (\"Function\" lands with AGL-92). */\nexport type HostVariableType =\n | 'date'\n | 'time'\n | 'text'\n | 'number'\n | 'boolean'\n | 'dictionary'\n | 'collection'\n\nexport const HOST_VARIABLE_TYPE_LABELS: Record<HostVariableType, string> = {\n date: 'Date',\n time: 'Time',\n text: 'Plain text',\n number: 'Number',\n boolean: 'True/false (boolean)',\n dictionary: 'Dictionary (key: value)',\n collection: 'Collection list (values)',\n}\n\n/**\n * `hosts/{hostId}/variables/{id}` doc, as far as binding reads it.\n *\n * A COMPUTED variable also carries the reference its computing plugin reads\n * — which record produces its value — and `value` is then the fallback the\n * page shows when that record is gone or fails. Binding never reads the\n * reference; the plugin that computes the value types and reads its own\n * (`plugin-manager/computed-variables`).\n */\nexport interface HostVariable {\n /** Binding identifier — `{{name}}`. */\n name: string\n type: HostVariableType\n /** Persisted as a string; formatted per type at resolve time. */\n value?: string\n}\n\nexport const VARIABLE_NAME_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]{0,39}$/\n\n/** Whether `name` may name a variable or a function's parameter (`VARIABLE_NAME_PATTERN`). */\nexport function isVariableName(name: string): boolean {\n return VARIABLE_NAME_PATTERN.test(name)\n}\n\n/** Human-readable rendering of a variable's value for text interpolation. */\nexport function formatVariableValue(variable: HostVariable): string {\n const raw = variable.value ?? ''\n switch (variable.type) {\n case 'boolean':\n return raw === 'true' ? 'true' : 'false'\n case 'number': {\n const parsed = Number(raw)\n return Number.isFinite(parsed) ? String(parsed) : ''\n }\n case 'date': {\n const parsed = new Date(raw)\n return Number.isNaN(parsed.getTime())\n ? raw\n : parsed.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n timeZone: 'UTC',\n })\n }\n case 'dictionary':\n case 'collection': {\n // Stored as JSON; render collections comma-joined and dictionaries\n // as `key: value` pairs so a bare {{name}} stays readable.\n try {\n const parsed = JSON.parse(raw)\n if (Array.isArray(parsed)) return parsed.map(String).join(', ')\n if (parsed && typeof parsed === 'object') {\n return Object.entries(parsed)\n .map(([key, value]) => `${key}: ${value}`)\n .join(', ')\n }\n } catch {\n // fall through to the raw string\n }\n return raw\n }\n case 'time':\n case 'text':\n default:\n return raw\n }\n}\n\n/** A function definition lookup keyed by function name (AGL-93). */\nexport type HostFunctionLookup = Record<string, HostFunction>\n\n/**\n * Variable values as an expression scope (numbers stay numeric). Keyed by\n * each doc's NAME regardless of how the lookup map is keyed (AGL-194:\n * maps are id-keyed now, but expressions reference variables by name).\n */\nfunction variableScope(\n variables: Record<string, HostVariable>,\n): Record<string, number | string | boolean> {\n const scope: Record<string, number | string | boolean> = {}\n for (const variable of Object.values(variables)) {\n if (!variable?.name) continue\n if (variable.type === 'number') {\n scope[variable.name] = Number(variable.value ?? 0)\n } else if (variable.type === 'boolean') {\n scope[variable.name] = variable.value === 'true'\n } else {\n scope[variable.name] = variable.value ?? ''\n }\n }\n return scope\n}\n\n/**\n * Replaces binding tokens with values (AGL-91/93/185/194): id forms\n * `{{var:id}}` / `{{fn:id(args)}}` resolve through id-keyed lookup maps.\n * Function args are expressions over literals and variable NAMES (the\n * scope keys by each doc's name). Unknown function refs keep the literal\n * token; unknown variable ids render empty; bare `{{name}}` strings are\n * plain text since the legacy fallback retired.\n */\nexport function resolveBindings(\n text: string,\n variables: Record<string, HostVariable>,\n functions: HostFunctionLookup = {},\n): string {\n const withVariableIds = text.replace(\n VARIABLE_ID_TOKEN_PATTERN,\n (_token, id) => {\n const variable = variables[String(id)]\n // Unknown ids render EMPTY, not literal (AGL-186): a raw doc id is\n // meaningless to visitors, unlike a readable legacy {{name}} token.\n return variable ? formatVariableValue(variable) : ''\n },\n )\n const withFunctions = withVariableIds.replace(\n FUNCTION_TOKEN_PATTERN,\n (token, rawName, rawArgs) => {\n const definition = functions[String(rawName).trim()]\n if (!definition) return token\n try {\n const scope = variableScope(variables)\n const argValues = String(rawArgs)\n .split(',')\n .map((argument) => argument.trim())\n .filter((argument) => argument.length > 0)\n .map((argument) => evaluateExpression(argument, scope))\n const args: Record<string, unknown> = {}\n definition.parameters?.forEach((parameter, index) => {\n args[parameter.name] = argValues[index]\n })\n // The site's variables are the function's outer scope (AGL-3202),\n // so `{{fn:id(25)}}` can price 25 sites without every rate being\n // passed in by position. Arguments still win over a variable of the\n // same name, as every parameter does.\n const result = evaluateHostFunction(definition, args, {\n globals: scope,\n })\n return result.ok ? String(result.value) : token\n } catch {\n return token\n }\n },\n )\n // Legacy {{name}} resolution retired (AGL-194): the production content\n // migration ran clean, so bare-name tokens are plain text now. Typing\n // them in the editor still works — save-time normalization converts\n // known names to id tokens before they persist.\n return withFunctions\n}\n\n/** Fast pre-check so binding-free content skips the walk entirely. */\nexport function hasBindings(text: string): boolean {\n return /\\{\\{/.test(text)\n}\n\n/**\n * The site variables ONE function reads, by name (AGL-3202).\n *\n * A widget runs in the visitor's browser, so whatever it may read has to be\n * on the page. Handing it the whole variable list would publish every value\n * a site holds to every page that places a calculator; this hands over the\n * names the function's own expressions use and nothing else. A name the\n * function declares itself is not a variable read — its parameter or local\n * shadows the variable — so it is not shipped either.\n */\nexport function functionGlobals(\n definition: HostFunction,\n variables: Record<string, HostVariable>,\n): Record<string, number | string | boolean> {\n const scope = variableScope(variables)\n const globals: Record<string, number | string | boolean> = {}\n for (const name of functionReferencedNames(definition)) {\n if (Object.prototype.hasOwnProperty.call(scope, name)) {\n globals[name] = scope[name]\n }\n }\n return globals\n}\n\n/**\n * Injects each function-running element's definition into its props at\n * compose time (AGL-93): the client runs the shared evaluator locally, so the\n * published page carries the definition instead of calling home. Unknown\n * names leave the node untouched (the element renders its editor\n * placeholder).\n *\n * Which elements run a function is DECLARED (AGL-3393): `bindings` maps a\n * component id to the prop that names its function, collected from each\n * plugin's `contributes.site.functionBindings`. Core names no element, so a\n * marketplace plugin's element is bound exactly as a first-party one is, and\n * an element nobody declared is never handed a definition.\n *\n * With `variables`, the site variables that function reads ride along as\n * `globals` (AGL-3202) — see {@link functionGlobals} for why it is only\n * those. The key is omitted when the function reads none, so a page built\n * before this existed serializes exactly as it did.\n */\nexport function attachFunctionDefinitions<T extends Record<string, any>>(\n nodes: T,\n functions: HostFunctionLookup,\n variables: Record<string, HostVariable>,\n bindings: Readonly<Record<string, string>>,\n): T {\n if (!Object.keys(functions).length || !Object.keys(bindings).length) {\n return nodes\n }\n const next: Record<string, any> = {}\n for (const [id, node] of Object.entries(nodes)) {\n const componentId = node?.componentId\n const prop =\n typeof componentId === 'string' &&\n Object.prototype.hasOwnProperty.call(bindings, componentId)\n ? bindings[componentId]\n : undefined\n const name = prop ? node?.props?.[prop] : undefined\n const definition = name ? functions[String(name).trim()] : undefined\n if (!definition) {\n next[id] = node\n continue\n }\n const globals = functionGlobals(definition, variables)\n next[id] = {\n ...node,\n props: {\n ...node.props,\n definition,\n ...(Object.keys(globals).length ? { globals } : {}),\n },\n }\n }\n return next as T\n}\n\n/**\n * Applies `resolveBindings` to every string prop across a normalized nodes\n * map (mutating a shallow copy). String props only — objects/arrays (sx,\n * option lists) pass through untouched; unsafe values in hrefs remain\n * covered by the render-time SAFE_HREF/sanitizer checks.\n */\nexport function resolveNodesBindings<T extends Record<string, any>>(\n nodes: T,\n variables: Record<string, HostVariable>,\n functions: HostFunctionLookup = {},\n): T {\n if (!Object.keys(variables).length && !Object.keys(functions).length) {\n return nodes\n }\n const next: Record<string, any> = {}\n for (const [id, node] of Object.entries(nodes)) {\n const props = node?.props\n if (!props) {\n next[id] = node\n continue\n }\n let changed = false\n const nextProps: Record<string, unknown> = { ...props }\n for (const [key, value] of Object.entries(props)) {\n if (typeof value === 'string' && hasBindings(value)) {\n nextProps[key] = resolveBindings(value, variables, functions)\n changed = true\n }\n }\n next[id] = changed ? { ...node, props: nextProps } : node\n }\n return next as T\n}\n"],"names":["FUNCTION_TOKEN_PATTERN","VARIABLE_ID_TOKEN_PATTERN","evaluateExpression","evaluateHostFunction","functionReferencedNames","HOST_VARIABLE_TYPE_LABELS","date","time","text","number","boolean","dictionary","collection","VARIABLE_NAME_PATTERN","isVariableName","name","test","formatVariableValue","variable","raw","value","type","parsed","Number","isFinite","String","Date","isNaN","getTime","toLocaleDateString","undefined","year","month","day","timeZone","JSON","parse","Array","isArray","map","join","Object","entries","key","variableScope","variables","scope","values","resolveBindings","functions","withVariableIds","replace","_token","id","withFunctions","token","rawName","rawArgs","definition","trim","argValues","split","argument","filter","length","args","parameters","forEach","parameter","index","result","globals","ok","hasBindings","functionGlobals","prototype","hasOwnProperty","call","attachFunctionDefinitions","nodes","bindings","keys","next","node","componentId","prop","props","resolveNodesBindings","changed","nextProps"],"mappings":"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"}
|
|
@@ -76,6 +76,13 @@ export interface VisitorConsentHost {
|
|
|
76
76
|
gaMeasurementId?: string;
|
|
77
77
|
/** GTM container (AGL-2486) — gated exactly as the GA id is. */
|
|
78
78
|
gtmContainerId?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Advertising vendor id → the site's account id with that vendor (AGL-1152,
|
|
81
|
+
* AGL-3694): the merchant's own Meta pixel, TikTok pixel, Pinterest tag,
|
|
82
|
+
* Google Ads id or LinkedIn partner id, each shaped by
|
|
83
|
+
* {@link ADVERTISING_TAG_ID_PATTERNS}.
|
|
84
|
+
*/
|
|
85
|
+
adTags?: Record<string, string> | null;
|
|
79
86
|
} | null;
|
|
80
87
|
consent?: {
|
|
81
88
|
/**
|
|
@@ -239,6 +246,33 @@ export declare const GOOGLE_ADS_ID_PATTERN: RegExp;
|
|
|
239
246
|
* matches nothing.
|
|
240
247
|
*/
|
|
241
248
|
export declare const LINKEDIN_PARTNER_ID_PATTERN: RegExp;
|
|
249
|
+
/**
|
|
250
|
+
* A TikTok pixel code (AGL-3694) — upper-case letters and digits, 20 today.
|
|
251
|
+
* The band is generous on both sides, like the Meta one; what it must refuse
|
|
252
|
+
* is anything that could escape the inline boot it is written into.
|
|
253
|
+
*/
|
|
254
|
+
export declare const TIKTOK_PIXEL_ID_PATTERN: RegExp;
|
|
255
|
+
/**
|
|
256
|
+
* A Pinterest tag id (AGL-3694) — numeric, 13 digits today. Its own field, so
|
|
257
|
+
* the overlap with the Meta band never lets one vendor's id load the other.
|
|
258
|
+
*/
|
|
259
|
+
export declare const PINTEREST_TAG_ID_PATTERN: RegExp;
|
|
260
|
+
/**
|
|
261
|
+
* Every advertising vendor a site can configure, by its `analytics.adTags`
|
|
262
|
+
* key, and the shape its account id must have — the patterns the loader and
|
|
263
|
+
* the console's Tracking tab share (AGL-3694). Declared here, not beside the
|
|
264
|
+
* vendor descriptors, because the console may not import the module that
|
|
265
|
+
* mounts them (`advertising-tag-gate.spec` case (f)).
|
|
266
|
+
*/
|
|
267
|
+
export declare const ADVERTISING_TAG_ID_PATTERNS: Readonly<Record<string, RegExp>>;
|
|
268
|
+
/** The site's well-formed account id with one advertising vendor, else null. */
|
|
269
|
+
export declare function resolveAdvertisingTagId(host: VisitorConsentHost | null | undefined, vendorId: string): string | null;
|
|
270
|
+
/**
|
|
271
|
+
* Whether the site configures ANY advertising tag with a well-formed id
|
|
272
|
+
* (AGL-3694). A pixel is a tracker in its own right, so a site running one and
|
|
273
|
+
* no analytics tag still needs the consent machinery in front of it.
|
|
274
|
+
*/
|
|
275
|
+
export declare function hostConfiguresAdvertisingTag(host: VisitorConsentHost | null | undefined): boolean;
|
|
242
276
|
/** The configured GA id when it is well-formed, else null. */
|
|
243
277
|
export declare function resolveGaMeasurementId(host: VisitorConsentHost | null | undefined): string | null;
|
|
244
278
|
/**
|
|
@@ -144,6 +144,43 @@ const CONSENT_STATUSES = new Set([
|
|
|
144
144
|
* would let a mis-paste into the wrong field validate and then load a tag that
|
|
145
145
|
* matches nothing.
|
|
146
146
|
*/ export const LINKEDIN_PARTNER_ID_PATTERN = /^[0-9]{4,10}$/;
|
|
147
|
+
/**
|
|
148
|
+
* A TikTok pixel code (AGL-3694) — upper-case letters and digits, 20 today.
|
|
149
|
+
* The band is generous on both sides, like the Meta one; what it must refuse
|
|
150
|
+
* is anything that could escape the inline boot it is written into.
|
|
151
|
+
*/ export const TIKTOK_PIXEL_ID_PATTERN = /^[A-Z0-9]{16,24}$/;
|
|
152
|
+
/**
|
|
153
|
+
* A Pinterest tag id (AGL-3694) — numeric, 13 digits today. Its own field, so
|
|
154
|
+
* the overlap with the Meta band never lets one vendor's id load the other.
|
|
155
|
+
*/ export const PINTEREST_TAG_ID_PATTERN = /^[0-9]{10,16}$/;
|
|
156
|
+
/**
|
|
157
|
+
* Every advertising vendor a site can configure, by its `analytics.adTags`
|
|
158
|
+
* key, and the shape its account id must have — the patterns the loader and
|
|
159
|
+
* the console's Tracking tab share (AGL-3694). Declared here, not beside the
|
|
160
|
+
* vendor descriptors, because the console may not import the module that
|
|
161
|
+
* mounts them (`advertising-tag-gate.spec` case (f)).
|
|
162
|
+
*/ export const ADVERTISING_TAG_ID_PATTERNS = Object.freeze({
|
|
163
|
+
meta: META_PIXEL_ID_PATTERN,
|
|
164
|
+
'google-ads': GOOGLE_ADS_ID_PATTERN,
|
|
165
|
+
linkedin: LINKEDIN_PARTNER_ID_PATTERN,
|
|
166
|
+
tiktok: TIKTOK_PIXEL_ID_PATTERN,
|
|
167
|
+
pinterest: PINTEREST_TAG_ID_PATTERN
|
|
168
|
+
});
|
|
169
|
+
/** The site's well-formed account id with one advertising vendor, else null. */ export function resolveAdvertisingTagId(host, vendorId) {
|
|
170
|
+
var _ref;
|
|
171
|
+
var _host_analytics_adTags, _host_analytics;
|
|
172
|
+
const pattern = ADVERTISING_TAG_ID_PATTERNS[vendorId];
|
|
173
|
+
if (!pattern) return null;
|
|
174
|
+
const candidate = String((_ref = host == null ? void 0 : (_host_analytics = host.analytics) == null ? void 0 : (_host_analytics_adTags = _host_analytics.adTags) == null ? void 0 : _host_analytics_adTags[vendorId]) != null ? _ref : '');
|
|
175
|
+
return pattern.test(candidate) ? candidate : null;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Whether the site configures ANY advertising tag with a well-formed id
|
|
179
|
+
* (AGL-3694). A pixel is a tracker in its own right, so a site running one and
|
|
180
|
+
* no analytics tag still needs the consent machinery in front of it.
|
|
181
|
+
*/ export function hostConfiguresAdvertisingTag(host) {
|
|
182
|
+
return Object.keys(ADVERTISING_TAG_ID_PATTERNS).some((vendorId)=>resolveAdvertisingTagId(host, vendorId) !== null);
|
|
183
|
+
}
|
|
147
184
|
/** The configured GA id when it is well-formed, else null. */ export function resolveGaMeasurementId(host) {
|
|
148
185
|
var _ref;
|
|
149
186
|
var _host_analytics;
|
|
@@ -220,7 +257,12 @@ const CONSENT_STATUSES = new Set([
|
|
|
220
257
|
// A CONTAINER counts (AGL-2486). Read as the measurement id alone, a site
|
|
221
258
|
// running only a container had no gated category, so no banner rendered
|
|
222
259
|
// and the container loaded ungated — see `hostConfiguresAnalyticsTag`.
|
|
223
|
-
|
|
260
|
+
// An advertising tag counts too (AGL-3694): a site running only a pixel
|
|
261
|
+
// has a tracker to ask about, and with no category it would get no banner
|
|
262
|
+
// and its pixel could never be granted.
|
|
263
|
+
if (!hostConfiguresAnalyticsTag(host) && !hostConfiguresAdvertisingTag(host)) {
|
|
264
|
+
return [];
|
|
265
|
+
}
|
|
224
266
|
return hostAsksAboutAdvertising(host) ? [
|
|
225
267
|
'analytics',
|
|
226
268
|
'advertising'
|
|
@@ -241,7 +283,12 @@ const CONSENT_STATUSES = new Set([
|
|
|
241
283
|
// Either tag qualifies (AGL-2486): advertising storage is what a
|
|
242
284
|
// measurement tag reads and what a container's advertising tags read, and
|
|
243
285
|
// a container is the likelier of the two to carry them.
|
|
244
|
-
|
|
286
|
+
//
|
|
287
|
+
// An advertising tag of the site's own qualifies as well (AGL-3694): it is
|
|
288
|
+
// the most direct thing the question is about, and without this a site
|
|
289
|
+
// running a pixel and no analytics id could never be asked, so its pixel
|
|
290
|
+
// could never load.
|
|
291
|
+
return (host == null ? void 0 : (_host_consent = host.consent) == null ? void 0 : _host_consent.advertising) === true && (hostConfiguresAnalyticsTag(host) || hostConfiguresAdvertisingTag(host));
|
|
245
292
|
}
|
|
246
293
|
/**
|
|
247
294
|
* Whether the published site runs the consent machinery at all: the tool is
|