@appmetrica/react-native-analytics 3.0.0 → 3.1.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.
Files changed (42) hide show
  1. package/android/build.gradle +1 -1
  2. package/android/src/main/java/io/appmetrica/analytics/reactnative/AppMetricaModule.java +10 -0
  3. package/android/src/main/java/io/appmetrica/analytics/reactnative/UserProfileSerializer.java +257 -0
  4. package/android/src/main/java/io/appmetrica/analytics/reactnative/Utils.java +9 -0
  5. package/appmetrica-react-native-analytics.podspec +1 -1
  6. package/ios/AMARNAppMetrica.m +6 -0
  7. package/ios/AMARNAppMetricaUtils.h +2 -0
  8. package/ios/AMARNAppMetricaUtils.m +8 -0
  9. package/ios/AMARNUserProfileSerializer.h +6 -0
  10. package/ios/AMARNUserProfileSerializer.m +182 -0
  11. package/lib/commonjs/ecommerce.js +10 -9
  12. package/lib/commonjs/ecommerce.js.map +1 -1
  13. package/lib/commonjs/index.js +17 -1
  14. package/lib/commonjs/index.js.map +1 -1
  15. package/lib/commonjs/userProfile.js +283 -0
  16. package/lib/commonjs/userProfile.js.map +1 -0
  17. package/lib/commonjs/utils.js +72 -0
  18. package/lib/commonjs/utils.js.map +1 -0
  19. package/lib/module/ecommerce.js +10 -9
  20. package/lib/module/ecommerce.js.map +1 -1
  21. package/lib/module/index.js +6 -1
  22. package/lib/module/index.js.map +1 -1
  23. package/lib/module/userProfile.js +267 -0
  24. package/lib/module/userProfile.js.map +1 -0
  25. package/lib/module/utils.js +61 -0
  26. package/lib/module/utils.js.map +1 -0
  27. package/lib/typescript/src/ecommerce.d.ts +3 -3
  28. package/lib/typescript/src/ecommerce.d.ts.map +1 -1
  29. package/lib/typescript/src/index.d.ts +5 -1
  30. package/lib/typescript/src/index.d.ts.map +1 -1
  31. package/lib/typescript/src/revenue.d.ts +1 -1
  32. package/lib/typescript/src/revenue.d.ts.map +1 -1
  33. package/lib/typescript/src/userProfile.d.ts +84 -0
  34. package/lib/typescript/src/userProfile.d.ts.map +1 -0
  35. package/lib/typescript/src/utils.d.ts +9 -0
  36. package/lib/typescript/src/utils.d.ts.map +1 -0
  37. package/package.json +1 -1
  38. package/src/ecommerce.ts +20 -12
  39. package/src/index.ts +10 -2
  40. package/src/revenue.ts +1 -1
  41. package/src/userProfile.ts +362 -0
  42. package/src/utils.ts +71 -0
package/src/index.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { Linking, NativeModules, Platform } from 'react-native';
2
2
  import type { ECommerceEvent } from './ecommerce';
3
3
  import type { AdRevenue, Revenue } from './revenue';
4
+ import type { UserProfile } from './userProfile';
5
+ import { normalizeAdRevenue } from './utils';
4
6
 
5
7
  const LINKING_ERROR =
6
8
  `The package '@appmetrica/react-native-analytics' doesn't seem to be linked. Make sure: \n\n` +
@@ -51,6 +53,7 @@ export type AppMetricaConfig = {
51
53
  activationAsSessionStart?: boolean; // iOS only
52
54
  sessionsAutoTracking?: boolean; // iOS only
53
55
  appOpenTrackingEnabled?: boolean;
56
+ userProfileID?: string;
54
57
  };
55
58
 
56
59
  export type PreloadInfo = {
@@ -87,6 +90,7 @@ export const UUID_KEY = 'appmetrica_uuid';
87
90
 
88
91
  export * from './ecommerce';
89
92
  export * from './revenue';
93
+ export * from './userProfile';
90
94
 
91
95
  export default class AppMetrica {
92
96
  static activate(config: AppMetricaConfig) {
@@ -116,7 +120,7 @@ export default class AppMetrica {
116
120
  AppMetricaNative.reportAppOpen(deeplink);
117
121
  }
118
122
 
119
- static reportError(identifier: string, message: string, _reason: Object) {
123
+ static reportError(identifier: string, message: string, _reason?: Object) {
120
124
  AppMetricaNative.reportError(identifier, message);
121
125
  }
122
126
 
@@ -164,6 +168,10 @@ export default class AppMetrica {
164
168
  }
165
169
 
166
170
  static reportAdRevenue(adRevenue: AdRevenue) {
167
- AppMetricaNative.reportAdRevenue(adRevenue);
171
+ AppMetricaNative.reportAdRevenue(normalizeAdRevenue(adRevenue));
172
+ }
173
+
174
+ static reportUserProfile(userProfile: UserProfile) {
175
+ AppMetricaNative.reportUserProfile(userProfile)
168
176
  }
169
177
  }
package/src/revenue.ts CHANGED
@@ -16,7 +16,7 @@ export type Receipt = {
16
16
  export type AdRevenue = {
17
17
  price: number | string;
18
18
  currency: string;
19
- payload?: Map<string, string>;
19
+ payload?: Map<string, string> | Record<string, string>;
20
20
  adNetwork?: string;
21
21
  adPlacementID?: string;
22
22
  adPlacementName?: string;
@@ -0,0 +1,362 @@
1
+ export class UserProfile {
2
+ private attributes: Array<UserProfileUpdate>;
3
+
4
+ constructor() {
5
+ this.attributes = [];
6
+ }
7
+
8
+ apply(attribute: UserProfileUpdate): UserProfile {
9
+ this.attributes.push(attribute);
10
+
11
+ return this;
12
+ }
13
+ }
14
+
15
+ type UserProfileUpdateType =
16
+ | 'BirthDateWithAge'
17
+ | 'BirthDateWithYear'
18
+ | 'BirthDateWithMonth'
19
+ | 'BirthDateWithDay'
20
+ | 'BirthDateValueReset'
21
+ | 'BooleanValue'
22
+ | 'BooleanValueReset'
23
+ | 'Counter'
24
+ | 'GenderValue'
25
+ | 'GenderValueReset'
26
+ | 'NameValue'
27
+ | 'NameValueReset'
28
+ | 'NotificationsEnabledValue'
29
+ | 'NotificationsEnabledValueReset'
30
+ | 'NumberValue'
31
+ | 'NumberValueReset'
32
+ | 'StringValue'
33
+ | 'StringValueReset';
34
+
35
+ export interface UserProfileUpdate {
36
+ type: UserProfileUpdateType;
37
+ key?: string;
38
+ value?: any;
39
+ ifUndefined?: boolean;
40
+ age?: number;
41
+ year?: number;
42
+ month?: number;
43
+ day?: number;
44
+ delta?: number;
45
+ }
46
+
47
+ export type UserProfileGender = 'male' | 'female' | 'other';
48
+
49
+ export class Attributes {
50
+ static birthDate() {
51
+ return new BirthDateAttribute();
52
+ }
53
+
54
+ static customBoolean(key: string) {
55
+ return new BooleanAttribute(key);
56
+ }
57
+
58
+ static customCounter(key: string) {
59
+ return new CounterAttribute(key);
60
+ }
61
+
62
+ static customNumber(key: string) {
63
+ return new NumberAttribute(key);
64
+ }
65
+
66
+ static customString(key: string) {
67
+ return new StringAttribute(key);
68
+ }
69
+
70
+ static gender() {
71
+ return new GenderAttribute();
72
+ }
73
+
74
+ static userName() {
75
+ return new NameAttribute();
76
+ }
77
+
78
+ static notificationsEnabled() {
79
+ return new NotificationsEnabledAttribute();
80
+ }
81
+ }
82
+
83
+ export class BirthDateAttribute {
84
+ withAge(age: number): UserProfileUpdate {
85
+ return {
86
+ type: 'BirthDateWithAge',
87
+ age: age,
88
+ ifUndefined: false,
89
+ };
90
+ }
91
+
92
+ withAgeIfUndefined(age: number): UserProfileUpdate {
93
+ return {
94
+ type: 'BirthDateWithAge',
95
+ age: age,
96
+ ifUndefined: true,
97
+ };
98
+ }
99
+
100
+ withYear(year: number): UserProfileUpdate {
101
+ return {
102
+ type: 'BirthDateWithYear',
103
+ year: year,
104
+ ifUndefined: false,
105
+ };
106
+ }
107
+
108
+ withYearIfUndefined(year: number): UserProfileUpdate {
109
+ return {
110
+ type: 'BirthDateWithYear',
111
+ year: year,
112
+ ifUndefined: true,
113
+ };
114
+ }
115
+
116
+ withMonth(year: number, month: number): UserProfileUpdate {
117
+ return {
118
+ type: 'BirthDateWithMonth',
119
+ year: year,
120
+ month: month,
121
+ ifUndefined: false,
122
+ };
123
+ }
124
+
125
+ withMonthIfUndefined(year: number, month: number): UserProfileUpdate {
126
+ return {
127
+ type: 'BirthDateWithMonth',
128
+ year: year,
129
+ month: month,
130
+ ifUndefined: true,
131
+ };
132
+ }
133
+
134
+ withDay(year: number, month: number, day: number): UserProfileUpdate {
135
+ return {
136
+ type: 'BirthDateWithDay',
137
+ year: year,
138
+ month: month,
139
+ day: day,
140
+ ifUndefined: false,
141
+ };
142
+ }
143
+
144
+ withDayIfUndefined(
145
+ year: number,
146
+ month: number,
147
+ day: number
148
+ ): UserProfileUpdate {
149
+ return {
150
+ type: 'BirthDateWithDay',
151
+ year: year,
152
+ month: month,
153
+ day: day,
154
+ ifUndefined: true,
155
+ };
156
+ }
157
+
158
+ withDate(date: Date): UserProfileUpdate {
159
+ return this.withDay(date.getFullYear(), date.getMonth(), date.getDate());
160
+ }
161
+
162
+ withDateIfUndefined(date: Date): UserProfileUpdate {
163
+ return this.withDayIfUndefined(
164
+ date.getFullYear(),
165
+ date.getMonth(),
166
+ date.getDate()
167
+ );
168
+ }
169
+
170
+ withValueReset(): UserProfileUpdate {
171
+ return {
172
+ type: 'BirthDateValueReset',
173
+ };
174
+ }
175
+ }
176
+
177
+ export class BooleanAttribute {
178
+ private readonly key: string;
179
+
180
+ constructor(key: string) {
181
+ this.key = key;
182
+ }
183
+
184
+ withValue(value: boolean): UserProfileUpdate {
185
+ return {
186
+ type: 'BooleanValue',
187
+ key: this.key,
188
+ value: value,
189
+ ifUndefined: false,
190
+ };
191
+ }
192
+
193
+ withValueIfUndefined(value: boolean): UserProfileUpdate {
194
+ return {
195
+ type: 'BooleanValue',
196
+ key: this.key,
197
+ value: value,
198
+ ifUndefined: true,
199
+ };
200
+ }
201
+
202
+ withValueReset(): UserProfileUpdate {
203
+ return {
204
+ type: 'BooleanValueReset',
205
+ key: this.key,
206
+ };
207
+ }
208
+ }
209
+
210
+ export class CounterAttribute {
211
+ private readonly key: string;
212
+
213
+ constructor(key: string) {
214
+ this.key = key;
215
+ }
216
+
217
+ withDelta(delta: number): UserProfileUpdate {
218
+ return {
219
+ type: 'Counter',
220
+ key: this.key,
221
+ delta: delta,
222
+ };
223
+ }
224
+ }
225
+
226
+ export class GenderAttribute {
227
+ withValue(gender: UserProfileGender): UserProfileUpdate {
228
+ return {
229
+ type: 'GenderValue',
230
+ value: gender,
231
+ ifUndefined: false,
232
+ };
233
+ }
234
+
235
+ withValueIfUndefined(gender: UserProfileGender): UserProfileUpdate {
236
+ return {
237
+ type: 'GenderValue',
238
+ value: gender,
239
+ ifUndefined: true,
240
+ };
241
+ }
242
+
243
+ withValueReset(): UserProfileUpdate {
244
+ return {
245
+ type: 'GenderValueReset',
246
+ };
247
+ }
248
+ }
249
+
250
+ export class NameAttribute {
251
+ withValue(value: string): UserProfileUpdate {
252
+ return {
253
+ type: 'NameValue',
254
+ value: value,
255
+ ifUndefined: false,
256
+ };
257
+ }
258
+
259
+ withValueIfUndefined(value: string): UserProfileUpdate {
260
+ return {
261
+ type: 'NameValue',
262
+ value: value,
263
+ ifUndefined: true,
264
+ };
265
+ }
266
+
267
+ withValueReset(): UserProfileUpdate {
268
+ return {
269
+ type: 'NameValueReset',
270
+ };
271
+ }
272
+ }
273
+
274
+ export class NotificationsEnabledAttribute {
275
+ withValue(value: boolean): UserProfileUpdate {
276
+ return {
277
+ type: 'NotificationsEnabledValue',
278
+ value: value,
279
+ ifUndefined: false,
280
+ };
281
+ }
282
+
283
+ withValueIfUndefined(value: boolean): UserProfileUpdate {
284
+ return {
285
+ type: 'NotificationsEnabledValue',
286
+ value: value,
287
+ ifUndefined: true,
288
+ };
289
+ }
290
+
291
+ withValueReset(): UserProfileUpdate {
292
+ return {
293
+ type: 'NotificationsEnabledValueReset',
294
+ };
295
+ }
296
+ }
297
+
298
+ export class NumberAttribute {
299
+ private readonly key: string;
300
+
301
+ constructor(key: string) {
302
+ this.key = key;
303
+ }
304
+
305
+ withValue(value: number): UserProfileUpdate {
306
+ return {
307
+ type: 'NumberValue',
308
+ key: this.key,
309
+ value: value,
310
+ ifUndefined: false,
311
+ };
312
+ }
313
+
314
+ withValueIfUndefined(value: number): UserProfileUpdate {
315
+ return {
316
+ type: 'NumberValue',
317
+ key: this.key,
318
+ value: value,
319
+ ifUndefined: true,
320
+ };
321
+ }
322
+
323
+ withValueReset(): UserProfileUpdate {
324
+ return {
325
+ type: 'NumberValueReset',
326
+ key: this.key,
327
+ };
328
+ }
329
+ }
330
+
331
+ export class StringAttribute {
332
+ private readonly key: string;
333
+
334
+ constructor(key: string) {
335
+ this.key = key;
336
+ }
337
+
338
+ withValue(value: string): UserProfileUpdate {
339
+ return {
340
+ type: 'StringValue',
341
+ key: this.key,
342
+ value: value,
343
+ ifUndefined: false,
344
+ };
345
+ }
346
+
347
+ withValueIfUndefined(value: string): UserProfileUpdate {
348
+ return {
349
+ type: 'StringValue',
350
+ key: this.key,
351
+ value: value,
352
+ ifUndefined: true,
353
+ };
354
+ }
355
+
356
+ withValueReset(): UserProfileUpdate {
357
+ return {
358
+ type: 'StringValueReset',
359
+ key: this.key,
360
+ };
361
+ }
362
+ }
package/src/utils.ts ADDED
@@ -0,0 +1,71 @@
1
+ import type {
2
+ ECommerceCartItem,
3
+ ECommerceOrder,
4
+ ECommerceProduct,
5
+ ECommerceReferrer,
6
+ ECommerceScreen,
7
+ } from './ecommerce';
8
+ import type { AdRevenue } from './revenue';
9
+
10
+ function convertMap(
11
+ map?: Map<string, string>
12
+ ): Record<string, string> | undefined {
13
+ return map !== undefined ? Object.fromEntries(map) : undefined;
14
+ }
15
+
16
+ export function normalizeECommerceOrder(order: ECommerceOrder): ECommerceOrder {
17
+ const newOrder = { ...order } as ECommerceOrder;
18
+ if (order.payload instanceof Map) {
19
+ newOrder.payload = convertMap(order.payload);
20
+ }
21
+ newOrder.products = order.products.map(normalizeECommerceCartItem)
22
+ return newOrder;
23
+ }
24
+
25
+ export function normalizeECommerceCartItem(
26
+ item: ECommerceCartItem
27
+ ): ECommerceCartItem {
28
+ const newItem = { ...item } as ECommerceCartItem;
29
+ newItem.product = normalizeECommerceProduct(item.product);
30
+ newItem.referrer = normalizeECommerceReferrer(item.referrer);
31
+ return newItem;
32
+ }
33
+
34
+ export function normalizeECommerceProduct(
35
+ product: ECommerceProduct
36
+ ): ECommerceProduct {
37
+ const newProduct = { ...product } as ECommerceProduct;
38
+ if (product.payload instanceof Map) {
39
+ newProduct.payload = convertMap(product.payload);
40
+ }
41
+ return newProduct;
42
+ }
43
+
44
+ export function normalizeECommerceReferrer(
45
+ referrer?: ECommerceReferrer
46
+ ): ECommerceReferrer | undefined {
47
+ if (referrer === undefined) {
48
+ return undefined;
49
+ }
50
+ const newReferrer = { ...referrer } as ECommerceReferrer;
51
+ if (referrer.screen != undefined) {
52
+ newReferrer.screen = normalizeECommerceScreen(referrer.screen);
53
+ }
54
+ return newReferrer;
55
+ }
56
+
57
+ export function normalizeECommerceScreen(screen: ECommerceScreen): ECommerceScreen {
58
+ const newScreen = { ...screen } as ECommerceScreen;
59
+ if (screen.payload instanceof Map) {
60
+ newScreen.payload = convertMap(screen.payload);
61
+ }
62
+ return newScreen;
63
+ }
64
+
65
+ export function normalizeAdRevenue(adRevenue: AdRevenue): AdRevenue {
66
+ const newAdRevenue = { ...adRevenue } as AdRevenue;
67
+ if (adRevenue.payload instanceof Map) {
68
+ newAdRevenue.payload = convertMap(adRevenue.payload);
69
+ }
70
+ return newAdRevenue;
71
+ }