@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/dist/browser-analytics.cjs +1 -1
- package/dist/browser-analytics.cjs.map +1 -1
- package/dist/browser-analytics.esm.js +14 -6
- package/dist/browser-analytics.esm.js.map +1 -1
- package/dist/browser-analytics.iife.js +1 -1
- package/dist/browser-analytics.iife.js.map +1 -1
- package/package.json +1 -1
- package/src/events/customEvent/trackCustomEvent.ts +2 -2
- package/src/events/identify/identify.ts +4 -2
- package/src/services/validator/index.ts +4 -0
- package/src/services/validator/validator.test.ts +41 -0
- package/src/services/{validator.ts → validator/validator.ts} +4 -8
- package/src/track.ts +18 -0
package/package.json
CHANGED
|
@@ -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
|
-
|
|
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,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
|
|
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
|
-
|
|
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
|
|