From 6cb7247a7fec7b9b9bb5eb41848a8b385db5cd84 Mon Sep 17 00:00:00 2001 From: Alexander Sapountzis Date: Fri, 28 Feb 2025 09:04:16 -0500 Subject: [PATCH 1/8] refactor: Migrate Forwarder module to TypeScript --- src/apiClient.ts | 14 +- src/configAPIClient.ts | 9 +- src/forwarders.interfaces.ts | 113 ++++- src/{forwarders.js => forwarders.ts} | 550 +++++++++++----------- src/identity-user-interfaces.ts | 2 +- src/kitBlocking.ts | 8 +- src/mp-instance.ts | 3 +- src/pre-init-utils.ts | 4 +- src/sdkRuntimeModels.ts | 17 +- src/sdkToEventsApiConverter.ts | 7 +- src/serverModel.ts | 4 +- src/sideloadedKit.ts | 5 + src/store.ts | 10 +- test/src/tests-apiClient.ts | 2 +- test/src/tests-forwarders.ts | 14 +- test/src/tests-identities-attributes.ts | 2 +- test/src/tests-runtimeToBatchEventsDTO.ts | 4 +- test/src/tests-serverModel.ts | 2 +- 18 files changed, 443 insertions(+), 327 deletions(-) rename src/{forwarders.js => forwarders.ts} (57%) diff --git a/src/apiClient.ts b/src/apiClient.ts index 5e0a2fe76..319a2a02d 100644 --- a/src/apiClient.ts +++ b/src/apiClient.ts @@ -1,15 +1,15 @@ import Constants from './constants'; -import Types from './types'; +import Types, { MessageType } from './types'; import { BatchUploader } from './batchUploader'; import { SDKEvent, SDKDataPlan } from './sdkRuntimeModels'; import KitBlocker from './kitBlocking'; import { Dictionary, isEmpty, parseNumber } from './utils'; import { IUploadObject } from './serverModel'; -import { MPForwarder } from './forwarders.interfaces'; import { IMParticleUser, ISDKUserAttributes } from './identity-user-interfaces'; import { AsyncUploader, FetchUploader, XHRUploader } from './uploaders'; import { IMParticleWebSDKInstance } from './mp-instance'; import { appendUserInfo } from './user-utils'; +import { IMPForwarder } from './forwarders.interfaces'; export interface IAPIClient { uploader: BatchUploader | null; @@ -24,7 +24,7 @@ export interface IAPIClient { ) => void; initializeForwarderStatsUploader: () => AsyncUploader; prepareForwardingStats: ( - forwarder: MPForwarder, + forwarder: IMPForwarder, event: IUploadObject ) => void; } @@ -140,7 +140,7 @@ export default function APIClient( // https://go.mparticle.com/work/SQDSDKS-6935 // While Event Name is 'usually' a string, there are some cases where it is a number // in that it could be a type of MessageType Enum - if (event.EventName as unknown as number !== Types.MessageType.AppStateTransition) { + if (event.EventName as unknown as number !== MessageType.AppStateTransition) { if (kitBlocker && kitBlocker.kitBlockingEnabled) { event = kitBlocker.createBlockedEvent(event); } @@ -193,7 +193,7 @@ export default function APIClient( }; this.prepareForwardingStats = function( - forwarder: MPForwarder, + forwarder: IMPForwarder, event:SDKEvent, ) : void { let forwardingStatsData: IForwardingStatsData; @@ -206,8 +206,8 @@ export default function APIClient( n: event.EventName, attrs: event.EventAttributes, sdk: event.SDKVersion, - dt: event.EventDataType, - et: event.EventCategory, + dt: event.EventDataType as number, + et: event.EventCategory as number, dbg: event.Debug, ct: event.Timestamp, eec: event.ExpandedEventCount, diff --git a/src/configAPIClient.ts b/src/configAPIClient.ts index b551af5f9..f88e5677b 100644 --- a/src/configAPIClient.ts +++ b/src/configAPIClient.ts @@ -14,6 +14,7 @@ import { } from './uploaders'; import { IPixelConfiguration } from './cookieSyncManager'; import { IMParticleWebSDKInstance } from './mp-instance'; +import { UserAttributeFilters, UserIdentityFilters } from './forwarders.interfaces'; export interface IKitConfigs extends IKitFilterSettings { name: string; @@ -26,6 +27,10 @@ export interface IKitConfigs extends IKitFilterSettings { settings: Dictionary; eventSubscriptionId: number; excludeAnonymousUser: boolean; + + // https://go.mparticle.com/work/SQDSDKS-5156 + isSandbox?: boolean; + hasSandbox?: boolean; } export interface IKitFilterSettings { @@ -33,8 +38,8 @@ export interface IKitFilterSettings { eventNameFilters: number[]; screenNameFilters: number[]; screenAttributeFilters: number[]; - userIdentityFilters: number[]; - userAttributeFilters: number[]; + userIdentityFilters: UserIdentityFilters; + userAttributeFilters: UserAttributeFilters; attributeFilters: number[]; filteringEventAttributeValue?: IFilteringEventAttributeValue; filteringUserAttributeValue?: IFilteringUserAttributeValue; diff --git a/src/forwarders.interfaces.ts b/src/forwarders.interfaces.ts index 6f8231623..74aaa29ff 100644 --- a/src/forwarders.interfaces.ts +++ b/src/forwarders.interfaces.ts @@ -1,15 +1,20 @@ -import { SDKEvent, SDKEventCustomFlags } from './sdkRuntimeModels'; +import { SDKEvent, SDKEventCustomFlags, SDKInitConfig } from './sdkRuntimeModels'; import { Dictionary } from './utils'; import { IKitConfigs, IKitFilterSettings } from './configAPIClient'; import { IdentityApiData } from '@mparticle/web-sdk'; +import { IFilteringConsentRuleValues, IFilteringEventAttributeValue, IFilteringUserAttributeValue, IKitConfigs, IKitFilterSettings } from './configAPIClient'; +import { Callback, IdentityApiData, Logger, UserIdentities } from '@mparticle/web-sdk'; import { IMParticleUser, + ISDKUserAttributes, ISDKUserIdentity, UserAttributes, } from './identity-user-interfaces'; - -// TODO: https://go.mparticle.com/work/SQDSDKS-4475 -export type MPForwarder = Dictionary; +import { IForwardingStatsData } from './apiClient'; +import { IPixelConfiguration } from './cookieSyncManager'; +import { IdentityAPIMethod } from './identity.interfaces'; +import { AsyncUploader } from './uploaders'; +import { IdentityType } from './types'; // The state of the kit when accessed via window.KitName via CDN // or imported as an NPM package @@ -86,3 +91,103 @@ export type forwardingStatsCallback = ( forwarder: ConfiguredKit, event: SDKEvent ) => void; + + +export type UserIdentityFilters = typeof IdentityType[]; +export type UserAttributeFilters = number[]; + +// FIXME: Remove in favor of IKitConfigs.settings +// https://go.mparticle.com/work/SQDSDKS-7113 +interface ForwarderSettings { + PriorityValue?: number; +} + +export interface IMPForwarder { + // @deprecated + setForwarderUserIdentities: (userIdentities: UserIdentities) => void; + + setForwarderOnUserIdentified: (user: IMParticleUser) => void; + setForwarderOnIdentityComplete: (user: IMParticleUser, identityMethod: IdentityAPIMethod) => void; + handleForwarderUserAttributes: (functionNameKey: string, key: string, value: string | string[]) => void; + id: number; + settings: ForwarderSettings; + forwarderStatsUploader: AsyncUploader; + isInitialized: boolean; + filteringConsentRuleValues: IFilteringConsentRuleValues; + filteringUserAttributeValue: IFilteringUserAttributeValue; + filteringEventAttributeValue: IFilteringEventAttributeValue; + excludeAnonymousUser: boolean; + userIdentityFilters: UserIdentityFilters; + userAttributeFilters: UserAttributeFilters; + initialized: boolean; + logger: Logger; + + suffix?: string; + + eventSubscriptionId: number; + + eventNameFilters: number[]; + eventTypeFilters: number[]; + attributeFilters: number[]; + + screenNameFilters: number[]; + screenAttributeFilters: number[]; + + + // Side loaded kit functionality in Forwarder methods + kitInstance: UnregisteredKit; + + // https://go.mparticle.com/work/SQDSDKS-5156 + isSandbox?: boolean; + hasSandbox?: boolean; + isVisible?: boolean; + + configureSideloadedKit: (kitConstructor: RegisteredKit) => void; + + sendSingleForwardingStatsToServer: (forwardingStatsData: IForwardingStatsData) => void; + applyToForwarders: (functionName: string, functionArgs: any[]) => void; + sendEventToForwarders: (event: SDKEvent) => void; + processPixelConfigs: (pixelConfigs: SDKInitConfig) => void; + configurePixel: (pixelConfig: IPixelConfiguration) => void; + returnConfiguredKit: (forwarder: RegisteredKit, config: IKitConfigs) => IMPForwarder; + + processSideloadedKits: (mpConfig: SDKInitConfig) => void; + + init: ( + setting: ForwarderSettings, + forwarderSettingsCallback: Callback, + testMode: boolean, + trackerId: string | number | null, + filteredUserAttributes: ISDKUserAttributes, + filteredUserIdentities: ISDKUserIdentity[], + appVersion: string, + appName: string, + customFlags: SDKEventCustomFlags, + clientId: string + ) => void; + + initForwarders: (userIdentities: UserIdentities, forwarderStatsCallback: Callback) => void; + isEnabledForUserAttributes: (filterObject?: IFilteringUserAttributeValue, user?: IMParticleUser) => boolean; + isEnabledForUnknownUser: (excludeAnonymousUserBoolean: boolean, user: IMParticleUser) => boolean; + + name?: string; + + // Techically these do not return a value, but we sometimes use a string as a debug message + onUserIdentified?: (user: IMParticleUser, identityApiData?: IdentityApiData) => string; + onIdentifyComplete?: (user: IMParticleUser, identityApiData: IdentityApiData) => string; + onLoginComplete?: (user: IMParticleUser, identityApiData: IdentityApiData) => string; + onLogoutComplete?: (user: IMParticleUser, identityApiData: IdentityApiData) => string; + onModifyComplete?: (user: IMParticleUser, identityApiData: IdentityApiData) => string; + setOptOut: (optOut: boolean) => string; + setUserAttribute?: (key: string, value: string | string[]) => string; + removeUserAttribute?: (key: string) => string; + process?: (event: SDKEvent) => string; + setUserIdentity?: (identity: string, type: number) => string; + + getForwarderStatsQueue: () => IForwardingStatsData[]; + setForwarderStatsQueue: (queue: IForwardingStatsData[]) => void; + processForwarders: (config: SDKInitConfig, forwardingStatsCallback: Callback) => void; + processUIEnabledKits: (config: SDKInitConfig) => void; + returnKitConstructors: () => Dictionary; + configureUIEnabledKit: (config: IKitConfigs, kitConstructor: Dictionary) => void; +} \ No newline at end of file diff --git a/src/forwarders.js b/src/forwarders.ts similarity index 57% rename from src/forwarders.js rename to src/forwarders.ts index 2847020bf..be56d94a9 100644 --- a/src/forwarders.js +++ b/src/forwarders.ts @@ -1,13 +1,20 @@ -import Types from './types'; +import { EventType, IdentityType, MessageType } from './types'; import filteredMparticleUser from './filteredMparticleUser'; -import { isEmpty } from './utils'; +import { inArray, isEmpty, valueof } from './utils'; import KitFilterHelper from './kitFilterHelper'; import Constants from './constants'; import APIClient from './apiClient'; +import { IMPForwarder, KitRegistrationConfig, UserAttributeFilters, UserIdentityFilters } from './forwarders.interfaces'; +import { IMParticleWebSDKInstance } from './mp-instance'; +import KitBlocker from './kitBlocking'; +import { IFilteringUserAttributeValue, IKitConfigs } from './configAPIClient'; +import { IMParticleUser, ISDKUserAttributes, ISDKUserIdentity, UserAttributes } from './identity-user-interfaces'; +import { SDKEvent } from './sdkRuntimeModels'; +import { Callback, UserIdentities } from '@mparticle/web-sdk'; const { Modify, Identify, Login, Logout } = Constants.IdentityMethods; -export default function Forwarders(mpInstance, kitBlocker) { +export default function Forwarders(this: IMPForwarder, mpInstance: IMParticleWebSDKInstance, kitBlocker: KitBlocker) { var self = this; this.forwarderStatsUploader = new APIClient( mpInstance, @@ -19,14 +26,19 @@ export default function Forwarders(mpInstance, kitBlocker) { removeUserAttribute: 'removeUserAttribute', }; - this.initForwarders = function(userIdentities, forwardingStatsCallback) { - var user = mpInstance.Identity.getCurrentUser(); - if ( - !mpInstance._Store.webviewBridgeEnabled && - mpInstance._Store.configuredForwarders - ) { + this.initForwarders = (userIdentities: UserIdentities, forwardingStatsCallback: Callback) => { + const user: IMParticleUser = mpInstance.Identity.getCurrentUser(); + const { + webviewBridgeEnabled, + configuredForwarders, + } = mpInstance._Store; + + const { filterUserAttributes, filterUserIdentities } = mpInstance._Helpers; + const { isEnabledForUserConsent } = mpInstance._Consent; + if (!webviewBridgeEnabled && configuredForwarders) { // Some js libraries require that they be loaded first, or last, etc - mpInstance._Store.configuredForwarders.sort(function(x, y) { + configuredForwarders.sort(function(x, y) { + // https://go.mparticle.com/work/SQDSDKS-7113 x.settings.PriorityValue = x.settings.PriorityValue || 0; y.settings.PriorityValue = y.settings.PriorityValue || 0; return ( @@ -34,74 +46,71 @@ export default function Forwarders(mpInstance, kitBlocker) { ); }); - mpInstance._Store.activeForwarders = mpInstance._Store.configuredForwarders.filter( - function(forwarder) { - if ( - !mpInstance._Consent.isEnabledForUserConsent( - forwarder.filteringConsentRuleValues, - user - ) - ) { - return false; - } - if ( - !self.isEnabledForUserAttributes( - forwarder.filteringUserAttributeValue, - user - ) - ) { - return false; - } - if ( - !self.isEnabledForUnknownUser( - forwarder.excludeAnonymousUser, - user - ) - ) { - return false; - } + mpInstance._Store.activeForwarders = configuredForwarders.filter((forwarder: IMPForwarder) => { + if ( + !isEnabledForUserConsent( + forwarder.filteringConsentRuleValues, + user + ) + ) { + return false; + } + if ( + !self.isEnabledForUserAttributes( + forwarder.filteringUserAttributeValue, + user + ) + ) { + return false; + } + if ( + !self.isEnabledForUnknownUser( + forwarder.excludeAnonymousUser, + user + ) + ) { + return false; + } - var filteredUserIdentities = mpInstance._Helpers.filterUserIdentities( - userIdentities, - forwarder.userIdentityFilters - ); - var filteredUserAttributes = mpInstance._Helpers.filterUserAttributes( - user ? user.getAllUserAttributes() : {}, - forwarder.userAttributeFilters + const filteredUserIdentities: ISDKUserIdentity[] = filterUserIdentities( + userIdentities, + forwarder.userIdentityFilters + ); + const filteredUserAttributes: ISDKUserAttributes = filterUserAttributes( + user ? user.getAllUserAttributes() : {}, + forwarder.userAttributeFilters + ); + if (!forwarder.initialized) { + forwarder.logger = mpInstance.Logger; + forwarder.init( + forwarder.settings, + forwardingStatsCallback, + false, + null, + filteredUserAttributes, + filteredUserIdentities, + mpInstance._Store.SDKConfig.appVersion, + mpInstance._Store.SDKConfig.appName, + mpInstance._Store.SDKConfig.customFlags, + mpInstance._Store.clientId ); - if (!forwarder.initialized) { - forwarder.logger = mpInstance.Logger; - forwarder.init( - forwarder.settings, - forwardingStatsCallback, - false, - null, - filteredUserAttributes, - filteredUserIdentities, - mpInstance._Store.SDKConfig.appVersion, - mpInstance._Store.SDKConfig.appName, - mpInstance._Store.SDKConfig.customFlags, - mpInstance._Store.clientId - ); - forwarder.initialized = true; - } - - return true; + forwarder.initialized = true; } - ); + + return true; + }); } }; - this.isEnabledForUserAttributes = function(filterObject, user) { - if ( - !filterObject || - !mpInstance._Helpers.isObject(filterObject) || - !Object.keys(filterObject).length - ) { + this.isEnabledForUserAttributes = (filterObject: IFilteringUserAttributeValue, user: IMParticleUser) => { + const { hashAttributeConditionalForwarding } = KitFilterHelper; + if (isEmpty(filterObject)) { return true; } - var attrHash, valueHash, userAttributes; + let attrHash: string; + let valueHash: string; + let userAttributes: UserAttributes; if (!user) { return false; @@ -109,27 +118,22 @@ export default function Forwarders(mpInstance, kitBlocker) { userAttributes = user.getAllUserAttributes(); } - var isMatch = false; + const { + userAttributeName, + userAttributeValue, + includeOnMatch + } = filterObject; + + let isMatch = false; try { - if ( - userAttributes && - mpInstance._Helpers.isObject(userAttributes) && - Object.keys(userAttributes).length - ) { - for (var attrName in userAttributes) { + if (!isEmpty(userAttributes)) { + for (const attrName in userAttributes) { if (userAttributes.hasOwnProperty(attrName)) { - attrHash = KitFilterHelper.hashAttributeConditionalForwarding( - attrName - ); - valueHash = KitFilterHelper.hashAttributeConditionalForwarding( - userAttributes[attrName] - ); + attrHash = hashAttributeConditionalForwarding(attrName); + valueHash = hashAttributeConditionalForwarding(userAttributes[attrName] as string); - if ( - attrHash === filterObject.userAttributeName && - valueHash === filterObject.userAttributeValue - ) { + if (attrHash === userAttributeName && valueHash === userAttributeValue) { isMatch = true; break; } @@ -137,18 +141,14 @@ export default function Forwarders(mpInstance, kitBlocker) { } } - if (filterObject) { - return filterObject.includeOnMatch === isMatch; - } else { - return true; - } + return filterObject ? includeOnMatch === isMatch : true; } catch (e) { // in any error scenario, err on side of returning true and forwarding event return true; } }; - this.isEnabledForUnknownUser = function(excludeAnonymousUserBoolean, user) { + this.isEnabledForUnknownUser = (excludeAnonymousUserBoolean: boolean, user: IMParticleUser) => { if (!user || !user.isLoggedIn()) { if (excludeAnonymousUserBoolean) { return false; @@ -157,127 +157,120 @@ export default function Forwarders(mpInstance, kitBlocker) { return true; }; - this.applyToForwarders = function(functionName, functionArgs) { - if (mpInstance._Store.activeForwarders.length) { - mpInstance._Store.activeForwarders.forEach(function(forwarder) { - var forwarderFunction = forwarder[functionName]; - if (forwarderFunction) { - try { - var result = forwarder[functionName](functionArgs); + this.applyToForwarders = (functionName: string, functionArgs: any[]) => { + const activeForwarders: IMPForwarder[] = mpInstance._Store.activeForwarders; - if (result) { - mpInstance.Logger.verbose(result); - } - } catch (e) { - mpInstance.Logger.verbose(e); + if (!activeForwarders) { + return; + } + activeForwarders.forEach(function(forwarder) { + const forwarderFunction: IMPForwarder = forwarder[functionName]; + if (forwarderFunction) { + try { + const result: string = forwarder[functionName](functionArgs); + + if (result) { + mpInstance.Logger.verbose(result); } + } catch (e) { + mpInstance.Logger.verbose(e as string); } - }); - } + } + }); }; - this.sendEventToForwarders = function(event) { - var clonedEvent, - hashedEventName, - hashedEventType, - filterUserIdentities = function(event, filterList) { - if (event.UserIdentities && event.UserIdentities.length) { - event.UserIdentities.forEach(function(userIdentity, i) { - if ( - mpInstance._Helpers.inArray( - filterList, - KitFilterHelper.hashUserIdentity( - userIdentity.Type - ) - ) - ) { - event.UserIdentities.splice(i, 1); - - if (i > 0) { - i--; - } - } - }); - } - }, - filterAttributes = function(event, filterList) { - var hash; + this.sendEventToForwarders = (event: SDKEvent) => { + const { webviewBridgeEnabled, activeForwarders } = mpInstance._Store; - if (!filterList) { - return; - } + let clonedEvent: SDKEvent; + let hashedEventName: number; + let hashedEventType: number; - for (var attrName in event.EventAttributes) { - if (event.EventAttributes.hasOwnProperty(attrName)) { - hash = KitFilterHelper.hashEventAttributeKey( - event.EventCategory, - event.EventName, - attrName - ); + const { hashUserIdentity } = KitFilterHelper; - if (mpInstance._Helpers.inArray(filterList, hash)) { - delete event.EventAttributes[attrName]; - } + const filterUserIdentities = (event: SDKEvent, filterList: UserIdentityFilters) => { + if (isEmpty(event.UserIdentities)) { + return; + } + event.UserIdentities.forEach(function(userIdentity: typeof IdentityType, index: number) { + const hash: number = hashUserIdentity(userIdentity.Type); + if (inArray(filterList, hash)) { + event.UserIdentities.splice(index, 1); + + if (index > 0) { + index--; } } - }, - inFilteredList = function(filterList, hash) { - if (filterList && filterList.length) { - if (mpInstance._Helpers.inArray(filterList, hash)) { - return true; + }); + }; + + const filterAttributes = (event: SDKEvent, filterList: UserAttributeFilters) => { + let hash: number; + + if (isEmpty(filterList)) { + return; + } + + for (const attrName in event.EventAttributes) { + if (event.EventAttributes.hasOwnProperty(attrName)) { + hash = KitFilterHelper.hashEventAttributeKey( + event.EventCategory as valueof, + event.EventName, + attrName + ); + + if (inArray(filterList, hash)) { + delete event.EventAttributes[attrName]; } } + } + }; - return false; - }, - forwardingRuleMessageTypes = [ - Types.MessageType.PageEvent, - Types.MessageType.PageView, - Types.MessageType.Commerce, - ]; + const inFilteredList = (filterList: UserAttributeFilters, hash: number) => !isEmpty(filterList) && inArray(filterList, hash); - if ( - !mpInstance._Store.webviewBridgeEnabled && - mpInstance._Store.activeForwarders - ) { - hashedEventName = KitFilterHelper.hashEventName( + const forwardingRuleMessageTypes = [ + MessageType.PageEvent, + MessageType.PageView, + MessageType.Commerce, + ]; + + if (!webviewBridgeEnabled && activeForwarders) { + const { hashEventName, hashEventType, hashAttributeConditionalForwarding } = KitFilterHelper; + hashedEventName = hashEventName( event.EventName, - event.EventCategory + + // FIXME: Set up union of EventType and EventCategory + event.EventCategory as valueof ); - hashedEventType = KitFilterHelper.hashEventType( - event.EventCategory + hashedEventType = hashEventType( + // FIXME: Set up union of EventType and EventCategory + event.EventCategory as valueof ); - for ( - var i = 0; - i < mpInstance._Store.activeForwarders.length; - i++ - ) { + for (let i = 0; i < activeForwarders.length; i++) { // Check attribute forwarding rule. This rule allows users to only forward an event if a // specific attribute exists and has a specific value. Alternatively, they can specify // that an event not be forwarded if the specified attribute name and value exists. // The two cases are controlled by the "includeOnMatch" boolean value. // Supported message types for attribute forwarding rules are defined in the forwardingRuleMessageTypes array + const { filteringEventAttributeValue } = activeForwarders[i]; + if ( + // FIXME: + // @ts-expect-error forwardingRuleMessageTypes.indexOf(event.EventDataType) > -1 && - mpInstance._Store.activeForwarders[i] - .filteringEventAttributeValue && - mpInstance._Store.activeForwarders[i] - .filteringEventAttributeValue.eventAttributeName && - mpInstance._Store.activeForwarders[i] - .filteringEventAttributeValue.eventAttributeValue + filteringEventAttributeValue && + filteringEventAttributeValue.eventAttributeName && + filteringEventAttributeValue.eventAttributeValue ) { - var foundProp = null; + let foundProp = null; // Attempt to find the attribute in the collection of event attributes if (event.EventAttributes) { - for (var prop in event.EventAttributes) { - var hashedEventAttributeName; - hashedEventAttributeName = KitFilterHelper.hashAttributeConditionalForwarding( - prop - ); + for (const prop in event.EventAttributes) { + const hashedEventAttributeName = hashAttributeConditionalForwarding(prop); if ( hashedEventAttributeName === @@ -299,19 +292,11 @@ export default function Forwarders(mpInstance, kitBlocker) { } } - var isMatch = - foundProp !== null && - foundProp.value === - mpInstance._Store.activeForwarders[i] - .filteringEventAttributeValue - .eventAttributeValue; + const isMatch = foundProp !== null && foundProp.value === activeForwarders[i].filteringEventAttributeValue.eventAttributeValue; - var shouldInclude = - mpInstance._Store.activeForwarders[i] - .filteringEventAttributeValue.includeOnMatch === - true - ? isMatch - : !isMatch; + const shouldInclude = activeForwarders[i].filteringEventAttributeValue.includeOnMatch === true + ? isMatch + : !isMatch; if (!shouldInclude) { continue; @@ -319,7 +304,7 @@ export default function Forwarders(mpInstance, kitBlocker) { } // Clone the event object, as we could be sending different attributes to each forwarder - clonedEvent = {}; + clonedEvent = {} as SDKEvent; clonedEvent = mpInstance._Helpers.extend( true, clonedEvent, @@ -327,20 +312,20 @@ export default function Forwarders(mpInstance, kitBlocker) { ); // Check event filtering rules if ( - event.EventDataType === Types.MessageType.PageEvent && + event.EventDataType === MessageType.PageEvent && (inFilteredList( - mpInstance._Store.activeForwarders[i].eventNameFilters, + activeForwarders[i].eventNameFilters, hashedEventName ) || inFilteredList( - mpInstance._Store.activeForwarders[i] + activeForwarders[i] .eventTypeFilters, hashedEventType )) ) { continue; } else if ( - event.EventDataType === Types.MessageType.Commerce && + event.EventDataType === MessageType.Commerce && inFilteredList( mpInstance._Store.activeForwarders[i].eventTypeFilters, hashedEventType @@ -348,7 +333,7 @@ export default function Forwarders(mpInstance, kitBlocker) { ) { continue; } else if ( - event.EventDataType === Types.MessageType.PageView && + event.EventDataType === MessageType.PageView && inFilteredList( mpInstance._Store.activeForwarders[i].screenNameFilters, hashedEventName @@ -359,14 +344,14 @@ export default function Forwarders(mpInstance, kitBlocker) { // Check attribute filtering rules if (clonedEvent.EventAttributes) { - if (event.EventDataType === Types.MessageType.PageEvent) { + if (event.EventDataType === MessageType.PageEvent) { filterAttributes( clonedEvent, mpInstance._Store.activeForwarders[i] .attributeFilters ); } else if ( - event.EventDataType === Types.MessageType.PageView + event.EventDataType === MessageType.PageView ) { filterAttributes( clonedEvent, @@ -379,23 +364,21 @@ export default function Forwarders(mpInstance, kitBlocker) { // Check user identity filtering rules filterUserIdentities( clonedEvent, - mpInstance._Store.activeForwarders[i].userIdentityFilters + activeForwarders[i].userIdentityFilters ); // Check user attribute filtering rules clonedEvent.UserAttributes = mpInstance._Helpers.filterUserAttributes( clonedEvent.UserAttributes, - mpInstance._Store.activeForwarders[i].userAttributeFilters + activeForwarders[i].userAttributeFilters ); - if (mpInstance._Store.activeForwarders[i].process) { + if (activeForwarders[i].process) { mpInstance.Logger.verbose( 'Sending message to forwarder: ' + - mpInstance._Store.activeForwarders[i].name - ); - var result = mpInstance._Store.activeForwarders[i].process( - clonedEvent + activeForwarders[i].name ); + const result = activeForwarders[i].process(clonedEvent); if (result) { mpInstance.Logger.verbose(result); @@ -405,7 +388,7 @@ export default function Forwarders(mpInstance, kitBlocker) { } }; - this.handleForwarderUserAttributes = function(functionNameKey, key, value) { + this.handleForwarderUserAttributes = (functionNameKey: string, key: string, value: string | string[]) => { if ( (kitBlocker && kitBlocker.isAttributeKeyBlocked(key)) || !mpInstance._Store.activeForwarders.length @@ -414,7 +397,7 @@ export default function Forwarders(mpInstance, kitBlocker) { } mpInstance._Store.activeForwarders.forEach(function(forwarder) { - const forwarderFunction = forwarder[functionNameKey]; + const forwarderFunction: IMPForwarder = forwarder[functionNameKey]; if ( !forwarderFunction || mpInstance._Helpers.isFilteredUserAttribute( @@ -425,7 +408,7 @@ export default function Forwarders(mpInstance, kitBlocker) { return; } try { - let result; + let result: string; if ( functionNameKey === @@ -443,21 +426,22 @@ 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) { - mpInstance._Store.activeForwarders.forEach(function(forwarder) { - var filteredUserIdentities = mpInstance._Helpers.filterUserIdentities( + // @deprecated + this.setForwarderUserIdentities = (userIdentities: UserIdentities) => { + mpInstance._Store.activeForwarders.forEach((forwarder) => { + const filteredUserIdentities: ISDKUserIdentity[] = mpInstance._Helpers.filterUserIdentities( userIdentities, forwarder.userIdentityFilters ); if (forwarder.setUserIdentity) { - filteredUserIdentities.forEach(function(identity) { - var result = forwarder.setUserIdentity( + filteredUserIdentities.forEach((identity) => { + const result: string = forwarder.setUserIdentity( identity.Identity, identity.Type ); @@ -469,16 +453,16 @@ export default function Forwarders(mpInstance, kitBlocker) { }); }; - this.setForwarderOnUserIdentified = function(user) { - mpInstance._Store.activeForwarders.forEach(function(forwarder) { - var filteredUser = filteredMparticleUser( + this.setForwarderOnUserIdentified = (user: IMParticleUser) => { + mpInstance._Store.activeForwarders.forEach((forwarder) => { + const filteredUser = filteredMparticleUser( user.getMPID(), forwarder, mpInstance, kitBlocker ); if (forwarder.onUserIdentified) { - var result = forwarder.onUserIdentified(filteredUser); + const result: string = forwarder.onUserIdentified(filteredUser); if (result) { mpInstance.Logger.verbose(result); } @@ -486,18 +470,18 @@ export default function Forwarders(mpInstance, kitBlocker) { }); }; - this.setForwarderOnIdentityComplete = function(user, identityMethod) { - var result; + this.setForwarderOnIdentityComplete = (user: IMParticleUser, identityMethod: IdentityAPIMethod) => { + let result: string; - mpInstance._Store.activeForwarders.forEach(function(forwarder) { - var filteredUser = filteredMparticleUser( + mpInstance._Store.activeForwarders.forEach((forwarder: IMPForwarder) => { + const filteredUser: IMParticleUser = filteredMparticleUser( user.getMPID(), forwarder, mpInstance, kitBlocker ); - const filteredUserIdentities = filteredUser.getUserIdentities(); + const filteredUserIdentities: IdentityApiData = filteredUser.getUserIdentities(); if (identityMethod === Identify) { if (forwarder.onIdentifyComplete) { @@ -543,14 +527,11 @@ export default function Forwarders(mpInstance, kitBlocker) { }); }; - this.getForwarderStatsQueue = function() { - return mpInstance._Persistence.forwardingStatsBatches - .forwardingStatsEventQueue; - }; + this.getForwarderStatsQueue = () => + mpInstance._Persistence.forwardingStatsBatches.forwardingStatsEventQueue; - this.setForwarderStatsQueue = function(queue) { + this.setForwarderStatsQueue = (queue: IForwardingStatsData[]) => mpInstance._Persistence.forwardingStatsBatches.forwardingStatsEventQueue = queue; - }; // Processing forwarders is a 2 step process: // 1. Configure the kit @@ -558,20 +539,21 @@ 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 = (config: SDKInitConfig, forwardingStatsCallback: Callback) => { if (!config) { mpInstance.Logger.warning( 'No config was passed. Cannot process forwarders' ); - } else { - this.processUIEnabledKits(config); - this.processSideloadedKits(config); - - self.initForwarders( - mpInstance._Store.SDKConfig.identifyRequest.userIdentities, - forwardingStatsCallback - ); + return; } + + this.processUIEnabledKits(config); + this.processSideloadedKits(config); + + self.initForwarders( + mpInstance._Store.SDKConfig.identifyRequest.userIdentities, + forwardingStatsCallback + ); }; // These are kits that are enabled via the mParticle UI. @@ -580,14 +562,12 @@ 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 = (config: SDKInitConfig) => { + const kits: Dictionary = this.returnKitConstructors(); try { - if (Array.isArray(config.kitConfigs) && config.kitConfigs.length) { - config.kitConfigs.forEach(function(kitConfig) { - self.configureUIEnabledKit(kitConfig, kits); - }); + if (Array.isArray(config.kitConfigs) && !isEmpty(config.kitConfigs)) { + config.kitConfigs.forEach((kitConfig) => self.configureUIEnabledKit(kitConfig, kits)); } } catch (e) { mpInstance.Logger.error( @@ -597,7 +577,8 @@ export default function Forwarders(mpInstance, kitBlocker) { } }; - this.returnKitConstructors = function() { + this.returnKitConstructors = () => { + // FIXME: Try to set this up with registered kits or something similar let kits = {}; // If there are kits inside of mpInstance._Store.SDKConfig.kits, then mParticle is self hosted if (!isEmpty(mpInstance._Store.SDKConfig.kits)) { @@ -625,26 +606,24 @@ export default function Forwarders(mpInstance, kitBlocker) { return kits; }; - this.configureUIEnabledKit = function(configuration, kits) { - let newKit = null; - const config = configuration; + this.configureUIEnabledKit = (config: IKitConfigs, kits: Dictionary) => { + let newKit: IMPForwarder | null = null; + const { SDKConfig } = mpInstance._Store; + + for (let kitName in kits) { + const { suffix, name, isDebug, isSandbox } = config; - for (let name in kits) { // Configs are returned with suffixes also. We need to consider the // config suffix here to match the constructor suffix - let kitNameWithConfigSuffix; - if (config.suffix) { - kitNameWithConfigSuffix = `${config.name}-${config.suffix}`; - } + const kitNameWithConfigSuffix: string = suffix ? `${name}-${suffix}` : undefined; - if (name === kitNameWithConfigSuffix || name === config.name) { - if ( - config.isDebug === - mpInstance._Store.SDKConfig.isDevelopmentMode || - config.isSandbox === - mpInstance._Store.SDKConfig.isDevelopmentMode - ) { - newKit = this.returnConfiguredKit(kits[name], config); + const isDevelopmentMode: boolean = + isDebug === SDKConfig.isDevelopmentMode || + isSandbox === SDKConfig.isDevelopmentMode; + + if (kitName === kitNameWithConfigSuffix || kitName === name) { + if (isDevelopmentMode) { + newKit = this.returnConfiguredKit(kits[kitName], config); mpInstance._Store.configuredForwarders.push(newKit); break; @@ -660,20 +639,24 @@ 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) { + // FIXME: Fix types here + this.processSideloadedKits = (mpConfig: SDKInitConfig) => { try { if (Array.isArray(mpConfig.sideloadedKits)) { - const registeredSideloadedKits = { kits: {} }; + const registeredSideloadedKits: KitRegistrationConfig = { kits: {} }; + + // FIXME: Expected type causes error const unregisteredSideloadedKits = mpConfig.sideloadedKits; - unregisteredSideloadedKits.forEach(function(unregisteredKit) { + // FIXME: Define type + unregisteredSideloadedKits.forEach((unregisteredKit) => { try { // Register each sideloaded kit, which adds a key of the sideloaded kit name // and a value of the sideloaded kit constructor. unregisteredKit.kitInstance.register( registeredSideloadedKits ); - const kitName = unregisteredKit.kitInstance.name; + const kitName: string = unregisteredKit.kitInstance.name; // Then add the kit filters to each registered kit. registeredSideloadedKits.kits[kitName].filters = unregisteredKit.filterDictionary; @@ -708,13 +691,14 @@ 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 = (kitConstructor: RegisteredKit) => { mpInstance._Store.configuredForwarders.push( - this.returnConfiguredKit(kitConstructor, kitConstructor.filters) + // FIXME: Figure out why filters should be typed as IKitConfigs + this.returnConfiguredKit(kitConstructor, kitConstructor.filters as IKitConfigs) ); }; - this.returnConfiguredKit = function(forwarder, config = {}) { + this.returnConfiguredKit = function(forwarder, config = {} as IKitConfigs) { const newForwarder = new forwarder.constructor(); newForwarder.id = config.moduleId; @@ -751,21 +735,21 @@ export default function Forwarders(mpInstance, kitBlocker) { return newForwarder; }; - this.configurePixel = function(settings) { + this.configurePixel = (settings: IPixelConfiguration) => { + const { SDKConfig } = mpInstance._Store; + if ( - settings.isDebug === - mpInstance._Store.SDKConfig.isDevelopmentMode || - settings.isProduction !== - mpInstance._Store.SDKConfig.isDevelopmentMode + settings.isDebug === SDKConfig.isDevelopmentMode || + settings.isProduction !== SDKConfig.isDevelopmentMode ) { mpInstance._Store.pixelConfigurations.push(settings); } }; - this.processPixelConfigs = function(config) { + this.processPixelConfigs = (config: SDKInitConfig) => { try { if (!isEmpty(config.pixelConfigs)) { - config.pixelConfigs.forEach(function(pixelConfig) { + config.pixelConfigs.forEach((pixelConfig: IPixelConfiguration) => { self.configurePixel(pixelConfig); }); } @@ -777,9 +761,9 @@ export default function Forwarders(mpInstance, kitBlocker) { } }; - this.sendSingleForwardingStatsToServer = async forwardingStatsData => { + this.sendSingleForwardingStatsToServer = async (forwardingStatsData: IForwardingStatsData) => { // https://go.mparticle.com/work/SQDSDKS-6568 - const fetchPayload = { + const fetchPayload: IFetchPayload = { method: 'post', body: JSON.stringify(forwardingStatsData), headers: { @@ -788,9 +772,9 @@ export default function Forwarders(mpInstance, kitBlocker) { }, }; - const response = await this.forwarderStatsUploader.upload(fetchPayload); + const response: 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/identity-user-interfaces.ts b/src/identity-user-interfaces.ts index fe2022746..c82116eba 100644 --- a/src/identity-user-interfaces.ts +++ b/src/identity-user-interfaces.ts @@ -29,7 +29,7 @@ interface ICart { // https://go.mparticle.com/work/SQDSDKS-5033 // https://go.mparticle.com/work/SQDSDKS-6354 export interface IMParticleUser extends User { - getAllUserAttributes(): any; + getAllUserAttributes(): UserAttributes; setUserTag(tagName: string, value?: any): void; setUserAttribute(key: string, value: any): void; getUserAudiences?(callback?: IdentityCallback): void; diff --git a/src/kitBlocking.ts b/src/kitBlocking.ts index 17622faca..956677ee6 100644 --- a/src/kitBlocking.ts +++ b/src/kitBlocking.ts @@ -1,7 +1,7 @@ import { convertEvent } from './sdkToEventsApiConverter'; -import { SDKEvent, MParticleWebSDK, KitBlockerDataPlan, SDKProduct } from './sdkRuntimeModels'; +import { SDKEvent, KitBlockerDataPlan, SDKProduct } from './sdkRuntimeModels'; import { BaseEvent, EventTypeEnum, CommerceEvent, ScreenViewEvent, CustomEvent } from '@mparticle/event-models'; -import Types from './types' +import Types, { CommerceEventType } from './types' import { DataPlanPoint } from '@mparticle/data-planning-models'; import { IMParticleWebSDKInstance } from './mp-instance'; @@ -415,12 +415,12 @@ export default class KitBlocker { } if (matchedEvent) { switch (event.EventCategory) { - case Types.CommerceEventType.ProductImpression: + case CommerceEventType.ProductImpression: clonedEvent.ProductImpressions.forEach(impression=> { removeAttribute(matchedEvent, impression?.ProductList) }); break; - case Types.CommerceEventType.ProductPurchase: + case CommerceEventType.ProductPurchase: removeAttribute(matchedEvent, clonedEvent.ProductAction?.ProductList) break; default: diff --git a/src/mp-instance.ts b/src/mp-instance.ts index ff74a52d9..b1258c2bf 100644 --- a/src/mp-instance.ts +++ b/src/mp-instance.ts @@ -49,6 +49,7 @@ import { IECommerce } from './ecommerce.interfaces'; import { INativeSdkHelpers } from './nativeSdkHelpers.interfaces'; import { IPersistence } from './persistence.interfaces'; import ForegroundTimer from './foregroundTimeTracker'; +import { IMPForwarder } from './forwarders.interfaces'; import RoktManager from './roktManager'; export interface IErrorLogMessage { @@ -73,7 +74,7 @@ export interface IMParticleWebSDKInstance extends MParticleWebSDK { _CookieSyncManager: ICookieSyncManager; _Ecommerce: IECommerce; _Events: IEvents; - _Forwarders: any; // https://go.mparticle.com/work/SQDSDKS-5767 + _Forwarders: IMPForwarder _ForwardingStatsUploader: ForwardingStatsUploader; _Helpers: SDKHelpersApi; _Identity: IIdentity; diff --git a/src/pre-init-utils.ts b/src/pre-init-utils.ts index 63505e25e..addb5145c 100644 --- a/src/pre-init-utils.ts +++ b/src/pre-init-utils.ts @@ -1,12 +1,12 @@ import { IPixelConfiguration } from './cookieSyncManager'; -import { MPForwarder } from './forwarders.interfaces'; +import { Kit, MPForwarder } from './forwarders.interfaces'; import { IntegrationDelays } from './mp-instance'; import { isEmpty, isFunction } from './utils'; export interface IPreInit { readyQueue: Function[] | any[]; integrationDelays: IntegrationDelays; - forwarderConstructors: MPForwarder[]; + forwarderConstructors: Kit[]; pixelConfigurations?: IPixelConfiguration[]; isDevelopmentMode?: boolean; } diff --git a/src/sdkRuntimeModels.ts b/src/sdkRuntimeModels.ts index 5a3e238e3..d9ad95a50 100644 --- a/src/sdkRuntimeModels.ts +++ b/src/sdkRuntimeModels.ts @@ -6,15 +6,16 @@ import { SDKEventOptions, SDKEventAttrs, Callback, + UserIdentities, } from '@mparticle/web-sdk'; import { IntegrationAttribute, IntegrationAttributes, IStore, WrapperSDKTypes } from './store'; import Validators from './validators'; import { Dictionary, valueof } from './utils'; import { IKitConfigs } from './configAPIClient'; import { SDKConsentApi, SDKConsentState } from './consent'; -import MPSideloadedKit from './sideloadedKit'; +import MPSideloadedKit, { IMPSideloadedKit } from './sideloadedKit'; import { ISessionManager } from './sessionManager'; -import { ConfiguredKit, MPForwarder, UnregisteredKit } from './forwarders.interfaces'; +import { ConfiguredKit, IMPForwarder, UnregisteredKit, UserAttributeFilters, UserIdentityFilters } from './forwarders.interfaces'; import { SDKIdentityApi, IAliasCallback, @@ -26,6 +27,7 @@ import { ISDKUserIdentity, IdentityCallback, ISDKUserAttributes, + UserAttributes, } from './identity-user-interfaces'; import { CommerceEventType, @@ -48,8 +50,9 @@ export interface SDKEvent { DeviceId: string; IsFirstRun: boolean; EventName: string; + // EventCategory: valueof | valueof; EventCategory: number; - UserAttributes?: ISDKUserAttributes; + UserAttributes?: UserAttributes; UserIdentities?: ISDKUserIdentity[]; SourceMessageId: string; MPID: string; @@ -60,6 +63,7 @@ export interface SDKEvent { SessionLength?: number; currentSessionMPIDs?: string[]; Timestamp: number; + // EventDataType: valueof; EventDataType: number; Debug: boolean; Location?: SDKGeoLocation; @@ -273,7 +277,7 @@ export interface SDKInitConfig kitConfigs?: IKitConfigs[]; kits?: Dictionary; - sideloadedKits?: MPForwarder[]; + sideloadedKits?: IMPSideloadedKit[]; dataPlanOptions?: KitBlockerOptions; flags?: Dictionary; pixelConfigs?: IPixelConfiguration[]; @@ -317,6 +321,9 @@ export interface SDKHelpersApi { createServiceUrl(url: string, devToken?: string): string; createXHR?(cb: () => void): XMLHttpRequest; extend?(...args: any[]); + isFilteredUserAttribute?: (key: string, filterList: UserAttributeFilters) => boolean; + filterUserAttributes?: (userAttributes: UserAttributes, filterList: UserAttributeFilters) => ISDKUserAttributes; + filterUserIdentities?: (userIdentities: UserIdentities, filterList: UserIdentityFilters) => ISDKUserIdentity[]; findKeyInObject?(obj: any, key: string): string; parseNumber?(value: string | number): number; generateUniqueId(); @@ -374,8 +381,10 @@ export interface SDKConfigApi { } export interface BaseEvent { + // messageType: valueof; messageType: number; name?: string; + // eventType?: valueof | valueof; eventType?: number; data?: SDKEventAttrs; customFlags?: { [key: string]: string }; diff --git a/src/sdkToEventsApiConverter.ts b/src/sdkToEventsApiConverter.ts index 1bfe59d1e..c2c2acbbe 100644 --- a/src/sdkToEventsApiConverter.ts +++ b/src/sdkToEventsApiConverter.ts @@ -11,8 +11,8 @@ import { SDKGDPRConsentState, SDKCCPAConsentState, } from './consent'; -import Types from './types'; -import { Dictionary, isEmpty } from './utils'; +import Types, { CommerceEventType, EventType } from './types'; +import { Dictionary, isEmpty, valueof } from './utils'; import { ISDKUserIdentity } from './identity-user-interfaces'; import { SDKIdentityTypeEnum } from './identity.interfaces'; import Constants from './constants'; @@ -113,7 +113,7 @@ export function convertEvents( ? window.screen.height : 0, }, - user_attributes: lastEvent.UserAttributes, + user_attributes: lastEvent.UserAttributes as Record, user_identities: convertUserIdentities(lastEvent.UserIdentities), consent_state: convertConsentState(currentConsentState), integration_attributes: lastEvent.IntegrationAttributes, @@ -592,6 +592,7 @@ export function convertCustomEvent(sdkEvent: SDKEvent): EventsApi.CustomEvent { } export function convertSdkEventType( + // sdkEventType: valueof | valueof sdkEventType: number ): | EventsApi.CustomEventDataCustomEventTypeEnum diff --git a/src/serverModel.ts b/src/serverModel.ts index c7cd2c9bd..598ef67ee 100644 --- a/src/serverModel.ts +++ b/src/serverModel.ts @@ -384,8 +384,8 @@ export default function ServerModel( this.convertEventToV2DTO = function(event: IUploadObject): IServerV2DTO { var dto: Partial = { n: event.EventName, - et: event.EventCategory, - ua: event.UserAttributes, + et: event.EventCategory as number, + ua: event.UserAttributes as Record, ui: event.UserIdentities, ia: event.IntegrationAttributes, str: event.Store, diff --git a/src/sideloadedKit.ts b/src/sideloadedKit.ts index 5bc6d1e63..88bee5f12 100644 --- a/src/sideloadedKit.ts +++ b/src/sideloadedKit.ts @@ -13,6 +13,7 @@ export interface IMPSideloadedKit { kitInstance: UnregisteredKit; filterDictionary: IKitFilterSettings; + // Custom filter methods used only for sideloaded kits addEventTypeFilter(eventType: valueof): void; addEventNameFilter(eventType: valueof, eventName: string): void; addEventAttributeFilter( @@ -120,6 +121,10 @@ export default class MPSideloadedKit implements IMPSideloadedKit{ const hashedUserAttributeKey = KitFilterHelper.hashUserAttribute( userAttributeKey ); + + // FIXME: this should technically be a string, but we are expecting a number + // and is bvreaking tests + // @ts-ignore this.filterDictionary.userAttributeFilters.push(hashedUserAttributeKey); } } diff --git a/src/store.ts b/src/store.ts index 1f6179323..0dcea5c22 100644 --- a/src/store.ts +++ b/src/store.ts @@ -30,7 +30,7 @@ import { returnConvertedBoolean, } from './utils'; import { IMinifiedConsentJSONObject, SDKConsentState } from './consent'; -import { ConfiguredKit, MPForwarder, UnregisteredKit } from './forwarders.interfaces'; +import { ConfiguredKit, UnregisteredKit } from './forwarders.interfaces'; import { IdentityCallback, UserAttributes } from './identity-user-interfaces'; import { IGlobalStoreV2MinifiedKeys, @@ -39,6 +39,7 @@ import { import { CookieSyncDates, IPixelConfiguration } from './cookieSyncManager'; import { IMParticleWebSDKInstance } from './mp-instance'; import ForegroundTimer from './foregroundTimeTracker'; +import { IMPSideloadedKit, IMPSideloadedKitConstructor } from './sideloadedKit'; // This represents the runtime configuration of the SDK AFTER // initialization has been complete and all settings and @@ -69,6 +70,7 @@ export interface SDKConfig { identifyRequest: IdentifyRequest; identityCallback: IdentityCallback; integrationDelayTimeout: number; + // sideloadedKits: IMPSideloadedKit[]; sideloadedKits: MPForwarder[]; aliasMaxWindow: number; deviceId?: string; @@ -179,9 +181,9 @@ export interface IStore { storageName: string | null; prodStorageName: string | null; activeForwarders: ConfiguredKit[]; - kits: Dictionary; - sideloadedKits: MPForwarder[]; - configuredForwarders: MPForwarder[]; + kits: Dictionary; + sideloadedKits: IMPSideloadedKit[]; + configuredForwarders: ConfiguredKit[]; pixelConfigurations: IPixelConfiguration[]; integrationDelayTimeoutStart: number; // UNIX Timestamp webviewBridgeEnabled?: boolean; diff --git a/test/src/tests-apiClient.ts b/test/src/tests-apiClient.ts index 614045fbb..06473a720 100644 --- a/test/src/tests-apiClient.ts +++ b/test/src/tests-apiClient.ts @@ -93,7 +93,7 @@ describe('Api Client', () => { getConsentState: () => { return consentState; }, - } as IMParticleUser; + } as unknown as IMParticleUser; }; mParticle diff --git a/test/src/tests-forwarders.ts b/test/src/tests-forwarders.ts index 11156d7cf..df1333eae 100644 --- a/test/src/tests-forwarders.ts +++ b/test/src/tests-forwarders.ts @@ -16,6 +16,9 @@ import { IdentityType } from '../../src/types'; import { IntegrationAttribute } from '../../src/store'; import { IConsentRules } from '../../src/consent'; import { UserIdentities } from '@mparticle/web-sdk'; +import { IMPSideloadedKit } from '../../src/sideloadedKit'; +import { UnregisteredKit } from '../../src/forwarders.interfaces'; +import { IFilteringUserAttributeValue } from '../../src/configAPIClient'; const { @@ -2048,7 +2051,7 @@ describe('forwarders', function() { enabled = mParticle .getInstance() - ._Forwarders.isEnabledForUserAttributes({}, null); + ._Forwarders.isEnabledForUserAttributes({} as IFilteringUserAttributeValue, null); expect(enabled).to.be.ok; }); @@ -3155,10 +3158,10 @@ describe('forwarders', function() { }); describe('filter dictionary integration tests', function() { - let sideloadedKit1; - let sideloadedKit2; - let mpSideloadedKit1; - let mpSideloadedKit2; + let sideloadedKit1: UnregisteredKit; + let sideloadedKit2: UnregisteredKit; + let mpSideloadedKit1: IMPSideloadedKit; + let mpSideloadedKit2: IMPSideloadedKit; beforeEach(function() { sideloadedKit1 = new MockSideloadedKit('SideloadedKit1', 1); @@ -3201,6 +3204,7 @@ describe('forwarders', function() { // The received event gets replaced by the last event sent to the forwarder // SideloadedKit11 has received the session start event, but not the Test Event // SideloadedKit22 will receive the Test Event + window.SideloadedKit11.instance.receivedEvent.EventName.should.not.equal( 'Test Event' ); diff --git a/test/src/tests-identities-attributes.ts b/test/src/tests-identities-attributes.ts index 1c9fdd222..1f8cff916 100644 --- a/test/src/tests-identities-attributes.ts +++ b/test/src/tests-identities-attributes.ts @@ -643,7 +643,7 @@ describe('identities and attributes', function() { const userAttributes = mParticle.Identity.getCurrentUser().getAllUserAttributes(); userAttributes.blah = 'test'; - userAttributes['numbers'].push(6); + (userAttributes['numbers'] as number[]).push(6); const userAttributes1 = mParticle.Identity.getCurrentUser().getAllUserAttributes(); diff --git a/test/src/tests-runtimeToBatchEventsDTO.ts b/test/src/tests-runtimeToBatchEventsDTO.ts index fb4522209..9dca1f019 100644 --- a/test/src/tests-runtimeToBatchEventsDTO.ts +++ b/test/src/tests-runtimeToBatchEventsDTO.ts @@ -66,7 +66,7 @@ describe('Old model to batch model conversion', () => { getConsentState: () => { return null; }, - } as IMParticleUser; + } as unknown as IMParticleUser; }; const publicEvent = { @@ -143,7 +143,7 @@ describe('Old model to batch model conversion', () => { getConsentState: () => { return null; }, - } as IMParticleUser; + } as unknown as IMParticleUser; }; const publicEvent = { messageType: Types.MessageType.PageEvent, diff --git a/test/src/tests-serverModel.ts b/test/src/tests-serverModel.ts index 3e96e630f..724dd0622 100644 --- a/test/src/tests-serverModel.ts +++ b/test/src/tests-serverModel.ts @@ -1319,7 +1319,7 @@ describe('ServerModel', () => { getConsentState: () => { return consentState; }, - } as IMParticleUser; + } as unknown as IMParticleUser; }; let sdkEvent = mParticle .getInstance() From cac319ebf1c251a99b93969a2f9bedc5cf991096 Mon Sep 17 00:00:00 2001 From: Alexander Sapountzis Date: Tue, 18 Mar 2025 15:08:09 -0400 Subject: [PATCH 2/8] Save Point --- src/configAPIClient.ts | 3 ++ src/forwarders.interfaces.ts | 90 ++++++++++++++++++++---------------- src/forwarders.ts | 38 ++++++++------- src/kitFilterHelper.ts | 5 +- src/pre-init-utils.ts | 4 +- src/sdkRuntimeModels.ts | 2 +- src/sideloadedKit.ts | 1 + src/store.ts | 5 +- src/utils.ts | 2 +- test/jest/utils.spec.ts | 19 ++++++++ test/src/tests-utils.ts | 15 ------ 11 files changed, 104 insertions(+), 80 deletions(-) diff --git a/src/configAPIClient.ts b/src/configAPIClient.ts index f88e5677b..34ec17502 100644 --- a/src/configAPIClient.ts +++ b/src/configAPIClient.ts @@ -16,6 +16,7 @@ import { IPixelConfiguration } from './cookieSyncManager'; import { IMParticleWebSDKInstance } from './mp-instance'; import { UserAttributeFilters, UserIdentityFilters } from './forwarders.interfaces'; +// FIXME: Technically this is an overlap of ISDKInitConfig export interface IKitConfigs extends IKitFilterSettings { name: string; suffix?: string; @@ -24,6 +25,8 @@ export interface IKitConfigs extends IKitFilterSettings { isVisible: boolean; isDebugString: BooleanStringLowerCase; hasDebugString: BooleanStringLowerCase; + + // TODO: These settings overlap with ForwarderSettings settings: Dictionary; eventSubscriptionId: number; excludeAnonymousUser: boolean; diff --git a/src/forwarders.interfaces.ts b/src/forwarders.interfaces.ts index 74aaa29ff..646c763fd 100644 --- a/src/forwarders.interfaces.ts +++ b/src/forwarders.interfaces.ts @@ -1,7 +1,5 @@ import { SDKEvent, SDKEventCustomFlags, SDKInitConfig } from './sdkRuntimeModels'; import { Dictionary } from './utils'; -import { IKitConfigs, IKitFilterSettings } from './configAPIClient'; -import { IdentityApiData } from '@mparticle/web-sdk'; import { IFilteringConsentRuleValues, IFilteringEventAttributeValue, IFilteringUserAttributeValue, IKitConfigs, IKitFilterSettings } from './configAPIClient'; import { Callback, IdentityApiData, Logger, UserIdentities } from '@mparticle/web-sdk'; import { @@ -45,17 +43,17 @@ export interface ConfiguredKit common: Dictionary; id: number; init( - settings: Dictionary, + settings: Dictionary, // FIXME: Make this a real type service: forwardingStatsCallback, testMode: boolean, trackerId: string | null, - userAttributes: UserAttributes, - userIdentities: ISDKUserIdentity, + userAttributes: ISDKUserAttributes, + userIdentities: ISDKUserIdentity[], appVersion: string, appName: string, customFlags: SDKEventCustomFlags, clientId: string - ): string; + ): string; onIdentifyComplete( user: IMParticleUser, filteredIdentityRequest: IdentityApiData @@ -72,16 +70,27 @@ export interface ConfiguredKit user: IMParticleUser, filteredIdentityRequest: IdentityApiData ): string; - onUserIdentified(user: IMParticleUser): string; + + // Techically these do not return a value, but we sometimes use a string as a debug message + onUserIdentified(user: IMParticleUser, identityApiData?: IdentityApiData): string; process(event: SDKEvent): string; setOptOut(isOptingOut: boolean): string; removeUserAttribute(key: string): string; - setUserAttribute(key: string, value: string): string; - setUserIdentity(id: UserIdentityId, type: UserIdentityType): void; + setUserAttribute(key: string, value: string | string[]): string; + setUserIdentity(id: UserIdentityId, type: UserIdentityType): string; // TODO: https://go.mparticle.com/work/SQDSDKS-5156 isSandbox: boolean; hasSandbox: boolean; + + filteringConsentRuleValues: IFilteringConsentRuleValues; + filteringUserAttributeValue: IFilteringUserAttributeValue; + filteringEventAttributeValue: IFilteringEventAttributeValue; + excludeAnonymousUser: boolean; + userIdentityFilters: UserIdentityFilters; + userAttributeFilters: UserAttributeFilters; + initialized: boolean; + logger: Logger; } export type UserIdentityId = string; @@ -102,6 +111,7 @@ interface ForwarderSettings { PriorityValue?: number; } +// Represents the Forwarder Module in the SDK export interface IMPForwarder { // @deprecated setForwarderUserIdentities: (userIdentities: UserIdentities) => void; @@ -113,14 +123,14 @@ export interface IMPForwarder { settings: ForwarderSettings; forwarderStatsUploader: AsyncUploader; isInitialized: boolean; - filteringConsentRuleValues: IFilteringConsentRuleValues; - filteringUserAttributeValue: IFilteringUserAttributeValue; - filteringEventAttributeValue: IFilteringEventAttributeValue; - excludeAnonymousUser: boolean; - userIdentityFilters: UserIdentityFilters; - userAttributeFilters: UserAttributeFilters; - initialized: boolean; - logger: Logger; + // filteringConsentRuleValues: IFilteringConsentRuleValues; + // filteringUserAttributeValue: IFilteringUserAttributeValue; + // filteringEventAttributeValue: IFilteringEventAttributeValue; + // excludeAnonymousUser: boolean; + // userIdentityFilters: UserIdentityFilters; + // userAttributeFilters: UserAttributeFilters; + // initialized: boolean; + // logger: Logger; suffix?: string; @@ -149,22 +159,22 @@ export interface IMPForwarder { sendEventToForwarders: (event: SDKEvent) => void; processPixelConfigs: (pixelConfigs: SDKInitConfig) => void; configurePixel: (pixelConfig: IPixelConfiguration) => void; - returnConfiguredKit: (forwarder: RegisteredKit, config: IKitConfigs) => IMPForwarder; + returnConfiguredKit: (forwarder: RegisteredKit, config: IKitConfigs) => ConfiguredKit; processSideloadedKits: (mpConfig: SDKInitConfig) => void; - init: ( - setting: ForwarderSettings, - forwarderSettingsCallback: Callback, - testMode: boolean, - trackerId: string | number | null, - filteredUserAttributes: ISDKUserAttributes, - filteredUserIdentities: ISDKUserIdentity[], - appVersion: string, - appName: string, - customFlags: SDKEventCustomFlags, - clientId: string - ) => void; + // init: ( + // setting: ForwarderSettings, + // forwarderSettingsCallback: Callback, + // testMode: boolean, + // trackerId: string | number | null, + // filteredUserAttributes: ISDKUserAttributes, + // filteredUserIdentities: ISDKUserIdentity[], + // appVersion: string, + // appName: string, + // customFlags: SDKEventCustomFlags, + // clientId: string + // ) => void; initForwarders: (userIdentities: UserIdentities, forwarderStatsCallback: Callback) => void; isEnabledForUserAttributes: (filterObject?: IFilteringUserAttributeValue, user?: IMParticleUser) => boolean; @@ -173,16 +183,16 @@ export interface IMPForwarder { name?: string; // Techically these do not return a value, but we sometimes use a string as a debug message - onUserIdentified?: (user: IMParticleUser, identityApiData?: IdentityApiData) => string; - onIdentifyComplete?: (user: IMParticleUser, identityApiData: IdentityApiData) => string; - onLoginComplete?: (user: IMParticleUser, identityApiData: IdentityApiData) => string; - onLogoutComplete?: (user: IMParticleUser, identityApiData: IdentityApiData) => string; - onModifyComplete?: (user: IMParticleUser, identityApiData: IdentityApiData) => string; - setOptOut: (optOut: boolean) => string; - setUserAttribute?: (key: string, value: string | string[]) => string; - removeUserAttribute?: (key: string) => string; - process?: (event: SDKEvent) => string; - setUserIdentity?: (identity: string, type: number) => string; + // onUserIdentified?: (user: IMParticleUser, identityApiData?: IdentityApiData) => string; + // onIdentifyComplete?: (user: IMParticleUser, identityApiData: IdentityApiData) => string; + // onLoginComplete?: (user: IMParticleUser, identityApiData: IdentityApiData) => string; + // onLogoutComplete?: (user: IMParticleUser, identityApiData: IdentityApiData) => string; + // onModifyComplete?: (user: IMParticleUser, identityApiData: IdentityApiData) => string; + // setOptOut: (optOut: boolean) => string; + // setUserAttribute?: (key: string, value: string | string[]) => string; + // removeUserAttribute?: (key: string) => string; + // process?: (event: SDKEvent) => string; + // setUserIdentity?: (identity: string, type: number) => string; getForwarderStatsQueue: () => IForwardingStatsData[]; setForwarderStatsQueue: (queue: IForwardingStatsData[]) => void; diff --git a/src/forwarders.ts b/src/forwarders.ts index be56d94a9..68f571c95 100644 --- a/src/forwarders.ts +++ b/src/forwarders.ts @@ -1,16 +1,19 @@ import { EventType, IdentityType, MessageType } from './types'; import filteredMparticleUser from './filteredMparticleUser'; -import { inArray, isEmpty, valueof } from './utils'; +import { Dictionary, inArray, isEmpty, valueof } from './utils'; import KitFilterHelper from './kitFilterHelper'; import Constants from './constants'; -import APIClient from './apiClient'; -import { IMPForwarder, KitRegistrationConfig, UserAttributeFilters, UserIdentityFilters } from './forwarders.interfaces'; +import APIClient, { IForwardingStatsData } from './apiClient'; +import { ConfiguredKit, IMPForwarder, KitRegistrationConfig, RegisteredKit, UserAttributeFilters, UserIdentityFilters } from './forwarders.interfaces'; import { IMParticleWebSDKInstance } from './mp-instance'; import KitBlocker from './kitBlocking'; -import { IFilteringUserAttributeValue, IKitConfigs } from './configAPIClient'; +import { IFilteringConsentRuleValues, IFilteringEventAttributeValue, IFilteringUserAttributeValue, IKitConfigs } from './configAPIClient'; import { IMParticleUser, ISDKUserAttributes, ISDKUserIdentity, UserAttributes } from './identity-user-interfaces'; -import { SDKEvent } from './sdkRuntimeModels'; -import { Callback, UserIdentities } from '@mparticle/web-sdk'; +import { SDKEvent, SDKInitConfig } from './sdkRuntimeModels'; +import { Callback, IdentityApiData, UserIdentities } from '@mparticle/web-sdk'; +import { IdentityAPIMethod } from './identity.interfaces'; +import { IPixelConfiguration } from './cookieSyncManager'; +import { IFetchPayload } from './uploaders'; const { Modify, Identify, Login, Logout } = Constants.IdentityMethods; @@ -46,7 +49,7 @@ export default function Forwarders(this: IMPForwarder, mpInstance: IMParticleWe ); }); - mpInstance._Store.activeForwarders = configuredForwarders.filter((forwarder: IMPForwarder) => { + mpInstance._Store.activeForwarders = configuredForwarders.filter((forwarder: ConfiguredKit) => { if ( !isEnabledForUserConsent( forwarder.filteringConsentRuleValues, @@ -158,12 +161,12 @@ export default function Forwarders(this: IMPForwarder, mpInstance: IMParticleWe }; this.applyToForwarders = (functionName: string, functionArgs: any[]) => { - const activeForwarders: IMPForwarder[] = mpInstance._Store.activeForwarders; + const activeForwarders: ConfiguredKit[] = mpInstance._Store.activeForwarders; if (!activeForwarders) { return; } - activeForwarders.forEach(function(forwarder) { + activeForwarders.forEach(function(forwarder: ConfiguredKit) { const forwarderFunction: IMPForwarder = forwarder[functionName]; if (forwarderFunction) { try { @@ -454,7 +457,7 @@ export default function Forwarders(this: IMPForwarder, mpInstance: IMParticleWe }; this.setForwarderOnUserIdentified = (user: IMParticleUser) => { - mpInstance._Store.activeForwarders.forEach((forwarder) => { + mpInstance._Store.activeForwarders.forEach((forwarder: ConfiguredKit) => { const filteredUser = filteredMparticleUser( user.getMPID(), forwarder, @@ -473,7 +476,7 @@ export default function Forwarders(this: IMPForwarder, mpInstance: IMParticleWe this.setForwarderOnIdentityComplete = (user: IMParticleUser, identityMethod: IdentityAPIMethod) => { let result: string; - mpInstance._Store.activeForwarders.forEach((forwarder: IMPForwarder) => { + mpInstance._Store.activeForwarders.forEach((forwarder: ConfiguredKit) => { const filteredUser: IMParticleUser = filteredMparticleUser( user.getMPID(), forwarder, @@ -607,7 +610,7 @@ export default function Forwarders(this: IMPForwarder, mpInstance: IMParticleWe }; this.configureUIEnabledKit = (config: IKitConfigs, kits: Dictionary) => { - let newKit: IMPForwarder | null = null; + let newKit: ConfiguredKit | null = null; const { SDKConfig } = mpInstance._Store; for (let kitName in kits) { @@ -698,8 +701,9 @@ export default function Forwarders(this: IMPForwarder, mpInstance: IMParticleWe ); }; - this.returnConfiguredKit = function(forwarder, config = {} as IKitConfigs) { - const newForwarder = new forwarder.constructor(); + this.returnConfiguredKit = (forwarder: RegisteredKit, config: IKitConfigs) => { + // FIXME: Make this a real type + const newForwarder: ConfiguredKit = new forwarder.constructor() as ConfiguredKit; newForwarder.id = config.moduleId; // TODO: isSandbox, hasSandbox is never used in any kit or in core SDK. @@ -723,12 +727,12 @@ export default function Forwarders(this: IMPForwarder, mpInstance: IMParticleWe newForwarder.userAttributeFilters = config.userAttributeFilters || []; newForwarder.filteringEventAttributeValue = - config.filteringEventAttributeValue || {}; + config.filteringEventAttributeValue || {} as IFilteringEventAttributeValue; newForwarder.filteringUserAttributeValue = - config.filteringUserAttributeValue || {}; + config.filteringUserAttributeValue || {} as IFilteringUserAttributeValue; newForwarder.eventSubscriptionId = config.eventSubscriptionId || null; newForwarder.filteringConsentRuleValues = - config.filteringConsentRuleValues || {}; + config.filteringConsentRuleValues || {} as IFilteringConsentRuleValues; newForwarder.excludeAnonymousUser = config.excludeAnonymousUser || false; diff --git a/src/kitFilterHelper.ts b/src/kitFilterHelper.ts index 0bbb44ba6..160b28033 100644 --- a/src/kitFilterHelper.ts +++ b/src/kitFilterHelper.ts @@ -1,16 +1,19 @@ import { generateHash, valueof } from "./utils"; // TODO: https://mparticle-eng.atlassian.net/browse/SQDSDKS-5381 -import { EventType, IdentityType } from "./types"; +import { CommerceEventType, EventType, IdentityType } from "./types"; export default class KitFilterHelper { + // static hashEventType(eventType: valueof | valueof): number { static hashEventType(eventType: valueof): number { return generateHash(eventType as unknown as string); }; + // static hashEventName(eventName: string, eventType: valueof | valueof): number { static hashEventName(eventName: string, eventType: valueof): number { return generateHash(eventType + eventName); }; + // static hashEventAttributeKey(eventType: valueof | valueof, eventName: string, customAttributeName: string): number { static hashEventAttributeKey(eventType: valueof, eventName: string, customAttributeName: string): number { return generateHash(eventType + eventName + customAttributeName); } diff --git a/src/pre-init-utils.ts b/src/pre-init-utils.ts index addb5145c..3d2ac42ba 100644 --- a/src/pre-init-utils.ts +++ b/src/pre-init-utils.ts @@ -1,12 +1,12 @@ import { IPixelConfiguration } from './cookieSyncManager'; -import { Kit, MPForwarder } from './forwarders.interfaces'; +import { UnregisteredKit } from './forwarders.interfaces'; import { IntegrationDelays } from './mp-instance'; import { isEmpty, isFunction } from './utils'; export interface IPreInit { readyQueue: Function[] | any[]; integrationDelays: IntegrationDelays; - forwarderConstructors: Kit[]; + forwarderConstructors: UnregisteredKit[]; pixelConfigurations?: IPixelConfiguration[]; isDevelopmentMode?: boolean; } diff --git a/src/sdkRuntimeModels.ts b/src/sdkRuntimeModels.ts index d9ad95a50..2e77c8d66 100644 --- a/src/sdkRuntimeModels.ts +++ b/src/sdkRuntimeModels.ts @@ -15,7 +15,7 @@ import { IKitConfigs } from './configAPIClient'; import { SDKConsentApi, SDKConsentState } from './consent'; import MPSideloadedKit, { IMPSideloadedKit } from './sideloadedKit'; import { ISessionManager } from './sessionManager'; -import { ConfiguredKit, IMPForwarder, UnregisteredKit, UserAttributeFilters, UserIdentityFilters } from './forwarders.interfaces'; +import { ConfiguredKit, UnregisteredKit, UserAttributeFilters, UserIdentityFilters } from './forwarders.interfaces'; import { SDKIdentityApi, IAliasCallback, diff --git a/src/sideloadedKit.ts b/src/sideloadedKit.ts index 88bee5f12..05abdb67a 100644 --- a/src/sideloadedKit.ts +++ b/src/sideloadedKit.ts @@ -9,6 +9,7 @@ import { UnregisteredKit } from './forwarders.interfaces'; import { EventType, IdentityType } from './types'; import { valueof } from './utils'; +// FIXME: Decide if this should extend Kit or RegisteredKit depending on the overlap export interface IMPSideloadedKit { kitInstance: UnregisteredKit; filterDictionary: IKitFilterSettings; diff --git a/src/store.ts b/src/store.ts index 0dcea5c22..f76ab3ec6 100644 --- a/src/store.ts +++ b/src/store.ts @@ -39,7 +39,7 @@ import { import { CookieSyncDates, IPixelConfiguration } from './cookieSyncManager'; import { IMParticleWebSDKInstance } from './mp-instance'; import ForegroundTimer from './foregroundTimeTracker'; -import { IMPSideloadedKit, IMPSideloadedKitConstructor } from './sideloadedKit'; +import { IMPSideloadedKit } from './sideloadedKit'; // This represents the runtime configuration of the SDK AFTER // initialization has been complete and all settings and @@ -70,8 +70,7 @@ export interface SDKConfig { identifyRequest: IdentifyRequest; identityCallback: IdentityCallback; integrationDelayTimeout: number; - // sideloadedKits: IMPSideloadedKit[]; - sideloadedKits: MPForwarder[]; + sideloadedKits: IMPSideloadedKit[]; aliasMaxWindow: number; deviceId?: string; forceHttps?: boolean; diff --git a/src/utils.ts b/src/utils.ts index a5e6fbc6a..21f1d816a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -16,7 +16,7 @@ const createCookieString = (value: string): string => const revertCookieString = (value: string): string => replacePipesWithCommas(replaceApostrophesWithQuotes(value)); -const inArray = (items: any[], name: string): boolean => { +const inArray = (items: any[], name: any): boolean => { let i = 0; if (Array.prototype.indexOf) { diff --git a/test/jest/utils.spec.ts b/test/jest/utils.spec.ts index d6d427c9c..f348fe2f0 100644 --- a/test/jest/utils.spec.ts +++ b/test/jest/utils.spec.ts @@ -5,6 +5,7 @@ import { replaceMPID, replaceAmpWithAmpersand, createCookieSyncUrl, + inArray, } from '../../src/utils'; import { deleteAllCookies } from './utils'; @@ -185,6 +186,24 @@ describe('Utils', () => { }); }); + describe('inArray', () => { + it('returns true if the item is in the array', () => { + expect(inArray(['foo', 'bar'], 'foo')).toBe(true); + expect(inArray([1, 2], 2)).toBe(true); + }); + + it('returns false if the item is not in the array', () => { + expect(inArray(['foo', 'bar'], 'baz')).toBe(false); + expect(inArray([1, 2], 3)).toBe(false); + }); + + it('returns false if the array is empty', () => { + expect(inArray([], 'foo')).toBe(false); + expect(inArray([], 1)).toBe(false); + }); + + }); + describe('#replaceMPID', () => { it('replaces the MPID in a string', () => { const mpid = '1234'; diff --git a/test/src/tests-utils.ts b/test/src/tests-utils.ts index 3e224eb42..1ca10fa1b 100644 --- a/test/src/tests-utils.ts +++ b/test/src/tests-utils.ts @@ -6,7 +6,6 @@ import { generateHash, generateUniqueId, getRampNumber, - inArray, isDataPlanSlug, isEmpty, isObject, @@ -228,20 +227,6 @@ describe('Utils', () => { }); }); - describe('#inArray', () => { - it('returns true if element is in the array', ()=> { - const things = ['people', 'places', 'things']; - - expect(inArray(things, 'people')).to.eq(true); - }); - - it('returns false if element is not in the array', ()=> { - const things = ['people', 'places', 'things']; - - expect(inArray(things, 'cats')).to.eq(false); - }); - }); - describe('#findKeyInObject', () => { it('returns the key if it exists in the object', () => { const things = { From 76359af54cfdc6a1e41a60f23169e3912ac49fe0 Mon Sep 17 00:00:00 2001 From: Alexander Sapountzis Date: Tue, 18 Mar 2025 15:19:02 -0400 Subject: [PATCH 3/8] Save Point --- src/apiClient.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/apiClient.ts b/src/apiClient.ts index 319a2a02d..ba35e1b2c 100644 --- a/src/apiClient.ts +++ b/src/apiClient.ts @@ -9,7 +9,7 @@ import { IMParticleUser, ISDKUserAttributes } from './identity-user-interfaces'; import { AsyncUploader, FetchUploader, XHRUploader } from './uploaders'; import { IMParticleWebSDKInstance } from './mp-instance'; import { appendUserInfo } from './user-utils'; -import { IMPForwarder } from './forwarders.interfaces'; +import { ConfiguredKit } from './forwarders.interfaces'; export interface IAPIClient { uploader: BatchUploader | null; @@ -24,7 +24,7 @@ export interface IAPIClient { ) => void; initializeForwarderStatsUploader: () => AsyncUploader; prepareForwardingStats: ( - forwarder: IMPForwarder, + forwarder: ConfiguredKit, event: IUploadObject ) => void; } @@ -193,7 +193,7 @@ export default function APIClient( }; this.prepareForwardingStats = function( - forwarder: IMPForwarder, + forwarder: ConfiguredKit, event:SDKEvent, ) : void { let forwardingStatsData: IForwardingStatsData; From a6ffd291dfc0a7ec83d0ce363bc2e866be25428f Mon Sep 17 00:00:00 2001 From: Alexander Sapountzis Date: Tue, 18 Mar 2025 16:45:21 -0400 Subject: [PATCH 4/8] Save Point --- src/configAPIClient.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/configAPIClient.ts b/src/configAPIClient.ts index 34ec17502..d14487272 100644 --- a/src/configAPIClient.ts +++ b/src/configAPIClient.ts @@ -14,9 +14,8 @@ import { } from './uploaders'; import { IPixelConfiguration } from './cookieSyncManager'; import { IMParticleWebSDKInstance } from './mp-instance'; -import { UserAttributeFilters, UserIdentityFilters } from './forwarders.interfaces'; +import { ForwarderSettings, UserAttributeFilters, UserIdentityFilters } from './forwarders.interfaces'; -// FIXME: Technically this is an overlap of ISDKInitConfig export interface IKitConfigs extends IKitFilterSettings { name: string; suffix?: string; @@ -25,9 +24,7 @@ export interface IKitConfigs extends IKitFilterSettings { isVisible: boolean; isDebugString: BooleanStringLowerCase; hasDebugString: BooleanStringLowerCase; - - // TODO: These settings overlap with ForwarderSettings - settings: Dictionary; + settings: ForwarderSettings; eventSubscriptionId: number; excludeAnonymousUser: boolean; From a695bb81dc54d684ed0fd1c2f5e0d068990187ab Mon Sep 17 00:00:00 2001 From: Alexander Sapountzis Date: Tue, 18 Mar 2025 16:45:41 -0400 Subject: [PATCH 5/8] Save Point --- src/forwarders.interfaces.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/forwarders.interfaces.ts b/src/forwarders.interfaces.ts index 646c763fd..7413d9c0f 100644 --- a/src/forwarders.interfaces.ts +++ b/src/forwarders.interfaces.ts @@ -43,7 +43,7 @@ export interface ConfiguredKit common: Dictionary; id: number; init( - settings: Dictionary, // FIXME: Make this a real type + settings: ForwarderSettings, service: forwardingStatsCallback, testMode: boolean, trackerId: string | null, @@ -107,7 +107,7 @@ export type UserAttributeFilters = number[]; // FIXME: Remove in favor of IKitConfigs.settings // https://go.mparticle.com/work/SQDSDKS-7113 -interface ForwarderSettings { +export interface ForwarderSettings { PriorityValue?: number; } From 52d0b364c6b6f8a40853930aec52c49bbe815ba7 Mon Sep 17 00:00:00 2001 From: Alexander Sapountzis Date: Tue, 18 Mar 2025 16:46:12 -0400 Subject: [PATCH 6/8] Save Point --- src/forwarders.interfaces.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/forwarders.interfaces.ts b/src/forwarders.interfaces.ts index 7413d9c0f..586b4dd5d 100644 --- a/src/forwarders.interfaces.ts +++ b/src/forwarders.interfaces.ts @@ -1,12 +1,22 @@ import { SDKEvent, SDKEventCustomFlags, SDKInitConfig } from './sdkRuntimeModels'; import { Dictionary } from './utils'; -import { IFilteringConsentRuleValues, IFilteringEventAttributeValue, IFilteringUserAttributeValue, IKitConfigs, IKitFilterSettings } from './configAPIClient'; -import { Callback, IdentityApiData, Logger, UserIdentities } from '@mparticle/web-sdk'; +import { + IFilteringConsentRuleValues, + IFilteringEventAttributeValue, + IFilteringUserAttributeValue, + IKitConfigs, + IKitFilterSettings +} from './configAPIClient'; +import { + Callback, + IdentityApiData, + Logger, + UserIdentities +} from '@mparticle/web-sdk'; import { IMParticleUser, ISDKUserAttributes, - ISDKUserIdentity, - UserAttributes, + ISDKUserIdentity } from './identity-user-interfaces'; import { IForwardingStatsData } from './apiClient'; import { IPixelConfiguration } from './cookieSyncManager'; From 34feff4e968c125f5a11db173b29862f13fbff4c Mon Sep 17 00:00:00 2001 From: Alexander Sapountzis Date: Tue, 18 Mar 2025 16:47:33 -0400 Subject: [PATCH 7/8] Save Point --- src/configAPIClient.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/configAPIClient.ts b/src/configAPIClient.ts index d14487272..33752098e 100644 --- a/src/configAPIClient.ts +++ b/src/configAPIClient.ts @@ -5,7 +5,6 @@ import { SDKEventCustomFlags, SDKInitConfig, } from './sdkRuntimeModels'; -import { Dictionary } from './utils'; import { AsyncUploader, IFetchPayload, @@ -14,7 +13,11 @@ import { } from './uploaders'; import { IPixelConfiguration } from './cookieSyncManager'; import { IMParticleWebSDKInstance } from './mp-instance'; -import { ForwarderSettings, UserAttributeFilters, UserIdentityFilters } from './forwarders.interfaces'; +import { + ForwarderSettings, + UserAttributeFilters, + UserIdentityFilters, +} from './forwarders.interfaces'; export interface IKitConfigs extends IKitFilterSettings { name: string; From e449d19d7a6c462b51f9b394170caf0f24350118 Mon Sep 17 00:00:00 2001 From: Alexander Sapountzis Date: Tue, 18 Mar 2025 17:00:55 -0400 Subject: [PATCH 8/8] Save Point --- src/forwarders.ts | 45 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/src/forwarders.ts b/src/forwarders.ts index 68f571c95..b451163d7 100644 --- a/src/forwarders.ts +++ b/src/forwarders.ts @@ -50,40 +50,35 @@ export default function Forwarders(this: IMPForwarder, mpInstance: IMParticleWe }); mpInstance._Store.activeForwarders = configuredForwarders.filter((forwarder: ConfiguredKit) => { - if ( - !isEnabledForUserConsent( - forwarder.filteringConsentRuleValues, - user - ) - ) { + const { SDKConfig, clientId } = mpInstance._Store; + const { + filteringConsentRuleValues, + filteringUserAttributeValue, + excludeAnonymousUser, + userAttributeFilters, + userIdentityFilters, + initialized, + } = forwarder; + + if (!isEnabledForUserConsent(filteringConsentRuleValues, user)) { return false; } - if ( - !self.isEnabledForUserAttributes( - forwarder.filteringUserAttributeValue, - user - ) - ) { + if (!self.isEnabledForUserAttributes(filteringUserAttributeValue, user)) { return false; } - if ( - !self.isEnabledForUnknownUser( - forwarder.excludeAnonymousUser, - user - ) - ) { + if (!self.isEnabledForUnknownUser(excludeAnonymousUser, user)) { return false; } const filteredUserIdentities: ISDKUserIdentity[] = filterUserIdentities( userIdentities, - forwarder.userIdentityFilters + userIdentityFilters ); const filteredUserAttributes: ISDKUserAttributes = filterUserAttributes( user ? user.getAllUserAttributes() : {}, - forwarder.userAttributeFilters + userAttributeFilters ); - if (!forwarder.initialized) { + if (!initialized) { forwarder.logger = mpInstance.Logger; forwarder.init( forwarder.settings, @@ -92,10 +87,10 @@ export default function Forwarders(this: IMPForwarder, mpInstance: IMParticleWe null, filteredUserAttributes, filteredUserIdentities, - mpInstance._Store.SDKConfig.appVersion, - mpInstance._Store.SDKConfig.appName, - mpInstance._Store.SDKConfig.customFlags, - mpInstance._Store.clientId + SDKConfig.appVersion, + SDKConfig.appName, + SDKConfig.customFlags, + clientId ); forwarder.initialized = true; }