From 2578b9a30aa4d54cf82631fa4a6ef5171c87eb3a Mon Sep 17 00:00:00 2001 From: Robert Ing Date: Thu, 21 May 2026 20:38:31 -0400 Subject: [PATCH 1/9] feat: Report deprecated method usage through logging dispatcher (#1270) --- src/consent.ts | 10 ++- src/identity.js | 110 +++++++++++++++++------- src/mp-instance.ts | 86 ++++++++++++------ src/reporting/deprecatedMethodLogger.ts | 19 ++++ src/reporting/types.ts | 1 + src/sessionManager.ts | 18 ++-- test/jest/reportingLogger.spec.ts | 41 +++++++++ 7 files changed, 216 insertions(+), 69 deletions(-) create mode 100644 src/reporting/deprecatedMethodLogger.ts diff --git a/src/consent.ts b/src/consent.ts index 81ae944cd..bcf1f6258 100644 --- a/src/consent.ts +++ b/src/consent.ts @@ -9,6 +9,7 @@ import KitFilterHelper from './kitFilterHelper'; import Constants from './constants'; import { IMParticleUser } from './identity-user-interfaces'; import { IMParticleWebSDKInstance } from './mp-instance'; +import { logDeprecatedMethodUsage } from './reporting/deprecatedMethodLogger'; const { CCPAPurpose } = Constants; @@ -505,8 +506,13 @@ export default function Consent(this: IConsent, mpInstance: IMParticleWebSDKInst // TODO: Can we remove this? It is deprecated. function removeCCPAState(this: ConsentState) { - mpInstance.Logger.warning( - 'removeCCPAState is deprecated and will be removed in a future release; use removeCCPAConsentState instead' + logDeprecatedMethodUsage( + { + methodName: 'Consent.removeCCPAState', + warningMessage: 'removeCCPAState is deprecated and will be removed in a future release; use removeCCPAConsentState instead', + }, + mpInstance.Logger, + mpInstance._LoggingDispatcher ); // @ts-ignore return removeCCPAConsentState(); diff --git a/src/identity.js b/src/identity.js index 29c9dacb9..c9e5dbe4d 100644 --- a/src/identity.js +++ b/src/identity.js @@ -20,6 +20,7 @@ import { } from './utils'; import { hasMPIDAndUserLoginChanged, hasMPIDChanged } from './user-utils'; import { processReadyQueue } from './pre-init-utils'; +import { logDeprecatedMethodUsage } from './reporting/deprecatedMethodLogger'; export default function Identity(mpInstance) { const { getFeatureFlag, extend } = mpInstance._Helpers; @@ -1252,8 +1253,14 @@ export default function Identity(mpInstance) { * @return a cart object */ getCart: function() { - mpInstance.Logger.warning( - 'Deprecated function Identity.getCurrentUser().getCart() will be removed in future releases' + logDeprecatedMethodUsage( + { + methodName: 'Identity.getCurrentUser().getCart()', + warningMessage: + 'Deprecated function Identity.getCurrentUser().getCart() will be removed in future releases', + }, + mpInstance.Logger, + mpInstance._LoggingDispatcher ); return self.mParticleUserCart(); }, @@ -1334,13 +1341,18 @@ export default function Identity(mpInstance) { * @deprecated */ add: function() { - mpInstance.Logger.warning( - generateDeprecationMessage( - 'Identity.getCurrentUser().getCart().add()', - true, - 'eCommerce.logProductAction()', - 'https://docs.mparticle.com/developers/sdk/web/commerce-tracking' - ) + logDeprecatedMethodUsage( + { + methodName: 'Identity.getCurrentUser().getCart().add()', + warningMessage: generateDeprecationMessage( + 'Identity.getCurrentUser().getCart().add()', + true, + 'eCommerce.logProductAction()', + 'https://docs.mparticle.com/developers/sdk/web/commerce-tracking' + ), + }, + mpInstance.Logger, + mpInstance._LoggingDispatcher ); }, /** @@ -1349,13 +1361,19 @@ export default function Identity(mpInstance) { * @deprecated */ remove: function() { - mpInstance.Logger.warning( - generateDeprecationMessage( - 'Identity.getCurrentUser().getCart().remove()', - true, - 'eCommerce.logProductAction()', - 'https://docs.mparticle.com/developers/sdk/web/commerce-tracking' - ) + logDeprecatedMethodUsage( + { + methodName: + 'Identity.getCurrentUser().getCart().remove()', + warningMessage: generateDeprecationMessage( + 'Identity.getCurrentUser().getCart().remove()', + true, + 'eCommerce.logProductAction()', + 'https://docs.mparticle.com/developers/sdk/web/commerce-tracking' + ), + }, + mpInstance.Logger, + mpInstance._LoggingDispatcher ); }, /** @@ -1364,13 +1382,19 @@ export default function Identity(mpInstance) { * @deprecated */ clear: function() { - mpInstance.Logger.warning( - generateDeprecationMessage( - 'Identity.getCurrentUser().getCart().clear()', - true, - '', - 'https://docs.mparticle.com/developers/sdk/web/commerce-tracking' - ) + logDeprecatedMethodUsage( + { + methodName: + 'Identity.getCurrentUser().getCart().clear()', + warningMessage: generateDeprecationMessage( + 'Identity.getCurrentUser().getCart().clear()', + true, + '', + 'https://docs.mparticle.com/developers/sdk/web/commerce-tracking' + ), + }, + mpInstance.Logger, + mpInstance._LoggingDispatcher ); }, /** @@ -1380,13 +1404,19 @@ export default function Identity(mpInstance) { * @deprecated */ getCartProducts: function() { - mpInstance.Logger.warning( - generateDeprecationMessage( - 'Identity.getCurrentUser().getCart().getCartProducts()', - true, - 'eCommerce.logProductAction()', - 'https://docs.mparticle.com/developers/sdk/web/commerce-tracking' - ) + logDeprecatedMethodUsage( + { + methodName: + 'Identity.getCurrentUser().getCart().getCartProducts()', + warningMessage: generateDeprecationMessage( + 'Identity.getCurrentUser().getCart().getCartProducts()', + true, + 'eCommerce.logProductAction()', + 'https://docs.mparticle.com/developers/sdk/web/commerce-tracking' + ), + }, + mpInstance.Logger, + mpInstance._LoggingDispatcher ); return []; }, @@ -1540,7 +1570,8 @@ export default function Identity(mpInstance) { prevUser, newUser, identityApiData, - mpInstance.Logger + mpInstance.Logger, + mpInstance._LoggingDispatcher ); const persistence = mpInstance._Persistence.getPersistence(); @@ -1775,14 +1806,27 @@ export default function Identity(mpInstance) { } // https://go.mparticle.com/work/SQDSDKS-6359 -function tryOnUserAlias(previousUser, newUser, identityApiData, logger) { +function tryOnUserAlias( + previousUser, + newUser, + identityApiData, + logger, + loggingDispatcher +) { if ( identityApiData && identityApiData.onUserAlias && isFunction(identityApiData.onUserAlias) ) { try { - logger.warning(generateDeprecationMessage('onUserAlias')); + logDeprecatedMethodUsage( + { + methodName: 'onUserAlias', + warningMessage: generateDeprecationMessage('onUserAlias'), + }, + logger, + loggingDispatcher + ); identityApiData.onUserAlias(previousUser, newUser); } catch (e) { logger.error( diff --git a/src/mp-instance.ts b/src/mp-instance.ts index 618b19ab3..4b9078573 100644 --- a/src/mp-instance.ts +++ b/src/mp-instance.ts @@ -55,6 +55,7 @@ import CookieConsentManager, { ICookieConsentManager } from './cookieConsentMana import { ErrorReportingDispatcher } from './reporting/errorReportingDispatcher'; import { LoggingDispatcher } from './reporting/loggingDispatcher'; import { IErrorReportingService, ILoggingService } from './reporting/types'; +import { logDeprecatedMethodUsage } from './reporting/deprecatedMethodLogger'; export interface IErrorLogMessage { message?: string; @@ -772,13 +773,18 @@ export default function mParticleInstance(this: IMParticleWebSDKInstance, instan * @deprecated */ add: function(product, logEventBoolean) { - self.Logger.warning( - generateDeprecationMessage( - 'eCommerce.Cart.add()', - true, - 'eCommerce.logProductAction()', - 'https://docs.mparticle.com/developers/sdk/web/commerce-tracking' - ) + logDeprecatedMethodUsage( + { + methodName: 'mPInstance.eCommerce.Cart.add()', + warningMessage: generateDeprecationMessage( + 'eCommerce.Cart.add()', + true, + 'eCommerce.logProductAction()', + 'https://docs.mparticle.com/developers/sdk/web/commerce-tracking' + ), + }, + self.Logger, + self._LoggingDispatcher ); }, /** @@ -789,13 +795,18 @@ export default function mParticleInstance(this: IMParticleWebSDKInstance, instan * @deprecated */ remove: function(product, logEventBoolean) { - self.Logger.warning( - generateDeprecationMessage( - 'eCommerce.Cart.remove()', - true, - 'eCommerce.logProductAction()', - 'https://docs.mparticle.com/developers/sdk/web/commerce-tracking' - ) + logDeprecatedMethodUsage( + { + methodName: 'mPInstance.eCommerce.Cart.remove()', + warningMessage: generateDeprecationMessage( + 'eCommerce.Cart.remove()', + true, + 'eCommerce.logProductAction()', + 'https://docs.mparticle.com/developers/sdk/web/commerce-tracking' + ), + }, + self.Logger, + self._LoggingDispatcher ); }, /** @@ -804,13 +815,18 @@ export default function mParticleInstance(this: IMParticleWebSDKInstance, instan * @deprecated */ clear: function() { - self.Logger.warning( - generateDeprecationMessage( - 'eCommerce.Cart.clear()', - true, - '', - 'https://docs.mparticle.com/developers/sdk/web/commerce-tracking' - ) + logDeprecatedMethodUsage( + { + methodName: 'mPInstance.eCommerce.Cart.clear()', + warningMessage: generateDeprecationMessage( + 'eCommerce.Cart.clear()', + true, + '', + 'https://docs.mparticle.com/developers/sdk/web/commerce-tracking' + ), + }, + self.Logger, + self._LoggingDispatcher ); }, }, @@ -940,8 +956,13 @@ export default function mParticleInstance(this: IMParticleWebSDKInstance, instan * @deprecated */ logCheckout: function(step, option, attrs, customFlags) { - self.Logger.warning( - 'mParticle.logCheckout is deprecated, please use mParticle.logProductAction instead' + logDeprecatedMethodUsage( + { + methodName: 'mParticle.logCheckout', + warningMessage: 'mParticle.logCheckout is deprecated, please use mParticle.logProductAction instead', + }, + self.Logger, + self._LoggingDispatcher ); if (!self._Store.isInitialized) { @@ -1020,8 +1041,13 @@ export default function mParticleInstance(this: IMParticleWebSDKInstance, instan attrs, customFlags ) { - self.Logger.warning( - 'mParticle.logPurchase is deprecated, please use mParticle.logProductAction instead' + logDeprecatedMethodUsage( + { + methodName: 'mParticle.logPurchase', + warningMessage: 'mParticle.logPurchase is deprecated, please use mParticle.logProductAction instead', + }, + self.Logger, + self._LoggingDispatcher ); if (!self._Store.isInitialized) { self.ready(function() { @@ -1132,8 +1158,13 @@ export default function mParticleInstance(this: IMParticleWebSDKInstance, instan attrs, customFlags ) { - self.Logger.warning( - 'mParticle.logRefund is deprecated, please use mParticle.logProductAction instead' + logDeprecatedMethodUsage( + { + methodName: 'mParticle.logRefund', + warningMessage: 'mParticle.logRefund is deprecated, please use mParticle.logProductAction instead', + }, + self.Logger, + self._LoggingDispatcher ); if (!self._Store.isInitialized) { self.ready(function() { @@ -1741,4 +1772,3 @@ function queueIfNotInitialized(func, self) { }); return true; } - diff --git a/src/reporting/deprecatedMethodLogger.ts b/src/reporting/deprecatedMethodLogger.ts new file mode 100644 index 000000000..33a9b55ed --- /dev/null +++ b/src/reporting/deprecatedMethodLogger.ts @@ -0,0 +1,19 @@ +import { ErrorCodes, ILoggingService } from './types'; +import { SDKLoggerApi } from '../sdkRuntimeModels'; + +interface DeprecatedMethodUsage { + methodName: string; + warningMessage: string; +} + +export function logDeprecatedMethodUsage( + usage: DeprecatedMethodUsage, + logger: Pick, + loggingDispatcher: ILoggingService | undefined +): void { + logger.warning(usage.warningMessage); + loggingDispatcher?.log({ + message: usage.methodName, + code: ErrorCodes.MP_DEPRECATED_METHOD_USAGE, + }); +} diff --git a/src/reporting/types.ts b/src/reporting/types.ts index 7378ca8f0..ba06ef73d 100644 --- a/src/reporting/types.ts +++ b/src/reporting/types.ts @@ -6,6 +6,7 @@ export const ErrorCodes = { IDENTITY_REQUEST: 'IDENTITY_REQUEST', IDENTITY_MISMATCH: 'IDENTITY_MISMATCH', ROKT_KIT_ATTACHED: 'ROKT_KIT_ATTACHED', + MP_DEPRECATED_METHOD_USAGE: 'MP_DEPRECATED_METHOD_USAGE', } as const; export type ErrorCodes = valueof; diff --git a/src/sessionManager.ts b/src/sessionManager.ts index 4b6cf68a4..418c4507e 100644 --- a/src/sessionManager.ts +++ b/src/sessionManager.ts @@ -6,6 +6,7 @@ import { generateDeprecationMessage } from './utils'; import { IMParticleUser } from './identity-user-interfaces'; import { IMParticleWebSDKInstance } from './mp-instance'; import { hasIdentityRequestChanged, hasExplicitIdentifier } from './identity-utils'; +import { logDeprecatedMethodUsage } from './reporting/deprecatedMethodLogger'; const { Messages } = Constants; @@ -67,12 +68,17 @@ export default function SessionManager( }; this.getSession = function (): string { - mpInstance.Logger.warning( - generateDeprecationMessage( - 'SessionManager.getSession()', - false, - 'SessionManager.getSessionId()' - ) + logDeprecatedMethodUsage( + { + methodName: 'SessionManager.getSession()', + warningMessage: generateDeprecationMessage( + 'SessionManager.getSession()', + false, + 'SessionManager.getSessionId()' + ), + }, + mpInstance.Logger, + mpInstance._LoggingDispatcher ); return this.getSessionId(); }; diff --git a/test/jest/reportingLogger.spec.ts b/test/jest/reportingLogger.spec.ts index 82ee5204d..ca4e1d700 100644 --- a/test/jest/reportingLogger.spec.ts +++ b/test/jest/reportingLogger.spec.ts @@ -1,6 +1,7 @@ import { ErrorReportingDispatcher } from '../../src/reporting/errorReportingDispatcher'; import { LoggingDispatcher } from '../../src/reporting/loggingDispatcher'; import { IErrorReportingService, ILoggingService, ISDKError, ISDKLogEntry, WSDKErrorSeverity, ErrorCodes } from '../../src/reporting/types'; +import { logDeprecatedMethodUsage } from '../../src/reporting/deprecatedMethodLogger'; describe('ErrorReportingDispatcher', () => { let dispatcher: ErrorReportingDispatcher; @@ -128,3 +129,43 @@ describe('LoggingDispatcher', () => { expect(service2.log).toHaveBeenCalledWith(entry); }); }); + +describe('logDeprecatedMethodUsage', () => { + it('keeps the console warning and emits structured usage details', () => { + const warning = jest.fn(); + const log = jest.fn(); + + logDeprecatedMethodUsage( + { + methodName: 'mParticle.logCheckout', + warningMessage: 'mParticle.logCheckout is deprecated, please use mParticle.logProductAction instead', + }, + { warning }, + { log } + ); + + expect(warning).toHaveBeenCalledWith( + 'mParticle.logCheckout is deprecated, please use mParticle.logProductAction instead' + ); + expect(log).toHaveBeenCalledWith({ + message: 'mParticle.logCheckout', + code: ErrorCodes.MP_DEPRECATED_METHOD_USAGE, + }); + }); + + it('does not require a registered logging dispatcher', () => { + const warning = jest.fn(); + + expect(() => logDeprecatedMethodUsage( + { + methodName: 'onUserAlias', + warningMessage: 'onUserAlias is a deprecated method and will be removed in future releases.', + }, + { warning }, + undefined + )).not.toThrow(); + expect(warning).toHaveBeenCalledWith( + 'onUserAlias is a deprecated method and will be removed in future releases.' + ); + }); +}); From 1634b3a5ce3f527fd132ddf031d53d75e85830be Mon Sep 17 00:00:00 2001 From: Jaissica Date: Mon, 13 Apr 2026 20:42:04 -0400 Subject: [PATCH 2/9] refactor: update forwarder module to TS --- src/forwarders.interfaces.ts | 65 +++++++- src/{forwarders.js => forwarders.ts} | 239 +++++++++++++++++---------- src/sdkRuntimeModels.ts | 6 +- src/store.ts | 2 +- 4 files changed, 225 insertions(+), 87 deletions(-) rename src/{forwarders.js => forwarders.ts} (75%) diff --git a/src/forwarders.interfaces.ts b/src/forwarders.interfaces.ts index 17caa1a67..d13328e27 100644 --- a/src/forwarders.interfaces.ts +++ b/src/forwarders.interfaces.ts @@ -1,8 +1,16 @@ import { SDKEvent, SDKEventCustomFlags } from './sdkRuntimeModels'; import { Dictionary } from './utils'; -import { IKitConfigs, IKitFilterSettings } from './configAPIClient'; +import { + IKitConfigs, + IKitFilterSettings, + IConfigResponse, + IFilteringUserAttributeValue, +} from './configAPIClient'; +import { IForwardingStatsData } from './apiClient'; import { IdentityApiData, IdentityType } from '@mparticle/web-sdk'; import { Batch } from '@mparticle/event-models'; +import { AsyncUploader } from './uploaders'; +import { IPixelConfiguration } from './cookieSyncManager'; import { IMParticleUser, @@ -81,6 +89,7 @@ export interface ConfiguredKit ): string; onUserIdentified(user: IMParticleUser): string; process(event: SDKEvent): string; + processBatch?(batch: Batch): string; setOptOut(isOptingOut: boolean): string; removeUserAttribute(key: string): string; setUserAttribute(key: string, value: string): string; @@ -140,3 +149,57 @@ export type forwardingStatsCallback = ( forwarder: ConfiguredKit, event: SDKEvent ) => void; + +export interface IForwarders { + forwarderStatsUploader: AsyncUploader; + initForwarders( + userIdentities: ISDKUserIdentity[], + forwardingStatsCallback: forwardingStatsCallback + ): void; + isEnabledForUserAttributes( + filterObject: IFilteringUserAttributeValue, + user: IMParticleUser + ): boolean; + isEnabledForUnknownUser( + excludeAnonymousUserBoolean: boolean, + user: IMParticleUser + ): boolean; + applyToForwarders(functionName: string, functionArgs: unknown): void; + sendEventToForwarders(event: SDKEvent): void; + sendBatchToForwarders(batch: Batch): void; + handleForwarderUserAttributes( + functionNameKey: string, + key: string, + value: string + ): void; + setForwarderUserIdentities(userIdentities: ISDKUserIdentity[]): void; + setForwarderOnUserIdentified(user: IMParticleUser): void; + setForwarderOnIdentityComplete( + user: IMParticleUser, + identityMethod: string + ): void; + getForwarderStatsQueue(): IForwardingStatsData[]; + setForwarderStatsQueue(queue: IForwardingStatsData[]): void; + processForwarders( + config: IConfigResponse, + forwardingStatsCallback: forwardingStatsCallback + ): void; + processUIEnabledKits(config: IConfigResponse): void; + returnKitConstructors(): Dictionary; + configureUIEnabledKit( + configuration: IKitConfigs, + kits: Dictionary + ): void; + processSideloadedKits(mpConfig: IConfigResponse): void; + configureSideloadedKit(kitConstructor: RegisteredKit): void; + returnConfiguredKit( + forwarder: RegisteredKit, + config: Partial + ): MPForwarder; + configurePixel(settings: IPixelConfiguration): void; + processPixelConfigs(config: IConfigResponse): void; + sendSingleForwardingStatsToServer( + forwardingStatsData: IForwardingStatsData + ): Promise; +} + diff --git a/src/forwarders.js b/src/forwarders.ts similarity index 75% rename from src/forwarders.js rename to src/forwarders.ts index 889e339dc..6edfec87f 100644 --- a/src/forwarders.js +++ b/src/forwarders.ts @@ -2,7 +2,7 @@ import filteredMparticleUser from './filteredMparticleUser'; import { isEmpty, extend } from './utils'; import KitFilterHelper from './kitFilterHelper'; import Constants from './constants'; -import APIClient from './apiClient'; +import APIClient, { IForwardingStatsData } from './apiClient'; import { isBlockedByForwardingRule, isBlockedByEventFilter, @@ -12,11 +12,36 @@ import { filterBatchEventAttributes, filterBatchIdentities, } from './forwarder-utils'; +import { IMParticleWebSDKInstance } from './mp-instance'; +import { SDKEvent } from './sdkRuntimeModels'; +import { + IForwarders, + MPForwarder, + RegisteredKit, + forwardingStatsCallback as ForwardingStatsCallback, + ConfiguredKit, +} from './forwarders.interfaces'; +import { + IConfigResponse, + IKitConfigs, + IFilteringUserAttributeValue, + IKitFilterSettings, +} from './configAPIClient'; +import { IPixelConfiguration } from './cookieSyncManager'; +import { Batch } from '@mparticle/event-models'; +import { IMParticleUser, ISDKUserIdentity } from './identity-user-interfaces'; +import KitBlocker from './kitBlocking'; +import { Dictionary } from './utils'; const { Modify, Identify, Login, Logout } = Constants.IdentityMethods; -export default function Forwarders(mpInstance, kitBlocker) { - var self = this; +export default function Forwarders( + this: IForwarders, + mpInstance: IMParticleWebSDKInstance, + kitBlocker: KitBlocker +): void { + const self = this; + this.forwarderStatsUploader = new APIClient( mpInstance, kitBlocker @@ -27,8 +52,11 @@ export default function Forwarders(mpInstance, kitBlocker) { removeUserAttribute: 'removeUserAttribute', }; - this.initForwarders = function(userIdentities, forwardingStatsCallback) { - var user = mpInstance.Identity.getCurrentUser(); + this.initForwarders = function( + userIdentities: ISDKUserIdentity[], + forwardingStatsCallback: ForwardingStatsCallback + ): void { + const user = mpInstance.Identity.getCurrentUser(); if ( !mpInstance._Store.webviewBridgeEnabled && mpInstance._Store.configuredForwarders @@ -53,7 +81,7 @@ export default function Forwarders(mpInstance, kitBlocker) { return false; } if ( - !self.isEnabledForUserAttributes( + !(self.isEnabledForUserAttributes as Function)( forwarder.filteringUserAttributeValue, user ) @@ -61,7 +89,7 @@ export default function Forwarders(mpInstance, kitBlocker) { return false; } if ( - !self.isEnabledForUnknownUser( + !(self.isEnabledForUnknownUser as Function)( forwarder.excludeAnonymousUser, user ) @@ -69,7 +97,7 @@ export default function Forwarders(mpInstance, kitBlocker) { return false; } - var filteredUserIdentities = mpInstance._Helpers.filterUserIdentities( + const filteredUserIdentities = (mpInstance._Helpers.filterUserIdentities as Function)( userIdentities, forwarder.userIdentityFilters ); @@ -100,7 +128,10 @@ export default function Forwarders(mpInstance, kitBlocker) { } }; - this.isEnabledForUserAttributes = function(filterObject, user) { + this.isEnabledForUserAttributes = function( + filterObject: IFilteringUserAttributeValue, + user: IMParticleUser + ): boolean { if ( !filterObject || !mpInstance._Helpers.isObject(filterObject) || @@ -109,7 +140,9 @@ export default function Forwarders(mpInstance, kitBlocker) { return true; } - var attrHash, valueHash, userAttributes; + let attrHash: string; + let valueHash: string; + let userAttributes: Record; if (!user) { return false; @@ -117,7 +150,7 @@ export default function Forwarders(mpInstance, kitBlocker) { userAttributes = user.getAllUserAttributes(); } - var isMatch = false; + let isMatch = false; try { if ( @@ -125,7 +158,7 @@ export default function Forwarders(mpInstance, kitBlocker) { mpInstance._Helpers.isObject(userAttributes) && Object.keys(userAttributes).length ) { - for (var attrName in userAttributes) { + for (const attrName in userAttributes) { if (userAttributes.hasOwnProperty(attrName)) { attrHash = KitFilterHelper.hashAttributeConditionalForwarding( attrName @@ -156,7 +189,10 @@ export default function Forwarders(mpInstance, kitBlocker) { } }; - this.isEnabledForUnknownUser = function(excludeAnonymousUserBoolean, user) { + this.isEnabledForUnknownUser = function( + excludeAnonymousUserBoolean: boolean, + user: IMParticleUser + ): boolean { if (!user || !user.isLoggedIn()) { if (excludeAnonymousUserBoolean) { return false; @@ -165,39 +201,42 @@ export default function Forwarders(mpInstance, kitBlocker) { return true; }; - this.applyToForwarders = function(functionName, functionArgs) { + this.applyToForwarders = function( + functionName: string, + functionArgs: string[] + ): void { if (mpInstance._Store.activeForwarders.length) { mpInstance._Store.activeForwarders.forEach(function(forwarder) { - var forwarderFunction = forwarder[functionName]; + const forwarderFunction = forwarder[functionName]; if (forwarderFunction) { try { - var result = forwarder[functionName](functionArgs); + const result = forwarder[functionName](functionArgs); if (result) { - mpInstance.Logger.verbose(result); + mpInstance.Logger.verbose(result as string); } } catch (e) { - mpInstance.Logger.verbose(e); + mpInstance.Logger.verbose(e as string); } } }); } }; - this.sendEventToForwarders = function(event) { - let clonedEvent; - let hashedEventName; - let hashedEventType; + this.sendEventToForwarders = function(event: SDKEvent): void { + let clonedEvent: SDKEvent; + let hashedEventName: number; + let hashedEventType: number; if ( !mpInstance._Store.webviewBridgeEnabled && mpInstance._Store.activeForwarders ) { - hashedEventName = KitFilterHelper.hashEventName( + hashedEventName = (KitFilterHelper.hashEventName as Function)( event.EventName, event.EventCategory ); - hashedEventType = KitFilterHelper.hashEventType( + hashedEventType = (KitFilterHelper.hashEventType as Function)( event.EventCategory ); @@ -209,7 +248,7 @@ export default function Forwarders(mpInstance, kitBlocker) { const forwarder = mpInstance._Store.activeForwarders[i]; if ( - isBlockedByForwardingRule( + (isBlockedByForwardingRule as Function)( event.EventDataType, event.EventAttributes, forwarder @@ -222,7 +261,7 @@ export default function Forwarders(mpInstance, kitBlocker) { clonedEvent = extend(true, {}, event); if ( - isBlockedByEventFilter( + (isBlockedByEventFilter as Function)( event.EventDataType, hashedEventName, hashedEventType, @@ -232,7 +271,7 @@ export default function Forwarders(mpInstance, kitBlocker) { continue; } - clonedEvent.EventAttributes = filterEventAttributes( + clonedEvent.EventAttributes = (filterEventAttributes as Function)( event.EventDataType, event.EventCategory, event.EventName, @@ -241,13 +280,13 @@ export default function Forwarders(mpInstance, kitBlocker) { ); // Check user identity filtering rules - clonedEvent.UserIdentities = filterUserIdentities( + clonedEvent.UserIdentities = (filterUserIdentities as Function)( clonedEvent.UserIdentities, forwarder.userIdentityFilters ); // Check user attribute filtering rules - clonedEvent.UserAttributes = KitFilterHelper.filterUserAttributes( + clonedEvent.UserAttributes = (KitFilterHelper.filterUserAttributes as Function)( clonedEvent.UserAttributes, forwarder.userAttributeFilters ); @@ -266,7 +305,7 @@ export default function Forwarders(mpInstance, kitBlocker) { } }; - this.sendBatchToForwarders = function(batch) { + this.sendBatchToForwarders = function(batch: Batch): void { if ( mpInstance._Store.webviewBridgeEnabled || !mpInstance._Store.activeForwarders @@ -286,15 +325,15 @@ export default function Forwarders(mpInstance, kitBlocker) { batchCopy.events = batchCopy.events.filter(function( batchEvent ) { - return isBatchEventAllowed(batchEvent, forwarder); + return (isBatchEventAllowed as Function)(batchEvent, forwarder); }); batchCopy.events.forEach(function(batchEvent) { - filterBatchEventAttributes(batchEvent, forwarder); + (filterBatchEventAttributes as Function)(batchEvent, forwarder); }); } - batchCopy.user_identities = filterBatchIdentities( + batchCopy.user_identities = (filterBatchIdentities as Function)( batchCopy.user_identities, forwarder.userIdentityFilters ); @@ -313,15 +352,19 @@ export default function Forwarders(mpInstance, kitBlocker) { const result = forwarder.processBatch(batchCopy); if (result) { - mpInstance.Logger.verbose(result); + mpInstance.Logger.verbose(result as string); } } catch (e) { - mpInstance.Logger.verbose(e); + mpInstance.Logger.verbose(e as string); } } }; - this.handleForwarderUserAttributes = function(functionNameKey, key, value) { + this.handleForwarderUserAttributes = function( + functionNameKey: string, + key: string, + value: string + ): void { if ( (kitBlocker && kitBlocker.isAttributeKeyBlocked(key)) || !mpInstance._Store.activeForwarders.length @@ -341,7 +384,7 @@ export default function Forwarders(mpInstance, kitBlocker) { return; } try { - let result; + let result: string; if ( functionNameKey === @@ -359,24 +402,28 @@ export default function Forwarders(mpInstance, kitBlocker) { mpInstance.Logger.verbose(result); } } catch (e) { - mpInstance.Logger.error(e); + mpInstance.Logger.error(e as string); } }); }; // TODO: https://go.mparticle.com/work/SQDSDKS-6036 - this.setForwarderUserIdentities = function(userIdentities) { + this.setForwarderUserIdentities = function( + userIdentities: ISDKUserIdentity[] + ): void { mpInstance._Store.activeForwarders.forEach(function(forwarder) { - var filteredUserIdentities = mpInstance._Helpers.filterUserIdentities( + const filteredUserIdentities = (mpInstance._Helpers.filterUserIdentities as Function)( userIdentities, forwarder.userIdentityFilters - ); + ) as ISDKUserIdentity[]; if (forwarder.setUserIdentity) { - filteredUserIdentities.forEach(function(identity) { - var result = forwarder.setUserIdentity( + filteredUserIdentities.forEach(function( + identity: ISDKUserIdentity + ) { + const result = (forwarder.setUserIdentity as Function)( identity.Identity, identity.Type - ); + ) as string; if (result) { mpInstance.Logger.verbose(result); } @@ -385,16 +432,18 @@ export default function Forwarders(mpInstance, kitBlocker) { }); }; - this.setForwarderOnUserIdentified = function(user) { + this.setForwarderOnUserIdentified = function( + user: IMParticleUser + ): void { mpInstance._Store.activeForwarders.forEach(function(forwarder) { - var filteredUser = filteredMparticleUser( + const filteredUser = filteredMparticleUser( user.getMPID(), forwarder, mpInstance, kitBlocker ); if (forwarder.onUserIdentified) { - var result = forwarder.onUserIdentified(filteredUser); + const result = forwarder.onUserIdentified(filteredUser); if (result) { mpInstance.Logger.verbose(result); } @@ -402,11 +451,14 @@ export default function Forwarders(mpInstance, kitBlocker) { }); }; - this.setForwarderOnIdentityComplete = function(user, identityMethod) { - var result; + this.setForwarderOnIdentityComplete = function( + user: IMParticleUser, + identityMethod: string + ): void { + let result: string; mpInstance._Store.activeForwarders.forEach(function(forwarder) { - var filteredUser = filteredMparticleUser( + const filteredUser = filteredMparticleUser( user.getMPID(), forwarder, mpInstance, @@ -459,12 +511,14 @@ export default function Forwarders(mpInstance, kitBlocker) { }); }; - this.getForwarderStatsQueue = function() { + this.getForwarderStatsQueue = function(): IForwardingStatsData[] { return mpInstance._Persistence.forwardingStatsBatches .forwardingStatsEventQueue; }; - this.setForwarderStatsQueue = function(queue) { + this.setForwarderStatsQueue = function( + queue: IForwardingStatsData[] + ): void { mpInstance._Persistence.forwardingStatsBatches.forwardingStatsEventQueue = queue; }; @@ -474,16 +528,19 @@ export default function Forwarders(mpInstance, kitBlocker) { // There are 2 types of kits: // 1. UI-enabled kits // 2. Sideloaded kits. - this.processForwarders = function(config, forwardingStatsCallback) { + this.processForwarders = function( + config: IConfigResponse, + forwardingStatsCallback: ForwardingStatsCallback + ): void { if (!config) { mpInstance.Logger.warning( 'No config was passed. Cannot process forwarders' ); } else { - this.processUIEnabledKits(config); - this.processSideloadedKits(config); + (self.processUIEnabledKits as Function)(config); + (self.processSideloadedKits as Function)(config); - self.initForwarders( + (self.initForwarders as Function)( mpInstance._Store.SDKConfig.identifyRequest.userIdentities, forwardingStatsCallback ); @@ -496,13 +553,13 @@ export default function Forwarders(mpInstance, kitBlocker) { // The kit configuration will be compared with the kit constructors to determine // if there is a match before being initialized. // Only kits that are configured properly can be active and used for kit forwarding. - this.processUIEnabledKits = function(config) { - let kits = this.returnKitConstructors(); + this.processUIEnabledKits = function(config: IConfigResponse): void { + const kits = (self.returnKitConstructors as Function)() as Dictionary; try { if (Array.isArray(config.kitConfigs) && config.kitConfigs.length) { - config.kitConfigs.forEach(function(kitConfig) { - self.configureUIEnabledKit(kitConfig, kits); + config.kitConfigs.forEach(function(kitConfig: IKitConfigs) { + (self.configureUIEnabledKit as Function)(kitConfig, kits); }); } } catch (e) { @@ -513,8 +570,8 @@ export default function Forwarders(mpInstance, kitBlocker) { } }; - this.returnKitConstructors = function() { - let kits = {}; + this.returnKitConstructors = function(): Dictionary { + let kits: Dictionary = {}; // If there are kits inside of mpInstance._Store.SDKConfig.kits, then mParticle is self hosted if (!isEmpty(mpInstance._Store.SDKConfig.kits)) { kits = mpInstance._Store.SDKConfig.kits; @@ -532,23 +589,26 @@ export default function Forwarders(mpInstance, kitBlocker) { // a suffix allows the SDK to distinguish the two. if (kitConstructor.suffix) { const kitNameWithConstructorSuffix = `${kitConstructor.name}-${kitConstructor.suffix}`; - kits[kitNameWithConstructorSuffix] = kitConstructor; + kits[kitNameWithConstructorSuffix] = kitConstructor as RegisteredKit; } else { - kits[kitConstructor.name] = kitConstructor; + kits[kitConstructor.name] = kitConstructor as RegisteredKit; } }); } return kits; }; - this.configureUIEnabledKit = function(configuration, kits) { - let newKit = null; + this.configureUIEnabledKit = function( + configuration: IKitConfigs, + kits: Dictionary + ): void { + let newKit: MPForwarder | null = null; const config = configuration; - for (let name in kits) { + for (const name in kits) { // Configs are returned with suffixes also. We need to consider the // config suffix here to match the constructor suffix - let kitNameWithConfigSuffix; + let kitNameWithConfigSuffix: string; if (config.suffix) { kitNameWithConfigSuffix = `${config.name}-${config.suffix}`; } @@ -557,10 +617,10 @@ export default function Forwarders(mpInstance, kitBlocker) { if ( config.isDebug === mpInstance._Store.SDKConfig.isDevelopmentMode || - config.isSandbox === + (config as IKitConfigs & { isSandbox?: boolean }).isSandbox === mpInstance._Store.SDKConfig.isDevelopmentMode ) { - newKit = this.returnConfiguredKit(kits[name], config); + newKit = (self.returnConfiguredKit as Function)(kits[name], config); mpInstance._Store.configuredForwarders.push(newKit); break; @@ -576,10 +636,12 @@ export default function Forwarders(mpInstance, kitBlocker) { // In the future, when all kits are moved to the mpConfig rather than // there being a separate process for MP configured kits and // sideloaded kits, this will need to be refactored. - this.processSideloadedKits = function(mpConfig) { + this.processSideloadedKits = function( + mpConfig: IConfigResponse & { sideloadedKits?: { kitInstance: { register: Function; name: string }; filterDictionary: IKitFilterSettings }[] } + ): void { try { if (Array.isArray(mpConfig.sideloadedKits)) { - const registeredSideloadedKits = { kits: {} }; + const registeredSideloadedKits: { kits: Dictionary } = { kits: {} }; const unregisteredSideloadedKits = mpConfig.sideloadedKits; unregisteredSideloadedKits.forEach(function(unregisteredKit) { @@ -605,7 +667,7 @@ export default function Forwarders(mpInstance, kitBlocker) { for (const registeredKitKey in registeredSideloadedKits.kits) { const registeredKit = registeredSideloadedKits.kits[registeredKitKey]; - self.configureSideloadedKit(registeredKit); + (self.configureSideloadedKit as Function)(registeredKit); } // If Sideloaded Kits are successfully registered, @@ -624,14 +686,19 @@ export default function Forwarders(mpInstance, kitBlocker) { }; // kits can be included via mParticle UI, or via sideloaded kit config API - this.configureSideloadedKit = function(kitConstructor) { + this.configureSideloadedKit = function( + kitConstructor: RegisteredKit + ): void { mpInstance._Store.configuredForwarders.push( - this.returnConfiguredKit(kitConstructor, kitConstructor.filters) + (self.returnConfiguredKit as Function)(kitConstructor, kitConstructor.filters) ); }; - this.returnConfiguredKit = function(forwarder, config = {}) { - const newForwarder = new forwarder.constructor(); + this.returnConfiguredKit = function( + forwarder: RegisteredKit, + config: Partial = {} + ): MPForwarder { + const newForwarder = new forwarder.constructor() as MPForwarder; newForwarder.id = config.moduleId; // TODO: isSandbox, hasSandbox is never used in any kit or in core SDK. @@ -666,7 +733,7 @@ export default function Forwarders(mpInstance, kitBlocker) { return newForwarder; }; - this.configurePixel = function(settings) { + this.configurePixel = function(settings: IPixelConfiguration): void { if ( settings.isDebug === mpInstance._Store.SDKConfig.isDevelopmentMode || @@ -677,11 +744,13 @@ export default function Forwarders(mpInstance, kitBlocker) { } }; - this.processPixelConfigs = function(config) { + this.processPixelConfigs = function(config: IConfigResponse): void { try { if (!isEmpty(config.pixelConfigs)) { - config.pixelConfigs.forEach(function(pixelConfig) { - self.configurePixel(pixelConfig); + config.pixelConfigs.forEach(function( + pixelConfig: IPixelConfiguration + ) { + (self.configurePixel as Function)(pixelConfig); }); } } catch (e) { @@ -692,10 +761,12 @@ export default function Forwarders(mpInstance, kitBlocker) { } }; - this.sendSingleForwardingStatsToServer = async forwardingStatsData => { + this.sendSingleForwardingStatsToServer = async ( + forwardingStatsData: IForwardingStatsData + ): Promise => { // https://go.mparticle.com/work/SQDSDKS-6568 const fetchPayload = { - method: 'post', + method: 'post' as const, body: JSON.stringify(forwardingStatsData), headers: { Accept: 'text/plain;charset=UTF-8', @@ -705,7 +776,7 @@ export default function Forwarders(mpInstance, kitBlocker) { const response = await this.forwarderStatsUploader.upload(fetchPayload); - let message; + let message: string; // This is a fire and forget, so we only need to log the response based on the code, and not return any response body if (response.status === 202) { // https://go.mparticle.com/work/SQDSDKS-6670 diff --git a/src/sdkRuntimeModels.ts b/src/sdkRuntimeModels.ts index e31084228..add4c4ac8 100644 --- a/src/sdkRuntimeModels.ts +++ b/src/sdkRuntimeModels.ts @@ -195,7 +195,7 @@ export interface MParticleWebSDK { configurePixel(config: IPixelConfiguration): void; endSession(): void; init(apiKey: string, config: SDKInitConfig, instanceName?: string): void; - _getActiveForwarders(): ConfiguredKit[]; + _getActiveForwarders(): MPForwarder[]; _getIntegrationDelays(): IntegrationDelays; _setIntegrationDelay(module: number, shouldDelayIntegration: boolean): void; _setWrapperSDKInfo(name: WrapperSDKTypes, version: string): void; @@ -389,6 +389,10 @@ export interface SDKHelpersApi { attrs: SDKEventAttrs, name: string ): Dictionary | null; + filterUserIdentities?( + userIdentitiesObject: Record, + filterList: number[] + ): ISDKUserIdentity[]; Validators: typeof Validators; } diff --git a/src/store.ts b/src/store.ts index 4bd1617e1..09119f61b 100644 --- a/src/store.ts +++ b/src/store.ts @@ -197,7 +197,7 @@ export interface IStore { requireDelay: boolean; isLocalStorageAvailable: boolean | null; storageName: string | null; - activeForwarders: ConfiguredKit[]; + activeForwarders: MPForwarder[]; kits: Dictionary; sideloadedKits: MPForwarder[]; configuredForwarders: MPForwarder[]; From 2660da15db044403675817b3c5b738e99cfa6b18 Mon Sep 17 00:00:00 2001 From: Jaissica Date: Wed, 20 May 2026 22:41:05 -0400 Subject: [PATCH 3/9] fix failing tests --- src/forwarders.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/forwarders.ts b/src/forwarders.ts index 6edfec87f..0ddef6337 100644 --- a/src/forwarders.ts +++ b/src/forwarders.ts @@ -313,7 +313,13 @@ export default function Forwarders( return; } - for (const forwarder of mpInstance._Store.activeForwarders) { + for ( + let i = 0; + i < mpInstance._Store.activeForwarders.length; + i++ + ) { + const forwarder = mpInstance._Store.activeForwarders[i]; + if (!forwarder.processBatch) { continue; } From 6dcf6bede95ee5dd0aa1215f7e6e58d35d69e736 Mon Sep 17 00:00:00 2001 From: Jaissica Date: Wed, 20 May 2026 23:46:09 -0400 Subject: [PATCH 4/9] remove self=this pattern --- src/forwarders.ts | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/forwarders.ts b/src/forwarders.ts index 0ddef6337..326984a6e 100644 --- a/src/forwarders.ts +++ b/src/forwarders.ts @@ -40,8 +40,6 @@ export default function Forwarders( mpInstance: IMParticleWebSDKInstance, kitBlocker: KitBlocker ): void { - const self = this; - this.forwarderStatsUploader = new APIClient( mpInstance, kitBlocker @@ -71,7 +69,7 @@ export default function Forwarders( }); mpInstance._Store.activeForwarders = mpInstance._Store.configuredForwarders.filter( - function(forwarder) { + (forwarder) => { if ( !mpInstance._Consent.isEnabledForUserConsent( forwarder.filteringConsentRuleValues, @@ -81,7 +79,7 @@ export default function Forwarders( return false; } if ( - !(self.isEnabledForUserAttributes as Function)( + !(this.isEnabledForUserAttributes as Function)( forwarder.filteringUserAttributeValue, user ) @@ -89,7 +87,7 @@ export default function Forwarders( return false; } if ( - !(self.isEnabledForUnknownUser as Function)( + !(this.isEnabledForUnknownUser as Function)( forwarder.excludeAnonymousUser, user ) @@ -543,10 +541,10 @@ export default function Forwarders( 'No config was passed. Cannot process forwarders' ); } else { - (self.processUIEnabledKits as Function)(config); - (self.processSideloadedKits as Function)(config); + (this.processUIEnabledKits as Function)(config); + (this.processSideloadedKits as Function)(config); - (self.initForwarders as Function)( + (this.initForwarders as Function)( mpInstance._Store.SDKConfig.identifyRequest.userIdentities, forwardingStatsCallback ); @@ -560,12 +558,12 @@ export default function Forwarders( // if there is a match before being initialized. // Only kits that are configured properly can be active and used for kit forwarding. this.processUIEnabledKits = function(config: IConfigResponse): void { - const kits = (self.returnKitConstructors as Function)() as Dictionary; + const kits = (this.returnKitConstructors as Function)() as Dictionary; try { if (Array.isArray(config.kitConfigs) && config.kitConfigs.length) { - config.kitConfigs.forEach(function(kitConfig: IKitConfigs) { - (self.configureUIEnabledKit as Function)(kitConfig, kits); + config.kitConfigs.forEach((kitConfig: IKitConfigs) => { + (this.configureUIEnabledKit as Function)(kitConfig, kits); }); } } catch (e) { @@ -626,7 +624,7 @@ export default function Forwarders( (config as IKitConfigs & { isSandbox?: boolean }).isSandbox === mpInstance._Store.SDKConfig.isDevelopmentMode ) { - newKit = (self.returnConfiguredKit as Function)(kits[name], config); + newKit = (this.returnConfiguredKit as Function)(kits[name], config); mpInstance._Store.configuredForwarders.push(newKit); break; @@ -673,7 +671,7 @@ export default function Forwarders( for (const registeredKitKey in registeredSideloadedKits.kits) { const registeredKit = registeredSideloadedKits.kits[registeredKitKey]; - (self.configureSideloadedKit as Function)(registeredKit); + (this.configureSideloadedKit as Function)(registeredKit); } // If Sideloaded Kits are successfully registered, @@ -696,7 +694,7 @@ export default function Forwarders( kitConstructor: RegisteredKit ): void { mpInstance._Store.configuredForwarders.push( - (self.returnConfiguredKit as Function)(kitConstructor, kitConstructor.filters) + (this.returnConfiguredKit as Function)(kitConstructor, kitConstructor.filters) ); }; @@ -753,10 +751,8 @@ export default function Forwarders( this.processPixelConfigs = function(config: IConfigResponse): void { try { if (!isEmpty(config.pixelConfigs)) { - config.pixelConfigs.forEach(function( - pixelConfig: IPixelConfiguration - ) { - (self.configurePixel as Function)(pixelConfig); + config.pixelConfigs.forEach((pixelConfig: IPixelConfiguration) => { + (this.configurePixel as Function)(pixelConfig); }); } } catch (e) { From d614b96e7355025656c3fe5f453cebf6c734f4cd Mon Sep 17 00:00:00 2001 From: Jaissica Date: Mon, 25 May 2026 19:09:00 -0400 Subject: [PATCH 5/9] fix: address PR review feedback --- src/forwarders.interfaces.ts | 7 ++++++- src/forwarders.ts | 17 +++++------------ src/sdkRuntimeModels.ts | 4 ++-- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/forwarders.interfaces.ts b/src/forwarders.interfaces.ts index d13328e27..9ba46bd21 100644 --- a/src/forwarders.interfaces.ts +++ b/src/forwarders.interfaces.ts @@ -39,6 +39,11 @@ export interface UnregisteredKit { suffix?: string; } +export interface SideloadedKit { + kitInstance: UnregisteredKit; + filterDictionary: IKitFilterSettings; +} + // The state of the kit after being added to forwarderConstructors in the CDN // or after registered to SDKConfig.kits via NPM // Sideloaded Kits would also be considered registered @@ -190,7 +195,7 @@ export interface IForwarders { configuration: IKitConfigs, kits: Dictionary ): void; - processSideloadedKits(mpConfig: IConfigResponse): void; + processSideloadedKits(mpConfig: IConfigResponse & { sideloadedKits?: SideloadedKit[] }): void; configureSideloadedKit(kitConstructor: RegisteredKit): void; returnConfiguredKit( forwarder: RegisteredKit, diff --git a/src/forwarders.ts b/src/forwarders.ts index 326984a6e..4a50be2e3 100644 --- a/src/forwarders.ts +++ b/src/forwarders.ts @@ -1,5 +1,5 @@ import filteredMparticleUser from './filteredMparticleUser'; -import { isEmpty, extend } from './utils'; +import { isEmpty, extend, Dictionary } from './utils'; import KitFilterHelper from './kitFilterHelper'; import Constants from './constants'; import APIClient, { IForwardingStatsData } from './apiClient'; @@ -19,7 +19,7 @@ import { MPForwarder, RegisteredKit, forwardingStatsCallback as ForwardingStatsCallback, - ConfiguredKit, + SideloadedKit, } from './forwarders.interfaces'; import { IConfigResponse, @@ -31,7 +31,6 @@ import { IPixelConfiguration } from './cookieSyncManager'; import { Batch } from '@mparticle/event-models'; import { IMParticleUser, ISDKUserIdentity } from './identity-user-interfaces'; import KitBlocker from './kitBlocking'; -import { Dictionary } from './utils'; const { Modify, Identify, Login, Logout } = Constants.IdentityMethods; @@ -238,13 +237,7 @@ export default function Forwarders( event.EventCategory ); - for ( - let i = 0; - i < mpInstance._Store.activeForwarders.length; - i++ - ) { - const forwarder = mpInstance._Store.activeForwarders[i]; - + for (const forwarder of mpInstance._Store.activeForwarders) { if ( (isBlockedByForwardingRule as Function)( event.EventDataType, @@ -356,7 +349,7 @@ export default function Forwarders( const result = forwarder.processBatch(batchCopy); if (result) { - mpInstance.Logger.verbose(result as string); + mpInstance.Logger.verbose(result); } } catch (e) { mpInstance.Logger.verbose(e as string); @@ -641,7 +634,7 @@ export default function Forwarders( // there being a separate process for MP configured kits and // sideloaded kits, this will need to be refactored. this.processSideloadedKits = function( - mpConfig: IConfigResponse & { sideloadedKits?: { kitInstance: { register: Function; name: string }; filterDictionary: IKitFilterSettings }[] } + mpConfig: IConfigResponse & { sideloadedKits?: SideloadedKit[] } ): void { try { if (Array.isArray(mpConfig.sideloadedKits)) { diff --git a/src/sdkRuntimeModels.ts b/src/sdkRuntimeModels.ts index add4c4ac8..73a127aba 100644 --- a/src/sdkRuntimeModels.ts +++ b/src/sdkRuntimeModels.ts @@ -195,7 +195,7 @@ export interface MParticleWebSDK { configurePixel(config: IPixelConfiguration): void; endSession(): void; init(apiKey: string, config: SDKInitConfig, instanceName?: string): void; - _getActiveForwarders(): MPForwarder[]; + _getActiveForwarders(): ConfiguredKit[]; _getIntegrationDelays(): IntegrationDelays; _setIntegrationDelay(module: number, shouldDelayIntegration: boolean): void; _setWrapperSDKInfo(name: WrapperSDKTypes, version: string): void; @@ -390,7 +390,7 @@ export interface SDKHelpersApi { name: string ): Dictionary | null; filterUserIdentities?( - userIdentitiesObject: Record, + userIdentitiesObject: Dictionary, filterList: number[] ): ISDKUserIdentity[]; Validators: typeof Validators; From 1ba077d5f8e0d273a6c13d6505b906b70d22b6d3 Mon Sep 17 00:00:00 2001 From: Jaissica Date: Mon, 25 May 2026 20:34:05 -0400 Subject: [PATCH 6/9] fix activeForwarders type in store --- src/store.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store.ts b/src/store.ts index 09119f61b..4bd1617e1 100644 --- a/src/store.ts +++ b/src/store.ts @@ -197,7 +197,7 @@ export interface IStore { requireDelay: boolean; isLocalStorageAvailable: boolean | null; storageName: string | null; - activeForwarders: MPForwarder[]; + activeForwarders: ConfiguredKit[]; kits: Dictionary; sideloadedKits: MPForwarder[]; configuredForwarders: MPForwarder[]; From aa30167161fcb3ab5cd4b484551fdf1a29ec4154 Mon Sep 17 00:00:00 2001 From: Jaissica Date: Mon, 25 May 2026 20:42:25 -0400 Subject: [PATCH 7/9] preserve ConfiguredKit[] type for activeForwarders and _getActiveForwarders --- src/forwarders.interfaces.ts | 5 ++++- src/forwarders.ts | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/forwarders.interfaces.ts b/src/forwarders.interfaces.ts index 9ba46bd21..76651219b 100644 --- a/src/forwarders.interfaces.ts +++ b/src/forwarders.interfaces.ts @@ -1,4 +1,4 @@ -import { SDKEvent, SDKEventCustomFlags } from './sdkRuntimeModels'; +import { SDKEvent, SDKEventCustomFlags, SDKLoggerApi } from './sdkRuntimeModels'; import { Dictionary } from './utils'; import { IKitConfigs, @@ -103,6 +103,9 @@ export interface ConfiguredKit // TODO: https://go.mparticle.com/work/SQDSDKS-5156 isSandbox: boolean; hasSandbox: boolean; + + initialized?: boolean; + logger?: SDKLoggerApi; } export interface KitInterface { diff --git a/src/forwarders.ts b/src/forwarders.ts index 4a50be2e3..987a8d82a 100644 --- a/src/forwarders.ts +++ b/src/forwarders.ts @@ -18,6 +18,7 @@ import { IForwarders, MPForwarder, RegisteredKit, + ConfiguredKit, forwardingStatsCallback as ForwardingStatsCallback, SideloadedKit, } from './forwarders.interfaces'; @@ -67,7 +68,7 @@ export default function Forwarders( ); }); - mpInstance._Store.activeForwarders = mpInstance._Store.configuredForwarders.filter( + mpInstance._Store.activeForwarders = (mpInstance._Store.configuredForwarders as unknown as ConfiguredKit[]).filter( (forwarder) => { if ( !mpInstance._Consent.isEnabledForUserConsent( From cea16d6fd73cbce9ccf3025d81ae10858f7b24e0 Mon Sep 17 00:00:00 2001 From: Jaissica Date: Mon, 25 May 2026 20:45:25 -0400 Subject: [PATCH 8/9] restore original loop styles in sendEventToForwarders and sendBatchToForwarders --- src/forwarders.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/forwarders.ts b/src/forwarders.ts index 987a8d82a..ad7184bdd 100644 --- a/src/forwarders.ts +++ b/src/forwarders.ts @@ -238,7 +238,13 @@ export default function Forwarders( event.EventCategory ); - for (const forwarder of mpInstance._Store.activeForwarders) { + for ( + let i = 0; + i < mpInstance._Store.activeForwarders.length; + i++ + ) { + const forwarder = mpInstance._Store.activeForwarders[i]; + if ( (isBlockedByForwardingRule as Function)( event.EventDataType, @@ -305,13 +311,7 @@ export default function Forwarders( return; } - for ( - let i = 0; - i < mpInstance._Store.activeForwarders.length; - i++ - ) { - const forwarder = mpInstance._Store.activeForwarders[i]; - + for (const forwarder of mpInstance._Store.activeForwarders) { if (!forwarder.processBatch) { continue; } From e8200050c1ba3fb2d41e821d1890661c9480e025 Mon Sep 17 00:00:00 2001 From: Jaissica Date: Mon, 25 May 2026 20:59:34 -0400 Subject: [PATCH 9/9] fix failing tests --- src/forwarders.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/forwarders.ts b/src/forwarders.ts index ad7184bdd..fcbfdce44 100644 --- a/src/forwarders.ts +++ b/src/forwarders.ts @@ -311,7 +311,13 @@ export default function Forwarders( return; } - for (const forwarder of mpInstance._Store.activeForwarders) { + for ( + let i = 0; + i < mpInstance._Store.activeForwarders.length; + i++ + ) { + const forwarder = mpInstance._Store.activeForwarders[i]; + if (!forwarder.processBatch) { continue; }