@reservamos/browser-analytics 1.0.3 → 1.0.5

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": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/reservamos/reservamos-browser-analytics.git"
@@ -1,5 +1,5 @@
1
1
  import type { EventData, EventMetadata } from '@/types/eventData';
2
- import { trackEvent } from '@/track';
2
+ import { trackEvent, trackEventError } from '@/track';
3
3
  import { eventNameSchema } from './customEventSchema';
4
4
 
5
5
  /**
@@ -18,7 +18,7 @@ function trackCustomEvent(
18
18
  trackEvent(eventName, eventData, meta);
19
19
  } catch (error) {
20
20
  console.error('Error trackCustomEvent:', error);
21
- return;
21
+ trackEventError(eventName, error);
22
22
  }
23
23
  }
24
24
 
@@ -1,5 +1,6 @@
1
1
  import createAnonymousProfile from '@/profiles/createAnonymousProfile';
2
2
  import validatorService from '@/services/validator';
3
+ import { trackEventError } from '@/track';
3
4
  import fingerprintService from '../../services/fingerprint';
4
5
  import mixpanelService from '../../services/mixpanel';
5
6
  import { DefaultProperties } from './identifySchema';
@@ -70,8 +71,8 @@ async function identify(
70
71
  }
71
72
  const anonymousProfile = await createAnonymousProfile(properties);
72
73
 
73
- if(anonymousProfile){
74
- properties.reservamos_one_id= anonymousProfile.id
74
+ if (anonymousProfile) {
75
+ properties.reservamos_one_id = anonymousProfile.id;
75
76
  }
76
77
  const mappedProps = mapProperties(properties);
77
78
  mixpanelService.identify(userId, mappedProps);
@@ -81,6 +82,7 @@ async function identify(
81
82
  }
82
83
  } catch (error) {
83
84
  console.error('Error identifying user', error);
85
+ trackEventError('Identify', error);
84
86
  }
85
87
  }
86
88
 
@@ -0,0 +1,4 @@
1
+ import validatorService, { eventSchemas, InitConfigSchema } from './validator';
2
+
3
+ export { InitConfigSchema, eventSchemas };
4
+ export default validatorService;
@@ -0,0 +1,41 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { customEventSchema } from '@/events/customEvent';
3
+ import validatorService, { eventSchemas } from './validator';
4
+
5
+ describe('parseEventProps', () => {
6
+ /**
7
+ * This test supposes that unknownEvent is not a known event.
8
+ * And that the customEventSchema does not support objects as values for a field.
9
+ */
10
+ it('Should use the customEventSchema if the event name is not a known event.', () => {
11
+ const customEventName = 'unknownEvent';
12
+ const invalidCustomEventData = {
13
+ test: {
14
+ test: 'test',
15
+ },
16
+ };
17
+ expect(Object.keys(eventSchemas).includes(customEventName)).toBe(false);
18
+ expect(() =>
19
+ validatorService.validateProps(invalidCustomEventData, customEventSchema),
20
+ ).toThrow();
21
+ expect(() =>
22
+ validatorService.parseEventProps(customEventName, invalidCustomEventData),
23
+ ).toThrow();
24
+ });
25
+
26
+ /**
27
+ * This test supposes that all known event schema validations
28
+ * will fail if the event data is empty.
29
+ */
30
+ it('Should use the known event schema if the event name is a known event.', () => {
31
+ const invalidKnownEventData = {};
32
+ Object.entries(eventSchemas).forEach(([eventName, eventSchema]) => {
33
+ expect(() =>
34
+ validatorService.validateProps(invalidKnownEventData, eventSchema),
35
+ ).toThrow();
36
+ expect(() =>
37
+ validatorService.parseEventProps(eventName, invalidKnownEventData),
38
+ ).toThrow();
39
+ });
40
+ });
41
+ });
@@ -11,8 +11,7 @@ import { searchSchema } from '@/events/search';
11
11
  import { seatChangeSchema } from '@/events/seatChange';
12
12
  import { viewResultsSchema } from '@/events/viewResults';
13
13
 
14
- const TrackTestEventSchema = z.object({}); // Allow empty object for track test event
15
- export const InitConfigSchema = z.object({
14
+ const InitConfigSchema = z.object({
16
15
  /**
17
16
  * The Mixpanel token used for authenticating API requests.
18
17
  */
@@ -40,6 +39,7 @@ export const InitConfigSchema = z.object({
40
39
  */
41
40
  identifyProxyUrl: z.string().optional(),
42
41
  });
42
+
43
43
  interface CustomError {
44
44
  field: string;
45
45
  error_type: string;
@@ -48,6 +48,7 @@ interface CustomError {
48
48
  message: string;
49
49
  suggestion: string;
50
50
  }
51
+
51
52
  // Error formatting
52
53
  const SchemaErrorFormatter = (error: ZodError): CustomError[] => {
53
54
  return error.issues.map((issue) => {
@@ -84,7 +85,6 @@ const SchemaErrorFormatter = (error: ZodError): CustomError[] => {
84
85
 
85
86
  // Mapping event names to Zod schemas
86
87
  const eventSchemas: Record<string, z.ZodSchema> = {
87
- 'Track Test': TrackTestEventSchema,
88
88
  'Search': searchSchema,
89
89
  'Seat Change': seatChangeSchema,
90
90
  'Interest In Home': interestInHomeSchema,
@@ -109,10 +109,6 @@ type EventDataSchema = z.infer<
109
109
  function parseEventProps(eventName: string, eventData: EventDataSchema): void {
110
110
  const eventSchema = eventSchemas[eventName] || customEventSchema;
111
111
 
112
- if (!eventSchema) {
113
- throw { message: `Event ${eventName} not found` };
114
- }
115
-
116
112
  try {
117
113
  eventSchema.parse(eventData);
118
114
  } catch (error) {
@@ -167,5 +163,5 @@ const validatorService = {
167
163
  validateProps,
168
164
  };
169
165
 
170
- // Export the validator object
166
+ export { InitConfigSchema, eventSchemas };
171
167
  export default validatorService;
package/src/track.ts CHANGED
@@ -63,6 +63,23 @@ function flattenEventData(data: object): EventData {
63
63
  }, {} as EventData);
64
64
  }
65
65
 
66
+ /**
67
+ * Send an error event to Mixpanel when an event fails to track.
68
+ * The event contains the event name, error message, and validation errors.
69
+ */
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ export function trackEventError(eventName: string, error: any): void {
72
+ try {
73
+ mixpanelService.track('Track Event Error', {
74
+ 'Failed Event Name': eventName,
75
+ 'Error Message': error?.message ?? 'Failed to track event',
76
+ 'Validation Errors': error?.errors || [],
77
+ });
78
+ } catch (trackingError) {
79
+ console.error('Failed to track error event:', trackingError);
80
+ }
81
+ }
82
+
66
83
  /**
67
84
  * Base function to track events with Mixpanel.
68
85
  * This function adds default properties like User Fingerprint.
@@ -101,6 +118,7 @@ export async function trackEvent(
101
118
  mixpanelService.track(eventName, properties);
102
119
  } catch (error) {
103
120
  console.error(`Error tracking event '${eventName}':`, error);
121
+ trackEventError(eventName, error);
104
122
  }
105
123
  }
106
124