@mparticle/web-sdk 2.18.0 → 2.18.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mparticle/web-sdk",
3
- "version": "2.18.0",
3
+ "version": "2.18.2",
4
4
  "description": "mParticle core SDK for web applications",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -101,7 +101,7 @@
101
101
  "karma-chai": "^0.1.0",
102
102
  "karma-chrome-launcher": "^3.1.0",
103
103
  "karma-edge-launcher": "^0.4.1",
104
- "karma-firefox-launcher": "^2.1.0",
104
+ "karma-firefox-launcher": "^2.1.2",
105
105
  "karma-ie-launcher": "^1.0.0",
106
106
  "karma-junit-reporter": "^2.0.1",
107
107
  "karma-mocha": "^2.0.1",
@@ -7,6 +7,7 @@ import {
7
7
  } from './sdkRuntimeModels';
8
8
  import { convertEvents } from './sdkToEventsApiConverter';
9
9
  import Types from './types';
10
+ import { isEmpty } from './utils';
10
11
 
11
12
  export class BatchUploader {
12
13
  //we upload JSON, but this content type is required to avoid a CORS preflight request
@@ -64,8 +65,8 @@ export class BatchUploader {
64
65
  return false;
65
66
  }
66
67
 
67
- queueEvent(event: SDKEvent) {
68
- if (event) {
68
+ queueEvent(event: SDKEvent): void {
69
+ if (!isEmpty(event)) {
69
70
  this.pendingEvents.push(event);
70
71
  this.mpInstance.Logger.verbose(
71
72
  `Queuing event: ${JSON.stringify(event)}`
@@ -131,15 +132,24 @@ export class BatchUploader {
131
132
  eventsBySession.set(sdkEvent.SessionId, events);
132
133
  }
133
134
  for (const entry of Array.from(eventsBySession.entries())) {
134
- let uploadBatchObject = convertEvents(mpid, entry[1], mpInstance);
135
- const onCreateBatchCallback = mpInstance._Store.SDKConfig.onCreateBatch;
135
+ let uploadBatchObject = convertEvents(
136
+ mpid,
137
+ entry[1],
138
+ mpInstance
139
+ );
140
+ const onCreateBatchCallback =
141
+ mpInstance._Store.SDKConfig.onCreateBatch;
136
142
 
137
143
  if (onCreateBatchCallback) {
138
- uploadBatchObject = onCreateBatchCallback(uploadBatchObject);
144
+ uploadBatchObject = onCreateBatchCallback(
145
+ uploadBatchObject
146
+ );
139
147
  if (uploadBatchObject) {
140
148
  uploadBatchObject.modified = true;
141
149
  } else {
142
- mpInstance.Logger.warning('Skiping batch upload because no batch was returned from onCreateBatch callback');
150
+ mpInstance.Logger.warning(
151
+ 'Skiping batch upload because no batch was returned from onCreateBatch callback'
152
+ );
143
153
  }
144
154
  }
145
155
 
@@ -193,13 +203,18 @@ export class BatchUploader {
193
203
 
194
204
  private async upload(
195
205
  logger: SDKLoggerApi,
196
- uploads: Batch[],
206
+ _uploads: Batch[],
197
207
  useBeacon: boolean
198
208
  ): Promise<Batch[]> {
199
209
  let uploader;
200
- if (!uploads || uploads.length < 1) {
210
+
211
+ // Filter out any batches that don't have events
212
+ const uploads = _uploads.filter(upload => !isEmpty(upload.events));
213
+
214
+ if (isEmpty(uploads)) {
201
215
  return null;
202
216
  }
217
+
203
218
  logger.verbose(`Uploading batches: ${JSON.stringify(uploads)}`);
204
219
  logger.verbose(`Batch count: ${uploads.length}`);
205
220
 
@@ -0,0 +1,141 @@
1
+ import { DataPlanConfig } from '@mparticle/web-sdk';
2
+ import {
3
+ BooleanStringLowerCase,
4
+ DataPlanResult,
5
+ MParticleWebSDK,
6
+ SDKEventCustomFlags,
7
+ SDKInitConfig,
8
+ } from './sdkRuntimeModels';
9
+ import { Dictionary } from './utils';
10
+
11
+ export type SDKCompleteInitCallback = (
12
+ apiKey: string,
13
+ config: SDKInitConfig,
14
+ mpInstance: MParticleWebSDK
15
+ ) => void;
16
+
17
+ export interface IKitConfigs {
18
+ name: string;
19
+ moduleId: number;
20
+ isDebug: boolean;
21
+ isVisible: boolean;
22
+ isDebugString: BooleanStringLowerCase;
23
+ hasDebugString: BooleanStringLowerCase;
24
+ settings: Dictionary;
25
+ screenNameFilters: number[];
26
+ screenAttributeFilters: number[];
27
+ userIdentityFilters: number[];
28
+ userAttributeFilters: number[];
29
+ eventNameFilters: number[];
30
+ eventTypeFilters: number[];
31
+ attributeFilters: number[];
32
+ filteringEventAttributeValue: Dictionary;
33
+ filteringConsentRuleValues: Dictionary;
34
+ consentRegulationFilters: number[];
35
+ consentRegulationPurposeFilters: number[];
36
+ messageTypeFilters: number[];
37
+ messageTypeStateFilters: number[];
38
+ eventSubscriptionId: number;
39
+ excludeAnonymousUser: boolean;
40
+ }
41
+
42
+ export interface IPixelConfig {
43
+ name: string;
44
+ moduleId: number;
45
+ esId: number;
46
+ isDebug: boolean;
47
+ isProduction: boolean;
48
+ settings: Dictionary;
49
+ frequencyCap: number;
50
+ pixelUrl: string;
51
+ redirectUrl: string;
52
+ }
53
+
54
+ export interface IConfigResponse {
55
+ appName: string;
56
+ dataPlanResult: DataPlanResult;
57
+ kitConfigs: IKitConfigs[];
58
+ serviceUrl: string;
59
+ secureServiceUrl: string;
60
+ minWebviewBridgeVersion: number;
61
+ workspaceToken: string;
62
+ pixelConfigs: IPixelConfig[];
63
+ flags: SDKEventCustomFlags;
64
+ }
65
+
66
+ export interface IConfigAPIClient {
67
+ getSDKConfiguration: (
68
+ apiKey: string,
69
+ config: SDKInitConfig,
70
+ completeSDKInitialization: SDKCompleteInitCallback,
71
+ mpInstance: MParticleWebSDK
72
+ ) => void;
73
+ }
74
+
75
+ export default function ConfigAPIClient(this: IConfigAPIClient) {
76
+ this.getSDKConfiguration = (
77
+ apiKey,
78
+ config,
79
+ completeSDKInitialization,
80
+ mpInstance
81
+ ): void => {
82
+ let url: string;
83
+ try {
84
+ const xhrCallback = function() {
85
+ if (xhr.readyState === 4) {
86
+ // when a 200 returns, merge current config with what comes back from config, prioritizing user inputted config
87
+ if (xhr.status === 200) {
88
+ config = mpInstance._Helpers.extend(
89
+ {},
90
+ config,
91
+ JSON.parse(xhr.responseText)
92
+ );
93
+ completeSDKInitialization(apiKey, config, mpInstance);
94
+ mpInstance.Logger.verbose(
95
+ 'Successfully received configuration from server'
96
+ );
97
+ } else {
98
+ // if for some reason a 200 doesn't return, then we initialize with the just the passed through config
99
+ completeSDKInitialization(apiKey, config, mpInstance);
100
+ mpInstance.Logger.verbose(
101
+ 'Issue with receiving configuration from server, received HTTP Code of ' +
102
+ xhr.status
103
+ );
104
+ }
105
+ }
106
+ };
107
+
108
+ const xhr = mpInstance._Helpers.createXHR(xhrCallback);
109
+ url =
110
+ 'https://' +
111
+ mpInstance._Store.SDKConfig.configUrl +
112
+ apiKey +
113
+ '/config?env=';
114
+ if (config.isDevelopmentMode) {
115
+ url = url + '1';
116
+ } else {
117
+ url = url + '0';
118
+ }
119
+
120
+ const dataPlan = config.dataPlan as DataPlanConfig;
121
+ if (dataPlan) {
122
+ if (dataPlan.planId) {
123
+ url = url + '&plan_id=' + dataPlan.planId || '';
124
+ }
125
+ if (dataPlan.planVersion) {
126
+ url = url + '&plan_version=' + dataPlan.planVersion || '';
127
+ }
128
+ }
129
+
130
+ if (xhr) {
131
+ xhr.open('get', url);
132
+ xhr.send(null);
133
+ }
134
+ } catch (e) {
135
+ completeSDKInitialization(apiKey, config, mpInstance);
136
+ mpInstance.Logger.error(
137
+ 'Error getting forwarder configuration from mParticle servers.'
138
+ );
139
+ }
140
+ };
141
+ }
@@ -4,6 +4,10 @@ import ServerModel from './serverModel';
4
4
  import { SDKEvent, BaseEvent, MParticleWebSDK } from './sdkRuntimeModels';
5
5
  import { convertEvents } from './sdkToEventsApiConverter';
6
6
  import * as EventsApi from '@mparticle/event-models';
7
+
8
+ const mockFunction = function () {
9
+ return null;
10
+ }
7
11
  export default class _BatchValidator {
8
12
  private getMPInstance() {
9
13
  return {
@@ -15,23 +19,95 @@ export default class _BatchValidator {
15
19
  return 'mockId';
16
20
  },
17
21
  extend: window.mParticle.getInstance()._Helpers.extend,
22
+ createServiceUrl: mockFunction,
23
+ parseNumber: mockFunction,
24
+ isObject: mockFunction,
25
+ returnConvertedBoolean: mockFunction,
26
+ Validators: null,
18
27
  },
28
+ _resetForTests: mockFunction,
29
+ _APIClient: null,
30
+ _Consent: null,
31
+ _ServerModel: null,
32
+ _SessionManager: null,
19
33
  _Store: {
20
34
  sessionId: 'mockSessionId',
21
- SDKConfig: {},
22
- },
23
- Identity: {
24
- getCurrentUser: function() {
25
- return null;
35
+ devToken: 'test_dev_token',
36
+ isFirstRun: true,
37
+ isEnabled: true,
38
+ sessionAttributes: {},
39
+ currentSessionMPIDs: [],
40
+ consentState: null,
41
+ clientId: null,
42
+ deviceId: null,
43
+ migrationData: {},
44
+ serverSettings: {},
45
+ dateLastEventSent: null,
46
+ sessionStartDate: null,
47
+ currentPosition: null,
48
+ isTracking: false,
49
+ watchPositionId: null,
50
+ cartProducts: [],
51
+ eventQueue: [],
52
+ currencyCode: null,
53
+ globalTimer: null,
54
+ context: null,
55
+ configurationLoaded: false,
56
+ identityCallInFlight: false,
57
+ migratingToIDSyncCookies: false,
58
+ nonCurrentUserMPIDs: {},
59
+ identifyCalled: false,
60
+ isLoggedIn: false,
61
+ cookieSyncDates: {},
62
+ integrationAttributes: {},
63
+ requireDelay: true,
64
+ isLocalStorageAvailable: null,
65
+ integrationDelayTimeoutStart: null,
66
+ storageName: null,
67
+ prodStorageName: null,
68
+ activeForwarders: [],
69
+ kits: {},
70
+ configuredForwarders: [],
71
+ pixelConfigurations: [],
72
+ wrapperSDKInfo: {
73
+ name: 'none',
74
+ version: null,
75
+ isInfoSet: false,
76
+ },
77
+ SDKConfig: {
78
+ isDevelopmentMode: false,
79
+ onCreateBatch: mockFunction,
26
80
  },
27
81
  },
28
- getAppVersion: function() {
29
- return null;
82
+ config: null,
83
+ eCommerce: null,
84
+ Identity: {
85
+ getCurrentUser: mockFunction,
86
+ IdentityAPI: {},
87
+ identify: mockFunction,
88
+ login: mockFunction,
89
+ logout: mockFunction,
90
+ modify: mockFunction,
30
91
  },
31
- getAppName: function() {
32
- return null;
92
+ Logger: {
93
+ verbose: mockFunction,
94
+ error: mockFunction,
95
+ warning: mockFunction,
33
96
  },
34
- };
97
+ ProductActionType: null,
98
+ ServerModel: null,
99
+ addForwarder: mockFunction,
100
+ generateHash: mockFunction,
101
+ getAppVersion: mockFunction,
102
+ getAppName: mockFunction,
103
+ getInstance: mockFunction,
104
+ init: mockFunction,
105
+ logBaseEvent: mockFunction,
106
+ logEvent: mockFunction,
107
+ logLevel: 'none',
108
+ setPosition: mockFunction,
109
+ upload: mockFunction,
110
+ } as MParticleWebSDK;
35
111
  }
36
112
 
37
113
  returnBatch(event: BaseEvent) {
@@ -1261,6 +1261,26 @@ export default function mParticleInstance(instanceName) {
1261
1261
  self._APIClient.processQueuedEvents();
1262
1262
  }
1263
1263
  };
1264
+
1265
+ // Internal use only. Used by our wrapper SDKs to identify themselves during initialization.
1266
+ this._setWrapperSDKInfo = function(name, version) {
1267
+ var queued = queueIfNotInitialized(function() {
1268
+ self._setWrapperSDKInfo(name, version);
1269
+ }, self);
1270
+
1271
+ if (queued) return;
1272
+
1273
+ if (
1274
+ self._Store.wrapperSDKInfo === undefined ||
1275
+ !self._Store.wrapperSDKInfo.isInfoSet
1276
+ ) {
1277
+ self._Store.wrapperSDKInfo = {
1278
+ name: name,
1279
+ version: version,
1280
+ isInfoSet: true,
1281
+ };
1282
+ }
1283
+ };
1264
1284
  }
1265
1285
 
1266
1286
  // Some (server) config settings need to be returned before they are set on SDKConfig in a self hosted environment
@@ -472,6 +472,9 @@ function mParticle() {
472
472
  this._getActiveForwarders = function() {
473
473
  return self.getInstance()._getActiveForwarders();
474
474
  };
475
+ this._setWrapperSDKInfo = function(name, version) {
476
+ self.getInstance()._setWrapperSDKInfo(name, version);
477
+ };
475
478
  }
476
479
 
477
480
  var mparticleInstance = new mParticle();
@@ -1,9 +1,15 @@
1
- import { DataPlanVersion } from '@mparticle/data-planning-models';
1
+ import * as EventsApi from '@mparticle/event-models';
2
2
  import { Batch } from '@mparticle/event-models';
3
- import { MPConfiguration, SDKEventCustomFlags } from '@mparticle/web-sdk';
4
- import { SDKConfig } from './store';
5
- import { Dictionary } from './utils';
3
+ import { DataPlanVersion, DataPlan } from '@mparticle/data-planning-models';
4
+ import { MPConfiguration, IdentityApiData } from '@mparticle/web-sdk';
5
+ import { IStore, SDKConfig } from './store';
6
6
  import Validators from './validators';
7
+ import { Dictionary } from './utils';
8
+ import { IServerModel } from './serverModel';
9
+ import { IKitConfigs } from './configAPIClient';
10
+
11
+ // TODO: Resolve this with version in @mparticle/web-sdk
12
+ export type SDKEventCustomFlags = Dictionary<any>;
7
13
 
8
14
  export interface SDKEvent {
9
15
  DeviceId: string;
@@ -25,7 +31,7 @@ export interface SDKEvent {
25
31
  Debug: boolean;
26
32
  Location?: SDKGeoLocation;
27
33
  OptOut?: boolean;
28
- CustomFlags?: { [key: string]: string };
34
+ CustomFlags?: SDKEventCustomFlags;
29
35
  AppVersion?: string;
30
36
  AppName?: string;
31
37
  Package?: string;
@@ -123,12 +129,18 @@ export interface MParticleWebSDK {
123
129
  addForwarder(mockForwarder: MPForwarder): void;
124
130
  Identity: SDKIdentityApi;
125
131
  Logger: SDKLoggerApi;
126
- _Store: SDKStoreApi;
132
+ _APIClient: any; // TODO: Set up API Client
133
+ _Store: IStore;
127
134
  _Helpers: SDKHelpersApi;
128
135
  config: SDKInitConfig;
129
- _resetForTests(MPConfig: SDKConfig): void;
136
+ _ServerModel: IServerModel;
137
+ _SessionManager: any; // TODO: Set up Session Manager
138
+ _Consent: any; // TODO: Set up Consent SDK
139
+ _resetForTests(MPConfig?: SDKConfig): void;
130
140
  init(apiKey: string, config: SDKInitConfig, instanceName?: string): void;
131
- getInstance();
141
+ getAppName(): string;
142
+ getAppVersion(): string;
143
+ getInstance(): MParticleWebSDK; // TODO: Create a new type for MParticleWebSDKInstance
132
144
  ServerModel();
133
145
  upload();
134
146
  setPosition(lat: number | string, lng: number | string): void;
@@ -146,10 +158,13 @@ export interface MParticleWebSDK {
146
158
  isIOS?: boolean;
147
159
  }
148
160
 
161
+ // Used in cases where server requires booleans as strings
162
+ export type BooleanStringLowerCase = 'false' | 'true';
163
+ export type BooleanStringTitleCase = 'False' | 'True';
164
+
149
165
  export type LogLevelType = 'none' | 'verbose' | 'warning' | 'error';
150
166
 
151
167
  // TODO: Create true types for Kits and Kit Configs
152
- export type KitConfigs = Dictionary;
153
168
  export type Kit = Dictionary;
154
169
  export type MPForwarder = Dictionary;
155
170
 
@@ -164,7 +179,7 @@ export interface SDKInitConfig
164
179
  dataPlan?: DataPlanConfig | KitBlockerDataPlan; // TODO: These should be eventually split into two different attributes
165
180
  logLevel?: LogLevelType;
166
181
 
167
- kitConfigs?: KitConfigs[];
182
+ kitConfigs?: IKitConfigs[];
168
183
  kits?: Dictionary<Kit>;
169
184
  dataPlanOptions?: KitBlockerOptions;
170
185
  flags?: Dictionary;
@@ -204,10 +219,16 @@ export interface SDKIdentityApi {
204
219
 
205
220
  export interface SDKHelpersApi {
206
221
  createServiceUrl(arg0: string, arg1: string): void;
207
- parseNumber(value: number);
222
+ createXHR?(cb: () => void): XMLHttpRequest;
223
+ extend(...args: any[]);
224
+ parseNumber(value: string | number): number;
208
225
  generateUniqueId();
209
226
  isObject(item: any);
210
227
  returnConvertedBoolean(data: string | boolean | number): boolean;
228
+ sanitizeAttributes(
229
+ attrs: Dictionary<string>,
230
+ name: string
231
+ ): Dictionary<string> | null;
211
232
  Validators: typeof Validators;
212
233
  }
213
234
 
@@ -217,7 +238,9 @@ export interface SDKLoggerApi {
217
238
  warning(arg0: string): void;
218
239
  }
219
240
 
241
+ // TODO: Merge this with IStore in store.ts
220
242
  export interface SDKStoreApi {
243
+ isEnabled: boolean;
221
244
  isFirstRun: boolean;
222
245
  devToken: string;
223
246
  SDKConfig: SDKConfigApi;
@@ -229,10 +252,13 @@ export interface SDKConfigApi {
229
252
  v3SecureServiceUrl?: string;
230
253
  isDevelopmentMode: boolean;
231
254
  appVersion?: string;
232
- onCreateBatch(batch: Batch): Batch;
255
+ onCreateBatch(batch: EventsApi.Batch): EventsApi.Batch;
233
256
  }
234
257
  export interface MParticleUser {
235
258
  getMPID(): string;
259
+ getConsentState(): any; // FIXME:
260
+ getAllUserAttributes(): any; // FIXME;
261
+ getUserIdentities(): IdentityApiData; // FIXME: Is this correct?
236
262
  }
237
263
 
238
264
  export interface SDKConsentState {
@@ -280,6 +306,10 @@ export interface BaseEvent {
280
306
  eventType?: number;
281
307
  data?: { [key: string]: string };
282
308
  customFlags?: { [key: string]: string };
309
+ toEventAPIObject?(): SDKEvent;
310
+ sourceMessageId?: string;
311
+ userAttributeChanges?: SDKUserAttributeChangeData;
312
+ userIdentityChanges?: SDKUserIdentityChangeData;
283
313
  }
284
314
 
285
315
  export interface KitBlockerOptions {