@tokenoftrust/storefront-runner 2.0.39 → 2.0.41
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/apps/storefront/public/platform/google-measurement/v2/entry.mjs +1 -1
- package/package.json +1 -1
- package/packages/public-runtime/src/integration/csp-compiler.ts +6 -3
- package/packages/public-runtime/src/integration/lifecycle-boot.ts +4 -4
- package/packages/public-runtime/src/integration/native-ga4-sandbox-asset.d.mts +2 -0
- package/packages/public-runtime/src/integration/native-ga4-sandbox-asset.mjs +26 -1
- package/packages/public-runtime/src/integration/native-ga4-sandbox-entry.ts +20 -11
- package/packages/public-runtime/src/integration/native-ga4-sandbox.ts +15 -7
- package/packages/public-runtime/src/integration/native-ga4.ts +7 -2
- package/packages/public-runtime/src/integration/platform-adapters.ts +10 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokenoftrust/storefront-runner",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.41",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE",
|
|
5
5
|
"description": "World-shareable storefront runner: multi-tenant renderer on Astro/Cloudflare. No control plane.",
|
|
6
6
|
"packageManager": "pnpm@11.9.0",
|
|
@@ -63,9 +63,12 @@ export const INTEGRATION_CSP_PROFILES: Readonly<Record<string, CspSourceSet>> =
|
|
|
63
63
|
"connect-src": ["https://cdn.usefathom.com"],
|
|
64
64
|
},
|
|
65
65
|
|
|
66
|
-
// Google code and network authority live only in the
|
|
67
|
-
//
|
|
68
|
-
|
|
66
|
+
// Google code and network authority live only in the isolated-origin sandbox. The
|
|
67
|
+
// hosted preview uses the dedicated tokenoftrust.store sibling. Custom-domain
|
|
68
|
+
// publication aliases are added from the validated canonical host at declaration time.
|
|
69
|
+
"google-measurement": {
|
|
70
|
+
"frame-src": ["https://analytics-frame.tokenoftrust.store"],
|
|
71
|
+
},
|
|
69
72
|
|
|
70
73
|
// Meta pixel (fbevents.js). The loader is served from connect.facebook.net; the
|
|
71
74
|
// pixel's collect endpoint is the facebook.com tracking origin. The tenant
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* constructs bundled platform code with host-owned capabilities. Every other entry goes
|
|
17
17
|
* through the authority-tier loader: it loads ONLY an `elevated-parent` entry (whose
|
|
18
18
|
* honest, review-only contract IS arbitrary parent-document JavaScript) and REFUSES every
|
|
19
|
-
* other tier. A reviewed registry entry may construct its own
|
|
19
|
+
* other tier. A reviewed registry entry may construct its own isolated-origin iframe and
|
|
20
20
|
* private typed MessagePort; arbitrary `sandbox`-tier entry modules remain refused by
|
|
21
21
|
* the parent-realm loader, so their isolation is never silently downgraded. Loading is
|
|
22
22
|
* also consent-gated: the binding reads
|
|
@@ -42,7 +42,7 @@ import type { NavigationCompletedEvent, NavigationKind } from "./events.js";
|
|
|
42
42
|
import { CommerceEventBroker } from "./commerce-broker.js";
|
|
43
43
|
import { validateBrowserEnvironment, BROWSER_ENVIRONMENT_GLOBAL, type BrowserEnvironment } from "./environment.js";
|
|
44
44
|
import { makePlatformAdapterRuntimeLoader } from "./platform-adapter-runtime.js";
|
|
45
|
-
import {
|
|
45
|
+
import { resolveNativeGa4SandboxUrl, type NativeGa4Transport } from "./native-ga4.js";
|
|
46
46
|
import {
|
|
47
47
|
createBrowserNativeGa4SandboxHost,
|
|
48
48
|
createNativeGa4SandboxTransport,
|
|
@@ -118,7 +118,7 @@ export interface BootLifecycleOptions {
|
|
|
118
118
|
fetchCapability?: typeof fetch;
|
|
119
119
|
/** Entry import capability; injectable for tests and non-browser hosts. */
|
|
120
120
|
importModule?: (url: string) => Promise<unknown>;
|
|
121
|
-
/** Reviewed
|
|
121
|
+
/** Reviewed isolated-origin GA4 transport; injectable for DOM-free tests. */
|
|
122
122
|
nativeGa4Transport?: NativeGa4Transport;
|
|
123
123
|
}
|
|
124
124
|
|
|
@@ -326,7 +326,7 @@ export function bootIntegrationLifecycle(
|
|
|
326
326
|
}
|
|
327
327
|
return createNativeGa4SandboxTransport(
|
|
328
328
|
createBrowserNativeGa4SandboxHost(document, MessageChannel),
|
|
329
|
-
|
|
329
|
+
resolveNativeGa4SandboxUrl(win.location.href),
|
|
330
330
|
);
|
|
331
331
|
},
|
|
332
332
|
});
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export const NATIVE_GA4_SANDBOX_ASSET_PATH: "platform/google-measurement/v2/sandbox.html";
|
|
2
2
|
export const NATIVE_GA4_SANDBOX_ASSET_URL: "/platform/google-measurement/v2/sandbox.html";
|
|
3
|
+
export const NATIVE_GA4_SANDBOX_ORIGIN: "https://analytics-frame.tokenoftrust.store";
|
|
4
|
+
export function resolveNativeGa4SandboxUrl(parentHref: string): string;
|
|
@@ -1,3 +1,28 @@
|
|
|
1
|
-
/** Stable provider-neutral artifact path for the reviewed GA4
|
|
1
|
+
/** Stable provider-neutral artifact path for the reviewed GA4 transport frame. */
|
|
2
2
|
export const NATIVE_GA4_SANDBOX_ASSET_PATH = "platform/google-measurement/v2/sandbox.html";
|
|
3
3
|
export const NATIVE_GA4_SANDBOX_ASSET_URL = `/${NATIVE_GA4_SANDBOX_ASSET_PATH}`;
|
|
4
|
+
export const NATIVE_GA4_SANDBOX_ORIGIN = "https://analytics-frame.tokenoftrust.store";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Keep Google tag execution on a real, isolated origin. An opaque sandbox origin makes
|
|
8
|
+
* gtag.js load successfully but silently suppresses every collection request. Production
|
|
9
|
+
* uses a dedicated no-auth hostname for hosted surfaces and the tenant's paired apex/www
|
|
10
|
+
* publication alias for custom domains. Local development uses an analytics.localhost
|
|
11
|
+
* sibling while retaining the current dev-server port.
|
|
12
|
+
*/
|
|
13
|
+
export function resolveNativeGa4SandboxUrl(parentHref) {
|
|
14
|
+
const parent = new URL(parentHref);
|
|
15
|
+
if (parent.hostname === "localhost" || parent.hostname.endsWith(".localhost")) {
|
|
16
|
+
const sandbox = new URL(NATIVE_GA4_SANDBOX_ASSET_URL, parent);
|
|
17
|
+
sandbox.hostname = "analytics.localhost";
|
|
18
|
+
return sandbox.href;
|
|
19
|
+
}
|
|
20
|
+
if (parent.hostname === "tokenoftrust.store" || parent.hostname.endsWith(".tokenoftrust.store")) {
|
|
21
|
+
return new URL(NATIVE_GA4_SANDBOX_ASSET_URL, NATIVE_GA4_SANDBOX_ORIGIN).href;
|
|
22
|
+
}
|
|
23
|
+
const sandbox = new URL(NATIVE_GA4_SANDBOX_ASSET_URL, parent);
|
|
24
|
+
sandbox.hostname = parent.hostname.startsWith("www.")
|
|
25
|
+
? parent.hostname.slice("www.".length)
|
|
26
|
+
: `www.${parent.hostname}`;
|
|
27
|
+
return sandbox.href;
|
|
28
|
+
}
|
|
@@ -64,11 +64,11 @@ export function startNativeGa4Sandbox(win: NativeGa4SandboxRuntimeWindow, doc: D
|
|
|
64
64
|
const bind = (event: MessageEvent): void => {
|
|
65
65
|
try {
|
|
66
66
|
const data = plainRecord(event.data);
|
|
67
|
-
const ownOrigin = new URL(win.location.href).origin;
|
|
68
67
|
if (
|
|
69
|
-
bound || event.source !== win.parent || event.
|
|
70
|
-
!data || !exactKeys(data, ["protocol", "type"]) ||
|
|
68
|
+
bound || event.source !== win.parent || event.ports.length !== 1 ||
|
|
69
|
+
!data || !exactKeys(data, ["protocol", "type", "parentOrigin"]) ||
|
|
71
70
|
data["protocol"] !== NATIVE_GA4_SANDBOX_PROTOCOL || data["type"] !== "bind"
|
|
71
|
+
|| !validOrigin(data["parentOrigin"]) || event.origin !== data["parentOrigin"]
|
|
72
72
|
) return;
|
|
73
73
|
bound = true;
|
|
74
74
|
win.removeEventListener("message", bind);
|
|
@@ -85,9 +85,8 @@ function runPort(port: MessagePort, win: NativeGa4SandboxRuntimeWindow, doc: Doc
|
|
|
85
85
|
let active = false;
|
|
86
86
|
let disposed = false;
|
|
87
87
|
let canonicalOrigin = "";
|
|
88
|
-
let
|
|
88
|
+
let currentDestinations: string[] = [];
|
|
89
89
|
let lastPageLocation = "";
|
|
90
|
-
let generation = 0;
|
|
91
90
|
let tagLoaded = false;
|
|
92
91
|
|
|
93
92
|
const dataLayer: unknown[] = [];
|
|
@@ -99,13 +98,14 @@ function runPort(port: MessagePort, win: NativeGa4SandboxRuntimeWindow, doc: Doc
|
|
|
99
98
|
|
|
100
99
|
const configure = (message: Record<string, unknown>): void => {
|
|
101
100
|
if (
|
|
102
|
-
!exactKeys(message, ["schemaVersion", "type", "destinationIds", "canonicalOrigin"]) ||
|
|
101
|
+
!exactKeys(message, ["schemaVersion", "type", "destinationIds", "canonicalOrigin", "analyticsConsent"]) ||
|
|
103
102
|
message["schemaVersion"] !== 1 || message["type"] !== "configure" ||
|
|
103
|
+
message["analyticsConsent"] !== "granted" ||
|
|
104
104
|
!validIds(message["destinationIds"]) || !validOrigin(message["canonicalOrigin"])
|
|
105
105
|
) return;
|
|
106
106
|
const ids = message["destinationIds"];
|
|
107
107
|
canonicalOrigin = message["canonicalOrigin"];
|
|
108
|
-
|
|
108
|
+
currentDestinations = [...ids];
|
|
109
109
|
lastPageLocation = "";
|
|
110
110
|
active = true;
|
|
111
111
|
|
|
@@ -119,9 +119,13 @@ function runPort(port: MessagePort, win: NativeGa4SandboxRuntimeWindow, doc: Doc
|
|
|
119
119
|
});
|
|
120
120
|
gtag("js", new Date());
|
|
121
121
|
}
|
|
122
|
+
// This sandbox is created and configured only after the parent lifecycle's
|
|
123
|
+
// platform consent gate grants analytics. Mirror that granted state into Google's
|
|
124
|
+
// consent mode; leaving its default denied suppresses the explicit page_view that
|
|
125
|
+
// follows even though the platform correctly admitted it.
|
|
126
|
+
gtag("consent", "update", { analytics_storage: message["analyticsConsent"] });
|
|
122
127
|
for (const id of ids) {
|
|
123
128
|
gtag("config", id, {
|
|
124
|
-
groups: currentGroup,
|
|
125
129
|
send_page_view: false,
|
|
126
130
|
allow_google_signals: false,
|
|
127
131
|
allow_ad_personalization_signals: false,
|
|
@@ -148,7 +152,6 @@ function runPort(port: MessagePort, win: NativeGa4SandboxRuntimeWindow, doc: Doc
|
|
|
148
152
|
const pageLocation = `${canonicalOrigin}${message["path"]}`;
|
|
149
153
|
lastPageLocation = pageLocation;
|
|
150
154
|
const params: Record<string, unknown> = {
|
|
151
|
-
send_to: currentGroup,
|
|
152
155
|
page_location: pageLocation,
|
|
153
156
|
page_path: message["path"],
|
|
154
157
|
};
|
|
@@ -160,7 +163,9 @@ function runPort(port: MessagePort, win: NativeGa4SandboxRuntimeWindow, doc: Doc
|
|
|
160
163
|
if (campaign[key] !== undefined) params[`campaign_${ga4Key}`] = campaign[key];
|
|
161
164
|
}
|
|
162
165
|
}
|
|
163
|
-
|
|
166
|
+
for (const id of currentDestinations) {
|
|
167
|
+
gtag("event", "page_view", { ...params, send_to: id });
|
|
168
|
+
}
|
|
164
169
|
return;
|
|
165
170
|
}
|
|
166
171
|
if (message["type"] === "action") {
|
|
@@ -169,7 +174,9 @@ function runPort(port: MessagePort, win: NativeGa4SandboxRuntimeWindow, doc: Doc
|
|
|
169
174
|
typeof message["name"] !== "string" || !APPROVED_ACTIONS.has(message["name"]) ||
|
|
170
175
|
message["pageLocation"] !== lastPageLocation || !lastPageLocation
|
|
171
176
|
) return;
|
|
172
|
-
|
|
177
|
+
for (const id of currentDestinations) {
|
|
178
|
+
gtag("event", message["name"], { send_to: id, page_location: lastPageLocation });
|
|
179
|
+
}
|
|
173
180
|
}
|
|
174
181
|
};
|
|
175
182
|
|
|
@@ -181,6 +188,7 @@ function runPort(port: MessagePort, win: NativeGa4SandboxRuntimeWindow, doc: Doc
|
|
|
181
188
|
if (message["type"] === "disable") {
|
|
182
189
|
if (exactKeys(message, ["schemaVersion", "type"]) && message["schemaVersion"] === 1) {
|
|
183
190
|
active = false;
|
|
191
|
+
currentDestinations = [];
|
|
184
192
|
lastPageLocation = "";
|
|
185
193
|
}
|
|
186
194
|
return;
|
|
@@ -189,6 +197,7 @@ function runPort(port: MessagePort, win: NativeGa4SandboxRuntimeWindow, doc: Doc
|
|
|
189
197
|
if (exactKeys(message, ["schemaVersion", "type"]) && message["schemaVersion"] === 1) {
|
|
190
198
|
active = false;
|
|
191
199
|
disposed = true;
|
|
200
|
+
currentDestinations = [];
|
|
192
201
|
lastPageLocation = "";
|
|
193
202
|
port.close();
|
|
194
203
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Closed parent/iframe protocol for the reviewed GA4
|
|
1
|
+
/** Closed parent/iframe protocol for the reviewed GA4 isolated-origin sandbox. */
|
|
2
2
|
export const NATIVE_GA4_SANDBOX_PROTOCOL = "tot.ga4-sandbox/1" as const;
|
|
3
3
|
export const NATIVE_GA4_SANDBOX_MAX_DESTINATIONS = 4 as const;
|
|
4
4
|
|
|
@@ -6,6 +6,8 @@ export interface NativeGa4SandboxConfig {
|
|
|
6
6
|
schemaVersion: 1;
|
|
7
7
|
destinationIds: string[];
|
|
8
8
|
canonicalOrigin: string;
|
|
9
|
+
/** The parent may configure GA4 only after the platform consent gate grants analytics. */
|
|
10
|
+
analyticsConsent: "granted";
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
export interface NativeGa4PageViewCommand {
|
|
@@ -52,6 +54,7 @@ export interface NativeGa4SandboxFrame {
|
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
export interface NativeGa4SandboxHost {
|
|
57
|
+
parentOrigin: string;
|
|
55
58
|
createFrame(): NativeGa4SandboxFrame;
|
|
56
59
|
appendFrame(frame: NativeGa4SandboxFrame): void;
|
|
57
60
|
createChannel(): { port1: NativeGa4MessagePort; port2: Transferable };
|
|
@@ -71,6 +74,7 @@ export function createBrowserNativeGa4SandboxHost(
|
|
|
71
74
|
messageChannel: typeof MessageChannel,
|
|
72
75
|
): NativeGa4SandboxHost {
|
|
73
76
|
return {
|
|
77
|
+
parentOrigin: doc.location.origin,
|
|
74
78
|
createFrame: () => doc.createElement("iframe"),
|
|
75
79
|
appendFrame: (frame) => (doc.body ?? doc.documentElement).append(frame as HTMLIFrameElement),
|
|
76
80
|
createChannel: () => new messageChannel(),
|
|
@@ -80,17 +84,21 @@ export function createBrowserNativeGa4SandboxHost(
|
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
/**
|
|
83
|
-
* Mount one hidden same-origin iframe and transfer exactly one MessagePort
|
|
84
|
-
*
|
|
85
|
-
*
|
|
87
|
+
* Mount one hidden same-site, cross-origin iframe and transfer exactly one MessagePort
|
|
88
|
+
* after load. gtag suppresses collection in an opaque third-party frame, so the receiver
|
|
89
|
+
* needs a real same-site origin. The exact origin, iframe window, and one-shot transfer
|
|
86
90
|
* are the authority boundary. No general parent `message` listener is installed.
|
|
87
91
|
*/
|
|
88
92
|
export function createNativeGa4SandboxTransport(
|
|
89
93
|
host: NativeGa4SandboxHost,
|
|
90
94
|
sandboxUrl: string,
|
|
91
95
|
): NativeGa4SandboxTransport {
|
|
96
|
+
const sandboxOrigin = new URL(sandboxUrl, host.parentOrigin).origin;
|
|
97
|
+
if (!host.parentOrigin || sandboxOrigin === host.parentOrigin) {
|
|
98
|
+
throw new Error("ga4_sandbox_origin_not_isolated");
|
|
99
|
+
}
|
|
92
100
|
const frame = host.createFrame();
|
|
93
|
-
frame.setAttribute("sandbox", "allow-scripts");
|
|
101
|
+
frame.setAttribute("sandbox", "allow-scripts allow-same-origin");
|
|
94
102
|
frame.setAttribute("referrerpolicy", "no-referrer");
|
|
95
103
|
frame.setAttribute("aria-hidden", "true");
|
|
96
104
|
frame.setAttribute("tabindex", "-1");
|
|
@@ -119,8 +127,8 @@ export function createNativeGa4SandboxTransport(
|
|
|
119
127
|
port = channel.port1;
|
|
120
128
|
try {
|
|
121
129
|
target.postMessage(
|
|
122
|
-
Object.freeze({ protocol: NATIVE_GA4_SANDBOX_PROTOCOL, type: "bind" }),
|
|
123
|
-
|
|
130
|
+
Object.freeze({ protocol: NATIVE_GA4_SANDBOX_PROTOCOL, type: "bind", parentOrigin: host.parentOrigin }),
|
|
131
|
+
sandboxOrigin,
|
|
124
132
|
[channel.port2],
|
|
125
133
|
);
|
|
126
134
|
} catch {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* The adapter consumes only manually-authored page/action events from the scoped
|
|
5
5
|
* lifecycle subscription. It never loads Google code into the regulated parent.
|
|
6
6
|
* Instead, a closed command crosses one private MessagePort into the reviewed,
|
|
7
|
-
*
|
|
7
|
+
* isolated-origin GA4 sandbox after consent and logical-event dedupe have passed.
|
|
8
8
|
*/
|
|
9
9
|
import type { IntegrationLifecycleContext, IntegrationLifecycleModule, LifecycleUpdateReason } from "./lifecycle.js";
|
|
10
10
|
import type { CommerceEventType } from "./events.js";
|
|
@@ -21,10 +21,14 @@ import type {
|
|
|
21
21
|
NativeGa4SandboxCommand,
|
|
22
22
|
NativeGa4SandboxConfig,
|
|
23
23
|
} from "./native-ga4-sandbox.js";
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
NATIVE_GA4_SANDBOX_ASSET_URL,
|
|
26
|
+
resolveNativeGa4SandboxUrl,
|
|
27
|
+
} from "./native-ga4-sandbox-asset.mjs";
|
|
25
28
|
|
|
26
29
|
export const NATIVE_GA4_ENTRY_URL = "/platform/google-measurement/v2/entry.mjs" as const;
|
|
27
30
|
export const NATIVE_GA4_SANDBOX_URL = NATIVE_GA4_SANDBOX_ASSET_URL;
|
|
31
|
+
export { resolveNativeGa4SandboxUrl };
|
|
28
32
|
export const NATIVE_GA4_ADAPTER_VERSION = "1.0.0" as const;
|
|
29
33
|
export const NATIVE_GA4_RUNTIME_ID = "native-ga4-v2" as const;
|
|
30
34
|
|
|
@@ -223,6 +227,7 @@ export function createNativeGa4Module(options: NativeGa4ModuleOptions): Integrat
|
|
|
223
227
|
schemaVersion: 1 as const,
|
|
224
228
|
destinationIds: [...next.destinationIds],
|
|
225
229
|
canonicalOrigin: next.canonicalOrigin,
|
|
230
|
+
analyticsConsent: "granted" as const,
|
|
226
231
|
};
|
|
227
232
|
runTransportEffect(transport?.configure ? () => transport.configure!(configuration) : undefined);
|
|
228
233
|
} catch {
|
|
@@ -75,7 +75,7 @@ import {
|
|
|
75
75
|
} from "./manifest.js";
|
|
76
76
|
import type { IntegrationCspProfile } from "./csp-compiler.js";
|
|
77
77
|
import { INTEGRATION_CSP_PROFILES } from "./csp-compiler.js";
|
|
78
|
-
import { INTEGRATION_CSP_DIRECTIVES } from "./csp.js";
|
|
78
|
+
import { INTEGRATION_CSP_DIRECTIVES, type CspSourceSet } from "./csp.js";
|
|
79
79
|
import { digestValue } from "./digest.js";
|
|
80
80
|
import type { EffectivePlan } from "./plan.js";
|
|
81
81
|
import { resolveEffectivePlan, type IntegrationDeclarationInput } from "./resolve.js";
|
|
@@ -140,7 +140,7 @@ const AMPLITUDE_PROJECT_KEY = /^(?=[a-f0-9]{32}$)(?=.*[a-f])[a-f0-9]+$/i;
|
|
|
140
140
|
|
|
141
141
|
/**
|
|
142
142
|
* Native Google Analytics 4 measurement. Reviewed parent code sends a closed event
|
|
143
|
-
* protocol to supported gtag.js inside a
|
|
143
|
+
* protocol to supported gtag.js inside a same-site, cross-origin iframe. Google code and network
|
|
144
144
|
* authority stay out of the parent document. It does not run a merchant-owned browser
|
|
145
145
|
* container. Depends on analytics consent (ADR 0023 Q3).
|
|
146
146
|
*/
|
|
@@ -486,6 +486,13 @@ export function buildPlatformAdapterDeclaration(
|
|
|
486
486
|
return blocked("validation-blocked", v.items);
|
|
487
487
|
}
|
|
488
488
|
|
|
489
|
+
const cspSources: CspSourceSet = {};
|
|
490
|
+
if (def.adapterId === GOOGLE_MEASUREMENT_ADAPTER.adapterId) {
|
|
491
|
+
const canonicalHost = envResult.value.canonicalHost.toLowerCase();
|
|
492
|
+
const apexHost = canonicalHost.startsWith("www.") ? canonicalHost.slice(4) : canonicalHost;
|
|
493
|
+
cspSources["frame-src"] = [`https://${apexHost}`, `https://www.${apexHost}`];
|
|
494
|
+
}
|
|
495
|
+
|
|
489
496
|
// Public config: one flat, primitive, PUBLIC id per configured stage. These are
|
|
490
497
|
// public measurement ids (they ship in page HTML), never secret material.
|
|
491
498
|
const publicConfig: Record<string, unknown> = {};
|
|
@@ -530,7 +537,7 @@ export function buildPlatformAdapterDeclaration(
|
|
|
530
537
|
loadWhen: "all-declared-purposes-eligible",
|
|
531
538
|
unknownState: "block",
|
|
532
539
|
},
|
|
533
|
-
csp: { profiles: [def.cspProfile], sources:
|
|
540
|
+
csp: { profiles: [def.cspProfile], sources: cspSources },
|
|
534
541
|
permissions: { events: adapterEventTypes(def), data: [], actions: [], domIntent: "none" },
|
|
535
542
|
performanceBudget: def.performanceBudget,
|
|
536
543
|
},
|