@reservamos/browser-analytics 0.1.4-alpha.9 → 0.2.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/browser-analytics.cjs +4 -3
- package/dist/browser-analytics.cjs.map +1 -0
- package/dist/browser-analytics.d.ts +429 -166
- package/dist/browser-analytics.esm.js +2823 -224
- package/dist/browser-analytics.esm.js.map +1 -0
- package/dist/browser-analytics.iife.js +4 -3
- package/dist/browser-analytics.iife.js.map +1 -0
- package/package.json +2 -1
- package/src/events/customEvent/customEventSchema.ts +19 -0
- package/src/events/customEvent/index.ts +7 -0
- package/src/events/customEvent/trackCustomEvent.ts +19 -0
- package/src/events/identify/identify.ts +17 -10
- package/src/events/identify/identifySchema.ts +2 -1
- package/src/events/identify/index.ts +3 -1
- package/src/events/interestInHome/trackInterestInHome.ts +7 -2
- package/src/events/interestInSearch/trackInterestInSearch.ts +7 -2
- package/src/events/passengersCreated/passengersCreatedSchema.ts +11 -48
- package/src/events/passengersCreated/trackPassengersCreated.ts +12 -3
- package/src/events/paymentAttempt/paymentAttemptSchema.ts +12 -45
- package/src/events/pickedDeparture/pickedDepartureSchema.ts +2 -9
- package/src/events/pickedDeparture/trackPickedDeparture.ts +7 -2
- package/src/events/purchaseAttempt/purchaseAttemptSchema.ts +6 -66
- package/src/events/purchaseAttempt/trackPurchaseAttempt.ts +8 -3
- package/src/events/search/trackSearch.ts +4 -2
- package/src/events/seatChange/trackSeatChange.ts +12 -3
- package/src/events/sharedSchemas/tripSchema.ts +42 -0
- package/src/events/viewResults/trackViewResults.ts +7 -2
- package/src/index.ts +17 -0
- package/src/init.ts +20 -3
- package/src/js-api-client.d.ts +15 -0
- package/src/profiles/createAnonymousProfile/createAnonymousProfile.test.ts +38 -0
- package/src/profiles/createAnonymousProfile/createAnonymousProfile.ts +78 -0
- package/src/profiles/createAnonymousProfile/createAnonymousProfileSchema.ts +15 -0
- package/src/profiles/createAnonymousProfile/index.ts +5 -0
- package/src/services/config.ts +24 -0
- package/src/services/fingerprint.ts +38 -2
- package/src/services/mixpanel.ts +21 -1
- package/src/services/validator.ts +21 -4
- package/src/track.ts +39 -5
- package/src/types/eventData.ts +5 -0
- package/src/util/primitiveFields.ts +70 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reservamos/browser-analytics",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/reservamos/reservamos-browser-analytics.git"
|
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
"typings": "./dist/reservamos-browser-analytics.d.ts",
|
|
87
87
|
"dependencies": {
|
|
88
88
|
"@fingerprintjs/fingerprintjs-pro-spa": "^1.3.2",
|
|
89
|
+
"@reservamos/js-api-client": "5.26.0",
|
|
89
90
|
"mixpanel-browser": "^2.55.1",
|
|
90
91
|
"zod": "^3.23.8"
|
|
91
92
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
const allowedPrimitiveSchema = z.union([
|
|
4
|
+
z.string(),
|
|
5
|
+
z.boolean(),
|
|
6
|
+
z.number(),
|
|
7
|
+
z.undefined(),
|
|
8
|
+
]);
|
|
9
|
+
|
|
10
|
+
const customEventSchema = z.record(
|
|
11
|
+
z.string(),
|
|
12
|
+
z.union([allowedPrimitiveSchema, z.array(allowedPrimitiveSchema)]),
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
type CustomEventProps = z.infer<typeof customEventSchema>;
|
|
16
|
+
|
|
17
|
+
const eventNameSchema = z.string().min(1, 'Event name is required');
|
|
18
|
+
export type { CustomEventProps };
|
|
19
|
+
export {customEventSchema, eventNameSchema} ;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CustomEventProps } from './customEventSchema';
|
|
2
|
+
import { customEventSchema } from './customEventSchema';
|
|
3
|
+
import trackCustomEvent from './trackCustomEvent';
|
|
4
|
+
|
|
5
|
+
export type { CustomEventProps };
|
|
6
|
+
export { customEventSchema };
|
|
7
|
+
export default trackCustomEvent;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { trackEvent } from '@/track';
|
|
2
|
+
import EventData from '@/types/eventData';
|
|
3
|
+
import { eventNameSchema } from './customEventSchema';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Tracks a custom event with any event name, data, and metadata.
|
|
7
|
+
* @param {string} eventName - The name of the custom event.
|
|
8
|
+
* @param {EventData} eventData - Additional data to include in the event.
|
|
9
|
+
*/
|
|
10
|
+
function trackCustomEvent(eventName: string, eventData: EventData = {}): void {
|
|
11
|
+
try {
|
|
12
|
+
eventNameSchema.parse(eventName);
|
|
13
|
+
trackEvent(eventName, eventData);
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.error('Error trackCustomEvent:', error);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export default trackCustomEvent;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import createAnonymousProfile from '@/profiles/createAnonymousProfile';
|
|
1
2
|
import validatorService from '@/services/validator';
|
|
2
3
|
import fingerprintService from '../../services/fingerprint';
|
|
3
4
|
import mixpanelService from '../../services/mixpanel';
|
|
@@ -51,31 +52,37 @@ function mapProperties(properties: UserProperties): Record<string, unknown> {
|
|
|
51
52
|
* @throws {Error} If analytics service is not initialized or userId is missing.
|
|
52
53
|
* @returns {Promise<void>}
|
|
53
54
|
*/
|
|
54
|
-
|
|
55
|
+
async function identify(
|
|
55
56
|
userId: string,
|
|
56
57
|
properties: UserProperties = {},
|
|
57
58
|
): Promise<void> {
|
|
58
|
-
if (!mixpanelService.isReady()) {
|
|
59
|
-
throw new Error('Analytics service is not initialized');
|
|
60
|
-
}
|
|
61
|
-
|
|
62
59
|
try {
|
|
60
|
+
if (!mixpanelService.isReady()) {
|
|
61
|
+
console.error('Mixpanel is not initialized.');
|
|
62
|
+
throw new Error('Mixpanel is not initialized.');
|
|
63
|
+
}
|
|
64
|
+
|
|
63
65
|
validatorService.parseIdentifyProps(properties);
|
|
64
66
|
|
|
65
67
|
if (!userId) {
|
|
66
|
-
|
|
68
|
+
console.error('User ID is required for identification.');
|
|
69
|
+
throw new Error('User ID is required for identification.');
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
const mappedProps = mapProperties(properties);
|
|
70
|
-
|
|
71
73
|
mixpanelService.identify(userId, mappedProps);
|
|
72
|
-
|
|
73
74
|
const fingerprint = await fingerprintService.getFingerprint();
|
|
74
|
-
|
|
75
75
|
if (fingerprint) {
|
|
76
76
|
mixpanelService.attachProperty(FINGERPRINT_PROPERTY, fingerprint);
|
|
77
77
|
}
|
|
78
78
|
} catch (error) {
|
|
79
|
-
console.error('Error
|
|
79
|
+
console.error('Error identifying user', error);
|
|
80
|
+
} finally {
|
|
81
|
+
createAnonymousProfile({
|
|
82
|
+
email: properties.email,
|
|
83
|
+
phone: properties.phone,
|
|
84
|
+
});
|
|
80
85
|
}
|
|
81
86
|
}
|
|
87
|
+
|
|
88
|
+
export default identify;
|
|
@@ -10,6 +10,7 @@ const IdentifySchema = z.object({
|
|
|
10
10
|
.optional(),
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
type DefaultProperties = z.infer<typeof IdentifySchema>;
|
|
14
14
|
|
|
15
|
+
export type { DefaultProperties };
|
|
15
16
|
export default IdentifySchema;
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import type { InterestInHomeProps } from './interestInHomeSchema';
|
|
2
2
|
import { trackEvent } from '@/track';
|
|
3
|
+
import EventData from '@/types/eventData';
|
|
3
4
|
|
|
4
5
|
const EVENT_NAME = 'Interest In Home';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Tracks a Interest In Home event.
|
|
8
9
|
* @param {InterestInHomeProps} eventData - The data associated with the Interest In Home event.
|
|
10
|
+
* @param {EventData} meta - Additional metadata to include in the event.
|
|
9
11
|
*/
|
|
10
|
-
function trackInterestInHome(
|
|
11
|
-
|
|
12
|
+
function trackInterestInHome(
|
|
13
|
+
eventData: InterestInHomeProps,
|
|
14
|
+
meta: EventData = {},
|
|
15
|
+
): void {
|
|
16
|
+
trackEvent(EVENT_NAME, eventData, meta);
|
|
12
17
|
}
|
|
13
18
|
|
|
14
19
|
export default trackInterestInHome;
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import type { InterestInSearchProps } from './interestInSearchSchema';
|
|
2
2
|
import { trackEvent } from '@/track';
|
|
3
|
+
import EventData from '@/types/eventData';
|
|
3
4
|
|
|
4
5
|
const EVENT_NAME = 'Interest In Search';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Tracks a Interest In Search event.
|
|
8
9
|
* @param {InterestInSearchProps} eventData - The data associated with the Interest In Search event.
|
|
10
|
+
* @param {EventData} meta - Additional metadata to include in the event.
|
|
9
11
|
*/
|
|
10
|
-
function trackInterestInSearch(
|
|
11
|
-
|
|
12
|
+
function trackInterestInSearch(
|
|
13
|
+
eventData: InterestInSearchProps,
|
|
14
|
+
meta: EventData = {},
|
|
15
|
+
): void {
|
|
16
|
+
trackEvent(EVENT_NAME, eventData, meta);
|
|
12
17
|
}
|
|
13
18
|
|
|
14
19
|
export default trackInterestInSearch;
|
|
@@ -1,54 +1,17 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import
|
|
2
|
+
import { arrayField, intField, numberField } from '@/util/primitiveFields';
|
|
3
3
|
import productValidation from '@/util/productValidation';
|
|
4
|
+
import tripSchema from '../sharedSchemas/tripSchema';
|
|
4
5
|
|
|
5
|
-
const passengersCreatedSchema = z
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
.string()
|
|
15
|
-
.min(1, 'Departure Destination Terminal is required'),
|
|
16
|
-
'Departure Line': z.string().min(1, 'Departure Line is required'),
|
|
17
|
-
'Departure Origin': z.string().min(1, 'Departure Origin is required'),
|
|
18
|
-
'Departure Origin Terminal': z
|
|
19
|
-
.string()
|
|
20
|
-
.min(1, 'Departure Origin Terminal is required'),
|
|
21
|
-
'Departure Price': z
|
|
22
|
-
.number()
|
|
23
|
-
.positive('Departure Price must be a positive number'),
|
|
24
|
-
'Departure Route': z.string().min(1, 'Departure Route is required'),
|
|
25
|
-
'Departure Stops': z
|
|
26
|
-
.number()
|
|
27
|
-
.int('Departure Stops must be an integer')
|
|
28
|
-
.nonnegative()
|
|
29
|
-
.optional(),
|
|
30
|
-
'Departure Time': z.string().refine(dateValidation, {
|
|
31
|
-
message:
|
|
32
|
-
'Invalid departure time datetime format. Must include at least YYYY-MM-DD',
|
|
33
|
-
}),
|
|
34
|
-
'Departure Transporter': z
|
|
35
|
-
.string()
|
|
36
|
-
.min(1, 'Departure Transporter is required'),
|
|
37
|
-
'Passenger Count': z
|
|
38
|
-
.number()
|
|
39
|
-
.int('Passenger Count must be an integer')
|
|
40
|
-
.positive(),
|
|
41
|
-
'Recommended Trip': z.boolean(),
|
|
42
|
-
'Recommended Trip Type': z.string().optional(),
|
|
43
|
-
'Routes': z.number().int('Routes must be an integer').positive(),
|
|
44
|
-
'Total': z.number().positive('Total must be a positive number'),
|
|
45
|
-
'Trip Length': z
|
|
46
|
-
.number()
|
|
47
|
-
.int('Trip Length must be an integer')
|
|
48
|
-
.nonnegative()
|
|
49
|
-
.optional(),
|
|
50
|
-
'product': productValidation,
|
|
51
|
-
});
|
|
6
|
+
const passengersCreatedSchema = z
|
|
7
|
+
.object({
|
|
8
|
+
'Trips': arrayField(tripSchema, 'Trips', 1),
|
|
9
|
+
'Passenger Count': intField('Passenger Count'),
|
|
10
|
+
'Trip Count': intField('Trip Count').optional(),
|
|
11
|
+
'Total': numberField('Total'),
|
|
12
|
+
'product': productValidation,
|
|
13
|
+
})
|
|
14
|
+
.strict();
|
|
52
15
|
|
|
53
16
|
type PassengersCreatedProps = z.infer<typeof passengersCreatedSchema>;
|
|
54
17
|
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import type { PassengersCreatedProps } from './passengersCreatedSchema';
|
|
2
2
|
import { trackEvent } from '@/track';
|
|
3
|
+
import EventData from '@/types/eventData';
|
|
3
4
|
|
|
4
5
|
const EVENT_NAME = 'Passengers Created';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
7
|
+
/**
|
|
8
|
+
* Tracks a Passengers Created event.
|
|
9
|
+
* @param {PassengersCreatedProps} eventProps - The data associated with the Passengers Created event.
|
|
10
|
+
* @param {EventData} meta - Additional metadata to include in the event.
|
|
11
|
+
*/
|
|
12
|
+
function trackPassengersCreated(
|
|
13
|
+
eventProps: PassengersCreatedProps,
|
|
14
|
+
meta: EventData = {},
|
|
15
|
+
): void {
|
|
16
|
+
trackEvent(EVENT_NAME, eventProps, meta);
|
|
17
|
+
}
|
|
9
18
|
|
|
10
19
|
export default trackPassengersCreated;
|
|
@@ -1,51 +1,18 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import
|
|
2
|
+
import { arrayField, intField, numberField } from '@/util/primitiveFields';
|
|
3
3
|
import productValidation from '@/util/productValidation';
|
|
4
|
+
import tripSchema from '../sharedSchemas/tripSchema';
|
|
4
5
|
|
|
5
|
-
const paymentAttemptSchema = z
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
.min(1, 'Departure Destination Terminal is required'),
|
|
16
|
-
'Departure Line': z.string().min(1, 'Departure Line is required'),
|
|
17
|
-
'Departure Origin': z.string().min(1, 'Departure Origin is required'),
|
|
18
|
-
'Departure Origin Terminal': z
|
|
19
|
-
.string()
|
|
20
|
-
.min(1, 'Departure Origin Terminal is required'),
|
|
21
|
-
'Departure Price': z
|
|
22
|
-
.number()
|
|
23
|
-
.positive('Departure Price must be a positive number'),
|
|
24
|
-
'Departure Route': z.string().min(1, 'Departure Route is required'),
|
|
25
|
-
'Departure Stop Cities': z.string().optional(),
|
|
26
|
-
'Departure Stops': z
|
|
27
|
-
.number()
|
|
28
|
-
.int('Departure Stops must be an integer')
|
|
29
|
-
.nonnegative()
|
|
30
|
-
.optional(),
|
|
31
|
-
'Departure Time': z.string().refine(dateValidation, {
|
|
32
|
-
message:
|
|
33
|
-
'Invalid departure time datetime format. Must include at least YYYY-MM-DD',
|
|
34
|
-
}),
|
|
35
|
-
'Departure Transporter': z
|
|
36
|
-
.string()
|
|
37
|
-
.min(1, 'Departure Transporter is required'),
|
|
38
|
-
'Passenger Count': z
|
|
39
|
-
.number()
|
|
40
|
-
.int('Passenger Count must be an integer')
|
|
41
|
-
.positive(),
|
|
42
|
-
'Payment Type': z.string().min(1, 'Payment Type is required'),
|
|
43
|
-
'Recommended Trip': z.boolean(),
|
|
44
|
-
'Recommended Trip Type': z.string().optional(),
|
|
45
|
-
'Routes': z.number().int('Routes must be an integer').positive(),
|
|
46
|
-
'Total': z.number().positive('Total must be a positive number'),
|
|
47
|
-
'product': productValidation,
|
|
48
|
-
});
|
|
6
|
+
const paymentAttemptSchema = z
|
|
7
|
+
.object({
|
|
8
|
+
'Trips': arrayField(tripSchema, 'Trips', 1),
|
|
9
|
+
'Passenger Count': intField('Passenger Count'),
|
|
10
|
+
'Trip Count': intField('Trip Count'),
|
|
11
|
+
'Payment Type': z.string().min(1, 'Payment Type is required'),
|
|
12
|
+
'Total': numberField('Total'),
|
|
13
|
+
'product': productValidation,
|
|
14
|
+
})
|
|
15
|
+
.strict();
|
|
49
16
|
|
|
50
17
|
type PaymentAttemptProps = z.infer<typeof paymentAttemptSchema>;
|
|
51
18
|
|
|
@@ -24,15 +24,8 @@ const pickedDepartureSchema = z.object({
|
|
|
24
24
|
'Transport Type': z.string().min(1, 'Transport Type is required'),
|
|
25
25
|
'Transporter': z.string().min(1, 'Transporter is required'),
|
|
26
26
|
'product': productValidation,
|
|
27
|
-
'Recommended Trip': z.boolean()
|
|
28
|
-
|
|
29
|
-
}),
|
|
30
|
-
'Recommended Trip Type': z
|
|
31
|
-
.string()
|
|
32
|
-
.or(z.null())
|
|
33
|
-
.refine((val) => val === null || typeof val === 'string', {
|
|
34
|
-
message: 'Recommended Trip Type must be a string or null',
|
|
35
|
-
}),
|
|
27
|
+
'Recommended Trip': z.boolean(),
|
|
28
|
+
'Recommended Trip Type': z.string().optional(),
|
|
36
29
|
});
|
|
37
30
|
|
|
38
31
|
type PickedDepartureProps = z.infer<typeof pickedDepartureSchema>;
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import type { PickedDepartureProps } from './pickedDepartureSchema';
|
|
2
2
|
import { trackEvent } from '@/track';
|
|
3
|
+
import EventData from '@/types/eventData';
|
|
3
4
|
|
|
4
5
|
const EVENT_NAME = 'Picked Departure';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Tracks a Picked Departure event.
|
|
8
9
|
* @param {PickedDepartureProps} eventData - The data associated with the Picked Departure event.
|
|
10
|
+
* @param {EventData} meta - Additional metadata to include in the event.
|
|
9
11
|
*/
|
|
10
|
-
function trackSearch(
|
|
11
|
-
|
|
12
|
+
function trackSearch(
|
|
13
|
+
eventData: PickedDepartureProps,
|
|
14
|
+
meta: EventData = {},
|
|
15
|
+
): void {
|
|
16
|
+
trackEvent(EVENT_NAME, eventData, meta);
|
|
12
17
|
}
|
|
13
18
|
|
|
14
19
|
export default trackSearch;
|
|
@@ -1,75 +1,15 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import
|
|
2
|
+
import { arrayField, intField, numberField } from '@/util/primitiveFields';
|
|
3
3
|
import productValidation from '@/util/productValidation';
|
|
4
|
+
import tripSchema from '../sharedSchemas/tripSchema';
|
|
4
5
|
|
|
5
6
|
const purchaseAttemptSchema = z
|
|
6
7
|
.object({
|
|
7
|
-
'
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
'
|
|
11
|
-
message: 'Departure Destination must be a string',
|
|
12
|
-
}),
|
|
13
|
-
'Departure Destination Terminal': z.string().refine((val) => val, {
|
|
14
|
-
message: 'Departure Destination Terminal must be a string',
|
|
15
|
-
}),
|
|
16
|
-
'Departure Line': z.string().refine((val) => val, {
|
|
17
|
-
message: 'Departure Line must be a string',
|
|
18
|
-
}),
|
|
19
|
-
'Departure Origin': z.string().refine((val) => val, {
|
|
20
|
-
message: 'Departure Origin must be a string',
|
|
21
|
-
}),
|
|
22
|
-
'Departure Origin Terminal': z.string().refine((val) => val, {
|
|
23
|
-
message: 'Departure Origin Terminal must be a string',
|
|
24
|
-
}),
|
|
25
|
-
'Departure Price': z.number().refine((val) => val, {
|
|
26
|
-
message: 'Departure Price must be a number',
|
|
27
|
-
}),
|
|
28
|
-
'Departure Route': z.string().refine((val) => val, {
|
|
29
|
-
message: 'Departure Route must be a string',
|
|
30
|
-
}),
|
|
31
|
-
'Departure Stops': z
|
|
32
|
-
.number()
|
|
33
|
-
.int()
|
|
34
|
-
.refine((val) => val, {
|
|
35
|
-
message: 'Departure Stops must be an integer',
|
|
36
|
-
}),
|
|
37
|
-
'Departure Time': z.string().refine(dateValidation, {
|
|
38
|
-
message: 'Invalid departure time datetime format',
|
|
39
|
-
}),
|
|
40
|
-
'Departure Transport Type': z.string().refine((val) => val, {
|
|
41
|
-
message: 'Departure Transport Type must be a string',
|
|
42
|
-
}),
|
|
43
|
-
'Departure Transporter': z.string().refine((val) => val, {
|
|
44
|
-
message: 'Departure Transporter must be a string',
|
|
45
|
-
}),
|
|
46
|
-
'Passenger Count': z
|
|
47
|
-
.number()
|
|
48
|
-
.int()
|
|
49
|
-
.refine((val) => val, {
|
|
50
|
-
message: 'Passenger Count must be an integer',
|
|
51
|
-
}),
|
|
52
|
-
'Recommended Trip': z.boolean().refine((val) => val, {
|
|
53
|
-
message: 'Recommended Trip must be a boolean',
|
|
54
|
-
}),
|
|
55
|
-
'Recommended Trip Type': z
|
|
56
|
-
.string()
|
|
57
|
-
.or(z.null())
|
|
58
|
-
.refine((val) => val === null || typeof val === 'string', {
|
|
59
|
-
message: 'Recommended Trip Type must be a string or null',
|
|
60
|
-
})
|
|
61
|
-
.optional(),
|
|
62
|
-
'Routes': z
|
|
63
|
-
.number()
|
|
64
|
-
.int()
|
|
65
|
-
.refine((val) => val, {
|
|
66
|
-
message: 'Routes must be an integer',
|
|
67
|
-
}),
|
|
68
|
-
'Total': z.number().refine((val) => val, {
|
|
69
|
-
message: 'Total must be a number',
|
|
70
|
-
}),
|
|
8
|
+
'Trips': arrayField(tripSchema, 'Trips', 1),
|
|
9
|
+
'Passenger Count': intField('Passenger Count'),
|
|
10
|
+
'Trip Count': intField('Trip Count'),
|
|
11
|
+
'Total': numberField('Total'),
|
|
71
12
|
'product': productValidation,
|
|
72
|
-
'Trip Length': z.number().int().optional(),
|
|
73
13
|
})
|
|
74
14
|
.strict();
|
|
75
15
|
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import type { PurchaseAttemptProps } from './purchaseAttemptSchema';
|
|
2
2
|
import { trackEvent } from '@/track';
|
|
3
|
+
import EventData from '@/types/eventData';
|
|
3
4
|
|
|
4
5
|
const EVENT_NAME = 'Purchase Attempt';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Tracks a Purchase Attempt event.
|
|
8
9
|
* @param {PurchaseAttemptProps} eventData - The data associated with the Purchase Attempt event.
|
|
10
|
+
* @param {EventData} meta - Additional metadata to include in the event.
|
|
9
11
|
*/
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
+
function trackPurchaseAttempt(
|
|
13
|
+
eventData: PurchaseAttemptProps,
|
|
14
|
+
meta: EventData = {},
|
|
15
|
+
): void {
|
|
16
|
+
trackEvent(EVENT_NAME, eventData, meta);
|
|
12
17
|
}
|
|
13
18
|
|
|
14
|
-
export default
|
|
19
|
+
export default trackPurchaseAttempt;
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import type { SearchProps } from './searchSchema';
|
|
2
2
|
import { trackEvent } from '@/track';
|
|
3
|
+
import EventData from '@/types/eventData';
|
|
3
4
|
|
|
4
5
|
const EVENT_NAME = 'Search';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Tracks a search event.
|
|
8
9
|
* @param {SearchProps} eventData - The data associated with the search event.
|
|
10
|
+
* @param {EventData} meta - Additional metadata to include in the event.
|
|
9
11
|
*/
|
|
10
|
-
function trackSearch(eventData: SearchProps) {
|
|
11
|
-
trackEvent(EVENT_NAME, eventData);
|
|
12
|
+
function trackSearch(eventData: SearchProps, meta: EventData = {}): void {
|
|
13
|
+
trackEvent(EVENT_NAME, eventData, meta);
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export default trackSearch;
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import type { SeatChangeProps } from './seatChangeSchema';
|
|
2
2
|
import { trackEvent } from '@/track';
|
|
3
|
+
import EventData from '@/types/eventData';
|
|
3
4
|
|
|
4
5
|
const EVENT_NAME = 'Seat Change';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
7
|
+
/**
|
|
8
|
+
* Tracks a Seat Change event.
|
|
9
|
+
* @param {SeatChangeProps} eventProps - The data associated with the Seat Change event.
|
|
10
|
+
* @param {EventData} meta - Additional metadata to include in the event.
|
|
11
|
+
*/
|
|
12
|
+
function trackSeatChange(
|
|
13
|
+
eventProps: SeatChangeProps,
|
|
14
|
+
meta: EventData = {},
|
|
15
|
+
): void {
|
|
16
|
+
trackEvent(EVENT_NAME, eventProps, meta);
|
|
17
|
+
}
|
|
9
18
|
|
|
10
19
|
export default trackSeatChange;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import {
|
|
3
|
+
dateField,
|
|
4
|
+
intField,
|
|
5
|
+
numberField,
|
|
6
|
+
stringField,
|
|
7
|
+
} from '@/util/primitiveFields';
|
|
8
|
+
|
|
9
|
+
const tripSchema = z.object({
|
|
10
|
+
'Departure Arrival': dateField('Departure Arrival'),
|
|
11
|
+
'Departure Destination': stringField('Departure Destination'),
|
|
12
|
+
'Departure Destination Terminal': stringField(
|
|
13
|
+
'Departure Destination Terminal',
|
|
14
|
+
),
|
|
15
|
+
'Departure Line': stringField('Departure Line'),
|
|
16
|
+
'Departure Origin': stringField('Departure Origin'),
|
|
17
|
+
'Departure Origin Terminal': stringField('Departure Origin Terminal'),
|
|
18
|
+
'Departure Price': numberField('Departure Price'),
|
|
19
|
+
'Departure Route': stringField('Departure Route'),
|
|
20
|
+
'Departure Stops': intField('Departure Stops'),
|
|
21
|
+
'Departure Time': dateField('Departure Time'),
|
|
22
|
+
'Departure Transport Type': stringField('Departure Transport Type'),
|
|
23
|
+
'Departure Transporter': stringField('Departure Transporter'),
|
|
24
|
+
'Return Arrival': dateField('Return Arrival').optional(),
|
|
25
|
+
'Return Destination': stringField('Return Destination').optional(),
|
|
26
|
+
'Return Destination Terminal': stringField(
|
|
27
|
+
'Return Destination Terminal',
|
|
28
|
+
).optional(),
|
|
29
|
+
'Return Line': stringField('Return Line').optional(),
|
|
30
|
+
'Return Origin': stringField('Return Origin').optional(),
|
|
31
|
+
'Return Origin Terminal': stringField('Return Origin Terminal').optional(),
|
|
32
|
+
'Return Price': numberField('Return Price').optional(),
|
|
33
|
+
'Return Route': stringField('Return Route').optional(),
|
|
34
|
+
'Return Stops': intField('Return Stops').optional(),
|
|
35
|
+
'Return Time': dateField('Return Time').optional(),
|
|
36
|
+
'Return Transport Type': stringField('Return Transport Type').optional(),
|
|
37
|
+
'Return Transporter': stringField('Return Transporter').optional(),
|
|
38
|
+
'Recommended Trip': z.boolean(),
|
|
39
|
+
'Recommended Trip Type': stringField('Recommended Trip Type').optional(),
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
export default tripSchema;
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import type { ViewResultsProps } from './viewResultsSchema';
|
|
2
2
|
import { trackEvent } from '@/track';
|
|
3
|
+
import EventData from '@/types/eventData';
|
|
3
4
|
|
|
4
5
|
const EVENT_NAME = 'View Results';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Tracks a View Results event.
|
|
8
9
|
* @param {ViewResultsProps} eventData - The data associated with the View Results event.
|
|
10
|
+
* @param {EventData} meta - Additional metadata to include in the event.
|
|
9
11
|
*/
|
|
10
|
-
function trackViewResults(
|
|
11
|
-
|
|
12
|
+
function trackViewResults(
|
|
13
|
+
eventData: ViewResultsProps,
|
|
14
|
+
meta: EventData = {},
|
|
15
|
+
): void {
|
|
16
|
+
trackEvent(EVENT_NAME, eventData, meta);
|
|
12
17
|
}
|
|
13
18
|
|
|
14
19
|
export default trackViewResults;
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CustomEventProps } from '@/events/customEvent';
|
|
1
2
|
import type { InterestInHomeProps } from '@/events/interestInHome';
|
|
2
3
|
import type { InterestInSearchProps } from '@/events/interestInSearch';
|
|
3
4
|
import type { PassengersCreatedProps } from '@/events/passengersCreated';
|
|
@@ -7,6 +8,8 @@ import type { PurchaseAttemptProps } from '@/events/purchaseAttempt';
|
|
|
7
8
|
import type { SearchProps } from '@/events/search';
|
|
8
9
|
import type { SeatChangeProps } from '@/events/seatChange';
|
|
9
10
|
import type { ViewResultsProps } from '@/events/viewResults';
|
|
11
|
+
import type { CreateAnonymousProfileProps } from '@/profiles/createAnonymousProfile';
|
|
12
|
+
import trackCustomEvent from '@/events/customEvent';
|
|
10
13
|
import identify from '@/events/identify';
|
|
11
14
|
import trackInterestInHome from '@/events/interestInHome';
|
|
12
15
|
import trackInterestInSearch from '@/events/interestInSearch';
|
|
@@ -19,10 +22,21 @@ import trackSeatChange from '@/events/seatChange';
|
|
|
19
22
|
import trackTest from '@/events/test';
|
|
20
23
|
import trackViewResults from '@/events/viewResults';
|
|
21
24
|
import { init } from '@/init';
|
|
25
|
+
import createAnonymousProfile from '@/profiles/createAnonymousProfile';
|
|
26
|
+
import fingerprintService from '@/services/fingerprint';
|
|
27
|
+
import mixpanelService from '@/services/mixpanel';
|
|
28
|
+
import './js-api-client.d.ts';
|
|
22
29
|
|
|
23
30
|
const analytics = {
|
|
24
31
|
init,
|
|
25
32
|
identify,
|
|
33
|
+
identifiers: {
|
|
34
|
+
getFingerprintId: fingerprintService.getCachedFingerprint,
|
|
35
|
+
getDistinctId: mixpanelService.getMixpanelDistinctId,
|
|
36
|
+
},
|
|
37
|
+
profiles: {
|
|
38
|
+
createAnonymousProfile,
|
|
39
|
+
},
|
|
26
40
|
track: {
|
|
27
41
|
test: trackTest,
|
|
28
42
|
search: trackSearch,
|
|
@@ -34,6 +48,7 @@ const analytics = {
|
|
|
34
48
|
paymentAttempt: trackPaymentAttempt,
|
|
35
49
|
purchaseAttempt: trackPurchaseAttempt,
|
|
36
50
|
pickedDeparture: trackPickedDeparture,
|
|
51
|
+
customEvent: trackCustomEvent,
|
|
37
52
|
},
|
|
38
53
|
};
|
|
39
54
|
|
|
@@ -47,5 +62,7 @@ export type {
|
|
|
47
62
|
InterestInSearchProps,
|
|
48
63
|
PurchaseAttemptProps,
|
|
49
64
|
PickedDepartureProps,
|
|
65
|
+
CustomEventProps,
|
|
66
|
+
CreateAnonymousProfileProps,
|
|
50
67
|
};
|
|
51
68
|
export default analytics;
|