You're Invited: Meet the Socket team at BSidesSF and RSAC - April 27 - May 1.RSVP
Socket
Sign inDemoInstall
Socket

@esri/telemetry

Package Overview
Dependencies
Maintainers
44
Versions
86
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@esri/telemetry - npm Package Compare versions

Comparing version

to
7.0.3

164

dist/esm/index.js

@@ -35,7 +35,26 @@ import sha256 from 'crypto-js/sha256.js';

this.debug = options.debug;
this.disabled = shouldDisableTracking(options);
this.suppressDisabledWarnings = options.suppressDisabledWarnings;
this.logger = options.logger || console;
if (this.disabled) {
this.logger.warn('Telemetry Disabled');
// if passed privacy settings, use them
if (options.userPrivacySettings) {
this._userPrivacySettings = options.userPrivacySettings;
}
// if consent is required, but no privacy settings are passed, create them
// this basically defaults to no tracking
if (options.requireConsent && !options.userPrivacySettings) {
this._userPrivacySettings = {
accepted: false,
performance: false,
targeting: false,
functional: false,
id: generateGUID(),
timestamp: Date.now(),
};
options.userPrivacySettings = this._userPrivacySettings;
}
// Check if tracking should be wholesale disabled
this.disabled = shouldDisableTracking(options);
if (this.disabled && !this.suppressDisabledWarnings) {
this.logger.info('Telemetry Disabled');
}
const user = ((_a = options.portal) === null || _a === void 0 ? void 0 : _a.user) || options.user;

@@ -50,13 +69,46 @@ if (user) {

initializeTrackers() {
const userSettings = this._userPrivacySettings;
// Reset trackers
this.trackers = [];
// Depending on the user settings, we may not want to load all trackers
if (this.options.plugins) {
this.trackers.push(...this.options.plugins);
if (userSettings) {
// ------------------------------------------------------
// Rules:
// if settings.performance: true, we can load the Esri Tracker
// if settings.{performance,targeting,functional}: true, we can load the 3rd party trackers
// ------------------------------------------------------
if (userSettings === null || userSettings === void 0 ? void 0 : userSettings.performance) {
this.trackers.push(...this.options.plugins.filter((tracker) => tracker.name === 'amazon'));
}
if ((userSettings === null || userSettings === void 0 ? void 0 : userSettings.performance) &&
(userSettings === null || userSettings === void 0 ? void 0 : userSettings.targeting) &&
(userSettings === null || userSettings === void 0 ? void 0 : userSettings.functional)) {
const thirdPartyTrackers = [
'adobe-analytics',
'google',
'googleAnalytics',
'siteimprove',
];
this.trackers.push(...this.options.plugins.filter((tracker) => thirdPartyTrackers.includes(tracker.name)));
}
}
else {
// enable all trackers
this.trackers.push(...this.options.plugins);
}
}
if (!this.trackers.length) {
this.logger.error(new Error('No trackers configured'));
// Just log that no trackers are configured
// this is likely due to the user privacy settings
// this.logger.error(new Error('No trackers configured'));
this.logger.info('No trackers configured');
}
}
getScriptTags() {
return this.trackers.map((tracker) => {
return this.trackers
.map((tracker) => {
return tracker.getScriptTags && tracker.getScriptTags();
}).join('');
})
.join('');
}

@@ -86,10 +138,39 @@ async init() {

}
/**
* Allow clients to update the user privacy settings
* after the telemetry instance has been created.
* Host app is responsible for persisting the settings
* into localStorage or cookies, depending on their requirements
*/
async updateUserPrivacySettings(newSettings) {
const { performance, targeting, functional } = this._userPrivacySettings;
// decide if the new settings are more restrictive than the previous ones
// if so we need to return `{reload: true}` so that the page can be reloaded
// to ensure that the trackers are re-initialized
const reload = (!newSettings.performance && performance) ||
(!newSettings.targeting && targeting) ||
(!newSettings.functional && functional);
// hold into it
this._userPrivacySettings = newSettings;
// we need to re-initialize the trackers based on the new settings
if (!reload) {
// if the new settings are more permissive than the old
// we know that at least some trackers are enabled,
// thus telemetry as a whole is not disabled
this.disabled = false;
// re-initialize the trackers
this.initializeTrackers();
// and initialize them because it is possible they have not been
await this.init();
}
return { reload };
}
logPageView(page, event = {}, options = {}) {
if (this.disabled) {
this.logger.warn('Page view was not logged because telemetry is disabled.');
if (this.disabled && !this.suppressDisabledWarnings) {
this.logger.info('Page view was not logged because telemetry is disabled.');
return false;
}
const enabledTrackers = this.trackers.filter(({ disabled }) => !disabled);
const enabledTrackers = this.trackers.filter(({ disabled, hasError }) => !disabled && !hasError);
if (!enabledTrackers.length) {
this.logger.warn('Page view was not logged because no enabled telemetry-plugins are registered.');
this.logger.info('Page view was not logged because no enabled telemetry-plugins are registered.');
return false;

@@ -108,9 +189,9 @@ }

logEvent(event, options = {}) {
if (this.disabled) {
this.logger.warn('Event was not logged because telemetry is disabled.');
if (this.disabled && !this.suppressDisabledWarnings) {
this.logger.info('Event was not logged because telemetry is disabled.');
return false;
}
const enabledTrackers = this.trackers.filter(({ disabled }) => !disabled);
const enabledTrackers = this.trackers.filter(({ disabled, hasError }) => !disabled && !hasError);
if (!enabledTrackers.length) {
this.logger.warn('Event was not logged because no enabled telemetry-plugins are registered.');
this.logger.info('Event was not logged because no enabled telemetry-plugins are registered.');
return false;

@@ -224,6 +305,14 @@ }

}
/**
* Disable a tracker. This does not deterministically unload
* the tracker from the page, but it does prevent events from
* this library from being sent to it. Thus, if you need to ensure
* that an instantiated tracker is fully disabled, you should reload
* the application (thus, the `reload` property on the return value from `updateUserPrivacySettings`)
* @param trackerName
*/
disableTracker(trackerName) {
var _a;
const tracker = this.trackers.find(({ name }) => name === trackerName);
if (tracker) {
if (tracker && !tracker.hasError) {
tracker.disabled = true;

@@ -233,6 +322,10 @@ (_a = tracker.disable) === null || _a === void 0 ? void 0 : _a.call(tracker);

}
/**
* Enable a specific tracker
* @param trackerName
*/
enableTracker(trackerName) {
var _a;
const tracker = this.trackers.find(({ name }) => name === trackerName);
if (tracker) {
if (tracker && !tracker.hasError) {
tracker.disabled = false;

@@ -265,2 +358,39 @@ (_a = tracker.enable) === null || _a === void 0 ? void 0 : _a.call(tracker);

}
// /**
// * Get the privacy settings from local storage or use the default values
// * @returns
// */
// function getPrivacySettings(win?: Window): IPrivacySettings {
// // Default settings, which is the same as if they rejected all tracking
// let settings: IPrivacySettings = {
// accepted: false,
// performance: false,
// targeting: false,
// functional: false,
// id: generateGUID(),
// timestamp: Date.now(),
// };
// if (win?.localStorage) {
// // try to get the privacy settings from local storage
// const storedSettings = win.localStorage.getItem('esri_privacy_settings');
// if (storedSettings) {
// settings = JSON.parse(storedSettings);
// } else {
// // store the default settings in local storage
// win.localStorage.setItem(
// 'esri_privacy_settings',
// JSON.stringify(settings),
// );
// }
// }
// return settings;
// }
// Created by github copilot
function generateGUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0;
const v = c === 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}
//# sourceMappingURL=index.js.map
export function shouldDisableTracking(options = {}) {
const { disabled, portal } = options;
const { disabled, portal, userPrivacySettings } = options;
// if user has turned off all tracking, then we disable tracking
if ((userPrivacySettings === null || userPrivacySettings === void 0 ? void 0 : userPrivacySettings.functional) === false &&
(userPrivacySettings === null || userPrivacySettings === void 0 ? void 0 : userPrivacySettings.performance) === false &&
(userPrivacySettings === null || userPrivacySettings === void 0 ? void 0 : userPrivacySettings.targeting) === false) {
return true;
}
if (disabled || (portal === null || portal === void 0 ? void 0 : portal.eueiEnabled) === false) {
return true;
}
if (!portal || hasEueiEnabledAndIsMemberOfOrg(portal) || isRegisteredUserWithoutOrgInUSA(portal) || isAnonymousUserInUSA(portal)) {
if (!portal ||
hasEueiEnabledAndIsMemberOfOrg(portal) ||
isRegisteredUserWithoutOrgInUSA(portal) ||
isAnonymousUserInUSA(portal)) {
return false;

@@ -8,0 +17,0 @@ }

@@ -39,7 +39,26 @@ "use strict";

this.debug = options.debug;
this.disabled = (0, should_disable_tracking_1.shouldDisableTracking)(options);
this.suppressDisabledWarnings = options.suppressDisabledWarnings;
this.logger = options.logger || console;
if (this.disabled) {
this.logger.warn('Telemetry Disabled');
// if passed privacy settings, use them
if (options.userPrivacySettings) {
this._userPrivacySettings = options.userPrivacySettings;
}
// if consent is required, but no privacy settings are passed, create them
// this basically defaults to no tracking
if (options.requireConsent && !options.userPrivacySettings) {
this._userPrivacySettings = {
accepted: false,
performance: false,
targeting: false,
functional: false,
id: generateGUID(),
timestamp: Date.now(),
};
options.userPrivacySettings = this._userPrivacySettings;
}
// Check if tracking should be wholesale disabled
this.disabled = (0, should_disable_tracking_1.shouldDisableTracking)(options);
if (this.disabled && !this.suppressDisabledWarnings) {
this.logger.info('Telemetry Disabled');
}
const user = ((_a = options.portal) === null || _a === void 0 ? void 0 : _a.user) || options.user;

@@ -54,13 +73,46 @@ if (user) {

initializeTrackers() {
const userSettings = this._userPrivacySettings;
// Reset trackers
this.trackers = [];
// Depending on the user settings, we may not want to load all trackers
if (this.options.plugins) {
this.trackers.push(...this.options.plugins);
if (userSettings) {
// ------------------------------------------------------
// Rules:
// if settings.performance: true, we can load the Esri Tracker
// if settings.{performance,targeting,functional}: true, we can load the 3rd party trackers
// ------------------------------------------------------
if (userSettings === null || userSettings === void 0 ? void 0 : userSettings.performance) {
this.trackers.push(...this.options.plugins.filter((tracker) => tracker.name === 'amazon'));
}
if ((userSettings === null || userSettings === void 0 ? void 0 : userSettings.performance) &&
(userSettings === null || userSettings === void 0 ? void 0 : userSettings.targeting) &&
(userSettings === null || userSettings === void 0 ? void 0 : userSettings.functional)) {
const thirdPartyTrackers = [
'adobe-analytics',
'google',
'googleAnalytics',
'siteimprove',
];
this.trackers.push(...this.options.plugins.filter((tracker) => thirdPartyTrackers.includes(tracker.name)));
}
}
else {
// enable all trackers
this.trackers.push(...this.options.plugins);
}
}
if (!this.trackers.length) {
this.logger.error(new Error('No trackers configured'));
// Just log that no trackers are configured
// this is likely due to the user privacy settings
// this.logger.error(new Error('No trackers configured'));
this.logger.info('No trackers configured');
}
}
getScriptTags() {
return this.trackers.map((tracker) => {
return this.trackers
.map((tracker) => {
return tracker.getScriptTags && tracker.getScriptTags();
}).join('');
})
.join('');
}

@@ -90,10 +142,39 @@ async init() {

}
/**
* Allow clients to update the user privacy settings
* after the telemetry instance has been created.
* Host app is responsible for persisting the settings
* into localStorage or cookies, depending on their requirements
*/
async updateUserPrivacySettings(newSettings) {
const { performance, targeting, functional } = this._userPrivacySettings;
// decide if the new settings are more restrictive than the previous ones
// if so we need to return `{reload: true}` so that the page can be reloaded
// to ensure that the trackers are re-initialized
const reload = (!newSettings.performance && performance) ||
(!newSettings.targeting && targeting) ||
(!newSettings.functional && functional);
// hold into it
this._userPrivacySettings = newSettings;
// we need to re-initialize the trackers based on the new settings
if (!reload) {
// if the new settings are more permissive than the old
// we know that at least some trackers are enabled,
// thus telemetry as a whole is not disabled
this.disabled = false;
// re-initialize the trackers
this.initializeTrackers();
// and initialize them because it is possible they have not been
await this.init();
}
return { reload };
}
logPageView(page, event = {}, options = {}) {
if (this.disabled) {
this.logger.warn('Page view was not logged because telemetry is disabled.');
if (this.disabled && !this.suppressDisabledWarnings) {
this.logger.info('Page view was not logged because telemetry is disabled.');
return false;
}
const enabledTrackers = this.trackers.filter(({ disabled }) => !disabled);
const enabledTrackers = this.trackers.filter(({ disabled, hasError }) => !disabled && !hasError);
if (!enabledTrackers.length) {
this.logger.warn('Page view was not logged because no enabled telemetry-plugins are registered.');
this.logger.info('Page view was not logged because no enabled telemetry-plugins are registered.');
return false;

@@ -112,9 +193,9 @@ }

logEvent(event, options = {}) {
if (this.disabled) {
this.logger.warn('Event was not logged because telemetry is disabled.');
if (this.disabled && !this.suppressDisabledWarnings) {
this.logger.info('Event was not logged because telemetry is disabled.');
return false;
}
const enabledTrackers = this.trackers.filter(({ disabled }) => !disabled);
const enabledTrackers = this.trackers.filter(({ disabled, hasError }) => !disabled && !hasError);
if (!enabledTrackers.length) {
this.logger.warn('Event was not logged because no enabled telemetry-plugins are registered.');
this.logger.info('Event was not logged because no enabled telemetry-plugins are registered.');
return false;

@@ -228,6 +309,14 @@ }

}
/**
* Disable a tracker. This does not deterministically unload
* the tracker from the page, but it does prevent events from
* this library from being sent to it. Thus, if you need to ensure
* that an instantiated tracker is fully disabled, you should reload
* the application (thus, the `reload` property on the return value from `updateUserPrivacySettings`)
* @param trackerName
*/
disableTracker(trackerName) {
var _a;
const tracker = this.trackers.find(({ name }) => name === trackerName);
if (tracker) {
if (tracker && !tracker.hasError) {
tracker.disabled = true;

@@ -237,6 +326,10 @@ (_a = tracker.disable) === null || _a === void 0 ? void 0 : _a.call(tracker);

}
/**
* Enable a specific tracker
* @param trackerName
*/
enableTracker(trackerName) {
var _a;
const tracker = this.trackers.find(({ name }) => name === trackerName);
if (tracker) {
if (tracker && !tracker.hasError) {
tracker.disabled = false;

@@ -270,2 +363,39 @@ (_a = tracker.enable) === null || _a === void 0 ? void 0 : _a.call(tracker);

}
// /**
// * Get the privacy settings from local storage or use the default values
// * @returns
// */
// function getPrivacySettings(win?: Window): IPrivacySettings {
// // Default settings, which is the same as if they rejected all tracking
// let settings: IPrivacySettings = {
// accepted: false,
// performance: false,
// targeting: false,
// functional: false,
// id: generateGUID(),
// timestamp: Date.now(),
// };
// if (win?.localStorage) {
// // try to get the privacy settings from local storage
// const storedSettings = win.localStorage.getItem('esri_privacy_settings');
// if (storedSettings) {
// settings = JSON.parse(storedSettings);
// } else {
// // store the default settings in local storage
// win.localStorage.setItem(
// 'esri_privacy_settings',
// JSON.stringify(settings),
// );
// }
// }
// return settings;
// }
// Created by github copilot
function generateGUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0;
const v = c === 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}
//# sourceMappingURL=index.js.map

@@ -5,7 +5,16 @@ "use strict";

function shouldDisableTracking(options = {}) {
const { disabled, portal } = options;
const { disabled, portal, userPrivacySettings } = options;
// if user has turned off all tracking, then we disable tracking
if ((userPrivacySettings === null || userPrivacySettings === void 0 ? void 0 : userPrivacySettings.functional) === false &&
(userPrivacySettings === null || userPrivacySettings === void 0 ? void 0 : userPrivacySettings.performance) === false &&
(userPrivacySettings === null || userPrivacySettings === void 0 ? void 0 : userPrivacySettings.targeting) === false) {
return true;
}
if (disabled || (portal === null || portal === void 0 ? void 0 : portal.eueiEnabled) === false) {
return true;
}
if (!portal || hasEueiEnabledAndIsMemberOfOrg(portal) || isRegisteredUserWithoutOrgInUSA(portal) || isAnonymousUserInUSA(portal)) {
if (!portal ||
hasEueiEnabledAndIsMemberOfOrg(portal) ||
isRegisteredUserWithoutOrgInUSA(portal) ||
isAnonymousUserInUSA(portal)) {
return false;

@@ -12,0 +21,0 @@ }

@@ -1,2 +0,2 @@

import { Attributes, EventData, TelemetryOptions, User, Workflow } from './types';
import { Attributes, EventData, IPrivacySettings, TelemetryOptions, User, Workflow } from './types';
export * from './utils';

@@ -9,3 +9,5 @@ export declare class Telemetry implements TelemetryCore<TelemetryOptions> {

private disabled;
private suppressDisabledWarnings;
private logger;
private _userPrivacySettings;
constructor(options: TelemetryOptions);

@@ -16,2 +18,11 @@ private initializeTrackers;

setUser(user?: string | User, orgType?: string): void;
/**
* Allow clients to update the user privacy settings
* after the telemetry instance has been created.
* Host app is responsible for persisting the settings
* into localStorage or cookies, depending on their requirements
*/
updateUserPrivacySettings(newSettings: IPrivacySettings): Promise<{
reload: boolean;
}>;
logPageView(page: string, event?: EventData, options?: TelemetryOptions): boolean;

@@ -29,3 +40,15 @@ logEvent(event: EventData, options?: TelemetryOptions): boolean;

preProcess(event?: EventData, options?: TelemetryOptions): Record<string, any>;
/**
* Disable a tracker. This does not deterministically unload
* the tracker from the page, but it does prevent events from
* this library from being sent to it. Thus, if you need to ensure
* that an instantiated tracker is fully disabled, you should reload
* the application (thus, the `reload` property on the return value from `updateUserPrivacySettings`)
* @param trackerName
*/
disableTracker(trackerName: string): void;
/**
* Enable a specific tracker
* @param trackerName
*/
enableTracker(trackerName: string): void;

@@ -32,0 +55,0 @@ }

@@ -32,4 +32,14 @@ export declare type GenericObject = {

debug?: boolean;
suppressDisabledWarnings?: boolean;
omitComplexData?: boolean;
logger?: ILogger;
/**
* If true, the system will not log any events until the user has accepted the privacy policy.
*/
requireConsent?: boolean;
/**
* Any existing privacy settings for the user. The host application is responsible for
* managing these settings via localStorage or cookies.
*/
userPrivacySettings?: IPrivacySettings;
}

@@ -39,2 +49,3 @@ export interface Tracker {

disabled?: boolean;
hasError?: boolean;
getScriptTags?(): string;

@@ -125,2 +136,10 @@ init(): Promise<void>;

}
export interface IPrivacySettings {
accepted: boolean;
performance: boolean;
targeting: boolean;
functional: boolean;
id: string;
timestamp: number;
}
export {};

@@ -1033,7 +1033,16 @@ (function (global, factory) {

function shouldDisableTracking(options = {}) {
const { disabled, portal } = options;
const { disabled, portal, userPrivacySettings } = options;
// if user has turned off all tracking, then we disable tracking
if ((userPrivacySettings === null || userPrivacySettings === void 0 ? void 0 : userPrivacySettings.functional) === false &&
(userPrivacySettings === null || userPrivacySettings === void 0 ? void 0 : userPrivacySettings.performance) === false &&
(userPrivacySettings === null || userPrivacySettings === void 0 ? void 0 : userPrivacySettings.targeting) === false) {
return true;
}
if (disabled || (portal === null || portal === void 0 ? void 0 : portal.eueiEnabled) === false) {
return true;
}
if (!portal || hasEueiEnabledAndIsMemberOfOrg(portal) || isRegisteredUserWithoutOrgInUSA(portal) || isAnonymousUserInUSA(portal)) {
if (!portal ||
hasEueiEnabledAndIsMemberOfOrg(portal) ||
isRegisteredUserWithoutOrgInUSA(portal) ||
isAnonymousUserInUSA(portal)) {
return false;

@@ -1217,7 +1226,26 @@ }

this.debug = options.debug;
this.disabled = shouldDisableTracking(options);
this.suppressDisabledWarnings = options.suppressDisabledWarnings;
this.logger = options.logger || console;
if (this.disabled) {
this.logger.warn('Telemetry Disabled');
// if passed privacy settings, use them
if (options.userPrivacySettings) {
this._userPrivacySettings = options.userPrivacySettings;
}
// if consent is required, but no privacy settings are passed, create them
// this basically defaults to no tracking
if (options.requireConsent && !options.userPrivacySettings) {
this._userPrivacySettings = {
accepted: false,
performance: false,
targeting: false,
functional: false,
id: generateGUID(),
timestamp: Date.now(),
};
options.userPrivacySettings = this._userPrivacySettings;
}
// Check if tracking should be wholesale disabled
this.disabled = shouldDisableTracking(options);
if (this.disabled && !this.suppressDisabledWarnings) {
this.logger.info('Telemetry Disabled');
}
const user = ((_a = options.portal) === null || _a === void 0 ? void 0 : _a.user) || options.user;

@@ -1232,13 +1260,46 @@ if (user) {

initializeTrackers() {
const userSettings = this._userPrivacySettings;
// Reset trackers
this.trackers = [];
// Depending on the user settings, we may not want to load all trackers
if (this.options.plugins) {
this.trackers.push(...this.options.plugins);
if (userSettings) {
// ------------------------------------------------------
// Rules:
// if settings.performance: true, we can load the Esri Tracker
// if settings.{performance,targeting,functional}: true, we can load the 3rd party trackers
// ------------------------------------------------------
if (userSettings === null || userSettings === void 0 ? void 0 : userSettings.performance) {
this.trackers.push(...this.options.plugins.filter((tracker) => tracker.name === 'amazon'));
}
if ((userSettings === null || userSettings === void 0 ? void 0 : userSettings.performance) &&
(userSettings === null || userSettings === void 0 ? void 0 : userSettings.targeting) &&
(userSettings === null || userSettings === void 0 ? void 0 : userSettings.functional)) {
const thirdPartyTrackers = [
'adobe-analytics',
'google',
'googleAnalytics',
'siteimprove',
];
this.trackers.push(...this.options.plugins.filter((tracker) => thirdPartyTrackers.includes(tracker.name)));
}
}
else {
// enable all trackers
this.trackers.push(...this.options.plugins);
}
}
if (!this.trackers.length) {
this.logger.error(new Error('No trackers configured'));
// Just log that no trackers are configured
// this is likely due to the user privacy settings
// this.logger.error(new Error('No trackers configured'));
this.logger.info('No trackers configured');
}
}
getScriptTags() {
return this.trackers.map((tracker) => {
return this.trackers
.map((tracker) => {
return tracker.getScriptTags && tracker.getScriptTags();
}).join('');
})
.join('');
}

@@ -1268,10 +1329,39 @@ async init() {

}
/**
* Allow clients to update the user privacy settings
* after the telemetry instance has been created.
* Host app is responsible for persisting the settings
* into localStorage or cookies, depending on their requirements
*/
async updateUserPrivacySettings(newSettings) {
const { performance, targeting, functional } = this._userPrivacySettings;
// decide if the new settings are more restrictive than the previous ones
// if so we need to return `{reload: true}` so that the page can be reloaded
// to ensure that the trackers are re-initialized
const reload = (!newSettings.performance && performance) ||
(!newSettings.targeting && targeting) ||
(!newSettings.functional && functional);
// hold into it
this._userPrivacySettings = newSettings;
// we need to re-initialize the trackers based on the new settings
if (!reload) {
// if the new settings are more permissive than the old
// we know that at least some trackers are enabled,
// thus telemetry as a whole is not disabled
this.disabled = false;
// re-initialize the trackers
this.initializeTrackers();
// and initialize them because it is possible they have not been
await this.init();
}
return { reload };
}
logPageView(page, event = {}, options = {}) {
if (this.disabled) {
this.logger.warn('Page view was not logged because telemetry is disabled.');
if (this.disabled && !this.suppressDisabledWarnings) {
this.logger.info('Page view was not logged because telemetry is disabled.');
return false;
}
const enabledTrackers = this.trackers.filter(({ disabled }) => !disabled);
const enabledTrackers = this.trackers.filter(({ disabled, hasError }) => !disabled && !hasError);
if (!enabledTrackers.length) {
this.logger.warn('Page view was not logged because no enabled telemetry-plugins are registered.');
this.logger.info('Page view was not logged because no enabled telemetry-plugins are registered.');
return false;

@@ -1290,9 +1380,9 @@ }

logEvent(event, options = {}) {
if (this.disabled) {
this.logger.warn('Event was not logged because telemetry is disabled.');
if (this.disabled && !this.suppressDisabledWarnings) {
this.logger.info('Event was not logged because telemetry is disabled.');
return false;
}
const enabledTrackers = this.trackers.filter(({ disabled }) => !disabled);
const enabledTrackers = this.trackers.filter(({ disabled, hasError }) => !disabled && !hasError);
if (!enabledTrackers.length) {
this.logger.warn('Event was not logged because no enabled telemetry-plugins are registered.');
this.logger.info('Event was not logged because no enabled telemetry-plugins are registered.');
return false;

@@ -1406,6 +1496,14 @@ }

}
/**
* Disable a tracker. This does not deterministically unload
* the tracker from the page, but it does prevent events from
* this library from being sent to it. Thus, if you need to ensure
* that an instantiated tracker is fully disabled, you should reload
* the application (thus, the `reload` property on the return value from `updateUserPrivacySettings`)
* @param trackerName
*/
disableTracker(trackerName) {
var _a;
const tracker = this.trackers.find(({ name }) => name === trackerName);
if (tracker) {
if (tracker && !tracker.hasError) {
tracker.disabled = true;

@@ -1415,6 +1513,10 @@ (_a = tracker.disable) === null || _a === void 0 ? void 0 : _a.call(tracker);

}
/**
* Enable a specific tracker
* @param trackerName
*/
enableTracker(trackerName) {
var _a;
const tracker = this.trackers.find(({ name }) => name === trackerName);
if (tracker) {
if (tracker && !tracker.hasError) {
tracker.disabled = false;

@@ -1447,2 +1549,39 @@ (_a = tracker.enable) === null || _a === void 0 ? void 0 : _a.call(tracker);

}
// /**
// * Get the privacy settings from local storage or use the default values
// * @returns
// */
// function getPrivacySettings(win?: Window): IPrivacySettings {
// // Default settings, which is the same as if they rejected all tracking
// let settings: IPrivacySettings = {
// accepted: false,
// performance: false,
// targeting: false,
// functional: false,
// id: generateGUID(),
// timestamp: Date.now(),
// };
// if (win?.localStorage) {
// // try to get the privacy settings from local storage
// const storedSettings = win.localStorage.getItem('esri_privacy_settings');
// if (storedSettings) {
// settings = JSON.parse(storedSettings);
// } else {
// // store the default settings in local storage
// win.localStorage.setItem(
// 'esri_privacy_settings',
// JSON.stringify(settings),
// );
// }
// }
// return settings;
// }
// Created by github copilot
function generateGUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0;
const v = c === 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}

@@ -1449,0 +1588,0 @@ exports.Telemetry = Telemetry;

@@ -1033,7 +1033,16 @@ (function (global, factory) {

function shouldDisableTracking(options = {}) {
const { disabled, portal } = options;
const { disabled, portal, userPrivacySettings } = options;
// if user has turned off all tracking, then we disable tracking
if ((userPrivacySettings === null || userPrivacySettings === void 0 ? void 0 : userPrivacySettings.functional) === false &&
(userPrivacySettings === null || userPrivacySettings === void 0 ? void 0 : userPrivacySettings.performance) === false &&
(userPrivacySettings === null || userPrivacySettings === void 0 ? void 0 : userPrivacySettings.targeting) === false) {
return true;
}
if (disabled || (portal === null || portal === void 0 ? void 0 : portal.eueiEnabled) === false) {
return true;
}
if (!portal || hasEueiEnabledAndIsMemberOfOrg(portal) || isRegisteredUserWithoutOrgInUSA(portal) || isAnonymousUserInUSA(portal)) {
if (!portal ||
hasEueiEnabledAndIsMemberOfOrg(portal) ||
isRegisteredUserWithoutOrgInUSA(portal) ||
isAnonymousUserInUSA(portal)) {
return false;

@@ -1217,7 +1226,26 @@ }

this.debug = options.debug;
this.disabled = shouldDisableTracking(options);
this.suppressDisabledWarnings = options.suppressDisabledWarnings;
this.logger = options.logger || console;
if (this.disabled) {
this.logger.warn('Telemetry Disabled');
// if passed privacy settings, use them
if (options.userPrivacySettings) {
this._userPrivacySettings = options.userPrivacySettings;
}
// if consent is required, but no privacy settings are passed, create them
// this basically defaults to no tracking
if (options.requireConsent && !options.userPrivacySettings) {
this._userPrivacySettings = {
accepted: false,
performance: false,
targeting: false,
functional: false,
id: generateGUID(),
timestamp: Date.now(),
};
options.userPrivacySettings = this._userPrivacySettings;
}
// Check if tracking should be wholesale disabled
this.disabled = shouldDisableTracking(options);
if (this.disabled && !this.suppressDisabledWarnings) {
this.logger.info('Telemetry Disabled');
}
const user = ((_a = options.portal) === null || _a === void 0 ? void 0 : _a.user) || options.user;

@@ -1232,13 +1260,46 @@ if (user) {

initializeTrackers() {
const userSettings = this._userPrivacySettings;
// Reset trackers
this.trackers = [];
// Depending on the user settings, we may not want to load all trackers
if (this.options.plugins) {
this.trackers.push(...this.options.plugins);
if (userSettings) {
// ------------------------------------------------------
// Rules:
// if settings.performance: true, we can load the Esri Tracker
// if settings.{performance,targeting,functional}: true, we can load the 3rd party trackers
// ------------------------------------------------------
if (userSettings === null || userSettings === void 0 ? void 0 : userSettings.performance) {
this.trackers.push(...this.options.plugins.filter((tracker) => tracker.name === 'amazon'));
}
if ((userSettings === null || userSettings === void 0 ? void 0 : userSettings.performance) &&
(userSettings === null || userSettings === void 0 ? void 0 : userSettings.targeting) &&
(userSettings === null || userSettings === void 0 ? void 0 : userSettings.functional)) {
const thirdPartyTrackers = [
'adobe-analytics',
'google',
'googleAnalytics',
'siteimprove',
];
this.trackers.push(...this.options.plugins.filter((tracker) => thirdPartyTrackers.includes(tracker.name)));
}
}
else {
// enable all trackers
this.trackers.push(...this.options.plugins);
}
}
if (!this.trackers.length) {
this.logger.error(new Error('No trackers configured'));
// Just log that no trackers are configured
// this is likely due to the user privacy settings
// this.logger.error(new Error('No trackers configured'));
this.logger.info('No trackers configured');
}
}
getScriptTags() {
return this.trackers.map((tracker) => {
return this.trackers
.map((tracker) => {
return tracker.getScriptTags && tracker.getScriptTags();
}).join('');
})
.join('');
}

@@ -1268,10 +1329,39 @@ async init() {

}
/**
* Allow clients to update the user privacy settings
* after the telemetry instance has been created.
* Host app is responsible for persisting the settings
* into localStorage or cookies, depending on their requirements
*/
async updateUserPrivacySettings(newSettings) {
const { performance, targeting, functional } = this._userPrivacySettings;
// decide if the new settings are more restrictive than the previous ones
// if so we need to return `{reload: true}` so that the page can be reloaded
// to ensure that the trackers are re-initialized
const reload = (!newSettings.performance && performance) ||
(!newSettings.targeting && targeting) ||
(!newSettings.functional && functional);
// hold into it
this._userPrivacySettings = newSettings;
// we need to re-initialize the trackers based on the new settings
if (!reload) {
// if the new settings are more permissive than the old
// we know that at least some trackers are enabled,
// thus telemetry as a whole is not disabled
this.disabled = false;
// re-initialize the trackers
this.initializeTrackers();
// and initialize them because it is possible they have not been
await this.init();
}
return { reload };
}
logPageView(page, event = {}, options = {}) {
if (this.disabled) {
this.logger.warn('Page view was not logged because telemetry is disabled.');
if (this.disabled && !this.suppressDisabledWarnings) {
this.logger.info('Page view was not logged because telemetry is disabled.');
return false;
}
const enabledTrackers = this.trackers.filter(({ disabled }) => !disabled);
const enabledTrackers = this.trackers.filter(({ disabled, hasError }) => !disabled && !hasError);
if (!enabledTrackers.length) {
this.logger.warn('Page view was not logged because no enabled telemetry-plugins are registered.');
this.logger.info('Page view was not logged because no enabled telemetry-plugins are registered.');
return false;

@@ -1290,9 +1380,9 @@ }

logEvent(event, options = {}) {
if (this.disabled) {
this.logger.warn('Event was not logged because telemetry is disabled.');
if (this.disabled && !this.suppressDisabledWarnings) {
this.logger.info('Event was not logged because telemetry is disabled.');
return false;
}
const enabledTrackers = this.trackers.filter(({ disabled }) => !disabled);
const enabledTrackers = this.trackers.filter(({ disabled, hasError }) => !disabled && !hasError);
if (!enabledTrackers.length) {
this.logger.warn('Event was not logged because no enabled telemetry-plugins are registered.');
this.logger.info('Event was not logged because no enabled telemetry-plugins are registered.');
return false;

@@ -1406,6 +1496,14 @@ }

}
/**
* Disable a tracker. This does not deterministically unload
* the tracker from the page, but it does prevent events from
* this library from being sent to it. Thus, if you need to ensure
* that an instantiated tracker is fully disabled, you should reload
* the application (thus, the `reload` property on the return value from `updateUserPrivacySettings`)
* @param trackerName
*/
disableTracker(trackerName) {
var _a;
const tracker = this.trackers.find(({ name }) => name === trackerName);
if (tracker) {
if (tracker && !tracker.hasError) {
tracker.disabled = true;

@@ -1415,6 +1513,10 @@ (_a = tracker.disable) === null || _a === void 0 ? void 0 : _a.call(tracker);

}
/**
* Enable a specific tracker
* @param trackerName
*/
enableTracker(trackerName) {
var _a;
const tracker = this.trackers.find(({ name }) => name === trackerName);
if (tracker) {
if (tracker && !tracker.hasError) {
tracker.disabled = false;

@@ -1447,2 +1549,39 @@ (_a = tracker.enable) === null || _a === void 0 ? void 0 : _a.call(tracker);

}
// /**
// * Get the privacy settings from local storage or use the default values
// * @returns
// */
// function getPrivacySettings(win?: Window): IPrivacySettings {
// // Default settings, which is the same as if they rejected all tracking
// let settings: IPrivacySettings = {
// accepted: false,
// performance: false,
// targeting: false,
// functional: false,
// id: generateGUID(),
// timestamp: Date.now(),
// };
// if (win?.localStorage) {
// // try to get the privacy settings from local storage
// const storedSettings = win.localStorage.getItem('esri_privacy_settings');
// if (storedSettings) {
// settings = JSON.parse(storedSettings);
// } else {
// // store the default settings in local storage
// win.localStorage.setItem(
// 'esri_privacy_settings',
// JSON.stringify(settings),
// );
// }
// }
// return settings;
// }
// Created by github copilot
function generateGUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0;
const v = c === 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}

@@ -1449,0 +1588,0 @@ exports.Telemetry = Telemetry;

4

package.json
{
"name": "@esri/telemetry",
"version": "7.0.2",
"version": "7.0.3",
"description": "A JavaScript Implementation of the ArcGIS Telemetry Specification",

@@ -55,3 +55,3 @@ "main": "dist/node/index.js",

},
"gitHead": "c92b317fe0643958ab784034f71c2ad5fcf098c1"
"gitHead": "d6a2f8ad11b07c45dcd263cad6618e2cd8a713ec"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet