@reservamos/browser-analytics 0.3.1-alpha.7 → 1.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reservamos/browser-analytics",
3
- "version": "0.3.1-alpha.7",
3
+ "version": "1.0.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/reservamos/reservamos-browser-analytics.git"
@@ -68,7 +68,11 @@ async function identify(
68
68
  console.error('User ID is required for identification.');
69
69
  throw new Error('User ID is required for identification.');
70
70
  }
71
+ const anonymousProfile = await createAnonymousProfile(properties);
71
72
 
73
+ if(anonymousProfile){
74
+ properties.reservamos_one_id= anonymousProfile.id
75
+ }
72
76
  const mappedProps = mapProperties(properties);
73
77
  mixpanelService.identify(userId, mappedProps);
74
78
  const fingerprint = await fingerprintService.getFingerprint();
@@ -77,11 +81,6 @@ async function identify(
77
81
  }
78
82
  } catch (error) {
79
83
  console.error('Error identifying user', error);
80
- } finally {
81
- createAnonymousProfile({
82
- email: properties.email,
83
- phone: properties.phone,
84
- });
85
84
  }
86
85
  }
87
86
 
@@ -1,6 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import {
3
3
  arrayField,
4
+ booleanField,
4
5
  intField,
5
6
  numberField,
6
7
  stringField,
@@ -19,6 +20,9 @@ const paymentAttemptSchema = z
19
20
  'Total': numberField('Total'),
20
21
  'product': productValidation,
21
22
  'Passengers': arrayField(passengerSchema, 'Passengers', 1).optional(),
23
+ 'Insurance': booleanField('Insurance').optional(),
24
+ 'Coupon': stringField('Coupon').optional(),
25
+ 'User Status': stringField('User Status').optional(),
22
26
  })
23
27
  .strict();
24
28
 
@@ -1,10 +1,3 @@
1
- /**
2
- * Tests for the createAnonymousProfile method.
3
- * Cases:
4
- * - Should not throw an error if the payload is invalid
5
- * - Should not throw an error if the payload is valid but the API call fails.
6
- */
7
-
8
1
  import type { CreateAnonymousProfileProps } from './createAnonymousProfileSchema';
9
2
  import { describe, expect, it } from 'vitest';
10
3
  import validatorService from '@/services/validator';
@@ -12,7 +5,7 @@ import createAnonymousProfile from './createAnonymousProfile';
12
5
  import CreateAnonymousProfileSchema from './createAnonymousProfileSchema';
13
6
 
14
7
  describe('createAnonymousProfile', () => {
15
- it('should not throw an error if the payload is invalid', async () => {
8
+ it('should return undefined if the payload is invalid', async () => {
16
9
  const invalidPayload = {};
17
10
  expect(() =>
18
11
  validatorService.validateProps(
@@ -20,10 +13,10 @@ describe('createAnonymousProfile', () => {
20
13
  CreateAnonymousProfileSchema,
21
14
  ),
22
15
  ).toThrow();
23
- await expect(createAnonymousProfile(invalidPayload)).resolves.not.toThrow();
16
+ await expect(createAnonymousProfile(invalidPayload)).resolves.toBe(undefined)
24
17
  });
25
18
 
26
- it('should not throw an error if the payload is valid but the API call fails', async () => {
19
+ it('should return undefined if the payload is valid but the API call fails', async () => {
27
20
  const validPayload: CreateAnonymousProfileProps = {
28
21
  email: 'test@test.com',
29
22
  };
@@ -33,6 +26,6 @@ describe('createAnonymousProfile', () => {
33
26
  CreateAnonymousProfileSchema,
34
27
  ),
35
28
  ).not.toThrow();
36
- await expect(createAnonymousProfile(validPayload)).resolves.not.toThrow();
29
+ await expect(createAnonymousProfile(validPayload)).resolves.toBe(undefined)
37
30
  });
38
31
  });
@@ -10,36 +10,49 @@ type IdentifierKey = 'phone' | 'email';
10
10
  interface AnonymousProfilePayload {
11
11
  identifier_key: IdentifierKey;
12
12
  identifier_value: string;
13
- details: Record<string, string | number | boolean>;
13
+ identifiers: AnonymousIdentifier[]
14
+ }
15
+ interface AnonymousProfileResponse {
16
+ id: string;
14
17
  }
15
-
16
18
  /**
17
19
  * Transforms the identifier object based on the provided values.
18
20
  * @param {CreateAnonymousProfileProps} values - The values to transform.
21
+ * @param {AnonymousIdentifier[]} identifiersProps - Additional identifiers to include.
19
22
  * @returns {AnonymousProfilePayload} The transformed identifier object.
20
23
  */
21
24
  function getAnonymousProfilePayload(
22
25
  values: CreateAnonymousProfileProps,
26
+ identifiersProps: AnonymousIdentifier[]
23
27
  ): AnonymousProfilePayload {
24
28
  let identifier_key: IdentifierKey = 'phone';
25
29
  let identifier_value: string = values.phone || '';
26
- const details: Record<string, string | number | boolean> = {};
30
+ const identifiers: AnonymousIdentifier[] = []
27
31
 
28
32
  if (values.email) {
29
33
  identifier_key = 'email';
30
34
  identifier_value = values.email;
31
35
  }
32
36
 
37
+ // List of allowed keys for details
38
+ const allowedKeys = ['cpf', 'passport', 'rg', 'email', 'phone'];
39
+
33
40
  Object.entries(values).forEach(([key, value]) => {
34
- if (key !== 'email' && key !== identifier_key && value !== undefined) {
35
- details[key] = value as string | number | boolean;
41
+ if (allowedKeys.includes(key.toLowerCase()) && value) {
42
+ if (key !== identifier_key) {
43
+ identifiers.push({ key, value: value as string });
44
+ }
36
45
  }
37
46
  });
38
47
 
48
+ if(identifiersProps.length){
49
+ identifiersProps.forEach((item)=> identifiers.push(item))
50
+ }
51
+
39
52
  return {
40
53
  identifier_key,
41
54
  identifier_value,
42
- details,
55
+ identifiers,
43
56
  };
44
57
  }
45
58
 
@@ -55,7 +68,7 @@ interface AnonymousIdentifier {
55
68
  */
56
69
  async function createAnonymousProfile(
57
70
  payload: CreateAnonymousProfileProps,
58
- ): Promise<void> {
71
+ ): Promise<AnonymousProfileResponse | undefined > {
59
72
  try {
60
73
  validatorService.validateProps(payload, CreateAnonymousProfileSchema);
61
74
 
@@ -64,14 +77,16 @@ async function createAnonymousProfile(
64
77
  const distinctId = mixpanelService.getMixpanelDistinctId();
65
78
 
66
79
  if (userFingerprintId)
67
- identifiers.push({ key: 'fingerprint_id', value: userFingerprintId });
80
+ identifiers.push({ key: 'fingerprint', value: userFingerprintId });
68
81
  if (distinctId) identifiers.push({ key: 'distinct_id', value: distinctId });
69
82
 
70
- const dataPayload = getAnonymousProfilePayload(payload);
71
-
72
- await coreApi.createAnonymousProfile({ ...dataPayload, identifiers });
83
+ const dataPayload = getAnonymousProfilePayload(payload,identifiers);
84
+
85
+ const result = await coreApi.createAnonymousProfile(dataPayload);
86
+ return result.data
73
87
  } catch (error) {
74
88
  console.error('Could not create anonymous profile:', error);
89
+ return undefined
75
90
  }
76
91
  }
77
92
 
@@ -4,6 +4,9 @@ const CreateAnonymousProfileSchema = z
4
4
  .object({
5
5
  email: z.string().email().optional(),
6
6
  phone: z.string().optional(),
7
+ cpf: z.string().optional(),
8
+ passport: z.string().optional(),
9
+ rg: z.string().optional(),
7
10
  })
8
11
  .refine((data) => data.email || data.phone, {
9
12
  message: "At least one of 'email' or 'phone' must be provided",
@@ -9,7 +9,7 @@ const coreAPIConfig = {
9
9
  },
10
10
  },
11
11
  prod: {
12
- coreUrl: 'https://datalake-api-dev.reservamossaas.com/api',
12
+ coreUrl: 'https://data-lake.reservamossaas.com/api',
13
13
  coreVersion: 'v1',
14
14
  headers: {
15
15
  Origin: origin,
@@ -68,3 +68,14 @@ export const arrayField = <T>(
68
68
 
69
69
  return arraySchema;
70
70
  };
71
+
72
+ /**
73
+ * Creates a Zod schema for a boolean field with a custom error message.
74
+ * @param {string} fieldName - The name of the field to be validated.
75
+ * @returns {z.ZodBoolean} A Zod schema for boolean validation.
76
+ */
77
+ export const booleanField = (fieldName: string) =>
78
+ z.boolean({
79
+ required_error: `${fieldName} is required`,
80
+ invalid_type_error: `${fieldName} must be a boolean`,
81
+ });
@@ -0,0 +1,12 @@
1
+ import { z } from 'zod';
2
+
3
+ const USER_STATUSES = ['GUEST', 'LOGGED', 'NEW_USER'] as const;
4
+ type UserStatusType = (typeof USER_STATUSES)[number];
5
+
6
+ const userStatusValidation = z
7
+ .enum(USER_STATUSES)
8
+ .refine((val): val is UserStatusType => USER_STATUSES.includes(val), {
9
+ message: `User Status must be one of: ${USER_STATUSES.join(', ')}`,
10
+ });
11
+
12
+ export default userStatusValidation;