@availity/analytics-core
Version:
Analytics base configuration for sdk-js
371 lines (363 loc) • 13.6 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __objRest = (source, exclude) => {
var target = {};
for (var prop in source)
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
target[prop] = source[prop];
if (source != null && __getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(source)) {
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
target[prop] = source[prop];
}
return target;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
// src/index.js
var index_exports = {};
__export(index_exports, {
AvAnalytics: () => AvAnalytics,
AvAnalyticsPlugin: () => AvAnalyticsPlugin,
AvDmaAnalytics: () => AvDmaAnalytics,
AvSplunkAnalytics: () => AvSplunkAnalytics,
AvTelemetryAnalytics: () => AvTelemetryAnalytics
});
module.exports = __toCommonJS(index_exports);
// src/util.js
var isLeftClickEvent = (event) => event.button === 0;
var isModifiedEvent = (event) => !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
var trackMap = {
select: ["focus", "blur"],
textarea: ["focus", "blur"],
input: ["focus", "blur"],
default: ["click"]
};
var isValidEventTypeOnTarget = (event) => (trackMap[event.target.nodeName.toLowerCase()] || trackMap.default).indexOf(event.type) > -1;
var isPluginEnabled = (plugin) => typeof plugin.isEnabled === "function" ? plugin.isEnabled() : plugin.isEnabled;
var camelCase = (str) => str.replaceAll(/-([\da-z])/gi, (match, char) => char.toUpperCase());
var getComposedPath = (node) => {
let parent;
if (node.parentNode) {
parent = node.parentNode;
} else if (node.host) {
parent = node.host;
} else if (node.defaultView) {
parent = node.defaultView;
}
if (parent !== void 0) {
return [node, ...getComposedPath(parent)];
}
return [node];
};
// src/analytics.js
var AvAnalytics = class {
constructor(plugins, promise = Promise, pageTracking, autoTrack = true, options = {}) {
__publicField(this, "startAutoTrack", () => {
document.body.addEventListener("click", this.handleEvent, true);
document.body.addEventListener("focus", this.handleEvent, true);
document.body.addEventListener("blur", this.handleEvent, true);
});
__publicField(this, "stopAutoTrack", () => {
document.body.removeEventListener("click", this.handleEvent, true);
document.body.removeEventListener("focus", this.handleEvent, true);
document.body.removeEventListener("blur", this.handleEvent, true);
});
__publicField(this, "handleEvent", (event) => {
if (this.invalidEvent(event)) {
return;
}
const target = event.target || event.srcElement;
const path = getComposedPath(event.target);
let analyticAttrs = {};
if (this.recursive) {
for (const pth of path.reverse()) {
const attrs = this.getAnalyticAttrs(pth);
analyticAttrs = __spreadValues(__spreadValues({}, analyticAttrs), attrs);
if (Object.keys(attrs).length > 0) {
analyticAttrs.elemId = pth.getAttribute("id") || pth.getAttribute("name") || void 0;
}
}
} else {
analyticAttrs = this.getAnalyticAttrs(target);
}
const actions = analyticAttrs ? this.eventModifiers.filter((mod) => analyticAttrs[mod] === event.type) : [];
if (Object.keys(analyticAttrs).length === 0 || this.recursive && actions.length === 0 || actions.length === 0) {
return;
}
analyticAttrs.action = analyticAttrs.action || event.type;
analyticAttrs.event = event.type;
analyticAttrs.elemId = analyticAttrs.elemId || target.getAttribute("id") || target.getAttribute("name") || void 0;
if (analyticAttrs.elemId === void 0) {
delete analyticAttrs.elemId;
}
for (const key of actions) {
if (key !== "action" && key !== "event") {
delete analyticAttrs[key];
}
}
this.trackEvent(analyticAttrs);
});
__publicField(this, "invalidEvent", (event) => isModifiedEvent(event) || event.type === "click" && !isLeftClickEvent(event) || !isValidEventTypeOnTarget(event));
__publicField(this, "getAnalyticAttrs", (elem) => {
if (!elem.attributes) return {};
const attrs = elem.attributes;
const analyticAttrs = {};
if (elem.nodeType === 1) {
for (let i = attrs.length - 1; i >= 0; i--) {
const { name } = attrs[i];
if (name.indexOf(`${this.attributePrefix}-`) === 0) {
const camelName = camelCase(name.slice(this.attributePrefix.length + 1));
analyticAttrs[camelName] = elem.getAttribute(name);
}
}
if (this.hasLogPlugin) {
const overridesKeys = Object.keys(analyticAttrs).filter((key) => key.startsWith("overrides"));
if (overridesKeys.length > 0) {
analyticAttrs.overrides = {};
for (const key of overridesKeys) {
const nestedKey = key.slice(9);
const finalKey = nestedKey.charAt(0).toLowerCase() + nestedKey.slice(1);
analyticAttrs.overrides[finalKey] = analyticAttrs[key];
delete analyticAttrs[key];
}
}
}
}
return analyticAttrs;
});
__publicField(this, "startPageTracking", () => {
if (!this.pageListener) {
this.pageListener = this.trackPageView;
window.addEventListener("hashchange", this.pageListener, false);
}
});
__publicField(this, "stopPageTracking", () => {
if (this.pageListener) {
window.removeEventListener("hashchange", this.pageListener, false);
delete this.pageListener;
}
});
__publicField(this, "init", () => {
this.setPageTracking();
for (const plugin of this.plugins) {
if (isPluginEnabled(plugin) && typeof plugin.init === "function") {
plugin.init();
}
}
});
__publicField(this, "setPageTracking", (value) => {
if (value != void 0) {
this.pageTracking = !!value;
}
const canPageTrack = typeof this.startPageTracking === "function" && typeof this.stopPageTracking === "function";
if (canPageTrack && this.pageTracking !== this.isPageTracking) {
if (this.pageTracking) {
this.startPageTracking();
} else {
this.stopPageTracking();
}
this.isPageTracking = this.pageTracking;
}
});
__publicField(this, "trackEvent", (properties) => {
const promises = [];
properties.url = properties.url || window.location.href || "N/A";
for (const plugin of this.plugins) {
const props = __spreadValues({}, properties);
if (isPluginEnabled(plugin) && typeof plugin.trackEvent === "function") {
promises.push(plugin.trackEvent(props));
}
}
return this.Promise.all(promises);
});
__publicField(this, "trackPageView", (url) => {
if (typeof url === "object") {
url = url.newURL;
}
url = url || window.location.href;
const promises = [];
for (const plugin of this.plugins) {
if (isPluginEnabled(plugin) && typeof plugin.trackPageView === "function") {
promises.push(plugin.trackPageView(url));
}
}
return this.Promise.all(promises);
});
if (!plugins || !promise) {
throw new Error("[plugins] and [promise] must be defined");
}
this.plugins = Array.isArray(plugins) ? plugins : [plugins];
this.pageTracking = !!pageTracking;
if (options.eventModifiers) {
this.eventModifiers = Array.isArray(options.eventModifiers) ? options.eventModifiers : [options.eventModifiers];
} else {
this.eventModifiers = ["action"];
}
this.Promise = promise;
this.recursive = !!options.recursive;
this.attributePrefix = options.attributePrefix || "data-analytics";
this.isPageTracking = false;
this.hasInit = false;
this.hasLogPlugin = this.plugins.some((plugin) => {
var _a, _b;
const apiName = (_b = (_a = plugin.AvLogMessages) == null ? void 0 : _a.defaultConfig) == null ? void 0 : _b.name;
return apiName === "appl/analytics/log" || apiName === "spc/analytics/log";
});
if (autoTrack) {
this.startAutoTrack();
}
}
};
// src/plugin.js
var AvAnalyticsPlugin = class {
constructor(enabled = true) {
this.enabled = !!enabled;
}
trackEvent() {
}
trackPageView() {
}
isEnabled() {
return this.enabled;
}
};
// src/splunk.js
var AvSplunkAnalytics = class extends AvAnalyticsPlugin {
constructor(AvLogMessages, enabled) {
super(enabled);
this.AvLogMessages = AvLogMessages;
}
trackEvent(properties) {
properties.level = properties.level || "info";
return this.AvLogMessages[properties.level](properties);
}
trackPageView(url) {
return this.trackEvent({ event: "page", url });
}
};
// src/telemetry.js
var import_uuid = require("uuid");
var AvTelemetryAnalytics = class extends AvAnalyticsPlugin {
constructor(AvLogMessages, enabled, source_system, contact, owner, sessionId) {
super(enabled);
this.AvLogMessages = AvLogMessages;
if (!source_system) throw new Error("source_system is required");
if (!contact) throw new Error("contact is required");
if (!owner) throw new Error("owner is required");
this.source_system = source_system;
this.contact = contact;
this.owner = owner;
this.sessionId = sessionId || (0, import_uuid.v4)();
}
trackEvent(_a) {
var _b = _a, { customerId, level, payerId } = _b, properties = __objRest(_b, ["customerId", "level", "payerId"]);
const payload = {
customerId,
contact: this.contact,
source_system: this.source_system,
version: "v1",
sessionId: this.sessionId,
owner: this.owner,
telemetryBody: {
level: level || "info",
entries: __spreadValues({}, properties)
}
};
if (payerId) payload.payerId = payerId;
return this.AvLogMessages[payload.telemetryBody.level](payload);
}
trackPageView(url) {
return this.trackEvent({
event: "page",
action: "load",
category: this.source_system,
label: "page-load",
url,
customerId: "0000"
});
}
};
// src/dma.js
var yup = __toESM(require("yup"));
var schema = yup.object().shape({
level: yup.string().optional(),
applicationId: yup.string().optional(),
payerSpaceId: yup.string().optional(),
label: yup.string().optional(),
appName: yup.string().optional(),
category: yup.string().optional(),
section: yup.string().optional(),
url: yup.string().optional(),
value: yup.string().optional(),
raw: yup.string().optional(),
feed: yup.string().optional(),
feedback: yup.string().optional(),
feedbackName: yup.string().optional(),
additionalFeedback: yup.string().optional(),
smile: yup.string().optional(),
surveyId: yup.string().optional()
}).noUnknown(true);
var AvDmaAnalytics = class extends AvAnalyticsPlugin {
constructor(AvLogMessages, enabled) {
super(enabled);
this.AvLogMessages = AvLogMessages;
}
trackEvent(properties) {
properties.level = properties.level || "info";
schema.validateSync(properties, {
strict: true
});
return this.AvLogMessages[properties.level](properties);
}
trackPageView(url) {
return this.trackEvent({ event: "page", url });
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
AvAnalytics,
AvAnalyticsPlugin,
AvDmaAnalytics,
AvSplunkAnalytics,
AvTelemetryAnalytics
});