@replohq/sdk 1.7.2 → 1.8.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/string.d.ts +0 -2
- package/_vendor/schemas/errors.d.ts +0 -3
- package/_vendor/schemas/loaderKeys.mjs +0 -1
- package/_vendor/schemas/money.d.ts +1 -1
- package/_vendor/schemas/money.mjs +0 -6
- package/_vendor/schemas/routing/rules.mjs +0 -1
- package/analytics/analytics-provider.js +0 -1
- package/analytics/analytics-sink.js +0 -1
- package/analytics/get-analytics-sinks.js +0 -1
- package/analytics/hooks/use-collection-viewed-analytics.d.ts +19 -0
- package/analytics/hooks/use-collection-viewed-analytics.js +26 -0
- package/analytics/hooks/use-product-viewed-analytics.js +0 -1
- package/analytics/replo-first-party-pixel.js +0 -1
- package/analytics/replo-pixel-script.js +0 -1
- package/analytics/sinks/converge-event-mapper.js +0 -1
- package/analytics/sinks/converge-sink.js +0 -1
- package/analytics/sinks/elevar-sink.js +1 -4
- package/analytics/sinks/ga4-sink.js +23 -5
- package/analytics/sinks/meta-sink.js +0 -4
- package/analytics/sinks/northbeam-sink.js +0 -1
- package/analytics/sinks/pinterest-sink.js +19 -5
- package/analytics/sinks/reddit-sink.js +16 -5
- package/analytics/sinks/replo-sink.js +0 -2
- package/analytics/sinks/snapchat-sink.js +0 -4
- package/analytics/sinks/tiktok-sink.js +18 -5
- package/analytics/sinks/window-sink.js +0 -3
- package/analytics/utils/analytics-products.d.ts +36 -0
- package/analytics/utils/analytics-products.js +57 -0
- package/analytics/utils/analytics-utils.js +0 -1
- package/analytics/utils/collection-analytics.d.ts +44 -0
- package/analytics/utils/collection-analytics.js +41 -0
- package/analytics/utils/navigation-tracker.js +0 -1
- package/analytics/utils/shopify-funnel-gate.js +0 -1
- package/cart/buy-now-action.js +0 -3
- package/cart/cart-actions.js +0 -1
- package/cart/cart-loader.js +0 -1
- package/cart/cart-provider.js +1 -2
- package/cart/cart-schema.js +0 -1
- package/cart/cart-types.js +0 -1
- package/cart/gateways/cart-constants.js +0 -2
- package/cart/gateways/cart-gateway.js +0 -1
- package/cart/gateways/cookie-cart-gateway.js +0 -5
- package/cart/gateways/default-cart-gateway.js +0 -1
- package/cart/gateways/resolver-cart-gateway.js +0 -5
- package/cart/gateways/stripe-cart-gateway.js +0 -1
- package/cart/hooks/use-add-to-cart.js +0 -4
- package/cart/hooks/use-buy-now.js +0 -1
- package/cart/return-urls.js +0 -1
- package/cart/storefront-urls.js +0 -1
- package/cart/utils/cart-adjustments.js +0 -1
- package/cart/utils/cart-analytics.js +0 -1
- package/cart/utils/cart-error.js +0 -1
- package/cart/utils/cart-utils.js +0 -1
- package/cart/utils/cookie-cart-persistence.js +0 -1
- package/cart/utils/variant-to-cart-line.js +0 -6
- package/chunk-7OPH5UFQ.mjs +0 -1
- package/chunk-AL3F36PH.mjs +5 -127
- package/chunk-EUQVEPSD.mjs +0 -1
- package/chunk-GV5FY7ZZ.mjs +0 -11
- package/chunk-UJCSKKID.mjs +0 -4
- package/chunk-VKO7P3ED.mjs +0 -2
- package/chunk-VPEVERWE.mjs +0 -1
- package/chunk-YJQVNUW7.mjs +0 -16
- package/consent/consent-action.js +0 -1
- package/consent/consent-actions.js +0 -1
- package/consent/consent-platform.js +0 -3
- package/consent/consent-store.js +0 -5
- package/consent/cookie.js +0 -1
- package/consent/inject-script-descriptors.js +0 -1
- package/consent/replo-scripts.js +0 -1
- package/consent/script-registration-store.js +0 -2
- package/consent/script-snippets.js +0 -7
- package/consent/types.js +0 -1
- package/consent/window-api.js +0 -1
- package/content.js +0 -1
- package/env.js +0 -1
- package/gateways/canopy-api.js +0 -10
- package/hooks/use-client-value.d.ts +1 -1
- package/hooks/use-client-value.js +0 -1
- package/hooks/use-formatted-price.js +0 -1
- package/lib/buildMetadata.js +3 -3
- package/lib/canopy-error.js +0 -1
- package/lib/external-navigation.d.ts +1 -1
- package/lib/external-navigation.js +0 -1
- package/lib/get-query-client.js +0 -1
- package/lib/integration-utils.js +0 -1
- package/lib/shopify-utils.js +0 -1
- package/lib/url-utils.js +0 -1
- package/loaders/collection-loader-args.js +0 -1
- package/loaders/collection-loader.js +0 -1
- package/loaders/collection-products-loader-args.js +0 -1
- package/loaders/collection-products-loader.js +0 -1
- package/loaders/contentful-entries-loader.js +0 -1
- package/loaders/contentful-entry-loader.js +0 -1
- package/loaders/invoke-loader-action.js +0 -1
- package/loaders/invoke-loader-server.js +0 -1
- package/loaders/invoke-loader.js +0 -1
- package/loaders/judgeme-review-aggregate-loader.js +0 -1
- package/loaders/judgeme-reviews-loader.js +0 -1
- package/loaders/levanta-product-loader.js +0 -1
- package/loaders/loader-error-boundary.d.ts +11 -2
- package/loaders/loader-error-boundary.js +52 -9
- package/loaders/loader-error-details.d.ts +2 -0
- package/loaders/loader-error-details.js +7 -0
- package/loaders/loader-keys.js +0 -1
- package/loaders/loader-schemas.js +0 -4
- package/loaders/loox-review-aggregate-loader.js +0 -1
- package/loaders/loox-reviews-loader.js +0 -1
- package/loaders/metaobject-loader.js +0 -1
- package/loaders/metaobjects-loader.js +0 -1
- package/loaders/okendo-review-aggregate-loader.js +0 -1
- package/loaders/okendo-reviews-loader.js +0 -1
- package/loaders/prefetch-loaders.js +0 -1
- package/loaders/preview-placeholder.js +0 -5
- package/loaders/product-loader-args.js +0 -1
- package/loaders/product-loader.js +0 -1
- package/loaders/rebuy-recommendations-loader.js +0 -1
- package/loaders/reviews-io-review-aggregate-loader.js +0 -1
- package/loaders/reviews-io-reviews-loader.js +0 -1
- package/loaders/smile-earning-rules-loader.js +0 -1
- package/loaders/smile-rewards-loader.js +0 -1
- package/loaders/smile-vip-tiers-loader.js +0 -1
- package/loaders/statsig-experiment-loader.js +0 -1
- package/loaders/yotpo-review-aggregate-loader.js +0 -1
- package/loaders/yotpo-reviews-loader.js +0 -1
- package/money.js +0 -1
- package/next/config.js +0 -18
- package/next/image-loader.js +0 -1
- package/next/open-next.js +0 -1
- package/orders/order-status-schema.js +0 -4
- package/orders/order-status.js +0 -3
- package/package.json +8 -4
- package/providers/query-provider.js +0 -1
- package/providers/replo-provider.js +4 -3
- package/routing/evaluate.js +0 -1
- package/routing/geo.js +0 -1
- package/routing/locale.js +0 -1
- package/routing/rules.js +0 -1
- package/analytics/analytics-provider.js.map +0 -7
- package/analytics/analytics-sink.js.map +0 -7
- package/analytics/get-analytics-sinks.js.map +0 -7
- package/analytics/hooks/use-product-viewed-analytics.js.map +0 -7
- package/analytics/replo-first-party-pixel.js.map +0 -7
- package/analytics/replo-pixel-script.js.map +0 -7
- package/analytics/sinks/converge-event-mapper.js.map +0 -7
- package/analytics/sinks/converge-sink.js.map +0 -7
- package/analytics/sinks/elevar-sink.js.map +0 -7
- package/analytics/sinks/ga4-sink.js.map +0 -7
- package/analytics/sinks/meta-sink.js.map +0 -7
- package/analytics/sinks/northbeam-sink.js.map +0 -7
- package/analytics/sinks/pinterest-sink.js.map +0 -7
- package/analytics/sinks/reddit-sink.js.map +0 -7
- package/analytics/sinks/replo-sink.js.map +0 -7
- package/analytics/sinks/snapchat-sink.js.map +0 -7
- package/analytics/sinks/tiktok-sink.js.map +0 -7
- package/analytics/sinks/window-sink.js.map +0 -7
- package/analytics/utils/analytics-utils.js.map +0 -7
- package/analytics/utils/navigation-tracker.js.map +0 -7
- package/analytics/utils/shopify-funnel-gate.js.map +0 -7
- package/cart/buy-now-action.js.map +0 -7
- package/cart/cart-actions.js.map +0 -7
- package/cart/cart-loader.js.map +0 -7
- package/cart/cart-provider.js.map +0 -7
- package/cart/cart-schema.js.map +0 -7
- package/cart/cart-types.js.map +0 -7
- package/cart/gateways/cart-constants.js.map +0 -7
- package/cart/gateways/cart-gateway.js.map +0 -7
- package/cart/gateways/cookie-cart-gateway.js.map +0 -7
- package/cart/gateways/default-cart-gateway.js.map +0 -7
- package/cart/gateways/resolver-cart-gateway.js.map +0 -7
- package/cart/gateways/stripe-cart-gateway.js.map +0 -7
- package/cart/hooks/use-add-to-cart.js.map +0 -7
- package/cart/hooks/use-buy-now.js.map +0 -7
- package/cart/return-urls.js.map +0 -7
- package/cart/storefront-urls.js.map +0 -7
- package/cart/utils/cart-adjustments.js.map +0 -7
- package/cart/utils/cart-analytics.js.map +0 -7
- package/cart/utils/cart-error.js.map +0 -7
- package/cart/utils/cart-utils.js.map +0 -7
- package/cart/utils/cookie-cart-persistence.js.map +0 -7
- package/cart/utils/variant-to-cart-line.js.map +0 -7
- package/consent/consent-action.js.map +0 -7
- package/consent/consent-actions.js.map +0 -7
- package/consent/consent-platform.js.map +0 -7
- package/consent/consent-store.js.map +0 -7
- package/consent/cookie.js.map +0 -7
- package/consent/inject-script-descriptors.js.map +0 -7
- package/consent/replo-scripts.js.map +0 -7
- package/consent/script-registration-store.js.map +0 -7
- package/consent/script-snippets.js.map +0 -7
- package/consent/types.js.map +0 -7
- package/consent/window-api.js.map +0 -7
- package/content.js.map +0 -7
- package/env.js.map +0 -7
- package/gateways/canopy-api.js.map +0 -7
- package/hooks/use-client-value.js.map +0 -7
- package/hooks/use-formatted-price.js.map +0 -7
- package/lib/buildMetadata.js.map +0 -7
- package/lib/canopy-error.js.map +0 -7
- package/lib/external-navigation.js.map +0 -7
- package/lib/get-query-client.js.map +0 -7
- package/lib/integration-utils.js.map +0 -7
- package/lib/shopify-utils.js.map +0 -7
- package/lib/url-utils.js.map +0 -7
- package/loaders/collection-loader-args.js.map +0 -7
- package/loaders/collection-loader.js.map +0 -7
- package/loaders/collection-products-loader-args.js.map +0 -7
- package/loaders/collection-products-loader.js.map +0 -7
- package/loaders/contentful-entries-loader.js.map +0 -7
- package/loaders/contentful-entry-loader.js.map +0 -7
- package/loaders/invoke-loader-action.js.map +0 -7
- package/loaders/invoke-loader-server.js.map +0 -7
- package/loaders/invoke-loader.js.map +0 -7
- package/loaders/judgeme-review-aggregate-loader.js.map +0 -7
- package/loaders/judgeme-reviews-loader.js.map +0 -7
- package/loaders/levanta-product-loader.js.map +0 -7
- package/loaders/loader-error-boundary.js.map +0 -7
- package/loaders/loader-keys.js.map +0 -7
- package/loaders/loader-schemas.js.map +0 -7
- package/loaders/loox-review-aggregate-loader.js.map +0 -7
- package/loaders/loox-reviews-loader.js.map +0 -7
- package/loaders/metaobject-loader.js.map +0 -7
- package/loaders/metaobjects-loader.js.map +0 -7
- package/loaders/okendo-review-aggregate-loader.js.map +0 -7
- package/loaders/okendo-reviews-loader.js.map +0 -7
- package/loaders/prefetch-loaders.js.map +0 -7
- package/loaders/preview-placeholder.js.map +0 -7
- package/loaders/product-loader-args.js.map +0 -7
- package/loaders/product-loader.js.map +0 -7
- package/loaders/rebuy-recommendations-loader.js.map +0 -7
- package/loaders/reviews-io-review-aggregate-loader.js.map +0 -7
- package/loaders/reviews-io-reviews-loader.js.map +0 -7
- package/loaders/smile-earning-rules-loader.js.map +0 -7
- package/loaders/smile-rewards-loader.js.map +0 -7
- package/loaders/smile-vip-tiers-loader.js.map +0 -7
- package/loaders/statsig-experiment-loader.js.map +0 -7
- package/loaders/yotpo-review-aggregate-loader.js.map +0 -7
- package/loaders/yotpo-reviews-loader.js.map +0 -7
- package/money.js.map +0 -7
- package/next/config.js.map +0 -7
- package/next/image-loader.js.map +0 -7
- package/next/open-next.js.map +0 -7
- package/orders/order-status-schema.js.map +0 -7
- package/orders/order-status.js.map +0 -7
- package/providers/query-provider.js.map +0 -7
- package/providers/replo-provider.js.map +0 -7
- package/routing/evaluate.js.map +0 -7
- package/routing/geo.js.map +0 -7
- package/routing/locale.js.map +0 -7
- package/routing/rules.js.map +0 -7
|
@@ -4,8 +4,6 @@ export declare function metafieldContainsHtml(metafieldValue: string): boolean;
|
|
|
4
4
|
export declare function capitalizeFirstLetter(inputString: string): string;
|
|
5
5
|
/**
|
|
6
6
|
* Get url without query params.
|
|
7
|
-
*
|
|
8
|
-
* @author Kurt 2024-10-14
|
|
9
7
|
*/
|
|
10
8
|
export declare const getUrlWithoutQueryParams: (url: string) => string | undefined;
|
|
11
9
|
/**
|
|
@@ -186,9 +186,6 @@ export type ErrorDetails = {
|
|
|
186
186
|
* Map of error keys to custom user-facing details. Should ONLY be used
|
|
187
187
|
* in cases where we want to override the default behavior of ErrorUserFacingDetails
|
|
188
188
|
* from the backend.
|
|
189
|
-
*
|
|
190
|
-
* TODO (Noah, 2024-01-15): Clean up these custom configs, all of them
|
|
191
|
-
* are only used by Django (and 'base' can be moved directly into the reducer function)
|
|
192
189
|
*/
|
|
193
190
|
export declare const CUSTOM_ERROR_KEY_TO_PROPS: {
|
|
194
191
|
"shopifyArticle.failedToPublish": () => {
|
|
@@ -15,7 +15,7 @@ export declare function fromMajorUnitsToMinorUnits({ amount, currencyCode, }: {
|
|
|
15
15
|
currencyCode: string;
|
|
16
16
|
}): number;
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* safe companion to fromMajorUnitsToMinorUnits for
|
|
19
19
|
* possibly-blank or user/CSV/provider-entered decimal strings — returns null
|
|
20
20
|
* for blank or non-numeric input instead of throwing. Callers with a
|
|
21
21
|
* source-specific cleaning or validation policy sanitize first, then convert
|
|
@@ -4,7 +4,6 @@ import '../../chunk-GV5FY7ZZ.mjs';
|
|
|
4
4
|
import { __commonJS, __toESM } from '../../chunk-UJCSKKID.mjs';
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
|
|
7
|
-
// ../../node_modules/.pnpm/first-match@0.0.1/node_modules/first-match/index.js
|
|
8
7
|
var require_first_match = __commonJS({
|
|
9
8
|
"../../node_modules/.pnpm/first-match@0.0.1/node_modules/first-match/index.js"(exports, module) {
|
|
10
9
|
function truthy(d) {
|
|
@@ -20,7 +19,6 @@ var require_first_match = __commonJS({
|
|
|
20
19
|
}
|
|
21
20
|
});
|
|
22
21
|
|
|
23
|
-
// ../../node_modules/.pnpm/nub@0.0.0/node_modules/nub/index.js
|
|
24
22
|
var require_nub = __commonJS({
|
|
25
23
|
"../../node_modules/.pnpm/nub@0.0.0/node_modules/nub/index.js"(exports, module) {
|
|
26
24
|
var nub = module.exports = function(xs, cmp) {
|
|
@@ -75,7 +73,6 @@ var require_nub = __commonJS({
|
|
|
75
73
|
}
|
|
76
74
|
});
|
|
77
75
|
|
|
78
|
-
// ../../node_modules/.pnpm/currency-codes@2.2.0/node_modules/currency-codes/data.js
|
|
79
76
|
var require_data = __commonJS({
|
|
80
77
|
"../../node_modules/.pnpm/currency-codes@2.2.0/node_modules/currency-codes/data.js"(exports, module) {
|
|
81
78
|
module.exports = [
|
|
@@ -1792,14 +1789,12 @@ var require_data = __commonJS({
|
|
|
1792
1789
|
}
|
|
1793
1790
|
});
|
|
1794
1791
|
|
|
1795
|
-
// ../../node_modules/.pnpm/currency-codes@2.2.0/node_modules/currency-codes/iso-4217-publish-date.js
|
|
1796
1792
|
var require_iso_4217_publish_date = __commonJS({
|
|
1797
1793
|
"../../node_modules/.pnpm/currency-codes@2.2.0/node_modules/currency-codes/iso-4217-publish-date.js"(exports, module) {
|
|
1798
1794
|
module.exports = "2024-06-25";
|
|
1799
1795
|
}
|
|
1800
1796
|
});
|
|
1801
1797
|
|
|
1802
|
-
// ../../node_modules/.pnpm/currency-codes@2.2.0/node_modules/currency-codes/index.js
|
|
1803
1798
|
var require_currency_codes = __commonJS({
|
|
1804
1799
|
"../../node_modules/.pnpm/currency-codes@2.2.0/node_modules/currency-codes/index.js"(exports) {
|
|
1805
1800
|
var first = require_first_match();
|
|
@@ -1859,7 +1854,6 @@ var require_currency_codes = __commonJS({
|
|
|
1859
1854
|
}
|
|
1860
1855
|
});
|
|
1861
1856
|
|
|
1862
|
-
// ../schemas/money.ts
|
|
1863
1857
|
var import_currency_codes = __toESM(require_currency_codes());
|
|
1864
1858
|
var InvalidAmountError = class extends ReploError {
|
|
1865
1859
|
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=analytics-sink.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AnalyticsCollection, AnalyticsCollectionProduct } from "../utils/collection-analytics";
|
|
2
|
+
interface UseCollectionViewedAnalyticsProps {
|
|
3
|
+
collection: AnalyticsCollection | null | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* The collection's products as the collection-products loader returns them.
|
|
6
|
+
* Pass `undefined` while they are still loading so the event carries the
|
|
7
|
+
* list when it fires.
|
|
8
|
+
*/
|
|
9
|
+
products: AnalyticsCollectionProduct[] | null | undefined;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Fires a `viewCollection` analytics event carrying the collection's products
|
|
13
|
+
* once the collection and its product list are both available. Re-renders
|
|
14
|
+
* and product-list updates for the same collection do not fire again; a
|
|
15
|
+
* different collection does, and returning to an earlier one counts as a new
|
|
16
|
+
* view, matching `useProductViewedAnalytics`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function useCollectionViewedAnalytics({ collection, products, }: UseCollectionViewedAnalyticsProps): void;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
3
|
+
import { useAnalytics } from "../analytics-provider";
|
|
4
|
+
import { buildCollectionViewedAnalyticsData } from "../utils/collection-analytics";
|
|
5
|
+
function useCollectionViewedAnalytics({
|
|
6
|
+
collection,
|
|
7
|
+
products
|
|
8
|
+
}) {
|
|
9
|
+
const analytics = useAnalytics();
|
|
10
|
+
const lastTrackedRef = useRef(null);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!analytics || !collection || !products) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (lastTrackedRef.current === collection.id) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
lastTrackedRef.current = collection.id;
|
|
19
|
+
void analytics.viewCollection({
|
|
20
|
+
data: buildCollectionViewedAnalyticsData({ collection, products })
|
|
21
|
+
});
|
|
22
|
+
}, [analytics, collection, products]);
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
useCollectionViewedAnalytics
|
|
26
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { legacyResourceId } from "../utils/analytics-products";
|
|
2
3
|
const GUEST_USER_PROPERTIES = { visitor_type: "guest" };
|
|
3
4
|
const FALLBACK_CURRENCY_CODE = "USD";
|
|
4
5
|
const nonEmptyStringSchema = z.union([z.string().min(1), z.number().finite().transform(String)]).optional().catch(void 0);
|
|
@@ -45,9 +46,6 @@ const collectionPayloadSchema = z.object({
|
|
|
45
46
|
function formatMoney(amount) {
|
|
46
47
|
return amount.toFixed(2);
|
|
47
48
|
}
|
|
48
|
-
function legacyResourceId(id) {
|
|
49
|
-
return id.replace(/^gid:\/\/shopify\/\w+\//, "");
|
|
50
|
-
}
|
|
51
49
|
function parseCheckoutLine(line) {
|
|
52
50
|
const parsed = checkoutLineSchema.safeParse(line);
|
|
53
51
|
if (!parsed.success || !parsed.data.merchandise) {
|
|
@@ -257,4 +255,3 @@ class ElevarSink {
|
|
|
257
255
|
export {
|
|
258
256
|
ElevarSink
|
|
259
257
|
};
|
|
260
|
-
//# sourceMappingURL=elevar-sink.js.map
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
legacyResourceId,
|
|
3
|
+
splitCollectionProducts,
|
|
4
|
+
withoutUndefined
|
|
5
|
+
} from "../utils/analytics-products";
|
|
1
6
|
import { createEventQueue } from "../utils/analytics-utils";
|
|
2
7
|
class GA4Sink {
|
|
3
|
-
// oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
|
|
4
8
|
send;
|
|
5
9
|
constructor() {
|
|
6
10
|
this.send = createEventQueue(
|
|
7
|
-
// Legacy cast - may or may not be necessary
|
|
8
|
-
// oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed
|
|
9
11
|
() => typeof window !== "undefined" && Boolean(window.gtag),
|
|
10
12
|
(event, params) => {
|
|
11
13
|
const gtag = window.gtag;
|
|
@@ -51,10 +53,26 @@ class GA4Sink {
|
|
|
51
53
|
this.send("begin_checkout", data);
|
|
52
54
|
}
|
|
53
55
|
async viewCollection({ data }) {
|
|
54
|
-
|
|
56
|
+
const { products, rest } = splitCollectionProducts(data);
|
|
57
|
+
this.send("view_item_list", {
|
|
58
|
+
item_list_id: data.collectionId,
|
|
59
|
+
item_list_name: data.collectionTitle,
|
|
60
|
+
currency: data.currency,
|
|
61
|
+
...products.length > 0 ? {
|
|
62
|
+
items: products.map((product, index) => {
|
|
63
|
+
return withoutUndefined({
|
|
64
|
+
item_id: legacyResourceId(product.productId),
|
|
65
|
+
item_name: product.productTitle,
|
|
66
|
+
item_variant: product.variantTitle,
|
|
67
|
+
price: product.price,
|
|
68
|
+
index
|
|
69
|
+
});
|
|
70
|
+
})
|
|
71
|
+
} : {},
|
|
72
|
+
...rest
|
|
73
|
+
});
|
|
55
74
|
}
|
|
56
75
|
}
|
|
57
76
|
export {
|
|
58
77
|
GA4Sink
|
|
59
78
|
};
|
|
60
|
-
//# sourceMappingURL=ga4-sink.js.map
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { createEventQueue } from "../utils/analytics-utils";
|
|
2
2
|
class MetaSink {
|
|
3
|
-
// oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
|
|
4
3
|
track;
|
|
5
4
|
constructor() {
|
|
6
5
|
this.track = createEventQueue(
|
|
7
|
-
// Legacy cast - may or may not be necessary
|
|
8
|
-
// oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed
|
|
9
6
|
() => typeof window !== "undefined" && Boolean(window.fbq),
|
|
10
7
|
(event, params) => {
|
|
11
8
|
const fbq = window.fbq;
|
|
@@ -53,4 +50,3 @@ class MetaSink {
|
|
|
53
50
|
export {
|
|
54
51
|
MetaSink
|
|
55
52
|
};
|
|
56
|
-
//# sourceMappingURL=meta-sink.js.map
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
legacyResourceId,
|
|
3
|
+
splitCollectionProducts,
|
|
4
|
+
withoutUndefined
|
|
5
|
+
} from "../utils/analytics-products";
|
|
1
6
|
import { createEventQueue } from "../utils/analytics-utils";
|
|
2
7
|
class PinterestSink {
|
|
3
|
-
// oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
|
|
4
8
|
track;
|
|
5
9
|
constructor() {
|
|
6
10
|
this.track = createEventQueue(
|
|
7
|
-
// Legacy cast - may or may not be necessary
|
|
8
|
-
// oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed
|
|
9
11
|
() => typeof window !== "undefined" && Boolean(window.pintrk),
|
|
10
12
|
(event, params) => {
|
|
11
13
|
const pintrk = window.pintrk;
|
|
@@ -64,13 +66,25 @@ class PinterestSink {
|
|
|
64
66
|
});
|
|
65
67
|
}
|
|
66
68
|
async viewCollection({ data }) {
|
|
69
|
+
const { products, rest } = splitCollectionProducts(data);
|
|
67
70
|
this.track("viewcategory", {
|
|
68
71
|
product_category: data.category,
|
|
69
|
-
|
|
72
|
+
currency: data.currency,
|
|
73
|
+
...products.length > 0 ? {
|
|
74
|
+
line_items: products.map((product) => {
|
|
75
|
+
return withoutUndefined({
|
|
76
|
+
product_id: legacyResourceId(product.productId),
|
|
77
|
+
product_name: product.productTitle,
|
|
78
|
+
product_price: product.price,
|
|
79
|
+
product_variant_id: product.variantId === void 0 ? void 0 : legacyResourceId(product.variantId),
|
|
80
|
+
product_variant: product.variantTitle
|
|
81
|
+
});
|
|
82
|
+
})
|
|
83
|
+
} : {},
|
|
84
|
+
...rest
|
|
70
85
|
});
|
|
71
86
|
}
|
|
72
87
|
}
|
|
73
88
|
export {
|
|
74
89
|
PinterestSink
|
|
75
90
|
};
|
|
76
|
-
//# sourceMappingURL=pinterest-sink.js.map
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
legacyResourceId,
|
|
3
|
+
splitCollectionProducts,
|
|
4
|
+
withoutUndefined
|
|
5
|
+
} from "../utils/analytics-products";
|
|
1
6
|
import { createEventQueue } from "../utils/analytics-utils";
|
|
2
7
|
class RedditSink {
|
|
3
|
-
// oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
|
|
4
8
|
track;
|
|
5
9
|
constructor() {
|
|
6
10
|
this.track = createEventQueue(
|
|
7
|
-
// Legacy cast - may or may not be necessary
|
|
8
|
-
// oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed
|
|
9
11
|
() => typeof window !== "undefined" && Boolean(window.rdt),
|
|
10
12
|
(event, params) => {
|
|
11
13
|
const rdt = window.rdt;
|
|
@@ -67,14 +69,23 @@ class RedditSink {
|
|
|
67
69
|
});
|
|
68
70
|
}
|
|
69
71
|
async viewCollection({ data }) {
|
|
72
|
+
const { products, rest } = splitCollectionProducts(data);
|
|
70
73
|
this.track("ViewContent", {
|
|
71
74
|
content_category: data.category,
|
|
72
75
|
content_type: "category",
|
|
73
|
-
|
|
76
|
+
currency: data.currency,
|
|
77
|
+
...products.length > 0 ? {
|
|
78
|
+
products: products.map((product) => {
|
|
79
|
+
return withoutUndefined({
|
|
80
|
+
id: legacyResourceId(product.productId),
|
|
81
|
+
name: product.productTitle
|
|
82
|
+
});
|
|
83
|
+
})
|
|
84
|
+
} : {},
|
|
85
|
+
...rest
|
|
74
86
|
});
|
|
75
87
|
}
|
|
76
88
|
}
|
|
77
89
|
export {
|
|
78
90
|
RedditSink
|
|
79
91
|
};
|
|
80
|
-
//# sourceMappingURL=reddit-sink.js.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { createMethodQueue } from "../utils/analytics-utils";
|
|
2
2
|
class ReploSink {
|
|
3
|
-
// oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
|
|
4
3
|
forward;
|
|
5
4
|
constructor() {
|
|
6
5
|
this.forward = createMethodQueue(
|
|
@@ -54,4 +53,3 @@ class ReploSink {
|
|
|
54
53
|
export {
|
|
55
54
|
ReploSink
|
|
56
55
|
};
|
|
57
|
-
//# sourceMappingURL=replo-sink.js.map
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { createEventQueue } from "../utils/analytics-utils";
|
|
2
2
|
class SnapchatSink {
|
|
3
|
-
// oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
|
|
4
3
|
track;
|
|
5
4
|
constructor() {
|
|
6
5
|
this.track = createEventQueue(
|
|
7
|
-
// Legacy cast - may or may not be necessary
|
|
8
|
-
// oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed
|
|
9
6
|
() => typeof window !== "undefined" && Boolean(window.snaptr),
|
|
10
7
|
(event, params) => {
|
|
11
8
|
const snaptr = window.snaptr;
|
|
@@ -64,4 +61,3 @@ class SnapchatSink {
|
|
|
64
61
|
export {
|
|
65
62
|
SnapchatSink
|
|
66
63
|
};
|
|
67
|
-
//# sourceMappingURL=snapchat-sink.js.map
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
legacyResourceId,
|
|
3
|
+
splitCollectionProducts,
|
|
4
|
+
withoutUndefined
|
|
5
|
+
} from "../utils/analytics-products";
|
|
1
6
|
import { createEventQueue } from "../utils/analytics-utils";
|
|
2
7
|
class TikTokSink {
|
|
3
|
-
// oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
|
|
4
8
|
track;
|
|
5
9
|
constructor() {
|
|
6
10
|
this.track = createEventQueue(
|
|
7
|
-
// Legacy cast - may or may not be necessary
|
|
8
|
-
// oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed
|
|
9
11
|
() => typeof window !== "undefined" && Boolean(window.ttq),
|
|
10
12
|
(event, params) => {
|
|
11
13
|
const ttq = window.ttq;
|
|
@@ -66,14 +68,25 @@ class TikTokSink {
|
|
|
66
68
|
});
|
|
67
69
|
}
|
|
68
70
|
async viewCollection({ data }) {
|
|
71
|
+
const { products, rest } = splitCollectionProducts(data);
|
|
69
72
|
this.track("ViewContent", {
|
|
70
73
|
content_type: "product_group",
|
|
71
74
|
content_category: data.category,
|
|
72
|
-
|
|
75
|
+
currency: data.currency,
|
|
76
|
+
...products.length > 0 ? {
|
|
77
|
+
contents: products.map((product) => {
|
|
78
|
+
return withoutUndefined({
|
|
79
|
+
content_id: legacyResourceId(product.productId),
|
|
80
|
+
content_type: "product_group",
|
|
81
|
+
content_name: product.productTitle,
|
|
82
|
+
price: product.price
|
|
83
|
+
});
|
|
84
|
+
})
|
|
85
|
+
} : {},
|
|
86
|
+
...rest
|
|
73
87
|
});
|
|
74
88
|
}
|
|
75
89
|
}
|
|
76
90
|
export {
|
|
77
91
|
TikTokSink
|
|
78
92
|
};
|
|
79
|
-
//# sourceMappingURL=tiktok-sink.js.map
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
class WindowSink {
|
|
2
|
-
// oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
|
|
3
2
|
dispatch(eventType, payload) {
|
|
4
3
|
window.dispatchEvent(
|
|
5
4
|
new CustomEvent("replo:analytics", {
|
|
@@ -11,7 +10,6 @@ class WindowSink {
|
|
|
11
10
|
})
|
|
12
11
|
);
|
|
13
12
|
}
|
|
14
|
-
// oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
|
|
15
13
|
async pageView(payload) {
|
|
16
14
|
this.dispatch("page_viewed", payload);
|
|
17
15
|
}
|
|
@@ -43,4 +41,3 @@ class WindowSink {
|
|
|
43
41
|
export {
|
|
44
42
|
WindowSink
|
|
45
43
|
};
|
|
46
|
-
//# sourceMappingURL=window-sink.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { 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
|
+
/**
|
|
30
|
+
* Shopify catalogs synced into ad platforms key on legacy numeric ids, while
|
|
31
|
+
* the Storefront API hands sites GIDs (`gid://shopify/Product/123`). Pixel
|
|
32
|
+
* catalog matching is an exact string match, so ids are sent bare.
|
|
33
|
+
*/
|
|
34
|
+
export declare function legacyResourceId(id: string): string;
|
|
35
|
+
export declare function withoutUndefined<RecordType extends Record<string, unknown>>(record: RecordType): Partial<RecordType>;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { 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
|
+
{ products }
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
return { products: lines, rest };
|
|
39
|
+
}
|
|
40
|
+
function legacyResourceId(id) {
|
|
41
|
+
return id.replace(/^gid:\/\/shopify\/\w+\//, "");
|
|
42
|
+
}
|
|
43
|
+
function withoutUndefined(record) {
|
|
44
|
+
const compacted = {};
|
|
45
|
+
for (const key in record) {
|
|
46
|
+
if (record[key] !== void 0) {
|
|
47
|
+
compacted[key] = record[key];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return compacted;
|
|
51
|
+
}
|
|
52
|
+
export {
|
|
53
|
+
legacyResourceId,
|
|
54
|
+
parseAnalyticsProductLines,
|
|
55
|
+
splitCollectionProducts,
|
|
56
|
+
withoutUndefined
|
|
57
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface AnalyticsMoney {
|
|
2
|
+
amount: number | string;
|
|
3
|
+
currencyCode: string;
|
|
4
|
+
}
|
|
5
|
+
export interface AnalyticsCollection {
|
|
6
|
+
id: string;
|
|
7
|
+
title?: string | null;
|
|
8
|
+
handle?: string | null;
|
|
9
|
+
}
|
|
10
|
+
export interface AnalyticsCollectionProductVariant {
|
|
11
|
+
id: string;
|
|
12
|
+
title?: string | null;
|
|
13
|
+
sku?: string | null;
|
|
14
|
+
price?: AnalyticsMoney | null;
|
|
15
|
+
}
|
|
16
|
+
export interface AnalyticsCollectionProduct {
|
|
17
|
+
id: string;
|
|
18
|
+
title?: string | null;
|
|
19
|
+
variants?: AnalyticsCollectionProductVariant[] | null;
|
|
20
|
+
minPrice?: AnalyticsMoney | null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The `viewCollection` payload: collection identity plus one line per product
|
|
24
|
+
* in the same shape the cart events use, priced from the first variant (or
|
|
25
|
+
* the product's minimum price) with no quantity.
|
|
26
|
+
*/
|
|
27
|
+
export declare function buildCollectionViewedAnalyticsData({ collection, products, }: {
|
|
28
|
+
collection: AnalyticsCollection;
|
|
29
|
+
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
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { withoutUndefined } from "./analytics-products";
|
|
2
|
+
function parseAmount(money) {
|
|
3
|
+
if (!money) {
|
|
4
|
+
return void 0;
|
|
5
|
+
}
|
|
6
|
+
const amount = Number(money.amount);
|
|
7
|
+
return Number.isFinite(amount) ? amount : void 0;
|
|
8
|
+
}
|
|
9
|
+
function buildCollectionProductLine(product) {
|
|
10
|
+
const variant = product.variants?.[0];
|
|
11
|
+
const money = variant?.price ?? product.minPrice ?? void 0;
|
|
12
|
+
return {
|
|
13
|
+
productId: product.id,
|
|
14
|
+
...withoutUndefined({
|
|
15
|
+
productTitle: product.title ?? void 0,
|
|
16
|
+
variantId: variant?.id,
|
|
17
|
+
variantTitle: variant?.title ?? void 0,
|
|
18
|
+
variantSku: variant?.sku ?? void 0,
|
|
19
|
+
price: parseAmount(money),
|
|
20
|
+
currency: money?.currencyCode
|
|
21
|
+
})
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function buildCollectionViewedAnalyticsData({
|
|
25
|
+
collection,
|
|
26
|
+
products
|
|
27
|
+
}) {
|
|
28
|
+
const lines = products.map(buildCollectionProductLine);
|
|
29
|
+
return {
|
|
30
|
+
collectionId: collection.id,
|
|
31
|
+
products: lines,
|
|
32
|
+
...withoutUndefined({
|
|
33
|
+
collectionTitle: collection.title ?? void 0,
|
|
34
|
+
collectionHandle: collection.handle ?? void 0,
|
|
35
|
+
currency: lines.find((line) => line.currency)?.currency
|
|
36
|
+
})
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
buildCollectionViewedAnalyticsData
|
|
41
|
+
};
|