@mparticle/web-sdk 2.17.4 → 2.18.1
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/dist/mparticle.common.js +63 -26
- package/dist/mparticle.esm.js +63 -26
- package/dist/mparticle.js +399 -240
- package/package.json +2 -2
- package/src/batchUploader.ts +23 -8
- package/src/helpers.js +1 -8
- package/src/mockBatchCreator.ts +80 -9
- package/src/mp-instance.js +55 -2
- package/src/mparticle-instance-manager.js +3 -0
- package/src/sdkRuntimeModels.ts +34 -11
- package/src/{serverModel.js → serverModel.ts} +260 -75
- package/src/store.ts +4 -2
- package/src/stub/mparticle.stub.js +1 -0
- package/src/types.js +6 -0
- package/src/utils.ts +16 -1
- package/src/validators.ts +4 -2
|
@@ -1,47 +1,230 @@
|
|
|
1
|
+
// TODO: This file is no longer the server model because the web SDK payload
|
|
2
|
+
// is now the server-to-server model. We should rename this to
|
|
3
|
+
// something more appropriate.
|
|
4
|
+
|
|
1
5
|
import Types from './types';
|
|
2
6
|
import Constants from './constants';
|
|
7
|
+
import {
|
|
8
|
+
BaseEvent,
|
|
9
|
+
MParticleUser,
|
|
10
|
+
MParticleWebSDK,
|
|
11
|
+
SDKConsentState,
|
|
12
|
+
SDKEvent,
|
|
13
|
+
SDKGeoLocation,
|
|
14
|
+
SDKProduct,
|
|
15
|
+
SDKUserIdentity,
|
|
16
|
+
} from './sdkRuntimeModels';
|
|
17
|
+
import { parseNumber, parseStringOrNumber, Dictionary } from './utils';
|
|
18
|
+
import { ServerSettings } from './store';
|
|
19
|
+
import { MPID } from '@mparticle/web-sdk';
|
|
20
|
+
|
|
21
|
+
const MessageType = Types.MessageType;
|
|
22
|
+
const ApplicationTransitionType = Types.ApplicationTransitionType;
|
|
23
|
+
|
|
24
|
+
// TODO: Move to Consent Module
|
|
25
|
+
export interface IPrivacyV2DTO {
|
|
26
|
+
c: boolean; // Consented
|
|
27
|
+
ts: number; // Timestamp
|
|
28
|
+
d: string; // Document
|
|
29
|
+
l: string; // Location
|
|
30
|
+
h: string; // HardwareID
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// TODO: Move to Consent Module
|
|
34
|
+
export interface IGDPRConsentStateDTO {
|
|
35
|
+
[key: string]: IPrivacyV2DTO;
|
|
36
|
+
}
|
|
3
37
|
|
|
4
|
-
|
|
5
|
-
|
|
38
|
+
// TODO: Move to Consent Module
|
|
39
|
+
export interface ICCPAConsentStateDTO {
|
|
40
|
+
data_sale_opt_out: IPrivacyV2DTO;
|
|
41
|
+
}
|
|
6
42
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
43
|
+
// TODO: Break this up into GDPR and CCPA interfaces
|
|
44
|
+
export interface IConsentStateDTO {
|
|
45
|
+
gdpr?: IGDPRConsentStateDTO;
|
|
46
|
+
ccpa?: ICCPAConsentStateDTO;
|
|
47
|
+
}
|
|
12
48
|
|
|
13
|
-
|
|
14
|
-
|
|
49
|
+
// TODO: Confirm which attributes are optional
|
|
50
|
+
export interface IServerDTO {
|
|
51
|
+
id: string | number;
|
|
52
|
+
nm: string | number;
|
|
53
|
+
pr: number;
|
|
54
|
+
qt: number;
|
|
55
|
+
br: string | number;
|
|
56
|
+
va: string | number;
|
|
57
|
+
ca: string | number;
|
|
58
|
+
ps: number;
|
|
59
|
+
cc: string | number;
|
|
60
|
+
attrs: Record<string, string> | null;
|
|
61
|
+
dp_id?: string;
|
|
62
|
+
dp_v?: number;
|
|
63
|
+
n?: string;
|
|
64
|
+
et?: number;
|
|
65
|
+
ua?: Dictionary<string | string[]>;
|
|
66
|
+
ui?: SDKUserIdentity[];
|
|
67
|
+
ia?: Dictionary<Dictionary<string>>;
|
|
68
|
+
str?: ServerSettings;
|
|
69
|
+
sdk?: string;
|
|
70
|
+
sid?: string;
|
|
71
|
+
sl?: number;
|
|
72
|
+
ssd?: number;
|
|
73
|
+
dt?: number;
|
|
74
|
+
dbg?: boolean;
|
|
75
|
+
ct?: number;
|
|
76
|
+
lc?: SDKGeoLocation;
|
|
77
|
+
o?: boolean;
|
|
78
|
+
eec?: number;
|
|
79
|
+
av?: string;
|
|
80
|
+
cgid?: string;
|
|
81
|
+
das?: string;
|
|
82
|
+
mpid?: MPID;
|
|
83
|
+
smpids?: MPID[];
|
|
84
|
+
con?: IConsentStateDTO;
|
|
85
|
+
fr?: boolean;
|
|
86
|
+
iu?: boolean; // isUpgrade
|
|
87
|
+
at?: number;
|
|
88
|
+
lr?: string;
|
|
89
|
+
flags?: Dictionary<string[]>;
|
|
90
|
+
cu?: string;
|
|
91
|
+
sc?: {
|
|
92
|
+
pl: IProductDTO[];
|
|
93
|
+
};
|
|
94
|
+
pd?: {
|
|
95
|
+
an: number;
|
|
96
|
+
cs: number;
|
|
97
|
+
co: string;
|
|
98
|
+
pl: IProductDTO[];
|
|
99
|
+
ta: string;
|
|
100
|
+
ti: string;
|
|
101
|
+
tcc: string;
|
|
102
|
+
tr: number;
|
|
103
|
+
ts: number;
|
|
104
|
+
tt: number;
|
|
105
|
+
};
|
|
106
|
+
pm?: {
|
|
107
|
+
an: string;
|
|
108
|
+
pl: IPromotionDTO[];
|
|
109
|
+
};
|
|
110
|
+
pi?: IProductImpressionDTO[];
|
|
111
|
+
pet?: number;
|
|
112
|
+
}
|
|
15
113
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
114
|
+
export interface IProductDTO {
|
|
115
|
+
id: string | number;
|
|
116
|
+
nm: string | number;
|
|
117
|
+
pr: number;
|
|
118
|
+
qt: number;
|
|
119
|
+
br: string | number;
|
|
120
|
+
va: string | number;
|
|
121
|
+
ca: string | number;
|
|
122
|
+
ps: number;
|
|
123
|
+
cc: string | number;
|
|
124
|
+
tpa: number;
|
|
125
|
+
attrs: Record<string, string> | null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface IPromotionDTO {
|
|
129
|
+
id: string | number;
|
|
130
|
+
nm: string | number;
|
|
131
|
+
ps: string | number;
|
|
132
|
+
cr: string;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface IProductImpressionDTO {
|
|
136
|
+
pil: string;
|
|
137
|
+
pl: IProductDTO[];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface IUploadObject extends SDKEvent {
|
|
141
|
+
// TODO: References to `ClientGeneratedId` can be removed when we remove the
|
|
142
|
+
// V2 event upload path because it does not exist in the V3 payload
|
|
143
|
+
ClientGeneratedId: string;
|
|
144
|
+
// FIXME: This reference to Store is misleading and can be removed whenever
|
|
145
|
+
// we deprecate v2 related code
|
|
146
|
+
Store: ServerSettings;
|
|
147
|
+
ExpandedEventCount: number;
|
|
148
|
+
ProfileMessageType: number;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface IServerModel {
|
|
152
|
+
convertEventToDTO: (event: IUploadObject) => IServerDTO;
|
|
153
|
+
createEventObject: (event: BaseEvent, user?: MParticleUser) => SDKEvent;
|
|
154
|
+
convertToConsentStateDTO: (state: SDKConsentState) => IConsentStateDTO;
|
|
155
|
+
appendUserInfo: (user: MParticleUser, event: SDKEvent) => void;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// TODO: Make this a pure function that returns a new object
|
|
159
|
+
function convertCustomFlags(event: SDKEvent, dto: IServerDTO) {
|
|
160
|
+
var valueArray: string[] = [];
|
|
161
|
+
dto.flags = {};
|
|
162
|
+
|
|
163
|
+
for (var prop in event.CustomFlags) {
|
|
164
|
+
valueArray = [];
|
|
165
|
+
|
|
166
|
+
if (event.CustomFlags.hasOwnProperty(prop)) {
|
|
167
|
+
if (Array.isArray(event.CustomFlags[prop])) {
|
|
168
|
+
event.CustomFlags[prop].forEach(function(customFlagProperty) {
|
|
169
|
+
// TODO: Can we use our utility functions here?
|
|
170
|
+
if (
|
|
171
|
+
typeof customFlagProperty === 'number' ||
|
|
172
|
+
typeof customFlagProperty === 'string' ||
|
|
173
|
+
typeof customFlagProperty === 'boolean'
|
|
20
174
|
) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
typeof event.CustomFlags[prop] === 'boolean'
|
|
33
|
-
) {
|
|
34
|
-
valueArray.push(event.CustomFlags[prop].toString());
|
|
35
|
-
}
|
|
175
|
+
valueArray.push(customFlagProperty.toString());
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
} else if (
|
|
179
|
+
// TODO: Can we use our utility functions here?
|
|
180
|
+
typeof event.CustomFlags[prop] === 'number' ||
|
|
181
|
+
typeof event.CustomFlags[prop] === 'string' ||
|
|
182
|
+
typeof event.CustomFlags[prop] === 'boolean'
|
|
183
|
+
) {
|
|
184
|
+
valueArray.push(event.CustomFlags[prop].toString());
|
|
185
|
+
}
|
|
36
186
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
187
|
+
if (valueArray.length) {
|
|
188
|
+
dto.flags[prop] = valueArray;
|
|
40
189
|
}
|
|
41
190
|
}
|
|
42
191
|
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function convertProductToDTO(product: SDKProduct): IProductDTO {
|
|
195
|
+
return {
|
|
196
|
+
id: parseStringOrNumber(product.Sku),
|
|
197
|
+
nm: parseStringOrNumber(product.Name),
|
|
198
|
+
pr: parseNumber(product.Price),
|
|
199
|
+
qt: parseNumber(product.Quantity),
|
|
200
|
+
br: parseStringOrNumber(product.Brand),
|
|
201
|
+
va: parseStringOrNumber(product.Variant),
|
|
202
|
+
ca: parseStringOrNumber(product.Category),
|
|
203
|
+
ps: parseNumber(product.Position),
|
|
204
|
+
cc: parseStringOrNumber(product.CouponCode),
|
|
205
|
+
tpa: parseNumber(product.TotalAmount),
|
|
206
|
+
attrs: product.Attributes,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function convertProductListToDTO(productList: SDKProduct[]): IProductDTO[] {
|
|
211
|
+
if (!productList) {
|
|
212
|
+
return [];
|
|
213
|
+
}
|
|
43
214
|
|
|
44
|
-
|
|
215
|
+
return productList.map(function(product) {
|
|
216
|
+
return convertProductToDTO(product);
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export default function ServerModel(
|
|
221
|
+
this: IServerModel,
|
|
222
|
+
mpInstance: MParticleWebSDK
|
|
223
|
+
) {
|
|
224
|
+
var self = this;
|
|
225
|
+
|
|
226
|
+
// TODO: Can we refactor this to not mutate the event?
|
|
227
|
+
this.appendUserInfo = function(user: MParticleUser, event: SDKEvent): void {
|
|
45
228
|
if (!event) {
|
|
46
229
|
return;
|
|
47
230
|
}
|
|
@@ -72,7 +255,7 @@ export default function ServerModel(mpInstance) {
|
|
|
72
255
|
if (mpInstance._Helpers.isObject(dtoUserIdentities)) {
|
|
73
256
|
if (Object.keys(dtoUserIdentities).length) {
|
|
74
257
|
for (var key in dtoUserIdentities) {
|
|
75
|
-
var userIdentity = {};
|
|
258
|
+
var userIdentity: Partial<SDKUserIdentity> = {};
|
|
76
259
|
userIdentity.Identity = dtoUserIdentities[key];
|
|
77
260
|
userIdentity.Type = mpInstance._Helpers.parseNumber(key);
|
|
78
261
|
validUserIdentities.push(userIdentity);
|
|
@@ -82,45 +265,21 @@ export default function ServerModel(mpInstance) {
|
|
|
82
265
|
event.UserIdentities = validUserIdentities;
|
|
83
266
|
};
|
|
84
267
|
|
|
85
|
-
function
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return productList.map(function(product) {
|
|
91
|
-
return convertProductToDTO(product);
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function convertProductToDTO(product) {
|
|
96
|
-
return {
|
|
97
|
-
id: mpInstance._Helpers.parseStringOrNumber(product.Sku),
|
|
98
|
-
nm: mpInstance._Helpers.parseStringOrNumber(product.Name),
|
|
99
|
-
pr: mpInstance._Helpers.parseNumber(product.Price),
|
|
100
|
-
qt: mpInstance._Helpers.parseNumber(product.Quantity),
|
|
101
|
-
br: mpInstance._Helpers.parseStringOrNumber(product.Brand),
|
|
102
|
-
va: mpInstance._Helpers.parseStringOrNumber(product.Variant),
|
|
103
|
-
ca: mpInstance._Helpers.parseStringOrNumber(product.Category),
|
|
104
|
-
ps: mpInstance._Helpers.parseNumber(product.Position),
|
|
105
|
-
cc: mpInstance._Helpers.parseStringOrNumber(product.CouponCode),
|
|
106
|
-
tpa: mpInstance._Helpers.parseNumber(product.TotalAmount),
|
|
107
|
-
attrs: product.Attributes,
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
this.convertToConsentStateDTO = function(state) {
|
|
268
|
+
this.convertToConsentStateDTO = function(
|
|
269
|
+
state: SDKConsentState
|
|
270
|
+
): IConsentStateDTO {
|
|
112
271
|
if (!state) {
|
|
113
272
|
return null;
|
|
114
273
|
}
|
|
115
|
-
var jsonObject = {};
|
|
274
|
+
var jsonObject: IConsentStateDTO = {};
|
|
116
275
|
var gdprConsentState = state.getGDPRConsentState();
|
|
117
276
|
if (gdprConsentState) {
|
|
118
|
-
var gdpr = {};
|
|
277
|
+
var gdpr: IGDPRConsentStateDTO = {};
|
|
119
278
|
jsonObject.gdpr = gdpr;
|
|
120
279
|
for (var purpose in gdprConsentState) {
|
|
121
280
|
if (gdprConsentState.hasOwnProperty(purpose)) {
|
|
122
281
|
var gdprConsent = gdprConsentState[purpose];
|
|
123
|
-
jsonObject.gdpr[purpose] = {};
|
|
282
|
+
jsonObject.gdpr[purpose] = {} as IPrivacyV2DTO;
|
|
124
283
|
if (typeof gdprConsent.Consented === 'boolean') {
|
|
125
284
|
gdpr[purpose].c = gdprConsent.Consented;
|
|
126
285
|
}
|
|
@@ -153,28 +312,41 @@ export default function ServerModel(mpInstance) {
|
|
|
153
312
|
};
|
|
154
313
|
}
|
|
155
314
|
|
|
156
|
-
return jsonObject;
|
|
315
|
+
return jsonObject as IConsentStateDTO;
|
|
157
316
|
};
|
|
158
317
|
|
|
159
|
-
this.createEventObject = function(
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
318
|
+
this.createEventObject = function(
|
|
319
|
+
event: BaseEvent,
|
|
320
|
+
user?: MParticleUser
|
|
321
|
+
): SDKEvent | IUploadObject {
|
|
322
|
+
var uploadObject: Partial<IUploadObject> = {};
|
|
323
|
+
var eventObject: Partial<SDKEvent> = {};
|
|
324
|
+
|
|
325
|
+
// The `optOut` variable is passed later in this method to the `uploadObject`
|
|
326
|
+
// so that it can be used to denote whether or not a user has "opted out" of being
|
|
327
|
+
// tracked. If this is an `optOut` Event, we set `optOut` to the inverse of the SDK's
|
|
328
|
+
// `isEnabled` boolean which is controlled via `MPInstanceManager.setOptOut`.
|
|
163
329
|
var optOut =
|
|
164
330
|
event.messageType === Types.MessageType.OptOut
|
|
165
331
|
? !mpInstance._Store.isEnabled
|
|
166
332
|
: null;
|
|
167
333
|
|
|
334
|
+
// TODO: Why is Webview Bridge Enabled or Opt Out necessary here?
|
|
168
335
|
if (
|
|
169
336
|
mpInstance._Store.sessionId ||
|
|
170
|
-
event.messageType
|
|
337
|
+
event.messageType === Types.MessageType.OptOut ||
|
|
171
338
|
mpInstance._Store.webviewBridgeEnabled
|
|
172
339
|
) {
|
|
173
340
|
if (event.hasOwnProperty('toEventAPIObject')) {
|
|
174
341
|
eventObject = event.toEventAPIObject();
|
|
175
342
|
} else {
|
|
176
343
|
eventObject = {
|
|
177
|
-
|
|
344
|
+
// This is an artifact from v2 events where SessionStart/End and AST event
|
|
345
|
+
// names are numbers (1, 2, or 10), but going forward with v3, these lifecycle
|
|
346
|
+
// events do not have names, but are denoted by their `event_type`
|
|
347
|
+
EventName:
|
|
348
|
+
event.name ||
|
|
349
|
+
((event.messageType as unknown) as string),
|
|
178
350
|
EventCategory: event.eventType,
|
|
179
351
|
EventAttributes: mpInstance._Helpers.sanitizeAttributes(
|
|
180
352
|
event.data,
|
|
@@ -190,11 +362,13 @@ export default function ServerModel(mpInstance) {
|
|
|
190
362
|
};
|
|
191
363
|
}
|
|
192
364
|
|
|
365
|
+
// TODO: Should we move this side effect outside of this method?
|
|
193
366
|
if (event.messageType !== Types.MessageType.SessionEnd) {
|
|
194
367
|
mpInstance._Store.dateLastEventSent = new Date();
|
|
195
368
|
}
|
|
196
369
|
|
|
197
370
|
uploadObject = {
|
|
371
|
+
// FIXME: Deprecate when we get rid of V2
|
|
198
372
|
Store: mpInstance._Store.serverSettings,
|
|
199
373
|
SDKVersion: Constants.sdkVersion,
|
|
200
374
|
SessionId: mpInstance._Store.sessionId,
|
|
@@ -222,9 +396,10 @@ export default function ServerModel(mpInstance) {
|
|
|
222
396
|
eventObject.LaunchReferral = window.location.href || null;
|
|
223
397
|
}
|
|
224
398
|
|
|
399
|
+
// FIXME: Remove duplicate occurence
|
|
225
400
|
eventObject.CurrencyCode = mpInstance._Store.currencyCode;
|
|
226
401
|
var currentUser = user || mpInstance.Identity.getCurrentUser();
|
|
227
|
-
self.appendUserInfo(currentUser, eventObject);
|
|
402
|
+
self.appendUserInfo(currentUser, eventObject as SDKEvent);
|
|
228
403
|
|
|
229
404
|
if (event.messageType === Types.MessageType.SessionEnd) {
|
|
230
405
|
eventObject.SessionLength =
|
|
@@ -232,9 +407,15 @@ export default function ServerModel(mpInstance) {
|
|
|
232
407
|
mpInstance._Store.sessionStartDate.getTime();
|
|
233
408
|
eventObject.currentSessionMPIDs =
|
|
234
409
|
mpInstance._Store.currentSessionMPIDs;
|
|
410
|
+
|
|
411
|
+
// Session attributes are assigned on a session level, but only uploaded
|
|
412
|
+
// when a session ends. As there is no way to attach event attributes to
|
|
413
|
+
// a `SessionEnd` event, we are uploading the session level attributes
|
|
414
|
+
// as event level attributes in a `SessionEnd` event.
|
|
235
415
|
eventObject.EventAttributes =
|
|
236
416
|
mpInstance._Store.sessionAttributes;
|
|
237
417
|
|
|
418
|
+
// TODO: We should move this out of here to avoid side effects
|
|
238
419
|
mpInstance._Store.currentSessionMPIDs = [];
|
|
239
420
|
mpInstance._Store.sessionStartDate = null;
|
|
240
421
|
}
|
|
@@ -247,8 +428,8 @@ export default function ServerModel(mpInstance) {
|
|
|
247
428
|
return null;
|
|
248
429
|
};
|
|
249
430
|
|
|
250
|
-
this.convertEventToDTO = function(event) {
|
|
251
|
-
var dto = {
|
|
431
|
+
this.convertEventToDTO = function(event: IUploadObject): IServerDTO {
|
|
432
|
+
var dto: Partial<IServerDTO> = {
|
|
252
433
|
n: event.EventName,
|
|
253
434
|
et: event.EventCategory,
|
|
254
435
|
ua: event.UserAttributes,
|
|
@@ -290,16 +471,20 @@ export default function ServerModel(mpInstance) {
|
|
|
290
471
|
dto.iu = false;
|
|
291
472
|
dto.at = ApplicationTransitionType.AppInit;
|
|
292
473
|
dto.lr = event.LaunchReferral;
|
|
474
|
+
|
|
475
|
+
// Nullify Attributes in case AST Was logged manually or
|
|
476
|
+
// via logBaseEvent. AST should not have any attributes
|
|
293
477
|
dto.attrs = null;
|
|
294
478
|
}
|
|
295
479
|
|
|
296
480
|
if (event.CustomFlags) {
|
|
297
|
-
convertCustomFlags(event, dto);
|
|
481
|
+
convertCustomFlags(event, dto as IServerDTO);
|
|
298
482
|
}
|
|
299
483
|
|
|
300
484
|
if (event.EventDataType === MessageType.Commerce) {
|
|
301
485
|
dto.cu = event.CurrencyCode;
|
|
302
486
|
|
|
487
|
+
// TODO: If Cart is deprecated, we should deprecate this too
|
|
303
488
|
if (event.ShoppingCart) {
|
|
304
489
|
dto.sc = {
|
|
305
490
|
pl: convertProductListToDTO(event.ShoppingCart.ProductList),
|
|
@@ -355,6 +540,6 @@ export default function ServerModel(mpInstance) {
|
|
|
355
540
|
dto.pet = event.ProfileMessageType;
|
|
356
541
|
}
|
|
357
542
|
|
|
358
|
-
return dto;
|
|
543
|
+
return dto as IServerDTO;
|
|
359
544
|
};
|
|
360
545
|
}
|
package/src/store.ts
CHANGED
|
@@ -115,8 +115,8 @@ export interface IStore {
|
|
|
115
115
|
devToken: string | null;
|
|
116
116
|
migrationData: MigrationData;
|
|
117
117
|
serverSettings: ServerSettings;
|
|
118
|
-
dateLastEventSent:
|
|
119
|
-
sessionStartDate:
|
|
118
|
+
dateLastEventSent: Date;
|
|
119
|
+
sessionStartDate: Date;
|
|
120
120
|
currentPosition: SDKGeoLocation | null;
|
|
121
121
|
isTracking: boolean;
|
|
122
122
|
watchPositionId: number | null;
|
|
@@ -143,8 +143,10 @@ export interface IStore {
|
|
|
143
143
|
configuredForwarders: MPForwarder[];
|
|
144
144
|
pixelConfigurations: PixelConfiguration[];
|
|
145
145
|
integrationDelayTimeoutStart: number; // UNIX Timestamp
|
|
146
|
+
webviewBridgeEnabled?: boolean;
|
|
146
147
|
}
|
|
147
148
|
|
|
149
|
+
// TODO: Merge this with SDKStoreApi in sdkRuntimeModels
|
|
148
150
|
export default function Store(
|
|
149
151
|
this: IStore,
|
|
150
152
|
config: SDKInitConfig,
|
package/src/types.js
CHANGED
|
@@ -361,6 +361,11 @@ var ApplicationTransitionType = {
|
|
|
361
361
|
AppInit: 1,
|
|
362
362
|
};
|
|
363
363
|
|
|
364
|
+
const Environment = {
|
|
365
|
+
Production: 'production',
|
|
366
|
+
Development: 'development',
|
|
367
|
+
};
|
|
368
|
+
|
|
364
369
|
export default {
|
|
365
370
|
MessageType: MessageType,
|
|
366
371
|
EventType: EventType,
|
|
@@ -371,4 +376,5 @@ export default {
|
|
|
371
376
|
ProductActionType: ProductActionType,
|
|
372
377
|
PromotionActionType: PromotionActionType,
|
|
373
378
|
TriggerUploadType: TriggerUploadType,
|
|
379
|
+
Environment,
|
|
374
380
|
};
|
package/src/utils.ts
CHANGED
|
@@ -49,6 +49,16 @@ const parseNumber = (value: string | number): number => {
|
|
|
49
49
|
return isNaN(floatValue) ? 0 : floatValue;
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
+
const parseStringOrNumber = (
|
|
53
|
+
value: string | number
|
|
54
|
+
): string | number | null => {
|
|
55
|
+
if (isStringOrNumber(value)) {
|
|
56
|
+
return value;
|
|
57
|
+
} else {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
52
62
|
// FIXME: REFACTOR for V3
|
|
53
63
|
// only used in store.js to sanitize server-side formatting of
|
|
54
64
|
// booleans when checking for `isDevelopmentMode`
|
|
@@ -86,6 +96,9 @@ const isDataPlanSlug = (str: string): boolean =>
|
|
|
86
96
|
const isStringOrNumber = (value: any): boolean =>
|
|
87
97
|
isString(value) || isNumber(value);
|
|
88
98
|
|
|
99
|
+
const isEmpty = (value: Dictionary<any> | null | undefined): boolean =>
|
|
100
|
+
value == null || !(Object.keys(value) || value).length;
|
|
101
|
+
|
|
89
102
|
export {
|
|
90
103
|
valueof,
|
|
91
104
|
converted,
|
|
@@ -93,11 +106,13 @@ export {
|
|
|
93
106
|
findKeyInObject,
|
|
94
107
|
inArray,
|
|
95
108
|
isObject,
|
|
109
|
+
isStringOrNumber,
|
|
96
110
|
parseNumber,
|
|
111
|
+
parseStringOrNumber,
|
|
97
112
|
returnConvertedBoolean,
|
|
98
113
|
isString,
|
|
99
114
|
isNumber,
|
|
100
115
|
isFunction,
|
|
101
|
-
isStringOrNumber,
|
|
102
116
|
isDataPlanSlug,
|
|
117
|
+
isEmpty,
|
|
103
118
|
};
|
package/src/validators.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import Types from './types';
|
|
2
|
-
import { isFunction, isNumber, isObject, isStringOrNumber } from './utils';
|
|
2
|
+
import { isFunction, isNumber, isObject, isStringOrNumber, valueof } from './utils';
|
|
3
3
|
import Constants from './constants';
|
|
4
4
|
import { IdentityApiData } from '@mparticle/web-sdk';
|
|
5
|
-
import { valueof } from './utils';
|
|
6
5
|
|
|
7
6
|
type IdentityAPIMethod = 'login' | 'logout' | 'identify' | 'modify';
|
|
8
7
|
|
|
@@ -13,14 +12,17 @@ type ValidationIdentitiesReturn = {
|
|
|
13
12
|
|
|
14
13
|
const Validators = {
|
|
15
14
|
// From ./utils
|
|
15
|
+
// Utility Functions for backwards compatability
|
|
16
16
|
isNumber,
|
|
17
17
|
isFunction,
|
|
18
18
|
isStringOrNumber,
|
|
19
19
|
|
|
20
|
+
// Validator Functions
|
|
20
21
|
isValidAttributeValue: function(value: any): boolean {
|
|
21
22
|
return value !== undefined && !isObject(value) && !Array.isArray(value);
|
|
22
23
|
},
|
|
23
24
|
|
|
25
|
+
// Validator Functions
|
|
24
26
|
// Neither null nor undefined can be a valid Key
|
|
25
27
|
isValidKeyValue: function(key: any): boolean {
|
|
26
28
|
return Boolean(
|