@mparticle/web-sdk 2.21.2 → 2.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/consent.ts CHANGED
@@ -6,9 +6,10 @@ import {
6
6
  } from '@mparticle/web-sdk';
7
7
  import { MParticleUser, MParticleWebSDK } from './sdkRuntimeModels';
8
8
  import { Dictionary, isObject } from './utils';
9
+ import KitFilterHelper from './kitFilterHelper';
10
+ import Constants from './constants';
9
11
 
10
- // Specifies to compiler that CCPAPurpose can only be one specific value
11
- export const CCPAPurpose = 'data_sale_opt_out' as const;
12
+ const { CCPAPurpose } = Constants;
12
13
 
13
14
  export interface IMinifiedConsentJSONObject {
14
15
  gdpr?: Dictionary<IPrivacyV2DTO>;
@@ -144,15 +145,13 @@ export default function Consent(this: IConsent, mpInstance: MParticleWebSDK) {
144
145
  // GDPR - '1' + purpose name
145
146
  // CCPA - '2data_sale_opt_out' (there is only 1 purpose of data_sale_opt_out for CCPA)
146
147
  const GDPRConsentHashPrefix = '1';
147
- const CCPAHashString = '2' + CCPAPurpose;
148
+ const CCPAHashPrefix = '2';
148
149
 
149
150
  const gdprConsentState = consentState.getGDPRConsentState();
150
151
  if (gdprConsentState) {
151
152
  for (const purpose in gdprConsentState) {
152
153
  if (gdprConsentState.hasOwnProperty(purpose)) {
153
- purposeHash = mpInstance._Helpers
154
- .generateHash(GDPRConsentHashPrefix + purpose)
155
- .toString();
154
+ purposeHash = KitFilterHelper.hashConsentPurposeConditionalForwarding(GDPRConsentHashPrefix, purpose);
156
155
  purposeHashes[purposeHash] =
157
156
  gdprConsentState[purpose].Consented;
158
157
  }
@@ -160,9 +159,7 @@ export default function Consent(this: IConsent, mpInstance: MParticleWebSDK) {
160
159
  }
161
160
  const CCPAConsentState = consentState.getCCPAConsentState();
162
161
  if (CCPAConsentState) {
163
- purposeHash = mpInstance._Helpers
164
- .generateHash(CCPAHashString)
165
- .toString();
162
+ purposeHash = KitFilterHelper.hashConsentPurposeConditionalForwarding(CCPAHashPrefix, CCPAPurpose);
166
163
  purposeHashes[purposeHash] = CCPAConsentState.Consented;
167
164
  }
168
165
  }
package/src/constants.ts CHANGED
@@ -163,6 +163,7 @@ const Constants = {
163
163
  OfflineStorage: 'offlineStorage',
164
164
  },
165
165
  DefaultInstance: 'default_instance',
166
+ CCPAPurpose: 'data_sale_opt_out'
166
167
  } as const;
167
168
 
168
169
  export default Constants;
package/src/forwarders.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import Types from './types';
2
2
  import filteredMparticleUser from './filteredMparticleUser';
3
3
  import { isEmpty } from './utils';
4
+ import KitFilterHelper from './kitFilterHelper';
4
5
 
5
6
  export default function Forwarders(mpInstance, kitBlocker) {
6
7
  var self = this;
@@ -110,12 +111,12 @@ export default function Forwarders(mpInstance, kitBlocker) {
110
111
  ) {
111
112
  for (var attrName in userAttributes) {
112
113
  if (userAttributes.hasOwnProperty(attrName)) {
113
- attrHash = mpInstance._Helpers
114
- .generateHash(attrName)
115
- .toString();
116
- valueHash = mpInstance._Helpers
117
- .generateHash(userAttributes[attrName])
118
- .toString();
114
+ attrHash = KitFilterHelper.hashAttributeConditionalForwarding(
115
+ attrName
116
+ );
117
+ valueHash = KitFilterHelper.hashAttributeConditionalForwarding(
118
+ userAttributes[attrName]
119
+ );
119
120
 
120
121
  if (
121
122
  attrHash === filterObject.userAttributeName &&
@@ -177,7 +178,9 @@ export default function Forwarders(mpInstance, kitBlocker) {
177
178
  if (
178
179
  mpInstance._Helpers.inArray(
179
180
  filterList,
180
- userIdentity.Type
181
+ KitFilterHelper.hashUserIdentity(
182
+ userIdentity.Type
183
+ )
181
184
  )
182
185
  ) {
183
186
  event.UserIdentities.splice(i, 1);
@@ -198,8 +201,10 @@ export default function Forwarders(mpInstance, kitBlocker) {
198
201
 
199
202
  for (var attrName in event.EventAttributes) {
200
203
  if (event.EventAttributes.hasOwnProperty(attrName)) {
201
- hash = mpInstance._Helpers.generateHash(
202
- event.EventCategory + event.EventName + attrName
204
+ hash = KitFilterHelper.hashEventAttributeKey(
205
+ event.EventCategory,
206
+ event.EventName,
207
+ attrName
203
208
  );
204
209
 
205
210
  if (mpInstance._Helpers.inArray(filterList, hash)) {
@@ -227,10 +232,11 @@ export default function Forwarders(mpInstance, kitBlocker) {
227
232
  !mpInstance._Store.webviewBridgeEnabled &&
228
233
  mpInstance._Store.activeForwarders
229
234
  ) {
230
- hashedEventName = mpInstance._Helpers.generateHash(
231
- event.EventCategory + event.EventName
235
+ hashedEventName = KitFilterHelper.hashEventName(
236
+ event.EventName,
237
+ event.EventCategory
232
238
  );
233
- hashedEventType = mpInstance._Helpers.generateHash(
239
+ hashedEventType = KitFilterHelper.hashEventType(
234
240
  event.EventCategory
235
241
  );
236
242
 
@@ -261,9 +267,9 @@ export default function Forwarders(mpInstance, kitBlocker) {
261
267
  if (event.EventAttributes) {
262
268
  for (var prop in event.EventAttributes) {
263
269
  var hashedEventAttributeName;
264
- hashedEventAttributeName = mpInstance._Helpers
265
- .generateHash(prop)
266
- .toString();
270
+ hashedEventAttributeName = KitFilterHelper.hashAttributeConditionalForwarding(
271
+ prop
272
+ );
267
273
 
268
274
  if (
269
275
  hashedEventAttributeName ===
@@ -273,11 +279,9 @@ export default function Forwarders(mpInstance, kitBlocker) {
273
279
  ) {
274
280
  foundProp = {
275
281
  name: hashedEventAttributeName,
276
- value: mpInstance._Helpers
277
- .generateHash(
278
- event.EventAttributes[prop]
279
- )
280
- .toString(),
282
+ value: KitFilterHelper.hashAttributeConditionalForwarding(
283
+ event.EventAttributes[prop]
284
+ ),
281
285
  };
282
286
  }
283
287
 
@@ -620,7 +624,14 @@ export default function Forwarders(mpInstance, kitBlocker) {
620
624
  // which is typed { kits: Dictionary<constructor> }.
621
625
  // The constructors are keyed by the name of the kit.
622
626
  config.sideloadedKits.forEach(function(sideloadedKit) {
623
- sideloadedKit.register(sideloadedKits);
627
+ try {
628
+ sideloadedKit.kitInstance.register(sideloadedKits);
629
+ } catch (e) {
630
+ console.error(
631
+ 'Error registering sideloaded kit ' +
632
+ sideloadedKit.kitInstance.name
633
+ );
634
+ }
624
635
  });
625
636
 
626
637
  // Then configure each kit
package/src/helpers.js CHANGED
@@ -2,6 +2,7 @@ import Types from './types';
2
2
  import Constants from './constants';
3
3
  import * as utils from './utils';
4
4
  import Validators from './validators';
5
+ import KitFilterHelper from './kitFilterHelper';
5
6
 
6
7
  var StorageNames = Constants.StorageNames;
7
8
 
@@ -306,13 +307,13 @@ export default function Helpers(mpInstance) {
306
307
  userIdentitiesObject,
307
308
  filterList
308
309
  ) {
309
- var filteredUserIdentities = {};
310
+ const filteredUserIdentities = {};
310
311
 
311
312
  if (userIdentitiesObject && Object.keys(userIdentitiesObject).length) {
312
- for (var userIdentityName in userIdentitiesObject) {
313
+ for (const userIdentityName in userIdentitiesObject) {
313
314
  if (userIdentitiesObject.hasOwnProperty(userIdentityName)) {
314
- var userIdentityType = Types.IdentityType.getIdentityType(
315
- userIdentityName
315
+ const userIdentityType = KitFilterHelper.hashUserIdentity(
316
+ Types.IdentityType.getIdentityType(userIdentityName)
316
317
  );
317
318
  if (!self.inArray(filterList, userIdentityType)) {
318
319
  filteredUserIdentities[userIdentityName] =
@@ -331,7 +332,9 @@ export default function Helpers(mpInstance) {
331
332
  if (userAttributes && Object.keys(userAttributes).length) {
332
333
  for (var userAttribute in userAttributes) {
333
334
  if (userAttributes.hasOwnProperty(userAttribute)) {
334
- var hashedUserAttribute = self.generateHash(userAttribute);
335
+ const hashedUserAttribute = KitFilterHelper.hashUserAttribute(
336
+ userAttribute
337
+ );
335
338
  if (!self.inArray(filterList, hashedUserAttribute)) {
336
339
  filteredUserAttributes[userAttribute] =
337
340
  userAttributes[userAttribute];
@@ -344,7 +347,9 @@ export default function Helpers(mpInstance) {
344
347
  };
345
348
 
346
349
  this.isFilteredUserAttribute = function(userAttributeKey, filterList) {
347
- const hashedUserAttribute = self.generateHash(userAttributeKey);
350
+ const hashedUserAttribute = KitFilterHelper.hashUserAttribute(
351
+ userAttributeKey
352
+ );
348
353
  return filterList && self.inArray(filterList, hashedUserAttribute);
349
354
  };
350
355
 
@@ -0,0 +1,47 @@
1
+ import { generateHash } from "./utils";
2
+ // TODO: https://mparticle-eng.atlassian.net/browse/SQDSDKS-5381
3
+ import { EventTypeEnum, IdentityType } from "./types.interfaces";
4
+ import Constants from './constants';
5
+
6
+ export default class KitFilterHelper {
7
+ static hashEventType(eventType: EventTypeEnum): number {
8
+ return generateHash(eventType as unknown as string);
9
+ };
10
+
11
+ static hashEventName(eventName: string, eventType: EventTypeEnum): number {
12
+ return generateHash(eventType + eventName);
13
+ };
14
+
15
+ static hashEventAttributeKey(eventType: EventTypeEnum, eventName: string, customAttributeName: string): number {
16
+ return generateHash(eventType + eventName + customAttributeName);
17
+ }
18
+
19
+ static hashUserAttribute(userAttributeKey: string): number {
20
+ return generateHash(userAttributeKey);
21
+ }
22
+
23
+ // User Identities are not actually hashed, this method is named this way to
24
+ // be consistent with the filter class. UserIdentityType is also a number
25
+ static hashUserIdentity(userIdentity: IdentityType): IdentityType {
26
+ return userIdentity;
27
+ }
28
+
29
+ static hashConsentPurpose(prefix: string, purpose: string){
30
+ return generateHash(prefix + purpose)
31
+
32
+ }
33
+
34
+ // The methods below are for conditional forwarding, a type of filter
35
+ // hashAttributeCondiitonalForwarding is used for both User and Event
36
+ // attribute keys and attribute values
37
+ // The backend returns the hashes as strings for conditional forwarding
38
+ // but returns "regular" filters as arrays of numbers
39
+ // See IFilteringEventAttributeValue in configApiClient.ts as an example
40
+ static hashAttributeConditionalForwarding(attribute: string): string {
41
+ return generateHash(attribute).toString();
42
+ }
43
+
44
+ static hashConsentPurposeConditionalForwarding(prefix: string, purpose: string): string {
45
+ return this.hashConsentPurpose(prefix, purpose).toString();
46
+ }
47
+ }
@@ -5,6 +5,7 @@ import { SDKEvent, BaseEvent, MParticleWebSDK } from './sdkRuntimeModels';
5
5
  import { convertEvents } from './sdkToEventsApiConverter';
6
6
  import * as EventsApi from '@mparticle/event-models';
7
7
  import { Batch } from '@mparticle/event-models';
8
+ import { IMPSideloadedKit} from './sideloadedKit';
8
9
 
9
10
  const mockFunction = function() {
10
11
  return null;
@@ -31,6 +32,7 @@ export default class _BatchValidator {
31
32
  },
32
33
  _resetForTests: mockFunction,
33
34
  _APIClient: null,
35
+ MPSideloadedKit: null,
34
36
  _Consent: null,
35
37
  _Forwarders: null,
36
38
  _NativeSdkHelpers: null,
@@ -3,6 +3,7 @@ import Types from './types';
3
3
  import Constants from './constants';
4
4
  import mParticleInstance from './mp-instance.js';
5
5
  import _BatchValidator from './mockBatchCreator';
6
+ import MPSideloadedKit from './sideloadedKit';
6
7
 
7
8
  if (!Array.prototype.forEach) {
8
9
  Array.prototype.forEach = Polyfill.forEach;
@@ -30,6 +31,8 @@ function mParticle() {
30
31
  this.CommerceEventType = Types.CommerceEventType;
31
32
  this.PromotionType = Types.PromotionActionType;
32
33
  this.ProductActionType = Types.ProductActionType;
34
+ this.MPSideloadedKit = MPSideloadedKit;
35
+
33
36
  if (typeof window !== 'undefined') {
34
37
  this.isIOS =
35
38
  window.mParticle && window.mParticle.isIOS
@@ -8,7 +8,7 @@ import { IServerModel } from './serverModel';
8
8
  import { IKitConfigs } from './configAPIClient';
9
9
  import { SDKConsentApi, SDKConsentState } from './consent';
10
10
  import { IPersistence } from './persistence.interfaces';
11
-
11
+ import { IMPSideloadedKit } from './sideloadedKit';
12
12
  // TODO: Resolve this with version in @mparticle/web-sdk
13
13
  export type SDKEventCustomFlags = Dictionary<any>;
14
14
 
@@ -130,6 +130,7 @@ export interface MParticleWebSDK {
130
130
  addForwarder(mockForwarder: MPForwarder): void;
131
131
  Identity: SDKIdentityApi;
132
132
  Logger: SDKLoggerApi;
133
+ MPSideloadedKit: IMPSideloadedKit;
133
134
  _APIClient: any; // TODO: Set up API Client
134
135
  _Store: IStore;
135
136
  _Forwarders: any;
@@ -0,0 +1,124 @@
1
+ import KitFilterHelper from './kitFilterHelper';
2
+ import {
3
+ IFilteringConsentRuleValues,
4
+ IFilteringEventAttributeValue,
5
+ IFilteringUserAttributeValue,
6
+ IKitFilterSettings,
7
+ } from './configAPIClient';
8
+ import { UnregisteredKit } from './forwarders.interfaces';
9
+ import { EventTypeEnum, IdentityType } from './types.interfaces';
10
+
11
+ export interface IMPSideloadedKit {
12
+ kitInstance: UnregisteredKit;
13
+ filterDictionary: IKitFilterSettings;
14
+
15
+ addEventTypeFilter(eventType: EventTypeEnum): void;
16
+ addEventNameFilter(eventType: EventTypeEnum, eventName: string): void;
17
+ addEventAttributeFilter(
18
+ eventType: EventTypeEnum,
19
+ eventName: string,
20
+ customAttributeKey: string
21
+ ): void;
22
+ addScreenNameFilter(screenName: string): void;
23
+ addScreenAttributeFilter(screenName: string, screenAttribute: string): void;
24
+ addUserIdentityFilter(userIdentity: IdentityType): void;
25
+ addUserAttributeFilter(userAttributeKey: string): void;
26
+ }
27
+
28
+ // This constructor is necessary to be able ot call new on mParticle.SideloadedKit
29
+ // https://stackoverflow.com/questions/13407036/how-does-interfaces-with-construct-signatures-work
30
+ export interface IMPSideloadedKitConstructor {
31
+ new(unregisteredKitInstance: UnregisteredKit): IMPSideloadedKit;
32
+ }
33
+
34
+ export default class MPSideloadedKit implements IMPSideloadedKit{
35
+ public kitInstance: UnregisteredKit;
36
+ public filterDictionary: IKitFilterSettings = {
37
+ eventTypeFilters: [],
38
+ eventNameFilters: [],
39
+ screenNameFilters: [],
40
+ screenAttributeFilters: [],
41
+ userIdentityFilters: [],
42
+ userAttributeFilters: [],
43
+ attributeFilters: [],
44
+ consentRegulationFilters: [],
45
+ consentRegulationPurposeFilters: [],
46
+ messageTypeFilters: [],
47
+ messageTypeStateFilters: [],
48
+
49
+ // The below filtering members are optional, but we instantiate them
50
+ // to simplify public method assignment
51
+ filteringEventAttributeValue: {} as IFilteringEventAttributeValue,
52
+ filteringUserAttributeValue: {} as IFilteringUserAttributeValue,
53
+ filteringConsentRuleValues: {} as IFilteringConsentRuleValues,
54
+ };
55
+
56
+ constructor(unregisteredKitInstance: UnregisteredKit) {
57
+ this.kitInstance = unregisteredKitInstance;
58
+ }
59
+
60
+ public addEventTypeFilter(eventType: EventTypeEnum): void {
61
+ const hashedEventType = KitFilterHelper.hashEventType(eventType);
62
+ this.filterDictionary.eventTypeFilters.push(hashedEventType);
63
+ }
64
+
65
+ public addEventNameFilter(
66
+ eventType: EventTypeEnum,
67
+ eventName: string
68
+ ): void {
69
+ const hashedEventName = KitFilterHelper.hashEventName(
70
+ eventName,
71
+ eventType
72
+ );
73
+ this.filterDictionary.eventNameFilters.push(hashedEventName);
74
+ }
75
+
76
+ public addEventAttributeFilter(
77
+ eventType: EventTypeEnum,
78
+ eventName: string,
79
+ customAttributeKey: string
80
+ ): void {
81
+ const hashedEventAttribute = KitFilterHelper.hashEventAttributeKey(
82
+ eventType,
83
+ eventName,
84
+ customAttributeKey
85
+ );
86
+ this.filterDictionary.attributeFilters.push(hashedEventAttribute);
87
+ }
88
+
89
+ public addScreenNameFilter(screenName: string): void {
90
+ const hashedScreenName = KitFilterHelper.hashEventName(
91
+ screenName,
92
+ EventTypeEnum.Unknown
93
+ );
94
+ this.filterDictionary.screenNameFilters.push(hashedScreenName);
95
+ }
96
+
97
+ public addScreenAttributeFilter(
98
+ screenName: string,
99
+ screenAttribute: string
100
+ ): void {
101
+ const hashedScreenAttribute = KitFilterHelper.hashEventAttributeKey(
102
+ EventTypeEnum.Unknown,
103
+ screenName,
104
+ screenAttribute
105
+ );
106
+ this.filterDictionary.screenAttributeFilters.push(
107
+ hashedScreenAttribute
108
+ );
109
+ }
110
+
111
+ public addUserIdentityFilter(userIdentity: IdentityType): void {
112
+ const hashedIdentityType = KitFilterHelper.hashUserIdentity(
113
+ userIdentity
114
+ );
115
+ this.filterDictionary.userIdentityFilters.push(hashedIdentityType);
116
+ }
117
+
118
+ public addUserAttributeFilter(userAttributeKey: string): void {
119
+ const hashedUserAttributeKey = KitFilterHelper.hashUserAttribute(
120
+ userAttributeKey
121
+ );
122
+ this.filterDictionary.userAttributeFilters.push(hashedUserAttributeKey);
123
+ }
124
+ }
@@ -0,0 +1,52 @@
1
+ export enum EventTypeEnum {
2
+ Unknown,
3
+ Navigation,
4
+ Location,
5
+ Search,
6
+ Transaction,
7
+ UserContent,
8
+ UserPreference,
9
+ Social,
10
+ Other,
11
+ Media,
12
+ }
13
+
14
+ // TODO: https://mparticle-eng.atlassian.net/browse/SQDSDKS-5403
15
+ export enum MessageType {
16
+ SessionStart = 1,
17
+ SessionEnd = 2,
18
+ PageView = 3,
19
+ PageEvent = 4,
20
+ CrashReport = 5,
21
+ OptOut = 6,
22
+ AppStateTransition = 10,
23
+ Profile = 14,
24
+ Commerce = 16,
25
+ UserAttributeChange = 17,
26
+ UserIdentityChange = 18,
27
+ Media = 20,
28
+ };
29
+
30
+ export enum IdentityType {
31
+ Other = 0,
32
+ CustomerId = 1,
33
+ Facebook = 2,
34
+ Twitter = 3,
35
+ Google = 4,
36
+ Microsoft = 5,
37
+ Yahoo = 6,
38
+ Email = 7,
39
+ FacebookCustomAudienceId = 9,
40
+ Other2 = 10,
41
+ Other3 = 11,
42
+ Other4 = 12,
43
+ Other5 = 13,
44
+ Other6 = 14,
45
+ Other7 = 15,
46
+ Other8 = 16,
47
+ Other9 = 17,
48
+ Other10 = 18,
49
+ MobileNumber = 19,
50
+ PhoneNumber2 = 20,
51
+ PhoneNumber3 = 21,
52
+ }