@tokenoftrust/storefront-runner 2.2.26 → 2.2.28

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokenoftrust/storefront-runner",
3
- "version": "2.2.26",
3
+ "version": "2.2.28",
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",
@@ -7,11 +7,14 @@
7
7
  * as non-identifying storefront traffic; it is never derived from a browser,
8
8
  * person, account, persisted client value, network address, or device signal.
9
9
  *
10
- * Channel ATTRIBUTION (UTM tokens + the referrer's origin) is allowed through as
11
- * plain `event_properties`: it is a minimized, campaign-scoped label already
12
- * validated upstream (`events.ts` `validatePageAttribution`), not a visitor or
13
- * device signal, and this adapter re-screens each value for PII before sending
14
- * it regardless. A persistent/session identity is a different thing entirely —
10
+ * Page views also carry channel ATTRIBUTION (UTM tokens + the referrer's origin)
11
+ * and the page LOCATION (`page_hostname` / `page_url`, from the server-stamped
12
+ * canonical host plus the validated path), as plain `event_properties` named to
13
+ * match the merchant's existing website events so their channel rules and page-URL
14
+ * mappings apply unchanged. These are labels about the page and the campaign, not
15
+ * about the visitor: attribution is minimized and validated upstream
16
+ * (`events.ts` `validatePageAttribution`) and re-screened for PII here, and the
17
+ * host never comes from the browser. A persistent/session identity is a different thing entirely —
15
18
  * it stays out, on purpose: `device_id` remains the fixed, non-identifying value
16
19
  * below and there is still no `session_id`, `user_id`, or any persisted client
17
20
  * value anywhere in this file.
@@ -63,16 +66,24 @@ export type AmplitudeAttributionProperties = Partial<{
63
66
  utm_campaign: string;
64
67
  utm_term: string;
65
68
  utm_content: string;
66
- referrer_origin: string;
69
+ /** The referring page's origin only (`https://host`), never its path or query. */
70
+ referrer: string;
67
71
  }>;
68
72
 
73
+ /** Where a page view happened: `page_path` from the event, the host from the trusted environment. */
74
+ export interface AmplitudePageLocationProperties {
75
+ page_path: string;
76
+ page_hostname: string;
77
+ page_url: string;
78
+ }
79
+
69
80
  export interface AmplitudeHttpEvent {
70
81
  event_type: "page_view" | (typeof APPROVED_MARKETING_ACTION_NAMES)[number];
71
82
  device_id: typeof ANONYMOUS_DEVICE_ID;
72
83
  insert_id: string;
73
84
  /** Occurrence time, epoch milliseconds. */
74
85
  time: number;
75
- event_properties: GovernedEventProperties & { page_path?: string } & AmplitudeAttributionProperties;
86
+ event_properties: GovernedEventProperties & Partial<AmplitudePageLocationProperties> & AmplitudeAttributionProperties;
76
87
  }
77
88
 
78
89
  export const AMPLITUDE_DEDUPE_CAPACITY = 512 as const;
@@ -154,7 +165,7 @@ function extractAttributionProperties(data: Record<string, unknown>): AmplitudeA
154
165
  if (isPlainObject(referrer)) {
155
166
  const origin = referrer["origin"];
156
167
  if (typeof origin === "string" && origin.length > 0 && !resemblesManagedAnalyticsPii(origin)) {
157
- out.referrer_origin = origin;
168
+ out.referrer = origin;
158
169
  }
159
170
  }
160
171
 
@@ -223,11 +234,16 @@ export function mapCommerceEventToAmplitude(
223
234
  }
224
235
  const path = event.data["path"];
225
236
  if (!isSafePagePath(path)) return null;
226
- const attribution = extractAttributionProperties(event.data);
237
+ const host = environmentResult.value.canonicalHost;
238
+ const location: AmplitudePageLocationProperties = {
239
+ page_path: path,
240
+ page_hostname: host,
241
+ page_url: `https://${host}${path}`,
242
+ };
227
243
  return {
228
244
  ...base,
229
245
  event_type: "page_view",
230
- event_properties: { ...governed, page_path: path, ...attribution },
246
+ event_properties: { ...governed, ...location, ...extractAttributionProperties(event.data) },
231
247
  };
232
248
  }
233
249
 
@@ -624,11 +624,15 @@ export const LARGE_PUBLIC_ASSET_IDEA_ID = "fb-1790956035713-snpovm";
624
624
  export const LARGE_PUBLIC_ASSET_FIX =
625
625
  `storing it under public/ will work, but every publish re-copies it into R2 and ` +
626
626
  `your Gitea repo keeps it forever — on a tenant with many of these, expect ` +
627
- `slower publishes and slower clones over time. Today, host it on a shared drive ` +
628
- `you control and tell us the URL so we can pull it in and serve it from R2 directly, ` +
629
- `rather than committing it to the tenant repo. We're tracking a built-in fix ` +
630
- `(automatic relocation to deduped storage, idea ${LARGE_PUBLIC_ASSET_IDEA_ID}) — ` +
631
- `vote for it if you'd like this handled for you sooner.`;
627
+ `slower publishes and slower clones over time. If this is an image, you don't ` +
628
+ `need to do anything extra: reference its public URL directly in your <img>/ ` +
629
+ `background-image/srcset and our capture step pulls it into CDN storage ` +
630
+ `automatically on publish. For a PDF or other non-image file, that auto-capture ` +
631
+ `doesn't apply yet — linking straight to an external URL avoids the repo-size ` +
632
+ `problem entirely, or send us the URL and we'll pull it in manually. We're ` +
633
+ `tracking a built-in fix to auto-relocate large files of any type the same way ` +
634
+ `images already work (idea ${LARGE_PUBLIC_ASSET_IDEA_ID}) — vote for it if ` +
635
+ `you'd like this handled for you sooner.`;
632
636
 
633
637
  /**
634
638
  * The advisory rules LOUD enough to call out by NAME at `tot validate` / `tot