@tokenoftrust/storefront-runner 2.0.30 → 2.0.31
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/astro.config.mjs +2 -0
- package/apps/storefront/integrations/google-measurement-sandbox-asset.mjs +97 -0
- package/apps/storefront/public/platform/google-measurement/v2/entry.mjs +13 -0
- package/package.json +1 -1
- package/packages/public-runtime/package.json +2 -1
- package/packages/public-runtime/src/integration/csp-compiler.ts +3 -6
- package/packages/public-runtime/src/integration/events.ts +5 -5
- package/packages/public-runtime/src/integration/index.ts +1 -0
- package/packages/public-runtime/src/integration/lifecycle-boot.ts +28 -14
- package/packages/public-runtime/src/integration/managed-analytics-value-safety.ts +9 -0
- 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 +3 -0
- package/packages/public-runtime/src/integration/native-ga4-sandbox-entry.ts +207 -0
- package/packages/public-runtime/src/integration/native-ga4-sandbox.ts +168 -0
- package/packages/public-runtime/src/integration/native-ga4.ts +111 -215
- package/packages/public-runtime/src/integration/platform-adapter-runtime.ts +18 -9
- package/packages/public-runtime/src/integration/platform-adapters.ts +20 -9
- package/apps/storefront/public/platform/google-measurement/v1/entry.mjs +0 -19
|
@@ -17,11 +17,11 @@ import {
|
|
|
17
17
|
createAmplitudeLifecycleModule,
|
|
18
18
|
} from "./native-amplitude.js";
|
|
19
19
|
import {
|
|
20
|
-
createNativeGa4FetchTransport,
|
|
21
20
|
createNativeGa4Module,
|
|
22
21
|
NATIVE_GA4_ADAPTER_VERSION,
|
|
23
22
|
NATIVE_GA4_ENTRY_URL,
|
|
24
23
|
NATIVE_GA4_RUNTIME_ID,
|
|
24
|
+
type NativeGa4Transport,
|
|
25
25
|
} from "./native-ga4.js";
|
|
26
26
|
import { AMPLITUDE_HTTP_ADAPTER, GOOGLE_MEASUREMENT_ADAPTER } from "./platform-adapters.js";
|
|
27
27
|
|
|
@@ -38,7 +38,8 @@ export interface PlatformAdapterEntryMarker {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
export interface PlatformAdapterRuntimeHost {
|
|
41
|
-
fetch
|
|
41
|
+
fetch?: typeof fetch;
|
|
42
|
+
nativeGa4Transport?: NativeGa4Transport;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
export interface PlatformAdapterRuntimeRegistration {
|
|
@@ -70,19 +71,23 @@ const AMPLITUDE_MARKER: PlatformAdapterEntryMarker = Object.freeze({
|
|
|
70
71
|
export const PLATFORM_ADAPTER_RUNTIME_REGISTRY: readonly PlatformAdapterRuntimeRegistration[] = Object.freeze([
|
|
71
72
|
Object.freeze({
|
|
72
73
|
marker: GA4_MARKER,
|
|
73
|
-
create: ({
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
create: ({ nativeGa4Transport }: PlatformAdapterRuntimeHost) => {
|
|
75
|
+
if (!nativeGa4Transport) throw new Error("platform_adapter_ga4_sandbox_unavailable");
|
|
76
|
+
return createNativeGa4Module({ transport: nativeGa4Transport });
|
|
77
|
+
},
|
|
76
78
|
}),
|
|
77
79
|
Object.freeze({
|
|
78
80
|
marker: AMPLITUDE_MARKER,
|
|
79
|
-
create: ({ fetch: fetchCapability }: PlatformAdapterRuntimeHost) =>
|
|
80
|
-
|
|
81
|
+
create: ({ fetch: fetchCapability }: PlatformAdapterRuntimeHost) => {
|
|
82
|
+
if (!fetchCapability) throw new Error("platform_adapter_fetch_unavailable");
|
|
83
|
+
return createAmplitudeLifecycleModule({ fetch: fetchCapability });
|
|
84
|
+
},
|
|
81
85
|
}),
|
|
82
86
|
]);
|
|
83
87
|
|
|
84
88
|
export interface PlatformAdapterRuntimeLoaderOptions {
|
|
85
89
|
fetchCapability?: typeof fetch;
|
|
90
|
+
nativeGa4Transport?: () => NativeGa4Transport;
|
|
86
91
|
importModule?: (url: string) => Promise<unknown>;
|
|
87
92
|
fallback: IntegrationModuleLoader;
|
|
88
93
|
}
|
|
@@ -137,10 +142,14 @@ export function makePlatformAdapterRuntimeLoader(
|
|
|
137
142
|
if (!platformClaim(integration)) return options.fallback(integration);
|
|
138
143
|
const registration = registrationFor(integration);
|
|
139
144
|
if (!registration) throw new Error("platform_adapter_entry_unreviewed");
|
|
140
|
-
if (!options.fetchCapability) throw new Error("platform_adapter_fetch_unavailable");
|
|
141
145
|
const namespace = await importModule(registration.marker.entry.url);
|
|
142
146
|
const marker = (namespace as { platformAdapterEntry?: unknown })?.platformAdapterEntry;
|
|
143
147
|
if (!markerEquals(registration.marker, marker)) throw new Error("platform_adapter_entry_invalid");
|
|
144
|
-
return registration.create({
|
|
148
|
+
return registration.create({
|
|
149
|
+
fetch: options.fetchCapability,
|
|
150
|
+
nativeGa4Transport: registration.marker.appId === GOOGLE_MEASUREMENT_ADAPTER.adapterId
|
|
151
|
+
? options.nativeGa4Transport?.()
|
|
152
|
+
: undefined,
|
|
153
|
+
});
|
|
145
154
|
};
|
|
146
155
|
}
|
|
@@ -107,6 +107,8 @@ export interface PlatformAdapterDefinition {
|
|
|
107
107
|
supportUrl: string;
|
|
108
108
|
/** The ONE platform-owned entry module every instance of this adapter points at. */
|
|
109
109
|
entryAsset: string;
|
|
110
|
+
/** Vendor origins used inside the reviewed adapter, independent of parent CSP effects. */
|
|
111
|
+
collectionOrigins: readonly string[];
|
|
110
112
|
/** The curated CSP profile slug this adapter's origins come from. */
|
|
111
113
|
cspProfile: IntegrationCspProfile;
|
|
112
114
|
/** The consent purpose the destination depends on (the broker enforces it). */
|
|
@@ -137,10 +139,10 @@ const META_PIXEL_ID = /^\d{10,20}$/;
|
|
|
137
139
|
const AMPLITUDE_PROJECT_KEY = /^(?=[a-f0-9]{32}$)(?=.*[a-f])[a-f0-9]+$/i;
|
|
138
140
|
|
|
139
141
|
/**
|
|
140
|
-
* Native Google Analytics 4 measurement.
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
142
|
+
* Native Google Analytics 4 measurement. Reviewed parent code sends a closed event
|
|
143
|
+
* protocol to supported gtag.js inside a null-origin iframe. Google code and network
|
|
144
|
+
* authority stay out of the parent document. It does not run a merchant-owned browser
|
|
145
|
+
* container. Depends on analytics consent (ADR 0023 Q3).
|
|
144
146
|
*/
|
|
145
147
|
export const GOOGLE_MEASUREMENT_ADAPTER: PlatformAdapterDefinition = Object.freeze({
|
|
146
148
|
adapterId: "platform.google-measurement",
|
|
@@ -148,20 +150,24 @@ export const GOOGLE_MEASUREMENT_ADAPTER: PlatformAdapterDefinition = Object.free
|
|
|
148
150
|
purpose: "Native Google Analytics 4 measurement.",
|
|
149
151
|
publisher: "Storefront platform adapter",
|
|
150
152
|
supportUrl: "https://developers.google.com/analytics/devguides/collection/ga4",
|
|
151
|
-
entryAsset: "/platform/google-measurement/
|
|
153
|
+
entryAsset: "/platform/google-measurement/v2/entry.mjs",
|
|
154
|
+
collectionOrigins: Object.freeze([
|
|
155
|
+
"https://www.googletagmanager.com",
|
|
156
|
+
"https://www.google-analytics.com",
|
|
157
|
+
"https://analytics.google.com",
|
|
158
|
+
]),
|
|
152
159
|
cspProfile: "google-measurement",
|
|
153
160
|
consentPurpose: "analytics",
|
|
154
161
|
phase: "document.deferred",
|
|
155
162
|
performanceBudget: Object.freeze({
|
|
156
163
|
maxTransferredBytes: 90_000,
|
|
157
|
-
maxAdditionalRequests:
|
|
164
|
+
maxAdditionalRequests: 5,
|
|
158
165
|
maxMainThreadMilliseconds: 120,
|
|
159
166
|
mustBeAsyncOrDeferred: true,
|
|
160
167
|
}),
|
|
161
168
|
idLabel: "GA4 measurement id (e.g. G-XXXXXXX)",
|
|
162
|
-
//
|
|
163
|
-
//
|
|
164
|
-
// budget's own `maxAdditionalRequests`.
|
|
169
|
+
// One gtag.js loader plus one event request per configured property (primary + rollups).
|
|
170
|
+
// The four-destination ceiling therefore consumes the five-request budget exactly.
|
|
165
171
|
maxDestinationsPerStage: 4,
|
|
166
172
|
validateId: (id: string) => GOOGLE_MEASUREMENT_ID.test(id),
|
|
167
173
|
eventMap: Object.freeze({
|
|
@@ -183,6 +189,7 @@ export const META_PIXEL_ADAPTER: PlatformAdapterDefinition = Object.freeze({
|
|
|
183
189
|
publisher: "Storefront platform adapter",
|
|
184
190
|
supportUrl: "https://developers.facebook.com/docs/meta-pixel",
|
|
185
191
|
entryAsset: "platform/meta-pixel/v1/entry.mjs",
|
|
192
|
+
collectionOrigins: Object.freeze(["https://connect.facebook.net", "https://www.facebook.com"]),
|
|
186
193
|
cspProfile: "meta-pixel",
|
|
187
194
|
consentPurpose: "marketing",
|
|
188
195
|
phase: "document.deferred",
|
|
@@ -217,6 +224,7 @@ export const AMPLITUDE_HTTP_ADAPTER: PlatformAdapterDefinition = Object.freeze({
|
|
|
217
224
|
publisher: "Storefront platform adapter",
|
|
218
225
|
supportUrl: "https://amplitude.com/docs/apis/analytics/http-v2",
|
|
219
226
|
entryAsset: "/platform/amplitude-http/v1/entry.mjs",
|
|
227
|
+
collectionOrigins: Object.freeze(["https://api2.amplitude.com"]),
|
|
220
228
|
cspProfile: "amplitude-http",
|
|
221
229
|
consentPurpose: "analytics",
|
|
222
230
|
phase: "document.deferred",
|
|
@@ -347,6 +355,8 @@ export interface PlatformAdapterCard {
|
|
|
347
355
|
performanceBudget: PerformanceBudget;
|
|
348
356
|
/** The exact CSP origins this adapter contributes (flattened, sorted). */
|
|
349
357
|
cspOrigins: string[];
|
|
358
|
+
/** Vendor collection/loading origins, even when isolated from the parent CSP. */
|
|
359
|
+
collectionOrigins: string[];
|
|
350
360
|
/** The semantic events this adapter measures. */
|
|
351
361
|
eventTypes: CommerceEventType[];
|
|
352
362
|
/** Which stages have a configured destination id, and whether each is conversion-live. */
|
|
@@ -415,6 +425,7 @@ export function buildPlatformAdapterCard(
|
|
|
415
425
|
consentPurposes: [def.consentPurpose],
|
|
416
426
|
performanceBudget: def.performanceBudget,
|
|
417
427
|
cspOrigins: profileOrigins(def.cspProfile),
|
|
428
|
+
collectionOrigins: [...def.collectionOrigins].sort(),
|
|
418
429
|
eventTypes: adapterEventTypes(def),
|
|
419
430
|
destinationBehavior: stageBehavior(ids),
|
|
420
431
|
};
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Reviewed same-origin marker for the native GA4 platform adapter.
|
|
3
|
-
*
|
|
4
|
-
* The lifecycle host imports this exact-version asset, verifies every field, then
|
|
5
|
-
* constructs the adapter from its bundled @tot/public-runtime implementation with
|
|
6
|
-
* host-injected fetch. This file executes no vendor code and reads no browser global.
|
|
7
|
-
*/
|
|
8
|
-
export const platformAdapterEntry = Object.freeze({
|
|
9
|
-
schemaVersion: 1,
|
|
10
|
-
origin: "platform-adapter",
|
|
11
|
-
executionTier: "platform-adapter",
|
|
12
|
-
appId: "platform.google-measurement",
|
|
13
|
-
version: "1.0.0",
|
|
14
|
-
entry: Object.freeze({
|
|
15
|
-
url: "/platform/google-measurement/v1/entry.mjs",
|
|
16
|
-
format: "module",
|
|
17
|
-
}),
|
|
18
|
-
runtime: "native-ga4-v1",
|
|
19
|
-
});
|