platform-types 1.10.794 → 1.10.795

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/dist/cjs/index.js CHANGED
@@ -110,6 +110,7 @@ __exportStar(require("./storefrontTheme.js"), exports);
110
110
  __exportStar(require("./storeNetwork.js"), exports);
111
111
  __exportStar(require("./storefrontAssets.js"), exports);
112
112
  __exportStar(require("./storefrontEvent.js"), exports);
113
+ __exportStar(require("./storefrontIngest.js"), exports);
113
114
  __exportStar(require("./storefrontSeo.js"), exports);
114
115
  __exportStar(require("./storefrontProductMeta.js"), exports);
115
116
  __exportStar(require("./storefrontWebLiteralKeys.js"), exports);
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ /**
3
+ * Guest storefront telemetry ingest — the HTTP route a shopper who never signs
4
+ * in sends first-party storefront events through (the signed-in shopper keeps
5
+ * the WebSocket `logs` action).
6
+ *
7
+ * Web (public, bound origin only): `POST /events` (a batch) and
8
+ * `POST /events/consent` (an analytics-consent withdrawal for one journey).
9
+ *
10
+ * The tenant is the request's bound Origin (a slug host or a verified custom
11
+ * domain), never `x-store` and never an event's `tenant_store_id`. Nothing a
12
+ * guest sends can claim to be a customer: `customer_id` is not part of a guest
13
+ * event, and one that carries it is dropped and counted.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.STOREFRONT_INGEST_LIMITS = exports.STOREFRONT_INGEST_ERROR_CODES = void 0;
17
+ /**
18
+ * The refusals of the guest ingest routes.
19
+ *
20
+ * - EVENTS_TENANT_UNRESOLVED (403): the request's Origin is bound to no shop.
21
+ * Checked before the body is read; nothing is stored.
22
+ * - EVENTS_BATCH_TOO_LARGE (413): the raw body is over
23
+ * {@link STOREFRONT_INGEST_LIMITS.maxBodyBytes} bytes, or `events` holds more
24
+ * than {@link STOREFRONT_INGEST_LIMITS.maxEvents} entries. Nothing is stored.
25
+ * - VALIDATION_FAILED (400): the request as a WHOLE is malformed — not JSON, not
26
+ * the envelope shape, or (withdrawal) `anonymousId` not a UUID. A single event
27
+ * that does not validate is never a 400: it is a counted drop in `dropped`.
28
+ * - EVENTS_RATE_LIMITED (429): the source's budget is spent. Nothing is stored;
29
+ * retry later.
30
+ */
31
+ exports.STOREFRONT_INGEST_ERROR_CODES = [
32
+ 'EVENTS_TENANT_UNRESOLVED',
33
+ 'EVENTS_BATCH_TOO_LARGE',
34
+ 'VALIDATION_FAILED',
35
+ 'EVENTS_RATE_LIMITED',
36
+ ];
37
+ /** Bounds of `POST /events`, enforced before any event is read. */
38
+ exports.STOREFRONT_INGEST_LIMITS = {
39
+ /** The raw request body ceiling, in UTF-8 bytes, measured before parsing. */
40
+ maxBodyBytes: 32 * 1024,
41
+ /** At most this many events per request. */
42
+ maxEvents: 25,
43
+ /** The longest `analyticsConsent.version` accepted; a longer one never stores an event. */
44
+ consentVersionMaxLength: 64,
45
+ };
package/dist/index.d.ts CHANGED
@@ -86,6 +86,7 @@ export * from './storefrontTheme.ts';
86
86
  export * from './storeNetwork.ts';
87
87
  export * from './storefrontAssets.ts';
88
88
  export * from './storefrontEvent.ts';
89
+ export * from './storefrontIngest.ts';
89
90
  export * from './storefrontSeo.ts';
90
91
  export * from './storefrontProductMeta.ts';
91
92
  export * from './storefrontWebLiteralKeys.ts';
package/dist/index.js CHANGED
@@ -94,6 +94,7 @@ export * from "./storefrontTheme.js";
94
94
  export * from "./storeNetwork.js";
95
95
  export * from "./storefrontAssets.js";
96
96
  export * from "./storefrontEvent.js";
97
+ export * from "./storefrontIngest.js";
97
98
  export * from "./storefrontSeo.js";
98
99
  export * from "./storefrontProductMeta.js";
99
100
  export * from "./storefrontWebLiteralKeys.js";
@@ -10,6 +10,13 @@ declare global {
10
10
  screen_type: 'desktop' | 'mobile';
11
11
  app_version: number;
12
12
  ts: string;
13
+ /**
14
+ * Server-stamped on a stored guest event (the unauthenticated `POST /events`
15
+ * ingest) from the request's analytics-consent block, so a later policy change
16
+ * can scope erasure. Never read from a client event: the validators drop it.
17
+ * Distinct from the signup contract's `consentVersion`.
18
+ */
19
+ analyticsConsentVersion?: string;
13
20
  }
14
21
  interface ProductViewedEvent extends StorefrontEventBase {
15
22
  event: 'Product Viewed';
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Guest storefront telemetry ingest — the HTTP route a shopper who never signs
3
+ * in sends first-party storefront events through (the signed-in shopper keeps
4
+ * the WebSocket `logs` action).
5
+ *
6
+ * Web (public, bound origin only): `POST /events` (a batch) and
7
+ * `POST /events/consent` (an analytics-consent withdrawal for one journey).
8
+ *
9
+ * The tenant is the request's bound Origin (a slug host or a verified custom
10
+ * domain), never `x-store` and never an event's `tenant_store_id`. Nothing a
11
+ * guest sends can claim to be a customer: `customer_id` is not part of a guest
12
+ * event, and one that carries it is dropped and counted.
13
+ */
14
+ /**
15
+ * The refusals of the guest ingest routes.
16
+ *
17
+ * - EVENTS_TENANT_UNRESOLVED (403): the request's Origin is bound to no shop.
18
+ * Checked before the body is read; nothing is stored.
19
+ * - EVENTS_BATCH_TOO_LARGE (413): the raw body is over
20
+ * {@link STOREFRONT_INGEST_LIMITS.maxBodyBytes} bytes, or `events` holds more
21
+ * than {@link STOREFRONT_INGEST_LIMITS.maxEvents} entries. Nothing is stored.
22
+ * - VALIDATION_FAILED (400): the request as a WHOLE is malformed — not JSON, not
23
+ * the envelope shape, or (withdrawal) `anonymousId` not a UUID. A single event
24
+ * that does not validate is never a 400: it is a counted drop in `dropped`.
25
+ * - EVENTS_RATE_LIMITED (429): the source's budget is spent. Nothing is stored;
26
+ * retry later.
27
+ */
28
+ export declare const STOREFRONT_INGEST_ERROR_CODES: readonly ["EVENTS_TENANT_UNRESOLVED", "EVENTS_BATCH_TOO_LARGE", "VALIDATION_FAILED", "EVENTS_RATE_LIMITED"];
29
+ /** Bounds of `POST /events`, enforced before any event is read. */
30
+ export declare const STOREFRONT_INGEST_LIMITS: {
31
+ /** The raw request body ceiling, in UTF-8 bytes, measured before parsing. */
32
+ readonly maxBodyBytes: number;
33
+ /** At most this many events per request. */
34
+ readonly maxEvents: 25;
35
+ /** The longest `analyticsConsent.version` accepted; a longer one never stores an event. */
36
+ readonly consentVersionMaxLength: 64;
37
+ };
38
+ declare global {
39
+ type StorefrontIngestErrorCode = (typeof STOREFRONT_INGEST_ERROR_CODES)[number];
40
+ /** The storefront event variants a guest may send. Any other variant is a counted drop. */
41
+ type GuestStorefrontEventName = 'Product Viewed' | 'Product List Viewed' | 'Cart Item Added' | 'Cart Item Removed' | 'Cart Viewed' | 'Search Submitted' | 'Checkout Started' | 'Checkout Step Completed';
42
+ /**
43
+ * A guest event: an allowed variant of `StorefrontEvent` with no
44
+ * `customer_id` (and no server-stamped field). Distributive, so each variant
45
+ * keeps its own discriminated shape.
46
+ */
47
+ type GuestStorefrontEvent = Extract<StorefrontEvent, {
48
+ event: GuestStorefrontEventName;
49
+ }> extends infer Variant ? Variant extends unknown ? Omit<Variant, 'customer_id' | 'audit' | 'analyticsConsentVersion'> : never : never;
50
+ /**
51
+ * The analytics-consent state the storefront holds for this shopper, separate
52
+ * from advertising consent. `version` names the consent text the shopper saw;
53
+ * a persisted event records it as `analyticsConsentVersion`.
54
+ */
55
+ interface StorefrontAnalyticsConsent {
56
+ analytics: 'granted' | 'denied';
57
+ version: string;
58
+ }
59
+ /**
60
+ * Web `POST /events` body. At most 25 events and 32 KiB. With
61
+ * `analytics: 'denied'` no per-journey event is stored — only an aggregate
62
+ * count with no `anonymous_id`. Under the platform's opt-in mode (the
63
+ * default) only `'granted'` stores events, so an absent block stores none;
64
+ * under opt-out everything but `'denied'` stores, an absent block included.
65
+ */
66
+ interface StorefrontEventIngestRequest {
67
+ events: GuestStorefrontEvent[];
68
+ analyticsConsent?: StorefrontAnalyticsConsent;
69
+ }
70
+ /**
71
+ * Web `POST /events` 202 `data`: counts only, never an echo of the batch.
72
+ * `accepted` events were stored (or were already stored under the same
73
+ * `event_id`); `dropped` ones were refused one by one — invalid, a
74
+ * customer-only variant, carrying `customer_id`, another tenant, outside the
75
+ * time window, fenced, not consented, or over a budget.
76
+ */
77
+ interface StorefrontEventIngestResponse {
78
+ accepted: number;
79
+ dropped: number;
80
+ }
81
+ /**
82
+ * Web `POST /events/consent` body: withdraw analytics consent for one
83
+ * journey. Every later event of that `anonymousId` is refused, however late
84
+ * it arrives. Nothing is erased: its earlier events expire by retention
85
+ * (30-day hot rows, the 390-day `guest/` archive). Answers 202 with no data.
86
+ */
87
+ interface StorefrontConsentWithdrawalRequest {
88
+ /** The journey's `anonymous_id` (a UUID). */
89
+ anonymousId: string;
90
+ analytics: 'denied';
91
+ }
92
+ }
93
+ export {};
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Guest storefront telemetry ingest — the HTTP route a shopper who never signs
3
+ * in sends first-party storefront events through (the signed-in shopper keeps
4
+ * the WebSocket `logs` action).
5
+ *
6
+ * Web (public, bound origin only): `POST /events` (a batch) and
7
+ * `POST /events/consent` (an analytics-consent withdrawal for one journey).
8
+ *
9
+ * The tenant is the request's bound Origin (a slug host or a verified custom
10
+ * domain), never `x-store` and never an event's `tenant_store_id`. Nothing a
11
+ * guest sends can claim to be a customer: `customer_id` is not part of a guest
12
+ * event, and one that carries it is dropped and counted.
13
+ */
14
+ /**
15
+ * The refusals of the guest ingest routes.
16
+ *
17
+ * - EVENTS_TENANT_UNRESOLVED (403): the request's Origin is bound to no shop.
18
+ * Checked before the body is read; nothing is stored.
19
+ * - EVENTS_BATCH_TOO_LARGE (413): the raw body is over
20
+ * {@link STOREFRONT_INGEST_LIMITS.maxBodyBytes} bytes, or `events` holds more
21
+ * than {@link STOREFRONT_INGEST_LIMITS.maxEvents} entries. Nothing is stored.
22
+ * - VALIDATION_FAILED (400): the request as a WHOLE is malformed — not JSON, not
23
+ * the envelope shape, or (withdrawal) `anonymousId` not a UUID. A single event
24
+ * that does not validate is never a 400: it is a counted drop in `dropped`.
25
+ * - EVENTS_RATE_LIMITED (429): the source's budget is spent. Nothing is stored;
26
+ * retry later.
27
+ */
28
+ export const STOREFRONT_INGEST_ERROR_CODES = [
29
+ 'EVENTS_TENANT_UNRESOLVED',
30
+ 'EVENTS_BATCH_TOO_LARGE',
31
+ 'VALIDATION_FAILED',
32
+ 'EVENTS_RATE_LIMITED',
33
+ ];
34
+ /** Bounds of `POST /events`, enforced before any event is read. */
35
+ export const STOREFRONT_INGEST_LIMITS = {
36
+ /** The raw request body ceiling, in UTF-8 bytes, measured before parsing. */
37
+ maxBodyBytes: 32 * 1024,
38
+ /** At most this many events per request. */
39
+ maxEvents: 25,
40
+ /** The longest `analyticsConsent.version` accepted; a longer one never stores an event. */
41
+ consentVersionMaxLength: 64,
42
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "platform-types",
3
- "version": "1.10.794",
3
+ "version": "1.10.795",
4
4
  "description": "Shared wire and entity contracts for the platform.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",