From 1cdacb3272564afb88cb57e4302248bff6f45f4f Mon Sep 17 00:00:00 2001 From: Jaissica Date: Tue, 12 May 2026 17:36:40 -0400 Subject: [PATCH 1/4] refactor: migrate identity module to TS --- src/identity-utils.ts | 2 +- src/identity.interfaces.ts | 47 +++-- src/{identity.js => identity.ts} | 258 ++++++++++++++++------------ src/identityApiClient.ts | 9 +- src/mp-instance.ts | 4 +- src/persistence.interfaces.ts | 8 +- src/store.ts | 1 + test/jest/identity.spec.ts | 9 +- test/src/tests-identity.ts | 5 +- test/src/tests-identityApiClient.ts | 5 +- 10 files changed, 206 insertions(+), 142 deletions(-) rename src/{identity.js => identity.ts} (90%) diff --git a/src/identity-utils.ts b/src/identity-utils.ts index 59ef35274..9c2fedd92 100644 --- a/src/identity-utils.ts +++ b/src/identity-utils.ts @@ -34,7 +34,7 @@ export type IParseCachedIdentityResponse = ( callback: IdentityCallback, identityApiData: IdentityApiData, identityMethod: string, - knownIdentities: IKnownIdentities, + knownIdentities: IKnownIdentities | UserIdentities, fromCachedIdentity: boolean ) => void; diff --git a/src/identity.interfaces.ts b/src/identity.interfaces.ts index a223b77d2..00301d5cc 100644 --- a/src/identity.interfaces.ts +++ b/src/identity.interfaces.ts @@ -1,4 +1,5 @@ import { IdentityApiData, MPID, UserIdentities } from '@mparticle/web-sdk'; +import { Context } from '@mparticle/event-models'; import AudienceManager from './audienceManager'; import { ICachedIdentityCall, IKnownIdentities } from './identity-utils'; import { BaseVault } from './vault'; @@ -18,6 +19,7 @@ const { platform, sdkVendor, sdkVersion, HTTPCodes } = Constants; export type IdentityPreProcessResult = { valid: boolean; error?: string; + cleanedIdentities?: IdentityApiData; }; export type IdentityAPIMethod = valueof; @@ -49,14 +51,14 @@ export enum SDKIdentityTypeEnum { export interface IIdentityAPIRequestData { client_sdk: { - platform: typeof platform; - sdk_vendor: typeof sdkVendor; - sdk_version: typeof sdkVersion; + platform: string; + sdk_vendor: string; + sdk_version: string; }; - context: string | null; + context: Context | null; environment: Environment; request_id: string; - request_timestamp_unixtime_ms: number; + request_timestamp_ms: number; previous_mpid: MPID | null; known_identities: IKnownIdentities; } @@ -86,7 +88,7 @@ export interface IIdentityRequest { sdkVendor: string, sdkVersion: string, deviceId: string, - context: string | null, + context: Context | null, mpid: MPID ): IIdentityAPIRequestData; createModifyIdentityRequest( @@ -95,17 +97,20 @@ export interface IIdentityRequest { platform: string, sdkVendor: string, sdkVersion: string, - context: string | null + context: Context | null ): IIdentityAPIModifyRequestData; createIdentityChanges( previousIdentities: UserIdentities, - newIdentitie: UserIdentities - ): IIdentityAPIIdentityChangeData; + newIdentities: UserIdentities + ): IIdentityAPIIdentityChangeData[]; preProcessIdentityRequest( identityApiData: IdentityApiData, callback: IdentityCallback, method: IdentityAPIMethod ): IdentityPreProcessResult; + createAliasNetworkRequest(aliasRequest: IAliasRequest): object; + convertAliasToNative(aliasRequest: IAliasRequest): object; + convertToNative(identityApiData: IdentityApiData): object | void; } export type AliasRequestScope = 'device' | 'mpid'; @@ -150,7 +155,7 @@ export interface SDKIdentityApi { getUsers?(): IMParticleUser[]; aliasUsers?( aliasRequest?: IAliasRequest, - callback?: IdentityCallback + callback?: IAliasCallback ): void; createAliasRequest?( sourceUser: IMParticleUser, @@ -211,18 +216,18 @@ export interface IIdentity { IdentityAPI: SDKIdentityApi; IdentityRequest: IIdentityRequest; - mParticleUser(mpid: MPID, IsLoggedIn: boolean): IMParticleUser; + mParticleUser(mpid?: MPID, IsLoggedIn?: boolean): IMParticleUser; createUserAttributeChange( key: string, - newValue: string, - previousUserAttributeValue: string, + newValue: string | string[] | null, + previousUserAttributeValue: string | string[] | null, isNewAttribute: boolean, deleted: boolean, user: IMParticleUser ): IUserAttributeChangeEvent; createUserIdentityChange( - identityType: SDKIdentityTypeEnum, + identityType: SDKIdentityTypeEnum | string, newIdentity: string, oldIdentity: string, newCreatedThisBatch: boolean, @@ -234,13 +239,13 @@ export interface IIdentity { callback: IdentityCallback, identityApiData: IdentityApiData, method: IdentityAPIMethod, - knownIdentities: UserIdentities, + knownIdentities: IKnownIdentities | UserIdentities, parsingCachedResponse: boolean ): void; sendUserAttributeChangeEvent( attributeKey: string, - newUserAttributeValue: string, - previousUserAttributeValue: string, + newUserAttributeValue: string | string[] | null, + previousUserAttributeValue: string | string[] | null, isNewAttribute: boolean, deleted: boolean, user: IMParticleUser @@ -251,6 +256,14 @@ export interface IIdentity { mpid: MPID, prevUserIdentities: UserIdentities ): void; + reinitForwardersOnUserChange( + prevUser: IMParticleUser, + newUser: IMParticleUser + ): void; + setForwarderCallbacks( + user: IMParticleUser, + method: IdentityAPIMethod + ): void; /** * @deprecated diff --git a/src/identity.js b/src/identity.ts similarity index 90% rename from src/identity.js rename to src/identity.ts index 29c9dacb9..22eb8f9fc 100644 --- a/src/identity.js +++ b/src/identity.ts @@ -4,15 +4,18 @@ import { cacheOrClearIdCache, createKnownIdentities, executeSearchRequest, + IKnownIdentities, + IParseCachedIdentityResponse, normalizeUserIdentityKeys, tryCacheIdentity, } from './identity-utils'; -import AudienceManager from './audienceManager'; +import AudienceManager, { IAudienceMemberships } from './audienceManager'; const { Messages, HTTPCodes, FeatureFlags, IdentityMethods } = Constants; const { ErrorMessages } = Messages; const { CacheIdentity } = FeatureFlags; const { Identify, Modify, Login, Logout } = IdentityMethods; import { + Environment, generateDeprecationMessage, isEmpty, isFunction, @@ -20,17 +23,40 @@ import { } from './utils'; import { hasMPIDAndUserLoginChanged, hasMPIDChanged } from './user-utils'; import { processReadyQueue } from './pre-init-utils'; - -export default function Identity(mpInstance) { +import { + IdentityCallback, + IIdentityResponse, + IMParticleUser, + mParticleUserCart, +} from './identity-user-interfaces'; +import { + IIdentity, + IIdentityAPIRequestData, + IdentityAPIMethod, + IAliasRequest, + IAliasCallback, + AliasRequestScope, + SDKIdentityTypeEnum, +} from './identity.interfaces'; +import { IMParticleWebSDKInstance } from './mp-instance'; +import { IdentityApiData, UserIdentities, MPID, ConsentState, UserAttributesValue } from '@mparticle/web-sdk'; +import { Context } from '@mparticle/event-models'; +import { BaseEvent, SDKEvent, SDKLoggerApi } from './sdkRuntimeModels'; +import { IdentitySearchCallback } from './identity/search'; + +export default function Identity( + this: IIdentity, + mpInstance: IMParticleWebSDKInstance +) { const { getFeatureFlag, extend } = mpInstance._Helpers; - var self = this; + const self: IIdentity = this; this.idCache = null; this.audienceManager = null; // https://go.mparticle.com/work/SQDSDKS-6353 this.IdentityRequest = { - preProcessIdentityRequest: function(identityApiData, callback, method) { + preProcessIdentityRequest: function(identityApiData: IdentityApiData, callback: IdentityCallback, method: IdentityAPIMethod) { mpInstance.Logger.verbose( Messages.InformationMessages.StartingLogEvent + ': ' + method ); @@ -87,24 +113,24 @@ export default function Identity(mpInstance) { }, createIdentityRequest: function( - identityApiData, - platform, - sdkVendor, - sdkVersion, - deviceId, - context, - mpid + identityApiData: IdentityApiData, + platform: string, + sdkVendor: string, + sdkVersion: string, + deviceId: string, + context: Context | null, + mpid: MPID ) { - var APIRequest = { + var APIRequest: IIdentityAPIRequestData = { client_sdk: { platform: platform, sdk_vendor: sdkVendor, sdk_version: sdkVersion, }, context: context, - environment: mpInstance._Store.SDKConfig.isDevelopmentMode + environment: (mpInstance._Store.SDKConfig.isDevelopmentMode ? 'development' - : 'production', + : 'production') as Environment, request_id: mpInstance._Helpers.generateUniqueId(), request_timestamp_ms: new Date().getTime(), previous_mpid: mpid || null, @@ -118,12 +144,12 @@ export default function Identity(mpInstance) { }, createModifyIdentityRequest: function( - currentUserIdentities, - newUserIdentities, - platform, - sdkVendor, - sdkVersion, - context + currentUserIdentities: UserIdentities, + newUserIdentities: UserIdentities, + platform: string, + sdkVendor: string, + sdkVersion: string, + context: Context | null ) { return { client_sdk: { @@ -132,9 +158,9 @@ export default function Identity(mpInstance) { sdk_version: sdkVersion, }, context: context, - environment: mpInstance._Store.SDKConfig.isDevelopmentMode + environment: (mpInstance._Store.SDKConfig.isDevelopmentMode ? 'development' - : 'production', + : 'production') as Environment, request_id: mpInstance._Helpers.generateUniqueId(), request_timestamp_ms: new Date().getTime(), identity_changes: this.createIdentityChanges( @@ -144,7 +170,7 @@ export default function Identity(mpInstance) { }; }, - createIdentityChanges: function(previousIdentities, newIdentities) { + createIdentityChanges: function(previousIdentities: UserIdentities, newIdentities: UserIdentities) { var identityChanges = []; var key; if ( @@ -166,7 +192,7 @@ export default function Identity(mpInstance) { }, // takes 2 UI objects keyed by name, combines them, returns them keyed by type - combineUserIdentities: function(previousUIByName, newUIByName) { + combineUserIdentities: function(previousUIByName: UserIdentities, newUIByName: UserIdentities) { var combinedUIByType = {}; var combinedUIByName = extend({}, previousUIByName, newUIByName); @@ -182,7 +208,7 @@ export default function Identity(mpInstance) { return combinedUIByType; }, - createAliasNetworkRequest: function(aliasRequest) { + createAliasNetworkRequest: function(aliasRequest: IAliasRequest) { return { request_id: mpInstance._Helpers.generateUniqueId(), request_type: 'alias', @@ -201,7 +227,7 @@ export default function Identity(mpInstance) { }; }, - convertAliasToNative: function(aliasRequest) { + convertAliasToNative: function(aliasRequest: IAliasRequest) { return { DestinationMpid: aliasRequest.destinationMpid, SourceMpid: aliasRequest.sourceMpid, @@ -211,7 +237,7 @@ export default function Identity(mpInstance) { }; }, - convertToNative: function(identityApiData) { + convertToNative: function(identityApiData: IdentityApiData) { var nativeIdentityRequest = []; if (identityApiData && identityApiData.userIdentities) { for (var key in identityApiData.userIdentities) { @@ -227,6 +253,7 @@ export default function Identity(mpInstance) { UserIdentities: nativeIdentityRequest, }; } + return undefined; }, }; /** @@ -242,7 +269,7 @@ export default function Identity(mpInstance) { * @param {Object} identityApiData The identityApiData object as indicated [here](https://github.com/mParticle/mparticle-sdk-javascript/blob/master-v2/README.md#1-customize-the-sdk) * @param {Function} [callback] A callback function that is called when the identify request completes */ - identify: function(identityApiData, callback) { + identify: function(identityApiData: IdentityApiData, callback: IdentityCallback) { // https://go.mparticle.com/work/SQDSDKS-6337 var mpid, currentUser = mpInstance.Identity.getCurrentUser(), @@ -273,7 +300,7 @@ export default function Identity(mpInstance) { const successfullyCachedIdentity = tryCacheIdentity( identityApiRequest.known_identities, self.idCache, - self.parseIdentityResponse, + self.parseIdentityResponse as IParseCachedIdentityResponse, mpid, callback, identityApiData, @@ -327,7 +354,9 @@ export default function Identity(mpInstance) { HTTPCodes.validationIssue, preProcessResult.error ); - mpInstance.Logger.verbose(preProcessResult); + mpInstance.Logger.verbose( + preProcessResult.error ?? JSON.stringify(preProcessResult) + ); } }, /** @@ -336,7 +365,7 @@ export default function Identity(mpInstance) { * @param {Object} identityApiData The identityApiData object as indicated [here](https://github.com/mParticle/mparticle-sdk-javascript/blob/master-v2/README.md#1-customize-the-sdk) * @param {Function} [callback] A callback function that is called when the logout request completes */ - logout: function(identityApiData, callback) { + logout: function(identityApiData: IdentityApiData, callback: IdentityCallback) { // https://go.mparticle.com/work/SQDSDKS-6337 var mpid, currentUser = mpInstance.Identity.getCurrentUser(), @@ -395,8 +424,9 @@ export default function Identity(mpInstance) { mpInstance._Store.activeForwarders.forEach(function( forwarder ) { - if (forwarder.logOut) { - forwarder.logOut(evt); + const fwd = forwarder as unknown as Record; + if (typeof fwd.logOut === 'function') { + fwd.logOut(evt); } }); } @@ -417,7 +447,9 @@ export default function Identity(mpInstance) { HTTPCodes.validationIssue, preProcessResult.error ); - mpInstance.Logger.verbose(preProcessResult); + mpInstance.Logger.verbose( + preProcessResult.error ?? JSON.stringify(preProcessResult) + ); } }, /** @@ -426,7 +458,7 @@ export default function Identity(mpInstance) { * @param {Object} identityApiData The identityApiData object as indicated [here](https://github.com/mParticle/mparticle-sdk-javascript/blob/master-v2/README.md#1-customize-the-sdk) * @param {Function} [callback] A callback function that is called when the login request completes */ - login: function(identityApiData, callback) { + login: function(identityApiData: IdentityApiData, callback: IdentityCallback) { // https://go.mparticle.com/work/SQDSDKS-6337 var mpid, currentUser = mpInstance.Identity.getCurrentUser(), @@ -459,7 +491,7 @@ export default function Identity(mpInstance) { const successfullyCachedIdentity = tryCacheIdentity( identityApiRequest.known_identities, self.idCache, - self.parseIdentityResponse, + self.parseIdentityResponse as IParseCachedIdentityResponse, mpid, callback, identityApiData, @@ -513,7 +545,9 @@ export default function Identity(mpInstance) { HTTPCodes.validationIssue, preProcessResult.error ); - mpInstance.Logger.verbose(preProcessResult); + mpInstance.Logger.verbose( + preProcessResult.error ?? JSON.stringify(preProcessResult) + ); } }, /** @@ -522,7 +556,7 @@ export default function Identity(mpInstance) { * @param {Object} identityApiData The identityApiData object as indicated [here](https://github.com/mParticle/mparticle-sdk-javascript/blob/master-v2/README.md#1-customize-the-sdk) * @param {Function} [callback] A callback function that is called when the modify request completes */ - modify: function(identityApiData, callback) { + modify: function(identityApiData: IdentityApiData, callback: IdentityCallback) { // https://go.mparticle.com/work/SQDSDKS-6337 var mpid, currentUser = mpInstance.Identity.getCurrentUser(), @@ -572,8 +606,7 @@ export default function Identity(mpInstance) { callback, identityApiData, self.parseIdentityResponse, - mpid, - identityApiRequest.known_identities + mpid ); } } else { @@ -592,7 +625,9 @@ export default function Identity(mpInstance) { HTTPCodes.validationIssue, preProcessResult.error ); - mpInstance.Logger.verbose(preProcessResult); + mpInstance.Logger.verbose( + preProcessResult.error ?? JSON.stringify(preProcessResult) + ); } }, /** @@ -627,7 +662,7 @@ export default function Identity(mpInstance) { * @param {String} mpid of the desired user * @return {Object} the user for mpid */ - getUser: function(mpid) { + getUser: function(mpid: MPID) { var persistence = mpInstance._Persistence.getPersistence(); if (persistence) { if ( @@ -676,7 +711,7 @@ export default function Identity(mpInstance) { * @param {Object} aliasRequest object representing an AliasRequest * @param {Function} [callback] A callback function that is called when the aliasUsers request completes */ - aliasUsers: function(aliasRequest, callback) { + aliasUsers: function(aliasRequest: IAliasRequest, callback: IAliasCallback) { var message; if (!aliasRequest.destinationMpid || !aliasRequest.sourceMpid) { message = Messages.ValidationMessages.AliasMissingMpid; @@ -724,7 +759,7 @@ export default function Identity(mpInstance) { ); var aliasRequestMessage = mpInstance._Identity.IdentityRequest.createAliasNetworkRequest( aliasRequest - ); + ) as IAliasRequest; mpInstance._IdentityAPIClient.sendAliasRequest( aliasRequestMessage, callback @@ -759,7 +794,7 @@ export default function Identity(mpInstance) { * @param {Object} knownIdentities A `UserIdentities` map. * @param {Function} callback Invoked with the `IIdentitySearchResult`. */ - search: function(workspaceApiKey, knownIdentities, callback) { + search: function(workspaceApiKey: string, knownIdentities: UserIdentities, callback: IdentitySearchCallback) { executeSearchRequest( mpInstance, workspaceApiKey, @@ -783,7 +818,7 @@ export default function Identity(mpInstance) { after applying this adjustment it will be impossible to create an aliasRequest passes the aliasUsers() validation that the startTime must be less than the endTime */ - createAliasRequest: function(sourceUser, destinationUser, scope) { + createAliasRequest: function(sourceUser: IMParticleUser, destinationUser: IMParticleUser, scope: AliasRequestScope) { try { if (!destinationUser || !sourceUser) { mpInstance.Logger.error( @@ -844,7 +879,7 @@ export default function Identity(mpInstance) { * Example: mParticle.Identity.getCurrentUser().getAllUserAttributes() * @class mParticle.Identity.getCurrentUser() */ - this.mParticleUser = function(mpid, isLoggedIn) { + this.mParticleUser = function(mpid?: MPID, isLoggedIn?: boolean): IMParticleUser { var self = this; return { /** @@ -883,7 +918,7 @@ export default function Identity(mpInstance) { * @method setUserTag * @param {String} tagName */ - setUserTag: function(tagName) { + setUserTag: function(tagName: string) { if (!mpInstance._Helpers.Validators.isValidKeyValue(tagName)) { mpInstance.Logger.error(Messages.ErrorMessages.BadKey); return; @@ -896,7 +931,7 @@ export default function Identity(mpInstance) { * @method removeUserTag * @param {String} tagName */ - removeUserTag: function(tagName) { + removeUserTag: function(tagName: string) { if (!mpInstance._Helpers.Validators.isValidKeyValue(tagName)) { mpInstance.Logger.error(Messages.ErrorMessages.BadKey); return; @@ -912,7 +947,7 @@ export default function Identity(mpInstance) { */ // https://go.mparticle.com/work/SQDSDKS-4576 // https://go.mparticle.com/work/SQDSDKS-6373 - setUserAttribute: function(key, newValue) { + setUserAttribute: function(key: string, newValue: string) { mpInstance._SessionManager.resetSessionTimer(); if (mpInstance._Helpers.canLog()) { @@ -988,7 +1023,7 @@ export default function Identity(mpInstance) { * @param {Object} user attribute object with keys of the attribute type, and value of the attribute value */ // https://go.mparticle.com/work/SQDSDKS-6373 - setUserAttributes: function(userAttributes) { + setUserAttributes: function(userAttributes: Record) { mpInstance._SessionManager.resetSessionTimer(); if (isObject(userAttributes)) { if (mpInstance._Helpers.canLog()) { @@ -1010,7 +1045,7 @@ export default function Identity(mpInstance) { * @method removeUserAttribute * @param {String} key */ - removeUserAttribute: function(key) { + removeUserAttribute: function(key: string) { var cookies, userAttributes; mpInstance._SessionManager.resetSessionTimer(); @@ -1076,7 +1111,7 @@ export default function Identity(mpInstance) { * @param {Array} value an array of values */ // https://go.mparticle.com/work/SQDSDKS-6373 - setUserAttributeList: function(key, newValue) { + setUserAttributeList: function(key: string, newValue: UserAttributesValue[]) { mpInstance._SessionManager.resetSessionTimer(); if (!mpInstance._Helpers.Validators.isValidKeyValue(key)) { @@ -1087,7 +1122,7 @@ export default function Identity(mpInstance) { if (!Array.isArray(newValue)) { mpInstance.Logger.error( 'The value you passed in to setUserAttributeList must be an array. You passed in a ' + - typeof value + typeof newValue ); return; } @@ -1146,7 +1181,7 @@ export default function Identity(mpInstance) { if (userAttributeChange) { self.sendUserAttributeChangeEvent( key, - newValue, + newValue as unknown as string[], previousUserAttributeValue, isNewAttribute, false, @@ -1233,12 +1268,11 @@ export default function Identity(mpInstance) { if (userAttributes) { for (const prop in userAttributes) { if (userAttributes.hasOwnProperty(prop)) { - if (Array.isArray(userAttributes[prop])) { - userAttributesCopy[prop] = userAttributes[ - prop - ].slice(); + const attrValue = userAttributes[prop]; + if (Array.isArray(attrValue)) { + userAttributesCopy[prop] = attrValue.slice(); } else { - userAttributesCopy[prop] = userAttributes[prop]; + userAttributesCopy[prop] = attrValue; } } } @@ -1271,7 +1305,7 @@ export default function Identity(mpInstance) { * @method setConsentState * @param {Object} consent state */ - setConsentState: function(state) { + setConsentState: function(state: ConsentState) { mpInstance._Store.setConsentState(mpid, state); mpInstance._Forwarders.initForwarders( this.getUserIdentities().userIdentities, @@ -1294,7 +1328,7 @@ export default function Identity(mpInstance) { * @param {Function} [callback] A callback function that is invoked when the user audience request completes */ // https://go.mparticle.com/work/SQDSDKS-6436 - getUserAudiences: function(callback) { + getUserAudiences: function(callback: IdentityCallback) { // user audience API is feature flagged if ( !mpInstance._Helpers.getFeatureFlag( @@ -1310,12 +1344,14 @@ export default function Identity(mpInstance) { self.audienceManager = new AudienceManager( mpInstance._Store.SDKConfig.userAudienceUrl, mpInstance._Store.devToken, - mpInstance.Logger, - mpid + mpInstance.Logger ); } - self.audienceManager.sendGetUserAudienceRequest(mpid, callback); + self.audienceManager.sendGetUserAudienceRequest( + mpid, + callback as unknown as (userAudiences: IAudienceMemberships) => void + ); }, }; }; @@ -1326,7 +1362,7 @@ export default function Identity(mpInstance) { * @class mParticle.Identity.getCurrentUser().getCart() * @deprecated */ - this.mParticleUserCart = function() { + this.mParticleUserCart = function(): mParticleUserCart { return { /** * Adds a cart product to the user cart @@ -1395,14 +1431,14 @@ export default function Identity(mpInstance) { // https://go.mparticle.com/work/SQDSDKS-6355 this.parseIdentityResponse = function( - identityResponse, - previousMPID, - callback, - identityApiData, - method, - knownIdentities, - parsingCachedResponse - ) { + identityResponse: IIdentityResponse, + previousMPID: MPID, + callback: IdentityCallback, + identityApiData: IdentityApiData, + method: IdentityAPIMethod, + knownIdentities: IKnownIdentities | UserIdentities, + parsingCachedResponse: boolean + ): void { const prevUser = mpInstance.Identity.getUser(previousMPID); const prevUserMPID = prevUser ? prevUser.getMPID() : null; const previousUIByName = prevUser @@ -1634,11 +1670,11 @@ export default function Identity(mpInstance) { // compare what identities exist vs what is previously was for the specific user if they were in memory before. // if it's the first time the user is logging in, send a user identity change request with this.sendUserIdentityChangeEvent = function( - newUserIdentities, - method, - mpid, - prevUserIdentities - ) { + newUserIdentities: UserIdentities, + method: IdentityAPIMethod, + mpid: MPID, + prevUserIdentities: UserIdentities + ): void { if (!mpid) { // https://go.mparticle.com/work/SQDSDKS-6501 if (method !== Modify) { @@ -1667,18 +1703,18 @@ export default function Identity(mpInstance) { currentUserInMemory ); mpInstance._APIClient?.sendEventToServer( - userIdentityChangeEvent + userIdentityChangeEvent as unknown as SDKEvent ); } } }; this.createUserIdentityChange = function( - identityType, - newIdentity, - oldIdentity, - isIdentityTypeNewToBatch, - userInMemory + identityType: string, + newIdentity: string, + oldIdentity: string, + isIdentityTypeNewToBatch: boolean, + userInMemory: IMParticleUser ) { var userIdentityChangeEvent; @@ -1698,19 +1734,19 @@ export default function Identity(mpInstance) { }, }, userInMemory, - }); + } as BaseEvent); return userIdentityChangeEvent; }; this.sendUserAttributeChangeEvent = function( - attributeKey, - newUserAttributeValue, - previousUserAttributeValue, - isNewAttribute, - deleted, - user - ) { + attributeKey: string, + newUserAttributeValue: string | string[] | null, + previousUserAttributeValue: string | string[] | null, + isNewAttribute: boolean, + deleted: boolean, + user: IMParticleUser + ): void { var userAttributeChangeEvent = self.createUserAttributeChange( attributeKey, newUserAttributeValue, @@ -1720,17 +1756,17 @@ export default function Identity(mpInstance) { user ); if (userAttributeChangeEvent) { - mpInstance._APIClient?.sendEventToServer(userAttributeChangeEvent); + mpInstance._APIClient?.sendEventToServer(userAttributeChangeEvent as unknown as SDKEvent); } }; this.createUserAttributeChange = function( - key, - newValue, - previousUserAttributeValue, - isNewAttribute, - deleted, - user + key: string, + newValue: string | string[] | null, + previousUserAttributeValue: string | string[] | null, + isNewAttribute: boolean, + deleted: boolean, + user: IMParticleUser ) { if (typeof previousUserAttributeValue === 'undefined') { previousUserAttributeValue = null; @@ -1743,8 +1779,8 @@ export default function Identity(mpInstance) { messageType: Types.MessageType.UserAttributeChange, userAttributeChanges: { UserAttributeName: key, - New: newValue, - Old: previousUserAttributeValue, + New: newValue as string, + Old: previousUserAttributeValue as string, Deleted: deleted, IsNewAttribute: isNewAttribute, }, @@ -1755,7 +1791,7 @@ export default function Identity(mpInstance) { return userAttributeChangeEvent; }; - this.reinitForwardersOnUserChange = function(prevUser, newUser) { + this.reinitForwardersOnUserChange = function(prevUser: IMParticleUser, newUser: IMParticleUser): void { if (hasMPIDAndUserLoginChanged(prevUser, newUser)) { mpInstance._Forwarders?.initForwarders( newUser.getUserIdentities().userIdentities, @@ -1764,7 +1800,7 @@ export default function Identity(mpInstance) { } }; - this.setForwarderCallbacks = function(user, method) { + this.setForwarderCallbacks = function(user: IMParticleUser, method: IdentityAPIMethod): void { // https://go.mparticle.com/work/SQDSDKS-6036 mpInstance._Forwarders?.setForwarderUserIdentities( user.getUserIdentities().userIdentities @@ -1774,8 +1810,18 @@ export default function Identity(mpInstance) { }; } +interface IdentityApiDataWithAlias extends IdentityApiData { + /** @deprecated */ + onUserAlias?: (previousUser: IMParticleUser, newUser: IMParticleUser) => void; +} + // https://go.mparticle.com/work/SQDSDKS-6359 -function tryOnUserAlias(previousUser, newUser, identityApiData, logger) { +function tryOnUserAlias( + previousUser: IMParticleUser, + newUser: IMParticleUser, + identityApiData: IdentityApiDataWithAlias, + logger: SDKLoggerApi +): void { if ( identityApiData && identityApiData.onUserAlias && diff --git a/src/identityApiClient.ts b/src/identityApiClient.ts index c26b9bade..19d280dad 100644 --- a/src/identityApiClient.ts +++ b/src/identityApiClient.ts @@ -13,6 +13,7 @@ import { IdentityAPIMethod, IIdentity, IIdentityAPIRequestData, + IIdentityAPIModifyRequestData, } from './identity.interfaces'; import { IdentityApiData, @@ -37,13 +38,13 @@ export interface IIdentityApiClient { aliasCallback: IAliasCallback ) => Promise; sendIdentityRequest: ( - identityApiRequest: IIdentityAPIRequestData, + identityApiRequest: IIdentityAPIRequestData | IIdentityAPIModifyRequestData, method: IdentityAPIMethod, callback: IdentityCallback, originalIdentityApiData: IdentityApiData, parseIdentityResponse: IIdentity['parseIdentityResponse'], mpid: MPID, - knownIdentities: UserIdentities + knownIdentities?: UserIdentities ) => Promise; getUploadUrl: (method: IdentityAPIMethod, mpid: MPID) => string; getIdentityResponseFromFetch: ( @@ -186,13 +187,13 @@ export default function IdentityAPIClient( }; this.sendIdentityRequest = async function( - identityApiRequest: IIdentityAPIRequestData, + identityApiRequest: IIdentityAPIRequestData | IIdentityAPIModifyRequestData, method: IdentityAPIMethod, callback: IdentityCallback, originalIdentityApiData: IdentityApiData, parseIdentityResponse: IIdentity['parseIdentityResponse'], mpid: MPID, - knownIdentities: UserIdentities + knownIdentities?: UserIdentities ) { if (mpInstance._RoktManager?.isInitialized) { mpInstance._Store.identifyRequestCount = (mpInstance._Store.identifyRequestCount || 0) + 1; diff --git a/src/mp-instance.ts b/src/mp-instance.ts index 618b19ab3..e42e0b348 100644 --- a/src/mp-instance.ts +++ b/src/mp-instance.ts @@ -35,7 +35,7 @@ import Identity from './identity'; import Consent, { IConsent } from './consent'; import KitBlocker from './kitBlocking'; import ConfigAPIClient, { IKitConfigs } from './configAPIClient'; -import IdentityAPIClient from './identityApiClient'; +import IdentityAPIClient, { IIdentityApiClient } from './identityApiClient'; import { isFunction, parseConfig, valueof, generateDeprecationMessage, extend } from './utils'; import { DisabledVault, LocalStorageVault } from './vault'; import { removeExpiredIdentityCacheDates, hasExplicitIdentifier } from './identity-utils'; @@ -82,7 +82,7 @@ export interface IMParticleWebSDKInstance extends MParticleWebSDK { _ForwardingStatsUploader: ForwardingStatsUploader; _Helpers: SDKHelpersApi; _Identity: IIdentity; - _IdentityAPIClient: typeof IdentityAPIClient; + _IdentityAPIClient: IIdentityApiClient; _IntegrationCapture: IntegrationCapture; _NativeSdkHelpers: INativeSdkHelpers; _Persistence: IPersistence; diff --git a/src/persistence.interfaces.ts b/src/persistence.interfaces.ts index 639de8a3e..4cc7c9bc1 100644 --- a/src/persistence.interfaces.ts +++ b/src/persistence.interfaces.ts @@ -118,12 +118,12 @@ export interface IPersistence { getCookieDomain(): string; getDomain(doc: string, locationHostname: string): string; saveUserCookieSyncDatesToPersistence(mpid: MPID, csd: CookieSyncDates): void; - savePersistence(persistance: IPersistenceMinified): void; + savePersistence(persistance: IPersistenceMinified, mpid?: MPID): void; getPersistence(): IPersistenceMinified; - getFirstSeenTime(mpid: MPID): string | null; - setFirstSeenTime(mpid: MPID, time: number): void; + getFirstSeenTime(mpid: MPID): number | null; + setFirstSeenTime(mpid: MPID, time?: number): void; getLastSeenTime(mpid: MPID): number | null; - setLastSeenTime(mpid: MPID, time: number): void; + setLastSeenTime(mpid: MPID, time?: number): void; getDeviceId(): string; setDeviceId(guid: string): void; resetPersistence(): void; diff --git a/src/store.ts b/src/store.ts index 4bd1617e1..2b12400aa 100644 --- a/src/store.ts +++ b/src/store.ts @@ -156,6 +156,7 @@ export interface IFeatureFlags { export interface IStore { isEnabled: boolean; isInitialized: boolean; + mpid: MPID; // Session Attributes are persistent attributes that are tied to the current session and // are uploaded then cleared when the session ends. diff --git a/test/jest/identity.spec.ts b/test/jest/identity.spec.ts index 22c799e33..1ca1aa9fa 100644 --- a/test/jest/identity.spec.ts +++ b/test/jest/identity.spec.ts @@ -17,6 +17,7 @@ import { import { hasExplicitIdentifier } from '../../src/identity-utils'; import { IStore } from '../../src/store'; import { MessageType } from '../../src/types'; +import { Context } from '@mparticle/event-models'; describe('Identity', () => { describe('#types', () => { @@ -122,10 +123,10 @@ describe('Identity', () => { sdk_vendor: 'mparticle', sdk_version: '1.0.0', }, - context: 'test-context', + context: 'test-context' as unknown as Context, environment: 'development', request_id: '123', - request_timestamp_unixtime_ms: Date.now(), + request_timestamp_ms: Date.now(), previous_mpid: null, known_identities: { email: 'user@mparticle.com', @@ -142,10 +143,10 @@ describe('Identity', () => { sdk_vendor: 'mparticle', sdk_version: '1.0.0', }, - context: 'test-context', + context: 'test-context' as unknown as Context, environment: 'development', request_id: '123', - request_timestamp_unixtime_ms: Date.now(), + request_timestamp_ms: Date.now(), identity_changes: [ { identity_type: SDKIdentityTypeEnum.google, diff --git a/test/src/tests-identity.ts b/test/src/tests-identity.ts index e17ecf5cd..661fd31be 100644 --- a/test/src/tests-identity.ts +++ b/test/src/tests-identity.ts @@ -15,6 +15,7 @@ import { IdentityApiData, UserIdentities, } from '@mparticle/web-sdk'; +import { Context } from '@mparticle/event-models'; import { IdentityCache } from '../../src/identity-utils'; import { IAliasRequest, @@ -1599,7 +1600,7 @@ describe('identity', function() { 'test-platform', 'test-sdk-vendor', 'test-sdk-version', - 'test-context' + 'test-context' as unknown as Context ); expect(identityRequest.identity_changes[0]).to.have.all.keys([ @@ -1650,7 +1651,7 @@ describe('identity', function() { 'test-platform', 'test-sdk-vendor', 'test-sdk-version', - 'test-context' + 'test-context' as unknown as Context ); expect(identityRequest.identity_changes[0]).to.have.all.keys([ diff --git a/test/src/tests-identityApiClient.ts b/test/src/tests-identityApiClient.ts index 0f3142af2..1b3f296d6 100644 --- a/test/src/tests-identityApiClient.ts +++ b/test/src/tests-identityApiClient.ts @@ -6,6 +6,7 @@ import { IAliasRequest, IIdentityAPIRequestData, } from '../../src/identity.interfaces'; +import { Context } from '@mparticle/event-models'; import Constants, { HTTP_ACCEPTED, HTTP_BAD_REQUEST, @@ -42,10 +43,10 @@ describe('Identity Api Client', () => { sdk_vendor: 'mparticle', sdk_version: '1.0.0', }, - context: 'test-context', + context: 'test-context' as unknown as Context, environment: 'development', request_id: '123', - request_timestamp_unixtime_ms: Date.now(), + request_timestamp_ms: Date.now(), previous_mpid: null, known_identities: { email: 'user@mparticle.com', From 8f4c21bb16331dd654fbca9f2eec2802c2351472 Mon Sep 17 00:00:00 2001 From: Jaissica Date: Wed, 20 May 2026 15:30:28 -0400 Subject: [PATCH 2/4] replace var with const/let, remove unnecessary casts and unused self in identity --- src/identity-utils.ts | 2 +- src/identity.ts | 150 +++++++++++++++++++++--------------------- 2 files changed, 75 insertions(+), 77 deletions(-) diff --git a/src/identity-utils.ts b/src/identity-utils.ts index 9c2fedd92..3182c6448 100644 --- a/src/identity-utils.ts +++ b/src/identity-utils.ts @@ -5,8 +5,8 @@ import Types from './types'; import { IdentityApiData, UserIdentities, - IdentityCallback, } from '@mparticle/web-sdk'; +import { IdentityCallback } from './identity-user-interfaces'; import { IdentityAPIMethod, IIdentityRequest } from './identity.interfaces'; import { IdentityResultBody, diff --git a/src/identity.ts b/src/identity.ts index 22eb8f9fc..b1a6fd792 100644 --- a/src/identity.ts +++ b/src/identity.ts @@ -77,7 +77,7 @@ export default function Identity( } : removedFalsyIdentityData; - var identityValidationResult = mpInstance._Helpers.Validators.validateIdentities( + const identityValidationResult = mpInstance._Helpers.Validators.validateIdentities( cleanedIdentityApiData, method ); @@ -96,7 +96,7 @@ export default function Identity( callback && !mpInstance._Helpers.Validators.isFunction(callback) ) { - var error = + const error = 'The optional callback must be a function. You tried entering a(n) ' + typeof callback; mpInstance.Logger.error(error); @@ -121,7 +121,7 @@ export default function Identity( context: Context | null, mpid: MPID ) { - var APIRequest: IIdentityAPIRequestData = { + const APIRequest: IIdentityAPIRequestData = { client_sdk: { platform: platform, sdk_vendor: sdkVendor, @@ -130,7 +130,7 @@ export default function Identity( context: context, environment: (mpInstance._Store.SDKConfig.isDevelopmentMode ? 'development' - : 'production') as Environment, + : 'production'), request_id: mpInstance._Helpers.generateUniqueId(), request_timestamp_ms: new Date().getTime(), previous_mpid: mpid || null, @@ -160,7 +160,7 @@ export default function Identity( context: context, environment: (mpInstance._Store.SDKConfig.isDevelopmentMode ? 'development' - : 'production') as Environment, + : 'production'), request_id: mpInstance._Helpers.generateUniqueId(), request_timestamp_ms: new Date().getTime(), identity_changes: this.createIdentityChanges( @@ -171,15 +171,14 @@ export default function Identity( }, createIdentityChanges: function(previousIdentities: UserIdentities, newIdentities: UserIdentities) { - var identityChanges = []; - var key; + const identityChanges = []; if ( newIdentities && isObject(newIdentities) && previousIdentities && isObject(previousIdentities) ) { - for (key in newIdentities) { + for (const key in newIdentities) { identityChanges.push({ old_value: previousIdentities[key] || null, new_value: newIdentities[key], @@ -193,11 +192,11 @@ export default function Identity( // takes 2 UI objects keyed by name, combines them, returns them keyed by type combineUserIdentities: function(previousUIByName: UserIdentities, newUIByName: UserIdentities) { - var combinedUIByType = {}; - var combinedUIByName = extend({}, previousUIByName, newUIByName); + const combinedUIByType = {}; + const combinedUIByName = extend({}, previousUIByName, newUIByName); - for (var key in combinedUIByName) { - var type = Types.IdentityType.getIdentityType(key); + for (const key in combinedUIByName) { + const type = Types.IdentityType.getIdentityType(key); // this check removes anything that is not whitelisted as an identity type if (type !== false && type >= 0) { combinedUIByType[Types.IdentityType.getIdentityType(key)] = @@ -238,9 +237,9 @@ export default function Identity( }, convertToNative: function(identityApiData: IdentityApiData) { - var nativeIdentityRequest = []; + const nativeIdentityRequest = []; if (identityApiData && identityApiData.userIdentities) { - for (var key in identityApiData.userIdentities) { + for (const key in identityApiData.userIdentities) { if (identityApiData.userIdentities.hasOwnProperty(key)) { nativeIdentityRequest.push({ Type: Types.IdentityType.getIdentityType(key), @@ -271,19 +270,19 @@ export default function Identity( */ identify: function(identityApiData: IdentityApiData, callback: IdentityCallback) { // https://go.mparticle.com/work/SQDSDKS-6337 - var mpid, - currentUser = mpInstance.Identity.getCurrentUser(), - preProcessResult = mpInstance._Identity.IdentityRequest.preProcessIdentityRequest( - identityApiData, - callback, - Identify - ); + let mpid; + const currentUser = mpInstance.Identity.getCurrentUser(); + const preProcessResult = mpInstance._Identity.IdentityRequest.preProcessIdentityRequest( + identityApiData, + callback, + Identify + ); if (currentUser) { mpid = currentUser.getMPID(); } if (preProcessResult.valid) { - var identityApiRequest = mpInstance._Identity.IdentityRequest.createIdentityRequest( + const identityApiRequest = mpInstance._Identity.IdentityRequest.createIdentityRequest( preProcessResult.cleanedIdentities, Constants.platform, Constants.sdkVendor, @@ -367,20 +366,20 @@ export default function Identity( */ logout: function(identityApiData: IdentityApiData, callback: IdentityCallback) { // https://go.mparticle.com/work/SQDSDKS-6337 - var mpid, - currentUser = mpInstance.Identity.getCurrentUser(), - preProcessResult = mpInstance._Identity.IdentityRequest.preProcessIdentityRequest( - identityApiData, - callback, - Logout - ); + let mpid; + const currentUser = mpInstance.Identity.getCurrentUser(); + const preProcessResult = mpInstance._Identity.IdentityRequest.preProcessIdentityRequest( + identityApiData, + callback, + Logout + ); if (currentUser) { mpid = currentUser.getMPID(); } if (preProcessResult.valid) { - var evt, - identityApiRequest = mpInstance._Identity.IdentityRequest.createIdentityRequest( + let evt; + const identityApiRequest = mpInstance._Identity.IdentityRequest.createIdentityRequest( preProcessResult.cleanedIdentities, Constants.platform, Constants.sdkVendor, @@ -460,20 +459,20 @@ export default function Identity( */ login: function(identityApiData: IdentityApiData, callback: IdentityCallback) { // https://go.mparticle.com/work/SQDSDKS-6337 - var mpid, - currentUser = mpInstance.Identity.getCurrentUser(), - preProcessResult = mpInstance._Identity.IdentityRequest.preProcessIdentityRequest( - identityApiData, - callback, - Login - ); + let mpid; + const currentUser = mpInstance.Identity.getCurrentUser(); + const preProcessResult = mpInstance._Identity.IdentityRequest.preProcessIdentityRequest( + identityApiData, + callback, + Login + ); if (currentUser) { mpid = currentUser.getMPID(); } if (preProcessResult.valid) { - var identityApiRequest = mpInstance._Identity.IdentityRequest.createIdentityRequest( + const identityApiRequest = mpInstance._Identity.IdentityRequest.createIdentityRequest( preProcessResult.cleanedIdentities, Constants.platform, Constants.sdkVendor, @@ -558,22 +557,22 @@ export default function Identity( */ modify: function(identityApiData: IdentityApiData, callback: IdentityCallback) { // https://go.mparticle.com/work/SQDSDKS-6337 - var mpid, - currentUser = mpInstance.Identity.getCurrentUser(), - preProcessResult = mpInstance._Identity.IdentityRequest.preProcessIdentityRequest( - identityApiData, - callback, - Modify - ); + let mpid; + const currentUser = mpInstance.Identity.getCurrentUser(); + const preProcessResult = mpInstance._Identity.IdentityRequest.preProcessIdentityRequest( + identityApiData, + callback, + Modify + ); if (currentUser) { mpid = currentUser.getMPID(); } if (preProcessResult.valid) { - var newUserIdentities = + const newUserIdentities = identityApiData && identityApiData.userIdentities ? preProcessResult.cleanedIdentities.userIdentities : {}; - var identityApiRequest = mpInstance._Identity.IdentityRequest.createModifyIdentityRequest( + const identityApiRequest = mpInstance._Identity.IdentityRequest.createModifyIdentityRequest( currentUser ? currentUser.getUserIdentities().userIdentities : {}, @@ -636,7 +635,7 @@ export default function Identity( * @return {Object} the current user object */ getCurrentUser: function() { - var mpid; + let mpid; if (mpInstance._Store) { mpid = mpInstance._Store.mpid; if (mpid) { @@ -663,7 +662,7 @@ export default function Identity( * @return {Object} the user for mpid */ getUser: function(mpid: MPID) { - var persistence = mpInstance._Persistence.getPersistence(); + const persistence = mpInstance._Persistence.getPersistence(); if (persistence) { if ( persistence[mpid] && @@ -684,18 +683,18 @@ export default function Identity( * @return {Array} array of users */ getUsers: function() { - var persistence = mpInstance._Persistence.getPersistence(); - var users = []; + const persistence = mpInstance._Persistence.getPersistence(); + const users = []; if (persistence) { - for (var key in persistence) { + for (const key in persistence) { if (!Constants.SDKv2NonMPIDCookieKeys.hasOwnProperty(key)) { users.push(self.mParticleUser(key)); } } } users.sort(function(a, b) { - var aLastSeen = a.getLastSeenTime() || 0; - var bLastSeen = b.getLastSeenTime() || 0; + const aLastSeen = a.getLastSeenTime() || 0; + const bLastSeen = b.getLastSeenTime() || 0; if (aLastSeen > bLastSeen) { return -1; } else { @@ -712,7 +711,7 @@ export default function Identity( * @param {Function} [callback] A callback function that is called when the aliasUsers request completes */ aliasUsers: function(aliasRequest: IAliasRequest, callback: IAliasCallback) { - var message; + let message; if (!aliasRequest.destinationMpid || !aliasRequest.sourceMpid) { message = Messages.ValidationMessages.AliasMissingMpid; } @@ -757,7 +756,7 @@ export default function Identity( ' -> ' + aliasRequest.destinationMpid ); - var aliasRequestMessage = mpInstance._Identity.IdentityRequest.createAliasNetworkRequest( + const aliasRequestMessage = mpInstance._Identity.IdentityRequest.createAliasNetworkRequest( aliasRequest ) as IAliasRequest; mpInstance._IdentityAPIClient.sendAliasRequest( @@ -826,7 +825,7 @@ export default function Identity( ); return null; } - var startTime = sourceUser.getFirstSeenTime(); + let startTime = sourceUser.getFirstSeenTime(); if (!startTime) { mpInstance.Identity.getUsers().forEach(function(user) { if ( @@ -837,14 +836,14 @@ export default function Identity( } }); } - var minFirstSeenTimeMs = + const minFirstSeenTimeMs = new Date().getTime() - mpInstance._Store.SDKConfig.aliasMaxWindow * 24 * 60 * 60 * 1000; - var endTime = + const endTime = sourceUser.getLastSeenTime() || new Date().getTime(); //if the startTime is greater than $maxAliasWindow ago, adjust the startTime to the earliest allowed if (startTime < minFirstSeenTimeMs) { @@ -880,7 +879,6 @@ export default function Identity( * @class mParticle.Identity.getCurrentUser() */ this.mParticleUser = function(mpid?: MPID, isLoggedIn?: boolean): IMParticleUser { - var self = this; return { /** * Get user identities for current user @@ -891,7 +889,7 @@ export default function Identity( const currentUserIdentities = {}; const identities = mpInstance._Store.getUserIdentities(mpid); - for (var identityType in identities) { + for (const identityType in identities) { if (identities.hasOwnProperty(identityType)) { currentUserIdentities[ Types.IdentityType.getIdentityName( @@ -1027,7 +1025,7 @@ export default function Identity( mpInstance._SessionManager.resetSessionTimer(); if (isObject(userAttributes)) { if (mpInstance._Helpers.canLog()) { - for (var key in userAttributes) { + for (const key in userAttributes) { if (userAttributes.hasOwnProperty(key)) { this.setUserAttribute(key, userAttributes[key]); } @@ -1046,7 +1044,7 @@ export default function Identity( * @param {String} key */ removeUserAttribute: function(key: string) { - var cookies, userAttributes; + let cookies, userAttributes; mpInstance._SessionManager.resetSessionTimer(); if (!mpInstance._Helpers.Validators.isValidKeyValue(key)) { @@ -1064,7 +1062,7 @@ export default function Identity( userAttributes = this.getAllUserAttributes(); - var existingProp = mpInstance._Helpers.findKeyInObject( + const existingProp = mpInstance._Helpers.findKeyInObject( userAttributes, key ); @@ -1073,7 +1071,7 @@ export default function Identity( key = existingProp; } - var deletedUAKeyCopy = userAttributes[key] + const deletedUAKeyCopy = userAttributes[key] ? userAttributes[key].toString() : null; @@ -1170,7 +1168,7 @@ export default function Identity( ) { userAttributeChange = true; } else { - for (var i = 0; i < newValue.length; i++) { + for (let i = 0; i < newValue.length; i++) { if (previousUserAttributeValue[i] !== newValue[i]) { userAttributeChange = true; break; @@ -1205,7 +1203,7 @@ export default function Identity( * @method removeAllUserAttributes */ removeAllUserAttributes: function() { - var userAttributes; + let userAttributes; mpInstance._SessionManager.resetSessionTimer(); @@ -1221,7 +1219,7 @@ export default function Identity( mpInstance._APIClient.prepareForwardingStats ); if (userAttributes) { - for (var prop in userAttributes) { + for (const prop in userAttributes) { if (userAttributes.hasOwnProperty(prop)) { mpInstance._Forwarders.handleForwarderUserAttributes( 'removeUserAttribute', @@ -1240,11 +1238,11 @@ export default function Identity( * @return {Object} an object of only keys with array values. Example: { attr1: [1, 2, 3], attr2: ['a', 'b', 'c'] } */ getUserAttributesLists: function() { - var userAttributes, - userAttributesLists = {}; + let userAttributes; + const userAttributesLists = {}; userAttributes = this.getAllUserAttributes(); - for (var key in userAttributes) { + for (const key in userAttributes) { if ( userAttributes.hasOwnProperty(key) && Array.isArray(userAttributes[key]) @@ -1685,7 +1683,7 @@ export default function Identity( // https://go.mparticle.com/work/SQDSDKS-6354 const currentUserInMemory = this.IdentityAPI.getUser(mpid); - for (var identityType in newUserIdentities) { + for (const identityType in newUserIdentities) { // Verifies a change actually happened if ( prevUserIdentities[identityType] !== @@ -1716,7 +1714,7 @@ export default function Identity( isIdentityTypeNewToBatch: boolean, userInMemory: IMParticleUser ) { - var userIdentityChangeEvent; + let userIdentityChangeEvent; // https://go.mparticle.com/work/SQDSDKS-6439 userIdentityChangeEvent = mpInstance._ServerModel.createEventObject({ @@ -1747,7 +1745,7 @@ export default function Identity( deleted: boolean, user: IMParticleUser ): void { - var userAttributeChangeEvent = self.createUserAttributeChange( + const userAttributeChangeEvent = self.createUserAttributeChange( attributeKey, newUserAttributeValue, previousUserAttributeValue, @@ -1771,7 +1769,7 @@ export default function Identity( if (typeof previousUserAttributeValue === 'undefined') { previousUserAttributeValue = null; } - var userAttributeChangeEvent; + let userAttributeChangeEvent; if (newValue !== previousUserAttributeValue) { // https://go.mparticle.com/work/SQDSDKS-6439 userAttributeChangeEvent = mpInstance._ServerModel.createEventObject( From 85a0f3cb6d252fc2980ca14bb759fde15d354b26 Mon Sep 17 00:00:00 2001 From: Jaissica Date: Wed, 20 May 2026 21:48:53 -0400 Subject: [PATCH 3/4] split comma-separated declaration --- src/identity.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/identity.ts b/src/identity.ts index b1a6fd792..0ba7d405a 100644 --- a/src/identity.ts +++ b/src/identity.ts @@ -1044,7 +1044,8 @@ export default function Identity( * @param {String} key */ removeUserAttribute: function(key: string) { - let cookies, userAttributes; + let cookies; + let userAttributes; mpInstance._SessionManager.resetSessionTimer(); if (!mpInstance._Helpers.Validators.isValidKeyValue(key)) { From d408003557854177fbf6c6277d56d44f0ff0323d Mon Sep 17 00:00:00 2001 From: Jaissica Date: Mon, 25 May 2026 17:06:27 -0400 Subject: [PATCH 4/4] tighten identity type annotations per PR review --- src/forwarders.interfaces.ts | 2 + src/identity-utils.ts | 2 +- src/identity.interfaces.ts | 4 +- src/identity.ts | 71 ++++++++++++++++++++---------------- src/identityApiClient.ts | 7 ++-- 5 files changed, 47 insertions(+), 39 deletions(-) diff --git a/src/forwarders.interfaces.ts b/src/forwarders.interfaces.ts index 17caa1a67..de2d6d71e 100644 --- a/src/forwarders.interfaces.ts +++ b/src/forwarders.interfaces.ts @@ -85,6 +85,8 @@ export interface ConfiguredKit removeUserAttribute(key: string): string; setUserAttribute(key: string, value: string): string; setUserIdentity(id: UserIdentityId, type: UserIdentityType): void; + // Legacy method present on some kit implementations; invoked on logout. + logOut?: (evt: SDKEvent) => void; // TODO: https://go.mparticle.com/work/SQDSDKS-5156 isSandbox: boolean; diff --git a/src/identity-utils.ts b/src/identity-utils.ts index 3182c6448..d8e5d43b6 100644 --- a/src/identity-utils.ts +++ b/src/identity-utils.ts @@ -34,7 +34,7 @@ export type IParseCachedIdentityResponse = ( callback: IdentityCallback, identityApiData: IdentityApiData, identityMethod: string, - knownIdentities: IKnownIdentities | UserIdentities, + knownIdentities: IKnownIdentities, fromCachedIdentity: boolean ) => void; diff --git a/src/identity.interfaces.ts b/src/identity.interfaces.ts index 00301d5cc..36699fdac 100644 --- a/src/identity.interfaces.ts +++ b/src/identity.interfaces.ts @@ -227,7 +227,7 @@ export interface IIdentity { user: IMParticleUser ): IUserAttributeChangeEvent; createUserIdentityChange( - identityType: SDKIdentityTypeEnum | string, + identityType: SDKIdentityTypeEnum, newIdentity: string, oldIdentity: string, newCreatedThisBatch: boolean, @@ -239,7 +239,7 @@ export interface IIdentity { callback: IdentityCallback, identityApiData: IdentityApiData, method: IdentityAPIMethod, - knownIdentities: IKnownIdentities | UserIdentities, + knownIdentities: IKnownIdentities, parsingCachedResponse: boolean ): void; sendUserAttributeChangeEvent( diff --git a/src/identity.ts b/src/identity.ts index 0ba7d405a..e74271fb1 100644 --- a/src/identity.ts +++ b/src/identity.ts @@ -1,5 +1,6 @@ import Constants, { HTTP_OK } from './constants'; import Types, { IdentityType } from './types'; +import AudienceManager, { IAudienceMemberships } from './audienceManager'; import { cacheOrClearIdCache, createKnownIdentities, @@ -9,20 +10,6 @@ import { normalizeUserIdentityKeys, tryCacheIdentity, } from './identity-utils'; -import AudienceManager, { IAudienceMemberships } from './audienceManager'; -const { Messages, HTTPCodes, FeatureFlags, IdentityMethods } = Constants; -const { ErrorMessages } = Messages; -const { CacheIdentity } = FeatureFlags; -const { Identify, Modify, Login, Logout } = IdentityMethods; -import { - Environment, - generateDeprecationMessage, - isEmpty, - isFunction, - isObject, -} from './utils'; -import { hasMPIDAndUserLoginChanged, hasMPIDChanged } from './user-utils'; -import { processReadyQueue } from './pre-init-utils'; import { IdentityCallback, IIdentityResponse, @@ -30,19 +17,38 @@ import { mParticleUserCart, } from './identity-user-interfaces'; import { + AliasRequestScope, + IAliasCallback, + IAliasRequest, + IdentityAPIMethod, IIdentity, IIdentityAPIRequestData, - IdentityAPIMethod, - IAliasRequest, - IAliasCallback, - AliasRequestScope, SDKIdentityTypeEnum, } from './identity.interfaces'; +import { IdentitySearchCallback } from './identity/search'; import { IMParticleWebSDKInstance } from './mp-instance'; -import { IdentityApiData, UserIdentities, MPID, ConsentState, UserAttributesValue } from '@mparticle/web-sdk'; -import { Context } from '@mparticle/event-models'; +import { processReadyQueue } from './pre-init-utils'; import { BaseEvent, SDKEvent, SDKLoggerApi } from './sdkRuntimeModels'; -import { IdentitySearchCallback } from './identity/search'; +import { hasMPIDAndUserLoginChanged, hasMPIDChanged } from './user-utils'; +import { + generateDeprecationMessage, + isEmpty, + isFunction, + isObject, +} from './utils'; +import { + ConsentState, + IdentityApiData, + MPID, + UserAttributesValue, + UserIdentities, +} from '@mparticle/web-sdk'; +import { Context } from '@mparticle/event-models'; + +const { Messages, HTTPCodes, FeatureFlags, IdentityMethods } = Constants; +const { ErrorMessages } = Messages; +const { CacheIdentity } = FeatureFlags; +const { Identify, Modify, Login, Logout } = IdentityMethods; export default function Identity( this: IIdentity, @@ -423,9 +429,8 @@ export default function Identity( mpInstance._Store.activeForwarders.forEach(function( forwarder ) { - const fwd = forwarder as unknown as Record; - if (typeof fwd.logOut === 'function') { - fwd.logOut(evt); + if (typeof forwarder.logOut === 'function') { + forwarder.logOut(evt); } }); } @@ -1435,7 +1440,7 @@ export default function Identity( callback: IdentityCallback, identityApiData: IdentityApiData, method: IdentityAPIMethod, - knownIdentities: IKnownIdentities | UserIdentities, + knownIdentities: IKnownIdentities, parsingCachedResponse: boolean ): void { const prevUser = mpInstance.Identity.getUser(previousMPID); @@ -1687,17 +1692,19 @@ export default function Identity( for (const identityType in newUserIdentities) { // Verifies a change actually happened if ( - prevUserIdentities[identityType] !== - newUserIdentities[identityType] + prevUserIdentities[identityType as keyof UserIdentities] !== + newUserIdentities[identityType as keyof UserIdentities] ) { // If a new identity type was introduced when the identity changes // we need to notify the server so that the user profile is updated in // the mParticle UI. - const isNewUserIdentityType = !prevUserIdentities[identityType]; + const isNewUserIdentityType = !prevUserIdentities[ + identityType as keyof UserIdentities + ]; const userIdentityChangeEvent = self.createUserIdentityChange( - identityType, - newUserIdentities[identityType], - prevUserIdentities[identityType], + identityType as SDKIdentityTypeEnum, + newUserIdentities[identityType as keyof UserIdentities], + prevUserIdentities[identityType as keyof UserIdentities], isNewUserIdentityType, currentUserInMemory ); @@ -1709,7 +1716,7 @@ export default function Identity( }; this.createUserIdentityChange = function( - identityType: string, + identityType: SDKIdentityTypeEnum, newIdentity: string, oldIdentity: string, isIdentityTypeNewToBatch: boolean, diff --git a/src/identityApiClient.ts b/src/identityApiClient.ts index 19d280dad..f33351de9 100644 --- a/src/identityApiClient.ts +++ b/src/identityApiClient.ts @@ -5,7 +5,7 @@ import { XHRUploader, IFetchPayload, } from './uploaders'; -import { CACHE_HEADER } from './identity-utils'; +import { CACHE_HEADER, IKnownIdentities } from './identity-utils'; import { obfuscateData, parseNumber, valueof } from './utils'; import { IAliasCallback, @@ -18,7 +18,6 @@ import { import { IdentityApiData, MPID, - UserIdentities, } from '@mparticle/web-sdk'; import { IdentityCallback, @@ -44,7 +43,7 @@ export interface IIdentityApiClient { originalIdentityApiData: IdentityApiData, parseIdentityResponse: IIdentity['parseIdentityResponse'], mpid: MPID, - knownIdentities?: UserIdentities + knownIdentities?: IKnownIdentities ) => Promise; getUploadUrl: (method: IdentityAPIMethod, mpid: MPID) => string; getIdentityResponseFromFetch: ( @@ -193,7 +192,7 @@ export default function IdentityAPIClient( originalIdentityApiData: IdentityApiData, parseIdentityResponse: IIdentity['parseIdentityResponse'], mpid: MPID, - knownIdentities?: UserIdentities + knownIdentities?: IKnownIdentities ) { if (mpInstance._RoktManager?.isInitialized) { mpInstance._Store.identifyRequestCount = (mpInstance._Store.identifyRequestCount || 0) + 1;