@vio-live/web-sdk 0.23.1 → 0.26.0
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/README.md +191 -21
- package/dist/{chunk-BRJMT7P4.js → chunk-5KWICUME.js} +1321 -333
- package/dist/chunk-5KWICUME.js.map +1 -0
- package/dist/{chunk-UVDOKFGD.js → chunk-A3LN5JEM.js} +235 -58
- package/dist/chunk-A3LN5JEM.js.map +1 -0
- package/dist/chunk-NCP76AXW.js +3 -0
- package/dist/{chunk-45YKS5UG.js.map → chunk-NCP76AXW.js.map} +1 -1
- package/dist/core/index.d.ts +1284 -596
- package/dist/core/index.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +3 -3
- package/dist/{tokens-DDfZuHF6.d.ts → tokens-Bn7fK9ta.d.ts} +72 -0
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +3 -3
- package/package.json +2 -1
- package/dist/chunk-45YKS5UG.js +0 -3
- package/dist/chunk-BRJMT7P4.js.map +0 -1
- package/dist/chunk-UVDOKFGD.js.map +0 -1
package/dist/core/index.d.ts
CHANGED
|
@@ -36,6 +36,25 @@ interface VioConfig {
|
|
|
36
36
|
contentId?: string | number;
|
|
37
37
|
/** Human-readable title of that content (`content_title`); see `contentId`. */
|
|
38
38
|
contentTitle?: string;
|
|
39
|
+
/**
|
|
40
|
+
* The campaign this PAGE belongs to (ADR-0034, amendment 3) — an editorial
|
|
41
|
+
* page (a Vev article, a Replit article) that is part of one campaign. Its
|
|
42
|
+
* slots are declared with it (the micro assigns them unless the dashboard
|
|
43
|
+
* already did) and, until that round-trips, the elements already resolve to
|
|
44
|
+
* it: assignment → page campaign → default. DOM alternative, inheritable:
|
|
45
|
+
* `data-vio-campaign` on any ancestor, or `vio-campaign` on the element.
|
|
46
|
+
*/
|
|
47
|
+
campaignId?: number;
|
|
48
|
+
/** Log the SDK's slot/attribution decisions at `console.debug` (manifest assignments per slot). */
|
|
49
|
+
debug?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* The surface's privacy mode, when the host knows it (ADR-0035): `minimal`
|
|
52
|
+
* keeps the entry context (referrer, utm, landing page) off the order
|
|
53
|
+
* attribution. Without it the SDK asks the surface itself
|
|
54
|
+
* (`GET /v2/mobile/surface`), once per page load; a host-set `minimal`
|
|
55
|
+
* always wins.
|
|
56
|
+
*/
|
|
57
|
+
privacyMode?: 'standard' | 'minimal';
|
|
39
58
|
/** Override REST API base. Defaults are env-aware. */
|
|
40
59
|
apiBase?: string;
|
|
41
60
|
/** Override GraphQL base. Defaults are env-aware. */
|
|
@@ -71,6 +90,9 @@ interface ResolvedConfig {
|
|
|
71
90
|
platform: VioPlatform;
|
|
72
91
|
contentId?: string | number;
|
|
73
92
|
contentTitle?: string;
|
|
93
|
+
campaignId?: number;
|
|
94
|
+
debug: boolean;
|
|
95
|
+
privacyMode?: 'standard' | 'minimal';
|
|
74
96
|
apiBase: string;
|
|
75
97
|
graphQLBase: string;
|
|
76
98
|
eventsBase: string;
|
|
@@ -194,6 +216,8 @@ interface BootstrapSlot {
|
|
|
194
216
|
platform?: string | null;
|
|
195
217
|
startDate?: string | null;
|
|
196
218
|
endDate?: string | null;
|
|
219
|
+
/** Who assigned it: the dashboard (always wins) or a page's own campaign (campaigns micro PR #16). */
|
|
220
|
+
source?: 'dashboard' | 'page' | null;
|
|
197
221
|
}
|
|
198
222
|
/**
|
|
199
223
|
* One entry of `campaigns[]`: every active campaign of the surface, with its
|
|
@@ -231,6 +255,12 @@ interface BootstrapResponse {
|
|
|
231
255
|
countryCode: string;
|
|
232
256
|
currencyCode: string;
|
|
233
257
|
};
|
|
258
|
+
/**
|
|
259
|
+
* The surface of the key, when the bootstrap says it (the campaigns
|
|
260
|
+
* service answers it on `/v2/mobile/surface` today; here when it adds it).
|
|
261
|
+
* Its `privacyMode` decides what the order attribution may carry.
|
|
262
|
+
*/
|
|
263
|
+
surface?: SurfaceResponse['surface'];
|
|
234
264
|
}
|
|
235
265
|
/**
|
|
236
266
|
* A slot this page declares to the campaigns service (ADR-0027 / ADR-0034):
|
|
@@ -240,6 +270,10 @@ interface BootstrapResponse {
|
|
|
240
270
|
interface ManifestLocation {
|
|
241
271
|
id: string;
|
|
242
272
|
displayName?: string;
|
|
273
|
+
/** The campaign this location belongs to when it differs from the page's (`ManifestRequest.campaignId`). */
|
|
274
|
+
campaignId?: number;
|
|
275
|
+
/** The kind of element the slot holds — `card` | `carousel` | `detail` for the SDK's, a host's own word otherwise. For the dashboard. */
|
|
276
|
+
kind?: string;
|
|
243
277
|
}
|
|
244
278
|
/**
|
|
245
279
|
* Where something happened, as `Vio.attribution(slot)` answers it — the ONE
|
|
@@ -254,6 +288,29 @@ interface Attribution {
|
|
|
254
288
|
sponsorId?: number;
|
|
255
289
|
contentId?: string;
|
|
256
290
|
contentTitle?: string;
|
|
291
|
+
/** The page's URL within the 2 048 cap (`content_url`) — what Commerce keeps on the order and its lines. */
|
|
292
|
+
contentUrl?: string;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* How much context analytics and Commerce may keep of a visit to this
|
|
296
|
+
* surface. `minimal` drops what says WHICH screen someone was on and WHY —
|
|
297
|
+
* the page (`content_url`, `content_title`), the slot (`location_id`) and
|
|
298
|
+
* the entry (referrer, utm, landing page) — the collector drops it from the
|
|
299
|
+
* events on its side (vio-analytics `privacy.ts`); the SDK keeps it off the
|
|
300
|
+
* order and off the cart lines it sends to Commerce. What measures the
|
|
301
|
+
* funnel and bills the sale stays: the surface, the campaign, the kind of
|
|
302
|
+
* component, the products and the amounts. A mode the SDK could not learn
|
|
303
|
+
* counts as `minimal`.
|
|
304
|
+
*/
|
|
305
|
+
type SurfacePrivacyMode = 'standard' | 'minimal';
|
|
306
|
+
/** Response of `GET /v2/mobile/surface`: what the key may know of its own surface. */
|
|
307
|
+
interface SurfaceResponse {
|
|
308
|
+
surface?: {
|
|
309
|
+
id?: number;
|
|
310
|
+
name?: string;
|
|
311
|
+
status?: string;
|
|
312
|
+
privacyMode?: SurfacePrivacyMode | string | null;
|
|
313
|
+
} | null;
|
|
257
314
|
}
|
|
258
315
|
/** Body of `POST /v2/mobile/components/manifest`. */
|
|
259
316
|
interface ManifestRequest {
|
|
@@ -265,6 +322,12 @@ interface ManifestRequest {
|
|
|
265
322
|
*/
|
|
266
323
|
mode: 'merge' | 'replace';
|
|
267
324
|
locations: ManifestLocation[];
|
|
325
|
+
/**
|
|
326
|
+
* The campaign the PAGE belongs to (`Vio.init({ campaignId })`): the micro
|
|
327
|
+
* assigns every declared location to it (`source: 'page'`) unless the
|
|
328
|
+
* dashboard already assigned that slot.
|
|
329
|
+
*/
|
|
330
|
+
campaignId?: number;
|
|
268
331
|
}
|
|
269
332
|
/** Response of `POST /v2/mobile/components/manifest`. */
|
|
270
333
|
interface ManifestResult {
|
|
@@ -275,6 +338,12 @@ interface ManifestResult {
|
|
|
275
338
|
id: number | string;
|
|
276
339
|
locationId: string;
|
|
277
340
|
displayName?: string | null;
|
|
341
|
+
/**
|
|
342
|
+
* What the micro did with the page's campaign for this slot: `created` /
|
|
343
|
+
* `kept` / `replaced` a page assignment, `dashboard` (the dashboard's
|
|
344
|
+
* assignment stands — the page's campaign is ignored there), `none`.
|
|
345
|
+
*/
|
|
346
|
+
assignment?: 'created' | 'kept' | 'replaced' | 'dashboard' | 'none';
|
|
278
347
|
}>;
|
|
279
348
|
deprecatedCount: number;
|
|
280
349
|
warnings: Array<{
|
|
@@ -353,6 +422,12 @@ declare class VioApi {
|
|
|
353
422
|
* sends `mode: 'merge'`; see `Vio.declareSlots()` for the dedupe on top.
|
|
354
423
|
*/
|
|
355
424
|
declareManifest(body: ManifestRequest): Promise<ManifestResult>;
|
|
425
|
+
/**
|
|
426
|
+
* The surface of the key (`GET /v2/mobile/surface`): its id, name, status
|
|
427
|
+
* and `privacyMode` — what decides whether the order attribution may carry
|
|
428
|
+
* the entry context (ADR-0035). A 404 means a service that predates it.
|
|
429
|
+
*/
|
|
430
|
+
surface(): Promise<SurfaceResponse>;
|
|
356
431
|
/**
|
|
357
432
|
* Get placement components for a campaign. Used by the carousel auto-fetch
|
|
358
433
|
* mode (`<vio-product-carousel campaign-id="36" location="news-favorites">`).
|
|
@@ -440,15 +515,29 @@ declare function createCommerceClient(options: CommerceClientOptions): CommerceC
|
|
|
440
515
|
* mental model stays consistent across platforms.
|
|
441
516
|
*/
|
|
442
517
|
/**
|
|
443
|
-
* Where a unit in the cart came from (ADR-0027 / ADR-0034): the
|
|
444
|
-
* the place showed when it was added, the place (`slot`)
|
|
445
|
-
*
|
|
446
|
-
* title.
|
|
518
|
+
* Where a unit in the cart came from (ADR-0027 / ADR-0034 / ADR-0035): the
|
|
519
|
+
* campaign the place showed when it was added, the place (`slot`), the kind
|
|
520
|
+
* of element it was added from, and the content (article: its id, URL and
|
|
521
|
+
* title). What `Vio.attribution(slot)` answers, minus the sponsor, plus the
|
|
522
|
+
* element's kind. The purchase is split per campaign from these, and since
|
|
523
|
+
* 0.26 Commerce receives them with every add (`origin` on the line, ADR-0035
|
|
524
|
+
* phase B) so the order knows where each unit was sold from.
|
|
447
525
|
*/
|
|
448
526
|
interface CartOrigin {
|
|
449
527
|
campaignId?: number;
|
|
450
528
|
slot?: string;
|
|
451
529
|
contentId?: string;
|
|
530
|
+
/**
|
|
531
|
+
* The kind of component the units were added from, as Commerce and the
|
|
532
|
+
* collector name it: `card` | `carousel` | `detail` for the SDK's elements
|
|
533
|
+
* (`componentKindOf()` — from the element's `componentTemplateId`, else
|
|
534
|
+
* the kind word in the slot id).
|
|
535
|
+
*/
|
|
536
|
+
componentKind?: string;
|
|
537
|
+
/** The page the units were added from (`content_url`, ≤ 2 048), kept so a later +1 from the cart credits the same page. */
|
|
538
|
+
contentUrl?: string;
|
|
539
|
+
/** Its title (`content_title`, ≤ 255). */
|
|
540
|
+
contentTitle?: string;
|
|
452
541
|
}
|
|
453
542
|
/** One origin of a line and how many of its units came from it. */
|
|
454
543
|
interface CartLineOrigin extends CartOrigin {
|
|
@@ -509,9 +598,10 @@ interface SponsorCartState {
|
|
|
509
598
|
* CustomEvent that UI components subscribe to (Web Components react via
|
|
510
599
|
* `requestUpdate()`).
|
|
511
600
|
*
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
*
|
|
601
|
+
* The backend cart (Vio Commerce GraphQL CreateCart / AddItem / UpdateItem /
|
|
602
|
+
* DeleteItem) is kept in sync optimistically from here; since 0.26 every add
|
|
603
|
+
* and every increase tells it where the units come from (`origin`, ADR-0035
|
|
604
|
+
* phase B) so the order is born attributed — see `origin-wire.ts`.
|
|
515
605
|
*/
|
|
516
606
|
|
|
517
607
|
interface CartChangeDetail {
|
|
@@ -660,12 +750,15 @@ declare class CartManager extends EventTarget {
|
|
|
660
750
|
origin?: CartOrigin;
|
|
661
751
|
}): void;
|
|
662
752
|
/** Send a line's target quantity to the backend — ONE request in flight per
|
|
663
|
-
* line.
|
|
664
|
-
*
|
|
665
|
-
*
|
|
666
|
-
*
|
|
667
|
-
*
|
|
668
|
-
*
|
|
753
|
+
* line. Targets that arrive while one is in flight queue behind it as
|
|
754
|
+
* steps (`queueStep`): reduced like the line's origins, sent in order once
|
|
755
|
+
* the current request settles — one request per queued increase from a
|
|
756
|
+
* different origin, one for a net decrease — so the server ends on the
|
|
757
|
+
* last intent, credits every increase to its own origin, and never sees two
|
|
758
|
+
* updates racing each other. While the sync is active the line keeps its
|
|
759
|
+
* optimistic quantity through any backend response (see
|
|
760
|
+
* `updateFromBackendCart`); a rejection drops what was queued and
|
|
761
|
+
* reconciles the cart from the server. */
|
|
669
762
|
private syncQuantity;
|
|
670
763
|
removeItem(lineItemId: string, sponsorId: number): void;
|
|
671
764
|
clearSponsorCart(sponsorId: number): void;
|
|
@@ -690,9 +783,15 @@ declare class CartManager extends EventTarget {
|
|
|
690
783
|
private loadFromStorage;
|
|
691
784
|
private emit;
|
|
692
785
|
}
|
|
693
|
-
/**
|
|
786
|
+
/**
|
|
787
|
+
* Only the attribution fields, trimmed; `{}` when nothing is known. The kind
|
|
788
|
+
* of element is kept as Commerce and the collector name it (`card`,
|
|
789
|
+
* `carousel`, `detail` — `componentKindOf`), from `componentKind` or from
|
|
790
|
+
* the `componentTemplateId` an element's attribution carries (`product-card`);
|
|
791
|
+
* the page as origin + path (`contentUrl`) and its title, within Commerce's caps.
|
|
792
|
+
*/
|
|
694
793
|
declare function normalizeOrigin(origin: CartOrigin | null | undefined): CartOrigin;
|
|
695
|
-
/** Two origins are the same place when campaign, slot and
|
|
794
|
+
/** Two origins are the same place when campaign, slot, content and kind of element all match (the page's URL and title are attributes of the place, not its identity). */
|
|
696
795
|
declare function sameOrigin(a: CartOrigin, b: CartOrigin): boolean;
|
|
697
796
|
/**
|
|
698
797
|
* The origins of a line for reporting: what it carries, plus an empty origin
|
|
@@ -702,188 +801,983 @@ declare function sameOrigin(a: CartOrigin, b: CartOrigin): boolean;
|
|
|
702
801
|
declare function lineOrigins(line: Pick<CartLineItem, 'origins' | 'quantity'>): CartLineOrigin[];
|
|
703
802
|
|
|
704
803
|
/**
|
|
705
|
-
*
|
|
804
|
+
* What the commerce gateway may not know yet.
|
|
706
805
|
*
|
|
707
|
-
*
|
|
708
|
-
*
|
|
709
|
-
*
|
|
710
|
-
*
|
|
806
|
+
* The SDK ships ahead of the gateway more than once a quarter: a selection
|
|
807
|
+
* (`buyer_ref`, 2026-10-19), an argument (`origin` on the cart lines,
|
|
808
|
+
* `attribution` on the checkout — ADR-0035 phase B). A gateway that does not
|
|
809
|
+
* have the field refuses the WHOLE operation at validation — before anything
|
|
810
|
+
* runs, with no `data` — so each such operation is sent again without the
|
|
811
|
+
* field, once, and the answer remembered for the page load. An operation that
|
|
812
|
+
* DID run and failed is never repeated: for a mutation that would be a second
|
|
813
|
+
* charge, a second line in the cart.
|
|
711
814
|
*
|
|
712
|
-
*
|
|
713
|
-
*
|
|
815
|
+
* One mechanism for all of them, so the next field costs a token here and a
|
|
816
|
+
* call to `withGatewayFeature`, not a new copy of the retry.
|
|
714
817
|
*/
|
|
715
|
-
|
|
818
|
+
type GatewayFeature = 'buyer_ref' | 'line_origin' | 'checkout_attribution';
|
|
819
|
+
/** Whether this page load still expects the gateway to know `feature` (false once it refused it). */
|
|
820
|
+
declare function gatewayHas(feature: GatewayFeature): boolean;
|
|
821
|
+
/** Forget what this page load learned (tests). One feature, or all of them. */
|
|
822
|
+
declare function resetGatewayFeatures(feature?: GatewayFeature): void;
|
|
716
823
|
/**
|
|
717
|
-
*
|
|
824
|
+
* True when `err` is the gateway refusing something it does not know, named
|
|
825
|
+
* `token` (`Cannot query field "buyer_ref" on type …`, `Unknown argument
|
|
826
|
+
* "origin" on field …`, `Unknown type "CartLineOriginInput"`, `Field "origin" is
|
|
827
|
+
* not defined by type "LineItemInput"`): a validation error, with no `data`
|
|
828
|
+
* and no `path` because nothing ran — safe to send again without it, a
|
|
829
|
+
* mutation included. Anything that ran (data present, or an error with a
|
|
830
|
+
* path) or any other message is not.
|
|
718
831
|
*/
|
|
719
|
-
declare
|
|
832
|
+
declare function isUnknownTokenError(err: unknown, token: string): boolean;
|
|
833
|
+
/** `isUnknownTokenError` for any of the names a feature goes by. */
|
|
834
|
+
declare function isUnknownFeatureError(err: unknown, feature: GatewayFeature): boolean;
|
|
720
835
|
/**
|
|
721
|
-
*
|
|
836
|
+
* Runs `request(true)` (the operation with the feature); when the gateway
|
|
837
|
+
* does not know it, `request(false)` (without it) — and from then on, for
|
|
838
|
+
* this page load, straight to the latter. Said once in the console: a
|
|
839
|
+
* gateway behind the SDK is worth knowing about, and so is a renamed type.
|
|
722
840
|
*/
|
|
723
|
-
declare
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
841
|
+
declare function withGatewayFeature<T>(feature: GatewayFeature, request: (supported: boolean) => Promise<T>): Promise<T>;
|
|
842
|
+
|
|
843
|
+
/**
|
|
844
|
+
* A line origin as Commerce receives it (ADR-0035 phase B): `origin` on each
|
|
845
|
+
* line of `AddItem` and, when the quantity goes UP, on `UpdateItem` — the
|
|
846
|
+
* origin of the units that update adds. shopcart keeps every origin of a
|
|
847
|
+
* line with its units (`cart_item.origins`) and writes the order from them:
|
|
848
|
+
* `order_item.campaign_id` / `location_id` / `component_kind`, and the
|
|
849
|
+
* order's page when the checkout does not name one.
|
|
850
|
+
*
|
|
851
|
+
* snake_case on the wire, the caps of shopcart's `LineOriginDto` enforced
|
|
852
|
+
* here, once. Pure: `lineOriginWire()` takes the origin and the page.
|
|
853
|
+
*/
|
|
854
|
+
|
|
855
|
+
/** The largest `Int` GraphQL coerces; a bigger id would fail the whole mutation. */
|
|
856
|
+
declare const GRAPHQL_INT_MAX = 2147483647;
|
|
857
|
+
/** `LineOriginDto` (shopcart `cart/dtos/send/line-origin.dto.ts`). */
|
|
858
|
+
interface LineOriginWire {
|
|
859
|
+
campaign_id?: number;
|
|
860
|
+
location_id?: string;
|
|
861
|
+
component_kind?: string;
|
|
862
|
+
content_url?: string;
|
|
863
|
+
content_title?: string;
|
|
864
|
+
}
|
|
865
|
+
/** The caps of `LineOriginDto` — a longer value is refused whole by the API, so it is cut here. */
|
|
866
|
+
declare const LINE_ORIGIN_CAPS: Readonly<{
|
|
867
|
+
locationId: 100;
|
|
868
|
+
componentKind: 32;
|
|
869
|
+
contentUrl: 2048;
|
|
870
|
+
contentTitle: 255;
|
|
871
|
+
}>;
|
|
872
|
+
/** The page the units are added from, for an origin that does not carry its own. */
|
|
873
|
+
interface OriginPage {
|
|
874
|
+
contentUrl?: string;
|
|
875
|
+
contentTitle?: string;
|
|
876
|
+
}
|
|
877
|
+
interface LineOriginWireOptions {
|
|
878
|
+
/** The current page, for an origin that does not carry its own. */
|
|
879
|
+
page?: OriginPage;
|
|
729
880
|
/**
|
|
730
|
-
*
|
|
731
|
-
*
|
|
732
|
-
*
|
|
733
|
-
*
|
|
881
|
+
* The surface's privacy mode. Only on a `standard` surface do the slot
|
|
882
|
+
* (`location_id`) and the page (`content_url`, `content_title`) travel —
|
|
883
|
+
* which screen a unit was sold from is what `minimal` keeps private, the
|
|
884
|
+
* same promise the collector keeps for the events. `campaign_id` and
|
|
885
|
+
* `component_kind` always do. Default `unknown`: fail closed.
|
|
734
886
|
*/
|
|
735
|
-
|
|
736
|
-
}
|
|
737
|
-
interface CreatePaymentVippsResponse {
|
|
738
|
-
/** Absent when Express was asked for and refused. */
|
|
739
|
-
payment_url?: string;
|
|
740
|
-
/** The reference the seller reads in its Vipps portal. */
|
|
741
|
-
reference?: string;
|
|
742
|
-
express?: boolean;
|
|
743
|
-
reason?: string;
|
|
744
|
-
}
|
|
745
|
-
interface GetVippsStatusVariables extends Record<string, unknown> {
|
|
746
|
-
checkoutId: string;
|
|
747
|
-
}
|
|
748
|
-
interface VippsStatusResult {
|
|
749
|
-
state: string;
|
|
750
|
-
/** Set when this checkout was closed as a duplicate: the checkout that paid the cart. */
|
|
751
|
-
duplicate_of?: string | null;
|
|
887
|
+
privacyMode?: SurfacePrivacyMode | 'unknown';
|
|
752
888
|
}
|
|
753
|
-
type VippsPaymentState = 'CREATED' | 'INITIATED' | 'AUTHORIZED' | 'TERMINATED' | 'EXPIRED' | string;
|
|
754
889
|
/**
|
|
755
|
-
*
|
|
890
|
+
* The origin for the wire, or `undefined` when the SDK knows no PLACE for the
|
|
891
|
+
* units — no campaign, no slot, no kind of element (a host adding with no
|
|
892
|
+
* attribution): then nothing is sent and the line inherits the order's
|
|
893
|
+
* campaign on the server. The page is the origin's own when it has one — the
|
|
894
|
+
* page the units were added from — else the current page's, as origin + path;
|
|
895
|
+
* `campaign_id` only as a positive `Int` (the DTO's `@IsInt() @Min(1)`, the
|
|
896
|
+
* gateway's 32-bit coercion).
|
|
756
897
|
*/
|
|
757
|
-
declare function
|
|
898
|
+
declare function lineOriginWire(origin: CartOrigin | null | undefined, options?: LineOriginWireOptions): LineOriginWire | undefined;
|
|
899
|
+
|
|
758
900
|
/**
|
|
759
|
-
*
|
|
901
|
+
* The `client` block — the standard context of the visit (EVENTS_CONTRACT
|
|
902
|
+
* "client", 2026-10-19): language, where the session landed from (the
|
|
903
|
+
* referrer and `utm_*` of the LANDING page, remembered for the session),
|
|
904
|
+
* screen size and time zone. What the collector derives from the request
|
|
905
|
+
* itself — device type, OS, browser, country — is NOT sent: no User-Agent
|
|
906
|
+
* parsing here, no duplicate of what the server knows better.
|
|
907
|
+
*
|
|
908
|
+
* Pure like `content.ts`: everything takes the globals it reads (defaults to
|
|
909
|
+
* the real ones), never throws, and answers `{}` where there is no browser
|
|
910
|
+
* (SSR, old engines). Capped to the collector's limits in ONE place: an
|
|
911
|
+
* over-long value is cut — none of these is an identity, so a cut referrer
|
|
912
|
+
* is still the right dimension.
|
|
913
|
+
*
|
|
914
|
+
* Landing memory: the first page of a session writes its referrer and utm
|
|
915
|
+
* parameters to `sessionStorage`; later pages read them back, so an event on
|
|
916
|
+
* page three still says the visit came from the newsletter — their own
|
|
917
|
+
* `document.referrer` (an internal page) is never a source. The referrer is
|
|
918
|
+
* kept as origin + path (no query, no fragment: a referrer's query is its
|
|
919
|
+
* tracking tail, not where the visit came from) and dropped altogether when
|
|
920
|
+
* it is this same host (a self-referral says nothing about the entry). A URL
|
|
921
|
+
* with utm parameters is a new landing (another campaign click) that replaces
|
|
922
|
+
* the memory — unless it was reached from this same host, i.e. an internal
|
|
923
|
+
* link that propagates utm, which keeps the landing that was. Without
|
|
924
|
+
* storage, or without consent to persist, each page stands alone.
|
|
760
925
|
*/
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
declare const
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
apiKey?: string;
|
|
778
|
-
/** Sponsor commerce key — goes in the Authorization header. */
|
|
779
|
-
commerceKey?: string;
|
|
780
|
-
/** True when the commerce key came from a resolved sponsor (bootstrap).
|
|
781
|
-
* False = we fell back to the host apiKey — writes like CreateCart should
|
|
782
|
-
* NOT proceed with the wrong key (the cart would be orphaned). */
|
|
783
|
-
sponsorResolved?: boolean;
|
|
784
|
-
}
|
|
926
|
+
interface ClientContext {
|
|
927
|
+
language?: string;
|
|
928
|
+
referrer?: string;
|
|
929
|
+
utm_source?: string;
|
|
930
|
+
utm_medium?: string;
|
|
931
|
+
utm_campaign?: string;
|
|
932
|
+
utm_term?: string;
|
|
933
|
+
utm_content?: string;
|
|
934
|
+
screen_w?: number;
|
|
935
|
+
screen_h?: number;
|
|
936
|
+
tz?: string;
|
|
937
|
+
}
|
|
938
|
+
declare const UTM_KEYS: readonly ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"];
|
|
939
|
+
type UtmKey = (typeof UTM_KEYS)[number];
|
|
940
|
+
/** Commerce's cap for the landing page on the order's entry context (`entry.landing_url`, ADR-0035). */
|
|
941
|
+
declare const CLIENT_LANDING_URL_MAX_LENGTH = 2048;
|
|
785
942
|
/**
|
|
786
|
-
*
|
|
787
|
-
*
|
|
788
|
-
*
|
|
789
|
-
*
|
|
943
|
+
* What a session remembers of the page it landed on. `url` is the landing
|
|
944
|
+
* page itself — origin + path, like the referrer: no query (the utm are kept
|
|
945
|
+
* apart, the rest is a tracking tail), no fragment — for the order's entry
|
|
946
|
+
* context; the events do not carry it (the collector derives the landing).
|
|
790
947
|
*/
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
948
|
+
interface Landing {
|
|
949
|
+
referrer?: string;
|
|
950
|
+
utm?: Partial<Record<UtmKey, string>>;
|
|
951
|
+
url?: string;
|
|
952
|
+
}
|
|
953
|
+
interface StorageLike {
|
|
954
|
+
getItem(key: string): string | null;
|
|
955
|
+
setItem(key: string, value: string): void;
|
|
956
|
+
removeItem?(key: string): void;
|
|
957
|
+
}
|
|
958
|
+
/** The globals the block is read from — injectable for tests; defaults to the real ones. */
|
|
959
|
+
interface ClientEnvironment {
|
|
960
|
+
navigator?: {
|
|
961
|
+
language?: unknown;
|
|
962
|
+
} | null;
|
|
963
|
+
document?: {
|
|
964
|
+
referrer?: unknown;
|
|
965
|
+
} | null;
|
|
966
|
+
location?: {
|
|
967
|
+
search?: unknown;
|
|
968
|
+
host?: unknown;
|
|
969
|
+
href?: unknown;
|
|
970
|
+
} | null;
|
|
971
|
+
screen?: {
|
|
972
|
+
width?: unknown;
|
|
973
|
+
height?: unknown;
|
|
974
|
+
} | null;
|
|
975
|
+
/** The session memory for the landing; `null` = none (SSR, private mode, blocked). */
|
|
976
|
+
storage?: StorageLike | null;
|
|
977
|
+
/** The time zone; defaults to `Intl.DateTimeFormat().resolvedOptions().timeZone`. */
|
|
978
|
+
timeZone?: () => unknown;
|
|
799
979
|
}
|
|
800
|
-
/**
|
|
801
|
-
*
|
|
802
|
-
*
|
|
803
|
-
*
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
declare function
|
|
807
|
-
|
|
808
|
-
declare function
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
declare function
|
|
816
|
-
|
|
817
|
-
declare function
|
|
980
|
+
/**
|
|
981
|
+
* The landing of this session: what is remembered — unless this page is a
|
|
982
|
+
* landing itself (utm parameters in its URL, reached from outside this host)
|
|
983
|
+
* or nothing is remembered yet, when this page's referrer and utm are taken
|
|
984
|
+
* (and, with `persist`, kept).
|
|
985
|
+
*/
|
|
986
|
+
declare function resolveLanding(env?: ClientEnvironment, persist?: boolean): Landing;
|
|
987
|
+
/** The landing page as the landing keeps it: origin + path, no query, no fragment; capped. */
|
|
988
|
+
declare function landingUrl(raw: unknown): string | undefined;
|
|
989
|
+
/**
|
|
990
|
+
* The landing this session REMEMBERS — what was written by the first page —
|
|
991
|
+
* or null when nothing is stored (no storage, no consent, analytics never
|
|
992
|
+
* started). Read only: for the order's entry context, which must not take the
|
|
993
|
+
* page the shopper pays on for the page they came in through.
|
|
994
|
+
*/
|
|
995
|
+
declare function storedLanding(storage?: StorageLike | null | undefined): Landing | null;
|
|
996
|
+
/** The block for the wire — read once per page load by the manager and reused on every event. */
|
|
997
|
+
declare function resolveClientContext(env?: ClientEnvironment, landing?: Landing): ClientContext;
|
|
818
998
|
|
|
819
999
|
/**
|
|
820
|
-
*
|
|
1000
|
+
* Slots — the pure half of ADR-0027 / ADR-0034 on the web.
|
|
821
1001
|
*
|
|
822
|
-
*
|
|
823
|
-
*
|
|
1002
|
+
* A slot is a NAME for a place on a page. The page declares its slots to the
|
|
1003
|
+
* campaigns service (`Vio.declareSlots()` / `Vio.registerSlot()` in client.ts),
|
|
1004
|
+
* the dashboard assigns a campaign to each one, optionally with a date window,
|
|
1005
|
+
* and `GET /v2/mobile/config` answers with `campaigns[].slots[]` — only the
|
|
1006
|
+
* assignments whose window is open NOW. Whatever no slot names shows the
|
|
1007
|
+
* surface's default campaign (`campaign`).
|
|
824
1008
|
*
|
|
825
|
-
*
|
|
826
|
-
*
|
|
827
|
-
*
|
|
828
|
-
* seller's when they brought both keys, ours otherwise. The two are
|
|
829
|
-
* halves of one account: the browser confirms with the key what the
|
|
830
|
-
* server minted with the secret one.
|
|
831
|
-
* 2. Stripe's Payment Element is mounted in a LIGHT-DOM container, the way
|
|
832
|
-
* the other embedded widgets are. Card fields are Stripe's own iframes,
|
|
833
|
-
* so card data never touches this SDK or our servers.
|
|
834
|
-
* 3. `confirm()` pays. A 3-D Secure challenge opens in Stripe's own modal
|
|
835
|
-
* over the page: `redirect: 'if_required'` keeps the shopper here for
|
|
836
|
-
* cards, and still redirects for a method that has no other way.
|
|
837
|
-
* 4. The Commerce order is NOT born here. Stripe's `payment_intent.succeeded`
|
|
838
|
-
* webhook creates it, verified server-side; the checkout is polled for
|
|
839
|
-
* its status afterwards, exactly as the redirect return does.
|
|
1009
|
+
* Everything here is side-effect free and never throws on a malformed
|
|
1010
|
+
* bootstrap: a broken `campaigns[]` must never blank a product block or break
|
|
1011
|
+
* `track()`.
|
|
840
1012
|
*/
|
|
841
1013
|
|
|
842
|
-
/** What
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
customer?: string;
|
|
849
|
-
/**
|
|
850
|
-
* Stripe Connect (ADR-0022): the seller's connected account, where the
|
|
851
|
-
* intent lives. The browser must name it or Stripe answers "no such
|
|
852
|
-
* payment_intent". Absent for every seller not on Connect.
|
|
853
|
-
*/
|
|
854
|
-
stripe_account?: string;
|
|
855
|
-
}
|
|
856
|
-
/** What `confirm()` answers. The browser's word is never the order. */
|
|
857
|
-
type StripeConfirmOutcome = {
|
|
858
|
-
status: 'succeeded';
|
|
859
|
-
paymentIntentId?: string;
|
|
860
|
-
}
|
|
861
|
-
/** Authorised but not settled yet, or Stripe redirected and will return. */
|
|
862
|
-
| {
|
|
863
|
-
status: 'pending';
|
|
864
|
-
paymentIntentId?: string;
|
|
865
|
-
} | {
|
|
866
|
-
status: 'failed';
|
|
867
|
-
message?: string;
|
|
868
|
-
code?: string;
|
|
1014
|
+
/** What `Vio.declareSlots()` accepts per slot. */
|
|
1015
|
+
type SlotInput = string | {
|
|
1016
|
+
id: string;
|
|
1017
|
+
displayName?: string;
|
|
1018
|
+
campaignId?: number;
|
|
1019
|
+
kind?: string;
|
|
869
1020
|
};
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
1021
|
+
/** The third argument of `Vio.registerSlot(id, displayName, …)`: the element's own campaign and what kind of element it is. */
|
|
1022
|
+
interface RegisterSlotOptions {
|
|
1023
|
+
campaignId?: number | string | null;
|
|
1024
|
+
/** `card` | `carousel` | `detail` for the SDK's elements; a host may name its own kind. */
|
|
1025
|
+
kind?: string;
|
|
873
1026
|
}
|
|
1027
|
+
/**
|
|
1028
|
+
* The kind of component some units were sold from, as Commerce keeps it on
|
|
1029
|
+
* the order line (`order_item.component_kind`, ≤ 32) — the SAME rule the
|
|
1030
|
+
* collector applies for `breakdown?by=component_kind` (vio-analytics
|
|
1031
|
+
* `componentKind`), so the order and the events agree: what the element says
|
|
1032
|
+
* it is (`component_template_id`: `product-card`, `product-carousel`,
|
|
1033
|
+
* `product-detail`, a Vev block's `vev-card`) lower-cased and without its
|
|
1034
|
+
* `product-` / `vev-` prefix, else the kind word in the slot id the page
|
|
1035
|
+
* declared (`card-<key>`, `<scope>-carousel-2`, `detail-1`); `undefined` when
|
|
1036
|
+
* neither says.
|
|
1037
|
+
*/
|
|
1038
|
+
declare function componentKindOf(templateId: unknown, slot?: unknown): string | undefined;
|
|
1039
|
+
/** The kind as the manifest carries it: trimmed, lower-case, cut at 32 chars; `undefined` for nothing. */
|
|
1040
|
+
declare function normalizeSlotKind(value: unknown): string | undefined;
|
|
1041
|
+
type BootLike = Pick<BootstrapResponse, 'campaign' | 'campaigns' | 'primarySponsor' | 'secondarySponsors'>;
|
|
1042
|
+
/**
|
|
1043
|
+
* The campaign a slot shows right now. Among the `status === 'active'`
|
|
1044
|
+
* entries of `campaigns[]`, the one with an assignment named `slot` for this
|
|
1045
|
+
* platform (`platform` null on the assignment, or equal to `platform`) whose
|
|
1046
|
+
* window contains `now` (`startDate <= now < endDate`, null = open). When
|
|
1047
|
+
* several qualify, the surface's default campaign wins, else the first the
|
|
1048
|
+
* backend lists.
|
|
1049
|
+
*
|
|
1050
|
+
* No assignment → the PAGE's campaign (`pageCampaignId`: the element's own
|
|
1051
|
+
* `vio-campaign`, an ancestor's `data-vio-campaign`, or `Vio.init({ campaignId })`)
|
|
1052
|
+
* when `campaigns[]` lists it as active — an editorial page resolves to its
|
|
1053
|
+
* campaign before (and regardless of) the manifest round-trip. Else the
|
|
1054
|
+
* default campaign: the `campaigns[]` entry whose id is `campaign.id`, or a
|
|
1055
|
+
* minimal entry built from `campaign` (+ the top-level sponsors) when the
|
|
1056
|
+
* list does not carry it. No bootstrap → null.
|
|
1057
|
+
*/
|
|
1058
|
+
declare function resolveSlotCampaign(boot: BootLike | null | undefined, slot: string | null | undefined, now?: number, platform?: string | null, pageCampaignId?: CampaignHint, sponsorId?: number | null): BootstrapCampaignEntry | null;
|
|
1059
|
+
/**
|
|
1060
|
+
* The sponsor rule: the active campaign of `campaigns[]` the sponsor takes
|
|
1061
|
+
* part in, as its primary or one of its secondaries — when it is in several,
|
|
1062
|
+
* the surface's default campaign if it is one of them, else the first one
|
|
1063
|
+
* the backend lists. Null when none (or on a malformed list).
|
|
1064
|
+
*/
|
|
1065
|
+
declare function sponsorCampaignEntry(boot: BootLike | null | undefined, sponsorId: number | null | undefined): BootstrapCampaignEntry | null;
|
|
1066
|
+
/**
|
|
1067
|
+
* A page campaign as the callers give it: one id, or the candidates in
|
|
1068
|
+
* precedence order (the element's `vio-campaign`, an ancestor's
|
|
1069
|
+
* `data-vio-campaign`, `Vio.init`'s). An unusable level (invalid, paused,
|
|
1070
|
+
* unknown) falls through to the next one; `0`, `null`, `''` mean unset.
|
|
1071
|
+
*/
|
|
1072
|
+
type CampaignHint = number | string | null | undefined | ReadonlyArray<number | string | null | undefined>;
|
|
1073
|
+
/**
|
|
1074
|
+
* A campaign id as the SDK accepts it: a positive safe integer, given as a
|
|
1075
|
+
* number or as a string of decimal digits (an attribute). Anything else —
|
|
1076
|
+
* `true`, `'0x10'`, `'1e3'`, an array, a float — is "absent".
|
|
1077
|
+
*/
|
|
1078
|
+
declare function toCampaignId(value: unknown): number | undefined;
|
|
1079
|
+
/** The usable ids of a hint, in order, without duplicates. */
|
|
1080
|
+
declare function campaignCandidates(hint: CampaignHint): number[];
|
|
1081
|
+
/**
|
|
1082
|
+
* The first candidate of `hint` that `campaigns[]` lists as ACTIVE (and, when
|
|
1083
|
+
* `sponsorId` is given, that the sponsor takes part in — primary or
|
|
1084
|
+
* secondary); null when none — a paused, ended or unknown page campaign is
|
|
1085
|
+
* ignored and the resolution moves on.
|
|
1086
|
+
*/
|
|
1087
|
+
declare function activeCampaignEntry(boot: BootLike | null | undefined, hint: CampaignHint, sponsorId?: number): BootstrapCampaignEntry | null;
|
|
1088
|
+
/** The kinds of Vio element that register themselves. */
|
|
1089
|
+
type SlotKind = 'card' | 'carousel' | 'detail';
|
|
1090
|
+
/**
|
|
1091
|
+
* The id an element gets when the host set no `vio-slot`:
|
|
1092
|
+
* `${scope ? scope + '-' : ''}${kind}-${ordinal + 1}` (`carousel-1`, `card-3`,
|
|
1093
|
+
* `article-123-carousel-1`), `ordinal` being the element's index among the
|
|
1094
|
+
* same-kind Vio elements WITH THE SAME SCOPE, in document order at connect
|
|
1095
|
+
* time. The scope is inherited from the DOM (`vio-scope` on the element, else
|
|
1096
|
+
* the nearest `data-vio-scope` ancestor): a Vev page or a Replit article
|
|
1097
|
+
* (`<body data-vio-scope="article-123">`) gets per-page slots with one line
|
|
1098
|
+
* and no per-element naming; a template that wants slots shared across
|
|
1099
|
+
* articles simply sets no scope. On purpose there is NO page path in the id:
|
|
1100
|
+
* the article goes to analytics as `content_id`, not into the slot. Stable
|
|
1101
|
+
* across reloads while the layout is; a layout change leaves a stale entry,
|
|
1102
|
+
* which ADR-0034 accepts.
|
|
1103
|
+
*/
|
|
1104
|
+
declare function autoSlotId(kind: SlotKind, ordinal: number, scope?: string | null): string;
|
|
1105
|
+
/** `"Carousel 1"`, `"Card 3"` — with ` · ${scopeName}` when the scope has a human label. */
|
|
1106
|
+
declare function autoSlotDisplayName(kind: SlotKind, ordinal: number, scopeName?: string | null): string;
|
|
1107
|
+
/** A scope value fit for an id: trimmed, inner whitespace → `-`. */
|
|
1108
|
+
declare function normalizeScope(scope: string | null | undefined): string;
|
|
874
1109
|
|
|
875
1110
|
/**
|
|
876
|
-
*
|
|
1111
|
+
* Vio.analytics — the web SDK's half of the Vio Analytics pipeline.
|
|
877
1112
|
*
|
|
878
|
-
*
|
|
879
|
-
*
|
|
880
|
-
*
|
|
881
|
-
*
|
|
882
|
-
*
|
|
883
|
-
* platform account instead of the merchant.
|
|
1113
|
+
* Events flow to the Vio collector (`POST <eventsBase>/v1/events`, repo
|
|
1114
|
+
* vio-live/vio-analytics) which owns raw storage (ClickHouse) and vendor
|
|
1115
|
+
* fan-out (Mixpanel today). THE SDK NEVER TALKS TO VENDORS — swapping or
|
|
1116
|
+
* dropping a vendor is a server-side change, zero client releases.
|
|
1117
|
+
* Wire contract: vio-analytics `docs/EVENTS_CONTRACT.md` (v1, snake_case).
|
|
884
1118
|
*
|
|
885
|
-
*
|
|
886
|
-
*
|
|
1119
|
+
* Design rules:
|
|
1120
|
+
* - SIDE-EFFECT-FREE MODULE. Nothing runs at import time (tsup/tree-shaking
|
|
1121
|
+
* contract, see lessons/web-sdk-tsup-singleton-and-build). Listeners are
|
|
1122
|
+
* installed by an explicit `Vio.analytics.start()`.
|
|
1123
|
+
* - `track()` works BEFORE `Vio.init()` — events queue and flush once the
|
|
1124
|
+
* SDK is configured (transport resolves at flush time, not at track time).
|
|
1125
|
+
* - SSR-safe: without `window` every call is a silent no-op.
|
|
1126
|
+
* - Retries are safe: `event_id` is stable per event, the collector
|
|
1127
|
+
* dedupes. Queue is bounded (drop-oldest) so a dead collector can never
|
|
1128
|
+
* grow memory unbounded.
|
|
1129
|
+
* - Anti-double-count: the SDK only reports what the server can't see.
|
|
1130
|
+
* Votes/participations are server truth; `ad_activation`/`cart_intent`
|
|
1131
|
+
* are mirrored server-side, never from here.
|
|
1132
|
+
*
|
|
1133
|
+
* Three sinks, matching the Vev precedent (vio-vev analytics.ts, which
|
|
1134
|
+
* becomes an adapter over this in F3):
|
|
1135
|
+
* 1. collector (default ON once started)
|
|
1136
|
+
* 2. window.dataLayer — GA4/GTM (opt-in `start({ dataLayer: true })`,
|
|
1137
|
+
* the publisher-facing feature; NOT part of the Vio pipeline)
|
|
1138
|
+
* 3. `vio:analytics` DOM event — always when started (inspector/bridges)
|
|
1139
|
+
*/
|
|
1140
|
+
|
|
1141
|
+
declare const ANALYTICS_EVENT_NAMES: readonly ["view_item_list", "select_item", "view_item", "add_to_cart", "remove_from_cart", "view_cart", "begin_checkout", "purchase", "component_impression", "component_click", "ad_impression", "ad_click", "poll_impression", "contest_impression", "session_start", "session_end", "checkout_error", "sdk_error"];
|
|
1142
|
+
type AnalyticsEventName = (typeof ANALYTICS_EVENT_NAMES)[number];
|
|
1143
|
+
/** Camel-case for DX; mapped to the snake_case wire format at build time. */
|
|
1144
|
+
interface AnalyticsContext {
|
|
1145
|
+
campaignId?: number;
|
|
1146
|
+
broadcastId?: string;
|
|
1147
|
+
campaignComponentId?: number;
|
|
1148
|
+
appPlacementId?: number;
|
|
1149
|
+
locationId?: string;
|
|
1150
|
+
componentTemplateId?: string;
|
|
1151
|
+
sponsorId?: number;
|
|
1152
|
+
activationId?: number;
|
|
1153
|
+
contentUrl?: string;
|
|
1154
|
+
/**
|
|
1155
|
+
* The host's own id for the piece of content the component sits in — an
|
|
1156
|
+
* article id in a CMS, a page id in a site builder. Carried verbatim so the
|
|
1157
|
+
* host can join Vio's funnel back onto its own per-article reporting
|
|
1158
|
+
* (revenue stops being an estimate). Left alone by the SDK.
|
|
1159
|
+
*/
|
|
1160
|
+
contentId?: string | number;
|
|
1161
|
+
/** Human-readable content snapshot; auto-filled from document.title. */
|
|
1162
|
+
contentTitle?: string;
|
|
1163
|
+
/** Código corto del fallo (`sdk_error` / `checkout_error`). */
|
|
1164
|
+
errorCode?: string;
|
|
1165
|
+
variant?: string;
|
|
1166
|
+
/**
|
|
1167
|
+
* The slot (ADR-0027) the component sits in — its `vio-slot`. Attribution
|
|
1168
|
+
* follows it: the event's `campaign_id` is the campaign assigned to the slot
|
|
1169
|
+
* right now, before the sponsor rule. On the wire it fills `location_id`
|
|
1170
|
+
* when no explicit `locationId` is given (a slot IS a location id to the
|
|
1171
|
+
* campaigns service).
|
|
1172
|
+
*/
|
|
1173
|
+
slot?: string;
|
|
1174
|
+
}
|
|
1175
|
+
interface AnalyticsItemInput {
|
|
1176
|
+
productId: number | string;
|
|
1177
|
+
name?: string;
|
|
1178
|
+
brand?: string;
|
|
1179
|
+
variantId?: number | string;
|
|
1180
|
+
price?: number;
|
|
1181
|
+
quantity?: number;
|
|
1182
|
+
}
|
|
1183
|
+
interface AnalyticsCommerce {
|
|
1184
|
+
items?: AnalyticsItemInput[];
|
|
1185
|
+
value?: number;
|
|
1186
|
+
currency?: string;
|
|
1187
|
+
orderId?: string;
|
|
1188
|
+
paymentMethod?: string;
|
|
1189
|
+
/**
|
|
1190
|
+
* The buyer reference (`buyer_id` on the wire): shopcart's `buyer_ref`, a
|
|
1191
|
+
* keyed hash of the buyer's email — one person, one ref across orders and
|
|
1192
|
+
* devices, nothing reversible. Never an email (see core/buyer-ref.ts).
|
|
1193
|
+
*/
|
|
1194
|
+
buyerId?: string;
|
|
1195
|
+
}
|
|
1196
|
+
interface TrackOptions {
|
|
1197
|
+
context?: AnalyticsContext;
|
|
1198
|
+
commerce?: AnalyticsCommerce;
|
|
1199
|
+
props?: Record<string, unknown>;
|
|
1200
|
+
}
|
|
1201
|
+
interface AnalyticsStartOptions {
|
|
1202
|
+
/** Where the SDK is embedded: 'vev' | 'replit' | 'custom' | … Default 'custom'. */
|
|
1203
|
+
host?: string;
|
|
1204
|
+
/**
|
|
1205
|
+
* Arrancar en modo cookieless hasta que el host llame `setConsent(true)`.
|
|
1206
|
+
* Default false: el SDK asume que el CMP del publisher ya decidió si nos
|
|
1207
|
+
* carga. Los publishers EU que necesitan medir antes del consentimiento
|
|
1208
|
+
* (o no pueden persistir sin él) ponen true.
|
|
1209
|
+
*/
|
|
1210
|
+
requireConsent?: boolean;
|
|
1211
|
+
/**
|
|
1212
|
+
* Install the automatic funnel listeners (vio:added-to-cart,
|
|
1213
|
+
* vio:checkout-open, vio:open-cart, vio:payment-success). Default true.
|
|
1214
|
+
* Hosts with their OWN instrumentation choke point (e.g. the Vev module,
|
|
1215
|
+
* which forwards every event through trackEvent()) set false so the same
|
|
1216
|
+
* user action is never tracked twice — they keep the session/batching/
|
|
1217
|
+
* transport engine and call track() themselves.
|
|
1218
|
+
*/
|
|
1219
|
+
autoTrack?: boolean;
|
|
1220
|
+
/**
|
|
1221
|
+
* Adopt the host's session id instead of minting one. A host that already
|
|
1222
|
+
* tracks its readers (its own impressions, dwell, clicks) needs Vio's
|
|
1223
|
+
* purchases to land in the SAME session, or the two datasets cannot be
|
|
1224
|
+
* joined. Pass the id the host already stores; omit it and the SDK keeps
|
|
1225
|
+
* its own rotating session.
|
|
1226
|
+
*/
|
|
1227
|
+
sessionId?: string;
|
|
1228
|
+
/** Send to the Vio collector. Default true. */
|
|
1229
|
+
collector?: boolean;
|
|
1230
|
+
/** Also push GA4 e-commerce events to window.dataLayer (publisher feature). */
|
|
1231
|
+
dataLayer?: boolean;
|
|
1232
|
+
/** console.debug every event. */
|
|
1233
|
+
debug?: boolean;
|
|
1234
|
+
}
|
|
1235
|
+
declare class AnalyticsManager extends EventTarget {
|
|
1236
|
+
private started;
|
|
1237
|
+
private options;
|
|
1238
|
+
private queue;
|
|
1239
|
+
private flushTimer;
|
|
1240
|
+
private retryAttempt;
|
|
1241
|
+
private retryNotBefore;
|
|
1242
|
+
private externalUserId;
|
|
1243
|
+
private sessionId;
|
|
1244
|
+
private requireConsent;
|
|
1245
|
+
private consentGranted;
|
|
1246
|
+
private anonIdCache;
|
|
1247
|
+
/** Set via start({ sessionId }) — the host owns the session, we follow. */
|
|
1248
|
+
private externalSessionId;
|
|
1249
|
+
private sessionStartedAt;
|
|
1250
|
+
/** Impression once-per-(session, component) guard; reset on session rotation. */
|
|
1251
|
+
private impressedComponents;
|
|
1252
|
+
/** Last NON-EMPTY cart snapshot — `purchase` uses it because several flows
|
|
1253
|
+
* (Apple Pay) clear the cart BEFORE `vio:payment-success` fires. */
|
|
1254
|
+
private lastCartSnapshot;
|
|
1255
|
+
/** The `client` block (language, landing referrer / utm, screen, tz): read once per page load, reused on every event. */
|
|
1256
|
+
private client;
|
|
1257
|
+
/** The landing it was read from — persisted later when consent arrives after the first event. */
|
|
1258
|
+
private landing;
|
|
1259
|
+
/** The landing this manager resolved on this page load (the first event's), or null before it; read only — for the order's entry context when nothing is stored yet. */
|
|
1260
|
+
get currentLanding(): Landing | null;
|
|
1261
|
+
private teardown;
|
|
1262
|
+
/**
|
|
1263
|
+
* Install listeners + begin flushing. Explicit on purpose (no module
|
|
1264
|
+
* side-effects). Safe to call twice (second call only updates options).
|
|
1265
|
+
*/
|
|
1266
|
+
/**
|
|
1267
|
+
* Consentimiento (ePrivacy/GDPR). Por defecto el SDK asume que el host ya
|
|
1268
|
+
* lo gestionó — su CMP decide si nos carga. Con `requireConsent: true`
|
|
1269
|
+
* arranca en modo **cookieless**: mide la visita con ids efímeros en
|
|
1270
|
+
* memoria y NO escribe nada en localStorage hasta que el host llame
|
|
1271
|
+
* `setConsent(true)`. Retirarlo borra lo persistido.
|
|
1272
|
+
*/
|
|
1273
|
+
setConsent(granted: boolean): void;
|
|
1274
|
+
/** ¿Podemos escribir en el dispositivo? */
|
|
1275
|
+
private get canPersist();
|
|
1276
|
+
start(options?: AnalyticsStartOptions): void;
|
|
1277
|
+
/** Stop timers + listeners (tests / SPA unmount). Queue survives. */
|
|
1278
|
+
stop(): void;
|
|
1279
|
+
/** Attach the partner's user id (opaque) to all subsequent events. */
|
|
1280
|
+
identify(externalUserId: string | null): void;
|
|
1281
|
+
/** Queue one event. Works pre-init and pre-start (SSR: no-op). */
|
|
1282
|
+
track(name: AnalyticsEventName, opts?: TrackOptions): void;
|
|
1283
|
+
/**
|
|
1284
|
+
* Impression helper: observes an element and tracks ONE
|
|
1285
|
+
* `component_impression` per (session, campaignComponentId) when the
|
|
1286
|
+
* contract's rule is met (≥50% visible, ≥1s dwell). Returns an
|
|
1287
|
+
* unobserve function.
|
|
1288
|
+
*/
|
|
1289
|
+
observeImpression(element: Element, context?: AnalyticsContext, opts?: {
|
|
1290
|
+
name?: Extract<AnalyticsEventName, 'component_impression' | 'ad_impression'>;
|
|
1291
|
+
/** Dedupe key override. Defaults to the strongest id available:
|
|
1292
|
+
* campaignComponentId → locationId → componentTemplateId. */
|
|
1293
|
+
key?: string;
|
|
1294
|
+
/** Called the one time the impression is tracked (e.g. to fire a
|
|
1295
|
+
* companion view_item_list). */
|
|
1296
|
+
onImpression?: () => void;
|
|
1297
|
+
}): () => void;
|
|
1298
|
+
/** Force a flush (mostly for tests). */
|
|
1299
|
+
flush(): Promise<void>;
|
|
1300
|
+
private buildEvent;
|
|
1301
|
+
/**
|
|
1302
|
+
* The `client` block: read once — the landing is remembered for the session
|
|
1303
|
+
* only when we may persist — then the same (frozen) object on every event.
|
|
1304
|
+
* `null` when there is nothing to say (no browser).
|
|
1305
|
+
*/
|
|
1306
|
+
private clientBlock;
|
|
1307
|
+
/** Guarda la sesión solo si podemos escribir en el dispositivo. */
|
|
1308
|
+
private persistSession;
|
|
1309
|
+
private anonId;
|
|
1310
|
+
/** Rolling session: renewed by activity, rotated after 30 min idle. */
|
|
1311
|
+
private ensureSession;
|
|
1312
|
+
private trackSessionEnd;
|
|
1313
|
+
private flushWithBeacon;
|
|
1314
|
+
/**
|
|
1315
|
+
* Auto-instrumentation over the SDK's own DOM events — the host app
|
|
1316
|
+
* writes ZERO tracking code for the commerce funnel.
|
|
1317
|
+
*/
|
|
1318
|
+
private installAutoListeners;
|
|
1319
|
+
/** The lines of the cart (current, else the pre-clear snapshot), optionally one sponsor's. */
|
|
1320
|
+
private cartLines;
|
|
1321
|
+
/**
|
|
1322
|
+
* The cart split per campaign — the shared rule of cart/slices.ts over the
|
|
1323
|
+
* current cart (else the pre-clear snapshot), plus whether any unit named
|
|
1324
|
+
* its campaign itself (a cart without origins is reported as before).
|
|
1325
|
+
*/
|
|
1326
|
+
private cartSlices;
|
|
1327
|
+
/**
|
|
1328
|
+
* The context of one of several per-campaign events: the slice's campaign,
|
|
1329
|
+
* slot and content — only its own; when the slice spans several slots or
|
|
1330
|
+
* articles the event names none rather than the one the click came from.
|
|
1331
|
+
*/
|
|
1332
|
+
private sliceContext;
|
|
1333
|
+
/**
|
|
1334
|
+
* The context of a single-campaign checkout/purchase: when the cart's origins
|
|
1335
|
+
* say which campaign they came from, the event says it too (plus the slot /
|
|
1336
|
+
* content when unique) — a cart without origins is exactly as before.
|
|
1337
|
+
*/
|
|
1338
|
+
private singleSliceContext;
|
|
1339
|
+
/** Current cart → commerce payload; falls back to the pre-clear snapshot. */
|
|
1340
|
+
private cartCommerce;
|
|
1341
|
+
private findLine;
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1344
|
+
* The `campaign_id` of an event. In order: the context's explicit id; the
|
|
1345
|
+
* campaign assigned to the context's `slot` right now (ADR-0027 — only an
|
|
1346
|
+
* open assignment for the init platform counts, see `findSlotAssignment`);
|
|
1347
|
+
* the PAGE's campaign (`opts.pageCampaignId`, else `Vio.init({ campaignId })`)
|
|
1348
|
+
* when `campaigns[]` lists it as active (ADR-0034, amendment 3);
|
|
1349
|
+
* the active campaign of `campaigns[]` the event's sponsor takes part in, as
|
|
1350
|
+
* its primary or one of its secondaries — when it is in several, the
|
|
1351
|
+
* surface's default campaign if it is one of them, else the first one the
|
|
1352
|
+
* backend lists; the default campaign (`campaign.id`). `/v2/mobile/config`
|
|
1353
|
+
* has no top-level `campaignId` — reading one is why every event used to
|
|
1354
|
+
* leave with `campaign_id: 0` and the campaigns screen stayed empty.
|
|
1355
|
+
*
|
|
1356
|
+
* A malformed `campaigns[]` (not an array, a null entry) never breaks
|
|
1357
|
+
* `track()`: it falls back to `campaign.id`.
|
|
1358
|
+
*/
|
|
1359
|
+
declare function resolveCampaignId(ctx: Pick<AnalyticsContext, 'campaignId' | 'sponsorId' | 'slot'>, boot: Pick<BootstrapResponse, 'campaign' | 'campaigns'> | null | undefined, opts?: {
|
|
1360
|
+
pageCampaignId?: CampaignHint;
|
|
1361
|
+
}): number | undefined;
|
|
1362
|
+
/**
|
|
1363
|
+
* `detail` of `vio:payment-success` as the checkout emits it. Four paths,
|
|
1364
|
+
* three shapes: a redirect return (`orderId` = Vio's checkout id), the
|
|
1365
|
+
* confirmation drawer and a provider's own receipt (`result` from the
|
|
1366
|
+
* provider or the backend, plus Vio's `checkoutId`), and Apple Pay express
|
|
1367
|
+
* from the cart (`result` with the backend's `confirmation`, no sponsor).
|
|
1368
|
+
*/
|
|
1369
|
+
interface PaymentSuccessDetail {
|
|
1370
|
+
method?: string;
|
|
1371
|
+
sponsorId?: number | string;
|
|
1372
|
+
/** The slot the purchase started from, when the emitter knows it. */
|
|
1373
|
+
slot?: string;
|
|
1374
|
+
/** The campaign the emitter attributed the purchase to (its `Vio.attribution`). */
|
|
1375
|
+
campaignId?: number;
|
|
1376
|
+
/** Per-element content override (`vio-content-id` / `vio-content-title`), when the emitter carries one. */
|
|
1377
|
+
contentId?: string | number;
|
|
1378
|
+
contentTitle?: string;
|
|
1379
|
+
/** Redirect return: Vio's checkout id (the name predates `checkoutId`). */
|
|
1380
|
+
orderId?: string | number;
|
|
1381
|
+
/** Vio's checkout id — from the checkout state or the return URL. */
|
|
1382
|
+
checkoutId?: string | number;
|
|
1383
|
+
/**
|
|
1384
|
+
* The buyer reference the emitter learned with the payment — shopcart's
|
|
1385
|
+
* `buyer_ref`, a keyed hash of the email (`buyerRef` from the SDK's own
|
|
1386
|
+
* checkout; `buyer_ref` when a host passes the backend's answer through).
|
|
1387
|
+
* Becomes `commerce.buyer_id`; never an email.
|
|
1388
|
+
*/
|
|
1389
|
+
buyerRef?: string | null;
|
|
1390
|
+
buyer_ref?: string | null;
|
|
1391
|
+
result?: PaymentSuccessResult | null;
|
|
1392
|
+
}
|
|
1393
|
+
/**
|
|
1394
|
+
* What the checkout attaches as `result`. Only `confirmation` carries a Vio
|
|
1395
|
+
* id: the order `ConfirmPaymentApplePay` created. `order.orderId` / `orderId`
|
|
1396
|
+
* are the PROVIDER's references (Qliro's, Walley's — the checkout itself
|
|
1397
|
+
* shows them as `providerRef`), and `chargedTotal` includes shipping on some
|
|
1398
|
+
* methods only. Analytics reads none of those.
|
|
1399
|
+
*/
|
|
1400
|
+
interface PaymentSuccessResult {
|
|
1401
|
+
confirmation?: {
|
|
1402
|
+
orderId?: string | number | null;
|
|
1403
|
+
status?: string;
|
|
1404
|
+
buyerRef?: string | null;
|
|
1405
|
+
buyer_ref?: string | null;
|
|
1406
|
+
} | null;
|
|
1407
|
+
/** The checkout as a host's backend answered it, when the host passes it through. */
|
|
1408
|
+
checkout?: {
|
|
1409
|
+
buyerRef?: string | null;
|
|
1410
|
+
buyer_ref?: string | null;
|
|
1411
|
+
} | null;
|
|
1412
|
+
buyerRef?: string | null;
|
|
1413
|
+
buyer_ref?: string | null;
|
|
1414
|
+
[key: string]: unknown;
|
|
1415
|
+
}
|
|
1416
|
+
/**
|
|
1417
|
+
* The buyer reference of a `vio:payment-success` / `vio:checkout-open`
|
|
1418
|
+
* detail, wherever its emitter put it: top-level (`buyerRef`, or `buyer_ref`
|
|
1419
|
+
* as the backend spells it), on the result, on the result's `confirmation`
|
|
1420
|
+
* (Apple Pay) or `checkout`. Only a reference survives — never an email
|
|
1421
|
+
* (`normalizeBuyerRef`).
|
|
1422
|
+
*/
|
|
1423
|
+
declare function buyerRefOf(d: {
|
|
1424
|
+
buyerRef?: unknown;
|
|
1425
|
+
buyer_ref?: unknown;
|
|
1426
|
+
result?: PaymentSuccessResult | null;
|
|
1427
|
+
} | null | undefined): string | undefined;
|
|
1428
|
+
/**
|
|
1429
|
+
* The `order_id` and `buyer_id` of a `purchase`. The id is ALWAYS a Vio id, never a provider's
|
|
1430
|
+
* reference. Normalized across every emitter: `orderId` (redirect return) →
|
|
1431
|
+
* `result.confirmation.orderId` (Apple Pay) → `checkoutId`. `value` and
|
|
1432
|
+
* `currency` are deliberately NOT read from the result: on every path they
|
|
1433
|
+
* come from the cart snapshot (sum of the items, no shipping), so revenue
|
|
1434
|
+
* stays comparable across payment methods — the charged total will arrive
|
|
1435
|
+
* through the server-side `order_paid` event. With nothing to say it
|
|
1436
|
+
* returns `{}`, so the cart snapshot keeps its keys.
|
|
1437
|
+
*/
|
|
1438
|
+
declare function purchaseFromPaymentSuccess(d: PaymentSuccessDetail): Pick<AnalyticsCommerce, 'orderId' | 'buyerId'>;
|
|
1439
|
+
|
|
1440
|
+
/**
|
|
1441
|
+
* The cart split per campaign (ADR-0034) — ONE rule, shared by the SDK's own
|
|
1442
|
+
* `begin_checkout` / `purchase` events, by `Vio.cartSlices()` and so by any
|
|
1443
|
+
* host with its own analytics sink (Vev).
|
|
1444
|
+
*
|
|
1445
|
+
* Every unit of every line goes to the campaign of its origin — the one the
|
|
1446
|
+
* place showed when it was added — and units without one to the campaign the
|
|
1447
|
+
* caller's rule resolves for the line's sponsor (`resolveCampaign`). One slice
|
|
1448
|
+
* per campaign: its items (quantities from the origins, merged per product +
|
|
1449
|
+
* variant), its value with two decimals, and `slot` / `contentId` /
|
|
1450
|
+
* `sponsorId` only when they are the same for the whole slice. A cart with
|
|
1451
|
+
* one campaign is one slice. Pure; never throws on odd lines.
|
|
1452
|
+
*/
|
|
1453
|
+
|
|
1454
|
+
/** An item of a slice — the analytics item shape (ids as given, normalized on the wire). */
|
|
1455
|
+
type VioItem = AnalyticsItemInput;
|
|
1456
|
+
/** One campaign's share of the cart. */
|
|
1457
|
+
interface CartSlice {
|
|
1458
|
+
campaignId?: number;
|
|
1459
|
+
sponsorId?: number;
|
|
1460
|
+
slot?: string;
|
|
1461
|
+
contentId?: string;
|
|
1462
|
+
items: VioItem[];
|
|
1463
|
+
value: number;
|
|
1464
|
+
currency?: string;
|
|
1465
|
+
/** 1-based position of this slice and how many there are. */
|
|
1466
|
+
slice: number;
|
|
1467
|
+
slices: number;
|
|
1468
|
+
}
|
|
1469
|
+
/** The campaign of a unit without an explicit one: the caller's rule (slot assignment → sponsor → default). */
|
|
1470
|
+
type ResolveCampaign = (slot: string | undefined, sponsorId: number) => number | undefined;
|
|
1471
|
+
declare function cartSlicesFrom(lines: ReadonlyArray<CartLineItem>, resolveCampaign: ResolveCampaign, fallbackCurrency?: string): CartSlice[];
|
|
1472
|
+
|
|
1473
|
+
/**
|
|
1474
|
+
* The attribution of a checkout (ADR-0035 phase B): what the order is born
|
|
1475
|
+
* knowing about the surface it was sold from, the campaign of the page, the
|
|
1476
|
+
* page itself and where the shopper came in from. Sent as `attribution` on
|
|
1477
|
+
* `CreateCheckout` and on the `UpdateCheckout` right before paying; shopcart
|
|
1478
|
+
* keeps it on the checkout (`checkout.attribution`, merged key by key) and
|
|
1479
|
+
* writes `order.surface_id` / `campaign_id` / `content_url` / `content_title`
|
|
1480
|
+
* / `entry_source` from it when the order is created. The surface itself is
|
|
1481
|
+
* checked there against the cart's channel: a page cannot credit a sale to
|
|
1482
|
+
* somebody else's surface.
|
|
1483
|
+
*
|
|
1484
|
+
* Pure: `checkoutAttributionOf()` takes what the facade gathered. snake_case
|
|
1485
|
+
* on the wire, the caps of shopcart's `CheckoutAttributionDto` enforced here.
|
|
1486
|
+
*/
|
|
1487
|
+
|
|
1488
|
+
/** `EntryContextDto`: what the page knew when the shopper came in (the SDK's landing memory). */
|
|
1489
|
+
interface EntryContextWire {
|
|
1490
|
+
referrer?: string;
|
|
1491
|
+
utm_source?: string;
|
|
1492
|
+
utm_medium?: string;
|
|
1493
|
+
utm_campaign?: string;
|
|
1494
|
+
landing_url?: string;
|
|
1495
|
+
}
|
|
1496
|
+
/** `CheckoutAttributionDto` (shopcart `checkout/dtos/checkout-attribution.dto.ts`). */
|
|
1497
|
+
interface CheckoutAttributionWire {
|
|
1498
|
+
surface_key?: string;
|
|
1499
|
+
campaign_id?: number;
|
|
1500
|
+
content_url?: string;
|
|
1501
|
+
content_title?: string;
|
|
1502
|
+
entry?: EntryContextWire;
|
|
1503
|
+
}
|
|
1504
|
+
/** The caps of `CheckoutAttributionDto` / `EntryContextDto`. */
|
|
1505
|
+
declare const CHECKOUT_ATTRIBUTION_CAPS: Readonly<{
|
|
1506
|
+
surfaceKey: 255;
|
|
1507
|
+
contentUrl: 2048;
|
|
1508
|
+
contentTitle: 255;
|
|
1509
|
+
referrer: 2048;
|
|
1510
|
+
utm: 128;
|
|
1511
|
+
landingUrl: 2048;
|
|
1512
|
+
}>;
|
|
1513
|
+
interface CheckoutAttributionInput {
|
|
1514
|
+
/** The surface's SDK key (`Vio.init({ apiKey })`) — shopcart resolves the surface from it. */
|
|
1515
|
+
surfaceKey?: string;
|
|
1516
|
+
/** The campaign the PAGE belongs to, when the bootstrap lists it as active (`Vio.pageCampaign()`). */
|
|
1517
|
+
pageCampaignId?: number;
|
|
1518
|
+
/** The cart split per campaign (`Vio.cartSlices(sponsorId)`), for the campaign that explains most units when the page has none. */
|
|
1519
|
+
slices?: ReadonlyArray<CartSlice>;
|
|
1520
|
+
/** The page at pay time: `Vio.content()`'s url and title. */
|
|
1521
|
+
content?: {
|
|
1522
|
+
url?: string;
|
|
1523
|
+
title?: string;
|
|
1524
|
+
};
|
|
1525
|
+
/** Where the session came in (`resolveLanding()`): referrer, utm, landing page. */
|
|
1526
|
+
landing?: Landing | null;
|
|
1527
|
+
/**
|
|
1528
|
+
* The surface's privacy mode. Only on a `standard` surface do the page
|
|
1529
|
+
* (`content_url`, `content_title`) and the entry context travel: which
|
|
1530
|
+
* screen the sale was made on and why the shopper was there is what
|
|
1531
|
+
* `minimal` keeps private — the same promise the collector keeps for the
|
|
1532
|
+
* events. `unknown` (it could not be learnt) counts as `minimal`: what can
|
|
1533
|
+
* reveal it is only sent when the surface is known to allow it. The surface
|
|
1534
|
+
* and the campaign always travel.
|
|
1535
|
+
*/
|
|
1536
|
+
privacyMode?: SurfacePrivacyMode | 'unknown';
|
|
1537
|
+
}
|
|
1538
|
+
/**
|
|
1539
|
+
* The attribution for the wire, or `undefined` when there is nothing to say.
|
|
1540
|
+
* The campaign is the page's; without one, the campaign that explains most
|
|
1541
|
+
* units of the cart under the same rule `purchase` is split by (ties: the
|
|
1542
|
+
* higher value, then the first). The page (origin + path) and the entry go
|
|
1543
|
+
* only on a `standard` surface.
|
|
1544
|
+
*/
|
|
1545
|
+
declare function checkoutAttributionOf(input: CheckoutAttributionInput): CheckoutAttributionWire | undefined;
|
|
1546
|
+
/** The landing as `entry`, capped; `undefined` when it says nothing. */
|
|
1547
|
+
declare function entryContextOf(landing: Landing | null | undefined): EntryContextWire | undefined;
|
|
1548
|
+
/**
|
|
1549
|
+
* The campaign that explains most units of the cart — over the slices
|
|
1550
|
+
* `purchase` is split by, so the order names the campaign the biggest
|
|
1551
|
+
* purchase event names. Ties go to the higher value, then to the first
|
|
1552
|
+
* slice. Units nobody attributes (a slice without campaign) never win.
|
|
1553
|
+
*/
|
|
1554
|
+
declare function dominantCampaignOf(slices: ReadonlyArray<CartSlice> | null | undefined): number | undefined;
|
|
1555
|
+
|
|
1556
|
+
/**
|
|
1557
|
+
* Vipps MobilePay Payment Adapter — GraphQL Integration & Types.
|
|
1558
|
+
*
|
|
1559
|
+
* Vipps payment integration uses 2 GraphQL operations:
|
|
1560
|
+
*
|
|
1561
|
+
* 1. `CreatePaymentVipps` mutation:
|
|
1562
|
+
* Initiates a Vipps payment session for a checkout and returns `payment_url`.
|
|
1563
|
+
*
|
|
1564
|
+
* 2. `GetVippsStatus` query:
|
|
1565
|
+
* Queries Vipps payment state directly for a checkout (`state`).
|
|
1566
|
+
*/
|
|
1567
|
+
|
|
1568
|
+
/**
|
|
1569
|
+
* GraphQL mutation to create a Vipps payment session.
|
|
1570
|
+
*/
|
|
1571
|
+
declare const CREATE_PAYMENT_VIPPS_MUTATION = "\nmutation CreatePaymentVipps($checkoutId: String!, $email: String, $returnUrl: String!, $express: Boolean) {\n Payment {\n CreatePaymentVipps(checkout_id: $checkoutId, email: $email, return_url: $returnUrl, express: $express) {\n payment_url\n reference\n express\n reason\n }\n }\n}\n";
|
|
1572
|
+
/**
|
|
1573
|
+
* GraphQL query to fetch current Vipps payment status.
|
|
1574
|
+
*/
|
|
1575
|
+
declare const GET_VIPPS_STATUS_QUERY = "\nquery GetVippsStatus($checkoutId: String!) {\n Payment {\n GetVippsStatus(checkout_id: $checkoutId) {\n state\n duplicate_of\n }\n }\n}\n";
|
|
1576
|
+
interface CreatePaymentVippsVariables extends Record<string, unknown> {
|
|
1577
|
+
checkoutId: string;
|
|
1578
|
+
/** Optional since Express: Vipps hands the email back with the payment. */
|
|
1579
|
+
email?: string;
|
|
1580
|
+
returnUrl: string;
|
|
1581
|
+
/**
|
|
1582
|
+
* `true` asks for Express — address and delivery chosen inside the Vipps
|
|
1583
|
+
* app. When the cart cannot have it, no payment is created and the answer
|
|
1584
|
+
* says `express: false` with the reason; the caller then opens the
|
|
1585
|
+
* ordinary checkout.
|
|
1586
|
+
*/
|
|
1587
|
+
express?: boolean;
|
|
1588
|
+
}
|
|
1589
|
+
interface CreatePaymentVippsResponse {
|
|
1590
|
+
/** Absent when Express was asked for and refused. */
|
|
1591
|
+
payment_url?: string;
|
|
1592
|
+
/** The reference the seller reads in its Vipps portal. */
|
|
1593
|
+
reference?: string;
|
|
1594
|
+
express?: boolean;
|
|
1595
|
+
reason?: string;
|
|
1596
|
+
}
|
|
1597
|
+
interface GetVippsStatusVariables extends Record<string, unknown> {
|
|
1598
|
+
checkoutId: string;
|
|
1599
|
+
}
|
|
1600
|
+
interface VippsStatusResult {
|
|
1601
|
+
state: string;
|
|
1602
|
+
/** Set when this checkout was closed as a duplicate: the checkout that paid the cart. */
|
|
1603
|
+
duplicate_of?: string | null;
|
|
1604
|
+
}
|
|
1605
|
+
type VippsPaymentState = 'CREATED' | 'INITIATED' | 'AUTHORIZED' | 'TERMINATED' | 'EXPIRED' | string;
|
|
1606
|
+
/**
|
|
1607
|
+
* Executes the `CreatePaymentVipps` GraphQL mutation.
|
|
1608
|
+
*/
|
|
1609
|
+
declare function createPaymentVipps(variables: CreatePaymentVippsVariables | Record<string, unknown>, options?: CartQueryOptions): Promise<CreatePaymentVippsResponse | null>;
|
|
1610
|
+
/**
|
|
1611
|
+
* Executes the `GetVippsStatus` GraphQL query.
|
|
1612
|
+
*/
|
|
1613
|
+
declare function getVippsStatus(variables: GetVippsStatusVariables | Record<string, unknown>, options?: CartQueryOptions): Promise<VippsStatusResult | null>;
|
|
1614
|
+
|
|
1615
|
+
declare const CREATE_CART_MUTATION = "\nmutation CreateCart($customerSessionId: String!, $currency: String!, $shippingCountry: String) {\n Cart {\n CreateCart(customer_session_id: $customerSessionId, currency: $currency, shipping_country: $shippingCountry) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
|
|
1616
|
+
declare const ADD_ITEM_MUTATION = "\nmutation AddItem($cartId: String!, $lineItems: [LineItemInput!]!) {\n Cart {\n AddItem(cart_id: $cartId, line_items: $lineItems) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
|
|
1617
|
+
declare const DELETE_ITEM_MUTATION = "\nmutation DeleteItem($cartId: String!, $cartItemId: String!) {\n Cart {\n DeleteItem(cart_id: $cartId, cart_item_id: $cartItemId) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
|
|
1618
|
+
declare const UPDATE_ITEM_MUTATION: string;
|
|
1619
|
+
/** `UpdateItem` with the `origin` of the added units (`CartLineOriginInput`, snake_case fields — see `lineOriginWire`). */
|
|
1620
|
+
declare const UPDATE_ITEM_WITH_ORIGIN_MUTATION: string;
|
|
1621
|
+
declare const GET_CART_QUERY = "\nquery GetCart($cartId: String!) {\n Cart {\n GetCart(cart_id: $cartId) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
|
|
1622
|
+
declare const GET_LINE_ITEMS_BY_SUPPLIER_QUERY = "\nquery GetLineItemsBySupplier($cartId: String!) {\n Cart {\n GetLineItemsBySupplier(cart_id: $cartId) {\n supplier {\n id\n name\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n }\n }\n}\n";
|
|
1623
|
+
declare const UPDATE_SHIPPINGS_BY_SUPPLIER_MUTATION = "\nmutation UpdateShippingsBySupplier($cartId: String!, $data: [DataUpdateShippingsBySupplier!]!) {\n Cart {\n UpdateShippingsBySupplier(cart_id: $cartId, data: $data) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
|
|
1624
|
+
declare const CREATE_CHECKOUT_MUTATION: string;
|
|
1625
|
+
/** `CreateCheckout` with the checkout's `attribution` (`CheckoutAttributionInput`, snake_case fields — see `checkoutAttributionOf`). */
|
|
1626
|
+
declare const CREATE_CHECKOUT_WITH_ATTRIBUTION_MUTATION: string;
|
|
1627
|
+
declare const UPDATE_CHECKOUT_MUTATION: string;
|
|
1628
|
+
/** `UpdateCheckout` with the checkout's `attribution` (`CheckoutAttributionInput`). */
|
|
1629
|
+
declare const UPDATE_CHECKOUT_WITH_ATTRIBUTION_MUTATION: string;
|
|
1630
|
+
declare const GET_CHECKOUT_QUERY = "\nquery GetCheckout($checkoutId: String!) {\n Checkout {\n GetCheckout(checkout_id: $checkoutId) {\n buyer_accepts_purchase_conditions\n buyer_accepts_terms_conditions\n created_at\n updated_at\n id\n deleted_at\n success_url\n cancel_url\n payment_method\n email\n status\n checkout_url\n origin_payment_id\n duplicate_of\n billing_address {\n id\n first_name\n last_name\n phone_code\n phone\n company\n address1\n address2\n city\n province\n province_code\n country\n country_code\n zip\n }\n shipping_address {\n id\n first_name\n last_name\n phone_code\n phone\n company\n address1\n address2\n city\n province\n province_code\n country\n country_code\n zip\n }\n available_payment_methods {\n name\n }\n discount_code\n cart {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n totals {\n currency_code\n subtotal\n shipping\n total\n taxes\n tax_rate\n discounts\n }\n }\n }\n}\n";
|
|
1631
|
+
declare const GET_AVAILABLE_PAYMENT_METHODS_QUERY = "\nquery Config {\n Payment {\n GetAvailablePaymentMethods {\n config {\n name\n type\n value\n }\n name\n }\n }\n}\n";
|
|
1632
|
+
|
|
1633
|
+
/** Transport options for a cart/checkout GraphQL call. */
|
|
1634
|
+
interface CartQueryOptions {
|
|
1635
|
+
endpoint?: string;
|
|
1636
|
+
apiKey?: string;
|
|
1637
|
+
/** Sponsor commerce key — goes in the Authorization header. */
|
|
1638
|
+
commerceKey?: string;
|
|
1639
|
+
/** True when the commerce key came from a resolved sponsor (bootstrap).
|
|
1640
|
+
* False = we fell back to the host apiKey — writes like CreateCart should
|
|
1641
|
+
* NOT proceed with the wrong key (the cart would be orphaned). */
|
|
1642
|
+
sponsorResolved?: boolean;
|
|
1643
|
+
}
|
|
1644
|
+
/**
|
|
1645
|
+
* Resolve endpoint + keys for cart GraphQL calls. Awaits Vio.bootstrap() once
|
|
1646
|
+
* if it hasn't run yet (the sponsor commerce keys come from bootstrap), then
|
|
1647
|
+
* uses the sponsor's commerce apiKey (via the Vio facade on globalThis,
|
|
1648
|
+
* avoiding an import cycle); falls back to the host apiKey.
|
|
1649
|
+
*/
|
|
1650
|
+
declare function getCartGraphQLOptions(sponsorId?: number): Promise<CartQueryOptions>;
|
|
1651
|
+
/** Stable per-browser customer session id (backend CreateCart requires one). */
|
|
1652
|
+
declare function getCustomerSessionId(): string;
|
|
1653
|
+
interface GraphQLEnvelope {
|
|
1654
|
+
data?: Record<string, Record<string, unknown>> | null;
|
|
1655
|
+
errors?: Array<{
|
|
1656
|
+
message?: string;
|
|
1657
|
+
path?: unknown;
|
|
1658
|
+
}>;
|
|
1659
|
+
}
|
|
1660
|
+
/** Execute a GraphQL query/mutation against the configured commerce endpoint.
|
|
1661
|
+
* Callers that skip `getCartGraphQLOptions()` (or pass a bare sponsorId) get
|
|
1662
|
+
* it resolved here instead of silently sending an unauthenticated request.
|
|
1663
|
+
* Rejects after `CART_GRAPHQL_TIMEOUT_MS` (and aborts the fetch). */
|
|
1664
|
+
declare function executeCartGraphQL(query: string, variables: Record<string, unknown>, options?: CartQueryOptions | number | undefined): Promise<GraphQLEnvelope>;
|
|
1665
|
+
declare function createCart(customerSessionId: string, currency: string, shippingCountry?: string | null, options?: CartQueryOptions): Promise<any>;
|
|
1666
|
+
/**
|
|
1667
|
+
* `AddItem`. A line may carry `origin` (`LineOriginWire`: where its units
|
|
1668
|
+
* come from — ADR-0035 phase B). A gateway that predates the field refuses
|
|
1669
|
+
* the whole mutation at validation (`LineItemInput` has no `origin`), so the
|
|
1670
|
+
* lines are sent again without it, once per page load — see gateway-features.
|
|
1671
|
+
*/
|
|
1672
|
+
declare function addItem(cartId: string, lineItems: unknown[], options?: CartQueryOptions): Promise<any>;
|
|
1673
|
+
declare function deleteItem(cartId: string, cartItemId: string, options?: CartQueryOptions): Promise<any>;
|
|
1674
|
+
/**
|
|
1675
|
+
* `UpdateItem`. `extra.origin` is where the units a quantity INCREASE adds
|
|
1676
|
+
* come from (ADR-0035 phase B); the server credits the new units to it. Sent
|
|
1677
|
+
* only with it; a gateway that predates the argument gets the legacy
|
|
1678
|
+
* mutation instead, once per page load — see gateway-features.
|
|
1679
|
+
*/
|
|
1680
|
+
declare function updateItem(cartId: string, cartItemId: string, shippingId?: string | null, qty?: number | null, options?: CartQueryOptions, extra?: {
|
|
1681
|
+
origin?: LineOriginWire;
|
|
1682
|
+
}): Promise<any>;
|
|
1683
|
+
declare function getCart(cartId: string, options?: CartQueryOptions): Promise<any>;
|
|
1684
|
+
declare function getLineItemsBySupplier(cartId: string, options?: CartQueryOptions): Promise<any>;
|
|
1685
|
+
declare function updateShippingsBySupplier(cartId: string, data: unknown[], options?: CartQueryOptions): Promise<any>;
|
|
1686
|
+
/**
|
|
1687
|
+
* `CreateCheckout`. With `extra.attribution` (`CheckoutAttributionWire`:
|
|
1688
|
+
* the surface, the page's campaign, the page and the entry — ADR-0035 phase
|
|
1689
|
+
* B) the checkout is born attributed; a gateway that predates the argument
|
|
1690
|
+
* gets the legacy mutation, once per page load — see gateway-features.
|
|
1691
|
+
*/
|
|
1692
|
+
declare function createCheckout(cartId: string, options?: CartQueryOptions, extra?: {
|
|
1693
|
+
attribution?: CheckoutAttributionWire;
|
|
1694
|
+
}): Promise<any>;
|
|
1695
|
+
/**
|
|
1696
|
+
* `UpdateCheckout`. `variables.attribution` (`CheckoutAttributionWire`) is
|
|
1697
|
+
* merged key by key over what the checkout has; a gateway that predates the
|
|
1698
|
+
* argument gets the legacy mutation without it, once per page load.
|
|
1699
|
+
*/
|
|
1700
|
+
declare function updateCheckout(variables: Record<string, unknown>, options?: CartQueryOptions): Promise<any>;
|
|
1701
|
+
declare function getCheckout(checkoutId: string, options?: CartQueryOptions): Promise<any>;
|
|
1702
|
+
/** What a checkout says of itself after paying: its Vio order number, once the order exists, and its buyer reference. */
|
|
1703
|
+
interface CheckoutReference {
|
|
1704
|
+
orderNumber: number | null;
|
|
1705
|
+
buyerRef: string | null;
|
|
1706
|
+
}
|
|
1707
|
+
/** The order number (null while the order does not exist yet) and the buyer reference (null when the API does not say it). */
|
|
1708
|
+
declare function getCheckoutReference(checkoutId: string, options?: CartQueryOptions): Promise<CheckoutReference>;
|
|
1709
|
+
declare function getAvailablePaymentMethods(options?: CartQueryOptions): Promise<any>;
|
|
1710
|
+
declare const CREATE_PAYMENT_STRIPE_MUTATION = "\nmutation CreatePaymentStripe($checkoutId: String!, $successUrl: String!, $paymentMethod: String!, $email: String!) {\n Payment {\n CreatePaymentStripe(checkout_id: $checkoutId, success_url: $successUrl, payment_method: $paymentMethod, email: $email) {\n order_id\n checkout_url\n }\n }\n}\n";
|
|
1711
|
+
declare function createPaymentStripe(variables: Record<string, unknown>, options?: CartQueryOptions): Promise<any>;
|
|
1712
|
+
|
|
1713
|
+
/**
|
|
1714
|
+
* Stripe on our own page — the Payment Element, no redirect.
|
|
1715
|
+
*
|
|
1716
|
+
* The older web flow minted a Stripe Payment Link and sent the shopper to a
|
|
1717
|
+
* page hosted by Stripe. This one keeps them here (Angelo, 2026-09-24):
|
|
1718
|
+
*
|
|
1719
|
+
* 1. Vio Commerce creates a PaymentIntent for the checkout
|
|
1720
|
+
* (`Payment { CreatePaymentIntentStripe }`) and answers with its client
|
|
1721
|
+
* secret AND the publishable key of the account that minted it — the
|
|
1722
|
+
* seller's when they brought both keys, ours otherwise. The two are
|
|
1723
|
+
* halves of one account: the browser confirms with the key what the
|
|
1724
|
+
* server minted with the secret one.
|
|
1725
|
+
* 2. Stripe's Payment Element is mounted in a LIGHT-DOM container, the way
|
|
1726
|
+
* the other embedded widgets are. Card fields are Stripe's own iframes,
|
|
1727
|
+
* so card data never touches this SDK or our servers.
|
|
1728
|
+
* 3. `confirm()` pays. A 3-D Secure challenge opens in Stripe's own modal
|
|
1729
|
+
* over the page: `redirect: 'if_required'` keeps the shopper here for
|
|
1730
|
+
* cards, and still redirects for a method that has no other way.
|
|
1731
|
+
* 4. The Commerce order is NOT born here. Stripe's `payment_intent.succeeded`
|
|
1732
|
+
* webhook creates it, verified server-side; the checkout is polled for
|
|
1733
|
+
* its status afterwards, exactly as the redirect return does.
|
|
1734
|
+
*/
|
|
1735
|
+
|
|
1736
|
+
/** What the backend hands over to pay a checkout on our page. */
|
|
1737
|
+
interface StripeIntent {
|
|
1738
|
+
/** `pi_..._secret_...`: what the browser confirms. */
|
|
1739
|
+
client_secret: string;
|
|
1740
|
+
/** The key of the SAME account that minted the secret. */
|
|
1741
|
+
publishable_key: string;
|
|
1742
|
+
customer?: string;
|
|
1743
|
+
/**
|
|
1744
|
+
* Stripe Connect (ADR-0022): the seller's connected account, where the
|
|
1745
|
+
* intent lives. The browser must name it or Stripe answers "no such
|
|
1746
|
+
* payment_intent". Absent for every seller not on Connect.
|
|
1747
|
+
*/
|
|
1748
|
+
stripe_account?: string;
|
|
1749
|
+
}
|
|
1750
|
+
/** What `confirm()` answers. The browser's word is never the order. */
|
|
1751
|
+
type StripeConfirmOutcome = {
|
|
1752
|
+
status: 'succeeded';
|
|
1753
|
+
paymentIntentId?: string;
|
|
1754
|
+
}
|
|
1755
|
+
/** Authorised but not settled yet, or Stripe redirected and will return. */
|
|
1756
|
+
| {
|
|
1757
|
+
status: 'pending';
|
|
1758
|
+
paymentIntentId?: string;
|
|
1759
|
+
} | {
|
|
1760
|
+
status: 'failed';
|
|
1761
|
+
message?: string;
|
|
1762
|
+
code?: string;
|
|
1763
|
+
};
|
|
1764
|
+
interface StripeElementHandle {
|
|
1765
|
+
confirm(): Promise<StripeConfirmOutcome>;
|
|
1766
|
+
unmount(): void;
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
/**
|
|
1770
|
+
* Apple Pay on the Web — via Stripe Payment Request API.
|
|
1771
|
+
*
|
|
1772
|
+
* Architecture decision (matches iOS Vio SDK pattern):
|
|
1773
|
+
* - One Stripe **publishable key** for the Vio platform (global, set
|
|
1774
|
+
* via `Vio.init({ stripePublishableKey })`).
|
|
1775
|
+
* - One **Stripe Connect account id** per sponsor — sourced from
|
|
1776
|
+
* `Vio.bootstrap()` response. Without it, the payment lands on the
|
|
1777
|
+
* platform account instead of the merchant.
|
|
1778
|
+
*
|
|
1779
|
+
* Apple Pay on the Web prerequisites (Stripe-managed for us):
|
|
1780
|
+
* - Stripe Connect account is enabled for Apple Pay
|
|
887
1781
|
* - Domain registration for Apple Pay (Stripe handles via Dashboard)
|
|
888
1782
|
* - Safari + macOS/iOS device with Apple Pay configured
|
|
889
1783
|
*
|
|
@@ -1492,8 +2386,20 @@ interface KlarnaPaymentsHandle {
|
|
|
1492
2386
|
/** Tear down the mounted widget. */
|
|
1493
2387
|
unmount(): void;
|
|
1494
2388
|
}
|
|
2389
|
+
/**
|
|
2390
|
+
* What the facade lends the manager. `orderAttribution` answers the
|
|
2391
|
+
* attribution of the order about to be created for a sponsor's cart
|
|
2392
|
+
* (`Vio.orderAttribution`, ADR-0035 phase B) — the surface, the page's
|
|
2393
|
+
* campaign, the page and the entry; sent as `attribution` on `CreateCheckout`
|
|
2394
|
+
* and on the `UpdateCheckout` before paying. Optional: without it (a manager
|
|
2395
|
+
* built apart from the facade) nothing is sent and nothing changes.
|
|
2396
|
+
*/
|
|
2397
|
+
interface CheckoutManagerDeps {
|
|
2398
|
+
orderAttribution?: (sponsorId: number) => Promise<CheckoutAttributionWire | undefined> | CheckoutAttributionWire | undefined;
|
|
2399
|
+
}
|
|
1495
2400
|
declare class CheckoutManager extends EventTarget {
|
|
1496
2401
|
private readonly cartManager;
|
|
2402
|
+
private readonly deps;
|
|
1497
2403
|
private state;
|
|
1498
2404
|
/** Counts `open()` calls — see CheckoutState.session. */
|
|
1499
2405
|
private sessionSeq;
|
|
@@ -1531,12 +2437,18 @@ declare class CheckoutManager extends EventTarget {
|
|
|
1531
2437
|
/** Per-sponsor payment methods cache + in-flight dedupe. */
|
|
1532
2438
|
private paymentMethodsCache;
|
|
1533
2439
|
private paymentMethodsPromises;
|
|
1534
|
-
constructor(cartManager: CartManager);
|
|
2440
|
+
constructor(cartManager: CartManager, deps?: CheckoutManagerDeps);
|
|
1535
2441
|
open(sponsorId: number): CheckoutState;
|
|
1536
2442
|
close(): void;
|
|
1537
|
-
/**
|
|
2443
|
+
/**
|
|
2444
|
+
* The attribution of the order this sponsor's cart is about to become
|
|
2445
|
+
* (ADR-0035 phase B), through the facade; `undefined` when there is none
|
|
2446
|
+
* to give or it fails — attribution never costs a checkout.
|
|
2447
|
+
*/
|
|
2448
|
+
private attributionFor;
|
|
2449
|
+
/** Create the backend checkout for the sponsor's cart (auto-accepts terms); born attributed when the facade knows the attribution. */
|
|
1538
2450
|
createCheckout(sponsorId: number): Promise<any>;
|
|
1539
|
-
/** Update the backend checkout (terms are re-asserted unless overridden). */
|
|
2451
|
+
/** Update the backend checkout (terms are re-asserted unless overridden; the attribution rides along unless the caller gives its own). */
|
|
1540
2452
|
updateCheckout(variables: Record<string, unknown>, sponsorId?: number): Promise<any>;
|
|
1541
2453
|
getCheckout(checkoutId: string, sponsorId?: number): Promise<any>;
|
|
1542
2454
|
/**
|
|
@@ -1545,6 +2457,15 @@ declare class CheckoutManager extends EventTarget {
|
|
|
1545
2457
|
* receipt, and a receipt does not fail for it.
|
|
1546
2458
|
*/
|
|
1547
2459
|
getOrderNumber(checkoutId: string, sponsorId?: number): Promise<number | null>;
|
|
2460
|
+
/**
|
|
2461
|
+
* What a paid checkout says of itself: the order number (as above) and the
|
|
2462
|
+
* buyer reference — shopcart's keyed hash of the buyer's email, what the
|
|
2463
|
+
* `vio:payment-success` detail carries as `buyerRef` and analytics sends as
|
|
2464
|
+
* `buyer_id`. Never throws; `null` for whatever the API does not say.
|
|
2465
|
+
*/
|
|
2466
|
+
getOrderReference(checkoutId: string, sponsorId?: number): Promise<CheckoutReference>;
|
|
2467
|
+
/** In-flight `getOrderReference` per checkout id (see there). */
|
|
2468
|
+
private referenceInFlight;
|
|
1548
2469
|
/**
|
|
1549
2470
|
* Payment methods enabled for the sponsor (backend-configured). Memoised per
|
|
1550
2471
|
* sponsor with in-flight dedupe — several UI components ask on every open.
|
|
@@ -1866,339 +2787,60 @@ declare class CheckoutManager extends EventTarget {
|
|
|
1866
2787
|
*
|
|
1867
2788
|
* Returns the button handle so the UI can unmount on teardown.
|
|
1868
2789
|
*/
|
|
1869
|
-
mountKlarnaExpress(container: HTMLElement): Promise<KlarnaButtonHandle>;
|
|
1870
|
-
/**
|
|
1871
|
-
* Klarna Payments — classic widget flow (server client_token). Creates a
|
|
1872
|
-
* session on vio-backend, then mounts Klarna's inline widget into
|
|
1873
|
-
* `container`. Returns a handle to switch category and to authorize → which
|
|
1874
|
-
* on approval creates the order via the same backend /orders route as KEC.
|
|
1875
|
-
*
|
|
1876
|
-
* Unlike `mountKlarnaExpress`, this needs no public `klarnaClientId` and no
|
|
1877
|
-
* origin handshake — auth is the server-side API key.
|
|
1878
|
-
*/
|
|
1879
|
-
mountKlarnaPayments(container: HTMLElement, opts?: {
|
|
1880
|
-
withShipping?: boolean;
|
|
1881
|
-
shippingId?: string;
|
|
1882
|
-
category?: string;
|
|
1883
|
-
}): Promise<KlarnaPaymentsHandle>;
|
|
1884
|
-
/** True if the Klarna Payments widget lib can load (UI gate). */
|
|
1885
|
-
klarnaPaymentsAvailable(): Promise<boolean>;
|
|
1886
|
-
/** Cart snapshot + chosen shipping line/amount, for express purchases. */
|
|
1887
|
-
private buildKlarnaInstantContext;
|
|
1888
|
-
/**
|
|
1889
|
-
* Express instant purchase — go straight to Klarna's own modal, no checkout
|
|
1890
|
-
* overlay. Creates a session (with shipping options), loads the widget into a
|
|
1891
|
-
* hidden container, then authorizes (which opens Klarna's confirm modal). On
|
|
1892
|
-
* approval creates the order → `payment-complete` (host shows confirmation);
|
|
1893
|
-
* on failure → `payment-error`. Call `open(sponsorId)` first.
|
|
1894
|
-
*/
|
|
1895
|
-
startKlarnaInstant(): Promise<void>;
|
|
1896
|
-
/**
|
|
1897
|
-
* REDIRECT path: call once on app load. If a Klarna purchase was launched
|
|
1898
|
-
* (pending context persisted) and we're back with a token — from the URL or
|
|
1899
|
-
* the SDK's resumed `complete` event — finish creating the order + confirm.
|
|
1900
|
-
*/
|
|
1901
|
-
resumeKlarnaReturn(): Promise<void>;
|
|
1902
|
-
/** Snapshot of the active cart for redirect recovery (minor units). */
|
|
1903
|
-
private buildKlarnaPendingContext;
|
|
1904
|
-
/**
|
|
1905
|
-
* POST the token + order lines to vio-backend (it holds the secret API key
|
|
1906
|
-
* and creates the real Klarna order). On success → `payment-complete`; on
|
|
1907
|
-
* failure → `payment-error`. Idempotent: clears the pending key so the
|
|
1908
|
-
* popup and redirect paths can't double-fire.
|
|
1909
|
-
*/
|
|
1910
|
-
private completeKlarnaOrder;
|
|
1911
|
-
get currentState(): CheckoutState | null;
|
|
1912
|
-
get items(): CartLineItem[];
|
|
1913
|
-
/**
|
|
1914
|
-
* Resolve the Stripe Connect account for the active sponsor — for now
|
|
1915
|
-
* pulled from bootstrap cache if present. Returns undefined if not set
|
|
1916
|
-
* (Stripe will route to the platform account in that case).
|
|
1917
|
-
*/
|
|
1918
|
-
private findStripeConnectAccount;
|
|
1919
|
-
/** The sponsor's connected account, read fresh from its channel config. */
|
|
1920
|
-
private resolveStripeConnectAccount;
|
|
1921
|
-
private emit;
|
|
1922
|
-
}
|
|
1923
|
-
|
|
1924
|
-
/**
|
|
1925
|
-
* Vio.analytics — the web SDK's half of the Vio Analytics pipeline.
|
|
1926
|
-
*
|
|
1927
|
-
* Events flow to the Vio collector (`POST <eventsBase>/v1/events`, repo
|
|
1928
|
-
* vio-live/vio-analytics) which owns raw storage (ClickHouse) and vendor
|
|
1929
|
-
* fan-out (Mixpanel today). THE SDK NEVER TALKS TO VENDORS — swapping or
|
|
1930
|
-
* dropping a vendor is a server-side change, zero client releases.
|
|
1931
|
-
* Wire contract: vio-analytics `docs/EVENTS_CONTRACT.md` (v1, snake_case).
|
|
1932
|
-
*
|
|
1933
|
-
* Design rules:
|
|
1934
|
-
* - SIDE-EFFECT-FREE MODULE. Nothing runs at import time (tsup/tree-shaking
|
|
1935
|
-
* contract, see lessons/web-sdk-tsup-singleton-and-build). Listeners are
|
|
1936
|
-
* installed by an explicit `Vio.analytics.start()`.
|
|
1937
|
-
* - `track()` works BEFORE `Vio.init()` — events queue and flush once the
|
|
1938
|
-
* SDK is configured (transport resolves at flush time, not at track time).
|
|
1939
|
-
* - SSR-safe: without `window` every call is a silent no-op.
|
|
1940
|
-
* - Retries are safe: `event_id` is stable per event, the collector
|
|
1941
|
-
* dedupes. Queue is bounded (drop-oldest) so a dead collector can never
|
|
1942
|
-
* grow memory unbounded.
|
|
1943
|
-
* - Anti-double-count: the SDK only reports what the server can't see.
|
|
1944
|
-
* Votes/participations are server truth; `ad_activation`/`cart_intent`
|
|
1945
|
-
* are mirrored server-side, never from here.
|
|
1946
|
-
*
|
|
1947
|
-
* Three sinks, matching the Vev precedent (vio-vev analytics.ts, which
|
|
1948
|
-
* becomes an adapter over this in F3):
|
|
1949
|
-
* 1. collector (default ON once started)
|
|
1950
|
-
* 2. window.dataLayer — GA4/GTM (opt-in `start({ dataLayer: true })`,
|
|
1951
|
-
* the publisher-facing feature; NOT part of the Vio pipeline)
|
|
1952
|
-
* 3. `vio:analytics` DOM event — always when started (inspector/bridges)
|
|
1953
|
-
*/
|
|
1954
|
-
|
|
1955
|
-
declare const ANALYTICS_EVENT_NAMES: readonly ["view_item_list", "select_item", "view_item", "add_to_cart", "remove_from_cart", "view_cart", "begin_checkout", "purchase", "component_impression", "component_click", "ad_impression", "ad_click", "poll_impression", "contest_impression", "session_start", "session_end", "checkout_error", "sdk_error"];
|
|
1956
|
-
type AnalyticsEventName = (typeof ANALYTICS_EVENT_NAMES)[number];
|
|
1957
|
-
/** Camel-case for DX; mapped to the snake_case wire format at build time. */
|
|
1958
|
-
interface AnalyticsContext {
|
|
1959
|
-
campaignId?: number;
|
|
1960
|
-
broadcastId?: string;
|
|
1961
|
-
campaignComponentId?: number;
|
|
1962
|
-
appPlacementId?: number;
|
|
1963
|
-
locationId?: string;
|
|
1964
|
-
componentTemplateId?: string;
|
|
1965
|
-
sponsorId?: number;
|
|
1966
|
-
activationId?: number;
|
|
1967
|
-
contentUrl?: string;
|
|
1968
|
-
/**
|
|
1969
|
-
* The host's own id for the piece of content the component sits in — an
|
|
1970
|
-
* article id in a CMS, a page id in a site builder. Carried verbatim so the
|
|
1971
|
-
* host can join Vio's funnel back onto its own per-article reporting
|
|
1972
|
-
* (revenue stops being an estimate). Left alone by the SDK.
|
|
1973
|
-
*/
|
|
1974
|
-
contentId?: string | number;
|
|
1975
|
-
/** Human-readable content snapshot; auto-filled from document.title. */
|
|
1976
|
-
contentTitle?: string;
|
|
1977
|
-
/** Código corto del fallo (`sdk_error` / `checkout_error`). */
|
|
1978
|
-
errorCode?: string;
|
|
1979
|
-
variant?: string;
|
|
1980
|
-
/**
|
|
1981
|
-
* The slot (ADR-0027) the component sits in — its `vio-slot`. Attribution
|
|
1982
|
-
* follows it: the event's `campaign_id` is the campaign assigned to the slot
|
|
1983
|
-
* right now, before the sponsor rule. On the wire it fills `location_id`
|
|
1984
|
-
* when no explicit `locationId` is given (a slot IS a location id to the
|
|
1985
|
-
* campaigns service).
|
|
1986
|
-
*/
|
|
1987
|
-
slot?: string;
|
|
1988
|
-
}
|
|
1989
|
-
interface AnalyticsItemInput {
|
|
1990
|
-
productId: number | string;
|
|
1991
|
-
name?: string;
|
|
1992
|
-
brand?: string;
|
|
1993
|
-
variantId?: number | string;
|
|
1994
|
-
price?: number;
|
|
1995
|
-
quantity?: number;
|
|
1996
|
-
}
|
|
1997
|
-
interface AnalyticsCommerce {
|
|
1998
|
-
items?: AnalyticsItemInput[];
|
|
1999
|
-
value?: number;
|
|
2000
|
-
currency?: string;
|
|
2001
|
-
orderId?: string;
|
|
2002
|
-
paymentMethod?: string;
|
|
2003
|
-
}
|
|
2004
|
-
interface TrackOptions {
|
|
2005
|
-
context?: AnalyticsContext;
|
|
2006
|
-
commerce?: AnalyticsCommerce;
|
|
2007
|
-
props?: Record<string, unknown>;
|
|
2008
|
-
}
|
|
2009
|
-
interface AnalyticsStartOptions {
|
|
2010
|
-
/** Where the SDK is embedded: 'vev' | 'replit' | 'custom' | … Default 'custom'. */
|
|
2011
|
-
host?: string;
|
|
2012
|
-
/**
|
|
2013
|
-
* Arrancar en modo cookieless hasta que el host llame `setConsent(true)`.
|
|
2014
|
-
* Default false: el SDK asume que el CMP del publisher ya decidió si nos
|
|
2015
|
-
* carga. Los publishers EU que necesitan medir antes del consentimiento
|
|
2016
|
-
* (o no pueden persistir sin él) ponen true.
|
|
2017
|
-
*/
|
|
2018
|
-
requireConsent?: boolean;
|
|
2019
|
-
/**
|
|
2020
|
-
* Install the automatic funnel listeners (vio:added-to-cart,
|
|
2021
|
-
* vio:checkout-open, vio:open-cart, vio:payment-success). Default true.
|
|
2022
|
-
* Hosts with their OWN instrumentation choke point (e.g. the Vev module,
|
|
2023
|
-
* which forwards every event through trackEvent()) set false so the same
|
|
2024
|
-
* user action is never tracked twice — they keep the session/batching/
|
|
2025
|
-
* transport engine and call track() themselves.
|
|
2026
|
-
*/
|
|
2027
|
-
autoTrack?: boolean;
|
|
2028
|
-
/**
|
|
2029
|
-
* Adopt the host's session id instead of minting one. A host that already
|
|
2030
|
-
* tracks its readers (its own impressions, dwell, clicks) needs Vio's
|
|
2031
|
-
* purchases to land in the SAME session, or the two datasets cannot be
|
|
2032
|
-
* joined. Pass the id the host already stores; omit it and the SDK keeps
|
|
2033
|
-
* its own rotating session.
|
|
2034
|
-
*/
|
|
2035
|
-
sessionId?: string;
|
|
2036
|
-
/** Send to the Vio collector. Default true. */
|
|
2037
|
-
collector?: boolean;
|
|
2038
|
-
/** Also push GA4 e-commerce events to window.dataLayer (publisher feature). */
|
|
2039
|
-
dataLayer?: boolean;
|
|
2040
|
-
/** console.debug every event. */
|
|
2041
|
-
debug?: boolean;
|
|
2042
|
-
}
|
|
2043
|
-
declare class AnalyticsManager extends EventTarget {
|
|
2044
|
-
private started;
|
|
2045
|
-
private options;
|
|
2046
|
-
private queue;
|
|
2047
|
-
private flushTimer;
|
|
2048
|
-
private retryAttempt;
|
|
2049
|
-
private retryNotBefore;
|
|
2050
|
-
private externalUserId;
|
|
2051
|
-
private sessionId;
|
|
2052
|
-
private requireConsent;
|
|
2053
|
-
private consentGranted;
|
|
2054
|
-
private anonIdCache;
|
|
2055
|
-
/** Set via start({ sessionId }) — the host owns the session, we follow. */
|
|
2056
|
-
private externalSessionId;
|
|
2057
|
-
private sessionStartedAt;
|
|
2058
|
-
/** Impression once-per-(session, component) guard; reset on session rotation. */
|
|
2059
|
-
private impressedComponents;
|
|
2060
|
-
/** Last NON-EMPTY cart snapshot — `purchase` uses it because several flows
|
|
2061
|
-
* (Apple Pay) clear the cart BEFORE `vio:payment-success` fires. */
|
|
2062
|
-
private lastCartSnapshot;
|
|
2063
|
-
private teardown;
|
|
2064
|
-
/**
|
|
2065
|
-
* Install listeners + begin flushing. Explicit on purpose (no module
|
|
2066
|
-
* side-effects). Safe to call twice (second call only updates options).
|
|
2067
|
-
*/
|
|
2068
|
-
/**
|
|
2069
|
-
* Consentimiento (ePrivacy/GDPR). Por defecto el SDK asume que el host ya
|
|
2070
|
-
* lo gestionó — su CMP decide si nos carga. Con `requireConsent: true`
|
|
2071
|
-
* arranca en modo **cookieless**: mide la visita con ids efímeros en
|
|
2072
|
-
* memoria y NO escribe nada en localStorage hasta que el host llame
|
|
2073
|
-
* `setConsent(true)`. Retirarlo borra lo persistido.
|
|
2074
|
-
*/
|
|
2075
|
-
setConsent(granted: boolean): void;
|
|
2076
|
-
/** ¿Podemos escribir en el dispositivo? */
|
|
2077
|
-
private get canPersist();
|
|
2078
|
-
start(options?: AnalyticsStartOptions): void;
|
|
2079
|
-
/** Stop timers + listeners (tests / SPA unmount). Queue survives. */
|
|
2080
|
-
stop(): void;
|
|
2081
|
-
/** Attach the partner's user id (opaque) to all subsequent events. */
|
|
2082
|
-
identify(externalUserId: string | null): void;
|
|
2083
|
-
/** Queue one event. Works pre-init and pre-start (SSR: no-op). */
|
|
2084
|
-
track(name: AnalyticsEventName, opts?: TrackOptions): void;
|
|
2790
|
+
mountKlarnaExpress(container: HTMLElement): Promise<KlarnaButtonHandle>;
|
|
2085
2791
|
/**
|
|
2086
|
-
*
|
|
2087
|
-
*
|
|
2088
|
-
*
|
|
2089
|
-
*
|
|
2792
|
+
* Klarna Payments — classic widget flow (server client_token). Creates a
|
|
2793
|
+
* session on vio-backend, then mounts Klarna's inline widget into
|
|
2794
|
+
* `container`. Returns a handle to switch category and to authorize → which
|
|
2795
|
+
* on approval creates the order via the same backend /orders route as KEC.
|
|
2796
|
+
*
|
|
2797
|
+
* Unlike `mountKlarnaExpress`, this needs no public `klarnaClientId` and no
|
|
2798
|
+
* origin handshake — auth is the server-side API key.
|
|
2090
2799
|
*/
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
/** Force a flush (mostly for tests). */
|
|
2101
|
-
flush(): Promise<void>;
|
|
2102
|
-
private buildEvent;
|
|
2103
|
-
/** Guarda la sesión solo si podemos escribir en el dispositivo. */
|
|
2104
|
-
private persistSession;
|
|
2105
|
-
private anonId;
|
|
2106
|
-
/** Rolling session: renewed by activity, rotated after 30 min idle. */
|
|
2107
|
-
private ensureSession;
|
|
2108
|
-
private trackSessionEnd;
|
|
2109
|
-
private flushWithBeacon;
|
|
2800
|
+
mountKlarnaPayments(container: HTMLElement, opts?: {
|
|
2801
|
+
withShipping?: boolean;
|
|
2802
|
+
shippingId?: string;
|
|
2803
|
+
category?: string;
|
|
2804
|
+
}): Promise<KlarnaPaymentsHandle>;
|
|
2805
|
+
/** True if the Klarna Payments widget lib can load (UI gate). */
|
|
2806
|
+
klarnaPaymentsAvailable(): Promise<boolean>;
|
|
2807
|
+
/** Cart snapshot + chosen shipping line/amount, for express purchases. */
|
|
2808
|
+
private buildKlarnaInstantContext;
|
|
2110
2809
|
/**
|
|
2111
|
-
*
|
|
2112
|
-
*
|
|
2810
|
+
* Express instant purchase — go straight to Klarna's own modal, no checkout
|
|
2811
|
+
* overlay. Creates a session (with shipping options), loads the widget into a
|
|
2812
|
+
* hidden container, then authorizes (which opens Klarna's confirm modal). On
|
|
2813
|
+
* approval creates the order → `payment-complete` (host shows confirmation);
|
|
2814
|
+
* on failure → `payment-error`. Call `open(sponsorId)` first.
|
|
2113
2815
|
*/
|
|
2114
|
-
|
|
2115
|
-
/** The lines of the cart (current, else the pre-clear snapshot), optionally one sponsor's. */
|
|
2116
|
-
private cartLines;
|
|
2816
|
+
startKlarnaInstant(): Promise<void>;
|
|
2117
2817
|
/**
|
|
2118
|
-
*
|
|
2119
|
-
*
|
|
2120
|
-
*
|
|
2818
|
+
* REDIRECT path: call once on app load. If a Klarna purchase was launched
|
|
2819
|
+
* (pending context persisted) and we're back with a token — from the URL or
|
|
2820
|
+
* the SDK's resumed `complete` event — finish creating the order + confirm.
|
|
2121
2821
|
*/
|
|
2122
|
-
|
|
2822
|
+
resumeKlarnaReturn(): Promise<void>;
|
|
2823
|
+
/** Snapshot of the active cart for redirect recovery (minor units). */
|
|
2824
|
+
private buildKlarnaPendingContext;
|
|
2123
2825
|
/**
|
|
2124
|
-
*
|
|
2125
|
-
*
|
|
2126
|
-
*
|
|
2826
|
+
* POST the token + order lines to vio-backend (it holds the secret API key
|
|
2827
|
+
* and creates the real Klarna order). On success → `payment-complete`; on
|
|
2828
|
+
* failure → `payment-error`. Idempotent: clears the pending key so the
|
|
2829
|
+
* popup and redirect paths can't double-fire.
|
|
2127
2830
|
*/
|
|
2128
|
-
private
|
|
2831
|
+
private completeKlarnaOrder;
|
|
2832
|
+
get currentState(): CheckoutState | null;
|
|
2833
|
+
get items(): CartLineItem[];
|
|
2129
2834
|
/**
|
|
2130
|
-
*
|
|
2131
|
-
*
|
|
2132
|
-
*
|
|
2835
|
+
* Resolve the Stripe Connect account for the active sponsor — for now
|
|
2836
|
+
* pulled from bootstrap cache if present. Returns undefined if not set
|
|
2837
|
+
* (Stripe will route to the platform account in that case).
|
|
2133
2838
|
*/
|
|
2134
|
-
private
|
|
2135
|
-
/**
|
|
2136
|
-
private
|
|
2137
|
-
private
|
|
2138
|
-
}
|
|
2139
|
-
/**
|
|
2140
|
-
* The `campaign_id` of an event. In order: the context's explicit id; the
|
|
2141
|
-
* campaign assigned to the context's `slot` right now (ADR-0027 — only an
|
|
2142
|
-
* open assignment for the init platform counts, see `findSlotAssignment`);
|
|
2143
|
-
* the active campaign of `campaigns[]` the event's sponsor takes part in, as
|
|
2144
|
-
* its primary or one of its secondaries — when it is in several, the
|
|
2145
|
-
* surface's default campaign if it is one of them, else the first one the
|
|
2146
|
-
* backend lists; the default campaign (`campaign.id`). `/v2/mobile/config`
|
|
2147
|
-
* has no top-level `campaignId` — reading one is why every event used to
|
|
2148
|
-
* leave with `campaign_id: 0` and the campaigns screen stayed empty.
|
|
2149
|
-
*
|
|
2150
|
-
* A malformed `campaigns[]` (not an array, a null entry) never breaks
|
|
2151
|
-
* `track()`: it falls back to `campaign.id`.
|
|
2152
|
-
*/
|
|
2153
|
-
declare function resolveCampaignId(ctx: Pick<AnalyticsContext, 'campaignId' | 'sponsorId' | 'slot'>, boot: Pick<BootstrapResponse, 'campaign' | 'campaigns'> | null | undefined): number | undefined;
|
|
2154
|
-
/**
|
|
2155
|
-
* `detail` of `vio:payment-success` as the checkout emits it. Four paths,
|
|
2156
|
-
* three shapes: a redirect return (`orderId` = Vio's checkout id), the
|
|
2157
|
-
* confirmation drawer and a provider's own receipt (`result` from the
|
|
2158
|
-
* provider or the backend, plus Vio's `checkoutId`), and Apple Pay express
|
|
2159
|
-
* from the cart (`result` with the backend's `confirmation`, no sponsor).
|
|
2160
|
-
*/
|
|
2161
|
-
interface PaymentSuccessDetail {
|
|
2162
|
-
method?: string;
|
|
2163
|
-
sponsorId?: number | string;
|
|
2164
|
-
/** The slot the purchase started from, when the emitter knows it. */
|
|
2165
|
-
slot?: string;
|
|
2166
|
-
/** The campaign the emitter attributed the purchase to (its `Vio.attribution`). */
|
|
2167
|
-
campaignId?: number;
|
|
2168
|
-
/** Per-element content override (`vio-content-id` / `vio-content-title`), when the emitter carries one. */
|
|
2169
|
-
contentId?: string | number;
|
|
2170
|
-
contentTitle?: string;
|
|
2171
|
-
/** Redirect return: Vio's checkout id (the name predates `checkoutId`). */
|
|
2172
|
-
orderId?: string | number;
|
|
2173
|
-
/** Vio's checkout id — from the checkout state or the return URL. */
|
|
2174
|
-
checkoutId?: string | number;
|
|
2175
|
-
result?: PaymentSuccessResult | null;
|
|
2176
|
-
}
|
|
2177
|
-
/**
|
|
2178
|
-
* What the checkout attaches as `result`. Only `confirmation` carries a Vio
|
|
2179
|
-
* id: the order `ConfirmPaymentApplePay` created. `order.orderId` / `orderId`
|
|
2180
|
-
* are the PROVIDER's references (Qliro's, Walley's — the checkout itself
|
|
2181
|
-
* shows them as `providerRef`), and `chargedTotal` includes shipping on some
|
|
2182
|
-
* methods only. Analytics reads none of those.
|
|
2183
|
-
*/
|
|
2184
|
-
interface PaymentSuccessResult {
|
|
2185
|
-
confirmation?: {
|
|
2186
|
-
orderId?: string | number | null;
|
|
2187
|
-
status?: string;
|
|
2188
|
-
} | null;
|
|
2189
|
-
[key: string]: unknown;
|
|
2839
|
+
private findStripeConnectAccount;
|
|
2840
|
+
/** The sponsor's connected account, read fresh from its channel config. */
|
|
2841
|
+
private resolveStripeConnectAccount;
|
|
2842
|
+
private emit;
|
|
2190
2843
|
}
|
|
2191
|
-
/**
|
|
2192
|
-
* The `order_id` of a `purchase`: ALWAYS a Vio id, never a provider's
|
|
2193
|
-
* reference. Normalized across every emitter: `orderId` (redirect return) →
|
|
2194
|
-
* `result.confirmation.orderId` (Apple Pay) → `checkoutId`. `value` and
|
|
2195
|
-
* `currency` are deliberately NOT read from the result: on every path they
|
|
2196
|
-
* come from the cart snapshot (sum of the items, no shipping), so revenue
|
|
2197
|
-
* stays comparable across payment methods — the charged total will arrive
|
|
2198
|
-
* through the server-side `order_paid` event. With nothing to say it
|
|
2199
|
-
* returns `{}`, so the cart snapshot keeps its keys.
|
|
2200
|
-
*/
|
|
2201
|
-
declare function purchaseFromPaymentSuccess(d: PaymentSuccessDetail): Pick<AnalyticsCommerce, 'orderId'>;
|
|
2202
2844
|
|
|
2203
2845
|
/**
|
|
2204
2846
|
* Content (article) attribution — the other half of "where did this happen".
|
|
@@ -2217,11 +2859,32 @@ declare function purchaseFromPaymentSuccess(d: PaymentSuccessDetail): Pick<Analy
|
|
|
2217
2859
|
interface ContentRef {
|
|
2218
2860
|
id?: string;
|
|
2219
2861
|
title?: string;
|
|
2862
|
+
/** The page's URL as origin + path (no query, no fragment), capped — what the order and the cart's origins carry as `content_url`. */
|
|
2863
|
+
url?: string;
|
|
2220
2864
|
}
|
|
2221
2865
|
interface ContentInit {
|
|
2222
2866
|
contentId?: string | number | null;
|
|
2223
2867
|
contentTitle?: string | null;
|
|
2224
2868
|
}
|
|
2869
|
+
/** The collector (and Commerce's `order.content_url`) cap `content_url` at 2 048 chars. */
|
|
2870
|
+
declare const CONTENT_URL_MAX_LENGTH = 2048;
|
|
2871
|
+
/**
|
|
2872
|
+
* A page as the ORDER and the cart's origins name it (`content_url` to
|
|
2873
|
+
* Commerce): origin + path — no query string, no fragment — within the cap.
|
|
2874
|
+
* The query is where a page carries e-mails, tokens and tracking tails
|
|
2875
|
+
* (`?email=…&utm_…#frag`); none of that belongs on an order row. A site whose
|
|
2876
|
+
* article lives in the query or the hash identifies it through `contentId`
|
|
2877
|
+
* (`Vio.init({ contentId })`, `?vio_content=`), not through the URL. Also
|
|
2878
|
+
* the shape of the landing's referrer and page (client-context.ts).
|
|
2879
|
+
*/
|
|
2880
|
+
declare function originAndPath(raw: unknown, max?: number): string | undefined;
|
|
2881
|
+
/**
|
|
2882
|
+
* A page URL within the cap for the analytics EVENTS — as is, else without
|
|
2883
|
+
* its query string (a long one is usually the tracking tail, not the page),
|
|
2884
|
+
* else cut. The collector keeps the query there (`page_views` strip it
|
|
2885
|
+
* themselves); the order does not (`originAndPath`).
|
|
2886
|
+
*/
|
|
2887
|
+
declare function capContentUrl(value: unknown): string | undefined;
|
|
2225
2888
|
/**
|
|
2226
2889
|
* Id: `Vio.init({ contentId })` → `?vio_content=` → `<meta name="vio:content-id">`
|
|
2227
2890
|
* → `<link rel="canonical">` href or `<meta property="og:url">` (without query
|
|
@@ -2235,95 +2898,7 @@ declare function resolveContent(init?: ContentInit | null, doc?: Document | null
|
|
|
2235
2898
|
search?: string;
|
|
2236
2899
|
} | null | undefined): ContentRef;
|
|
2237
2900
|
|
|
2238
|
-
|
|
2239
|
-
* Slots — the pure half of ADR-0027 / ADR-0034 on the web.
|
|
2240
|
-
*
|
|
2241
|
-
* A slot is a NAME for a place on a page. The page declares its slots to the
|
|
2242
|
-
* campaigns service (`Vio.declareSlots()` / `Vio.registerSlot()` in client.ts),
|
|
2243
|
-
* the dashboard assigns a campaign to each one, optionally with a date window,
|
|
2244
|
-
* and `GET /v2/mobile/config` answers with `campaigns[].slots[]` — only the
|
|
2245
|
-
* assignments whose window is open NOW. Whatever no slot names shows the
|
|
2246
|
-
* surface's default campaign (`campaign`).
|
|
2247
|
-
*
|
|
2248
|
-
* Everything here is side-effect free and never throws on a malformed
|
|
2249
|
-
* bootstrap: a broken `campaigns[]` must never blank a product block or break
|
|
2250
|
-
* `track()`.
|
|
2251
|
-
*/
|
|
2252
|
-
|
|
2253
|
-
/** What `Vio.declareSlots()` accepts per slot. */
|
|
2254
|
-
type SlotInput = string | {
|
|
2255
|
-
id: string;
|
|
2256
|
-
displayName?: string;
|
|
2257
|
-
};
|
|
2258
|
-
type BootLike = Pick<BootstrapResponse, 'campaign' | 'campaigns' | 'primarySponsor' | 'secondarySponsors'>;
|
|
2259
|
-
/**
|
|
2260
|
-
* The campaign a slot shows right now. Among the `status === 'active'`
|
|
2261
|
-
* entries of `campaigns[]`, the one with an assignment named `slot` for this
|
|
2262
|
-
* platform (`platform` null on the assignment, or equal to `platform`) whose
|
|
2263
|
-
* window contains `now` (`startDate <= now < endDate`, null = open). When
|
|
2264
|
-
* several qualify, the surface's default campaign wins, else the first the
|
|
2265
|
-
* backend lists.
|
|
2266
|
-
*
|
|
2267
|
-
* No slot, or no assignment → the default campaign: the `campaigns[]` entry
|
|
2268
|
-
* whose id is `campaign.id`, or a minimal entry built from `campaign` (+ the
|
|
2269
|
-
* top-level sponsors) when the list does not carry it. No bootstrap → null.
|
|
2270
|
-
*/
|
|
2271
|
-
declare function resolveSlotCampaign(boot: BootLike | null | undefined, slot: string | null | undefined, now?: number, platform?: string | null): BootstrapCampaignEntry | null;
|
|
2272
|
-
/** The kinds of Vio element that register themselves. */
|
|
2273
|
-
type SlotKind = 'card' | 'carousel' | 'detail';
|
|
2274
|
-
/**
|
|
2275
|
-
* The id an element gets when the host set no `vio-slot`:
|
|
2276
|
-
* `${scope ? scope + '-' : ''}${kind}-${ordinal + 1}` (`carousel-1`, `card-3`,
|
|
2277
|
-
* `article-123-carousel-1`), `ordinal` being the element's index among the
|
|
2278
|
-
* same-kind Vio elements WITH THE SAME SCOPE, in document order at connect
|
|
2279
|
-
* time. The scope is inherited from the DOM (`vio-scope` on the element, else
|
|
2280
|
-
* the nearest `data-vio-scope` ancestor): a Vev page or a Replit article
|
|
2281
|
-
* (`<body data-vio-scope="article-123">`) gets per-page slots with one line
|
|
2282
|
-
* and no per-element naming; a template that wants slots shared across
|
|
2283
|
-
* articles simply sets no scope. On purpose there is NO page path in the id:
|
|
2284
|
-
* the article goes to analytics as `content_id`, not into the slot. Stable
|
|
2285
|
-
* across reloads while the layout is; a layout change leaves a stale entry,
|
|
2286
|
-
* which ADR-0034 accepts.
|
|
2287
|
-
*/
|
|
2288
|
-
declare function autoSlotId(kind: SlotKind, ordinal: number, scope?: string | null): string;
|
|
2289
|
-
/** `"Carousel 1"`, `"Card 3"` — with ` · ${scopeName}` when the scope has a human label. */
|
|
2290
|
-
declare function autoSlotDisplayName(kind: SlotKind, ordinal: number, scopeName?: string | null): string;
|
|
2291
|
-
/** A scope value fit for an id: trimmed, inner whitespace → `-`. */
|
|
2292
|
-
declare function normalizeScope(scope: string | null | undefined): string;
|
|
2293
|
-
|
|
2294
|
-
/**
|
|
2295
|
-
* The cart split per campaign (ADR-0034) — ONE rule, shared by the SDK's own
|
|
2296
|
-
* `begin_checkout` / `purchase` events, by `Vio.cartSlices()` and so by any
|
|
2297
|
-
* host with its own analytics sink (Vev).
|
|
2298
|
-
*
|
|
2299
|
-
* Every unit of every line goes to the campaign of its origin — the one the
|
|
2300
|
-
* place showed when it was added — and units without one to the campaign the
|
|
2301
|
-
* caller's rule resolves for the line's sponsor (`resolveCampaign`). One slice
|
|
2302
|
-
* per campaign: its items (quantities from the origins, merged per product +
|
|
2303
|
-
* variant), its value with two decimals, and `slot` / `contentId` /
|
|
2304
|
-
* `sponsorId` only when they are the same for the whole slice. A cart with
|
|
2305
|
-
* one campaign is one slice. Pure; never throws on odd lines.
|
|
2306
|
-
*/
|
|
2307
|
-
|
|
2308
|
-
/** An item of a slice — the analytics item shape (ids as given, normalized on the wire). */
|
|
2309
|
-
type VioItem = AnalyticsItemInput;
|
|
2310
|
-
/** One campaign's share of the cart. */
|
|
2311
|
-
interface CartSlice {
|
|
2312
|
-
campaignId?: number;
|
|
2313
|
-
sponsorId?: number;
|
|
2314
|
-
slot?: string;
|
|
2315
|
-
contentId?: string;
|
|
2316
|
-
items: VioItem[];
|
|
2317
|
-
value: number;
|
|
2318
|
-
currency?: string;
|
|
2319
|
-
/** 1-based position of this slice and how many there are. */
|
|
2320
|
-
slice: number;
|
|
2321
|
-
slices: number;
|
|
2322
|
-
}
|
|
2323
|
-
/** The campaign of a unit without an explicit one: the caller's rule (slot assignment → sponsor → default). */
|
|
2324
|
-
type ResolveCampaign = (slot: string | undefined, sponsorId: number) => number | undefined;
|
|
2325
|
-
declare function cartSlicesFrom(lines: ReadonlyArray<CartLineItem>, resolveCampaign: ResolveCampaign, fallbackCurrency?: string): CartSlice[];
|
|
2326
|
-
|
|
2901
|
+
type PrivacyAnswer = SurfacePrivacyMode | 'unknown';
|
|
2327
2902
|
declare class VioFacade {
|
|
2328
2903
|
private apiInstance;
|
|
2329
2904
|
private commerceClients;
|
|
@@ -2336,8 +2911,11 @@ declare class VioFacade {
|
|
|
2336
2911
|
* (another key or environment) is still in flight after a re-init; its answer
|
|
2337
2912
|
* belongs to that configuration and must not land in this one. */
|
|
2338
2913
|
private generation;
|
|
2339
|
-
/** Slot ids present on the page (`Vio.registerSlot`): how many elements hold each
|
|
2914
|
+
/** Slot ids present on the page (`Vio.registerSlot`): how many elements hold each, its display name, its own campaign and its kind. */
|
|
2340
2915
|
private slotRegistry;
|
|
2916
|
+
/** Slots already warned about (`dashboard`: the dashboard's assignment stands; `replaced`: this page moved it). */
|
|
2917
|
+
private warnedDashboardSlots;
|
|
2918
|
+
private warnedReplacedSlots;
|
|
2341
2919
|
/** Pending debounced declaration of the registry. */
|
|
2342
2920
|
private slotDeclareTimer;
|
|
2343
2921
|
/** A name appeared (or the key changed) since the registry was last declared. */
|
|
@@ -2350,6 +2928,10 @@ declare class VioFacade {
|
|
|
2350
2928
|
private cartManager;
|
|
2351
2929
|
private checkoutManager;
|
|
2352
2930
|
private analyticsManager;
|
|
2931
|
+
/** What the surface answered of its privacy mode (`GET /v2/mobile/surface`) and when; `unknown` expires after a minute. */
|
|
2932
|
+
private surfaceMode;
|
|
2933
|
+
/** The request in flight for it, if any. */
|
|
2934
|
+
private surfaceRequest;
|
|
2353
2935
|
init(config: VioConfig): void;
|
|
2354
2936
|
/**
|
|
2355
2937
|
* The content (article, page) this SDK instance is rendered in — what every
|
|
@@ -2365,7 +2947,7 @@ declare class VioFacade {
|
|
|
2365
2947
|
get config(): ResolvedConfig;
|
|
2366
2948
|
/** Multi-sponsor cart manager. Reactive — listen via addEventListener('change', ...). */
|
|
2367
2949
|
get cart(): CartManager;
|
|
2368
|
-
/** Checkout flow manager. Subscribes to cart state via the CartManager. */
|
|
2950
|
+
/** Checkout flow manager. Subscribes to cart state via the CartManager; asks here for the order's attribution. */
|
|
2369
2951
|
get checkout(): CheckoutManager;
|
|
2370
2952
|
/**
|
|
2371
2953
|
* Analytics — track() queues even pre-init; nothing is sent (and no
|
|
@@ -2406,19 +2988,39 @@ declare class VioFacade {
|
|
|
2406
2988
|
/**
|
|
2407
2989
|
* Register a slot present on the page (the `<vio-*>` elements call it with
|
|
2408
2990
|
* their effective id — the host's `vio-slot` or the auto-generated one —
|
|
2409
|
-
*
|
|
2410
|
-
*
|
|
2411
|
-
*
|
|
2412
|
-
*
|
|
2413
|
-
*
|
|
2414
|
-
|
|
2415
|
-
|
|
2991
|
+
* the optional display name, and the element's own campaign when it has
|
|
2992
|
+
* one: `vio-campaign` or an ancestor's `data-vio-campaign`). The registry is
|
|
2993
|
+
* declared ONCE, debounced, after the first successful bootstrap — and again
|
|
2994
|
+
* whenever a new id, display name, campaign or kind appears. A `displayName` /
|
|
2995
|
+
* `campaignId` given later for an id already registered replaces the one
|
|
2996
|
+
* kept; `undefined` leaves it alone. The third argument is the campaign id
|
|
2997
|
+
* (as before) or `{ campaignId?, kind? }`, and a fourth `{ kind? }` may
|
|
2998
|
+
* follow a positional campaign — the elements call
|
|
2999
|
+
* `registerSlot(id, name, campaignId, { kind })` so a facade from an older
|
|
3000
|
+
* bundle, which reads only three arguments, still gets the campaign. `kind`
|
|
3001
|
+
* is what kind of element holds the slot (`card` | `carousel` | `detail`);
|
|
3002
|
+
* the FIRST kind an id gets stays (the cards a carousel renders share its
|
|
3003
|
+
* id: the slot is the carousel's). The returned function unregisters;
|
|
3004
|
+
* removal never re-declares.
|
|
3005
|
+
*/
|
|
3006
|
+
registerSlot(name: string, displayName?: string, campaignIdOrOptions?: number | string | null | RegisterSlotOptions, options?: RegisterSlotOptions): () => void;
|
|
2416
3007
|
/**
|
|
2417
3008
|
* The campaign a slot shows now, from the last bootstrap: its assigned and
|
|
2418
3009
|
* open campaign for the init platform, else the surface's default. With no
|
|
2419
3010
|
* slot, the default. `null` before the bootstrap. See `resolveSlotCampaign`.
|
|
2420
3011
|
*/
|
|
2421
|
-
campaignForSlot(slot?: string | null
|
|
3012
|
+
campaignForSlot(slot?: string | null, hint?: {
|
|
3013
|
+
campaignId?: CampaignHint;
|
|
3014
|
+
sponsorId?: number | string | null;
|
|
3015
|
+
}): BootstrapCampaignEntry | null;
|
|
3016
|
+
/** The page-campaign candidates in precedence order: the element's (own, ancestor), then `Vio.init`'s. */
|
|
3017
|
+
private pageCampaignCandidates;
|
|
3018
|
+
/**
|
|
3019
|
+
* The campaign the PAGE belongs to (`Vio.init({ campaignId })`, ADR-0034
|
|
3020
|
+
* amendment 3), as the last bootstrap lists it — only when it is there and
|
|
3021
|
+
* active; `null` otherwise (no page campaign, paused, unknown, no bootstrap).
|
|
3022
|
+
*/
|
|
3023
|
+
pageCampaign(): BootstrapCampaignEntry | null;
|
|
2422
3024
|
/**
|
|
2423
3025
|
* THE attribution helper — the SDK elements, Vev and Replit all use this
|
|
2424
3026
|
* one. For a place (`slot`): the campaign it shows right now
|
|
@@ -2429,12 +3031,69 @@ declare class VioFacade {
|
|
|
2429
3031
|
*
|
|
2430
3032
|
* `hint.sponsorId` — when the caller already knows the sponsor (a card with
|
|
2431
3033
|
* `sponsor-id`) it is kept as `sponsorId`, and the campaign follows the same
|
|
2432
|
-
* cascade analytics uses (slot assignment → the sponsor's
|
|
2433
|
-
* default), so what the cart remembers matches what the
|
|
3034
|
+
* cascade analytics uses (slot assignment → page campaign → the sponsor's
|
|
3035
|
+
* active campaign → default), so what the cart remembers matches what the
|
|
3036
|
+
* events say — the page campaign applies there only when that sponsor takes
|
|
3037
|
+
* part in it. `hint.campaignId` — the element's own page campaign
|
|
3038
|
+
* candidates (`vio-campaign`, an ancestor's `data-vio-campaign`), ahead of
|
|
3039
|
+
* `Vio.init`'s; an unusable one falls through to the next; `0` = unset.
|
|
2434
3040
|
*/
|
|
2435
3041
|
attribution(slot?: string | null, hint?: {
|
|
2436
3042
|
sponsorId?: number | string;
|
|
3043
|
+
campaignId?: CampaignHint;
|
|
2437
3044
|
}): Attribution;
|
|
3045
|
+
/**
|
|
3046
|
+
* What the surface answered and is still believed: `standard` / `minimal`
|
|
3047
|
+
* for the configuration; `unknown` for a minute after a timeout or a
|
|
3048
|
+
* failure (then it is asked again). `null` = nothing believed.
|
|
3049
|
+
*/
|
|
3050
|
+
private believedSurfaceMode;
|
|
3051
|
+
/**
|
|
3052
|
+
* Ask the surface its privacy mode (`GET /v2/mobile/surface`), once —
|
|
3053
|
+
* started at `init()` and again by `bootstrap()`, never by the payment
|
|
3054
|
+
* path, which only reads what is known (`privacyModeNow`). Resolves what
|
|
3055
|
+
* was learnt within 1.5 s: the mode; `standard` for a service that predates
|
|
3056
|
+
* the endpoint (404) or a surface that names none; `unknown` for a word the
|
|
3057
|
+
* SDK does not know, a timeout or any other failure — believed for a
|
|
3058
|
+
* minute, then asked again. An answer that arrives after the cap still
|
|
3059
|
+
* lands for the next step. Never throws.
|
|
3060
|
+
*/
|
|
3061
|
+
preloadPrivacyMode(): Promise<PrivacyAnswer>;
|
|
3062
|
+
/**
|
|
3063
|
+
* How much of the visit the order attribution may carry (ADR-0035): the
|
|
3064
|
+
* surface's privacy mode, as known RIGHT NOW, without waiting —
|
|
3065
|
+
* `Vio.init({ privacyMode: 'minimal' })` when the host says so, else what
|
|
3066
|
+
* the bootstrap says of the surface, else what the surface answered to the
|
|
3067
|
+
* ask `init()` started (`preloadPrivacyMode`), else the host's `standard`
|
|
3068
|
+
* once the surface could not tell. `unknown` while nothing is known: then
|
|
3069
|
+
* the page, the slot and the entry stay off what goes to Commerce, because
|
|
3070
|
+
* what can reveal which screen someone was on, and why, is only sent when
|
|
3071
|
+
* the surface is known to allow it. The payment path reads this one.
|
|
3072
|
+
*/
|
|
3073
|
+
privacyModeNow(): PrivacyAnswer;
|
|
3074
|
+
/**
|
|
3075
|
+
* `privacyModeNow`, but waiting for the ask in flight when there is one
|
|
3076
|
+
* (at most its 1.5 s cap) — for the cart's lines, which are not the
|
|
3077
|
+
* payment path. Never throws.
|
|
3078
|
+
*/
|
|
3079
|
+
privacyMode(): Promise<PrivacyAnswer>;
|
|
3080
|
+
/**
|
|
3081
|
+
* The attribution of the order a sponsor's cart is about to become
|
|
3082
|
+
* (ADR-0035 phase B) — what `CreateCheckout` / `UpdateCheckout` send as
|
|
3083
|
+
* `attribution` and shopcart writes on the order: the surface (its SDK
|
|
3084
|
+
* key), the page's campaign (`pageCampaign()`; without one, the campaign
|
|
3085
|
+
* that explains most units of the cart under the same rule `purchase` is
|
|
3086
|
+
* split by — `cartSlices`) and, on a surface KNOWN to be `standard`
|
|
3087
|
+
* (`privacyModeNow`), the page (`content()`'s url as origin + path, and
|
|
3088
|
+
* title) and where the session came in: the landing the session REMEMBERS
|
|
3089
|
+
* (`storedLanding`, else the one analytics resolved on this page) — never
|
|
3090
|
+
* the page the shopper pays on taken for a landing. Synchronous: nothing
|
|
3091
|
+
* on the way to a payment waits for it. snake_case, capped to Commerce's
|
|
3092
|
+
* limits. `undefined` when there is nothing to say; never throws.
|
|
3093
|
+
*/
|
|
3094
|
+
orderAttribution(sponsorId?: number): CheckoutAttributionWire | undefined;
|
|
3095
|
+
/** The landing the session remembers: what the first page stored, else what analytics resolved on this page load (consent pending); null otherwise. */
|
|
3096
|
+
private rememberedLanding;
|
|
2438
3097
|
/**
|
|
2439
3098
|
* The cart split per campaign — the SAME rule `begin_checkout` / `purchase`
|
|
2440
3099
|
* use, for hosts with their own analytics sink (Vev). Every unit of every
|
|
@@ -2448,11 +3107,40 @@ declare class VioFacade {
|
|
|
2448
3107
|
cartSlices(sponsorId?: number, opts?: {
|
|
2449
3108
|
items?: CartLineItem[];
|
|
2450
3109
|
}): CartSlice[];
|
|
3110
|
+
/**
|
|
3111
|
+
* What the micro did with the page's campaign per slot (`assignment`):
|
|
3112
|
+
* `console.debug` when `Vio.init({ debug: true })`; a warning once per
|
|
3113
|
+
* slot when the dashboard's own assignment stands (only for a slot this
|
|
3114
|
+
* page actually sent a campaign for) and once per slot when this page moved
|
|
3115
|
+
* it from an earlier page assignment (`replaced`).
|
|
3116
|
+
*/
|
|
3117
|
+
private reportAssignments;
|
|
3118
|
+
/**
|
|
3119
|
+
* The memory keys of the sent locations whose campaign the micro did not
|
|
3120
|
+
* take up: every location when a campaign was sent and no answer carries
|
|
3121
|
+
* `assignment` (an older micro), or the ones answered `none` for a campaign
|
|
3122
|
+
* the bootstrap lists as active. They are remembered with the 1 h TTL.
|
|
3123
|
+
*/
|
|
3124
|
+
private campaignNotTakenUp;
|
|
2451
3125
|
private scheduleSlotDeclaration;
|
|
2452
3126
|
private findSponsor;
|
|
2453
3127
|
}
|
|
2454
3128
|
declare const Vio: VioFacade;
|
|
2455
3129
|
|
|
3130
|
+
/**
|
|
3131
|
+
* The buyer reference — shopcart's `buyer_ref`: the keyed hash Commerce
|
|
3132
|
+
* computes from the buyer's email, so one person is one ref across orders,
|
|
3133
|
+
* devices and platforms, and nothing in it can be turned back into an email
|
|
3134
|
+
* without Commerce's secret. The SDK forwards it as analytics `buyer_id`
|
|
3135
|
+
* (EVENTS_CONTRACT `commerce.buyer_id`, ≤ 128 chars in the collector's
|
|
3136
|
+
* schema) and never puts anything else in its place: an email, a name, an
|
|
3137
|
+
* over-long value are dropped — not hashed client-side, not cut (a cut hash
|
|
3138
|
+
* is another identity).
|
|
3139
|
+
*/
|
|
3140
|
+
declare const BUYER_REF_MAX_LENGTH = 128;
|
|
3141
|
+
/** The reference when `value` is one; `undefined` for anything else (never an email). */
|
|
3142
|
+
declare function normalizeBuyerRef(value: unknown): string | undefined;
|
|
3143
|
+
|
|
2456
3144
|
/**
|
|
2457
3145
|
* SDK version reported in analytics events (`sdk_version`) and available
|
|
2458
3146
|
* to consumers. Kept as a constant (not a package.json import) so the
|
|
@@ -2460,7 +3148,7 @@ declare const Vio: VioFacade;
|
|
|
2460
3148
|
*
|
|
2461
3149
|
* RELEASE CHECKLIST: bump together with package.json (see CONTRIBUTING).
|
|
2462
3150
|
*/
|
|
2463
|
-
declare const SDK_VERSION = "0.
|
|
3151
|
+
declare const SDK_VERSION = "0.25.0";
|
|
2464
3152
|
|
|
2465
3153
|
/**
|
|
2466
3154
|
* Vipps MobilePay's own button, the way the design guidelines ask for it.
|
|
@@ -2489,4 +3177,4 @@ declare function vippsButtonAttributes(verb?: 'buy' | 'pay' | 'express' | 'conti
|
|
|
2489
3177
|
language?: string;
|
|
2490
3178
|
}): Record<string, string>;
|
|
2491
3179
|
|
|
2492
|
-
export { ADD_ITEM_MUTATION, type AddManualOptions, type AddProductOptions, type AnalyticsCommerce, type AnalyticsContext, type AnalyticsEventName, type AnalyticsItemInput, AnalyticsManager, type AnalyticsStartOptions, type ApplePayConfig, type ApplePayResult, type Attribution, type BootstrapCampaign, type BootstrapCampaignEntry, type BootstrapCampaignStatus, type BootstrapResponse, type BootstrapSlot, CREATE_CART_MUTATION, CREATE_CHECKOUT_MUTATION, CREATE_PAYMENT_STRIPE_MUTATION, CREATE_PAYMENT_VIPPS_MUTATION, type CartChangeDetail, type CartLineItem, type CartLineOrigin, CartManager, type CartOrigin, type CartQueryOptions, type CartSlice, type CheckoutAddress, type CheckoutChangeDetail, CheckoutManager, type CheckoutState, CommerceClient, Configuration, type ContentRef, type CreatePaymentVippsResponse, type CreatePaymentVippsVariables, DELETE_ITEM_MUTATION, type Environment, GET_AVAILABLE_PAYMENT_METHODS_QUERY, GET_CART_QUERY, GET_CHECKOUT_QUERY, GET_LINE_ITEMS_BY_SUPPLIER_QUERY, GET_VIPPS_STATUS_QUERY, type GetVippsStatusVariables, type ImageSize, type ManifestLocation, type ManifestRequest, type ManifestResult, type PaymentCompleteDetail, type PaymentMethod, type PaymentSelectDetail, type PaymentSuccessDetail, type PaymentSuccessResult, type PlacementComponent, type Product, type ProductCategory, type ProductImage, type ProductOption, type ProductPrice, type ProductVariant, type ResolvedConfig, SDK_VERSION, type SlotInput, type SlotKind, type Sponsor, type SponsorCartState, type SponsorCommerceBlock, type TrackOptions, UPDATE_CHECKOUT_MUTATION, UPDATE_ITEM_MUTATION, UPDATE_SHIPPINGS_BY_SUPPLIER_MUTATION, VIPPS_BUTTON_SCRIPT, VIPPS_BUTTON_TAG, Vio, VioApi, VioApiError, type VioConfig, type VioItem, type VioPlatform, type VippsPaymentState, type VippsStatusResult, addItem, autoSlotDisplayName, autoSlotId, cartSlicesFrom, checkApplePayAvailability, createCart, createCheckout, createCommerceClient, createPaymentStripe, createPaymentVipps, createVioApi, deleteItem, displayPrice, ensureVippsButton, executeCartGraphQL, formatPrice, getAvailablePaymentMethods, getCart, getCartGraphQLOptions, getCheckout, getCustomerSessionId, getGlobalCurrency, getLineItemsBySupplier, getVippsStatus, lineOrigins, normalizeOrigin, normalizeScope, primaryImageUrl, purchaseFromPaymentSuccess, resolveCampaignId, resolveContent, resolveSlotCampaign, sameOrigin, showApplePaySheet, updateCheckout, updateItem, updateShippingsBySupplier, vippsButtonAttributes };
|
|
3180
|
+
export { ADD_ITEM_MUTATION, type AddManualOptions, type AddProductOptions, type AnalyticsCommerce, type AnalyticsContext, type AnalyticsEventName, type AnalyticsItemInput, AnalyticsManager, type AnalyticsStartOptions, type ApplePayConfig, type ApplePayResult, type Attribution, BUYER_REF_MAX_LENGTH, type BootstrapCampaign, type BootstrapCampaignEntry, type BootstrapCampaignStatus, type BootstrapResponse, type BootstrapSlot, CHECKOUT_ATTRIBUTION_CAPS, CLIENT_LANDING_URL_MAX_LENGTH, CONTENT_URL_MAX_LENGTH, CREATE_CART_MUTATION, CREATE_CHECKOUT_MUTATION, CREATE_CHECKOUT_WITH_ATTRIBUTION_MUTATION, CREATE_PAYMENT_STRIPE_MUTATION, CREATE_PAYMENT_VIPPS_MUTATION, type CampaignHint, type CartChangeDetail, type CartLineItem, type CartLineOrigin, CartManager, type CartOrigin, type CartQueryOptions, type CartSlice, type CheckoutAddress, type CheckoutAttributionInput, type CheckoutAttributionWire, type CheckoutChangeDetail, CheckoutManager, type CheckoutManagerDeps, type CheckoutReference, type CheckoutState, type ClientContext, CommerceClient, Configuration, type ContentRef, type CreatePaymentVippsResponse, type CreatePaymentVippsVariables, DELETE_ITEM_MUTATION, type EntryContextWire, type Environment, GET_AVAILABLE_PAYMENT_METHODS_QUERY, GET_CART_QUERY, GET_CHECKOUT_QUERY, GET_LINE_ITEMS_BY_SUPPLIER_QUERY, GET_VIPPS_STATUS_QUERY, GRAPHQL_INT_MAX, type GatewayFeature, type GetVippsStatusVariables, type ImageSize, LINE_ORIGIN_CAPS, type Landing, type LineOriginWire, type LineOriginWireOptions, type ManifestLocation, type ManifestRequest, type ManifestResult, type OriginPage, type PaymentCompleteDetail, type PaymentMethod, type PaymentSelectDetail, type PaymentSuccessDetail, type PaymentSuccessResult, type PlacementComponent, type Product, type ProductCategory, type ProductImage, type ProductOption, type ProductPrice, type ProductVariant, type RegisterSlotOptions, type ResolvedConfig, SDK_VERSION, type SlotInput, type SlotKind, type Sponsor, type SponsorCartState, type SponsorCommerceBlock, type SurfacePrivacyMode, type SurfaceResponse, type TrackOptions, UPDATE_CHECKOUT_MUTATION, UPDATE_CHECKOUT_WITH_ATTRIBUTION_MUTATION, UPDATE_ITEM_MUTATION, UPDATE_ITEM_WITH_ORIGIN_MUTATION, UPDATE_SHIPPINGS_BY_SUPPLIER_MUTATION, VIPPS_BUTTON_SCRIPT, VIPPS_BUTTON_TAG, Vio, VioApi, VioApiError, type VioConfig, type VioItem, type VioPlatform, type VippsPaymentState, type VippsStatusResult, activeCampaignEntry, addItem, autoSlotDisplayName, autoSlotId, buyerRefOf, campaignCandidates, capContentUrl, cartSlicesFrom, checkApplePayAvailability, checkoutAttributionOf, componentKindOf, createCart, createCheckout, createCommerceClient, createPaymentStripe, createPaymentVipps, createVioApi, deleteItem, displayPrice, dominantCampaignOf, ensureVippsButton, entryContextOf, executeCartGraphQL, formatPrice, gatewayHas, getAvailablePaymentMethods, getCart, getCartGraphQLOptions, getCheckout, getCheckoutReference, getCustomerSessionId, getGlobalCurrency, getLineItemsBySupplier, getVippsStatus, isUnknownFeatureError, isUnknownTokenError, landingUrl, lineOriginWire, lineOrigins, normalizeBuyerRef, normalizeOrigin, normalizeScope, normalizeSlotKind, originAndPath, primaryImageUrl, purchaseFromPaymentSuccess, resetGatewayFeatures, resolveCampaignId, resolveClientContext, resolveContent, resolveLanding, resolveSlotCampaign, sameOrigin, showApplePaySheet, sponsorCampaignEntry, storedLanding, toCampaignId, updateCheckout, updateItem, updateShippingsBySupplier, vippsButtonAttributes, withGatewayFeature };
|