@chordcommerce/analytics 1.22.0-beta.1 → 1.22.0-beta.2
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 +7 -1
- package/dist/cjs/client/cdp.js +0 -6
- package/dist/cjs/client/consent/index.js +3 -10
- package/dist/cjs/client/consent/onetrust-api.d.ts +10 -0
- package/dist/cjs/client/consent/onetrust-api.js +14 -1
- package/dist/cjs/client/consent/onetrust.js +1 -1
- package/dist/cjs/client/identifiers.d.ts +10 -6
- package/dist/cjs/client/identifiers.js +10 -6
- package/dist/cjs/client/index.d.ts +2 -2
- package/dist/cjs/client/index.js +11 -7
- package/dist/cjs/types/client.d.ts +8 -6
- package/dist/client/cdp.js +0 -6
- package/dist/client/consent/index.js +3 -8
- package/dist/client/consent/onetrust-api.d.ts +10 -0
- package/dist/client/consent/onetrust-api.js +12 -0
- package/dist/client/consent/onetrust.js +2 -2
- package/dist/client/identifiers.d.ts +10 -6
- package/dist/client/identifiers.js +10 -6
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +93 -89
- package/dist/types/client.d.ts +8 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -181,13 +181,19 @@ The release flow:
|
|
|
181
181
|
4. If releasable commits exist, the package is published to npm and GitHub Packages, CHANGELOG.md is updated, and a Git tag is created.
|
|
182
182
|
5. If no releasable commits exist, `semantic-release` exits cleanly and nothing is published.
|
|
183
183
|
|
|
184
|
+
### PR titles must follow conventional commits
|
|
185
|
+
|
|
186
|
+
When using GitHub's **squash merge** (the default), the PR title becomes the first line of the squash commit message. Semantic-release only parses the **first line** to determine the version bump, so **the PR title must use a conventional commit prefix** (e.g., `fix: resolve consent race condition`). Individual commit messages in the PR body are ignored.
|
|
187
|
+
|
|
188
|
+
If the PR title does not start with a releasable prefix, no release will be published even if the individual commits within the PR use `fix:` or `feat:`.
|
|
189
|
+
|
|
184
190
|
### When a release happens (and when it doesn't)
|
|
185
191
|
|
|
186
192
|
A release is published **only** when all three conditions are met:
|
|
187
193
|
|
|
188
194
|
1. A push lands on `main` or `beta` (via merged PR or direct push)
|
|
189
195
|
2. Tests pass
|
|
190
|
-
3. There are new commits since the last release tag with a releasable prefix
|
|
196
|
+
3. There are new commits since the last release tag with a releasable prefix (checked against the **first line** of each commit message)
|
|
191
197
|
|
|
192
198
|
**Releasable commit prefixes** (these trigger a version bump):
|
|
193
199
|
|
package/dist/cjs/client/cdp.js
CHANGED
|
@@ -80,15 +80,9 @@ var addCdpSnippet = function (options) { return __awaiter(void 0, void 0, void 0
|
|
|
80
80
|
_a.sent();
|
|
81
81
|
initialConsent = null;
|
|
82
82
|
if (!options.consent) return [3 /*break*/, 3];
|
|
83
|
-
if (options.debug && options.enableLogging) {
|
|
84
|
-
console.log('[Chord Analytics DEBUG]: Setting up consent management');
|
|
85
|
-
}
|
|
86
83
|
return [4 /*yield*/, (0, index_js_1.addCdpConsent)(options).init()];
|
|
87
84
|
case 2:
|
|
88
85
|
initialConsent = _a.sent();
|
|
89
|
-
if (options.debug && options.enableLogging) {
|
|
90
|
-
console.log('[Chord Analytics DEBUG]: Consent management setup complete');
|
|
91
|
-
}
|
|
92
86
|
_a.label = 3;
|
|
93
87
|
case 3:
|
|
94
88
|
if (options.debug && options.enableLogging) {
|
|
@@ -152,7 +152,7 @@ var addCdpConsent = function (options) {
|
|
|
152
152
|
* or null if consent setup failed or was blocked.
|
|
153
153
|
*/
|
|
154
154
|
var init = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
155
|
-
var canBeTracked,
|
|
155
|
+
var canBeTracked, error_1;
|
|
156
156
|
return __generator(this, function (_a) {
|
|
157
157
|
switch (_a.label) {
|
|
158
158
|
case 0:
|
|
@@ -180,17 +180,10 @@ var addCdpConsent = function (options) {
|
|
|
180
180
|
case 2:
|
|
181
181
|
_a.trys.push([2, 4, , 5]);
|
|
182
182
|
return [4 /*yield*/, setupConsentManagement()];
|
|
183
|
-
case 3:
|
|
184
|
-
result = _a.sent();
|
|
185
|
-
if (options.debug && options.enableLogging) {
|
|
186
|
-
console.log('[Chord Analytics DEBUG]: setupConsentManagement() returned:', JSON.stringify(result));
|
|
187
|
-
}
|
|
188
|
-
return [2 /*return*/, result];
|
|
183
|
+
case 3: return [2 /*return*/, _a.sent()];
|
|
189
184
|
case 4:
|
|
190
185
|
error_1 = _a.sent();
|
|
191
|
-
|
|
192
|
-
console.error('[Chord Analytics DEBUG]: Error setting up consent management:', error_1);
|
|
193
|
-
}
|
|
186
|
+
console.error('Error setting up consent management:', error_1);
|
|
194
187
|
return [2 /*return*/, null];
|
|
195
188
|
case 5: return [2 /*return*/];
|
|
196
189
|
}
|
|
@@ -71,6 +71,16 @@ export declare const getOneTrustActiveGroups: () => string | undefined;
|
|
|
71
71
|
* getNormalizedActiveGroupIds() // ["C0001", "C0003"]
|
|
72
72
|
*/
|
|
73
73
|
export declare const getNormalizedActiveGroupIds: () => string[];
|
|
74
|
+
/**
|
|
75
|
+
* Check if OnetrustActiveGroups is populated with actual consent categories.
|
|
76
|
+
*
|
|
77
|
+
* OneTrust sets window.OnetrustActiveGroups after the API object is available,
|
|
78
|
+
* so this guards against a race condition where the API exists but consent
|
|
79
|
+
* categories have not yet been populated.
|
|
80
|
+
*
|
|
81
|
+
* @returns true if OnetrustActiveGroups is a non-empty string with at least one group ID
|
|
82
|
+
*/
|
|
83
|
+
export declare const hasActiveGroups: () => boolean;
|
|
74
84
|
/**
|
|
75
85
|
* Get all configured consent groups from OneTrust.
|
|
76
86
|
*
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Modeled after analytics-next's onetrust-api.ts
|
|
9
9
|
*/
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.coerceConsentModel = exports.getNormalizedCategories = exports.getAllGroups = exports.getNormalizedActiveGroupIds = exports.getOneTrustActiveGroups = exports.getOneTrustGlobal = exports.OtConsentModel = void 0;
|
|
11
|
+
exports.coerceConsentModel = exports.getNormalizedCategories = exports.getAllGroups = exports.hasActiveGroups = exports.getNormalizedActiveGroupIds = exports.getOneTrustActiveGroups = exports.getOneTrustGlobal = exports.OtConsentModel = void 0;
|
|
12
12
|
/**
|
|
13
13
|
* OneTrust consent model types
|
|
14
14
|
*/
|
|
@@ -70,6 +70,19 @@ var getNormalizedActiveGroupIds = function () {
|
|
|
70
70
|
return groups.trim().split(',').filter(Boolean);
|
|
71
71
|
};
|
|
72
72
|
exports.getNormalizedActiveGroupIds = getNormalizedActiveGroupIds;
|
|
73
|
+
/**
|
|
74
|
+
* Check if OnetrustActiveGroups is populated with actual consent categories.
|
|
75
|
+
*
|
|
76
|
+
* OneTrust sets window.OnetrustActiveGroups after the API object is available,
|
|
77
|
+
* so this guards against a race condition where the API exists but consent
|
|
78
|
+
* categories have not yet been populated.
|
|
79
|
+
*
|
|
80
|
+
* @returns true if OnetrustActiveGroups is a non-empty string with at least one group ID
|
|
81
|
+
*/
|
|
82
|
+
var hasActiveGroups = function () {
|
|
83
|
+
return (0, exports.getNormalizedActiveGroupIds)().length > 0;
|
|
84
|
+
};
|
|
85
|
+
exports.hasActiveGroups = hasActiveGroups;
|
|
73
86
|
/**
|
|
74
87
|
* Get all configured consent groups from OneTrust.
|
|
75
88
|
*
|
|
@@ -63,7 +63,7 @@ var onetrustConsentAdapter = function (options) {
|
|
|
63
63
|
},
|
|
64
64
|
userCanBeTracked: userCanBeTracked,
|
|
65
65
|
getCategories: function () { return (0, onetrust_api_js_1.getNormalizedCategories)(); },
|
|
66
|
-
isConsentReady: function () { return !!(0, onetrust_api_js_1.getOneTrustGlobal)(); },
|
|
66
|
+
isConsentReady: function () { return !!(0, onetrust_api_js_1.getOneTrustGlobal)() && (0, onetrust_api_js_1.hasActiveGroups)(); },
|
|
67
67
|
getConsentModel: function () {
|
|
68
68
|
var api = (0, onetrust_api_js_1.getOneTrustGlobal)();
|
|
69
69
|
if (!api)
|
|
@@ -39,13 +39,17 @@ export declare const getShopifyCart: (baseUrl?: string, localePath?: string) =>
|
|
|
39
39
|
*/
|
|
40
40
|
export declare const updateShopifyCartAttributes: (attributes: Record<string, string>, baseUrl?: string, localePath?: string) => Promise<ShopifyCart>;
|
|
41
41
|
/**
|
|
42
|
-
* Sync identifiers to Shopify cart attributes.
|
|
42
|
+
* Sync CDP and analytics identifiers to Shopify cart attributes.
|
|
43
43
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
44
|
+
* By default, syncs the Chord CDP anonymous ID (`__eventn_id` cookie) and
|
|
45
|
+
* Google Analytics client ID (`_ga` cookie) to the cart. These attributes
|
|
46
|
+
* are included in Shopify order webhooks, enabling server-side events to
|
|
47
|
+
* correlate with client-side tracking sessions.
|
|
48
48
|
*
|
|
49
|
-
*
|
|
49
|
+
* Smart deduplication: only updates the cart if identifiers are missing or
|
|
50
|
+
* have changed, avoiding unnecessary API calls on repeat page loads.
|
|
51
|
+
*
|
|
52
|
+
* @param options - Optional configuration for base URL, locale path, or custom identifier getter
|
|
53
|
+
* @returns The updated cart, or undefined if no update was needed or an error occurred
|
|
50
54
|
*/
|
|
51
55
|
export declare const syncIdentifiersToCart: (options?: IdentifierSyncOptions) => Promise<ShopifyCart | undefined>;
|
|
@@ -150,14 +150,18 @@ var updateShopifyCartAttributes = function (attributes, baseUrl, localePath) { r
|
|
|
150
150
|
}); };
|
|
151
151
|
exports.updateShopifyCartAttributes = updateShopifyCartAttributes;
|
|
152
152
|
/**
|
|
153
|
-
* Sync identifiers to Shopify cart attributes.
|
|
153
|
+
* Sync CDP and analytics identifiers to Shopify cart attributes.
|
|
154
154
|
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
155
|
+
* By default, syncs the Chord CDP anonymous ID (`__eventn_id` cookie) and
|
|
156
|
+
* Google Analytics client ID (`_ga` cookie) to the cart. These attributes
|
|
157
|
+
* are included in Shopify order webhooks, enabling server-side events to
|
|
158
|
+
* correlate with client-side tracking sessions.
|
|
159
159
|
*
|
|
160
|
-
*
|
|
160
|
+
* Smart deduplication: only updates the cart if identifiers are missing or
|
|
161
|
+
* have changed, avoiding unnecessary API calls on repeat page loads.
|
|
162
|
+
*
|
|
163
|
+
* @param options - Optional configuration for base URL, locale path, or custom identifier getter
|
|
164
|
+
* @returns The updated cart, or undefined if no update was needed or an error occurred
|
|
161
165
|
*/
|
|
162
166
|
var syncIdentifiersToCart = function (options) {
|
|
163
167
|
if (options === void 0) { options = {}; }
|
|
@@ -159,10 +159,10 @@ export declare class ChordAnalytics<T extends ObjectTypes = ObjectTypes> {
|
|
|
159
159
|
private webPixelMessageHandler;
|
|
160
160
|
/**
|
|
161
161
|
* Set up a listener for postMessage events from the Shopify Web Pixel sandbox.
|
|
162
|
-
* This allows the
|
|
162
|
+
* This allows the web pixel (running in Shopify's sandboxed iframe)
|
|
163
163
|
* to forward analytics events to this ChordAnalytics instance on the storefront.
|
|
164
164
|
*
|
|
165
|
-
* The
|
|
165
|
+
* The web pixel sends messages in the format:
|
|
166
166
|
* - { source: 'chord-web-pixel', type: 'track', payload: [eventName, properties] }
|
|
167
167
|
* - { source: 'chord-web-pixel', type: 'identify', payload: [userId, traits] }
|
|
168
168
|
* - { source: 'chord-web-pixel', type: 'page', payload: [properties] }
|
package/dist/cjs/client/index.js
CHANGED
|
@@ -70,7 +70,7 @@ var CONSENT_QUEUE_MAX_EVENTS = 50; // Max number of events to queue
|
|
|
70
70
|
var ChordAnalytics = /** @class */ (function () {
|
|
71
71
|
function ChordAnalytics(options) {
|
|
72
72
|
var _this = this;
|
|
73
|
-
var _a, _b, _c, _d, _e;
|
|
73
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
74
74
|
/**
|
|
75
75
|
* Allows snippet.js to detect whether this library has been initialized yet.
|
|
76
76
|
*/
|
|
@@ -799,10 +799,10 @@ var ChordAnalytics = /** @class */ (function () {
|
|
|
799
799
|
this.webPixelMessageHandler = null;
|
|
800
800
|
/**
|
|
801
801
|
* Set up a listener for postMessage events from the Shopify Web Pixel sandbox.
|
|
802
|
-
* This allows the
|
|
802
|
+
* This allows the web pixel (running in Shopify's sandboxed iframe)
|
|
803
803
|
* to forward analytics events to this ChordAnalytics instance on the storefront.
|
|
804
804
|
*
|
|
805
|
-
* The
|
|
805
|
+
* The web pixel sends messages in the format:
|
|
806
806
|
* - { source: 'chord-web-pixel', type: 'track', payload: [eventName, properties] }
|
|
807
807
|
* - { source: 'chord-web-pixel', type: 'identify', payload: [userId, traits] }
|
|
808
808
|
* - { source: 'chord-web-pixel', type: 'page', payload: [properties] }
|
|
@@ -1447,12 +1447,16 @@ var ChordAnalytics = /** @class */ (function () {
|
|
|
1447
1447
|
window[this.options.namespace] = (window === null || window === void 0 ? void 0 : window[this.options.namespace]) || this;
|
|
1448
1448
|
this.initializeCdp();
|
|
1449
1449
|
}
|
|
1450
|
-
//
|
|
1451
|
-
|
|
1450
|
+
// Set up web pixel listener: explicit true/false takes precedence,
|
|
1451
|
+
// otherwise auto-detect by checking for window.Shopify.shop (Liquid storefront)
|
|
1452
|
+
var shouldEnableWebPixel = (_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.enableWebPixelListener) !== null && _e !== void 0 ? _e : (typeof window !== 'undefined' && !!((_f = window.Shopify) === null || _f === void 0 ? void 0 : _f.shop));
|
|
1453
|
+
if (shouldEnableWebPixel) {
|
|
1452
1454
|
this.setupWebPixelListener();
|
|
1453
1455
|
}
|
|
1454
|
-
//
|
|
1455
|
-
|
|
1456
|
+
// Sync identifiers to cart: explicit true/false takes precedence,
|
|
1457
|
+
// otherwise auto-detect by checking for window.Shopify.shop (Liquid storefront)
|
|
1458
|
+
var shouldEnableIdentifierSync = (_h = (_g = this.options) === null || _g === void 0 ? void 0 : _g.enableIdentifierSync) !== null && _h !== void 0 ? _h : (typeof window !== 'undefined' && !!((_j = window.Shopify) === null || _j === void 0 ? void 0 : _j.shop));
|
|
1459
|
+
if (shouldEnableIdentifierSync) {
|
|
1456
1460
|
this.syncIdentifiersToCart();
|
|
1457
1461
|
}
|
|
1458
1462
|
}
|
|
@@ -35,15 +35,17 @@ export interface ChordAnalyticsOptions<T extends ObjectTypes = ObjectTypes> {
|
|
|
35
35
|
debug?: boolean;
|
|
36
36
|
enableLogging?: boolean;
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
38
|
+
* Controls the postMessage listener for events from the Shopify Custom Web
|
|
39
|
+
* Pixel sandbox. When true, always enables the listener. When false, always
|
|
40
|
+
* disables it. When undefined (default), auto-detects by checking for
|
|
41
|
+
* window.Shopify.shop which is present on Shopify Liquid storefronts.
|
|
41
42
|
*/
|
|
42
43
|
enableWebPixelListener?: boolean;
|
|
43
44
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
45
|
+
* Controls syncing CDP anonymous ID and Google Client ID to Shopify cart
|
|
46
|
+
* attributes. When true, always enables sync. When false, always disables it.
|
|
47
|
+
* When undefined (default), auto-detects by checking for window.Shopify.shop
|
|
48
|
+
* which is present on Shopify Liquid storefronts.
|
|
47
49
|
*/
|
|
48
50
|
enableIdentifierSync?: boolean;
|
|
49
51
|
formatters: ChordAnalyticsFormatters<T>;
|
package/dist/client/cdp.js
CHANGED
|
@@ -44,13 +44,7 @@ export const addCdpSnippet = (options) => __awaiter(void 0, void 0, void 0, func
|
|
|
44
44
|
yield cdpReadyPromise;
|
|
45
45
|
let initialConsent = null;
|
|
46
46
|
if (options.consent) {
|
|
47
|
-
if (options.debug && options.enableLogging) {
|
|
48
|
-
console.log('[Chord Analytics DEBUG]: Setting up consent management');
|
|
49
|
-
}
|
|
50
47
|
initialConsent = yield addCdpConsent(options).init();
|
|
51
|
-
if (options.debug && options.enableLogging) {
|
|
52
|
-
console.log('[Chord Analytics DEBUG]: Consent management setup complete');
|
|
53
|
-
}
|
|
54
48
|
}
|
|
55
49
|
if (options.debug && options.enableLogging) {
|
|
56
50
|
console.log('[Chord Analytics DEBUG]: CDP snippet added, initialConsent:', JSON.stringify(initialConsent));
|
|
@@ -121,17 +121,12 @@ export const addCdpConsent = (options) => {
|
|
|
121
121
|
return null;
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
|
+
// Set up consent management and wait for it to complete
|
|
124
125
|
try {
|
|
125
|
-
|
|
126
|
-
if (options.debug && options.enableLogging) {
|
|
127
|
-
console.log('[Chord Analytics DEBUG]: setupConsentManagement() returned:', JSON.stringify(result));
|
|
128
|
-
}
|
|
129
|
-
return result;
|
|
126
|
+
return yield setupConsentManagement();
|
|
130
127
|
}
|
|
131
128
|
catch (error) {
|
|
132
|
-
|
|
133
|
-
console.error('[Chord Analytics DEBUG]: Error setting up consent management:', error);
|
|
134
|
-
}
|
|
129
|
+
console.error('Error setting up consent management:', error);
|
|
135
130
|
return null;
|
|
136
131
|
}
|
|
137
132
|
});
|
|
@@ -71,6 +71,16 @@ export declare const getOneTrustActiveGroups: () => string | undefined;
|
|
|
71
71
|
* getNormalizedActiveGroupIds() // ["C0001", "C0003"]
|
|
72
72
|
*/
|
|
73
73
|
export declare const getNormalizedActiveGroupIds: () => string[];
|
|
74
|
+
/**
|
|
75
|
+
* Check if OnetrustActiveGroups is populated with actual consent categories.
|
|
76
|
+
*
|
|
77
|
+
* OneTrust sets window.OnetrustActiveGroups after the API object is available,
|
|
78
|
+
* so this guards against a race condition where the API exists but consent
|
|
79
|
+
* categories have not yet been populated.
|
|
80
|
+
*
|
|
81
|
+
* @returns true if OnetrustActiveGroups is a non-empty string with at least one group ID
|
|
82
|
+
*/
|
|
83
|
+
export declare const hasActiveGroups: () => boolean;
|
|
74
84
|
/**
|
|
75
85
|
* Get all configured consent groups from OneTrust.
|
|
76
86
|
*
|
|
@@ -64,6 +64,18 @@ export const getNormalizedActiveGroupIds = () => {
|
|
|
64
64
|
return [];
|
|
65
65
|
return groups.trim().split(',').filter(Boolean);
|
|
66
66
|
};
|
|
67
|
+
/**
|
|
68
|
+
* Check if OnetrustActiveGroups is populated with actual consent categories.
|
|
69
|
+
*
|
|
70
|
+
* OneTrust sets window.OnetrustActiveGroups after the API object is available,
|
|
71
|
+
* so this guards against a race condition where the API exists but consent
|
|
72
|
+
* categories have not yet been populated.
|
|
73
|
+
*
|
|
74
|
+
* @returns true if OnetrustActiveGroups is a non-empty string with at least one group ID
|
|
75
|
+
*/
|
|
76
|
+
export const hasActiveGroups = () => {
|
|
77
|
+
return getNormalizedActiveGroupIds().length > 0;
|
|
78
|
+
};
|
|
67
79
|
/**
|
|
68
80
|
* Get all configured consent groups from OneTrust.
|
|
69
81
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getOneTrustGlobal, getNormalizedCategories, coerceConsentModel, } from './onetrust-api.js';
|
|
1
|
+
import { getOneTrustGlobal, getNormalizedCategories, coerceConsentModel, hasActiveGroups, } from './onetrust-api.js';
|
|
2
2
|
/**
|
|
3
3
|
* Returns whether the user can currently be tracked.
|
|
4
4
|
* Uses duck typing to check if OneTrust is fully loaded.
|
|
@@ -60,7 +60,7 @@ export const onetrustConsentAdapter = (options) => {
|
|
|
60
60
|
},
|
|
61
61
|
userCanBeTracked,
|
|
62
62
|
getCategories: () => getNormalizedCategories(),
|
|
63
|
-
isConsentReady: () => !!getOneTrustGlobal(),
|
|
63
|
+
isConsentReady: () => !!getOneTrustGlobal() && hasActiveGroups(),
|
|
64
64
|
getConsentModel: () => {
|
|
65
65
|
const api = getOneTrustGlobal();
|
|
66
66
|
if (!api)
|
|
@@ -39,13 +39,17 @@ export declare const getShopifyCart: (baseUrl?: string, localePath?: string) =>
|
|
|
39
39
|
*/
|
|
40
40
|
export declare const updateShopifyCartAttributes: (attributes: Record<string, string>, baseUrl?: string, localePath?: string) => Promise<ShopifyCart>;
|
|
41
41
|
/**
|
|
42
|
-
* Sync identifiers to Shopify cart attributes.
|
|
42
|
+
* Sync CDP and analytics identifiers to Shopify cart attributes.
|
|
43
43
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
44
|
+
* By default, syncs the Chord CDP anonymous ID (`__eventn_id` cookie) and
|
|
45
|
+
* Google Analytics client ID (`_ga` cookie) to the cart. These attributes
|
|
46
|
+
* are included in Shopify order webhooks, enabling server-side events to
|
|
47
|
+
* correlate with client-side tracking sessions.
|
|
48
48
|
*
|
|
49
|
-
*
|
|
49
|
+
* Smart deduplication: only updates the cart if identifiers are missing or
|
|
50
|
+
* have changed, avoiding unnecessary API calls on repeat page loads.
|
|
51
|
+
*
|
|
52
|
+
* @param options - Optional configuration for base URL, locale path, or custom identifier getter
|
|
53
|
+
* @returns The updated cart, or undefined if no update was needed or an error occurred
|
|
50
54
|
*/
|
|
51
55
|
export declare const syncIdentifiersToCart: (options?: IdentifierSyncOptions) => Promise<ShopifyCart | undefined>;
|
|
@@ -100,14 +100,18 @@ export const updateShopifyCartAttributes = (attributes, baseUrl, localePath) =>
|
|
|
100
100
|
return response.json();
|
|
101
101
|
});
|
|
102
102
|
/**
|
|
103
|
-
* Sync identifiers to Shopify cart attributes.
|
|
103
|
+
* Sync CDP and analytics identifiers to Shopify cart attributes.
|
|
104
104
|
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
105
|
+
* By default, syncs the Chord CDP anonymous ID (`__eventn_id` cookie) and
|
|
106
|
+
* Google Analytics client ID (`_ga` cookie) to the cart. These attributes
|
|
107
|
+
* are included in Shopify order webhooks, enabling server-side events to
|
|
108
|
+
* correlate with client-side tracking sessions.
|
|
109
109
|
*
|
|
110
|
-
*
|
|
110
|
+
* Smart deduplication: only updates the cart if identifiers are missing or
|
|
111
|
+
* have changed, avoiding unnecessary API calls on repeat page loads.
|
|
112
|
+
*
|
|
113
|
+
* @param options - Optional configuration for base URL, locale path, or custom identifier getter
|
|
114
|
+
* @returns The updated cart, or undefined if no update was needed or an error occurred
|
|
111
115
|
*/
|
|
112
116
|
export const syncIdentifiersToCart = (options = {}) => __awaiter(void 0, void 0, void 0, function* () {
|
|
113
117
|
try {
|
package/dist/client/index.d.ts
CHANGED
|
@@ -159,10 +159,10 @@ export declare class ChordAnalytics<T extends ObjectTypes = ObjectTypes> {
|
|
|
159
159
|
private webPixelMessageHandler;
|
|
160
160
|
/**
|
|
161
161
|
* Set up a listener for postMessage events from the Shopify Web Pixel sandbox.
|
|
162
|
-
* This allows the
|
|
162
|
+
* This allows the web pixel (running in Shopify's sandboxed iframe)
|
|
163
163
|
* to forward analytics events to this ChordAnalytics instance on the storefront.
|
|
164
164
|
*
|
|
165
|
-
* The
|
|
165
|
+
* The web pixel sends messages in the format:
|
|
166
166
|
* - { source: 'chord-web-pixel', type: 'track', payload: [eventName, properties] }
|
|
167
167
|
* - { source: 'chord-web-pixel', type: 'identify', payload: [userId, traits] }
|
|
168
168
|
* - { source: 'chord-web-pixel', type: 'page', payload: [properties] }
|
package/dist/client/index.js
CHANGED
|
@@ -19,7 +19,7 @@ const CONSENT_QUEUE_MAX_SIZE_BYTES = 100 * 1024; // 100KB max queue size
|
|
|
19
19
|
const CONSENT_QUEUE_MAX_EVENTS = 50; // Max number of events to queue
|
|
20
20
|
export class ChordAnalytics {
|
|
21
21
|
constructor(options) {
|
|
22
|
-
var _a, _b, _c, _d, _e;
|
|
22
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
23
23
|
/**
|
|
24
24
|
* Allows snippet.js to detect whether this library has been initialized yet.
|
|
25
25
|
*/
|
|
@@ -586,7 +586,7 @@ export class ChordAnalytics {
|
|
|
586
586
|
});
|
|
587
587
|
});
|
|
588
588
|
this.reset = () => __awaiter(this, void 0, void 0, function* () {
|
|
589
|
-
var
|
|
589
|
+
var _k;
|
|
590
590
|
try {
|
|
591
591
|
this.resetInProgress = true;
|
|
592
592
|
const a = this.ccdp();
|
|
@@ -603,12 +603,12 @@ export class ChordAnalytics {
|
|
|
603
603
|
// eslint-disable-next-line
|
|
604
604
|
yield new Promise((resolve) => setTimeout(resolve, 10));
|
|
605
605
|
try {
|
|
606
|
-
const userState = ((
|
|
606
|
+
const userState = ((_k = a === null || a === void 0 ? void 0 : a.user) === null || _k === void 0 ? void 0 : _k.call(a)) || {};
|
|
607
607
|
if (userState.userId === null || userState.userId === undefined) {
|
|
608
608
|
break;
|
|
609
609
|
}
|
|
610
610
|
}
|
|
611
|
-
catch (
|
|
611
|
+
catch (_l) {
|
|
612
612
|
break;
|
|
613
613
|
}
|
|
614
614
|
attempts++;
|
|
@@ -628,10 +628,10 @@ export class ChordAnalytics {
|
|
|
628
628
|
this.webPixelMessageHandler = null;
|
|
629
629
|
/**
|
|
630
630
|
* Set up a listener for postMessage events from the Shopify Web Pixel sandbox.
|
|
631
|
-
* This allows the
|
|
631
|
+
* This allows the web pixel (running in Shopify's sandboxed iframe)
|
|
632
632
|
* to forward analytics events to this ChordAnalytics instance on the storefront.
|
|
633
633
|
*
|
|
634
|
-
* The
|
|
634
|
+
* The web pixel sends messages in the format:
|
|
635
635
|
* - { source: 'chord-web-pixel', type: 'track', payload: [eventName, properties] }
|
|
636
636
|
* - { source: 'chord-web-pixel', type: 'identify', payload: [userId, traits] }
|
|
637
637
|
* - { source: 'chord-web-pixel', type: 'page', payload: [properties] }
|
|
@@ -717,8 +717,8 @@ export class ChordAnalytics {
|
|
|
717
717
|
});
|
|
718
718
|
// TODO: Add support for props.products
|
|
719
719
|
this.trackCartViewed = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
720
|
-
var
|
|
721
|
-
const cart = (
|
|
720
|
+
var _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
721
|
+
const cart = (_q = (_p = (_o = (_m = this.options) === null || _m === void 0 ? void 0 : _m.formatters) === null || _o === void 0 ? void 0 : _o.objects) === null || _p === void 0 ? void 0 : _p.cart) === null || _q === void 0 ? void 0 : _q.call(_p, {
|
|
722
722
|
cart: props === null || props === void 0 ? void 0 : props.cart,
|
|
723
723
|
});
|
|
724
724
|
const payload = {
|
|
@@ -727,17 +727,17 @@ export class ChordAnalytics {
|
|
|
727
727
|
products: cart === null || cart === void 0 ? void 0 : cart.products,
|
|
728
728
|
value: cart === null || cart === void 0 ? void 0 : cart.value,
|
|
729
729
|
};
|
|
730
|
-
if ((
|
|
731
|
-
const formattedPayload = (
|
|
730
|
+
if ((_t = (_s = (_r = this.options) === null || _r === void 0 ? void 0 : _r.formatters) === null || _s === void 0 ? void 0 : _s.events) === null || _t === void 0 ? void 0 : _t.cartViewed) {
|
|
731
|
+
const formattedPayload = (_w = (_v = (_u = this.options) === null || _u === void 0 ? void 0 : _u.formatters) === null || _v === void 0 ? void 0 : _v.events) === null || _w === void 0 ? void 0 : _w.cartViewed(props, payload);
|
|
732
732
|
return this.track('Cart Viewed', formattedPayload, options);
|
|
733
733
|
}
|
|
734
734
|
return this.track('Cart Viewed', payload, options);
|
|
735
735
|
});
|
|
736
736
|
// TODO: Add support for props.products
|
|
737
737
|
this.trackCheckoutStarted = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
738
|
-
var
|
|
739
|
-
const formatter = (
|
|
740
|
-
const checkout = (
|
|
738
|
+
var _x, _y, _z, _0, _1, _2, _3;
|
|
739
|
+
const formatter = (_z = (_y = (_x = this.options) === null || _x === void 0 ? void 0 : _x.formatters) === null || _y === void 0 ? void 0 : _y.events) === null || _z === void 0 ? void 0 : _z.checkoutStarted;
|
|
740
|
+
const checkout = (_3 = (_2 = (_1 = (_0 = this.options) === null || _0 === void 0 ? void 0 : _0.formatters) === null || _1 === void 0 ? void 0 : _1.objects) === null || _2 === void 0 ? void 0 : _2.checkout) === null || _3 === void 0 ? void 0 : _3.call(_2, {
|
|
741
741
|
checkout: props === null || props === void 0 ? void 0 : props.checkout,
|
|
742
742
|
});
|
|
743
743
|
const payload = checkout;
|
|
@@ -748,8 +748,8 @@ export class ChordAnalytics {
|
|
|
748
748
|
return this.track('Checkout Started', payload, options);
|
|
749
749
|
});
|
|
750
750
|
this.trackCheckoutStepCompleted = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
751
|
-
var
|
|
752
|
-
const formatter = (
|
|
751
|
+
var _4, _5, _6;
|
|
752
|
+
const formatter = (_6 = (_5 = (_4 = this.options) === null || _4 === void 0 ? void 0 : _4.formatters) === null || _5 === void 0 ? void 0 : _5.events) === null || _6 === void 0 ? void 0 : _6.checkoutStepCompleted;
|
|
753
753
|
const payload = {
|
|
754
754
|
checkout_id: props === null || props === void 0 ? void 0 : props.checkoutId,
|
|
755
755
|
payment_method: props === null || props === void 0 ? void 0 : props.paymentMethod,
|
|
@@ -763,8 +763,8 @@ export class ChordAnalytics {
|
|
|
763
763
|
return this.track('Checkout Step Completed', payload, options);
|
|
764
764
|
});
|
|
765
765
|
this.trackCheckoutStepViewed = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
766
|
-
var
|
|
767
|
-
const formatter = (
|
|
766
|
+
var _7, _8, _9;
|
|
767
|
+
const formatter = (_9 = (_8 = (_7 = this.options) === null || _7 === void 0 ? void 0 : _7.formatters) === null || _8 === void 0 ? void 0 : _8.events) === null || _9 === void 0 ? void 0 : _9.checkoutStepViewed;
|
|
768
768
|
const payload = {
|
|
769
769
|
checkout_id: props === null || props === void 0 ? void 0 : props.checkoutId,
|
|
770
770
|
payment_method: props === null || props === void 0 ? void 0 : props.paymentMethod,
|
|
@@ -778,8 +778,8 @@ export class ChordAnalytics {
|
|
|
778
778
|
return this.track('Checkout Step Viewed', payload, options);
|
|
779
779
|
});
|
|
780
780
|
this.trackCouponApplied = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
781
|
-
var
|
|
782
|
-
const formatter = (
|
|
781
|
+
var _10, _11, _12;
|
|
782
|
+
const formatter = (_12 = (_11 = (_10 = this.options) === null || _10 === void 0 ? void 0 : _10.formatters) === null || _11 === void 0 ? void 0 : _11.events) === null || _12 === void 0 ? void 0 : _12.couponApplied;
|
|
783
783
|
const payload = {
|
|
784
784
|
cart_id: props === null || props === void 0 ? void 0 : props.cartId,
|
|
785
785
|
coupon_id: props === null || props === void 0 ? void 0 : props.couponId,
|
|
@@ -794,8 +794,8 @@ export class ChordAnalytics {
|
|
|
794
794
|
return this.track('Coupon Applied', payload, options);
|
|
795
795
|
});
|
|
796
796
|
this.trackCouponDenied = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
797
|
-
var
|
|
798
|
-
const formatter = (
|
|
797
|
+
var _13, _14, _15;
|
|
798
|
+
const formatter = (_15 = (_14 = (_13 = this.options) === null || _13 === void 0 ? void 0 : _13.formatters) === null || _14 === void 0 ? void 0 : _14.events) === null || _15 === void 0 ? void 0 : _15.couponDenied;
|
|
799
799
|
const payload = {
|
|
800
800
|
cart_id: props === null || props === void 0 ? void 0 : props.cartId,
|
|
801
801
|
coupon_id: props === null || props === void 0 ? void 0 : props.couponId,
|
|
@@ -810,8 +810,8 @@ export class ChordAnalytics {
|
|
|
810
810
|
return this.track('Coupon Denied', payload, options);
|
|
811
811
|
});
|
|
812
812
|
this.trackCouponEntered = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
813
|
-
var
|
|
814
|
-
const formatter = (
|
|
813
|
+
var _16, _17, _18;
|
|
814
|
+
const formatter = (_18 = (_17 = (_16 = this.options) === null || _16 === void 0 ? void 0 : _16.formatters) === null || _17 === void 0 ? void 0 : _17.events) === null || _18 === void 0 ? void 0 : _18.couponEntered;
|
|
815
815
|
const payload = {
|
|
816
816
|
cart_id: props === null || props === void 0 ? void 0 : props.cartId,
|
|
817
817
|
coupon_id: props === null || props === void 0 ? void 0 : props.couponId,
|
|
@@ -825,8 +825,8 @@ export class ChordAnalytics {
|
|
|
825
825
|
return this.track('Coupon Entered', payload, options);
|
|
826
826
|
});
|
|
827
827
|
this.trackCouponRemoved = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
828
|
-
var
|
|
829
|
-
const formatter = (
|
|
828
|
+
var _19, _20, _21;
|
|
829
|
+
const formatter = (_21 = (_20 = (_19 = this.options) === null || _19 === void 0 ? void 0 : _19.formatters) === null || _20 === void 0 ? void 0 : _20.events) === null || _21 === void 0 ? void 0 : _21.couponRemoved;
|
|
830
830
|
const payload = {
|
|
831
831
|
cart_id: props === null || props === void 0 ? void 0 : props.cartId,
|
|
832
832
|
coupon_id: props === null || props === void 0 ? void 0 : props.couponId,
|
|
@@ -841,8 +841,8 @@ export class ChordAnalytics {
|
|
|
841
841
|
return this.track('Coupon Removed', payload, options);
|
|
842
842
|
});
|
|
843
843
|
this.trackEmailCaptured = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
844
|
-
var
|
|
845
|
-
const formatter = (
|
|
844
|
+
var _22, _23, _24;
|
|
845
|
+
const formatter = (_24 = (_23 = (_22 = this.options) === null || _22 === void 0 ? void 0 : _22.formatters) === null || _23 === void 0 ? void 0 : _23.events) === null || _24 === void 0 ? void 0 : _24.emailCaptured;
|
|
846
846
|
const payload = {
|
|
847
847
|
email: props === null || props === void 0 ? void 0 : props.email,
|
|
848
848
|
placement_component: props === null || props === void 0 ? void 0 : props.placementComponent,
|
|
@@ -855,13 +855,13 @@ export class ChordAnalytics {
|
|
|
855
855
|
return this.track('Email Captured', payload, options);
|
|
856
856
|
});
|
|
857
857
|
this.trackProductAdded = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
858
|
-
var
|
|
859
|
-
const formatter = (
|
|
860
|
-
const product = (
|
|
861
|
-
const cart = (
|
|
858
|
+
var _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36;
|
|
859
|
+
const formatter = (_27 = (_26 = (_25 = this.options) === null || _25 === void 0 ? void 0 : _25.formatters) === null || _26 === void 0 ? void 0 : _26.events) === null || _27 === void 0 ? void 0 : _27.productAdded;
|
|
860
|
+
const product = (_31 = (_30 = (_29 = (_28 = this.options) === null || _28 === void 0 ? void 0 : _28.formatters) === null || _29 === void 0 ? void 0 : _29.objects) === null || _30 === void 0 ? void 0 : _30.product) === null || _31 === void 0 ? void 0 : _31.call(_30, props === null || props === void 0 ? void 0 : props.product);
|
|
861
|
+
const cart = (_35 = (_34 = (_33 = (_32 = this.options) === null || _32 === void 0 ? void 0 : _32.formatters) === null || _33 === void 0 ? void 0 : _33.objects) === null || _34 === void 0 ? void 0 : _34.cart) === null || _35 === void 0 ? void 0 : _35.call(_34, {
|
|
862
862
|
cart: props === null || props === void 0 ? void 0 : props.cart,
|
|
863
863
|
});
|
|
864
|
-
const quantity = ((
|
|
864
|
+
const quantity = ((_36 = props === null || props === void 0 ? void 0 : props.product) === null || _36 === void 0 ? void 0 : _36.quantity) || 1;
|
|
865
865
|
const payload = Object.assign(Object.assign({}, product), { cart_id: cart.cart_id, currency: cart.currency, products: [Object.assign(Object.assign({}, product), { quantity })], total: product.price * (quantity || 1), value: product.price * (quantity || 1) });
|
|
866
866
|
if (typeof formatter === 'function') {
|
|
867
867
|
const formattedPayload = formatter(props, payload);
|
|
@@ -870,14 +870,14 @@ export class ChordAnalytics {
|
|
|
870
870
|
return this.track('Product Added', payload, options);
|
|
871
871
|
});
|
|
872
872
|
this.trackProductClicked = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
873
|
-
var
|
|
874
|
-
const formatter = (
|
|
875
|
-
const product = (
|
|
876
|
-
const cart = (
|
|
873
|
+
var _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49;
|
|
874
|
+
const formatter = (_39 = (_38 = (_37 = this.options) === null || _37 === void 0 ? void 0 : _37.formatters) === null || _38 === void 0 ? void 0 : _38.events) === null || _39 === void 0 ? void 0 : _39.productClicked;
|
|
875
|
+
const product = (_43 = (_42 = (_41 = (_40 = this.options) === null || _40 === void 0 ? void 0 : _40.formatters) === null || _41 === void 0 ? void 0 : _41.objects) === null || _42 === void 0 ? void 0 : _42.product) === null || _43 === void 0 ? void 0 : _43.call(_42, props === null || props === void 0 ? void 0 : props.product);
|
|
876
|
+
const cart = (_47 = (_46 = (_45 = (_44 = this.options) === null || _44 === void 0 ? void 0 : _44.formatters) === null || _45 === void 0 ? void 0 : _45.objects) === null || _46 === void 0 ? void 0 : _46.cart) === null || _47 === void 0 ? void 0 : _47.call(_46, {
|
|
877
877
|
cart: props === null || props === void 0 ? void 0 : props.cart,
|
|
878
878
|
});
|
|
879
|
-
const quantity = ((
|
|
880
|
-
const payload = Object.assign(Object.assign({}, product), { cart_id: cart.cart_id, currency: cart.currency, item_list_id: (
|
|
879
|
+
const quantity = ((_48 = props === null || props === void 0 ? void 0 : props.product) === null || _48 === void 0 ? void 0 : _48.quantity) || 1;
|
|
880
|
+
const payload = Object.assign(Object.assign({}, product), { cart_id: cart.cart_id, currency: cart.currency, item_list_id: (_49 = props === null || props === void 0 ? void 0 : props.listId) === null || _49 === void 0 ? void 0 : _49.toString(), item_list_name: props === null || props === void 0 ? void 0 : props.listName, products: [Object.assign(Object.assign({}, product), { quantity })] });
|
|
881
881
|
if (typeof formatter === 'function') {
|
|
882
882
|
const formattedPayload = formatter(props, payload);
|
|
883
883
|
return this.track('Product Clicked', formattedPayload, options);
|
|
@@ -885,13 +885,13 @@ export class ChordAnalytics {
|
|
|
885
885
|
return this.track('Product Clicked', payload, options);
|
|
886
886
|
});
|
|
887
887
|
this.trackVariantClicked = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
888
|
-
var
|
|
889
|
-
const formatter = (
|
|
890
|
-
const product = (
|
|
891
|
-
const cart = (
|
|
888
|
+
var _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61;
|
|
889
|
+
const formatter = (_52 = (_51 = (_50 = this.options) === null || _50 === void 0 ? void 0 : _50.formatters) === null || _51 === void 0 ? void 0 : _51.events) === null || _52 === void 0 ? void 0 : _52.variantClicked;
|
|
890
|
+
const product = (_56 = (_55 = (_54 = (_53 = this.options) === null || _53 === void 0 ? void 0 : _53.formatters) === null || _54 === void 0 ? void 0 : _54.objects) === null || _55 === void 0 ? void 0 : _55.product) === null || _56 === void 0 ? void 0 : _56.call(_55, props === null || props === void 0 ? void 0 : props.product);
|
|
891
|
+
const cart = (_60 = (_59 = (_58 = (_57 = this.options) === null || _57 === void 0 ? void 0 : _57.formatters) === null || _58 === void 0 ? void 0 : _58.objects) === null || _59 === void 0 ? void 0 : _59.cart) === null || _60 === void 0 ? void 0 : _60.call(_59, {
|
|
892
892
|
cart: props === null || props === void 0 ? void 0 : props.cart,
|
|
893
893
|
});
|
|
894
|
-
const quantity = ((
|
|
894
|
+
const quantity = ((_61 = props === null || props === void 0 ? void 0 : props.product) === null || _61 === void 0 ? void 0 : _61.quantity) || 1;
|
|
895
895
|
const payload = Object.assign(Object.assign({}, product), { cart_id: cart.cart_id, currency: cart.currency, quantity: quantity, line_item_id: props === null || props === void 0 ? void 0 : props.lineItemId, coupon: props === null || props === void 0 ? void 0 : props.coupon });
|
|
896
896
|
if (typeof formatter === 'function') {
|
|
897
897
|
const formattedPayload = formatter(props, payload);
|
|
@@ -900,13 +900,13 @@ export class ChordAnalytics {
|
|
|
900
900
|
return this.track('Variant Clicked', payload, options);
|
|
901
901
|
});
|
|
902
902
|
this.trackProductListFiltered = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
903
|
-
var
|
|
904
|
-
const formatter = (
|
|
903
|
+
var _62, _63, _64, _65, _66;
|
|
904
|
+
const formatter = (_64 = (_63 = (_62 = this.options) === null || _62 === void 0 ? void 0 : _62.formatters) === null || _63 === void 0 ? void 0 : _63.events) === null || _64 === void 0 ? void 0 : _64.productListFiltered;
|
|
905
905
|
const payload = {
|
|
906
906
|
category: props === null || props === void 0 ? void 0 : props.category,
|
|
907
907
|
filters: props === null || props === void 0 ? void 0 : props.filters,
|
|
908
|
-
list_id: (
|
|
909
|
-
item_list_id: (
|
|
908
|
+
list_id: (_65 = props === null || props === void 0 ? void 0 : props.listId) === null || _65 === void 0 ? void 0 : _65.toString(),
|
|
909
|
+
item_list_id: (_66 = props === null || props === void 0 ? void 0 : props.listId) === null || _66 === void 0 ? void 0 : _66.toString(),
|
|
910
910
|
item_list_name: props === null || props === void 0 ? void 0 : props.listName,
|
|
911
911
|
sorts: props === null || props === void 0 ? void 0 : props.sorts,
|
|
912
912
|
};
|
|
@@ -917,14 +917,14 @@ export class ChordAnalytics {
|
|
|
917
917
|
return this.track('Product List Filtered', payload, options);
|
|
918
918
|
});
|
|
919
919
|
this.trackProductListViewed = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
920
|
-
var
|
|
921
|
-
const formatter = (
|
|
920
|
+
var _67, _68, _69, _70, _71, _72;
|
|
921
|
+
const formatter = (_69 = (_68 = (_67 = this.options) === null || _67 === void 0 ? void 0 : _67.formatters) === null || _68 === void 0 ? void 0 : _68.events) === null || _69 === void 0 ? void 0 : _69.productListViewed;
|
|
922
922
|
const payload = {
|
|
923
923
|
category: props === null || props === void 0 ? void 0 : props.category,
|
|
924
|
-
list_id: (
|
|
925
|
-
item_list_id: (
|
|
924
|
+
list_id: (_70 = props === null || props === void 0 ? void 0 : props.listId) === null || _70 === void 0 ? void 0 : _70.toString(),
|
|
925
|
+
item_list_id: (_71 = props === null || props === void 0 ? void 0 : props.listId) === null || _71 === void 0 ? void 0 : _71.toString(),
|
|
926
926
|
item_list_name: props === null || props === void 0 ? void 0 : props.listName,
|
|
927
|
-
products: (
|
|
927
|
+
products: (_72 = props === null || props === void 0 ? void 0 : props.products) === null || _72 === void 0 ? void 0 : _72.map((p, i) => {
|
|
928
928
|
var _a, _b, _c, _d;
|
|
929
929
|
return (_d = (_c = (_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.formatters) === null || _b === void 0 ? void 0 : _b.objects) === null || _c === void 0 ? void 0 : _c.product) === null || _d === void 0 ? void 0 : _d.call(_c, Object.assign(Object.assign({}, p), { position: i + 1 }));
|
|
930
930
|
}),
|
|
@@ -937,8 +937,8 @@ export class ChordAnalytics {
|
|
|
937
937
|
return this.track('Product List Viewed', payload, options);
|
|
938
938
|
});
|
|
939
939
|
this.trackProductRemoved = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
940
|
-
var
|
|
941
|
-
const formatter = (
|
|
940
|
+
var _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87;
|
|
941
|
+
const formatter = (_75 = (_74 = (_73 = this.options) === null || _73 === void 0 ? void 0 : _73.formatters) === null || _74 === void 0 ? void 0 : _74.events) === null || _75 === void 0 ? void 0 : _75.productRemoved;
|
|
942
942
|
/*
|
|
943
943
|
const product = this.options?.formatters?.objects?.product?.({
|
|
944
944
|
position: props?.position,
|
|
@@ -947,13 +947,13 @@ export class ChordAnalytics {
|
|
|
947
947
|
variantId: props?.variantId,
|
|
948
948
|
})
|
|
949
949
|
*/
|
|
950
|
-
const lineItem = (
|
|
950
|
+
const lineItem = (_79 = (_78 = (_77 = (_76 = this.options) === null || _76 === void 0 ? void 0 : _76.formatters) === null || _77 === void 0 ? void 0 : _77.objects) === null || _78 === void 0 ? void 0 : _78.lineItem) === null || _79 === void 0 ? void 0 : _79.call(_78, {
|
|
951
951
|
lineItem: props === null || props === void 0 ? void 0 : props.lineItem,
|
|
952
952
|
});
|
|
953
|
-
const cart = (
|
|
953
|
+
const cart = (_83 = (_82 = (_81 = (_80 = this.options) === null || _80 === void 0 ? void 0 : _80.formatters) === null || _81 === void 0 ? void 0 : _81.objects) === null || _82 === void 0 ? void 0 : _82.cart) === null || _83 === void 0 ? void 0 : _83.call(_82, {
|
|
954
954
|
cart: props === null || props === void 0 ? void 0 : props.cart,
|
|
955
955
|
});
|
|
956
|
-
const payload = Object.assign(Object.assign({}, lineItem), { cart_id: cart.cart_id, currency: cart.currency, products: [lineItem], total: ((
|
|
956
|
+
const payload = Object.assign(Object.assign({}, lineItem), { cart_id: cart.cart_id, currency: cart.currency, products: [lineItem], total: ((_84 = lineItem === null || lineItem === void 0 ? void 0 : lineItem.price) !== null && _84 !== void 0 ? _84 : 0) * ((_85 = lineItem === null || lineItem === void 0 ? void 0 : lineItem.quantity) !== null && _85 !== void 0 ? _85 : 1), value: ((_86 = lineItem === null || lineItem === void 0 ? void 0 : lineItem.price) !== null && _86 !== void 0 ? _86 : 0) * ((_87 = lineItem === null || lineItem === void 0 ? void 0 : lineItem.quantity) !== null && _87 !== void 0 ? _87 : 1) });
|
|
957
957
|
if (typeof formatter === 'function') {
|
|
958
958
|
const formattedPayload = formatter(props, payload);
|
|
959
959
|
return this.track('Product Removed', formattedPayload, options);
|
|
@@ -961,14 +961,14 @@ export class ChordAnalytics {
|
|
|
961
961
|
return this.track('Product Removed', payload, options);
|
|
962
962
|
});
|
|
963
963
|
this.trackProductViewed = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
964
|
-
var
|
|
965
|
-
const formatter = (
|
|
966
|
-
const product = (
|
|
967
|
-
const cart = (
|
|
964
|
+
var _88, _89, _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _100;
|
|
965
|
+
const formatter = (_90 = (_89 = (_88 = this.options) === null || _88 === void 0 ? void 0 : _88.formatters) === null || _89 === void 0 ? void 0 : _89.events) === null || _90 === void 0 ? void 0 : _90.productViewed;
|
|
966
|
+
const product = (_94 = (_93 = (_92 = (_91 = this.options) === null || _91 === void 0 ? void 0 : _91.formatters) === null || _92 === void 0 ? void 0 : _92.objects) === null || _93 === void 0 ? void 0 : _93.product) === null || _94 === void 0 ? void 0 : _94.call(_93, props === null || props === void 0 ? void 0 : props.product);
|
|
967
|
+
const cart = (_98 = (_97 = (_96 = (_95 = this.options) === null || _95 === void 0 ? void 0 : _95.formatters) === null || _96 === void 0 ? void 0 : _96.objects) === null || _97 === void 0 ? void 0 : _97.cart) === null || _98 === void 0 ? void 0 : _98.call(_97, {
|
|
968
968
|
cart: props === null || props === void 0 ? void 0 : props.cart,
|
|
969
969
|
});
|
|
970
|
-
const quantity = ((
|
|
971
|
-
const payload = Object.assign(Object.assign({}, product), { cart_id: cart.cart_id, currency: cart.currency, products: [Object.assign(Object.assign({}, product), { quantity })], value: product.price * (((
|
|
970
|
+
const quantity = ((_99 = props === null || props === void 0 ? void 0 : props.product) === null || _99 === void 0 ? void 0 : _99.quantity) || 1;
|
|
971
|
+
const payload = Object.assign(Object.assign({}, product), { cart_id: cart.cart_id, currency: cart.currency, products: [Object.assign(Object.assign({}, product), { quantity })], value: product.price * (((_100 = props === null || props === void 0 ? void 0 : props.product) === null || _100 === void 0 ? void 0 : _100.quantity) || 1) });
|
|
972
972
|
if (typeof formatter === 'function') {
|
|
973
973
|
const formattedPayload = formatter(props, payload);
|
|
974
974
|
return this.track('Product Viewed', formattedPayload, options);
|
|
@@ -976,12 +976,12 @@ export class ChordAnalytics {
|
|
|
976
976
|
return this.track('Product Viewed', payload, options);
|
|
977
977
|
});
|
|
978
978
|
this.trackProductsSearched = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
979
|
-
var
|
|
980
|
-
const formatter = (
|
|
979
|
+
var _101, _102, _103, _104;
|
|
980
|
+
const formatter = (_103 = (_102 = (_101 = this.options) === null || _101 === void 0 ? void 0 : _101.formatters) === null || _102 === void 0 ? void 0 : _102.events) === null || _103 === void 0 ? void 0 : _103.productsSearched;
|
|
981
981
|
const payload = {
|
|
982
982
|
currency: props === null || props === void 0 ? void 0 : props.currency,
|
|
983
983
|
price: typeof (props === null || props === void 0 ? void 0 : props.price) !== 'undefined' ? Number(props === null || props === void 0 ? void 0 : props.price) : undefined,
|
|
984
|
-
product_id: (
|
|
984
|
+
product_id: (_104 = props === null || props === void 0 ? void 0 : props.productId) === null || _104 === void 0 ? void 0 : _104.toString(),
|
|
985
985
|
quantity: props === null || props === void 0 ? void 0 : props.quantity,
|
|
986
986
|
query: props === null || props === void 0 ? void 0 : props.query,
|
|
987
987
|
};
|
|
@@ -992,8 +992,8 @@ export class ChordAnalytics {
|
|
|
992
992
|
return this.track('Products Searched', payload, options);
|
|
993
993
|
});
|
|
994
994
|
this.trackSignedIn = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
995
|
-
var
|
|
996
|
-
const formatter = (
|
|
995
|
+
var _105, _106, _107;
|
|
996
|
+
const formatter = (_107 = (_106 = (_105 = this.options) === null || _105 === void 0 ? void 0 : _105.formatters) === null || _106 === void 0 ? void 0 : _106.events) === null || _107 === void 0 ? void 0 : _107.signedIn;
|
|
997
997
|
const payload = {
|
|
998
998
|
email: props === null || props === void 0 ? void 0 : props.email,
|
|
999
999
|
method: props === null || props === void 0 ? void 0 : props.method,
|
|
@@ -1005,8 +1005,8 @@ export class ChordAnalytics {
|
|
|
1005
1005
|
return this.track('Signed In', payload, options);
|
|
1006
1006
|
});
|
|
1007
1007
|
this.trackSignedOut = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
1008
|
-
var
|
|
1009
|
-
const formatter = (
|
|
1008
|
+
var _108, _109, _110;
|
|
1009
|
+
const formatter = (_110 = (_109 = (_108 = this.options) === null || _108 === void 0 ? void 0 : _108.formatters) === null || _109 === void 0 ? void 0 : _109.events) === null || _110 === void 0 ? void 0 : _110.signedOut;
|
|
1010
1010
|
const payload = {
|
|
1011
1011
|
email: props === null || props === void 0 ? void 0 : props.email,
|
|
1012
1012
|
};
|
|
@@ -1017,8 +1017,8 @@ export class ChordAnalytics {
|
|
|
1017
1017
|
return this.track('Signed Out', payload, options);
|
|
1018
1018
|
});
|
|
1019
1019
|
this.trackSignedUp = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
1020
|
-
var
|
|
1021
|
-
const formatter = (
|
|
1020
|
+
var _111, _112, _113;
|
|
1021
|
+
const formatter = (_113 = (_112 = (_111 = this.options) === null || _111 === void 0 ? void 0 : _111.formatters) === null || _112 === void 0 ? void 0 : _112.events) === null || _113 === void 0 ? void 0 : _113.signedUp;
|
|
1022
1022
|
const payload = {
|
|
1023
1023
|
email: props === null || props === void 0 ? void 0 : props.email,
|
|
1024
1024
|
method: props === null || props === void 0 ? void 0 : props.method,
|
|
@@ -1030,8 +1030,8 @@ export class ChordAnalytics {
|
|
|
1030
1030
|
return this.track('Signed Up', payload, options);
|
|
1031
1031
|
});
|
|
1032
1032
|
this.trackLoginStarted = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
1033
|
-
var
|
|
1034
|
-
const formatter = (
|
|
1033
|
+
var _114, _115, _116;
|
|
1034
|
+
const formatter = (_116 = (_115 = (_114 = this.options) === null || _114 === void 0 ? void 0 : _114.formatters) === null || _115 === void 0 ? void 0 : _115.events) === null || _116 === void 0 ? void 0 : _116.loginStarted;
|
|
1035
1035
|
const payload = {
|
|
1036
1036
|
email: props === null || props === void 0 ? void 0 : props.email,
|
|
1037
1037
|
};
|
|
@@ -1042,8 +1042,8 @@ export class ChordAnalytics {
|
|
|
1042
1042
|
return this.track('Login Started', payload, options);
|
|
1043
1043
|
});
|
|
1044
1044
|
this.trackSubscriptionCancelled = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
1045
|
-
var
|
|
1046
|
-
const formatter = (
|
|
1045
|
+
var _117, _118, _119, _120;
|
|
1046
|
+
const formatter = (_119 = (_118 = (_117 = this.options) === null || _117 === void 0 ? void 0 : _117.formatters) === null || _118 === void 0 ? void 0 : _118.events) === null || _119 === void 0 ? void 0 : _119.subscriptionCancelled;
|
|
1047
1047
|
const payload = {
|
|
1048
1048
|
actionable_date: props === null || props === void 0 ? void 0 : props.actionableDate,
|
|
1049
1049
|
address: props === null || props === void 0 ? void 0 : props.address,
|
|
@@ -1052,7 +1052,7 @@ export class ChordAnalytics {
|
|
|
1052
1052
|
end_date: props === null || props === void 0 ? void 0 : props.endDate,
|
|
1053
1053
|
interval_length: props === null || props === void 0 ? void 0 : props.intervalLength,
|
|
1054
1054
|
interval_units: props === null || props === void 0 ? void 0 : props.intervalUnits,
|
|
1055
|
-
products: (
|
|
1055
|
+
products: (_120 = props === null || props === void 0 ? void 0 : props.products) === null || _120 === void 0 ? void 0 : _120.map((p, i) => {
|
|
1056
1056
|
var _a, _b, _c, _d;
|
|
1057
1057
|
return (_d = (_c = (_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.formatters) === null || _b === void 0 ? void 0 : _b.objects) === null || _c === void 0 ? void 0 : _c.product) === null || _d === void 0 ? void 0 : _d.call(_c, Object.assign(Object.assign({}, p), { position: i + 1 }));
|
|
1058
1058
|
}),
|
|
@@ -1067,8 +1067,8 @@ export class ChordAnalytics {
|
|
|
1067
1067
|
return this.track('Subscription Cancelled', payload, options);
|
|
1068
1068
|
});
|
|
1069
1069
|
this.trackNavigationClicked = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
1070
|
-
var
|
|
1071
|
-
const formatter = (
|
|
1070
|
+
var _121, _122, _123;
|
|
1071
|
+
const formatter = (_123 = (_122 = (_121 = this.options) === null || _121 === void 0 ? void 0 : _121.formatters) === null || _122 === void 0 ? void 0 : _122.events) === null || _123 === void 0 ? void 0 : _123.navigationClicked;
|
|
1072
1072
|
const payload = {
|
|
1073
1073
|
category: props === null || props === void 0 ? void 0 : props.category,
|
|
1074
1074
|
label: props === null || props === void 0 ? void 0 : props.label,
|
|
@@ -1083,15 +1083,15 @@ export class ChordAnalytics {
|
|
|
1083
1083
|
return this.track('Navigation Clicked', payload, options);
|
|
1084
1084
|
});
|
|
1085
1085
|
this.trackPaymentInfoEntered = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
1086
|
-
var
|
|
1087
|
-
const formatter = (
|
|
1086
|
+
var _124, _125, _126, _127;
|
|
1087
|
+
const formatter = (_126 = (_125 = (_124 = this.options) === null || _124 === void 0 ? void 0 : _124.formatters) === null || _125 === void 0 ? void 0 : _125.events) === null || _126 === void 0 ? void 0 : _126.paymentInfoEntered;
|
|
1088
1088
|
const payload = {
|
|
1089
1089
|
checkout_id: props === null || props === void 0 ? void 0 : props.checkoutId,
|
|
1090
1090
|
coupon: props === null || props === void 0 ? void 0 : props.coupon,
|
|
1091
1091
|
currency: props === null || props === void 0 ? void 0 : props.currency,
|
|
1092
1092
|
order_id: props === null || props === void 0 ? void 0 : props.orderId,
|
|
1093
1093
|
payment_method: props === null || props === void 0 ? void 0 : props.paymentMethod,
|
|
1094
|
-
products: (
|
|
1094
|
+
products: (_127 = props === null || props === void 0 ? void 0 : props.products) === null || _127 === void 0 ? void 0 : _127.map((p, i) => {
|
|
1095
1095
|
var _a, _b, _c, _d;
|
|
1096
1096
|
return (_d = (_c = (_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.formatters) === null || _b === void 0 ? void 0 : _b.objects) === null || _c === void 0 ? void 0 : _c.product) === null || _d === void 0 ? void 0 : _d.call(_c, Object.assign(Object.assign({}, p), { position: i + 1 }));
|
|
1097
1097
|
}),
|
|
@@ -1106,8 +1106,8 @@ export class ChordAnalytics {
|
|
|
1106
1106
|
return this.track('Payment Info Entered', payload, options);
|
|
1107
1107
|
});
|
|
1108
1108
|
this.trackOrderCompleted = (props, options) => __awaiter(this, void 0, void 0, function* () {
|
|
1109
|
-
var
|
|
1110
|
-
const formatter = (
|
|
1109
|
+
var _128, _129, _130, _131;
|
|
1110
|
+
const formatter = (_130 = (_129 = (_128 = this.options) === null || _128 === void 0 ? void 0 : _128.formatters) === null || _129 === void 0 ? void 0 : _129.events) === null || _130 === void 0 ? void 0 : _130.orderCompleted;
|
|
1111
1111
|
const payload = {
|
|
1112
1112
|
affiliation: props === null || props === void 0 ? void 0 : props.affiliation,
|
|
1113
1113
|
campaign_id: props === null || props === void 0 ? void 0 : props.campaignId,
|
|
@@ -1127,7 +1127,7 @@ export class ChordAnalytics {
|
|
|
1127
1127
|
order_date: props === null || props === void 0 ? void 0 : props.orderDate,
|
|
1128
1128
|
order_id: props === null || props === void 0 ? void 0 : props.orderId,
|
|
1129
1129
|
phone: props === null || props === void 0 ? void 0 : props.phone,
|
|
1130
|
-
products: (
|
|
1130
|
+
products: (_131 = props === null || props === void 0 ? void 0 : props.products) === null || _131 === void 0 ? void 0 : _131.map((p, i) => {
|
|
1131
1131
|
var _a;
|
|
1132
1132
|
return ({
|
|
1133
1133
|
affiliation: p === null || p === void 0 ? void 0 : p.affiliation,
|
|
@@ -1199,12 +1199,16 @@ export class ChordAnalytics {
|
|
|
1199
1199
|
window[this.options.namespace] = (window === null || window === void 0 ? void 0 : window[this.options.namespace]) || this;
|
|
1200
1200
|
this.initializeCdp();
|
|
1201
1201
|
}
|
|
1202
|
-
//
|
|
1203
|
-
|
|
1202
|
+
// Set up web pixel listener: explicit true/false takes precedence,
|
|
1203
|
+
// otherwise auto-detect by checking for window.Shopify.shop (Liquid storefront)
|
|
1204
|
+
const shouldEnableWebPixel = (_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.enableWebPixelListener) !== null && _e !== void 0 ? _e : (typeof window !== 'undefined' && !!((_f = window.Shopify) === null || _f === void 0 ? void 0 : _f.shop));
|
|
1205
|
+
if (shouldEnableWebPixel) {
|
|
1204
1206
|
this.setupWebPixelListener();
|
|
1205
1207
|
}
|
|
1206
|
-
//
|
|
1207
|
-
|
|
1208
|
+
// Sync identifiers to cart: explicit true/false takes precedence,
|
|
1209
|
+
// otherwise auto-detect by checking for window.Shopify.shop (Liquid storefront)
|
|
1210
|
+
const shouldEnableIdentifierSync = (_h = (_g = this.options) === null || _g === void 0 ? void 0 : _g.enableIdentifierSync) !== null && _h !== void 0 ? _h : (typeof window !== 'undefined' && !!((_j = window.Shopify) === null || _j === void 0 ? void 0 : _j.shop));
|
|
1211
|
+
if (shouldEnableIdentifierSync) {
|
|
1208
1212
|
this.syncIdentifiersToCart();
|
|
1209
1213
|
}
|
|
1210
1214
|
}
|
package/dist/types/client.d.ts
CHANGED
|
@@ -35,15 +35,17 @@ export interface ChordAnalyticsOptions<T extends ObjectTypes = ObjectTypes> {
|
|
|
35
35
|
debug?: boolean;
|
|
36
36
|
enableLogging?: boolean;
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
38
|
+
* Controls the postMessage listener for events from the Shopify Custom Web
|
|
39
|
+
* Pixel sandbox. When true, always enables the listener. When false, always
|
|
40
|
+
* disables it. When undefined (default), auto-detects by checking for
|
|
41
|
+
* window.Shopify.shop which is present on Shopify Liquid storefronts.
|
|
41
42
|
*/
|
|
42
43
|
enableWebPixelListener?: boolean;
|
|
43
44
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
45
|
+
* Controls syncing CDP anonymous ID and Google Client ID to Shopify cart
|
|
46
|
+
* attributes. When true, always enables sync. When false, always disables it.
|
|
47
|
+
* When undefined (default), auto-detects by checking for window.Shopify.shop
|
|
48
|
+
* which is present on Shopify Liquid storefronts.
|
|
47
49
|
*/
|
|
48
50
|
enableIdentifierSync?: boolean;
|
|
49
51
|
formatters: ChordAnalyticsFormatters<T>;
|
package/package.json
CHANGED