@replohq/sdk 1.22.0 → 2.1.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/_vendor/replo-utils/lib/json.mjs +4 -5
- package/_vendor/replo-utils/lib/misc.mjs +4 -3
- package/_vendor/replo-utils/lib/object.d.ts +16 -1
- package/_vendor/replo-utils/lib/object.mjs +3 -4
- package/_vendor/schemas/contentEntry.mjs +3 -3
- package/_vendor/schemas/contentManifest.mjs +6 -6
- package/_vendor/schemas/errors.d.ts +3 -43
- package/_vendor/schemas/{money.d.ts → moneyFormat.d.ts} +1 -8
- package/_vendor/schemas/{money.mjs → moneyFormat.mjs} +5 -16
- package/_vendor/schemas/reploError.d.ts +43 -0
- package/_vendor/schemas/routing/locale.mjs +6 -4
- package/_vendor/schemas/routing/rules.mjs +6 -4
- package/analytics/analytics-sink.d.ts +126 -14
- package/analytics/combine-sinks.js +36 -13
- package/analytics/get-analytics-sinks.js +6 -4
- package/analytics/hooks/use-product-viewed-analytics.d.ts +1 -17
- package/analytics/hooks/use-product-viewed-analytics.js +5 -14
- package/analytics/legacy-checkout.d.ts +2 -0
- package/analytics/legacy-checkout.js +26 -0
- package/analytics/sinks/converge-event-mapper.d.ts +10 -11
- package/analytics/sinks/converge-event-mapper.js +50 -133
- package/analytics/sinks/converge-sink.d.ts +8 -7
- package/analytics/sinks/converge-sink.js +21 -3
- package/analytics/sinks/elevar-sink.d.ts +9 -7
- package/analytics/sinks/elevar-sink.js +37 -128
- package/analytics/sinks/ga4-sink.d.ts +9 -8
- package/analytics/sinks/ga4-sink.js +9 -8
- package/analytics/sinks/intelligems-sink.d.ts +9 -8
- package/analytics/sinks/intelligems-sink.js +3 -1
- package/analytics/sinks/meta-sink.d.ts +5 -4
- package/analytics/sinks/meta-sink.js +7 -3
- package/analytics/sinks/northbeam-sink.d.ts +1 -0
- package/analytics/sinks/northbeam-sink.js +2 -0
- package/analytics/sinks/pinterest-sink.d.ts +7 -6
- package/analytics/sinks/pinterest-sink.js +14 -20
- package/analytics/sinks/reddit-sink.d.ts +8 -7
- package/analytics/sinks/reddit-sink.js +13 -20
- package/analytics/sinks/replo-sink.d.ts +21 -9
- package/analytics/sinks/replo-sink.js +37 -39
- package/analytics/sinks/segment-event-mapper.d.ts +86 -0
- package/analytics/sinks/segment-event-mapper.js +71 -0
- package/analytics/sinks/segment-sink.d.ts +23 -0
- package/analytics/sinks/segment-sink.js +84 -0
- package/analytics/sinks/snapchat-sink.d.ts +6 -5
- package/analytics/sinks/snapchat-sink.js +8 -8
- package/analytics/sinks/tiktok-sink.d.ts +8 -7
- package/analytics/sinks/tiktok-sink.js +10 -15
- package/analytics/sinks/window-sink.d.ts +11 -9
- package/analytics/sinks/window-sink.js +5 -1
- package/analytics/sinks/x-sink.d.ts +5 -4
- package/analytics/sinks/x-sink.js +19 -50
- package/analytics/test-fixtures.d.ts +5 -0
- package/analytics/test-fixtures.js +18 -0
- package/analytics/utils/analytics-products.d.ts +0 -30
- package/analytics/utils/analytics-products.js +1 -51
- package/analytics/utils/collection-analytics.d.ts +2 -15
- package/analytics/utils/collection-analytics.js +14 -18
- package/analytics/utils/product-analytics.d.ts +23 -0
- package/analytics/utils/product-analytics.js +21 -0
- package/cart/hooks/use-add-to-cart.js +1 -1
- package/cart/utils/cart-analytics.d.ts +3 -23
- package/cart/utils/cart-analytics.js +1 -1
- package/cart/utils/cart-utils.js +1 -1
- package/cart/utils/variant-to-cart-line.js +1 -1
- package/chunk-CKRRL66R.mjs +28 -0
- package/{chunk-VVB7BEDE.mjs → chunk-O4QBR4QC.mjs} +9 -4
- package/{chunk-EUIVDITZ.mjs → chunk-OPKMOW43.mjs} +1 -1
- package/{chunk-C37TXOGI.mjs → chunk-PSYP2DYM.mjs} +1 -1
- package/{chunk-ACQS4AG5.mjs → chunk-TTEBDCWT.mjs} +272 -109
- package/{chunk-HFKL4ZR5.mjs → chunk-XGXJOHUY.mjs} +2 -1
- package/{chunk-AQG3256R.mjs → chunk-XSMYSAKY.mjs} +0 -26
- package/{chunk-SSBIMQES.mjs → chunk-XWWFRIXV.mjs} +36 -99
- package/chunk-ZPDXVFCR.mjs +66 -0
- package/hooks/use-formatted-price.js +1 -1
- package/lib/buildMetadata.js +3 -3
- package/loaders/collection-loader.js +8 -6
- package/loaders/collection-products-loader.js +8 -6
- package/loaders/contentful-entries-loader.js +5 -3
- package/loaders/contentful-entry-loader.js +5 -3
- package/loaders/integration-loader-schemas.d.ts +260 -0
- package/loaders/integration-loader-schemas.js +55 -0
- package/loaders/invoke-loader.d.ts +5 -0
- package/loaders/invoke-loader.js +1 -1
- package/loaders/judgeme-review-aggregate-loader.d.ts +1 -1
- package/loaders/judgeme-review-aggregate-loader.js +10 -6
- package/loaders/judgeme-reviews-loader.d.ts +1 -1
- package/loaders/judgeme-reviews-loader.js +5 -3
- package/loaders/kaching-bundles-loader.js +5 -3
- package/loaders/levanta-product-loader.js +8 -6
- package/loaders/loox-review-aggregate-loader.d.ts +1 -1
- package/loaders/loox-review-aggregate-loader.js +10 -6
- package/loaders/loox-reviews-loader.d.ts +1 -1
- package/loaders/loox-reviews-loader.js +8 -6
- package/loaders/metaobject-loader.js +5 -3
- package/loaders/metaobjects-loader.js +5 -3
- package/loaders/okendo-review-aggregate-loader.d.ts +2 -7
- package/loaders/okendo-review-aggregate-loader.js +8 -12
- package/loaders/okendo-reviews-loader.d.ts +2 -42
- package/loaders/okendo-reviews-loader.js +5 -8
- package/loaders/product-loader.js +5 -3
- package/loaders/rebuy-recommendations-loader.d.ts +2 -167
- package/loaders/rebuy-recommendations-loader.js +8 -10
- package/loaders/reviews-io-review-aggregate-loader.d.ts +1 -1
- package/loaders/reviews-io-review-aggregate-loader.js +5 -3
- package/loaders/reviews-io-reviews-loader.d.ts +1 -1
- package/loaders/reviews-io-reviews-loader.js +7 -3
- package/loaders/shopify-integration-details-loader.js +10 -6
- package/loaders/smile-earning-rules-loader.d.ts +2 -8
- package/loaders/smile-earning-rules-loader.js +8 -16
- package/loaders/smile-rewards-loader.d.ts +2 -8
- package/loaders/smile-rewards-loader.js +8 -16
- package/loaders/smile-vip-tiers-loader.d.ts +2 -7
- package/loaders/smile-vip-tiers-loader.js +8 -15
- package/loaders/statsig-experiment-loader.js +5 -3
- package/loaders/yotpo-review-aggregate-loader.d.ts +1 -1
- package/loaders/yotpo-review-aggregate-loader.js +10 -6
- package/loaders/yotpo-reviews-loader.d.ts +1 -1
- package/loaders/yotpo-reviews-loader.js +5 -3
- package/money.d.ts +1 -1
- package/money.js +1 -1
- package/package.json +8 -4
- package/chunk-CQYCPDPI.mjs +0 -166
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { toCheckoutStartedData } from "../legacy-checkout";
|
|
2
|
+
import { createAnalyticsQueue } from "../utils/analytics-utils";
|
|
3
|
+
import {
|
|
4
|
+
mapSegmentCartLine,
|
|
5
|
+
mapSegmentCartViewed,
|
|
6
|
+
mapSegmentCheckoutStarted,
|
|
7
|
+
mapSegmentOrder,
|
|
8
|
+
mapSegmentProduct,
|
|
9
|
+
mapSegmentProductList
|
|
10
|
+
} from "./segment-event-mapper";
|
|
11
|
+
function findSegment() {
|
|
12
|
+
if (typeof window === "undefined") {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
return window.analytics ?? null;
|
|
16
|
+
}
|
|
17
|
+
class SegmentSink {
|
|
18
|
+
send = createAnalyticsQueue({
|
|
19
|
+
isReady: () => Boolean(findSegment()),
|
|
20
|
+
send: (call) => {
|
|
21
|
+
const analytics = findSegment();
|
|
22
|
+
if (call.method === "page") {
|
|
23
|
+
analytics?.page(call.properties);
|
|
24
|
+
} else {
|
|
25
|
+
analytics?.track(call.event, call.properties);
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
queueName: "Segment"
|
|
29
|
+
});
|
|
30
|
+
track(event, properties) {
|
|
31
|
+
this.send({ method: "track", event, properties });
|
|
32
|
+
}
|
|
33
|
+
async customEvent({ event, properties }) {
|
|
34
|
+
this.track(event, properties ?? {});
|
|
35
|
+
}
|
|
36
|
+
async pageView(metadata) {
|
|
37
|
+
if (metadata?.navigationType === "initial") {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (!metadata) {
|
|
41
|
+
this.send({ method: "page", properties: {} });
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this.send({
|
|
45
|
+
method: "page",
|
|
46
|
+
properties: {
|
|
47
|
+
url: metadata.url,
|
|
48
|
+
path: new URL(metadata.url, window.location.origin).pathname,
|
|
49
|
+
title: metadata.title,
|
|
50
|
+
referrer: metadata.referrer
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
async purchase(payload) {
|
|
55
|
+
this.track("Order Completed", mapSegmentOrder(payload));
|
|
56
|
+
}
|
|
57
|
+
async click({ data }) {
|
|
58
|
+
this.track("Element Clicked", data);
|
|
59
|
+
}
|
|
60
|
+
async productViewed({ data }) {
|
|
61
|
+
this.track("Product Viewed", mapSegmentProduct(data, data.currency));
|
|
62
|
+
}
|
|
63
|
+
async addToCart({ data }) {
|
|
64
|
+
this.track("Product Added", mapSegmentCartLine(data));
|
|
65
|
+
}
|
|
66
|
+
async removeFromCart({ data }) {
|
|
67
|
+
this.track("Product Removed", mapSegmentCartLine(data));
|
|
68
|
+
}
|
|
69
|
+
async viewCart({ data }) {
|
|
70
|
+
this.track("Cart Viewed", mapSegmentCartViewed(data));
|
|
71
|
+
}
|
|
72
|
+
async startCheckout(payload) {
|
|
73
|
+
this.track(
|
|
74
|
+
"Checkout Started",
|
|
75
|
+
mapSegmentCheckoutStarted(toCheckoutStartedData(payload.data))
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
async viewCollection({ data }) {
|
|
79
|
+
this.track("Product List Viewed", mapSegmentProductList(data));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
export {
|
|
83
|
+
SegmentSink
|
|
84
|
+
};
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import type { AnalyticsSink,
|
|
1
|
+
import type { AnalyticsSink, CartLineEventPayload, CheckoutStartedPayload, ClickPayload, LegacyCheckoutStartedPayload, ProductViewedPayload, PurchasePayload } from "../analytics-sink";
|
|
2
2
|
export declare class SnapchatSink implements AnalyticsSink {
|
|
3
3
|
private track;
|
|
4
4
|
constructor();
|
|
5
|
+
customEvent(): Promise<void>;
|
|
5
6
|
pageView(): Promise<void>;
|
|
6
7
|
purchase({ amount, currency, data }: PurchasePayload): Promise<void>;
|
|
7
|
-
click({ data }:
|
|
8
|
-
productViewed({ data }:
|
|
9
|
-
addToCart({ data }:
|
|
8
|
+
click({ data }: ClickPayload): Promise<void>;
|
|
9
|
+
productViewed({ data }: ProductViewedPayload): Promise<void>;
|
|
10
|
+
addToCart({ data }: CartLineEventPayload): Promise<void>;
|
|
10
11
|
removeFromCart(): Promise<void>;
|
|
11
12
|
viewCart(): Promise<void>;
|
|
12
|
-
startCheckout(
|
|
13
|
+
startCheckout(payload: CheckoutStartedPayload | LegacyCheckoutStartedPayload): Promise<void>;
|
|
13
14
|
viewCollection(): Promise<void>;
|
|
14
15
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { toCheckoutStartedData } from "../legacy-checkout";
|
|
1
2
|
import { createEventQueue } from "../utils/analytics-utils";
|
|
2
3
|
class SnapchatSink {
|
|
3
4
|
track;
|
|
@@ -11,6 +12,8 @@ class SnapchatSink {
|
|
|
11
12
|
"Snapchat"
|
|
12
13
|
);
|
|
13
14
|
}
|
|
15
|
+
async customEvent() {
|
|
16
|
+
}
|
|
14
17
|
async pageView() {
|
|
15
18
|
this.track("PAGE_VIEW");
|
|
16
19
|
}
|
|
@@ -26,20 +29,16 @@ class SnapchatSink {
|
|
|
26
29
|
}
|
|
27
30
|
async productViewed({ data }) {
|
|
28
31
|
this.track("VIEW_CONTENT", {
|
|
29
|
-
item_ids: data.product_id ? [data.product_id] : void 0,
|
|
30
32
|
price: data.price,
|
|
31
33
|
currency: data.currency,
|
|
32
|
-
item_category: data.category,
|
|
33
34
|
...data
|
|
34
35
|
});
|
|
35
36
|
}
|
|
36
37
|
async addToCart({ data }) {
|
|
37
38
|
this.track("ADD_CART", {
|
|
38
|
-
item_ids: data.product_id ? [data.product_id] : void 0,
|
|
39
39
|
price: data.price,
|
|
40
|
-
num_items: data.quantity
|
|
40
|
+
num_items: data.quantity,
|
|
41
41
|
currency: data.currency,
|
|
42
|
-
item_category: data.category,
|
|
43
42
|
...data
|
|
44
43
|
});
|
|
45
44
|
}
|
|
@@ -47,11 +46,12 @@ class SnapchatSink {
|
|
|
47
46
|
}
|
|
48
47
|
async viewCart() {
|
|
49
48
|
}
|
|
50
|
-
async startCheckout(
|
|
49
|
+
async startCheckout(payload) {
|
|
50
|
+
const data = toCheckoutStartedData(payload.data);
|
|
51
51
|
this.track("START_CHECKOUT", {
|
|
52
52
|
currency: data.currency,
|
|
53
|
-
number_items: data.
|
|
54
|
-
price: data.
|
|
53
|
+
number_items: data.itemCount,
|
|
54
|
+
price: data.total,
|
|
55
55
|
...data
|
|
56
56
|
});
|
|
57
57
|
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import type { AnalyticsSink,
|
|
1
|
+
import type { AnalyticsSink, CartLineEventPayload, CartViewedPayload, CheckoutStartedPayload, ClickPayload, CollectionViewedPayload, LegacyCheckoutStartedPayload, ProductViewedPayload, PurchasePayload } from "../analytics-sink";
|
|
2
2
|
export declare class TikTokSink implements AnalyticsSink {
|
|
3
3
|
private track;
|
|
4
4
|
constructor();
|
|
5
|
+
customEvent(): Promise<void>;
|
|
5
6
|
pageView(): Promise<void>;
|
|
6
7
|
purchase({ amount, currency, data }: PurchasePayload): Promise<void>;
|
|
7
|
-
click({ data }:
|
|
8
|
-
productViewed({ data }:
|
|
9
|
-
addToCart({ data }:
|
|
8
|
+
click({ data }: ClickPayload): Promise<void>;
|
|
9
|
+
productViewed({ data }: ProductViewedPayload): Promise<void>;
|
|
10
|
+
addToCart({ data }: CartLineEventPayload): Promise<void>;
|
|
10
11
|
removeFromCart(): Promise<void>;
|
|
11
|
-
viewCart({ data }:
|
|
12
|
-
startCheckout(
|
|
13
|
-
viewCollection({ data }:
|
|
12
|
+
viewCart({ data }: CartViewedPayload): Promise<void>;
|
|
13
|
+
startCheckout(payload: CheckoutStartedPayload | LegacyCheckoutStartedPayload): Promise<void>;
|
|
14
|
+
viewCollection({ data }: CollectionViewedPayload): Promise<void>;
|
|
14
15
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
withoutUndefined
|
|
5
|
-
} from "../utils/analytics-products";
|
|
1
|
+
import { filterUndefined } from "../../_vendor/replo-utils/lib/object.mjs";
|
|
2
|
+
import { toCheckoutStartedData } from "../legacy-checkout";
|
|
3
|
+
import { legacyResourceId } from "../utils/analytics-products";
|
|
6
4
|
import { createEventQueue } from "../utils/analytics-utils";
|
|
7
5
|
class TikTokSink {
|
|
8
6
|
track;
|
|
@@ -16,6 +14,8 @@ class TikTokSink {
|
|
|
16
14
|
"TikTok"
|
|
17
15
|
);
|
|
18
16
|
}
|
|
17
|
+
async customEvent() {
|
|
18
|
+
}
|
|
19
19
|
async pageView() {
|
|
20
20
|
this.track("PageView");
|
|
21
21
|
}
|
|
@@ -33,21 +33,16 @@ class TikTokSink {
|
|
|
33
33
|
async productViewed({ data }) {
|
|
34
34
|
this.track("ViewContent", {
|
|
35
35
|
content_type: "product",
|
|
36
|
-
content_id: data.product_id,
|
|
37
36
|
value: data.price,
|
|
38
37
|
currency: data.currency,
|
|
39
|
-
content_category: data.category,
|
|
40
38
|
...data
|
|
41
39
|
});
|
|
42
40
|
}
|
|
43
41
|
async addToCart({ data }) {
|
|
44
42
|
this.track("AddToCart", {
|
|
45
43
|
content_type: "product",
|
|
46
|
-
content_id: data.product_id,
|
|
47
44
|
value: data.price,
|
|
48
45
|
currency: data.currency,
|
|
49
|
-
quantity: data.quantity ?? 1,
|
|
50
|
-
content_category: data.category,
|
|
51
46
|
...data
|
|
52
47
|
});
|
|
53
48
|
}
|
|
@@ -59,23 +54,23 @@ class TikTokSink {
|
|
|
59
54
|
...data
|
|
60
55
|
});
|
|
61
56
|
}
|
|
62
|
-
async startCheckout(
|
|
57
|
+
async startCheckout(payload) {
|
|
58
|
+
const data = toCheckoutStartedData(payload.data);
|
|
63
59
|
this.track("InitiateCheckout", {
|
|
64
|
-
value: data.
|
|
60
|
+
value: data.total,
|
|
65
61
|
currency: data.currency,
|
|
66
62
|
content_type: "product",
|
|
67
63
|
...data
|
|
68
64
|
});
|
|
69
65
|
}
|
|
70
66
|
async viewCollection({ data }) {
|
|
71
|
-
const { products, rest } =
|
|
67
|
+
const { products, ...rest } = data;
|
|
72
68
|
this.track("ViewContent", {
|
|
73
69
|
content_type: "product_group",
|
|
74
|
-
content_category: data.category,
|
|
75
70
|
currency: data.currency,
|
|
76
71
|
...products.length > 0 ? {
|
|
77
72
|
contents: products.map((product) => {
|
|
78
|
-
return
|
|
73
|
+
return filterUndefined({
|
|
79
74
|
content_id: legacyResourceId(product.productId),
|
|
80
75
|
content_type: "product_group",
|
|
81
76
|
content_name: product.productTitle,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { AnalyticsSink,
|
|
1
|
+
import type { AnalyticsSink, CartLineEventPayload, CartViewedPayload, CheckoutStartedPayload, ClickPayload, CollectionViewedPayload, LegacyCheckoutStartedPayload, ProductViewedPayload, PurchasePayload } from "../analytics-sink";
|
|
2
|
+
import type { PageMetadata } from "../utils/navigation-tracker";
|
|
2
3
|
/**
|
|
3
4
|
* Dispatches CustomEvents to the global window object so 3rd-party scripts or
|
|
4
5
|
* external tools can subscribe to analytics events without coupling directly to
|
|
@@ -6,13 +7,14 @@ import type { AnalyticsSink, DataPayload, PurchasePayload } from "../analytics-s
|
|
|
6
7
|
*/
|
|
7
8
|
export declare class WindowSink implements AnalyticsSink {
|
|
8
9
|
private dispatch;
|
|
9
|
-
|
|
10
|
+
customEvent(): Promise<void>;
|
|
11
|
+
pageView(payload?: PageMetadata): Promise<void>;
|
|
10
12
|
purchase(payload: PurchasePayload): Promise<void>;
|
|
11
|
-
click(payload:
|
|
12
|
-
productViewed(payload:
|
|
13
|
-
addToCart(payload:
|
|
14
|
-
removeFromCart(payload:
|
|
15
|
-
viewCart(payload:
|
|
16
|
-
startCheckout(payload:
|
|
17
|
-
viewCollection(payload:
|
|
13
|
+
click(payload: ClickPayload): Promise<void>;
|
|
14
|
+
productViewed(payload: ProductViewedPayload): Promise<void>;
|
|
15
|
+
addToCart(payload: CartLineEventPayload): Promise<void>;
|
|
16
|
+
removeFromCart(payload: CartLineEventPayload): Promise<void>;
|
|
17
|
+
viewCart(payload: CartViewedPayload): Promise<void>;
|
|
18
|
+
startCheckout(payload: CheckoutStartedPayload | LegacyCheckoutStartedPayload): Promise<void>;
|
|
19
|
+
viewCollection(payload: CollectionViewedPayload): Promise<void>;
|
|
18
20
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { toCheckoutStartedData } from "../legacy-checkout";
|
|
1
2
|
class WindowSink {
|
|
2
3
|
dispatch(eventType, payload) {
|
|
3
4
|
window.dispatchEvent(
|
|
@@ -10,6 +11,8 @@ class WindowSink {
|
|
|
10
11
|
})
|
|
11
12
|
);
|
|
12
13
|
}
|
|
14
|
+
async customEvent() {
|
|
15
|
+
}
|
|
13
16
|
async pageView(payload) {
|
|
14
17
|
this.dispatch("page_viewed", payload);
|
|
15
18
|
}
|
|
@@ -32,7 +35,8 @@ class WindowSink {
|
|
|
32
35
|
this.dispatch("cart_viewed", payload);
|
|
33
36
|
}
|
|
34
37
|
async startCheckout(payload) {
|
|
35
|
-
|
|
38
|
+
const data = toCheckoutStartedData(payload.data);
|
|
39
|
+
this.dispatch("checkout_started", { data });
|
|
36
40
|
}
|
|
37
41
|
async viewCollection(payload) {
|
|
38
42
|
this.dispatch("collection_viewed", payload);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { XPixelEvents } from "../../_vendor/schemas/generated/consent";
|
|
2
|
-
import type { AnalyticsSink,
|
|
2
|
+
import type { AnalyticsSink, CartLineEventPayload, CheckoutStartedPayload, LegacyCheckoutStartedPayload, ProductViewedPayload, PurchasePayload } from "../analytics-sink";
|
|
3
3
|
import type { PageMetadata } from "../utils/navigation-tracker";
|
|
4
4
|
declare global {
|
|
5
5
|
interface Window {
|
|
@@ -20,13 +20,14 @@ export declare class XSink implements AnalyticsSink {
|
|
|
20
20
|
events: XPixelEvents;
|
|
21
21
|
});
|
|
22
22
|
private track;
|
|
23
|
+
customEvent(): Promise<void>;
|
|
23
24
|
pageView(metadata: PageMetadata | undefined): Promise<void>;
|
|
24
25
|
purchase({ amount, currency, data }: PurchasePayload): Promise<void>;
|
|
25
26
|
click(): Promise<void>;
|
|
26
|
-
productViewed({ data }:
|
|
27
|
-
addToCart({ data }:
|
|
27
|
+
productViewed({ data }: ProductViewedPayload): Promise<void>;
|
|
28
|
+
addToCart({ data }: CartLineEventPayload): Promise<void>;
|
|
28
29
|
removeFromCart(): Promise<void>;
|
|
29
30
|
viewCart(): Promise<void>;
|
|
30
|
-
startCheckout(
|
|
31
|
+
startCheckout(payload: CheckoutStartedPayload | LegacyCheckoutStartedPayload): Promise<void>;
|
|
31
32
|
viewCollection(): Promise<void>;
|
|
32
33
|
}
|
|
@@ -1,54 +1,21 @@
|
|
|
1
1
|
import { filterUndefined } from "../../_vendor/replo-utils/lib/object.mjs";
|
|
2
|
-
import * as z from "zod";
|
|
3
2
|
import { isXEventIdForPixel } from "../../consent/script-snippets";
|
|
3
|
+
import { toCheckoutStartedData } from "../legacy-checkout";
|
|
4
4
|
import { legacyResourceId } from "../utils/analytics-products";
|
|
5
5
|
import { createEventQueue } from "../utils/analytics-utils";
|
|
6
|
-
|
|
7
|
-
const nonEmptyStringSchema = z.union([
|
|
8
|
-
z.string().min(1),
|
|
9
|
-
z.number().finite().transform(String)
|
|
10
|
-
]);
|
|
11
|
-
const finiteNumberSchema = z.union([
|
|
12
|
-
z.number().finite(),
|
|
13
|
-
z.string().trim().min(1).transform(Number).pipe(z.number().finite())
|
|
14
|
-
]);
|
|
15
|
-
function parseRecord(value) {
|
|
16
|
-
const result = analyticsRecordSchema.safeParse(value);
|
|
17
|
-
return result.success ? result.data : {};
|
|
18
|
-
}
|
|
19
|
-
function parseString(value) {
|
|
20
|
-
const result = nonEmptyStringSchema.safeParse(value);
|
|
21
|
-
return result.success ? result.data : void 0;
|
|
22
|
-
}
|
|
23
|
-
function parseNumber(value) {
|
|
24
|
-
const result = finiteNumberSchema.safeParse(value);
|
|
25
|
-
return result.success ? result.data : void 0;
|
|
26
|
-
}
|
|
27
|
-
function mapContent(value, defaultQuantity) {
|
|
28
|
-
const line = parseRecord(value);
|
|
29
|
-
const variant = parseRecord(line.variant);
|
|
30
|
-
const product = parseRecord(variant.product);
|
|
31
|
-
const productId = parseString(line.productId) ?? parseString(product.id);
|
|
32
|
-
if (!productId) {
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
6
|
+
function mapContent(line, defaultQuantity) {
|
|
35
7
|
return filterUndefined({
|
|
36
|
-
content_id: legacyResourceId(productId),
|
|
37
|
-
content_name:
|
|
38
|
-
content_price:
|
|
39
|
-
num_items:
|
|
8
|
+
content_id: legacyResourceId(line.productId),
|
|
9
|
+
content_name: line.productTitle || void 0,
|
|
10
|
+
content_price: line.price,
|
|
11
|
+
num_items: line.quantity ?? defaultQuantity
|
|
40
12
|
});
|
|
41
13
|
}
|
|
42
14
|
function mapContents(lines) {
|
|
43
|
-
|
|
44
|
-
if (!result.success) {
|
|
45
|
-
return void 0;
|
|
46
|
-
}
|
|
47
|
-
const contents = result.data.map((line) => mapContent(line, void 0)).filter((content) => content !== null);
|
|
48
|
-
return contents.length > 0 ? contents : void 0;
|
|
15
|
+
return lines && lines.length > 0 ? lines.map((line) => mapContent(line, void 0)) : void 0;
|
|
49
16
|
}
|
|
50
17
|
function lineValue(content) {
|
|
51
|
-
if (content
|
|
18
|
+
if (content.content_price === void 0) {
|
|
52
19
|
return void 0;
|
|
53
20
|
}
|
|
54
21
|
return content.content_price * (content.num_items ?? 1);
|
|
@@ -74,6 +41,8 @@ class XSink {
|
|
|
74
41
|
this.send(eventId, filterUndefined(parameters));
|
|
75
42
|
}
|
|
76
43
|
}
|
|
44
|
+
async customEvent() {
|
|
45
|
+
}
|
|
77
46
|
async pageView(metadata) {
|
|
78
47
|
if (metadata?.navigationType === "initial") {
|
|
79
48
|
return;
|
|
@@ -84,7 +53,7 @@ class XSink {
|
|
|
84
53
|
this.track("purchase", {
|
|
85
54
|
value: amount,
|
|
86
55
|
currency,
|
|
87
|
-
conversion_id:
|
|
56
|
+
conversion_id: data.orderId,
|
|
88
57
|
contents: mapContents(data.lineItems)
|
|
89
58
|
});
|
|
90
59
|
}
|
|
@@ -94,27 +63,27 @@ class XSink {
|
|
|
94
63
|
const content = mapContent(data, 1);
|
|
95
64
|
this.track("productViewed", {
|
|
96
65
|
value: lineValue(content),
|
|
97
|
-
currency:
|
|
98
|
-
contents:
|
|
66
|
+
currency: data.currency || void 0,
|
|
67
|
+
contents: [content]
|
|
99
68
|
});
|
|
100
69
|
}
|
|
101
70
|
async addToCart({ data }) {
|
|
102
71
|
const content = mapContent(data, 1);
|
|
103
72
|
this.track("addToCart", {
|
|
104
73
|
value: lineValue(content),
|
|
105
|
-
currency:
|
|
106
|
-
contents:
|
|
74
|
+
currency: data.currency || void 0,
|
|
75
|
+
contents: [content]
|
|
107
76
|
});
|
|
108
77
|
}
|
|
109
78
|
async removeFromCart() {
|
|
110
79
|
}
|
|
111
80
|
async viewCart() {
|
|
112
81
|
}
|
|
113
|
-
async startCheckout(
|
|
114
|
-
const
|
|
82
|
+
async startCheckout(payload) {
|
|
83
|
+
const data = toCheckoutStartedData(payload.data);
|
|
115
84
|
this.track("startCheckout", {
|
|
116
|
-
value:
|
|
117
|
-
currency:
|
|
85
|
+
value: data.total,
|
|
86
|
+
currency: data.currency,
|
|
118
87
|
contents: mapContents(data.lineItems)
|
|
119
88
|
});
|
|
120
89
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CartLineData, CartViewedData, CheckoutStartedData, CollectionViewedData } from "./analytics-sink";
|
|
2
|
+
export declare function cartLine(overrides?: Partial<CartLineData>): CartLineData;
|
|
3
|
+
export declare function cartView(overrides?: Partial<CartViewedData>): CartViewedData;
|
|
4
|
+
export declare function checkoutStarted(overrides?: Partial<CheckoutStartedData>): CheckoutStartedData;
|
|
5
|
+
export declare function collectionViewed(overrides?: Partial<CollectionViewedData>): CollectionViewedData;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
function cartLine(overrides = {}) {
|
|
2
|
+
return { productId: "1", price: 1, quantity: 1, ...overrides };
|
|
3
|
+
}
|
|
4
|
+
function cartView(overrides = {}) {
|
|
5
|
+
return { itemCount: 0, subtotal: 0, lineItems: [], ...overrides };
|
|
6
|
+
}
|
|
7
|
+
function checkoutStarted(overrides = {}) {
|
|
8
|
+
return { itemCount: 0, subtotal: 0, total: 0, lineItems: [], ...overrides };
|
|
9
|
+
}
|
|
10
|
+
function collectionViewed(overrides = {}) {
|
|
11
|
+
return { collectionId: "c1", products: [], ...overrides };
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
cartLine,
|
|
15
|
+
cartView,
|
|
16
|
+
checkoutStarted,
|
|
17
|
+
collectionViewed
|
|
18
|
+
};
|
|
@@ -1,36 +1,6 @@
|
|
|
1
|
-
import * as z from "zod";
|
|
2
|
-
/**
|
|
3
|
-
* The flat per-product line the cart provider and the viewed hooks emit.
|
|
4
|
-
* Prices are decimal major units.
|
|
5
|
-
*/
|
|
6
|
-
declare const analyticsProductLineSchema: z.ZodObject<{
|
|
7
|
-
productId: z.ZodCatch<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>]>>>;
|
|
8
|
-
productTitle: z.ZodCatch<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>]>>>;
|
|
9
|
-
variantId: z.ZodCatch<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>]>>>;
|
|
10
|
-
variantTitle: z.ZodCatch<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>]>>>;
|
|
11
|
-
variantSku: z.ZodCatch<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>]>>>;
|
|
12
|
-
price: z.ZodCatch<z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<number, string>>, z.ZodNumber>]>>>;
|
|
13
|
-
currency: z.ZodCatch<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>]>>>;
|
|
14
|
-
quantity: z.ZodCatch<z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<number, string>>, z.ZodNumber>]>>>;
|
|
15
|
-
}, z.core.$strip>;
|
|
16
|
-
export type AnalyticsProductLine = z.infer<typeof analyticsProductLineSchema> & {
|
|
17
|
-
productId: string;
|
|
18
|
-
};
|
|
19
|
-
export declare function parseAnalyticsProductLines(value: unknown): AnalyticsProductLine[];
|
|
20
|
-
/**
|
|
21
|
-
* Separates a collection-view payload's `products` list from the scalar
|
|
22
|
-
* fields, so a sink can map the list into its own item shape and forward the
|
|
23
|
-
* rest untouched.
|
|
24
|
-
*/
|
|
25
|
-
export declare function splitCollectionProducts(data: Record<string, unknown>): {
|
|
26
|
-
products: AnalyticsProductLine[];
|
|
27
|
-
rest: Record<string, unknown>;
|
|
28
|
-
};
|
|
29
1
|
/**
|
|
30
2
|
* Shopify catalogs synced into ad platforms key on legacy numeric ids, while
|
|
31
3
|
* the Storefront API hands sites GIDs (`gid://shopify/Product/123`). Pixel
|
|
32
4
|
* catalog matching is an exact string match, so ids are sent bare.
|
|
33
5
|
*/
|
|
34
6
|
export declare function legacyResourceId(id: string): string;
|
|
35
|
-
export declare function withoutUndefined<RecordType extends Record<string, unknown>>(record: RecordType): Partial<RecordType>;
|
|
36
|
-
export {};
|
|
@@ -1,56 +1,6 @@
|
|
|
1
|
-
import * as z from "zod";
|
|
2
|
-
const nonEmptyStringSchema = z.union([z.string().min(1), z.number().finite().transform(String)]).optional().catch(void 0);
|
|
3
|
-
const finiteNumberSchema = z.union([
|
|
4
|
-
z.number().finite(),
|
|
5
|
-
z.string().trim().min(1).transform(Number).pipe(z.number().finite())
|
|
6
|
-
]).optional().catch(void 0);
|
|
7
|
-
const analyticsProductLineSchema = z.object({
|
|
8
|
-
productId: nonEmptyStringSchema,
|
|
9
|
-
productTitle: nonEmptyStringSchema,
|
|
10
|
-
variantId: nonEmptyStringSchema,
|
|
11
|
-
variantTitle: nonEmptyStringSchema,
|
|
12
|
-
variantSku: nonEmptyStringSchema,
|
|
13
|
-
price: finiteNumberSchema,
|
|
14
|
-
currency: nonEmptyStringSchema,
|
|
15
|
-
quantity: finiteNumberSchema
|
|
16
|
-
});
|
|
17
|
-
function parseAnalyticsProductLines(value) {
|
|
18
|
-
if (!Array.isArray(value)) {
|
|
19
|
-
return [];
|
|
20
|
-
}
|
|
21
|
-
return value.flatMap((item) => {
|
|
22
|
-
const parsed = analyticsProductLineSchema.safeParse(item);
|
|
23
|
-
if (!parsed.success || !parsed.data.productId) {
|
|
24
|
-
return [];
|
|
25
|
-
}
|
|
26
|
-
return [{ ...parsed.data, productId: parsed.data.productId }];
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
function splitCollectionProducts(data) {
|
|
30
|
-
const { products, ...rest } = data;
|
|
31
|
-
const lines = parseAnalyticsProductLines(products);
|
|
32
|
-
if (Array.isArray(products) && products.length > 0 && lines.length === 0) {
|
|
33
|
-
console.warn(
|
|
34
|
-
"[analytics] collection view products did not match the per-line shape and were dropped"
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
return { products: lines, rest };
|
|
38
|
-
}
|
|
39
1
|
function legacyResourceId(id) {
|
|
40
2
|
return id.replace(/^gid:\/\/shopify\/\w+\//, "");
|
|
41
3
|
}
|
|
42
|
-
function withoutUndefined(record) {
|
|
43
|
-
const compacted = {};
|
|
44
|
-
for (const key in record) {
|
|
45
|
-
if (record[key] !== void 0) {
|
|
46
|
-
compacted[key] = record[key];
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return compacted;
|
|
50
|
-
}
|
|
51
4
|
export {
|
|
52
|
-
legacyResourceId
|
|
53
|
-
parseAnalyticsProductLines,
|
|
54
|
-
splitCollectionProducts,
|
|
55
|
-
withoutUndefined
|
|
5
|
+
legacyResourceId
|
|
56
6
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CollectionViewedData } from "../analytics-sink";
|
|
1
2
|
export interface AnalyticsMoney {
|
|
2
3
|
amount: number | string;
|
|
3
4
|
currencyCode: string;
|
|
@@ -27,18 +28,4 @@ export interface AnalyticsCollectionProduct {
|
|
|
27
28
|
export declare function buildCollectionViewedAnalyticsData({ collection, products, }: {
|
|
28
29
|
collection: AnalyticsCollection;
|
|
29
30
|
products: AnalyticsCollectionProduct[];
|
|
30
|
-
}):
|
|
31
|
-
collectionTitle?: string | undefined;
|
|
32
|
-
collectionHandle?: string | undefined;
|
|
33
|
-
currency?: string | undefined;
|
|
34
|
-
collectionId: string;
|
|
35
|
-
products: {
|
|
36
|
-
productTitle?: string | undefined;
|
|
37
|
-
variantId?: string | undefined;
|
|
38
|
-
variantTitle?: string | undefined;
|
|
39
|
-
variantSku?: string | undefined;
|
|
40
|
-
price?: number | undefined;
|
|
41
|
-
currency?: string | undefined;
|
|
42
|
-
productId: string;
|
|
43
|
-
}[];
|
|
44
|
-
};
|
|
31
|
+
}): CollectionViewedData;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { filterUndefined } from "../../_vendor/replo-utils/lib/object.mjs";
|
|
2
2
|
function parseAmount(money) {
|
|
3
3
|
if (!money) {
|
|
4
4
|
return void 0;
|
|
@@ -9,32 +9,28 @@ function parseAmount(money) {
|
|
|
9
9
|
function buildCollectionProductLine(product) {
|
|
10
10
|
const variant = product.variants?.[0];
|
|
11
11
|
const money = variant?.price ?? product.minPrice ?? void 0;
|
|
12
|
-
return {
|
|
12
|
+
return filterUndefined({
|
|
13
13
|
productId: product.id,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
})
|
|
22
|
-
};
|
|
14
|
+
productTitle: product.title ?? void 0,
|
|
15
|
+
variantId: variant?.id,
|
|
16
|
+
variantTitle: variant?.title ?? void 0,
|
|
17
|
+
variantSku: variant?.sku ?? void 0,
|
|
18
|
+
price: parseAmount(money),
|
|
19
|
+
currency: money?.currencyCode
|
|
20
|
+
});
|
|
23
21
|
}
|
|
24
22
|
function buildCollectionViewedAnalyticsData({
|
|
25
23
|
collection,
|
|
26
24
|
products
|
|
27
25
|
}) {
|
|
28
26
|
const lines = products.map(buildCollectionProductLine);
|
|
29
|
-
return {
|
|
27
|
+
return filterUndefined({
|
|
30
28
|
collectionId: collection.id,
|
|
31
29
|
products: lines,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
})
|
|
37
|
-
};
|
|
30
|
+
collectionTitle: collection.title ?? void 0,
|
|
31
|
+
collectionHandle: collection.handle ?? void 0,
|
|
32
|
+
currency: lines.find((line) => line.currency)?.currency
|
|
33
|
+
});
|
|
38
34
|
}
|
|
39
35
|
export {
|
|
40
36
|
buildCollectionViewedAnalyticsData
|