@aglyn/aglyn 1.0.0-beta.234 → 1.0.0-beta.236
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/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-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
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ /**
|
|
17
|
+
* WHAT A PLUGIN'S SITE FEATURE NEEDS THE PUBLISHED PAGE'S POLICY TO ADMIT
|
|
18
|
+
* (AGL-3698).
|
|
19
|
+
*
|
|
20
|
+
* The tenant enforces `connect-src`, `frame-src`, `img-src`, `media-src` and
|
|
21
|
+
* `font-src` (AGL-1152). A plugin that loads a vendor's widget on a site —
|
|
22
|
+
* the merchant's own live chat is the first — needs that vendor's hosts in
|
|
23
|
+
* those directives, and only on the sites that switched the feature on:
|
|
24
|
+
* pinning them for every site would make every published page's policy
|
|
25
|
+
* describe a vendor most of them never load.
|
|
26
|
+
*
|
|
27
|
+
* So a plugin DECLARES the hosts in `plugins.config.json` (`siteCsp`), keyed
|
|
28
|
+
* by the value of one field of its site settings document
|
|
29
|
+
* (`hosts/{hostId}/pluginSettings/{pluginId}`), and switched by another. The
|
|
30
|
+
* generator compiles the declaration into `first-party-plugins.generated.ts`,
|
|
31
|
+
* and the tenant's lockdown verdict — the route that already hands the
|
|
32
|
+
* middleware every per-site list — reads the settings document of each
|
|
33
|
+
* declared plugin the site runs and adds the chosen variant's hosts. Core
|
|
34
|
+
* names no vendor and no plugin.
|
|
35
|
+
*
|
|
36
|
+
* The hosts ride the owner-list path in `security-origins.js`, so they are
|
|
37
|
+
* held to the same parse as an owner's own entries: a bare hostname or one
|
|
38
|
+
* leading `*.`, made `https://`. A `wss://` connection to an admitted host is
|
|
39
|
+
* covered by its `https://` source (CSP Level 3 scheme matching).
|
|
40
|
+
*/ import { PLUGIN_SITE_CSP_DECLARED } from "./first-party-plugins.generated.js";
|
|
41
|
+
/** The directives a plugin may widen; the enforced, owner-widenable ones. */ export const PLUGIN_SITE_CSP_DIRECTIVES = [
|
|
42
|
+
'connect',
|
|
43
|
+
'frame',
|
|
44
|
+
'img',
|
|
45
|
+
'media',
|
|
46
|
+
'font'
|
|
47
|
+
];
|
|
48
|
+
/** Every first-party declaration, compiled from `plugins.config.json`. */ export function pluginSiteCspDeclarations() {
|
|
49
|
+
return PLUGIN_SITE_CSP_DECLARED;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The hosts one plugin's stored settings admit, or none.
|
|
53
|
+
*
|
|
54
|
+
* Fails CLOSED on every malformed input: a switch that is not exactly `true`,
|
|
55
|
+
* an unknown variant, an empty required field. The settings document is
|
|
56
|
+
* written through the plugin's own route, but a reader of a policy input
|
|
57
|
+
* trusts nothing it did not parse.
|
|
58
|
+
*/ export function pluginSiteCspHostsFor(declaration, settings) {
|
|
59
|
+
var _declaration_variants_variant;
|
|
60
|
+
if (!settings || settings[declaration.switchField] !== true) return {};
|
|
61
|
+
if (declaration.requiredField) {
|
|
62
|
+
const required = settings[declaration.requiredField];
|
|
63
|
+
if (typeof required !== 'string' || !required.trim()) return {};
|
|
64
|
+
}
|
|
65
|
+
const variant = declaration.variantField ? settings[declaration.variantField] : 'default';
|
|
66
|
+
if (typeof variant !== 'string') return {};
|
|
67
|
+
if (!Object.prototype.hasOwnProperty.call(declaration.variants, variant)) {
|
|
68
|
+
return {};
|
|
69
|
+
}
|
|
70
|
+
return (_declaration_variants_variant = declaration.variants[variant]) != null ? _declaration_variants_variant : {};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The union of what every declared plugin the site runs admits, by
|
|
74
|
+
* directive, de-duplicated and in declaration order.
|
|
75
|
+
*
|
|
76
|
+
* `settingsByPlugin` holds the stored settings document of each plugin the
|
|
77
|
+
* caller read; a plugin missing from `enabledPluginIds` admits nothing even
|
|
78
|
+
* when its settings are present, because a switched-off plugin loads nothing
|
|
79
|
+
* on the page.
|
|
80
|
+
*/ export function pluginSiteCspHosts(enabledPluginIds, settingsByPlugin, declared = PLUGIN_SITE_CSP_DECLARED) {
|
|
81
|
+
const out = Object.fromEntries(PLUGIN_SITE_CSP_DIRECTIVES.map((directive)=>[
|
|
82
|
+
directive,
|
|
83
|
+
[]
|
|
84
|
+
]));
|
|
85
|
+
const enabled = new Set(enabledPluginIds);
|
|
86
|
+
for (const declaration of declared){
|
|
87
|
+
if (!enabled.has(declaration.pluginId)) continue;
|
|
88
|
+
const hosts = pluginSiteCspHostsFor(declaration, settingsByPlugin[declaration.pluginId]);
|
|
89
|
+
for (const directive of PLUGIN_SITE_CSP_DIRECTIVES){
|
|
90
|
+
var _hosts_directive;
|
|
91
|
+
for (const host of (_hosts_directive = hosts[directive]) != null ? _hosts_directive : []){
|
|
92
|
+
if (!out[directive].includes(host)) out[directive].push(host);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
/** The declared plugins among a site's enabled set: the settings worth reading. */ export function pluginSiteCspPluginsToRead(enabledPluginIds, declared = PLUGIN_SITE_CSP_DECLARED) {
|
|
99
|
+
const enabled = new Set(enabledPluginIds);
|
|
100
|
+
return declared.map((declaration)=>declaration.pluginId).filter((pluginId)=>enabled.has(pluginId));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
//# sourceMappingURL=plugin-site-csp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/plugin-site-csp.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * WHAT A PLUGIN'S SITE FEATURE NEEDS THE PUBLISHED PAGE'S POLICY TO ADMIT\n * (AGL-3698).\n *\n * The tenant enforces `connect-src`, `frame-src`, `img-src`, `media-src` and\n * `font-src` (AGL-1152). A plugin that loads a vendor's widget on a site —\n * the merchant's own live chat is the first — needs that vendor's hosts in\n * those directives, and only on the sites that switched the feature on:\n * pinning them for every site would make every published page's policy\n * describe a vendor most of them never load.\n *\n * So a plugin DECLARES the hosts in `plugins.config.json` (`siteCsp`), keyed\n * by the value of one field of its site settings document\n * (`hosts/{hostId}/pluginSettings/{pluginId}`), and switched by another. The\n * generator compiles the declaration into `first-party-plugins.generated.ts`,\n * and the tenant's lockdown verdict — the route that already hands the\n * middleware every per-site list — reads the settings document of each\n * declared plugin the site runs and adds the chosen variant's hosts. Core\n * names no vendor and no plugin.\n *\n * The hosts ride the owner-list path in `security-origins.js`, so they are\n * held to the same parse as an owner's own entries: a bare hostname or one\n * leading `*.`, made `https://`. A `wss://` connection to an admitted host is\n * covered by its `https://` source (CSP Level 3 scheme matching).\n */\n\nimport { PLUGIN_SITE_CSP_DECLARED } from './first-party-plugins.generated'\n\n/** The directives a plugin may widen; the enforced, owner-widenable ones. */\nexport const PLUGIN_SITE_CSP_DIRECTIVES = [\n 'connect',\n 'frame',\n 'img',\n 'media',\n 'font',\n] as const\n\nexport type PluginSiteCspDirective = (typeof PLUGIN_SITE_CSP_DIRECTIVES)[number]\n\nexport type PluginSiteCspHosts = Partial<\n Record<PluginSiteCspDirective, readonly string[]>\n>\n\n/** One plugin's declaration, as the generator compiles it. */\nexport interface PluginSiteCspDeclaration {\n pluginId: string\n /** The settings field that must be exactly `true` for anything to be admitted. */\n switchField: string\n /**\n * The settings field whose value names the variant. Absent for a plugin\n * with one set of hosts, which declares a single `default` variant.\n */\n variantField?: string\n /** A settings field that must hold a non-empty string, or nothing loads. */\n requiredField?: string\n /** The hosts each variant needs, by directive. */\n variants: Readonly<Record<string, PluginSiteCspHosts>>\n}\n\n/** Every first-party declaration, compiled from `plugins.config.json`. */\nexport function pluginSiteCspDeclarations(): readonly PluginSiteCspDeclaration[] {\n return PLUGIN_SITE_CSP_DECLARED\n}\n\n/**\n * The hosts one plugin's stored settings admit, or none.\n *\n * Fails CLOSED on every malformed input: a switch that is not exactly `true`,\n * an unknown variant, an empty required field. The settings document is\n * written through the plugin's own route, but a reader of a policy input\n * trusts nothing it did not parse.\n */\nexport function pluginSiteCspHostsFor(\n declaration: PluginSiteCspDeclaration,\n settings: Record<string, unknown> | null | undefined,\n): PluginSiteCspHosts {\n if (!settings || settings[declaration.switchField] !== true) return {}\n if (declaration.requiredField) {\n const required = settings[declaration.requiredField]\n if (typeof required !== 'string' || !required.trim()) return {}\n }\n const variant = declaration.variantField\n ? settings[declaration.variantField]\n : 'default'\n if (typeof variant !== 'string') return {}\n if (!Object.prototype.hasOwnProperty.call(declaration.variants, variant)) {\n return {}\n }\n return declaration.variants[variant] ?? {}\n}\n\n/**\n * The union of what every declared plugin the site runs admits, by\n * directive, de-duplicated and in declaration order.\n *\n * `settingsByPlugin` holds the stored settings document of each plugin the\n * caller read; a plugin missing from `enabledPluginIds` admits nothing even\n * when its settings are present, because a switched-off plugin loads nothing\n * on the page.\n */\nexport function pluginSiteCspHosts(\n enabledPluginIds: readonly string[],\n settingsByPlugin: Readonly<Record<string, Record<string, unknown> | null | undefined>>,\n declared: readonly PluginSiteCspDeclaration[] = PLUGIN_SITE_CSP_DECLARED,\n): Record<PluginSiteCspDirective, string[]> {\n const out = Object.fromEntries(\n PLUGIN_SITE_CSP_DIRECTIVES.map((directive) => [directive, [] as string[]]),\n ) as Record<PluginSiteCspDirective, string[]>\n const enabled = new Set(enabledPluginIds)\n for (const declaration of declared) {\n if (!enabled.has(declaration.pluginId)) continue\n const hosts = pluginSiteCspHostsFor(\n declaration,\n settingsByPlugin[declaration.pluginId],\n )\n for (const directive of PLUGIN_SITE_CSP_DIRECTIVES) {\n for (const host of hosts[directive] ?? []) {\n if (!out[directive].includes(host)) out[directive].push(host)\n }\n }\n }\n return out\n}\n\n/** The declared plugins among a site's enabled set: the settings worth reading. */\nexport function pluginSiteCspPluginsToRead(\n enabledPluginIds: readonly string[],\n declared: readonly PluginSiteCspDeclaration[] = PLUGIN_SITE_CSP_DECLARED,\n): string[] {\n const enabled = new Set(enabledPluginIds)\n return declared\n .map((declaration) => declaration.pluginId)\n .filter((pluginId) => enabled.has(pluginId))\n}\n"],"names":["PLUGIN_SITE_CSP_DECLARED","PLUGIN_SITE_CSP_DIRECTIVES","pluginSiteCspDeclarations","pluginSiteCspHostsFor","declaration","settings","switchField","requiredField","required","trim","variant","variantField","Object","prototype","hasOwnProperty","call","variants","pluginSiteCspHosts","enabledPluginIds","settingsByPlugin","declared","out","fromEntries","map","directive","enabled","Set","has","pluginId","hosts","host","includes","push","pluginSiteCspPluginsToRead","filter"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;;;;;;;CAwBC,GAED,SAASA,wBAAwB,QAAQ,qCAAiC;AAE1E,2EAA2E,GAC3E,OAAO,MAAMC,6BAA6B;IACxC;IACA;IACA;IACA;IACA;CACD,CAAS;AAwBV,wEAAwE,GACxE,OAAO,SAASC;IACd,OAAOF;AACT;AAEA;;;;;;;CAOC,GACD,OAAO,SAASG,sBACdC,WAAqC,EACrCC,QAAoD;QAc7CD;IAZP,IAAI,CAACC,YAAYA,QAAQ,CAACD,YAAYE,WAAW,CAAC,KAAK,MAAM,OAAO,CAAC;IACrE,IAAIF,YAAYG,aAAa,EAAE;QAC7B,MAAMC,WAAWH,QAAQ,CAACD,YAAYG,aAAa,CAAC;QACpD,IAAI,OAAOC,aAAa,YAAY,CAACA,SAASC,IAAI,IAAI,OAAO,CAAC;IAChE;IACA,MAAMC,UAAUN,YAAYO,YAAY,GACpCN,QAAQ,CAACD,YAAYO,YAAY,CAAC,GAClC;IACJ,IAAI,OAAOD,YAAY,UAAU,OAAO,CAAC;IACzC,IAAI,CAACE,OAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACX,YAAYY,QAAQ,EAAEN,UAAU;QACxE,OAAO,CAAC;IACV;IACA,QAAON,gCAAAA,YAAYY,QAAQ,CAACN,QAAQ,YAA7BN,gCAAiC,CAAC;AAC3C;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASa,mBACdC,gBAAmC,EACnCC,gBAAsF,EACtFC,WAAgDpB,wBAAwB;IAExE,MAAMqB,MAAMT,OAAOU,WAAW,CAC5BrB,2BAA2BsB,GAAG,CAAC,CAACC,YAAc;YAACA;YAAW,EAAE;SAAa;IAE3E,MAAMC,UAAU,IAAIC,IAAIR;IACxB,KAAK,MAAMd,eAAegB,SAAU;QAClC,IAAI,CAACK,QAAQE,GAAG,CAACvB,YAAYwB,QAAQ,GAAG;QACxC,MAAMC,QAAQ1B,sBACZC,aACAe,gBAAgB,CAACf,YAAYwB,QAAQ,CAAC;QAExC,KAAK,MAAMJ,aAAavB,2BAA4B;gBAC/B4B;YAAnB,KAAK,MAAMC,SAAQD,mBAAAA,KAAK,CAACL,UAAU,YAAhBK,mBAAoB,EAAE,CAAE;gBACzC,IAAI,CAACR,GAAG,CAACG,UAAU,CAACO,QAAQ,CAACD,OAAOT,GAAG,CAACG,UAAU,CAACQ,IAAI,CAACF;YAC1D;QACF;IACF;IACA,OAAOT;AACT;AAEA,iFAAiF,GACjF,OAAO,SAASY,2BACdf,gBAAmC,EACnCE,WAAgDpB,wBAAwB;IAExE,MAAMyB,UAAU,IAAIC,IAAIR;IACxB,OAAOE,SACJG,GAAG,CAAC,CAACnB,cAAgBA,YAAYwB,QAAQ,EACzCM,MAAM,CAAC,CAACN,WAAaH,QAAQE,GAAG,CAACC;AACtC"}
|
|
@@ -69,6 +69,7 @@ export const AGLYN_HOST_SURFACE = Object.freeze({
|
|
|
69
69
|
formatVariableValue: m7.formatVariableValue,
|
|
70
70
|
functionGlobals: m7.functionGlobals,
|
|
71
71
|
hasBindings: m7.hasBindings,
|
|
72
|
+
isVariableName: m7.isVariableName,
|
|
72
73
|
resolveBindings: m7.resolveBindings,
|
|
73
74
|
resolveNodesBindings: m7.resolveNodesBindings,
|
|
74
75
|
COMPONENT_CATEGORY_ORDER: m8.COMPONENT_CATEGORY_ORDER,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/realm-host-aglyn.generated.ts"],"sourcesContent":["/**\n * GENERATED FILE — do not edit. Regenerate with:\n * node tools/scripts/generate-realm-host-exports.mjs\n *\n * The realm plugin surface of `@aglyn/aglyn` (AGL-3392): what a signed\n * bundle reads from core. Imported only by the lazily loaded host module.\n */\n/* eslint-disable */\n\nimport * as m0 from \"../aglyn\"\nimport * as m1 from \"../app-utils/binding-tokens\"\nimport * as m2 from \"../app-utils/enabled-plugins-context\"\nimport * as m3 from \"../app-utils/functions\"\nimport * as m4 from \"../app-utils/node-identity\"\nimport * as m5 from \"../app-utils/screen-link-context-value\"\nimport * as m6 from \"../app-utils/site-context\"\nimport * as m7 from \"../app-utils/variables\"\nimport * as m8 from \"../foundation/constants/components\"\nimport * as m9 from \"../foundation/constants/shared\"\nimport * as m10 from \"../foundation/definitions/components.types\"\nimport * as m11 from \"./feature-plugins\"\nimport * as m12 from \"../types/nodes\"\n\nexport const AGLYN_HOST_SURFACE: Readonly<Record<string, unknown>> = Object.freeze({\n Aglyn: m0.Aglyn,\n aglyn: m0.aglyn,\n canvas: m0.canvas,\n components: m0.components,\n emitter: m0.emitter,\n logger: m0.logger,\n plugins: m0.plugins,\n FUNCTION_TOKEN_PATTERN: m1.FUNCTION_TOKEN_PATTERN,\n MISSING_BINDING_LABEL: m1.MISSING_BINDING_LABEL,\n NAME_TOKEN_PATTERN: m1.NAME_TOKEN_PATTERN,\n VARIABLE_ID_TOKEN_PATTERN: m1.VARIABLE_ID_TOKEN_PATTERN,\n bindingTokenNeedsDeep: m1.bindingTokenNeedsDeep,\n displayBindingTokens: m1.displayBindingTokens,\n editableBindingTokens: m1.editableBindingTokens,\n formatFunctionIdToken: m1.formatFunctionIdToken,\n formatVariableIdToken: m1.formatVariableIdToken,\n keyById: m1.keyById,\n nodesReferenceBinding: m1.nodesReferenceBinding,\n normalizeBindingTokens: m1.normalizeBindingTokens,\n rewriteBindingTokensDeep: m1.rewriteBindingTokensDeep,\n textReferencesBinding: m1.textReferencesBinding,\n CATEGORY_REQUIRED_CAPABILITY: m2.CATEGORY_REQUIRED_CAPABILITY,\n EnabledPluginsContext: m2.EnabledPluginsContext,\n isCategoryCapabilityEnabled: m2.isCategoryCapabilityEnabled,\n isFromEnabledPlugin: m2.isFromEnabledPlugin,\n isSwitchedOffForRenderedSite: m2.isSwitchedOffForRenderedSite,\n useEnabledPlugins: m2.useEnabledPlugins,\n FUNCTION_BUILTIN_NAMES: m3.FUNCTION_BUILTIN_NAMES,\n FUNCTION_MAX_OPERATIONS: m3.FUNCTION_MAX_OPERATIONS,\n evaluateExpression: m3.evaluateExpression,\n evaluateHostFunction: m3.evaluateHostFunction,\n expressionIdentifiers: m3.expressionIdentifiers,\n expressionSyntaxError: m3.expressionSyntaxError,\n formatFunctionParameterOptions: m3.formatFunctionParameterOptions,\n functionReferencedNames: m3.functionReferencedNames,\n parseFunctionParameterOptions: m3.parseFunctionParameterOptions,\n NodeIdentityContext: m4.NodeIdentityContext,\n useNodeId: m4.useNodeId,\n ScreenLinkContext: m5.ScreenLinkContext,\n PREVIEW_REFUSED_STATUS: m6.PREVIEW_REFUSED_STATUS,\n PREVIEW_WRITE_BLOCKED_EVENT: m6.PREVIEW_WRITE_BLOCKED_EVENT,\n SiteContext: m6.SiteContext,\n isPreviewRefusal: m6.isPreviewRefusal,\n useSite: m6.useSite,\n useSiteFetch: m6.useSiteFetch,\n HOST_VARIABLE_TYPE_LABELS: m7.HOST_VARIABLE_TYPE_LABELS,\n VARIABLE_NAME_PATTERN: m7.VARIABLE_NAME_PATTERN,\n attachFunctionDefinitions: m7.attachFunctionDefinitions,\n formatVariableValue: m7.formatVariableValue,\n functionGlobals: m7.functionGlobals,\n hasBindings: m7.hasBindings,\n resolveBindings: m7.resolveBindings,\n resolveNodesBindings: m7.resolveNodesBindings,\n COMPONENT_CATEGORY_ORDER: m8.COMPONENT_CATEGORY_ORDER,\n ComponentCategory: m8.ComponentCategory,\n REUSABLE_COMPONENT_CATEGORY: m8.REUSABLE_COMPONENT_CATEGORY,\n REUSABLE_EMAIL_BLOCK_CATEGORY: m8.REUSABLE_EMAIL_BLOCK_CATEGORY,\n FEATURE_FLAG: m9.FEATURE_FLAG,\n RICH_TEXT_COMMANDS: m9.RICH_TEXT_COMMANDS,\n FieldComponentType: m10.FieldComponentType,\n FieldValidatorType: m10.FieldValidatorType,\n LinealDirectiveFlag: m10.LinealDirectiveFlag,\n CONSOLE_HOST_GATED_WIDGET_SLOTS: m11.CONSOLE_HOST_GATED_WIDGET_SLOTS,\n CONSOLE_SEARCH_LOAD_POINT: m11.CONSOLE_SEARCH_LOAD_POINT,\n CONSOLE_STAFF_WIDGET_SLOTS: m11.CONSOLE_STAFF_WIDGET_SLOTS,\n CONSOLE_WIDGET_SLOTS: m11.CONSOLE_WIDGET_SLOTS,\n MUI_BUNDLE_ID: m11.MUI_BUNDLE_ID,\n THEME_PRESETS_LOAD_POINT: m11.THEME_PRESETS_LOAD_POINT,\n defineUiFeatureBundle: m11.defineUiFeatureBundle,\n isConsoleHostGatedWidgetSlot: m11.isConsoleHostGatedWidgetSlot,\n isConsoleStaffWidgetSlot: m11.isConsoleStaffWidgetSlot,\n listConsoleExtensions: m11.listConsoleExtensions,\n listConsoleNavItems: m11.listConsoleNavItems,\n listConsoleOrgNavItems: m11.listConsoleOrgNavItems,\n listConsoleProviders: m11.listConsoleProviders,\n listConsolePublicPages: m11.listConsolePublicPages,\n listConsoleSearchSources: m11.listConsoleSearchSources,\n listConsoleStaffPages: m11.listConsoleStaffPages,\n listConsoleThemePresets: m11.listConsoleThemePresets,\n listConsoleWidgets: m11.listConsoleWidgets,\n normalizeConsolePublicPath: m11.normalizeConsolePublicPath,\n registerConsoleExtension: m11.registerConsoleExtension,\n resolveConsoleOrgPluginPage: m11.resolveConsoleOrgPluginPage,\n resolveConsolePluginPage: m11.resolveConsolePluginPage,\n resolveConsolePublicPage: m11.resolveConsolePublicPage,\n resolveConsoleStaffPage: m11.resolveConsoleStaffPage,\n unregisterConsoleExtension: m11.unregisterConsoleExtension,\n NodeType: m12.NodeType,\n})\n"],"names":["m0","m1","m2","m3","m4","m5","m6","m7","m8","m9","m10","m11","m12","AGLYN_HOST_SURFACE","Object","freeze","Aglyn","aglyn","canvas","components","emitter","logger","plugins","FUNCTION_TOKEN_PATTERN","MISSING_BINDING_LABEL","NAME_TOKEN_PATTERN","VARIABLE_ID_TOKEN_PATTERN","bindingTokenNeedsDeep","displayBindingTokens","editableBindingTokens","formatFunctionIdToken","formatVariableIdToken","keyById","nodesReferenceBinding","normalizeBindingTokens","rewriteBindingTokensDeep","textReferencesBinding","CATEGORY_REQUIRED_CAPABILITY","EnabledPluginsContext","isCategoryCapabilityEnabled","isFromEnabledPlugin","isSwitchedOffForRenderedSite","useEnabledPlugins","FUNCTION_BUILTIN_NAMES","FUNCTION_MAX_OPERATIONS","evaluateExpression","evaluateHostFunction","expressionIdentifiers","expressionSyntaxError","formatFunctionParameterOptions","functionReferencedNames","parseFunctionParameterOptions","NodeIdentityContext","useNodeId","ScreenLinkContext","PREVIEW_REFUSED_STATUS","PREVIEW_WRITE_BLOCKED_EVENT","SiteContext","isPreviewRefusal","useSite","useSiteFetch","HOST_VARIABLE_TYPE_LABELS","VARIABLE_NAME_PATTERN","attachFunctionDefinitions","formatVariableValue","functionGlobals","hasBindings","resolveBindings","resolveNodesBindings","COMPONENT_CATEGORY_ORDER","ComponentCategory","REUSABLE_COMPONENT_CATEGORY","REUSABLE_EMAIL_BLOCK_CATEGORY","FEATURE_FLAG","RICH_TEXT_COMMANDS","FieldComponentType","FieldValidatorType","LinealDirectiveFlag","CONSOLE_HOST_GATED_WIDGET_SLOTS","CONSOLE_SEARCH_LOAD_POINT","CONSOLE_STAFF_WIDGET_SLOTS","CONSOLE_WIDGET_SLOTS","MUI_BUNDLE_ID","THEME_PRESETS_LOAD_POINT","defineUiFeatureBundle","isConsoleHostGatedWidgetSlot","isConsoleStaffWidgetSlot","listConsoleExtensions","listConsoleNavItems","listConsoleOrgNavItems","listConsoleProviders","listConsolePublicPages","listConsoleSearchSources","listConsoleStaffPages","listConsoleThemePresets","listConsoleWidgets","normalizeConsolePublicPath","registerConsoleExtension","resolveConsoleOrgPluginPage","resolveConsolePluginPage","resolveConsolePublicPage","resolveConsoleStaffPage","unregisterConsoleExtension","NodeType"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/realm-host-aglyn.generated.ts"],"sourcesContent":["/**\n * GENERATED FILE — do not edit. Regenerate with:\n * node tools/scripts/generate-realm-host-exports.mjs\n *\n * The realm plugin surface of `@aglyn/aglyn` (AGL-3392): what a signed\n * bundle reads from core. Imported only by the lazily loaded host module.\n */\n/* eslint-disable */\n\nimport * as m0 from \"../aglyn\"\nimport * as m1 from \"../app-utils/binding-tokens\"\nimport * as m2 from \"../app-utils/enabled-plugins-context\"\nimport * as m3 from \"../app-utils/functions\"\nimport * as m4 from \"../app-utils/node-identity\"\nimport * as m5 from \"../app-utils/screen-link-context-value\"\nimport * as m6 from \"../app-utils/site-context\"\nimport * as m7 from \"../app-utils/variables\"\nimport * as m8 from \"../foundation/constants/components\"\nimport * as m9 from \"../foundation/constants/shared\"\nimport * as m10 from \"../foundation/definitions/components.types\"\nimport * as m11 from \"./feature-plugins\"\nimport * as m12 from \"../types/nodes\"\n\nexport const AGLYN_HOST_SURFACE: Readonly<Record<string, unknown>> = Object.freeze({\n Aglyn: m0.Aglyn,\n aglyn: m0.aglyn,\n canvas: m0.canvas,\n components: m0.components,\n emitter: m0.emitter,\n logger: m0.logger,\n plugins: m0.plugins,\n FUNCTION_TOKEN_PATTERN: m1.FUNCTION_TOKEN_PATTERN,\n MISSING_BINDING_LABEL: m1.MISSING_BINDING_LABEL,\n NAME_TOKEN_PATTERN: m1.NAME_TOKEN_PATTERN,\n VARIABLE_ID_TOKEN_PATTERN: m1.VARIABLE_ID_TOKEN_PATTERN,\n bindingTokenNeedsDeep: m1.bindingTokenNeedsDeep,\n displayBindingTokens: m1.displayBindingTokens,\n editableBindingTokens: m1.editableBindingTokens,\n formatFunctionIdToken: m1.formatFunctionIdToken,\n formatVariableIdToken: m1.formatVariableIdToken,\n keyById: m1.keyById,\n nodesReferenceBinding: m1.nodesReferenceBinding,\n normalizeBindingTokens: m1.normalizeBindingTokens,\n rewriteBindingTokensDeep: m1.rewriteBindingTokensDeep,\n textReferencesBinding: m1.textReferencesBinding,\n CATEGORY_REQUIRED_CAPABILITY: m2.CATEGORY_REQUIRED_CAPABILITY,\n EnabledPluginsContext: m2.EnabledPluginsContext,\n isCategoryCapabilityEnabled: m2.isCategoryCapabilityEnabled,\n isFromEnabledPlugin: m2.isFromEnabledPlugin,\n isSwitchedOffForRenderedSite: m2.isSwitchedOffForRenderedSite,\n useEnabledPlugins: m2.useEnabledPlugins,\n FUNCTION_BUILTIN_NAMES: m3.FUNCTION_BUILTIN_NAMES,\n FUNCTION_MAX_OPERATIONS: m3.FUNCTION_MAX_OPERATIONS,\n evaluateExpression: m3.evaluateExpression,\n evaluateHostFunction: m3.evaluateHostFunction,\n expressionIdentifiers: m3.expressionIdentifiers,\n expressionSyntaxError: m3.expressionSyntaxError,\n formatFunctionParameterOptions: m3.formatFunctionParameterOptions,\n functionReferencedNames: m3.functionReferencedNames,\n parseFunctionParameterOptions: m3.parseFunctionParameterOptions,\n NodeIdentityContext: m4.NodeIdentityContext,\n useNodeId: m4.useNodeId,\n ScreenLinkContext: m5.ScreenLinkContext,\n PREVIEW_REFUSED_STATUS: m6.PREVIEW_REFUSED_STATUS,\n PREVIEW_WRITE_BLOCKED_EVENT: m6.PREVIEW_WRITE_BLOCKED_EVENT,\n SiteContext: m6.SiteContext,\n isPreviewRefusal: m6.isPreviewRefusal,\n useSite: m6.useSite,\n useSiteFetch: m6.useSiteFetch,\n HOST_VARIABLE_TYPE_LABELS: m7.HOST_VARIABLE_TYPE_LABELS,\n VARIABLE_NAME_PATTERN: m7.VARIABLE_NAME_PATTERN,\n attachFunctionDefinitions: m7.attachFunctionDefinitions,\n formatVariableValue: m7.formatVariableValue,\n functionGlobals: m7.functionGlobals,\n hasBindings: m7.hasBindings,\n isVariableName: m7.isVariableName,\n resolveBindings: m7.resolveBindings,\n resolveNodesBindings: m7.resolveNodesBindings,\n COMPONENT_CATEGORY_ORDER: m8.COMPONENT_CATEGORY_ORDER,\n ComponentCategory: m8.ComponentCategory,\n REUSABLE_COMPONENT_CATEGORY: m8.REUSABLE_COMPONENT_CATEGORY,\n REUSABLE_EMAIL_BLOCK_CATEGORY: m8.REUSABLE_EMAIL_BLOCK_CATEGORY,\n FEATURE_FLAG: m9.FEATURE_FLAG,\n RICH_TEXT_COMMANDS: m9.RICH_TEXT_COMMANDS,\n FieldComponentType: m10.FieldComponentType,\n FieldValidatorType: m10.FieldValidatorType,\n LinealDirectiveFlag: m10.LinealDirectiveFlag,\n CONSOLE_HOST_GATED_WIDGET_SLOTS: m11.CONSOLE_HOST_GATED_WIDGET_SLOTS,\n CONSOLE_SEARCH_LOAD_POINT: m11.CONSOLE_SEARCH_LOAD_POINT,\n CONSOLE_STAFF_WIDGET_SLOTS: m11.CONSOLE_STAFF_WIDGET_SLOTS,\n CONSOLE_WIDGET_SLOTS: m11.CONSOLE_WIDGET_SLOTS,\n MUI_BUNDLE_ID: m11.MUI_BUNDLE_ID,\n THEME_PRESETS_LOAD_POINT: m11.THEME_PRESETS_LOAD_POINT,\n defineUiFeatureBundle: m11.defineUiFeatureBundle,\n isConsoleHostGatedWidgetSlot: m11.isConsoleHostGatedWidgetSlot,\n isConsoleStaffWidgetSlot: m11.isConsoleStaffWidgetSlot,\n listConsoleExtensions: m11.listConsoleExtensions,\n listConsoleNavItems: m11.listConsoleNavItems,\n listConsoleOrgNavItems: m11.listConsoleOrgNavItems,\n listConsoleProviders: m11.listConsoleProviders,\n listConsolePublicPages: m11.listConsolePublicPages,\n listConsoleSearchSources: m11.listConsoleSearchSources,\n listConsoleStaffPages: m11.listConsoleStaffPages,\n listConsoleThemePresets: m11.listConsoleThemePresets,\n listConsoleWidgets: m11.listConsoleWidgets,\n normalizeConsolePublicPath: m11.normalizeConsolePublicPath,\n registerConsoleExtension: m11.registerConsoleExtension,\n resolveConsoleOrgPluginPage: m11.resolveConsoleOrgPluginPage,\n resolveConsolePluginPage: m11.resolveConsolePluginPage,\n resolveConsolePublicPage: m11.resolveConsolePublicPage,\n resolveConsoleStaffPage: m11.resolveConsoleStaffPage,\n unregisterConsoleExtension: m11.unregisterConsoleExtension,\n NodeType: m12.NodeType,\n})\n"],"names":["m0","m1","m2","m3","m4","m5","m6","m7","m8","m9","m10","m11","m12","AGLYN_HOST_SURFACE","Object","freeze","Aglyn","aglyn","canvas","components","emitter","logger","plugins","FUNCTION_TOKEN_PATTERN","MISSING_BINDING_LABEL","NAME_TOKEN_PATTERN","VARIABLE_ID_TOKEN_PATTERN","bindingTokenNeedsDeep","displayBindingTokens","editableBindingTokens","formatFunctionIdToken","formatVariableIdToken","keyById","nodesReferenceBinding","normalizeBindingTokens","rewriteBindingTokensDeep","textReferencesBinding","CATEGORY_REQUIRED_CAPABILITY","EnabledPluginsContext","isCategoryCapabilityEnabled","isFromEnabledPlugin","isSwitchedOffForRenderedSite","useEnabledPlugins","FUNCTION_BUILTIN_NAMES","FUNCTION_MAX_OPERATIONS","evaluateExpression","evaluateHostFunction","expressionIdentifiers","expressionSyntaxError","formatFunctionParameterOptions","functionReferencedNames","parseFunctionParameterOptions","NodeIdentityContext","useNodeId","ScreenLinkContext","PREVIEW_REFUSED_STATUS","PREVIEW_WRITE_BLOCKED_EVENT","SiteContext","isPreviewRefusal","useSite","useSiteFetch","HOST_VARIABLE_TYPE_LABELS","VARIABLE_NAME_PATTERN","attachFunctionDefinitions","formatVariableValue","functionGlobals","hasBindings","isVariableName","resolveBindings","resolveNodesBindings","COMPONENT_CATEGORY_ORDER","ComponentCategory","REUSABLE_COMPONENT_CATEGORY","REUSABLE_EMAIL_BLOCK_CATEGORY","FEATURE_FLAG","RICH_TEXT_COMMANDS","FieldComponentType","FieldValidatorType","LinealDirectiveFlag","CONSOLE_HOST_GATED_WIDGET_SLOTS","CONSOLE_SEARCH_LOAD_POINT","CONSOLE_STAFF_WIDGET_SLOTS","CONSOLE_WIDGET_SLOTS","MUI_BUNDLE_ID","THEME_PRESETS_LOAD_POINT","defineUiFeatureBundle","isConsoleHostGatedWidgetSlot","isConsoleStaffWidgetSlot","listConsoleExtensions","listConsoleNavItems","listConsoleOrgNavItems","listConsoleProviders","listConsolePublicPages","listConsoleSearchSources","listConsoleStaffPages","listConsoleThemePresets","listConsoleWidgets","normalizeConsolePublicPath","registerConsoleExtension","resolveConsoleOrgPluginPage","resolveConsolePluginPage","resolveConsolePublicPage","resolveConsoleStaffPage","unregisterConsoleExtension","NodeType"],"mappings":"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"}
|
|
@@ -86,6 +86,19 @@ export declare function registerSitePageResolver(fn: SitePageResolver): void;
|
|
|
86
86
|
export declare function registerSitePageEnricher(fn: SitePageEnricher): void;
|
|
87
87
|
export declare function resolveSiteRedirect(context: SitePageContext): Promise<SiteRedirectAnswer | undefined>;
|
|
88
88
|
export declare function resolveSitePage(context: SitePageContext): Promise<SitePageAnswer | undefined>;
|
|
89
|
+
/**
|
|
90
|
+
* The page prop an enricher names the vendors it loads on the ANALYTICS
|
|
91
|
+
* grant with (AGL-3698): a feature that loads a third party with the page
|
|
92
|
+
* only for a visitor whose recorded consent grants analytics — a live chat
|
|
93
|
+
* set to load with the page — names it here, so the consent banner the
|
|
94
|
+
* visitor answers names it too. A list of display names, `['Tidio chat']`.
|
|
95
|
+
*
|
|
96
|
+
* The one key enrichers SHARE rather than own: every contribution is joined,
|
|
97
|
+
* not overwritten, so two plugins each naming a vendor both reach the banner.
|
|
98
|
+
*/
|
|
99
|
+
export declare const CONSENT_ANALYTICS_VENDORS_PROP = "consentAnalyticsVendors";
|
|
100
|
+
/** The vendor names a page's props carry under {@link CONSENT_ANALYTICS_VENDORS_PROP}. */
|
|
101
|
+
export declare function consentAnalyticsVendorsOf(props: unknown): string[];
|
|
89
102
|
export interface SitePageEnrichment {
|
|
90
103
|
/** The merged contributions, spread into the page props as before. */
|
|
91
104
|
props: Record<string, unknown>;
|
|
@@ -57,6 +57,27 @@ export async function resolveSitePage(context) {
|
|
|
57
57
|
if (typeof value === 'object') return Object.keys(value).length === 0;
|
|
58
58
|
return false;
|
|
59
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* The page prop an enricher names the vendors it loads on the ANALYTICS
|
|
62
|
+
* grant with (AGL-3698): a feature that loads a third party with the page
|
|
63
|
+
* only for a visitor whose recorded consent grants analytics — a live chat
|
|
64
|
+
* set to load with the page — names it here, so the consent banner the
|
|
65
|
+
* visitor answers names it too. A list of display names, `['Tidio chat']`.
|
|
66
|
+
*
|
|
67
|
+
* The one key enrichers SHARE rather than own: every contribution is joined,
|
|
68
|
+
* not overwritten, so two plugins each naming a vendor both reach the banner.
|
|
69
|
+
*/ export const CONSENT_ANALYTICS_VENDORS_PROP = 'consentAnalyticsVendors';
|
|
70
|
+
/** The vendor names a page's props carry under {@link CONSENT_ANALYTICS_VENDORS_PROP}. */ export function consentAnalyticsVendorsOf(props) {
|
|
71
|
+
const value = props == null ? void 0 : props[CONSENT_ANALYTICS_VENDORS_PROP];
|
|
72
|
+
if (!Array.isArray(value)) return [];
|
|
73
|
+
const out = [];
|
|
74
|
+
for (const entry of value){
|
|
75
|
+
if (typeof entry !== 'string') continue;
|
|
76
|
+
const name = entry.trim().slice(0, 60);
|
|
77
|
+
if (name && !out.includes(name)) out.push(name);
|
|
78
|
+
}
|
|
79
|
+
return out;
|
|
80
|
+
}
|
|
60
81
|
export async function runSitePageEnrichers(context) {
|
|
61
82
|
const merged = {};
|
|
62
83
|
const contributors = new Set();
|
|
@@ -85,7 +106,17 @@ export async function runSitePageEnrichers(context) {
|
|
|
85
106
|
try {
|
|
86
107
|
if (outcome.status === 'rejected') throw outcome.reason;
|
|
87
108
|
const result = outcome.value;
|
|
109
|
+
const vendors = [
|
|
110
|
+
...consentAnalyticsVendorsOf(merged),
|
|
111
|
+
...consentAnalyticsVendorsOf(result)
|
|
112
|
+
];
|
|
88
113
|
Object.assign(merged, result);
|
|
114
|
+
// Joined, not overwritten — see CONSENT_ANALYTICS_VENDORS_PROP.
|
|
115
|
+
if (vendors.length) {
|
|
116
|
+
merged[CONSENT_ANALYTICS_VENDORS_PROP] = consentAnalyticsVendorsOf({
|
|
117
|
+
[CONSENT_ANALYTICS_VENDORS_PROP]: vendors
|
|
118
|
+
});
|
|
119
|
+
}
|
|
89
120
|
// "Contributed" means produced something with content, not merely
|
|
90
121
|
// returned a key. Every marketing enricher returns its full key set on
|
|
91
122
|
// every page — `announcementBar: null`, `experiments: []` — so keying
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/site-page-hooks.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// The leaf module, NOT `api-plugins` — that one is reachable only through the\n// `/server` entry, and importing it from this shared barrel formed a cycle\n// that left the binding missing at runtime (AGL-1289).\nimport { getRegisteringPluginId } from '../app-utils/registering-plugin'\n\n/**\n * Tenant page-composition extension points (AGL-418): plugins hook the\n * site loader (`load-page-data`) from their `/server` entries instead of\n * the app importing plugin domain code. Three kinds, run in this order:\n *\n * 1. REDIRECT RESOLVERS — may answer a request with a redirect before any\n * route resolution (plugins-redirects' rule engine, AGL-155).\n * 2. PAGE RESOLVERS — may fully resolve a path into page props\n * (plugins-commerce's PDP/PLP template composition for /products/* and\n * /collections/*, AGL-299). First non-undefined answer wins.\n * 3. ENRICHERS — contribute extra props onto an already-resolved screen\n * page (plugins-marketing's overlays/experiments/client-automations).\n * Outputs are shallow-merged into the page props in registration order.\n *\n * Handlers run server-side (node runtime) and may use firebase-admin.\n * Errors in enrichers are isolated (a broken plugin never 500s the site);\n * resolver errors propagate because their output IS the page.\n */\n\nexport interface SitePageContext {\n hostId: string\n /** The resolved host doc. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n host: any\n /** The org billing doc (entitlement source); undefined pre-billing. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n org?: any\n /** Request path, '/a/b' form ('/' for the site root). */\n path: string\n slugSegments: string[]\n /**\n * This surface has NO single request path, so `path` above is a\n * placeholder and nothing may be targeted by it (AGL-2511).\n *\n * One surface sets it: the host's designed 404 body. The `not-found`\n * boundary fetches it by host and the response is cached per HOST — one\n * compose a minute however many missing URLs are hit, which is the whole\n * reason a scan of ten thousand dead URLs is cheap. Enriching it per path\n * would key that cache per URL and make the same scan ten thousand\n * composes.\n *\n * An enricher that reads `path` must, when this is set, contribute only\n * what is path-INDEPENDENT and drop the rest — never substitute a plausible\n * path. A site-wide announcement bar is path-independent and shows; an\n * overlay pinned to `/pricing` cannot be evaluated and does not.\n */\n pathUnknown?: boolean\n screenId?: string\n /** The resolved screen doc (enrichers only). */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n screen?: any\n /**\n * The composed node tree for the page — layout applied, versions and\n * references denormalized (enrichers only, AGL-659).\n *\n * An enricher that wants to seed a block's data server-side has to know\n * which blocks are actually on the page and how each one is configured;\n * the screen doc alone does not say, because composition pulls in layout\n * and referenced nodes.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n nodes?: any\n}\n\nexport interface SiteRedirectAnswer {\n destination: string\n statusCode: number\n}\nexport type SiteRedirectResolver = (\n context: SitePageContext,\n) => Promise<SiteRedirectAnswer | undefined> | SiteRedirectAnswer | undefined\n\n/** A fully-composed page (the loader returns it verbatim as `props`). */\nexport type SitePageAnswer = Record<string, unknown>\nexport type SitePageResolver = (\n context: SitePageContext,\n) => Promise<SitePageAnswer | undefined>\n\nexport type SitePageEnricher = (\n context: SitePageContext,\n) => Promise<Record<string, unknown> | undefined>\n\nconst redirectResolvers: SiteRedirectResolver[] = []\nconst pageResolvers: SitePageResolver[] = []\nconst enrichers: SitePageEnricher[] = []\n/**\n * Which plugin registered which enricher (AGL-1289). Recorded from the loader's\n * existing \"currently registering\" marker — the same mechanism that gives\n * `registerPluginApiRoute` its path→plugin ownership — so plugins need no new\n * API and nothing has to be kept in sync by hand.\n */\nconst enricherOwners = new WeakMap<SitePageEnricher, string>()\n\nexport function registerSiteRedirectResolver(fn: SiteRedirectResolver): void {\n redirectResolvers.push(fn)\n}\nexport function registerSitePageResolver(fn: SitePageResolver): void {\n pageResolvers.push(fn)\n}\nexport function registerSitePageEnricher(fn: SitePageEnricher): void {\n enrichers.push(fn)\n const owner = getRegisteringPluginId()\n if (owner) enricherOwners.set(fn, owner)\n}\n\nexport async function resolveSiteRedirect(\n context: SitePageContext,\n): Promise<SiteRedirectAnswer | undefined> {\n for (const resolver of redirectResolvers) {\n const answer = await resolver(context)\n if (answer) return answer\n }\n return undefined\n}\n\nexport async function resolveSitePage(\n context: SitePageContext,\n): Promise<SitePageAnswer | undefined> {\n for (const resolver of pageResolvers) {\n const answer = await resolver(context)\n if (answer) return answer\n }\n return undefined\n}\n\n/** Null/undefined, an empty array or an empty object — nothing to render. */\nfunction isEmptyContribution(value: unknown): boolean {\n if (value == null) return true\n if (Array.isArray(value)) return value.length === 0\n if (typeof value === 'object') return Object.keys(value).length === 0\n return false\n}\n\nexport interface SitePageEnrichment {\n /** The merged contributions, spread into the page props as before. */\n props: Record<string, unknown>\n /** Plugins that returned something non-empty for THIS page. */\n contributors: string[]\n /**\n * True when an enricher produced work but could not be attributed to a\n * plugin — registered outside a plugin's register fn, so the loader's\n * marker was unset. Callers narrowing on `contributors` must treat this as\n * \"cannot narrow\": an unattributed contribution belongs to somebody.\n */\n unattributed: boolean\n}\n\nexport async function runSitePageEnrichers(\n context: SitePageContext,\n): Promise<SitePageEnrichment> {\n const merged: Record<string, unknown> = {}\n const contributors = new Set<string>()\n let unattributed = false\n\n // CONCURRENT, MERGED IN REGISTRATION ORDER (2026-08-26).\n //\n // This was a sequential `for … await`, so every enricher waited on the one\n // before it for no reason: each takes the same immutable `context`, returns\n // its own prop slice, and shares nothing. Production timing put the phase at\n // a flat ~85–120 ms on EVERY render — including pages whose entire loader\n // was 137 ms — because it is a fixed number of round trips, not work that\n // scales with the page.\n //\n // `allSettled` rather than `all`: a broken plugin must drop its slice, never\n // the page, which is the isolation the per-enricher try/catch gave and the\n // plugin docs promise. Results are merged in ARRAY order, which `allSettled`\n // preserves — so two enrichers contributing the same key resolve exactly as\n // they did when the loop was sequential, and `contributors` keeps its\n // insertion order.\n const settled = await Promise.allSettled(\n enrichers.map(async (enricher) => (await enricher(context)) ?? {}),\n )\n\n for (const [index, outcome] of settled.entries()) {\n const enricher = enrichers[index]\n try {\n if (outcome.status === 'rejected') throw outcome.reason\n const result = outcome.value\n Object.assign(merged, result)\n // \"Contributed\" means produced something with content, not merely\n // returned a key. Every marketing enricher returns its full key set on\n // every page — `announcementBar: null`, `experiments: []` — so keying\n // off presence would mark it a contributor everywhere and the\n // attribution would be worth nothing.\n if (Object.values(result).some((value) => !isEmptyContribution(value))) {\n const owner = enricherOwners.get(enricher)\n if (owner) contributors.add(owner)\n else unattributed = true\n }\n } catch (error) {\n // A broken plugin must not take the site down — the page renders\n // without that plugin's contribution.\n console.error('site page enricher failed', error)\n }\n }\n return { props: merged, contributors: [...contributors], unattributed }\n}\n"],"names":["getRegisteringPluginId","redirectResolvers","pageResolvers","enrichers","enricherOwners","WeakMap","registerSiteRedirectResolver","fn","push","registerSitePageResolver","registerSitePageEnricher","owner","set","resolveSiteRedirect","context","resolver","answer","undefined","resolveSitePage","isEmptyContribution","value","Array","isArray","length","Object","keys","runSitePageEnrichers","merged","contributors","Set","unattributed","settled","Promise","allSettled","map","enricher","index","outcome","entries","status","reason","result","assign","values","some","get","add","error","console","props"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,8EAA8E;AAC9E,2EAA2E;AAC3E,uDAAuD;AACvD,SAASA,sBAAsB,QAAQ,qCAAiC;AAoFxE,MAAMC,oBAA4C,EAAE;AACpD,MAAMC,gBAAoC,EAAE;AAC5C,MAAMC,YAAgC,EAAE;AACxC;;;;;CAKC,GACD,MAAMC,iBAAiB,IAAIC;AAE3B,OAAO,SAASC,6BAA6BC,EAAwB;IACnEN,kBAAkBO,IAAI,CAACD;AACzB;AACA,OAAO,SAASE,yBAAyBF,EAAoB;IAC3DL,cAAcM,IAAI,CAACD;AACrB;AACA,OAAO,SAASG,yBAAyBH,EAAoB;IAC3DJ,UAAUK,IAAI,CAACD;IACf,MAAMI,QAAQX;IACd,IAAIW,OAAOP,eAAeQ,GAAG,CAACL,IAAII;AACpC;AAEA,OAAO,eAAeE,oBACpBC,OAAwB;IAExB,KAAK,MAAMC,YAAYd,kBAAmB;QACxC,MAAMe,SAAS,MAAMD,SAASD;QAC9B,IAAIE,QAAQ,OAAOA;IACrB;IACA,OAAOC;AACT;AAEA,OAAO,eAAeC,gBACpBJ,OAAwB;IAExB,KAAK,MAAMC,YAAYb,cAAe;QACpC,MAAMc,SAAS,MAAMD,SAASD;QAC9B,IAAIE,QAAQ,OAAOA;IACrB;IACA,OAAOC;AACT;AAEA,2EAA2E,GAC3E,SAASE,oBAAoBC,KAAc;IACzC,IAAIA,SAAS,MAAM,OAAO;IAC1B,IAAIC,MAAMC,OAAO,CAACF,QAAQ,OAAOA,MAAMG,MAAM,KAAK;IAClD,IAAI,OAAOH,UAAU,UAAU,OAAOI,OAAOC,IAAI,CAACL,OAAOG,MAAM,KAAK;IACpE,OAAO;AACT;AAgBA,OAAO,eAAeG,qBACpBZ,OAAwB;IAExB,MAAMa,SAAkC,CAAC;IACzC,MAAMC,eAAe,IAAIC;IACzB,IAAIC,eAAe;IAEnB,yDAAyD;IACzD,EAAE;IACF,2EAA2E;IAC3E,4EAA4E;IAC5E,6EAA6E;IAC7E,0EAA0E;IAC1E,0EAA0E;IAC1E,wBAAwB;IACxB,EAAE;IACF,6EAA6E;IAC7E,2EAA2E;IAC3E,6EAA6E;IAC7E,4EAA4E;IAC5E,sEAAsE;IACtE,mBAAmB;IACnB,MAAMC,UAAU,MAAMC,QAAQC,UAAU,CACtC9B,UAAU+B,GAAG,CAAC,OAAOC;YAAc;gBAAA,OAAA,MAAMA,SAASrB,oBAAf,OAA4B,CAAC;;IAGlE,KAAK,MAAM,CAACsB,OAAOC,QAAQ,IAAIN,QAAQO,OAAO,GAAI;QAChD,MAAMH,WAAWhC,SAAS,CAACiC,MAAM;QACjC,IAAI;YACF,IAAIC,QAAQE,MAAM,KAAK,YAAY,MAAMF,QAAQG,MAAM;YACvD,MAAMC,SAASJ,QAAQjB,KAAK;YAC5BI,OAAOkB,MAAM,CAACf,QAAQc;YACtB,kEAAkE;YAClE,uEAAuE;YACvE,sEAAsE;YACtE,8DAA8D;YAC9D,sCAAsC;YACtC,IAAIjB,OAAOmB,MAAM,CAACF,QAAQG,IAAI,CAAC,CAACxB,QAAU,CAACD,oBAAoBC,SAAS;gBACtE,MAAMT,QAAQP,eAAeyC,GAAG,CAACV;gBACjC,IAAIxB,OAAOiB,aAAakB,GAAG,CAACnC;qBACvBmB,eAAe;YACtB;QACF,EAAE,OAAOiB,OAAO;YACd,iEAAiE;YACjE,sCAAsC;YACtCC,QAAQD,KAAK,CAAC,6BAA6BA;QAC7C;IACF;IACA,OAAO;QAAEE,OAAOtB;QAAQC,cAAc;eAAIA;SAAa;QAAEE;IAAa;AACxE"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/site-page-hooks.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// The leaf module, NOT `api-plugins` — that one is reachable only through the\n// `/server` entry, and importing it from this shared barrel formed a cycle\n// that left the binding missing at runtime (AGL-1289).\nimport { getRegisteringPluginId } from '../app-utils/registering-plugin'\n\n/**\n * Tenant page-composition extension points (AGL-418): plugins hook the\n * site loader (`load-page-data`) from their `/server` entries instead of\n * the app importing plugin domain code. Three kinds, run in this order:\n *\n * 1. REDIRECT RESOLVERS — may answer a request with a redirect before any\n * route resolution (plugins-redirects' rule engine, AGL-155).\n * 2. PAGE RESOLVERS — may fully resolve a path into page props\n * (plugins-commerce's PDP/PLP template composition for /products/* and\n * /collections/*, AGL-299). First non-undefined answer wins.\n * 3. ENRICHERS — contribute extra props onto an already-resolved screen\n * page (plugins-marketing's overlays/experiments/client-automations).\n * Outputs are shallow-merged into the page props in registration order.\n *\n * Handlers run server-side (node runtime) and may use firebase-admin.\n * Errors in enrichers are isolated (a broken plugin never 500s the site);\n * resolver errors propagate because their output IS the page.\n */\n\nexport interface SitePageContext {\n hostId: string\n /** The resolved host doc. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n host: any\n /** The org billing doc (entitlement source); undefined pre-billing. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n org?: any\n /** Request path, '/a/b' form ('/' for the site root). */\n path: string\n slugSegments: string[]\n /**\n * This surface has NO single request path, so `path` above is a\n * placeholder and nothing may be targeted by it (AGL-2511).\n *\n * One surface sets it: the host's designed 404 body. The `not-found`\n * boundary fetches it by host and the response is cached per HOST — one\n * compose a minute however many missing URLs are hit, which is the whole\n * reason a scan of ten thousand dead URLs is cheap. Enriching it per path\n * would key that cache per URL and make the same scan ten thousand\n * composes.\n *\n * An enricher that reads `path` must, when this is set, contribute only\n * what is path-INDEPENDENT and drop the rest — never substitute a plausible\n * path. A site-wide announcement bar is path-independent and shows; an\n * overlay pinned to `/pricing` cannot be evaluated and does not.\n */\n pathUnknown?: boolean\n screenId?: string\n /** The resolved screen doc (enrichers only). */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n screen?: any\n /**\n * The composed node tree for the page — layout applied, versions and\n * references denormalized (enrichers only, AGL-659).\n *\n * An enricher that wants to seed a block's data server-side has to know\n * which blocks are actually on the page and how each one is configured;\n * the screen doc alone does not say, because composition pulls in layout\n * and referenced nodes.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n nodes?: any\n}\n\nexport interface SiteRedirectAnswer {\n destination: string\n statusCode: number\n}\nexport type SiteRedirectResolver = (\n context: SitePageContext,\n) => Promise<SiteRedirectAnswer | undefined> | SiteRedirectAnswer | undefined\n\n/** A fully-composed page (the loader returns it verbatim as `props`). */\nexport type SitePageAnswer = Record<string, unknown>\nexport type SitePageResolver = (\n context: SitePageContext,\n) => Promise<SitePageAnswer | undefined>\n\nexport type SitePageEnricher = (\n context: SitePageContext,\n) => Promise<Record<string, unknown> | undefined>\n\nconst redirectResolvers: SiteRedirectResolver[] = []\nconst pageResolvers: SitePageResolver[] = []\nconst enrichers: SitePageEnricher[] = []\n/**\n * Which plugin registered which enricher (AGL-1289). Recorded from the loader's\n * existing \"currently registering\" marker — the same mechanism that gives\n * `registerPluginApiRoute` its path→plugin ownership — so plugins need no new\n * API and nothing has to be kept in sync by hand.\n */\nconst enricherOwners = new WeakMap<SitePageEnricher, string>()\n\nexport function registerSiteRedirectResolver(fn: SiteRedirectResolver): void {\n redirectResolvers.push(fn)\n}\nexport function registerSitePageResolver(fn: SitePageResolver): void {\n pageResolvers.push(fn)\n}\nexport function registerSitePageEnricher(fn: SitePageEnricher): void {\n enrichers.push(fn)\n const owner = getRegisteringPluginId()\n if (owner) enricherOwners.set(fn, owner)\n}\n\nexport async function resolveSiteRedirect(\n context: SitePageContext,\n): Promise<SiteRedirectAnswer | undefined> {\n for (const resolver of redirectResolvers) {\n const answer = await resolver(context)\n if (answer) return answer\n }\n return undefined\n}\n\nexport async function resolveSitePage(\n context: SitePageContext,\n): Promise<SitePageAnswer | undefined> {\n for (const resolver of pageResolvers) {\n const answer = await resolver(context)\n if (answer) return answer\n }\n return undefined\n}\n\n/** Null/undefined, an empty array or an empty object — nothing to render. */\nfunction isEmptyContribution(value: unknown): boolean {\n if (value == null) return true\n if (Array.isArray(value)) return value.length === 0\n if (typeof value === 'object') return Object.keys(value).length === 0\n return false\n}\n\n/**\n * The page prop an enricher names the vendors it loads on the ANALYTICS\n * grant with (AGL-3698): a feature that loads a third party with the page\n * only for a visitor whose recorded consent grants analytics — a live chat\n * set to load with the page — names it here, so the consent banner the\n * visitor answers names it too. A list of display names, `['Tidio chat']`.\n *\n * The one key enrichers SHARE rather than own: every contribution is joined,\n * not overwritten, so two plugins each naming a vendor both reach the banner.\n */\nexport const CONSENT_ANALYTICS_VENDORS_PROP = 'consentAnalyticsVendors'\n\n/** The vendor names a page's props carry under {@link CONSENT_ANALYTICS_VENDORS_PROP}. */\nexport function consentAnalyticsVendorsOf(props: unknown): string[] {\n const value = (props as Record<string, unknown> | null | undefined)?.[\n CONSENT_ANALYTICS_VENDORS_PROP\n ]\n if (!Array.isArray(value)) return []\n const out: string[] = []\n for (const entry of value) {\n if (typeof entry !== 'string') continue\n const name = entry.trim().slice(0, 60)\n if (name && !out.includes(name)) out.push(name)\n }\n return out\n}\n\nexport interface SitePageEnrichment {\n /** The merged contributions, spread into the page props as before. */\n props: Record<string, unknown>\n /** Plugins that returned something non-empty for THIS page. */\n contributors: string[]\n /**\n * True when an enricher produced work but could not be attributed to a\n * plugin — registered outside a plugin's register fn, so the loader's\n * marker was unset. Callers narrowing on `contributors` must treat this as\n * \"cannot narrow\": an unattributed contribution belongs to somebody.\n */\n unattributed: boolean\n}\n\nexport async function runSitePageEnrichers(\n context: SitePageContext,\n): Promise<SitePageEnrichment> {\n const merged: Record<string, unknown> = {}\n const contributors = new Set<string>()\n let unattributed = false\n\n // CONCURRENT, MERGED IN REGISTRATION ORDER (2026-08-26).\n //\n // This was a sequential `for … await`, so every enricher waited on the one\n // before it for no reason: each takes the same immutable `context`, returns\n // its own prop slice, and shares nothing. Production timing put the phase at\n // a flat ~85–120 ms on EVERY render — including pages whose entire loader\n // was 137 ms — because it is a fixed number of round trips, not work that\n // scales with the page.\n //\n // `allSettled` rather than `all`: a broken plugin must drop its slice, never\n // the page, which is the isolation the per-enricher try/catch gave and the\n // plugin docs promise. Results are merged in ARRAY order, which `allSettled`\n // preserves — so two enrichers contributing the same key resolve exactly as\n // they did when the loop was sequential, and `contributors` keeps its\n // insertion order.\n const settled = await Promise.allSettled(\n enrichers.map(async (enricher) => (await enricher(context)) ?? {}),\n )\n\n for (const [index, outcome] of settled.entries()) {\n const enricher = enrichers[index]\n try {\n if (outcome.status === 'rejected') throw outcome.reason\n const result = outcome.value\n const vendors = [\n ...consentAnalyticsVendorsOf(merged),\n ...consentAnalyticsVendorsOf(result),\n ]\n Object.assign(merged, result)\n // Joined, not overwritten — see CONSENT_ANALYTICS_VENDORS_PROP.\n if (vendors.length) {\n merged[CONSENT_ANALYTICS_VENDORS_PROP] = consentAnalyticsVendorsOf({\n [CONSENT_ANALYTICS_VENDORS_PROP]: vendors,\n })\n }\n // \"Contributed\" means produced something with content, not merely\n // returned a key. Every marketing enricher returns its full key set on\n // every page — `announcementBar: null`, `experiments: []` — so keying\n // off presence would mark it a contributor everywhere and the\n // attribution would be worth nothing.\n if (Object.values(result).some((value) => !isEmptyContribution(value))) {\n const owner = enricherOwners.get(enricher)\n if (owner) contributors.add(owner)\n else unattributed = true\n }\n } catch (error) {\n // A broken plugin must not take the site down — the page renders\n // without that plugin's contribution.\n console.error('site page enricher failed', error)\n }\n }\n return { props: merged, contributors: [...contributors], unattributed }\n}\n"],"names":["getRegisteringPluginId","redirectResolvers","pageResolvers","enrichers","enricherOwners","WeakMap","registerSiteRedirectResolver","fn","push","registerSitePageResolver","registerSitePageEnricher","owner","set","resolveSiteRedirect","context","resolver","answer","undefined","resolveSitePage","isEmptyContribution","value","Array","isArray","length","Object","keys","CONSENT_ANALYTICS_VENDORS_PROP","consentAnalyticsVendorsOf","props","out","entry","name","trim","slice","includes","runSitePageEnrichers","merged","contributors","Set","unattributed","settled","Promise","allSettled","map","enricher","index","outcome","entries","status","reason","result","vendors","assign","values","some","get","add","error","console"],"mappings":"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"}
|