@armco/analytics 0.2.10 → 0.2.11
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/package.json +20 -9
- package/.npmignore +0 -6
- package/analytics.d.ts +0 -19
- package/analytics.js +0 -537
- package/constants.d.ts +0 -3
- package/constants.js +0 -3
- package/flush.d.ts +0 -3
- package/flush.js +0 -36
- package/global-modules.d.ts +0 -14
- package/helper.d.ts +0 -1
- package/helper.js +0 -3
- package/index.d.ts +0 -2
- package/index.interface.d.ts +0 -28
- package/index.interface.js +0 -1
- package/index.js +0 -13
- package/location.d.ts +0 -6
- package/location.js +0 -42
- package/session.d.ts +0 -4
- package/session.js +0 -76
- package/tsconfig.prod.tsbuildinfo +0 -1
package/package.json
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@armco/analytics",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "
|
|
5
|
-
"main": "index.js",
|
|
3
|
+
"version": "0.2.11",
|
|
4
|
+
"description": "Universal Analytics Library for Browser and Node.js",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
6
7
|
"type": "module",
|
|
7
8
|
"scripts": {
|
|
8
9
|
"build": "npx ts-node build.js",
|
|
9
10
|
"lint": "npx eslint --ext .ts src/",
|
|
10
|
-
"lint:tests": "npx eslint --ext .ts
|
|
11
|
+
"lint:tests": "npx eslint --ext .ts tests/",
|
|
11
12
|
"start": "node ./dist --env=production",
|
|
12
13
|
"dev": "nodemon",
|
|
13
|
-
"test": "
|
|
14
|
-
"test:
|
|
14
|
+
"test": "jest",
|
|
15
|
+
"test:watch": "jest --watch",
|
|
16
|
+
"test:coverage": "jest --coverage",
|
|
17
|
+
"test:unit": "jest --testPathPattern=tests/unit",
|
|
18
|
+
"test:integration": "jest --testPathPattern=tests/integration",
|
|
15
19
|
"publish:local": "./publish-local.sh",
|
|
16
20
|
"publish:sh": "./publish.sh",
|
|
17
21
|
"publish:sh:minor": "./publish.sh minor"
|
|
@@ -27,26 +31,33 @@
|
|
|
27
31
|
"insights",
|
|
28
32
|
"automated"
|
|
29
33
|
],
|
|
30
|
-
"author": "mohit.nagar@armco.
|
|
34
|
+
"author": "mohit.nagar@armco.dev",
|
|
31
35
|
"license": "ISC",
|
|
32
36
|
"bugs": {
|
|
33
37
|
"url": "https://github.com/ReStruct-Corporate-Advantage/analytics/issues"
|
|
34
38
|
},
|
|
35
39
|
"homepage": "https://github.com/ReStruct-Corporate-Advantage/analytics#readme",
|
|
36
40
|
"files": [
|
|
37
|
-
"
|
|
41
|
+
"dist",
|
|
42
|
+
"README.md",
|
|
43
|
+
"LICENSE"
|
|
38
44
|
],
|
|
39
45
|
"devDependencies": {
|
|
46
|
+
"@jest/globals": "^29.7.0",
|
|
40
47
|
"@types/fs-extra": "^11.0.1",
|
|
48
|
+
"@types/jest": "^29.5.11",
|
|
41
49
|
"@types/js-cookie": "^3.0.3",
|
|
42
50
|
"@types/node": "^20.4.2",
|
|
43
51
|
"@types/uuid": "^9.0.2",
|
|
44
52
|
"fs-extra": "^11.1.1",
|
|
53
|
+
"jest": "^29.7.0",
|
|
54
|
+
"ts-jest": "^29.1.1",
|
|
45
55
|
"typescript": "^5.1.6"
|
|
46
56
|
},
|
|
47
57
|
"dependencies": {
|
|
48
58
|
"js-cookie": "^3.0.5",
|
|
49
59
|
"jstz": "^2.1.1",
|
|
50
|
-
"uuid": "^9.0.0"
|
|
60
|
+
"uuid": "^9.0.0",
|
|
61
|
+
"zod": "^4.1.13"
|
|
51
62
|
}
|
|
52
63
|
}
|
package/.npmignore
DELETED
package/analytics.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { startSession, getSessionId } from "./session";
|
|
2
|
-
import { User, Event, ConfigType } from "./index.interface";
|
|
3
|
-
declare let enabled: boolean | null;
|
|
4
|
-
declare function loadConfiguration(): Promise<any>;
|
|
5
|
-
declare function getEnvironment(): string;
|
|
6
|
-
declare function getEnvironmentType(): "browser" | "node" | "unknown";
|
|
7
|
-
export declare function sendBulkData(data: Event[], callback?: Function): Promise<void>;
|
|
8
|
-
declare function trackEvent(event: string | Event, data?: any): void;
|
|
9
|
-
declare function trackPageView(pageName: string, data?: {
|
|
10
|
-
[key: string]: any;
|
|
11
|
-
}): void;
|
|
12
|
-
declare function trackError(errorMessage: string): void;
|
|
13
|
-
declare function enableTracking(enable: boolean): void;
|
|
14
|
-
declare function generateAnonymousId(): string;
|
|
15
|
-
declare function identify(appUser: User): void;
|
|
16
|
-
declare function sendHostProjectName(): void;
|
|
17
|
-
declare function init(config?: ConfigType): void;
|
|
18
|
-
declare function logout(): void;
|
|
19
|
-
export { enabled as analyticsEnabled, init, identify, getEnvironmentType, getEnvironment, loadConfiguration, logout, trackEvent, trackPageView, trackError, enableTracking, generateAnonymousId, sendHostProjectName, getSessionId, startSession, };
|
package/analytics.js
DELETED
|
@@ -1,537 +0,0 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
import * as fs from "fs";
|
|
11
|
-
import * as path from "path";
|
|
12
|
-
import { v4 as uuidv4 } from "uuid";
|
|
13
|
-
import { ADD, ARMCO_SERVER } from "./constants";
|
|
14
|
-
import { startSession, getSessionId, terminateSession } from "./session";
|
|
15
|
-
import { ipLookup, success, error, localTimeRegion } from "./location";
|
|
16
|
-
import { isArClient } from "./helper";
|
|
17
|
-
import { hookFlushHandlers, queueEvent } from "./flush";
|
|
18
|
-
const tsConfigPath = getEnvironmentType() === "node"
|
|
19
|
-
? path.resolve(process.cwd(), "tsconfig.json")
|
|
20
|
-
: "../../../../tsConfig.json";
|
|
21
|
-
const packageJsonPath = getEnvironmentType() === "node"
|
|
22
|
-
? path.resolve(process.cwd(), "package.json")
|
|
23
|
-
: "../../../../package.json";
|
|
24
|
-
let ar_anonymous_id;
|
|
25
|
-
let user = null;
|
|
26
|
-
let apiKey = null;
|
|
27
|
-
let analyticsLogEndpoint;
|
|
28
|
-
let analyticsTagEndpoint;
|
|
29
|
-
let hostProjectName = null;
|
|
30
|
-
let enabled = null;
|
|
31
|
-
const CONFIG_FILE_NAME = "analyticsrc";
|
|
32
|
-
let region;
|
|
33
|
-
let address;
|
|
34
|
-
let coordinates;
|
|
35
|
-
let runtime = null;
|
|
36
|
-
let CONFIG;
|
|
37
|
-
let environment;
|
|
38
|
-
function isTypeScriptProject() {
|
|
39
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
40
|
-
if (fs &&
|
|
41
|
-
"existsSync" in fs &&
|
|
42
|
-
!(fs.existsSync(tsConfigPath) && fs.existsSync(packageJsonPath))) {
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
let tsConfig, packageJson;
|
|
46
|
-
try {
|
|
47
|
-
tsConfig = yield import(tsConfigPath);
|
|
48
|
-
if (tsConfig && tsConfig.compilerOptions) {
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
console.error("Error loading tsconfig.json:", error);
|
|
54
|
-
}
|
|
55
|
-
try {
|
|
56
|
-
packageJson = yield import(tsConfigPath);
|
|
57
|
-
if (packageJson &&
|
|
58
|
-
packageJson.devDependencies &&
|
|
59
|
-
packageJson.devDependencies.typescript) {
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
catch (error) {
|
|
64
|
-
console.error("Error loading tsconfig.json:", error);
|
|
65
|
-
}
|
|
66
|
-
if (packageJson &&
|
|
67
|
-
packageJson.devDependencies &&
|
|
68
|
-
packageJson.devDependencies.typescript) {
|
|
69
|
-
return true;
|
|
70
|
-
}
|
|
71
|
-
return false;
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
function loadConfiguration() {
|
|
75
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
-
const ROOT = (runtime || getEnvironment()) === "production" ? "../../" : "../../../../";
|
|
77
|
-
let configFilePath = `${ROOT}${CONFIG_FILE_NAME}.json`;
|
|
78
|
-
try {
|
|
79
|
-
const config = yield import(configFilePath);
|
|
80
|
-
return config;
|
|
81
|
-
}
|
|
82
|
-
catch (error) {
|
|
83
|
-
console.error(`[ANALYTICS] Failed to load configuration from ${configFilePath}.`);
|
|
84
|
-
}
|
|
85
|
-
const isTS = yield isTypeScriptProject();
|
|
86
|
-
configFilePath = `${ROOT}${CONFIG_FILE_NAME}.${isTS ? "ts" : "js"}`;
|
|
87
|
-
try {
|
|
88
|
-
const config = yield import(configFilePath);
|
|
89
|
-
console.log(`[ANALYTICS] Configuration loaded from ${configFilePath} successfully.`);
|
|
90
|
-
return config.default;
|
|
91
|
-
}
|
|
92
|
-
catch (error) {
|
|
93
|
-
console.error(`[ANALYTICS] Failed to load configuration from ${configFilePath}.`);
|
|
94
|
-
}
|
|
95
|
-
console.error(`[ANALYTICS] No valid configuration file found. Expected one of ${CONFIG_FILE_NAME}.js, ${CONFIG_FILE_NAME}.json or ${CONFIG_FILE_NAME}.ts`);
|
|
96
|
-
return null;
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
function getEnvironment() {
|
|
100
|
-
if (typeof process !== "undefined" && process.env && process.env.NODE_ENV) {
|
|
101
|
-
return process.env.NODE_ENV;
|
|
102
|
-
}
|
|
103
|
-
if (import.meta.env && import.meta.env.MODE) {
|
|
104
|
-
return import.meta.env.MODE;
|
|
105
|
-
}
|
|
106
|
-
return "development";
|
|
107
|
-
}
|
|
108
|
-
function getEnvironmentType() {
|
|
109
|
-
if (typeof window !== "undefined" && typeof window.document !== "undefined") {
|
|
110
|
-
return "browser";
|
|
111
|
-
}
|
|
112
|
-
else if (typeof process !== "undefined" &&
|
|
113
|
-
process.versions != null &&
|
|
114
|
-
process.versions.node != null) {
|
|
115
|
-
return "node";
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
return "unknown";
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
function getHostProjectName() {
|
|
122
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
123
|
-
if (!hostProjectName) {
|
|
124
|
-
try {
|
|
125
|
-
const packageJson = yield import(packageJsonPath);
|
|
126
|
-
hostProjectName = packageJson.name || null;
|
|
127
|
-
console.log("[ANALYTICS] Fetched project name from package details: ", hostProjectName);
|
|
128
|
-
enabled = isEnabled();
|
|
129
|
-
}
|
|
130
|
-
catch (e) {
|
|
131
|
-
console.warn("[ANALYTICS] Failed to fetch project name, continuing without");
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return hostProjectName;
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
function enrichEventData(data) {
|
|
138
|
-
if (data) {
|
|
139
|
-
data.eventId = uuidv4();
|
|
140
|
-
data.client = hostProjectName;
|
|
141
|
-
data.sessionId = getSessionId();
|
|
142
|
-
data.url = window.location.href;
|
|
143
|
-
region && (data.region = region);
|
|
144
|
-
address && !data.address && (data.address = address);
|
|
145
|
-
coordinates && !data.coordinates && (data.coordinates = coordinates);
|
|
146
|
-
!data.timestamp && (data.timestamp = new Date());
|
|
147
|
-
!data.userId && (data.userId = user ? user.email : ar_anonymous_id);
|
|
148
|
-
!data.email && user && user.email && (data.email = user.email);
|
|
149
|
-
user && (data.user = user);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
function isMalformedEvent(data) {
|
|
153
|
-
return !data || !data.eventType;
|
|
154
|
-
}
|
|
155
|
-
export function sendBulkData(data, callback) {
|
|
156
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
157
|
-
const promises = data && data.map((event) => sendAnalyticsData(event));
|
|
158
|
-
Promise.all(promises).then(() => callback && callback());
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
function sendAnalyticsData(data) {
|
|
162
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
163
|
-
try {
|
|
164
|
-
if (!apiKey && !analyticsLogEndpoint) {
|
|
165
|
-
console.error("Neither of API key and Analytics server configured. Data not sent.");
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
const options = {
|
|
169
|
-
method: "POST",
|
|
170
|
-
headers: {
|
|
171
|
-
"Content-Type": "application/json",
|
|
172
|
-
},
|
|
173
|
-
body: JSON.stringify({ event: data }),
|
|
174
|
-
};
|
|
175
|
-
if (apiKey) {
|
|
176
|
-
options.headers.Authorization = `Bearer ${apiKey}`;
|
|
177
|
-
}
|
|
178
|
-
const logEndpoint = apiKey
|
|
179
|
-
? ARMCO_SERVER + ADD
|
|
180
|
-
: analyticsLogEndpoint;
|
|
181
|
-
try {
|
|
182
|
-
const response = yield fetch(logEndpoint, options);
|
|
183
|
-
if (response.status === 200) {
|
|
184
|
-
console.log("Analytics data sent to server:", logEndpoint, data, response.status, response.statusText);
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
console.warn("Failed to send analytics payload to:", logEndpoint, data, response.status, response.statusText);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
catch (e) {
|
|
191
|
-
console.warn("Failed attempt to log event");
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
catch (error) {
|
|
195
|
-
console.error("Failed to send analytics data:", error);
|
|
196
|
-
}
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
function tagEvents(email) {
|
|
200
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
201
|
-
try {
|
|
202
|
-
if (!apiKey && !analyticsTagEndpoint) {
|
|
203
|
-
console.error("Neither of API key and Analytics server configured. Tagging won't be attempted.");
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
const options = {
|
|
207
|
-
method: "POST",
|
|
208
|
-
headers: {
|
|
209
|
-
"Content-Type": "application/json",
|
|
210
|
-
},
|
|
211
|
-
body: { event: JSON.stringify({ email, anonymousId: ar_anonymous_id }) },
|
|
212
|
-
};
|
|
213
|
-
if (apiKey) {
|
|
214
|
-
options.headers.Authorization = `Bearer ${apiKey}`;
|
|
215
|
-
}
|
|
216
|
-
const tagEndpoint = apiKey
|
|
217
|
-
? ARMCO_SERVER + ADD
|
|
218
|
-
: analyticsTagEndpoint;
|
|
219
|
-
const response = yield fetch(tagEndpoint, options);
|
|
220
|
-
console.log("Analytics data sent to server:", tagEndpoint, response.status, response.statusText);
|
|
221
|
-
}
|
|
222
|
-
catch (error) {
|
|
223
|
-
console.error("Failed to send analytics data:", error);
|
|
224
|
-
}
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
function trackEvent(event, data) {
|
|
228
|
-
const tracker = user && user.email ? user.email : ar_anonymous_id;
|
|
229
|
-
if (enabled && tracker) {
|
|
230
|
-
if (typeof event === "string") {
|
|
231
|
-
data = data || {};
|
|
232
|
-
if (data) {
|
|
233
|
-
data.eventType = event;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
data = event;
|
|
238
|
-
}
|
|
239
|
-
if (isMalformedEvent(data)) {
|
|
240
|
-
console.error("Attempting to send empty event, or event missing eventType, failing send...");
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
enrichEventData(data);
|
|
244
|
-
(CONFIG === null || CONFIG === void 0 ? void 0 : CONFIG.submissionStrategy) === "DEFER"
|
|
245
|
-
? queueEvent(data)
|
|
246
|
-
: sendAnalyticsData(data);
|
|
247
|
-
}
|
|
248
|
-
else {
|
|
249
|
-
console.log("Analytics disabled or user not identified. Event data not sent.");
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
function trackPageView(pageName, data) {
|
|
253
|
-
const pageViewEvent = Object.assign({ eventType: "Page View", pageName }, data);
|
|
254
|
-
trackEvent("Page View", pageViewEvent);
|
|
255
|
-
}
|
|
256
|
-
function trackError(errorMessage) {
|
|
257
|
-
const errorEvent = {
|
|
258
|
-
eventType: "Error",
|
|
259
|
-
timestamp: new Date(),
|
|
260
|
-
errorMessage,
|
|
261
|
-
};
|
|
262
|
-
trackEvent(errorEvent);
|
|
263
|
-
}
|
|
264
|
-
function isEnabled() {
|
|
265
|
-
if (typeof navigator !== "undefined" && "doNotTrack" in navigator) {
|
|
266
|
-
const doNotTrackValue = navigator.doNotTrack;
|
|
267
|
-
if (doNotTrackValue === "1" || doNotTrackValue === "yes") {
|
|
268
|
-
console.warn("[ANALYTICS] Tracking disabled in client, events will not be logged!");
|
|
269
|
-
return isArClient(hostProjectName) || false;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
return true;
|
|
273
|
-
}
|
|
274
|
-
function enableTracking(enable) {
|
|
275
|
-
enabled = isEnabled() && enable;
|
|
276
|
-
}
|
|
277
|
-
function generateAnonymousId() {
|
|
278
|
-
ar_anonymous_id = uuidv4();
|
|
279
|
-
return ar_anonymous_id;
|
|
280
|
-
}
|
|
281
|
-
function populateLocationDetails() {
|
|
282
|
-
if (!navigator.geolocation) {
|
|
283
|
-
console.warn("Geolocation is not supported by your browser");
|
|
284
|
-
ipLookup();
|
|
285
|
-
}
|
|
286
|
-
else {
|
|
287
|
-
navigator.geolocation.getCurrentPosition((position) => {
|
|
288
|
-
coordinates = {
|
|
289
|
-
latitude: position.coords.latitude,
|
|
290
|
-
longitude: position.coords.longitude,
|
|
291
|
-
};
|
|
292
|
-
success(position, (reverseGeocodingResponse) => {
|
|
293
|
-
address = reverseGeocodingResponse.results[0].formatted_address;
|
|
294
|
-
});
|
|
295
|
-
}, error);
|
|
296
|
-
}
|
|
297
|
-
region = localTimeRegion;
|
|
298
|
-
}
|
|
299
|
-
const trackedItems = [
|
|
300
|
-
"a[href]",
|
|
301
|
-
"button",
|
|
302
|
-
"input[type='button']",
|
|
303
|
-
"input[type='submit']",
|
|
304
|
-
"input[type='reset']",
|
|
305
|
-
"input[type='checkbox']",
|
|
306
|
-
"input[type='radio']",
|
|
307
|
-
"select",
|
|
308
|
-
"textarea",
|
|
309
|
-
"area",
|
|
310
|
-
"details",
|
|
311
|
-
"summary",
|
|
312
|
-
"iframe",
|
|
313
|
-
"object",
|
|
314
|
-
"embed",
|
|
315
|
-
"label",
|
|
316
|
-
"img",
|
|
317
|
-
"[role='button']",
|
|
318
|
-
"[role='checkbox']",
|
|
319
|
-
"[role='link']",
|
|
320
|
-
"[role='menuitem']",
|
|
321
|
-
"[role='menuitemcheckbox']",
|
|
322
|
-
"[role='menuitemradio']",
|
|
323
|
-
"[data-track='true']",
|
|
324
|
-
];
|
|
325
|
-
function isClickable(element) {
|
|
326
|
-
return (element.matches(trackedItems.join(", ")) ||
|
|
327
|
-
element.onclick != null ||
|
|
328
|
-
window.getComputedStyle(element).cursor === "pointer");
|
|
329
|
-
}
|
|
330
|
-
function handleTrackedItemClick(e) {
|
|
331
|
-
var _a;
|
|
332
|
-
const clickedElement = e.target;
|
|
333
|
-
if (isClickable(clickedElement)) {
|
|
334
|
-
const dataAttributes = Object.assign({}, clickedElement.dataset);
|
|
335
|
-
const id = clickedElement.id || null;
|
|
336
|
-
const name = clickedElement.getAttribute("name") || null;
|
|
337
|
-
const classes = Array.from(clickedElement.classList);
|
|
338
|
-
const elementType = clickedElement.tagName.toLowerCase();
|
|
339
|
-
const textContent = clickedElement.textContent;
|
|
340
|
-
const href = "href" in clickedElement
|
|
341
|
-
? clickedElement.href
|
|
342
|
-
: null;
|
|
343
|
-
const role = clickedElement.getAttribute("role") || null;
|
|
344
|
-
const parentElementId = ((_a = clickedElement.parentElement) === null || _a === void 0 ? void 0 : _a.id) || null;
|
|
345
|
-
const value = "value" in clickedElement && clickedElement.value
|
|
346
|
-
? clickedElement.value
|
|
347
|
-
: null;
|
|
348
|
-
const mergedData = Object.assign(Object.assign({}, dataAttributes), { id,
|
|
349
|
-
name,
|
|
350
|
-
classes,
|
|
351
|
-
textContent,
|
|
352
|
-
href, tagName: elementType, role,
|
|
353
|
-
parentElementId,
|
|
354
|
-
value });
|
|
355
|
-
trackEvent("CLICK", { element: mergedData });
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
function hookTrackers() {
|
|
359
|
-
if (environment === "browser") {
|
|
360
|
-
const TRACK_EVENTS = (CONFIG === null || CONFIG === void 0 ? void 0 : CONFIG.trackEvents) || [
|
|
361
|
-
"click",
|
|
362
|
-
"submit",
|
|
363
|
-
"select-change",
|
|
364
|
-
];
|
|
365
|
-
if (TRACK_EVENTS.indexOf("click") > -1) {
|
|
366
|
-
console.log("[ANALYTICS] Attaching Click handlers");
|
|
367
|
-
const clickables = Array.from(document.querySelectorAll("*"));
|
|
368
|
-
console.log("[ANALYTICS] Found " +
|
|
369
|
-
clickables.length +
|
|
370
|
-
" items that can be clicked!");
|
|
371
|
-
console.log("[ANALYTICS] Dynamically added elements will be added to this list.");
|
|
372
|
-
document.addEventListener("click", handleTrackedItemClick);
|
|
373
|
-
console.log("[ANALYTICS] Click handlers Attached");
|
|
374
|
-
}
|
|
375
|
-
if (TRACK_EVENTS.indexOf("submit") > -1) {
|
|
376
|
-
console.log("[ANALYTICS] Attaching Submit handlers");
|
|
377
|
-
document.addEventListener("submit", (event) => {
|
|
378
|
-
const formElement = event.target;
|
|
379
|
-
trackEvent("SUBMIT", {
|
|
380
|
-
submit: {
|
|
381
|
-
formId: formElement.id,
|
|
382
|
-
formData: new FormData(formElement),
|
|
383
|
-
},
|
|
384
|
-
});
|
|
385
|
-
});
|
|
386
|
-
console.log("[ANALYTICS] Submit handlers attached");
|
|
387
|
-
}
|
|
388
|
-
if (TRACK_EVENTS.indexOf("select-change") > -1) {
|
|
389
|
-
console.log("[ANALYTICS] Attaching Select OnChange handlers");
|
|
390
|
-
document.addEventListener("change", (event) => {
|
|
391
|
-
const target = event.target;
|
|
392
|
-
if (target.tagName === "SELECT") {
|
|
393
|
-
const selectedOptionValue = target.value;
|
|
394
|
-
const selectedOptionLabel = target
|
|
395
|
-
.selectedOptions[0].label;
|
|
396
|
-
trackEvent("SELECT_CHANGE", {
|
|
397
|
-
value: selectedOptionValue,
|
|
398
|
-
label: selectedOptionLabel,
|
|
399
|
-
});
|
|
400
|
-
}
|
|
401
|
-
});
|
|
402
|
-
console.log("[ANALYTICS] Select OnChange handlers attached");
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
function identify(appUser) {
|
|
407
|
-
if (user === null) {
|
|
408
|
-
user = appUser;
|
|
409
|
-
}
|
|
410
|
-
else {
|
|
411
|
-
user.email = appUser.email;
|
|
412
|
-
}
|
|
413
|
-
tagEvents(user.email);
|
|
414
|
-
ar_anonymous_id = null;
|
|
415
|
-
}
|
|
416
|
-
function sendHostProjectName() {
|
|
417
|
-
if (hostProjectName) {
|
|
418
|
-
const data = {
|
|
419
|
-
hostProjectName,
|
|
420
|
-
};
|
|
421
|
-
sendAnalyticsData(data);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
function showTrackingPopup() {
|
|
425
|
-
var _a, _b;
|
|
426
|
-
const popupContent = `
|
|
427
|
-
<div class="tracking-popup" style="position: fixed;
|
|
428
|
-
width: 50%;
|
|
429
|
-
left: 25%;
|
|
430
|
-
bottom: 2rem;
|
|
431
|
-
padding: 1rem;
|
|
432
|
-
background: aliceblue;
|
|
433
|
-
border-radius: 5px;
|
|
434
|
-
display: flex;
|
|
435
|
-
border: 1px solid #ccc;
|
|
436
|
-
justify-content: space-between;">
|
|
437
|
-
<p style="width: 80%;">We use cookies to collect and analyze data to improve our website. By clicking "Accept," you consent to the use of cookies.</p>
|
|
438
|
-
<a class="btn-accept" style="display: flex;
|
|
439
|
-
align-items: center;
|
|
440
|
-
font-weight: bold;
|
|
441
|
-
cursor: pointer;"
|
|
442
|
-
onClick="${(e) => {
|
|
443
|
-
e.preventDefault();
|
|
444
|
-
enableTracking(true);
|
|
445
|
-
}};"
|
|
446
|
-
>Got it!</a>
|
|
447
|
-
</div>
|
|
448
|
-
`;
|
|
449
|
-
document.body.insertAdjacentHTML("beforeend", popupContent);
|
|
450
|
-
(_a = document.querySelector(".btn-accept")) === null || _a === void 0 ? void 0 : _a.addEventListener("click", function () {
|
|
451
|
-
var _a;
|
|
452
|
-
(_a = document.querySelector(".tracking-popup")) === null || _a === void 0 ? void 0 : _a.remove();
|
|
453
|
-
});
|
|
454
|
-
(_b = document
|
|
455
|
-
.querySelector(".btn-decline")) === null || _b === void 0 ? void 0 : _b.addEventListener("click", function () {
|
|
456
|
-
var _a;
|
|
457
|
-
enableTracking(false);
|
|
458
|
-
(_a = document.querySelector(".tracking-popup")) === null || _a === void 0 ? void 0 : _a.remove();
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
function loadAnalytics(config) {
|
|
462
|
-
console.log("[ANALYTICS] Loading Configuration");
|
|
463
|
-
CONFIG = config;
|
|
464
|
-
if (CONFIG) {
|
|
465
|
-
console.log("[ANALYTICS] Configuration loaded");
|
|
466
|
-
apiKey = CONFIG.apiKey || null;
|
|
467
|
-
analyticsLogEndpoint = CONFIG.analyticsLogEndpoint || null;
|
|
468
|
-
analyticsTagEndpoint = CONFIG.analyticsTagEndpoint || null;
|
|
469
|
-
hostProjectName = CONFIG.hostProjectName || hostProjectName || null;
|
|
470
|
-
console.log("[ANALYTICS] Check if Analytics enabled");
|
|
471
|
-
enabled = isEnabled();
|
|
472
|
-
if (enabled) {
|
|
473
|
-
console.log("[ANALYTICS] Display Tracker Popup");
|
|
474
|
-
CONFIG.showPopUp && showTrackingPopup();
|
|
475
|
-
console.log("[ANALYTICS] Hook Event Trackers");
|
|
476
|
-
hookTrackers();
|
|
477
|
-
console.log('[ANALYTICS] Hook Handlers to flush events (use when submissionStrategy is configured as "DEFER"');
|
|
478
|
-
hookFlushHandlers(CONFIG.submissionStrategy);
|
|
479
|
-
console.log("[ANALYTICS] Find User Location Details");
|
|
480
|
-
populateLocationDetails();
|
|
481
|
-
console.log("[ANALYTICS] Initiate Session and Anonymous User ID");
|
|
482
|
-
const anonId = generateAnonymousId();
|
|
483
|
-
console.log("Tracking User as", anonId);
|
|
484
|
-
startSession();
|
|
485
|
-
window.addEventListener("load", function () {
|
|
486
|
-
console.log("[ANALYTICS] Logging page load");
|
|
487
|
-
trackEvent("PAGE");
|
|
488
|
-
});
|
|
489
|
-
window.addEventListener("popstate", (event) => {
|
|
490
|
-
const url = window.location.href;
|
|
491
|
-
trackEvent("NAV", { url });
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
else {
|
|
495
|
-
console.warn("[ANALYTICS] Analytics blocked by client, or disabled by configuration!");
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
function init(config) {
|
|
500
|
-
try {
|
|
501
|
-
environment = getEnvironmentType();
|
|
502
|
-
runtime = getEnvironment();
|
|
503
|
-
const projectName = config && config.hostProjectName;
|
|
504
|
-
if (projectName) {
|
|
505
|
-
hostProjectName = projectName;
|
|
506
|
-
loadAnalytics(config);
|
|
507
|
-
}
|
|
508
|
-
else {
|
|
509
|
-
getHostProjectName()
|
|
510
|
-
.then((projectName) => {
|
|
511
|
-
hostProjectName = projectName;
|
|
512
|
-
if (config) {
|
|
513
|
-
loadAnalytics(config);
|
|
514
|
-
}
|
|
515
|
-
else {
|
|
516
|
-
loadConfiguration().then((config) => {
|
|
517
|
-
loadAnalytics(config);
|
|
518
|
-
});
|
|
519
|
-
}
|
|
520
|
-
})
|
|
521
|
-
.catch((err) => {
|
|
522
|
-
console.error("[ANALYTICS] Couldn't determine host project name, no events will be logged!");
|
|
523
|
-
});
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
catch (e) {
|
|
527
|
-
console.log("[ANALYTICS]", e);
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
function logout() {
|
|
531
|
-
if (user) {
|
|
532
|
-
user = null;
|
|
533
|
-
generateAnonymousId();
|
|
534
|
-
}
|
|
535
|
-
terminateSession();
|
|
536
|
-
}
|
|
537
|
-
export { enabled as analyticsEnabled, init, identify, getEnvironmentType, getEnvironment, loadConfiguration, logout, trackEvent, trackPageView, trackError, enableTracking, generateAnonymousId, sendHostProjectName, getSessionId, startSession, };
|
package/constants.d.ts
DELETED
package/constants.js
DELETED
package/flush.d.ts
DELETED
package/flush.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { sendBulkData } from "./analytics";
|
|
2
|
-
const MAX_EVENTS = 100;
|
|
3
|
-
const FLUSH_INTERVAL = 15000;
|
|
4
|
-
let events = [];
|
|
5
|
-
export function queueEvent(event) {
|
|
6
|
-
events.push(event);
|
|
7
|
-
if (events.length >= MAX_EVENTS) {
|
|
8
|
-
flushEvents();
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
function flushEvents() {
|
|
12
|
-
sendBulkData(events, () => {
|
|
13
|
-
events = [];
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
function handleBeforeUnload() {
|
|
17
|
-
if (events.length > 0) {
|
|
18
|
-
flushEvents();
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
function handleVisibilityChange() {
|
|
22
|
-
if (document.visibilityState === "hidden" && events.length > 0) {
|
|
23
|
-
flushEvents();
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
export function hookFlushHandlers(submissionStrategy = "ONEVENT") {
|
|
27
|
-
if (typeof window !== "undefined" && submissionStrategy === "DEFER") {
|
|
28
|
-
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
29
|
-
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
30
|
-
setInterval(() => {
|
|
31
|
-
if (events.length > 0) {
|
|
32
|
-
flushEvents();
|
|
33
|
-
}
|
|
34
|
-
}, FLUSH_INTERVAL);
|
|
35
|
-
}
|
|
36
|
-
}
|
package/global-modules.d.ts
DELETED
package/helper.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function isArClient(name: string | null): boolean;
|
package/helper.js
DELETED
package/index.d.ts
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { init, identify, getEnvironment, getEnvironmentType, trackEvent, trackPageView, trackError, enableTracking, generateAnonymousId, sendHostProjectName, getSessionId, startSession } from "./analytics";
|
|
2
|
-
export { init, identify, getEnvironment, getEnvironmentType, trackEvent, trackPageView, trackError, enableTracking, generateAnonymousId, sendHostProjectName, getSessionId, startSession, };
|
package/index.interface.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export interface User {
|
|
2
|
-
email: string;
|
|
3
|
-
}
|
|
4
|
-
export interface Event {
|
|
5
|
-
eventType: string;
|
|
6
|
-
timestamp?: Date;
|
|
7
|
-
region?: string;
|
|
8
|
-
address?: string;
|
|
9
|
-
coordinates?: {
|
|
10
|
-
latitude: number;
|
|
11
|
-
longitude: number;
|
|
12
|
-
};
|
|
13
|
-
[key: string]: any;
|
|
14
|
-
}
|
|
15
|
-
export interface ConfigType {
|
|
16
|
-
apiKey?: string;
|
|
17
|
-
analyticsLogEndpoint?: string;
|
|
18
|
-
analyticsTagEndpoint?: string;
|
|
19
|
-
hostProjectName?: string;
|
|
20
|
-
trackEvents?: Array<string>;
|
|
21
|
-
submissionStrategy?: SubmissionStrategy;
|
|
22
|
-
showPopUp?: boolean;
|
|
23
|
-
}
|
|
24
|
-
export type SubmissionStrategy = "ONEVENT" | "DEFER";
|
|
25
|
-
export type objType = {
|
|
26
|
-
[key: string]: any;
|
|
27
|
-
};
|
|
28
|
-
export type EVENT_TYPES = "CLICK" | "SUBMIT" | "SCROLL" | string;
|
package/index.interface.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/index.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { init, identify, getEnvironment, getEnvironmentType, trackEvent, trackPageView, trackError, enableTracking, generateAnonymousId, sendHostProjectName, getSessionId, startSession, } from "./analytics";
|
|
2
|
-
document.addEventListener("DOMContentLoaded", function (event) {
|
|
3
|
-
const environment = getEnvironment();
|
|
4
|
-
console.info("[ANALYTICS] Idenfitied environment: ", environment);
|
|
5
|
-
if (!environment || environment === "development") {
|
|
6
|
-
console.info("[ANALYTICS] Attempting to auto-load analytics configurations from environment...");
|
|
7
|
-
init();
|
|
8
|
-
}
|
|
9
|
-
else {
|
|
10
|
-
console.info("[ANALYTICS] Identified non-dev environment, analytics auto load wouldn't be attempted.");
|
|
11
|
-
}
|
|
12
|
-
});
|
|
13
|
-
export { init, identify, getEnvironment, getEnvironmentType, trackEvent, trackPageView, trackError, enableTracking, generateAnonymousId, sendHostProjectName, getSessionId, startSession, };
|
package/location.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export declare function ipLookup(): void;
|
|
2
|
-
export declare function success(position: any, callback: Function): void;
|
|
3
|
-
export declare function error(): void;
|
|
4
|
-
declare const localTimeRegion: string;
|
|
5
|
-
declare const localTime: string;
|
|
6
|
-
export { localTimeRegion, localTime };
|
package/location.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import jstz from "jstz";
|
|
2
|
-
export function ipLookup() {
|
|
3
|
-
fetch("https://extreme-ip-lookup.com/json/")
|
|
4
|
-
.then((res) => res.json())
|
|
5
|
-
.then((response) => {
|
|
6
|
-
fallbackProcess(response);
|
|
7
|
-
})
|
|
8
|
-
.catch(() => {
|
|
9
|
-
console.log("We could not find your location");
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
export function success(position, callback) {
|
|
13
|
-
const latitude = position.coords.latitude;
|
|
14
|
-
const longitude = position.coords.longitude;
|
|
15
|
-
reverseGeocodingWithGoogle(latitude, longitude, callback);
|
|
16
|
-
}
|
|
17
|
-
export function error() {
|
|
18
|
-
console.log("Unable to retrieve your location");
|
|
19
|
-
}
|
|
20
|
-
function reverseGeocodingWithGoogle(latitude, longitude, callback) {
|
|
21
|
-
fetch(`https://maps.googleapis.com/maps/api/geocode/json?
|
|
22
|
-
latlng=${latitude},${longitude}&key={GOOGLE_MAP_KEY}`)
|
|
23
|
-
.then((res) => res.json())
|
|
24
|
-
.then((response) => {
|
|
25
|
-
callback ? callback(response) : processUserData(response);
|
|
26
|
-
})
|
|
27
|
-
.catch((status) => {
|
|
28
|
-
ipLookup();
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
function processUserData(response) {
|
|
32
|
-
console.log(response.results[0].formatted_address);
|
|
33
|
-
}
|
|
34
|
-
function fallbackProcess(response) {
|
|
35
|
-
const address = document.querySelector(".address");
|
|
36
|
-
address.innerText = `${response.city}, ${response.country}`;
|
|
37
|
-
}
|
|
38
|
-
const localTimeRegion = jstz.determine().name();
|
|
39
|
-
const localTime = new Date().toLocaleString("en-US", {
|
|
40
|
-
timeZone: localTimeRegion,
|
|
41
|
-
});
|
|
42
|
-
export { localTimeRegion, localTime };
|
package/session.d.ts
DELETED
package/session.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import Cookies from "js-cookie";
|
|
2
|
-
import { v4 as uuidv4 } from "uuid";
|
|
3
|
-
const SESSION_COOKIE_NAME = "ar-session-id";
|
|
4
|
-
const SESSION_EXPIRATION_TIME = 30;
|
|
5
|
-
let localStorageTimeout;
|
|
6
|
-
function generateSessionId() {
|
|
7
|
-
return uuidv4();
|
|
8
|
-
}
|
|
9
|
-
export function startSession() {
|
|
10
|
-
const sessionId = generateSessionId();
|
|
11
|
-
const expirationDate = new Date();
|
|
12
|
-
let tabId = sessionStorage.getItem("tabId");
|
|
13
|
-
if (!tabId) {
|
|
14
|
-
const timestamp = expirationDate.getTime();
|
|
15
|
-
tabId = `${uuidv4()}-${timestamp}`;
|
|
16
|
-
sessionStorage.setItem("tabId", tabId);
|
|
17
|
-
}
|
|
18
|
-
const cookieName = `${SESSION_COOKIE_NAME}-${tabId}`;
|
|
19
|
-
refreshSessionId(sessionId, cookieName);
|
|
20
|
-
return sessionId;
|
|
21
|
-
}
|
|
22
|
-
function refreshSessionId(sessionId, cookieName) {
|
|
23
|
-
const expirationDate = new Date();
|
|
24
|
-
expirationDate.setMinutes(expirationDate.getMinutes() + SESSION_EXPIRATION_TIME);
|
|
25
|
-
try {
|
|
26
|
-
Cookies.set(cookieName, sessionId, { expires: expirationDate });
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
clearTimeout(localStorageTimeout);
|
|
30
|
-
localStorageTimeout = setTimeout(() => localStorage.removeItem(cookieName), SESSION_EXPIRATION_TIME * 1000);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
export function getSessionId() {
|
|
34
|
-
let sessionId;
|
|
35
|
-
const tabId = sessionStorage.getItem("tabId");
|
|
36
|
-
if (!tabId) {
|
|
37
|
-
return startSession();
|
|
38
|
-
}
|
|
39
|
-
const cookieName = `${SESSION_COOKIE_NAME}-${tabId}`;
|
|
40
|
-
sessionId = Cookies.get(cookieName);
|
|
41
|
-
if (!sessionId) {
|
|
42
|
-
sessionId = localStorage.getItem(cookieName);
|
|
43
|
-
}
|
|
44
|
-
if (!sessionId) {
|
|
45
|
-
return startSession();
|
|
46
|
-
}
|
|
47
|
-
refreshSessionId(sessionId, cookieName);
|
|
48
|
-
return sessionId;
|
|
49
|
-
}
|
|
50
|
-
export function extendSession() {
|
|
51
|
-
const tabId = sessionStorage.getItem("tabId");
|
|
52
|
-
if (!tabId) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
const cookieName = `${SESSION_COOKIE_NAME}-${tabId}`;
|
|
56
|
-
let sessionId = Cookies.get(cookieName);
|
|
57
|
-
if (!sessionId) {
|
|
58
|
-
sessionId = localStorage.getItem(cookieName);
|
|
59
|
-
}
|
|
60
|
-
if (sessionId) {
|
|
61
|
-
refreshSessionId(sessionId, cookieName);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
export function terminateSession() {
|
|
65
|
-
const tabId = sessionStorage.getItem("tabId");
|
|
66
|
-
if (!tabId) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
const cookieName = `${SESSION_COOKIE_NAME}-${tabId}`;
|
|
70
|
-
if (typeof window !== "undefined" && window.Cookies) {
|
|
71
|
-
Cookies.remove(cookieName);
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
localStorage.removeItem(cookieName);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"root":["../analytics.ts","../constants.ts","../flush.ts","../global-modules.d.ts","../helper.ts","../index.interface.ts","../index.ts","../location.ts","../session.ts"],"version":"5.8.2"}
|