@armco/analytics 0.2.2 → 0.2.4
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/analytics.js +100 -50
- package/constants.d.ts +1 -1
- package/constants.js +1 -1
- package/index.interface.d.ts +2 -1
- package/package.json +1 -1
package/analytics.js
CHANGED
|
@@ -21,7 +21,8 @@ const packageJsonPath = getEnvironmentType() === "node" ? path.resolve(process.c
|
|
|
21
21
|
let ar_anonymous_id;
|
|
22
22
|
let user = null;
|
|
23
23
|
let apiKey = null;
|
|
24
|
-
let
|
|
24
|
+
let analyticsLogEndpoint;
|
|
25
|
+
let analyticsTagEndpoint;
|
|
25
26
|
let hostProjectName = null;
|
|
26
27
|
let enabled = null;
|
|
27
28
|
const CONFIG_FILE_NAME = "analyticsrc";
|
|
@@ -74,19 +75,19 @@ function loadConfiguration() {
|
|
|
74
75
|
return config;
|
|
75
76
|
}
|
|
76
77
|
catch (error) {
|
|
77
|
-
console.error(`Failed to load configuration from ${configFilePath}.`);
|
|
78
|
+
console.error(`[ANALYTICS] Failed to load configuration from ${configFilePath}.`);
|
|
78
79
|
}
|
|
79
80
|
const isTS = yield isTypeScriptProject();
|
|
80
81
|
configFilePath = `${ROOT}${CONFIG_FILE_NAME}.${isTS ? "ts" : "js"}`;
|
|
81
82
|
try {
|
|
82
83
|
const config = yield import(configFilePath);
|
|
83
|
-
console.log(`Configuration loaded from ${configFilePath} successfully.`);
|
|
84
|
+
console.log(`[ANALYTICS] Configuration loaded from ${configFilePath} successfully.`);
|
|
84
85
|
return config.default;
|
|
85
86
|
}
|
|
86
87
|
catch (error) {
|
|
87
|
-
console.error(`Failed to load configuration from ${configFilePath}.`);
|
|
88
|
+
console.error(`[ANALYTICS] Failed to load configuration from ${configFilePath}.`);
|
|
88
89
|
}
|
|
89
|
-
console.error(`No valid configuration file found. Expected one of ${CONFIG_FILE_NAME}.js, ${CONFIG_FILE_NAME}.json or ${CONFIG_FILE_NAME}.ts`);
|
|
90
|
+
console.error(`[ANALYTICS] No valid configuration file found. Expected one of ${CONFIG_FILE_NAME}.js, ${CONFIG_FILE_NAME}.json or ${CONFIG_FILE_NAME}.ts`);
|
|
90
91
|
return null;
|
|
91
92
|
});
|
|
92
93
|
}
|
|
@@ -115,9 +116,15 @@ function getEnvironmentType() {
|
|
|
115
116
|
function getHostProjectName() {
|
|
116
117
|
return __awaiter(this, void 0, void 0, function* () {
|
|
117
118
|
if (!hostProjectName) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
try {
|
|
120
|
+
const packageJson = yield import(packageJsonPath);
|
|
121
|
+
hostProjectName = packageJson.name || null;
|
|
122
|
+
console.log("[ANALYTICS] Fetched project name from package details: ", hostProjectName);
|
|
123
|
+
enabled = isEnabled();
|
|
124
|
+
}
|
|
125
|
+
catch (e) {
|
|
126
|
+
console.warn("[ANALYTICS] Failed to fetch project name, continuing without");
|
|
127
|
+
}
|
|
121
128
|
}
|
|
122
129
|
return hostProjectName;
|
|
123
130
|
});
|
|
@@ -127,6 +134,7 @@ function enrichEventData(data) {
|
|
|
127
134
|
data.eventId = uuidv4();
|
|
128
135
|
data.client = hostProjectName;
|
|
129
136
|
data.sessionId = getSessionId();
|
|
137
|
+
data.url = window.location.href;
|
|
130
138
|
region && (data.region = region);
|
|
131
139
|
address && !data.address && (data.address = address);
|
|
132
140
|
coordinates && !data.coordinates && (data.coordinates = coordinates);
|
|
@@ -148,7 +156,7 @@ export function sendBulkData(data, callback) {
|
|
|
148
156
|
function sendAnalyticsData(data) {
|
|
149
157
|
return __awaiter(this, void 0, void 0, function* () {
|
|
150
158
|
try {
|
|
151
|
-
if (!apiKey && !
|
|
159
|
+
if (!apiKey && !analyticsLogEndpoint) {
|
|
152
160
|
console.error('Neither of API key and Analytics server configured. Data not sent.');
|
|
153
161
|
return;
|
|
154
162
|
}
|
|
@@ -162,9 +170,14 @@ function sendAnalyticsData(data) {
|
|
|
162
170
|
if (apiKey) {
|
|
163
171
|
options.headers.Authorization = `Bearer ${apiKey}`;
|
|
164
172
|
}
|
|
165
|
-
const logEndpoint = apiKey ? ARMCO_SERVER + ADD :
|
|
166
|
-
|
|
167
|
-
|
|
173
|
+
const logEndpoint = apiKey ? ARMCO_SERVER + ADD : analyticsLogEndpoint;
|
|
174
|
+
try {
|
|
175
|
+
const response = yield fetch(logEndpoint, options);
|
|
176
|
+
console.log('Analytics data sent to server:', logEndpoint, data, response.status, response.statusText);
|
|
177
|
+
}
|
|
178
|
+
catch (e) {
|
|
179
|
+
console.warn("Failed attempt to log event");
|
|
180
|
+
}
|
|
168
181
|
}
|
|
169
182
|
catch (error) {
|
|
170
183
|
console.error('Failed to send analytics data:', error);
|
|
@@ -174,7 +187,7 @@ function sendAnalyticsData(data) {
|
|
|
174
187
|
function tagEvents(email) {
|
|
175
188
|
return __awaiter(this, void 0, void 0, function* () {
|
|
176
189
|
try {
|
|
177
|
-
if (!apiKey && !
|
|
190
|
+
if (!apiKey && !analyticsTagEndpoint) {
|
|
178
191
|
console.error('Neither of API key and Analytics server configured. Tagging won\'t be attempted.');
|
|
179
192
|
return;
|
|
180
193
|
}
|
|
@@ -188,7 +201,7 @@ function tagEvents(email) {
|
|
|
188
201
|
if (apiKey) {
|
|
189
202
|
options.headers.Authorization = `Bearer ${apiKey}`;
|
|
190
203
|
}
|
|
191
|
-
const tagEndpoint = apiKey ? ARMCO_SERVER + ADD :
|
|
204
|
+
const tagEndpoint = apiKey ? ARMCO_SERVER + ADD : analyticsTagEndpoint;
|
|
192
205
|
const response = yield fetch(tagEndpoint, options);
|
|
193
206
|
console.log('Analytics data sent to server:', tagEndpoint, response.status, response.statusText);
|
|
194
207
|
}
|
|
@@ -264,6 +277,71 @@ function populateLocationDetails() {
|
|
|
264
277
|
}
|
|
265
278
|
region = localTimeRegion;
|
|
266
279
|
}
|
|
280
|
+
const trackedItems = [
|
|
281
|
+
"a[href]",
|
|
282
|
+
"button",
|
|
283
|
+
"input[type='button']",
|
|
284
|
+
"input[type='submit']",
|
|
285
|
+
"input[type='reset']",
|
|
286
|
+
"input[type='checkbox']",
|
|
287
|
+
"input[type='radio']",
|
|
288
|
+
"select",
|
|
289
|
+
"textarea",
|
|
290
|
+
"area",
|
|
291
|
+
"details",
|
|
292
|
+
"summary",
|
|
293
|
+
"iframe",
|
|
294
|
+
"object",
|
|
295
|
+
"embed",
|
|
296
|
+
"label",
|
|
297
|
+
"img",
|
|
298
|
+
"[role='button']",
|
|
299
|
+
"[role='checkbox']",
|
|
300
|
+
"[role='link']",
|
|
301
|
+
"[role='menuitem']",
|
|
302
|
+
"[role='menuitemcheckbox']",
|
|
303
|
+
"[role='menuitemradio']",
|
|
304
|
+
"[data-track='true']"
|
|
305
|
+
];
|
|
306
|
+
function isClickable(element) {
|
|
307
|
+
return element.matches(trackedItems.join(", ")) ||
|
|
308
|
+
element.onclick != null ||
|
|
309
|
+
window.getComputedStyle(element).cursor == "pointer";
|
|
310
|
+
}
|
|
311
|
+
function handleTrackedItemClick(e) {
|
|
312
|
+
var _a;
|
|
313
|
+
const clickedElement = e.target;
|
|
314
|
+
if (isClickable(clickedElement)) {
|
|
315
|
+
const dataAttributes = Object.assign({}, clickedElement.dataset);
|
|
316
|
+
const id = clickedElement.id || null;
|
|
317
|
+
const name = clickedElement.getAttribute('name') || null;
|
|
318
|
+
const classes = Array.from(clickedElement.classList);
|
|
319
|
+
const elementType = clickedElement.tagName.toLowerCase();
|
|
320
|
+
const textContent = clickedElement.textContent;
|
|
321
|
+
const href = 'href' in clickedElement ? clickedElement.href : null;
|
|
322
|
+
const role = clickedElement.getAttribute('role') || null;
|
|
323
|
+
const parentElementId = ((_a = clickedElement.parentElement) === null || _a === void 0 ? void 0 : _a.id) || null;
|
|
324
|
+
const value = 'value' in clickedElement && clickedElement.value
|
|
325
|
+
? clickedElement.value
|
|
326
|
+
: null;
|
|
327
|
+
const mergedData = Object.assign({}, dataAttributes, {
|
|
328
|
+
id,
|
|
329
|
+
name,
|
|
330
|
+
classes,
|
|
331
|
+
textContent,
|
|
332
|
+
href,
|
|
333
|
+
tagName: elementType,
|
|
334
|
+
role,
|
|
335
|
+
parentElementId,
|
|
336
|
+
});
|
|
337
|
+
trackEvent("CLICK", {
|
|
338
|
+
click: {
|
|
339
|
+
data: mergedData,
|
|
340
|
+
value,
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
}
|
|
267
345
|
function hookTrackers() {
|
|
268
346
|
if (environment === "browser") {
|
|
269
347
|
const TRACK_EVENTS = (CONFIG === null || CONFIG === void 0 ? void 0 : CONFIG.trackEvents) || ["click", "submit", "select-change"];
|
|
@@ -271,41 +349,8 @@ function hookTrackers() {
|
|
|
271
349
|
console.log("[ANALYTICS] Attaching Click handlers");
|
|
272
350
|
const clickables = Array.from(document.querySelectorAll('*'));
|
|
273
351
|
console.log("[ANALYTICS] Found " + clickables.length + " items that can be clicked!");
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
return element.tagName === "BUTTON" ||
|
|
277
|
-
element.tagName === "A" ||
|
|
278
|
-
element.onclick != null ||
|
|
279
|
-
window.getComputedStyle(element).cursor == "pointer";
|
|
280
|
-
})
|
|
281
|
-
.forEach((element) => {
|
|
282
|
-
element.addEventListener("click", e => {
|
|
283
|
-
var _a;
|
|
284
|
-
const clickedElement = e.target;
|
|
285
|
-
const id = clickedElement.id;
|
|
286
|
-
const classes = Array.from(clickedElement.classList);
|
|
287
|
-
const dataAttributes = Object.keys(clickedElement.dataset).map(key => ({ [key]: clickedElement.dataset[key] }));
|
|
288
|
-
const textContent = clickedElement.textContent;
|
|
289
|
-
const href = 'href' in clickedElement ? clickedElement.href : null;
|
|
290
|
-
const elementType = clickedElement.tagName.toLowerCase();
|
|
291
|
-
const parentElementId = ((_a = clickedElement.parentElement) === null || _a === void 0 ? void 0 : _a.id) || null;
|
|
292
|
-
const value = 'value' in clickedElement && clickedElement.value
|
|
293
|
-
? clickedElement.value
|
|
294
|
-
: null;
|
|
295
|
-
trackEvent("CLICK", {
|
|
296
|
-
click: {
|
|
297
|
-
id,
|
|
298
|
-
classes,
|
|
299
|
-
dataAttributes,
|
|
300
|
-
textContent,
|
|
301
|
-
href,
|
|
302
|
-
elementType,
|
|
303
|
-
parentElementId,
|
|
304
|
-
value,
|
|
305
|
-
}
|
|
306
|
-
});
|
|
307
|
-
});
|
|
308
|
-
});
|
|
352
|
+
console.log("[ANALYTICS] Dynamically added elements will be added to this list.");
|
|
353
|
+
document.addEventListener("click", handleTrackedItemClick);
|
|
309
354
|
console.log("[ANALYTICS] Click handlers Attached");
|
|
310
355
|
}
|
|
311
356
|
if (TRACK_EVENTS.indexOf("submit") > -1) {
|
|
@@ -392,7 +437,8 @@ function loadAnalytics(config) {
|
|
|
392
437
|
if (CONFIG) {
|
|
393
438
|
console.log("[ANALYTICS] Configuration loaded");
|
|
394
439
|
apiKey = CONFIG.apiKey || null;
|
|
395
|
-
|
|
440
|
+
analyticsLogEndpoint = CONFIG.analyticsLogEndpoint || null;
|
|
441
|
+
analyticsTagEndpoint = CONFIG.analyticsTagEndpoint || null;
|
|
396
442
|
hostProjectName = CONFIG.hostProjectName || hostProjectName || null;
|
|
397
443
|
console.log("[ANALYTICS] Check if Analytics enabled");
|
|
398
444
|
enabled = isEnabled();
|
|
@@ -409,6 +455,10 @@ function loadAnalytics(config) {
|
|
|
409
455
|
const anonId = generateAnonymousId();
|
|
410
456
|
console.log("Tracking User as", anonId);
|
|
411
457
|
startSession();
|
|
458
|
+
window.addEventListener('load', function () {
|
|
459
|
+
console.log("[ANALYTICS] Logging page load");
|
|
460
|
+
trackEvent("PAGE");
|
|
461
|
+
});
|
|
412
462
|
}
|
|
413
463
|
else {
|
|
414
464
|
console.warn("[ANALYTICS] Analytics blocked by client, or disabled by configuration!");
|
package/constants.d.ts
CHANGED
package/constants.js
CHANGED
package/index.interface.d.ts
CHANGED
|
@@ -14,7 +14,8 @@ export interface Event {
|
|
|
14
14
|
}
|
|
15
15
|
export interface ConfigType {
|
|
16
16
|
apiKey?: string;
|
|
17
|
-
|
|
17
|
+
analyticsLogEndpoint?: string;
|
|
18
|
+
analyticsTagEndpoint?: string;
|
|
18
19
|
hostProjectName?: string;
|
|
19
20
|
trackEvents?: Array<string>;
|
|
20
21
|
submissionStrategy?: SubmissionStrategy;
|