@mparticle/web-sdk
Advanced tools
Comparing version 2.26.0 to 2.26.1
{ | ||
"name": "@mparticle/web-sdk", | ||
"version": "2.26.0", | ||
"version": "2.26.1", | ||
"description": "mParticle core SDK for web applications", | ||
@@ -5,0 +5,0 @@ "license": "Apache-2.0", |
@@ -444,3 +444,2 @@ import Types from './types'; | ||
this.decoded = utils.decoded; | ||
this.returnConvertedBoolean = utils.returnConvertedBoolean; | ||
this.parseStringOrNumber = utils.parseStringOrNumber; | ||
@@ -447,0 +446,0 @@ this.generateHash = utils.generateHash; |
@@ -8,3 +8,3 @@ // This file is used ONLY for the mParticle ESLint plugin. It should NOT be used otherwise! | ||
import { Batch } from '@mparticle/event-models'; | ||
import { IMPSideloadedKit} from './sideloadedKit'; | ||
import { IMPSideloadedKit } from './sideloadedKit'; | ||
@@ -31,3 +31,2 @@ const mockFunction = function() { | ||
isObject: mockFunction, | ||
returnConvertedBoolean: mockFunction, | ||
Validators: null, | ||
@@ -34,0 +33,0 @@ }, |
@@ -39,7 +39,9 @@ // | ||
import IdentityAPIClient from './identityApiClient'; | ||
import { isEmpty, isFunction } from './utils'; | ||
import { LocalStorageVault } from './vault'; | ||
import { removeExpiredIdentityCacheDates } from './identity-utils'; | ||
var Messages = Constants.Messages, | ||
HTTPCodes = Constants.HTTPCodes; | ||
const { Messages, HTTPCodes, FeatureFlags } = Constants; | ||
const { ReportBatching } = FeatureFlags; | ||
const { StartingInitialization } = Messages.InformationMessages; | ||
@@ -293,3 +295,3 @@ /** | ||
this.startTrackingLocation = function(callback) { | ||
if (!self._Helpers.Validators.isFunction(callback)) { | ||
if (!isFunction(callback)) { | ||
self.Logger.warning( | ||
@@ -1297,121 +1299,34 @@ 'Warning: Location tracking is triggered, but not including a callback into the `startTrackingLocation` may result in events logged too quickly and not being associated with a location.' | ||
mpInstance._Forwarders = new Forwarders(mpInstance, kitBlocker); | ||
if (config.flags) { | ||
if ( | ||
config.flags.hasOwnProperty( | ||
Constants.FeatureFlags.EventBatchingIntervalMillis | ||
) | ||
) { | ||
mpInstance._Store.SDKConfig.flags[ | ||
Constants.FeatureFlags.EventBatchingIntervalMillis | ||
] = | ||
config.flags[ | ||
Constants.FeatureFlags.EventBatchingIntervalMillis | ||
]; | ||
} | ||
} | ||
mpInstance._Store.processConfig(config); | ||
// add a new function to apply items to the store that require config to be returned | ||
mpInstance._Store.storageName = mpInstance._Helpers.createMainStorageName( | ||
config.workspaceToken | ||
); | ||
mpInstance._Store.prodStorageName = mpInstance._Helpers.createProductStorageName( | ||
config.workspaceToken | ||
); | ||
// idCache is instantiated here as opposed to when _Identity is instantiated | ||
// because it depends on _Store.storageName, which is not sent until above | ||
// because it is a setting on config which returns asyncronously | ||
// in self hosted mode | ||
mpInstance._Identity.idCache = new LocalStorageVault( | ||
`${mpInstance._Store.storageName}-id-cache`, | ||
{ | ||
logger: mpInstance.Logger, | ||
} | ||
); | ||
mpInstance._Identity.idCache = createIdentityCache(mpInstance); | ||
removeExpiredIdentityCacheDates(mpInstance._Identity.idCache); | ||
if (config.hasOwnProperty('workspaceToken')) { | ||
mpInstance._Store.SDKConfig.workspaceToken = config.workspaceToken; | ||
// Web View Bridge is used for cases where the Web SDK is loaded within an iOS or Android device's | ||
// Web View. The Web SDK simply acts as a passthrough to the mParticle Native SDK. It is not | ||
// responsible for sending events directly to mParticle's servers. The Web SDK will not initialize | ||
// persistence or Identity directly. | ||
if (mpInstance._Store.webviewBridgeEnabled) { | ||
mpInstance._NativeSdkHelpers.initializeSessionAttributes(apiKey); | ||
} else { | ||
mpInstance.Logger.warning( | ||
'You should have a workspaceToken on your config object for security purposes.' | ||
); | ||
} | ||
// Main SDK initialization flow | ||
if (config.hasOwnProperty('requiredWebviewBridgeName')) { | ||
mpInstance._Store.SDKConfig.requiredWebviewBridgeName = | ||
config.requiredWebviewBridgeName; | ||
} else if (config.hasOwnProperty('workspaceToken')) { | ||
mpInstance._Store.SDKConfig.requiredWebviewBridgeName = | ||
config.workspaceToken; | ||
} | ||
mpInstance._Store.webviewBridgeEnabled = mpInstance._NativeSdkHelpers.isWebviewEnabled( | ||
mpInstance._Store.SDKConfig.requiredWebviewBridgeName, | ||
mpInstance._Store.SDKConfig.minWebviewBridgeVersion | ||
); | ||
mpInstance._Store.configurationLoaded = true; | ||
// https://go.mparticle.com/work/SQDSDKS-6044 | ||
if (!mpInstance._Store.webviewBridgeEnabled) { | ||
// Load any settings/identities/attributes from cookie or localStorage | ||
mpInstance._Persistence.initializeStorage(); | ||
} | ||
if (mpInstance._Store.webviewBridgeEnabled) { | ||
mpInstance._NativeSdkHelpers.sendToNative( | ||
Constants.NativeSdkPaths.SetSessionAttribute, | ||
JSON.stringify({ key: '$src_env', value: 'webview' }) | ||
); | ||
if (apiKey) { | ||
mpInstance._NativeSdkHelpers.sendToNative( | ||
Constants.NativeSdkPaths.SetSessionAttribute, | ||
JSON.stringify({ key: '$src_key', value: apiKey }) | ||
); | ||
} | ||
} else { | ||
var currentUser; | ||
// Set up user identitiy variables for later use | ||
const currentUser = mpInstance.Identity.getCurrentUser(); | ||
const currentUserMPID = currentUser ? currentUser.getMPID() : null; | ||
const currentUserIdentities = currentUser | ||
? currentUser.getUserIdentities().userIdentities | ||
: {}; | ||
// If no initialIdentityRequest is passed in, we set the user identities to what is currently in cookies for the identify request | ||
if ( | ||
(mpInstance._Helpers.isObject( | ||
mpInstance._Store.SDKConfig.identifyRequest | ||
) && | ||
mpInstance._Helpers.isObject( | ||
mpInstance._Store.SDKConfig.identifyRequest.userIdentities | ||
) && | ||
Object.keys( | ||
mpInstance._Store.SDKConfig.identifyRequest.userIdentities | ||
).length === 0) || | ||
!mpInstance._Store.SDKConfig.identifyRequest | ||
) { | ||
var modifiedUIforIdentityRequest = {}; | ||
mpInstance._Store.SDKConfig.identifyRequest = mpInstance._Store.hasInvalidIdentifyRequest() | ||
? { userIdentities: currentUserIdentities } | ||
: mpInstance._Store.SDKConfig.identifyRequest; | ||
currentUser = mpInstance.Identity.getCurrentUser(); | ||
if (currentUser) { | ||
var identities = | ||
currentUser.getUserIdentities().userIdentities || {}; | ||
for (var identityKey in identities) { | ||
if (identities.hasOwnProperty(identityKey)) { | ||
modifiedUIforIdentityRequest[identityKey] = | ||
identities[identityKey]; | ||
} | ||
} | ||
} | ||
mpInstance._Store.SDKConfig.identifyRequest = { | ||
userIdentities: modifiedUIforIdentityRequest, | ||
}; | ||
if (mpInstance._Helpers.getFeatureFlag(ReportBatching)) { | ||
mpInstance._ForwardingStatsUploader.startForwardingStatsTimer(); | ||
} | ||
currentUser = mpInstance.Identity.getCurrentUser(); | ||
if ( | ||
mpInstance._Helpers.getFeatureFlag( | ||
Constants.FeatureFlags.ReportBatching | ||
) | ||
) { | ||
mpInstance._ForwardingStatsUploader.startForwardingStatsTimer(); | ||
} | ||
mpInstance._Forwarders.processForwarders( | ||
@@ -1421,62 +1336,26 @@ config, | ||
); | ||
mpInstance._Forwarders.processPixelConfigs(config); | ||
// Checks if session is created, resumed, or needs to be ended | ||
// Logs a session start or session end event accordingly | ||
mpInstance._SessionManager.initialize(); | ||
mpInstance._Events.logAST(); | ||
// Call mParticle._Store.SDKConfig.identityCallback when identify was not called due to a reload or a sessionId already existing | ||
// Any identity callback should always be ran regardless if an identity call is made | ||
if ( | ||
!mpInstance._Store.identifyCalled && | ||
mpInstance._Store.SDKConfig.identityCallback && | ||
currentUser && | ||
currentUser.getMPID() | ||
) { | ||
mpInstance._Store.SDKConfig.identityCallback({ | ||
httpCode: HTTPCodes.activeSession, | ||
getUser: function() { | ||
return mpInstance._Identity.mParticleUser( | ||
currentUser.getMPID() | ||
); | ||
}, | ||
getPreviousUser: function() { | ||
var users = mpInstance.Identity.getUsers(); | ||
var mostRecentUser = users.shift(); | ||
if ( | ||
mostRecentUser && | ||
currentUser && | ||
mostRecentUser.getMPID() === currentUser.getMPID() | ||
) { | ||
mostRecentUser = users.shift(); | ||
} | ||
return mostRecentUser || null; | ||
}, | ||
body: { | ||
mpid: currentUser.getMPID(), | ||
is_logged_in: mpInstance._Store.isLoggedIn, | ||
matched_identities: currentUser.getUserIdentities() | ||
.userIdentities, | ||
context: null, | ||
is_ephemeral: false, | ||
}, | ||
}); | ||
} | ||
processIdentityCallback( | ||
mpInstance, | ||
currentUser, | ||
currentUserMPID, | ||
currentUserIdentities | ||
); | ||
} | ||
mpInstance._Store.isInitialized = true; | ||
// Call any functions that are waiting for the library to be initialized | ||
if ( | ||
mpInstance._preInit.readyQueue && | ||
mpInstance._preInit.readyQueue.length | ||
) { | ||
mpInstance._preInit.readyQueue.forEach(function(readyQueueItem) { | ||
if (mpInstance._Helpers.Validators.isFunction(readyQueueItem)) { | ||
readyQueueItem(); | ||
} else if (Array.isArray(readyQueueItem)) { | ||
processPreloadedItem(readyQueueItem, mpInstance); | ||
} | ||
}); | ||
mpInstance._preInit.readyQueue = []; | ||
try { | ||
mpInstance._preInit.readyQueue = processReadyQueue( | ||
mpInstance._preInit.readyQueue | ||
); | ||
} catch (error) { | ||
mpInstance.Logger.error(error); | ||
} | ||
@@ -1551,2 +1430,8 @@ | ||
function createIdentityCache(mpInstance) { | ||
return new LocalStorageVault(`${mpInstance._Store.storageName}-id-cache`, { | ||
logger: mpInstance.Logger, | ||
}); | ||
} | ||
function runPreConfigFetchInitialization(mpInstance, apiKey, config) { | ||
@@ -1556,5 +1441,3 @@ mpInstance.Logger = new Logger(config); | ||
window.mParticle.Store = mpInstance._Store; | ||
mpInstance.Logger.verbose( | ||
Messages.InformationMessages.StartingInitialization | ||
); | ||
mpInstance.Logger.verbose(StartingInitialization); | ||
@@ -1576,5 +1459,47 @@ // Check to see if localStorage is available before main configuration runs | ||
function processPreloadedItem(readyQueueItem, mpInstance) { | ||
var args = readyQueueItem, | ||
method = args.splice(0, 1)[0]; | ||
function processIdentityCallback( | ||
mpInstance, | ||
currentUser, | ||
currentUserMPID, | ||
currentUserIdentities | ||
) { | ||
// https://go.mparticle.com/work/SQDSDKS-6323 | ||
// Call mParticle._Store.SDKConfig.identityCallback when identify was not called | ||
// due to a reload or a sessionId already existing | ||
// Any identity callback should always be ran regardless if an identity call | ||
// is made | ||
if ( | ||
!mpInstance._Store.identifyCalled && | ||
mpInstance._Store.SDKConfig.identityCallback && | ||
currentUser && | ||
currentUserMPID | ||
) { | ||
mpInstance._Store.SDKConfig.identityCallback({ | ||
httpCode: HTTPCodes.activeSession, | ||
getUser: function() { | ||
return mpInstance._Identity.mParticleUser(currentUserMPID); | ||
}, | ||
getPreviousUser: function() { | ||
const users = mpInstance.Identity.getUsers(); | ||
let mostRecentUser = users.shift(); | ||
const mostRecentUserMPID = mostRecentUser.getMPID(); | ||
if (mostRecentUser && mostRecentUserMPID === currentUserMPID) { | ||
mostRecentUser = users.shift(); | ||
} | ||
return mostRecentUser || null; | ||
}, | ||
body: { | ||
mpid: currentUserMPID, | ||
is_logged_in: mpInstance._Store.isLoggedIn, | ||
matched_identities: currentUserIdentities, | ||
context: null, | ||
is_ephemeral: false, | ||
}, | ||
}); | ||
} | ||
} | ||
function processPreloadedItem(readyQueueItem) { | ||
const args = readyQueueItem; | ||
const method = args.splice(0, 1)[0]; | ||
// if the first argument is a method on the base mParticle object, run it | ||
@@ -1585,7 +1510,7 @@ if (mParticle[args[0]]) { | ||
} else { | ||
var methodArray = method.split('.'); | ||
const methodArray = method.split('.'); | ||
try { | ||
var computedMPFunction = mParticle; | ||
for (var i = 0; i < methodArray.length; i++) { | ||
var currentMethod = methodArray[i]; | ||
for (let i = 0; i < methodArray.length; i++) { | ||
const currentMethod = methodArray[i]; | ||
computedMPFunction = computedMPFunction[currentMethod]; | ||
@@ -1595,5 +1520,3 @@ } | ||
} catch (e) { | ||
mpInstance.Logger.verbose( | ||
'Unable to compute proper mParticle function ' + e | ||
); | ||
throw new Error('Unable to compute proper mParticle function ' + e); | ||
} | ||
@@ -1603,2 +1526,16 @@ } | ||
function processReadyQueue(readyQueue) { | ||
if (!isEmpty(readyQueue)) { | ||
readyQueue.forEach(function(readyQueueItem) { | ||
if (isFunction(readyQueueItem)) { | ||
readyQueueItem(); | ||
} else if (Array.isArray(readyQueueItem)) { | ||
processPreloadedItem(readyQueueItem); | ||
} | ||
}); | ||
return []; | ||
} | ||
} | ||
function queueIfNotInitialized(func, self) { | ||
@@ -1605,0 +1542,0 @@ if (!self.isInitialized()) { |
@@ -10,2 +10,20 @@ import Constants from './constants'; | ||
var self = this; | ||
this.initializeSessionAttributes = function(apiKey) { | ||
const { SetSessionAttribute } = Constants.NativeSdkPaths; | ||
const env = JSON.stringify({ | ||
key: '$src_env', | ||
value: 'webview', | ||
}); | ||
const key = JSON.stringify({ | ||
key: '$src_key', | ||
value: apiKey, | ||
}); | ||
self.sendToNative(SetSessionAttribute, env); | ||
if (apiKey) { | ||
self.sendToNative(SetSessionAttribute, key); | ||
} | ||
}; | ||
this.isBridgeV2Available = function(bridgeName) { | ||
@@ -12,0 +30,0 @@ if (!bridgeName) { |
@@ -254,2 +254,4 @@ import * as EventsApi from '@mparticle/event-models'; | ||
canLog?(): boolean; | ||
createMainStorageName?(workspaceToken: string): string; | ||
createProductStorageName?(workspaceToken: string): string; | ||
createServiceUrl(url: string, devToken?: string): void; | ||
@@ -276,3 +278,2 @@ createXHR?(cb: () => void): XMLHttpRequest; | ||
): void; | ||
returnConvertedBoolean(data: string | boolean | number): boolean; | ||
sanitizeAttributes?( | ||
@@ -279,0 +280,0 @@ attrs: Dictionary<string>, |
@@ -50,2 +50,3 @@ import { MPID } from '@mparticle/web-sdk'; | ||
if (persistence && !persistence.cu) { | ||
// https://go.mparticle.com/work/SQDSDKS-6323 | ||
mpInstance.Identity.identify( | ||
@@ -52,0 +53,0 @@ mpInstance._Store.SDKConfig.identifyRequest, |
@@ -23,3 +23,11 @@ import { Batch } from '@mparticle/event-models'; | ||
} from './sdkRuntimeModels'; | ||
import { isNumber, isDataPlanSlug, Dictionary, parseNumber } from './utils'; | ||
import { | ||
Dictionary, | ||
isDataPlanSlug, | ||
isEmpty, | ||
isNumber, | ||
isObject, | ||
parseNumber, | ||
returnConvertedBoolean, | ||
} from './utils'; | ||
import { SDKConsentState } from './consent'; | ||
@@ -75,2 +83,5 @@ import { Kit, MPForwarder } from './forwarders.interfaces'; | ||
v3SecureServiceUrl?: string; | ||
webviewBridgeName?: string; | ||
workspaceToken?: string; | ||
requiredWebviewBridgeName?: string; | ||
} | ||
@@ -119,3 +130,3 @@ | ||
export interface IFeatureFlags { | ||
reportBatching?: string; | ||
reportBatching?: boolean; | ||
eventBatchingIntervalMillis?: number; | ||
@@ -175,3 +186,2 @@ offlineStorage?: string; | ||
setDeviceId?(deviceId: string): void; | ||
getFirstSeenTime?(mpid: MPID): number; | ||
@@ -182,3 +192,5 @@ setFirstSeenTime?(mpid: MPID, time?: number): void; | ||
hasInvalidIdentifyRequest?: () => boolean; | ||
nullifySession?: () => void; | ||
processConfig(config: SDKInitConfig): void; | ||
} | ||
@@ -193,2 +205,9 @@ | ||
) { | ||
const { | ||
createMainStorageName, | ||
createProductStorageName, | ||
} = mpInstance._Helpers; | ||
const { isWebviewEnabled } = mpInstance._NativeSdkHelpers; | ||
const defaultStore: Partial<IStore> = { | ||
@@ -275,4 +294,7 @@ isEnabled: true, | ||
this.SDKConfig.flags = processFlags(config, this | ||
.SDKConfig as SDKConfig); | ||
// We process the initial config that is passed via the SDK init | ||
// and then we will reprocess the config within the processConfig | ||
// function when the config is updated from the server | ||
// https://go.mparticle.com/work/SQDSDKS-6317 | ||
this.SDKConfig.flags = processFlags(config); | ||
@@ -283,3 +305,3 @@ if (config.deviceId) { | ||
if (config.hasOwnProperty('isDevelopmentMode')) { | ||
this.SDKConfig.isDevelopmentMode = mpInstance._Helpers.returnConvertedBoolean( | ||
this.SDKConfig.isDevelopmentMode = returnConvertedBoolean( | ||
config.isDevelopmentMode | ||
@@ -465,2 +487,12 @@ ); | ||
this.hasInvalidIdentifyRequest = (): boolean => { | ||
const { identifyRequest } = this.SDKConfig; | ||
return ( | ||
(isObject(identifyRequest) && | ||
isObject(identifyRequest.userIdentities) && | ||
isEmpty(identifyRequest.userIdentities)) || | ||
!identifyRequest | ||
); | ||
}; | ||
this.getDeviceId = () => this.deviceId; | ||
@@ -473,9 +505,2 @@ this.setDeviceId = (deviceId: string) => { | ||
this.nullifySession = (): void => { | ||
this.sessionId = null; | ||
this.dateLastEventSent = null; | ||
this.sessionAttributes = {}; | ||
mpInstance._Persistence.update(); | ||
}; | ||
this.getFirstSeenTime = (mpid: MPID) => { | ||
@@ -552,8 +577,43 @@ if (!mpid) { | ||
}; | ||
this.nullifySession = (): void => { | ||
this.sessionId = null; | ||
this.dateLastEventSent = null; | ||
this.sessionAttributes = {}; | ||
mpInstance._Persistence.update(); | ||
}; | ||
this.processConfig = (config: SDKInitConfig) => { | ||
const { workspaceToken, requiredWebviewBridgeName } = config; | ||
// We should reprocess the flags in case they have changed when we request an updated config | ||
// such as if the SDK is being self-hosted and the flags are different on the server config | ||
// https://go.mparticle.com/work/SQDSDKS-6317 | ||
this.SDKConfig.flags = processFlags(config); | ||
if (workspaceToken) { | ||
this.SDKConfig.workspaceToken = workspaceToken; | ||
} else { | ||
mpInstance.Logger.warning( | ||
'You should have a workspaceToken on your config object for security purposes.' | ||
); | ||
} | ||
// add a new function to apply items to the store that require config to be returned | ||
this.storageName = createMainStorageName(workspaceToken); | ||
this.prodStorageName = createProductStorageName(workspaceToken); | ||
this.SDKConfig.requiredWebviewBridgeName = | ||
requiredWebviewBridgeName || workspaceToken; | ||
this.webviewBridgeEnabled = isWebviewEnabled( | ||
this.SDKConfig.requiredWebviewBridgeName, | ||
this.SDKConfig.minWebviewBridgeVersion | ||
); | ||
this.configurationLoaded = true; | ||
}; | ||
} | ||
export function processFlags( | ||
config: SDKInitConfig, | ||
SDKConfig: SDKConfig | ||
): IFeatureFlags { | ||
// https://go.mparticle.com/work/SQDSDKS-6317 | ||
export function processFlags(config: SDKInitConfig): IFeatureFlags { | ||
const flags: IFeatureFlags = {}; | ||
@@ -573,2 +633,3 @@ const { | ||
// https://go.mparticle.com/work/SQDSDKS-6317 | ||
// Passed in config flags take priority over defaults | ||
@@ -575,0 +636,0 @@ flags[ReportBatching] = config.flags[ReportBatching] || false; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1529970
27481