@useblu/blu-lytics 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/LICENSE +21 -0
- package/README.md +105 -0
- package/lib/dispatchers/dispatchers.spec.d.ts +2 -0
- package/lib/dispatchers/dispatchers.spec.d.ts.map +1 -0
- package/lib/dispatchers/dispatchers.spec.js +36 -0
- package/lib/dispatchers/dispatchers.types.d.ts +17 -0
- package/lib/dispatchers/dispatchers.types.d.ts.map +1 -0
- package/lib/dispatchers/dispatchers.types.js +1 -0
- package/lib/dispatchers/index.d.ts +13 -0
- package/lib/dispatchers/index.d.ts.map +1 -0
- package/lib/dispatchers/index.js +56 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +2 -0
- package/lib/initializers/index.d.ts +21 -0
- package/lib/initializers/index.d.ts.map +1 -0
- package/lib/initializers/index.js +130 -0
- package/lib/initializers/initializers.spec.d.ts +2 -0
- package/lib/initializers/initializers.spec.d.ts.map +1 -0
- package/lib/initializers/initializers.spec.js +39 -0
- package/lib/initializers/initializers.types.d.ts +8 -0
- package/lib/initializers/initializers.types.d.ts.map +1 -0
- package/lib/initializers/initializers.types.js +1 -0
- package/lib/providers/index.d.ts +13 -0
- package/lib/providers/index.d.ts.map +1 -0
- package/lib/providers/index.js +39 -0
- package/lib/providers/provider.types.d.ts +8 -0
- package/lib/providers/provider.types.d.ts.map +1 -0
- package/lib/providers/provider.types.js +1 -0
- package/lib/providers/setups/clarity/clarity.d.ts +4 -0
- package/lib/providers/setups/clarity/clarity.d.ts.map +1 -0
- package/lib/providers/setups/clarity/clarity.js +17 -0
- package/lib/providers/setups/fullstory/fullstory.d.ts +4 -0
- package/lib/providers/setups/fullstory/fullstory.d.ts.map +1 -0
- package/lib/providers/setups/fullstory/fullstory.js +18 -0
- package/lib/providers/setups/fullstory/fullstory.spec.d.ts +2 -0
- package/lib/providers/setups/fullstory/fullstory.spec.d.ts.map +1 -0
- package/lib/providers/setups/fullstory/fullstory.spec.js +30 -0
- package/lib/providers/setups/mixpanel/mixpanel.d.ts +4 -0
- package/lib/providers/setups/mixpanel/mixpanel.d.ts.map +1 -0
- package/lib/providers/setups/mixpanel/mixpanel.js +35 -0
- package/lib/providers/setups/mixpanel/mixpanel.spec.d.ts +2 -0
- package/lib/providers/setups/mixpanel/mixpanel.spec.d.ts.map +1 -0
- package/lib/providers/setups/mixpanel/mixpanel.spec.js +38 -0
- package/lib/providers/setups/sentry/sentry.d.ts +4 -0
- package/lib/providers/setups/sentry/sentry.d.ts.map +1 -0
- package/lib/providers/setups/sentry/sentry.js +42 -0
- package/lib/providers/setups/sentry/sentry.spec.d.ts +2 -0
- package/lib/providers/setups/sentry/sentry.spec.d.ts.map +1 -0
- package/lib/providers/setups/sentry/sentry.spec.js +56 -0
- package/lib/utils/index.d.ts +3 -0
- package/lib/utils/index.d.ts.map +1 -0
- package/lib/utils/index.js +2 -0
- package/package.json +67 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 BLU
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<h1 align="center">
|
|
2
|
+
<img alt="blu-lytics" src="https://github.com/Pagnet/blu-lytics/assets/102989712/7d06f590-85c6-4373-bec5-c672aa46a68b">
|
|
3
|
+
</h1>
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## How it works
|
|
7
|
+
Main goals include: being the sole entry point, simplifying integration between monitoring tools, and enabling centralized sending of messages and events.
|
|
8
|
+
These goals offer developers the following benefits:
|
|
9
|
+
|
|
10
|
+
- **Unified messages and events** <br>
|
|
11
|
+
Allows messages and events to be propagated across all monitoring tools through a single entry point.
|
|
12
|
+
|
|
13
|
+
- **Centralized and simplified configuration (Zero config)** <br>
|
|
14
|
+
Enables initializing tools by providing only their key or token, without the need for prior configuration, saving time and reducing code.
|
|
15
|
+
|
|
16
|
+
- **Scalability** <br>
|
|
17
|
+
Facilitates the removal or addition of a tool, as the library contains all necessary configuration for operation. Flexibility that enhances the efficiency of monitoring tool management.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
```sh
|
|
22
|
+
yarn add @useblu/blu-lytics
|
|
23
|
+
```
|
|
24
|
+
or
|
|
25
|
+
```sh
|
|
26
|
+
npm i @useblu/blu-lytics
|
|
27
|
+
```
|
|
28
|
+
## Usage
|
|
29
|
+
### Importing Library
|
|
30
|
+
|
|
31
|
+
#### Destructuring the import
|
|
32
|
+
```js
|
|
33
|
+
|
|
34
|
+
import { initializeProviders } from ‘blu-lytics’;
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
#### Importing all functionalities
|
|
38
|
+
```js
|
|
39
|
+
|
|
40
|
+
import * as blu-lytics from ‘blu-lytics’;
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Method: `initializeProviders`
|
|
45
|
+
This method simplifies the connection to one or more monitoring tools, eliminating the need for pre-configurations. Simply provide the name of the tool to be used and its API key 'apiKey'.
|
|
46
|
+
|
|
47
|
+
To establish a connection with a single tool, it is necessary to pass an object as a parameter, containing the fields providerName, apiKey, and another object with the environment (the latter is optional, with the default value being 'production').
|
|
48
|
+
```js
|
|
49
|
+
initializeProviders({providerName: 'track-tool-name', apiKey: 'your-api-key'}, {environment: ‘development’});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
To connect to more than one tool, it is necessary to pass an array (list) of objects as a parameter, maintaining the fields providerName, apiKey, and another object containing environment (optional).
|
|
53
|
+
```js
|
|
54
|
+
initializeProviders([
|
|
55
|
+
{ providerName: 'track-tool-name', apiKey: 'your-api-key'},
|
|
56
|
+
{ providerName: 'another-track-tool-name', apiKey: 'your-api-key'}
|
|
57
|
+
], {environment: ‘development’});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Method: `sendScreenEvent`
|
|
61
|
+
This method sends a message that will be propagated and recorded in all tools that have been previously initialized through the initializeProviders method. To use it, only a string needs to be provided as a parameter.
|
|
62
|
+
```js
|
|
63
|
+
sendScreenEvent(‘page_view’);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Method: `sendCustomEvent`
|
|
67
|
+
This method sends an event with a message and additional optional parameters, which will be propagated and recorded in all tools that have been previously initialized through the initializeProviders method.
|
|
68
|
+
|
|
69
|
+
To use it, two parameters need to be provided: a string to describe the event and an object containing the additional optional fields.
|
|
70
|
+
```js
|
|
71
|
+
sendCustomEvent('your_custom_page', {
|
|
72
|
+
props1: 'any-information',
|
|
73
|
+
props2: true,
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Method: `sendUserIdentification`
|
|
78
|
+
This method sends relevant information related to user identification, such as their name, email, and ID, for example.
|
|
79
|
+
|
|
80
|
+
To use, it is possible to provide two parameters: a string representing a unique identifier and an object containing additional and optional fields.
|
|
81
|
+
```js
|
|
82
|
+
sendUserIdentification('user-id', {
|
|
83
|
+
name: 'user name',
|
|
84
|
+
email: 'user@email.com',
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Supported tracking tools
|
|
89
|
+
- Sentry
|
|
90
|
+
- Fullstory
|
|
91
|
+
- Mixpanel
|
|
92
|
+
|
|
93
|
+
## Incoming Updates
|
|
94
|
+
### - Suport for Microsoft Clarity
|
|
95
|
+
|
|
96
|
+
## Contributing
|
|
97
|
+
Whether you're helping us fix bugs, improve the docs, or spread the word, we'd love to have you as part of this project! Read below to learn how you can take part of it.
|
|
98
|
+
### Code of Conduct
|
|
99
|
+
We adopted a Code of Conduct that we expect project participants to adhere to. Please read [the full text](.github/CODE_OF_CONDUCT.md) so that you can understand what actions will and will not be tolerated.
|
|
100
|
+
### Contributing Guide
|
|
101
|
+
Read our [contributing guide](.github/CONTRIBUTING.md) to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes.
|
|
102
|
+
### Release to NPM
|
|
103
|
+
To release a new version on NPM registry, just bump version on *`package.json`* and merge it into master to automatically publish a new version.
|
|
104
|
+
## License
|
|
105
|
+
All packages are licensed under the terms of the MIT License.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatchers.spec.d.ts","sourceRoot":"","sources":["../../src/dispatchers/dispatchers.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { sendCustomEvent, sendScreenEvent, sendUserIdentification, } from './index';
|
|
2
|
+
jest.mock('../initializers', function () { return ({
|
|
3
|
+
userSelectedEnvironment: 'development'
|
|
4
|
+
}); });
|
|
5
|
+
jest.mock('../providers', function () { return ({
|
|
6
|
+
providersList: [
|
|
7
|
+
{
|
|
8
|
+
screenEvent: jest.fn(),
|
|
9
|
+
customEvent: jest.fn(),
|
|
10
|
+
userIdentification: jest.fn()
|
|
11
|
+
},
|
|
12
|
+
]
|
|
13
|
+
}); });
|
|
14
|
+
jest.mock('../utils', function () { return ({
|
|
15
|
+
isValidProvidersList: jest.fn(function () { return true; })
|
|
16
|
+
}); });
|
|
17
|
+
describe('Event dispatching functions', function () {
|
|
18
|
+
afterEach(function () {
|
|
19
|
+
jest.clearAllMocks();
|
|
20
|
+
});
|
|
21
|
+
it('should be dispatch sendScreenEvent', function () {
|
|
22
|
+
var consoleLogSpy = jest.spyOn(console, 'log');
|
|
23
|
+
sendScreenEvent('TestScreen');
|
|
24
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('[BLUEFIN]: Screen event: TestScreen');
|
|
25
|
+
});
|
|
26
|
+
it('should be dispatch sendCustomEvent', function () {
|
|
27
|
+
var consoleLogSpy = jest.spyOn(console, 'log');
|
|
28
|
+
sendCustomEvent('TestEvent', { prop1: 'value1' });
|
|
29
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('[BLUEFIN]: Custom event: TestEvent - {"prop1":"value1"}');
|
|
30
|
+
});
|
|
31
|
+
it('should be dispatch sendUserIdentification', function () {
|
|
32
|
+
var consoleLogSpy = jest.spyOn(console, 'log');
|
|
33
|
+
sendUserIdentification('123', { name: 'Name' });
|
|
34
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('[BLUEFIN]: User identification: 123 - {"name":"Name"}');
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type EventType = 'customEvent' | 'screenEvent' | 'userIdentification';
|
|
2
|
+
export type PropertiesType = {
|
|
3
|
+
[key: string]: string;
|
|
4
|
+
};
|
|
5
|
+
export type UserPropertiesType = {
|
|
6
|
+
email?: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
[key: string]: string | undefined;
|
|
9
|
+
};
|
|
10
|
+
export type EventData = {
|
|
11
|
+
screen?: string;
|
|
12
|
+
properties?: PropertiesType;
|
|
13
|
+
event?: string;
|
|
14
|
+
id?: string;
|
|
15
|
+
userProperties?: UserPropertiesType;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=dispatchers.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatchers.types.d.ts","sourceRoot":"","sources":["../../src/dispatchers/dispatchers.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,aAAa,GAAG,oBAAoB,CAAC;AAC7E,MAAM,MAAM,cAAc,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC;AACvD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC,CAAC;AACF,MAAM,MAAM,SAAS,GAAG;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,kBAAkB,CAAC;CACrC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { EventData, PropertiesType, UserPropertiesType } from './dispatchers.types';
|
|
2
|
+
/**
|
|
3
|
+
* Dispatches the specified event data to all configured providers.
|
|
4
|
+
*
|
|
5
|
+
* @param {EventData} eventData - The data associated with the event to be dispatched.
|
|
6
|
+
* @returns {void}
|
|
7
|
+
*/
|
|
8
|
+
export declare const dispatchEventToAllProviders: (eventData: EventData) => void;
|
|
9
|
+
declare const sendScreenEvent: (screen: string) => void;
|
|
10
|
+
declare const sendCustomEvent: (event: string, properties: PropertiesType) => void;
|
|
11
|
+
declare const sendUserIdentification: (id: string, userProperties: UserPropertiesType) => void;
|
|
12
|
+
export { sendCustomEvent, sendScreenEvent, sendUserIdentification };
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dispatchers/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEpF;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,cAAe,SAAS,KAAG,IAsBlE,CAAC;AAEF,QAAA,MAAM,eAAe,WAAY,MAAM,KAAG,IAMzC,CAAC;AAEF,QAAA,MAAM,eAAe,UAAW,MAAM,cAAc,cAAc,KAAG,IAQpE,CAAC;AAEF,QAAA,MAAM,sBAAsB,OACtB,MAAM,kBACM,kBAAkB,KACjC,IAQF,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,sBAAsB,EAAE,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
2
|
+
import { userSelectedEnvironment } from '../initializers';
|
|
3
|
+
import { providersList } from '../providers';
|
|
4
|
+
import { isValidProvidersList } from '../utils';
|
|
5
|
+
/**
|
|
6
|
+
* Dispatches the specified event data to all configured providers.
|
|
7
|
+
*
|
|
8
|
+
* @param {EventData} eventData - The data associated with the event to be dispatched.
|
|
9
|
+
* @returns {void}
|
|
10
|
+
*/
|
|
11
|
+
export var dispatchEventToAllProviders = function (eventData) {
|
|
12
|
+
if (!isValidProvidersList(providersList)) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
providersList.forEach(function (provider) {
|
|
16
|
+
var actions = {
|
|
17
|
+
screenEvent: function () { return provider.screenEvent
|
|
18
|
+
&& eventData.screen
|
|
19
|
+
&& provider.screenEvent(eventData.screen); },
|
|
20
|
+
customEvent: function () { return provider.customEvent
|
|
21
|
+
&& eventData.event
|
|
22
|
+
&& eventData.properties
|
|
23
|
+
&& provider.customEvent(eventData.event, eventData.properties); },
|
|
24
|
+
userIdentification: function () { return provider.userIdentification
|
|
25
|
+
&& eventData.id
|
|
26
|
+
&& eventData.userProperties
|
|
27
|
+
&& provider.userIdentification(eventData.id, eventData.userProperties); }
|
|
28
|
+
};
|
|
29
|
+
Object.values(actions).forEach(function (action) { return action(); });
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
var sendScreenEvent = function (screen) {
|
|
33
|
+
if (userSelectedEnvironment === 'development') {
|
|
34
|
+
console.log("[BLUEFIN]: Screen event: ".concat(screen));
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
dispatchEventToAllProviders({ screen: screen });
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var sendCustomEvent = function (event, properties) {
|
|
41
|
+
if (userSelectedEnvironment === 'development') {
|
|
42
|
+
console.log("[BLUEFIN]: Custom event: ".concat(event, " - ").concat(JSON.stringify(properties)));
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
dispatchEventToAllProviders({ event: event, properties: properties });
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
var sendUserIdentification = function (id, userProperties) {
|
|
49
|
+
if (userSelectedEnvironment === 'development') {
|
|
50
|
+
console.log("[BLUEFIN]: User identification: ".concat(id, " - ").concat(JSON.stringify(userProperties)));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
dispatchEventToAllProviders({ id: id, userProperties: userProperties });
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
export { sendCustomEvent, sendScreenEvent, sendUserIdentification };
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { IInitializeParams, EnvironmentType } from './initializers.types';
|
|
2
|
+
/**
|
|
3
|
+
* Represents the current environment setting for providers.
|
|
4
|
+
* @type {EnvironmentType}
|
|
5
|
+
* @description This variable stores the current environment setting
|
|
6
|
+
* used by providers. It is initially undefined and
|
|
7
|
+
* gets updated when the `initializeProviders` function is called.
|
|
8
|
+
* Make sure to call `initializeProviders` before accessing this value.
|
|
9
|
+
*/
|
|
10
|
+
declare let userSelectedEnvironment: EnvironmentType;
|
|
11
|
+
/**
|
|
12
|
+
* Initializes error tracking providers based on the given parameters.
|
|
13
|
+
* @param {IInitializeParams | IInitializeParams[]} paramsArray - Parameters for initialization.
|
|
14
|
+
* @options {EnvironmentType} environment - The environment (e.g., 'production', 'development').
|
|
15
|
+
* @returns {void}
|
|
16
|
+
*/
|
|
17
|
+
export declare const initializeProviders: (paramsArray: IInitializeParams | IInitializeParams[], options?: {
|
|
18
|
+
environment: EnvironmentType;
|
|
19
|
+
}) => void;
|
|
20
|
+
export { userSelectedEnvironment };
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/initializers/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AA+F1E;;;;;;;GAOG;AACH,QAAA,IAAI,uBAAuB,EAAE,eAAe,CAAC;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,gBACjB,iBAAiB,GAAG,iBAAiB,EAAE;iBAC5B,eAAe;MACtC,IAwCF,CAAC;AAEF,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/* eslint-disable import/no-mutable-exports */
|
|
2
|
+
import * as Sentry from '@sentry/react';
|
|
3
|
+
import { init } from '@fullstory/browser';
|
|
4
|
+
import mixpanel from 'mixpanel-browser';
|
|
5
|
+
import { BrowserTracing } from '@sentry/tracing';
|
|
6
|
+
import { CaptureConsole } from '@sentry/integrations';
|
|
7
|
+
import { clarity } from 'react-microsoft-clarity';
|
|
8
|
+
/**
|
|
9
|
+
* Checks if the environment is set to 'production'.
|
|
10
|
+
* @param {EnvironmentType} environment - The environment (e.g., 'production', 'development').
|
|
11
|
+
* @returns {boolean} - True if the environment is 'production', false otherwise.
|
|
12
|
+
*/
|
|
13
|
+
var isProduction = function (environment) { return environment === 'production'; };
|
|
14
|
+
/**
|
|
15
|
+
* Initializes Microsoft Clarity for error tracking in a web environment.
|
|
16
|
+
* @param {EnvironmentType} environment - The environment (e.g., 'production', 'development').
|
|
17
|
+
* @param {string} id - The Clarity project id.
|
|
18
|
+
* @returns {void}
|
|
19
|
+
*/
|
|
20
|
+
var clarityInitializer = function (environment, apiKey) {
|
|
21
|
+
if (isProduction(environment))
|
|
22
|
+
clarity.init(apiKey);
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Initializes FullStory for error tracking in a web environment.
|
|
26
|
+
* @param {EnvironmentType} environment - The environment (e.g., 'production', 'development').
|
|
27
|
+
* @param {string} orgId - The FullStory organization ID.
|
|
28
|
+
* @returns {void}
|
|
29
|
+
*/
|
|
30
|
+
var fullStoryInitializer = function (environment, apiKey) {
|
|
31
|
+
if (isProduction(environment))
|
|
32
|
+
init({ orgId: apiKey });
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Initializes MixPanel for error tracking in a web environment.
|
|
36
|
+
* @param {EnvironmentType} environment - The environment (e.g., 'production', 'development').
|
|
37
|
+
* @param {string} credential - The MixPanel project token.
|
|
38
|
+
* @returns {void}
|
|
39
|
+
*/
|
|
40
|
+
var mixPanelInitializer = function (environment, apiKey) {
|
|
41
|
+
if (isProduction(environment)) {
|
|
42
|
+
mixpanel.init(apiKey, {
|
|
43
|
+
track_pageview: true,
|
|
44
|
+
persistence: 'localStorage'
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Initializes Sentry for error tracking in a web environment.
|
|
50
|
+
* @param {EnvironmentType} environment - The environment (e.g., 'production', 'development').
|
|
51
|
+
* @param {string} dsn - The Sentry DSN (Data Source Name).
|
|
52
|
+
* @param {number} tracesSampleRate - The percentage of transactions to be sampled (0 to 1).
|
|
53
|
+
* @returns {void}
|
|
54
|
+
*/
|
|
55
|
+
var sentryInitializer = function (environment, apiKey, tracesSampleRate) {
|
|
56
|
+
if (tracesSampleRate === void 0) { tracesSampleRate = 0.5; }
|
|
57
|
+
if (!isProduction(environment)) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (tracesSampleRate < 0 || tracesSampleRate > 1) {
|
|
61
|
+
throw new Error('tracesSampleRate must be in the range [0, 1]');
|
|
62
|
+
}
|
|
63
|
+
Sentry.init({
|
|
64
|
+
dsn: apiKey,
|
|
65
|
+
integrations: [
|
|
66
|
+
new BrowserTracing(),
|
|
67
|
+
new CaptureConsole({
|
|
68
|
+
levels: ['warn', 'error']
|
|
69
|
+
}),
|
|
70
|
+
],
|
|
71
|
+
environment: environment,
|
|
72
|
+
tracesSampleRate: tracesSampleRate,
|
|
73
|
+
initialScope: {
|
|
74
|
+
tags: {
|
|
75
|
+
environment: environment
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Represents the current environment setting for providers.
|
|
82
|
+
* @type {EnvironmentType}
|
|
83
|
+
* @description This variable stores the current environment setting
|
|
84
|
+
* used by providers. It is initially undefined and
|
|
85
|
+
* gets updated when the `initializeProviders` function is called.
|
|
86
|
+
* Make sure to call `initializeProviders` before accessing this value.
|
|
87
|
+
*/
|
|
88
|
+
var userSelectedEnvironment;
|
|
89
|
+
/**
|
|
90
|
+
* Initializes error tracking providers based on the given parameters.
|
|
91
|
+
* @param {IInitializeParams | IInitializeParams[]} paramsArray - Parameters for initialization.
|
|
92
|
+
* @options {EnvironmentType} environment - The environment (e.g., 'production', 'development').
|
|
93
|
+
* @returns {void}
|
|
94
|
+
*/
|
|
95
|
+
export var initializeProviders = function (paramsArray, options) {
|
|
96
|
+
if (options === void 0) { options = { environment: 'production' }; }
|
|
97
|
+
var environment = options.environment;
|
|
98
|
+
var initializedProviders = [];
|
|
99
|
+
var initialize = function (params) {
|
|
100
|
+
var providerName = params.providerName, _a = params.tracesSampleRate, tracesSampleRate = _a === void 0 ? 0.1 : _a, _b = params.apiKey, apiKey = _b === void 0 ? '' : _b;
|
|
101
|
+
switch (providerName) {
|
|
102
|
+
case 'Clarity':
|
|
103
|
+
clarityInitializer(environment, apiKey);
|
|
104
|
+
break;
|
|
105
|
+
case 'FullStory':
|
|
106
|
+
fullStoryInitializer(environment, apiKey);
|
|
107
|
+
break;
|
|
108
|
+
case 'Sentry':
|
|
109
|
+
sentryInitializer(environment, apiKey, tracesSampleRate);
|
|
110
|
+
break;
|
|
111
|
+
case 'MixPanel':
|
|
112
|
+
mixPanelInitializer(environment, apiKey);
|
|
113
|
+
break;
|
|
114
|
+
default:
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
initializedProviders.push(providerName);
|
|
118
|
+
};
|
|
119
|
+
userSelectedEnvironment = environment;
|
|
120
|
+
if (Array.isArray(paramsArray)) {
|
|
121
|
+
paramsArray.forEach(initialize);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
initialize(paramsArray);
|
|
125
|
+
}
|
|
126
|
+
if (initializedProviders.length > 0) {
|
|
127
|
+
console.log('[Bluefin] Initialized providers:', initializedProviders);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
export { userSelectedEnvironment };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initializers.spec.d.ts","sourceRoot":"","sources":["../../src/initializers/initializers.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { initializeProviders, userSelectedEnvironment, } from './index';
|
|
2
|
+
jest.mock('@sentry/react', function () { return ({
|
|
3
|
+
init: jest.fn()
|
|
4
|
+
}); });
|
|
5
|
+
jest.mock('mixpanel-browser', function () { return ({
|
|
6
|
+
init: jest.fn()
|
|
7
|
+
}); });
|
|
8
|
+
describe('Initializers', function () {
|
|
9
|
+
beforeEach(function () {
|
|
10
|
+
jest.clearAllMocks();
|
|
11
|
+
});
|
|
12
|
+
describe('initializeProviders', function () {
|
|
13
|
+
it('should initialize providers and update userSelectedEnvironment', function () {
|
|
14
|
+
var paramsArray = [{ providerName: 'Mixpanel', apiKey: 'your-api-key' }, { providerName: 'Sentry', apiKey: 'your-api-key' }];
|
|
15
|
+
var logSpy = jest.spyOn(console, 'log').mockImplementation(function () { });
|
|
16
|
+
initializeProviders(paramsArray, { environment: 'production' });
|
|
17
|
+
expect(userSelectedEnvironment).toBe('production');
|
|
18
|
+
expect(logSpy).toHaveBeenCalledWith('[Bluefin] Initialized providers:', expect.arrayContaining(['Mixpanel', 'Sentry']));
|
|
19
|
+
logSpy.mockRestore();
|
|
20
|
+
});
|
|
21
|
+
it('should throw an error when initializing Sentry with an invalid tracesSampleRate', function () {
|
|
22
|
+
var paramsArray = [
|
|
23
|
+
{ providerName: 'Sentry', apiKey: 'your-api-key', tracesSampleRate: 1.5 },
|
|
24
|
+
];
|
|
25
|
+
expect(function () { return initializeProviders(paramsArray, { environment: 'production' }); }).toThrow('tracesSampleRate must be in the range [0, 1]');
|
|
26
|
+
});
|
|
27
|
+
it('should not throw an error when initializing Sentry with a valid tracesSampleRate', function () {
|
|
28
|
+
var validParams = [
|
|
29
|
+
{ providerName: 'Sentry', apiKey: 'your-api-key', tracesSampleRate: 0.5 },
|
|
30
|
+
];
|
|
31
|
+
expect(function () { return initializeProviders(validParams, { environment: 'production' }); }).not.toThrow();
|
|
32
|
+
});
|
|
33
|
+
it('should default to "production" environment if not specified in parameters', function () {
|
|
34
|
+
var paramsArray = { providerName: 'Sentry', apiKey: 'your-api-key' };
|
|
35
|
+
initializeProviders(paramsArray);
|
|
36
|
+
expect(userSelectedEnvironment).toEqual('production');
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type ProviderNameType = 'Clarity' | 'Sentry' | 'FullStory' | 'MixPanel' | 'Firebase';
|
|
2
|
+
export type EnvironmentType = 'development' | 'staging' | 'production';
|
|
3
|
+
export interface IInitializeParams {
|
|
4
|
+
providerName: ProviderNameType;
|
|
5
|
+
tracesSampleRate?: number;
|
|
6
|
+
apiKey?: string;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=initializers.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initializers.types.d.ts","sourceRoot":"","sources":["../../src/initializers/initializers.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,GAAG,UAAU,GAAG,UAAU,CAAC;AAE5F,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,SAAS,GAAG,YAAY,CAAC;AAEvE,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,gBAAgB,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ProviderType } from './provider.types';
|
|
2
|
+
/**
|
|
3
|
+
* An array containing the list of providers, initialized with the default provider(s).
|
|
4
|
+
*/
|
|
5
|
+
declare const providersList: ProviderType[];
|
|
6
|
+
/**
|
|
7
|
+
* Adds or updates a provider in the providers list.
|
|
8
|
+
*
|
|
9
|
+
* @param provider - The provider to be added or updated.
|
|
10
|
+
*/
|
|
11
|
+
declare const setup: (provider: ProviderType) => void;
|
|
12
|
+
export { providersList, setup };
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAchD;;GAEG;AACH,QAAA,MAAM,aAAa,EAAE,YAAY,EAA0B,CAAC;AAE5D;;;;GAIG;AACH,QAAA,MAAM,KAAK,aAAc,YAAY,KAAG,IAUvC,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
2
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
3
|
+
if (ar || !(i in from)) {
|
|
4
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
5
|
+
ar[i] = from[i];
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
9
|
+
};
|
|
10
|
+
import SentryProvider from './setups/sentry/sentry';
|
|
11
|
+
import MixPanelProvider from './setups/mixpanel/mixpanel';
|
|
12
|
+
import FullStoryProvider from './setups/fullstory/fullstory';
|
|
13
|
+
/**
|
|
14
|
+
* An array containing the default provider(s).
|
|
15
|
+
*/
|
|
16
|
+
var providersDefault = [
|
|
17
|
+
SentryProvider,
|
|
18
|
+
MixPanelProvider,
|
|
19
|
+
FullStoryProvider,
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* An array containing the list of providers, initialized with the default provider(s).
|
|
23
|
+
*/
|
|
24
|
+
var providersList = __spreadArray([], providersDefault, true);
|
|
25
|
+
/**
|
|
26
|
+
* Adds or updates a provider in the providers list.
|
|
27
|
+
*
|
|
28
|
+
* @param provider - The provider to be added or updated.
|
|
29
|
+
*/
|
|
30
|
+
var setup = function (provider) {
|
|
31
|
+
var existingIndex = providersList.findIndex(function (existingProvider) { return existingProvider.name === provider.name; });
|
|
32
|
+
if (existingIndex !== -1) {
|
|
33
|
+
providersList[existingIndex] = provider;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
providersList.unshift(provider);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
export { providersList, setup };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { PropertiesType } from '../dispatchers/dispatchers.types';
|
|
2
|
+
export type ProviderType = {
|
|
3
|
+
name: 'Clarity' | 'Sentry' | 'FullStory' | 'MixPanel';
|
|
4
|
+
userIdentification: (id: string, userProperties: any) => void;
|
|
5
|
+
customEvent: (event: string, properties: PropertiesType) => void;
|
|
6
|
+
screenEvent: (screen: string) => void;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=provider.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.types.d.ts","sourceRoot":"","sources":["../../src/providers/provider.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAElE,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,WAAW,GAAG,UAAU,CAAE;IACvD,kBAAkB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,KAAK,IAAI,CAAC;IAC9D,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,KAAK,IAAI,CAAC;IACjE,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clarity.d.ts","sourceRoot":"","sources":["../../../../src/providers/setups/clarity/clarity.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AA0BpD,QAAA,MAAM,eAAe,EAAE,YAKtB,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { clarity } from 'react-microsoft-clarity';
|
|
2
|
+
var dispatchUserIdentification = function (id, userProperties) {
|
|
3
|
+
clarity.identify(id, { userProperties: userProperties });
|
|
4
|
+
};
|
|
5
|
+
var dispatchCustomEvent = function (event, properties) {
|
|
6
|
+
clarity.setTag(event, 'customEvent');
|
|
7
|
+
};
|
|
8
|
+
var dispatchScreenEvent = function (screen) {
|
|
9
|
+
clarity.setTag(screen, 'screen');
|
|
10
|
+
};
|
|
11
|
+
var ClarityProvider = {
|
|
12
|
+
name: 'Clarity',
|
|
13
|
+
userIdentification: dispatchUserIdentification,
|
|
14
|
+
customEvent: dispatchCustomEvent,
|
|
15
|
+
screenEvent: dispatchScreenEvent
|
|
16
|
+
};
|
|
17
|
+
export default ClarityProvider;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fullstory.d.ts","sourceRoot":"","sources":["../../../../src/providers/setups/fullstory/fullstory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AA2BpD,QAAA,MAAM,iBAAiB,EAAE,YAKxB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as FullStory from '@fullstory/browser';
|
|
2
|
+
var dispatchUserIdentification = function (id, userProperties) {
|
|
3
|
+
FullStory.identify(id);
|
|
4
|
+
FullStory.setUserVars(userProperties);
|
|
5
|
+
};
|
|
6
|
+
var dispatchCustomEvent = function (event, properties) {
|
|
7
|
+
FullStory.event(event, { properties: properties });
|
|
8
|
+
};
|
|
9
|
+
var dispatchScreenEvent = function (screen) {
|
|
10
|
+
FullStory.event(screen, {});
|
|
11
|
+
};
|
|
12
|
+
var FullStoryProvider = {
|
|
13
|
+
name: 'FullStory',
|
|
14
|
+
userIdentification: dispatchUserIdentification,
|
|
15
|
+
customEvent: dispatchCustomEvent,
|
|
16
|
+
screenEvent: dispatchScreenEvent
|
|
17
|
+
};
|
|
18
|
+
export default FullStoryProvider;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fullstory.spec.d.ts","sourceRoot":"","sources":["../../../../src/providers/setups/fullstory/fullstory.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as FullStory from '@fullstory/browser';
|
|
2
|
+
import FullStoryProvider from './fullstory';
|
|
3
|
+
jest.mock('@fullstory/browser', function () { return ({
|
|
4
|
+
identify: jest.fn(),
|
|
5
|
+
setUserVars: jest.fn(),
|
|
6
|
+
event: jest.fn()
|
|
7
|
+
}); });
|
|
8
|
+
describe('FullStoryProvider', function () {
|
|
9
|
+
afterEach(function () {
|
|
10
|
+
jest.clearAllMocks();
|
|
11
|
+
});
|
|
12
|
+
it('dispatchUserIdentification should call FullStory.identify and FullStory.setUserVars', function () {
|
|
13
|
+
var id = '123';
|
|
14
|
+
var userProperties = { email: 'test@example.com', name: 'Test User' };
|
|
15
|
+
FullStoryProvider.userIdentification(id, userProperties);
|
|
16
|
+
expect(FullStory.identify).toHaveBeenCalledWith(id);
|
|
17
|
+
expect(FullStory.setUserVars).toHaveBeenCalledWith(userProperties);
|
|
18
|
+
});
|
|
19
|
+
it('dispatchCustomEvent should call FullStory.event with properties', function () {
|
|
20
|
+
var event = 'customEvent';
|
|
21
|
+
var properties = { key: 'value' };
|
|
22
|
+
FullStoryProvider.customEvent(event, properties);
|
|
23
|
+
expect(FullStory.event).toHaveBeenCalledWith(event, { properties: properties });
|
|
24
|
+
});
|
|
25
|
+
it('dispatchScreenEvent should call FullStory.event with empty properties', function () {
|
|
26
|
+
var screen = 'testScreen';
|
|
27
|
+
FullStoryProvider.screenEvent(screen);
|
|
28
|
+
expect(FullStory.event).toHaveBeenCalledWith(screen, {});
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mixpanel.d.ts","sourceRoot":"","sources":["../../../../src/providers/setups/mixpanel/mixpanel.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AA0CpD,QAAA,MAAM,gBAAgB,EAAE,YAKvB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import mixpanel from 'mixpanel-browser';
|
|
2
|
+
var dispatchUserIdentification = function (id, userProperties) {
|
|
3
|
+
mixpanel.identify(id);
|
|
4
|
+
var superProperties = ['name', 'email'];
|
|
5
|
+
var peopleProperties = {};
|
|
6
|
+
var cipherProperty = function (key) {
|
|
7
|
+
if (userProperties === null || userProperties === void 0 ? void 0 : userProperties[key]) {
|
|
8
|
+
peopleProperties["$".concat(key)] = userProperties[key];
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
superProperties.forEach(cipherProperty);
|
|
12
|
+
Object.entries(userProperties)
|
|
13
|
+
.filter(function (_a) {
|
|
14
|
+
var key = _a[0], value = _a[1];
|
|
15
|
+
return !superProperties.includes(key) && value;
|
|
16
|
+
})
|
|
17
|
+
.forEach(function (_a) {
|
|
18
|
+
var key = _a[0], value = _a[1];
|
|
19
|
+
peopleProperties[key] = value;
|
|
20
|
+
});
|
|
21
|
+
mixpanel.people.set(peopleProperties);
|
|
22
|
+
};
|
|
23
|
+
var dispatchCustomEvent = function (event, properties) {
|
|
24
|
+
mixpanel.track(event, { properties: properties });
|
|
25
|
+
};
|
|
26
|
+
var dispatchScreenEvent = function (screen) {
|
|
27
|
+
mixpanel.track(screen);
|
|
28
|
+
};
|
|
29
|
+
var MixPanelProvider = {
|
|
30
|
+
name: 'MixPanel',
|
|
31
|
+
userIdentification: dispatchUserIdentification,
|
|
32
|
+
customEvent: dispatchCustomEvent,
|
|
33
|
+
screenEvent: dispatchScreenEvent
|
|
34
|
+
};
|
|
35
|
+
export default MixPanelProvider;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mixpanel.spec.d.ts","sourceRoot":"","sources":["../../../../src/providers/setups/mixpanel/mixpanel.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import mixpanel from 'mixpanel-browser';
|
|
2
|
+
import MixPanelProvider from './mixpanel';
|
|
3
|
+
jest.mock('mixpanel-browser', function () { return ({
|
|
4
|
+
identify: jest.fn(),
|
|
5
|
+
track: jest.fn(),
|
|
6
|
+
people: {
|
|
7
|
+
set: jest.fn()
|
|
8
|
+
}
|
|
9
|
+
}); });
|
|
10
|
+
describe('MixPanelProvider', function () {
|
|
11
|
+
afterEach(function () {
|
|
12
|
+
jest.clearAllMocks();
|
|
13
|
+
});
|
|
14
|
+
test('dispatchUserIdentification should call mixpanel.identify and mixpanel.people.set', function () {
|
|
15
|
+
var id = 'testUserId';
|
|
16
|
+
var userProperties = {
|
|
17
|
+
email: 'test@example.com',
|
|
18
|
+
name: 'Test User'
|
|
19
|
+
};
|
|
20
|
+
MixPanelProvider.userIdentification(id, userProperties);
|
|
21
|
+
expect(mixpanel.identify).toHaveBeenCalledWith(id);
|
|
22
|
+
expect(mixpanel.people.set).toHaveBeenCalledWith({
|
|
23
|
+
$name: 'Test User',
|
|
24
|
+
$email: 'test@example.com'
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
test('dispatchCustomEvent should call mixpanel.track with event and properties', function () {
|
|
28
|
+
var event = 'testEvent';
|
|
29
|
+
var properties = { key1: 'value1', key2: 'value2' };
|
|
30
|
+
MixPanelProvider.customEvent(event, properties);
|
|
31
|
+
expect(mixpanel.track).toHaveBeenCalledWith(event, { properties: properties });
|
|
32
|
+
});
|
|
33
|
+
test('dispatchScreenEvent should call mixpanel.track with screen', function () {
|
|
34
|
+
var screen = 'testScreen';
|
|
35
|
+
MixPanelProvider.screenEvent(screen);
|
|
36
|
+
expect(mixpanel.track).toHaveBeenCalledWith(screen);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sentry.d.ts","sourceRoot":"","sources":["../../../../src/providers/setups/sentry/sentry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AA6CpD,QAAA,MAAM,cAAc,EAAE,YAKrB,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import * as Sentry from '@sentry/react';
|
|
13
|
+
var dispatchUserIdentification = function (id, userProperties) {
|
|
14
|
+
var userSentry = __assign({ id: id, email: userProperties.email || '', username: userProperties.name || '' }, userProperties);
|
|
15
|
+
Sentry.setUser(userSentry);
|
|
16
|
+
};
|
|
17
|
+
var dispatchCustomEvent = function (event, properties) {
|
|
18
|
+
var breadcrumb = {
|
|
19
|
+
category: 'customEvent',
|
|
20
|
+
message: event,
|
|
21
|
+
level: Sentry.Severity.Info,
|
|
22
|
+
data: properties,
|
|
23
|
+
type: 'info'
|
|
24
|
+
};
|
|
25
|
+
Sentry.addBreadcrumb(breadcrumb);
|
|
26
|
+
};
|
|
27
|
+
var dispatchScreenEvent = function (screen) {
|
|
28
|
+
var breadcrumb = {
|
|
29
|
+
category: 'screen',
|
|
30
|
+
message: screen,
|
|
31
|
+
level: Sentry.Severity.Info,
|
|
32
|
+
type: 'info'
|
|
33
|
+
};
|
|
34
|
+
Sentry.addBreadcrumb(breadcrumb);
|
|
35
|
+
};
|
|
36
|
+
var SentryProvider = {
|
|
37
|
+
name: 'Sentry',
|
|
38
|
+
userIdentification: dispatchUserIdentification,
|
|
39
|
+
customEvent: dispatchCustomEvent,
|
|
40
|
+
screenEvent: dispatchScreenEvent
|
|
41
|
+
};
|
|
42
|
+
export default SentryProvider;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sentry.spec.d.ts","sourceRoot":"","sources":["../../../../src/providers/setups/sentry/sentry.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as Sentry from '@sentry/react';
|
|
2
|
+
import SentryProvider from './sentry';
|
|
3
|
+
jest.mock('@sentry/react', function () { return ({
|
|
4
|
+
__esModule: true,
|
|
5
|
+
setUser: jest.fn(),
|
|
6
|
+
addBreadcrumb: jest.fn(),
|
|
7
|
+
Severity: {
|
|
8
|
+
Info: 'info'
|
|
9
|
+
}
|
|
10
|
+
}); });
|
|
11
|
+
describe('SentryProvider', function () {
|
|
12
|
+
afterEach(function () {
|
|
13
|
+
jest.clearAllMocks();
|
|
14
|
+
});
|
|
15
|
+
it('dispatchUserIdentification should set user in Sentry', function () {
|
|
16
|
+
var userId = '123';
|
|
17
|
+
var userProperties = {
|
|
18
|
+
email: 'test@example.com',
|
|
19
|
+
name: 'Test User',
|
|
20
|
+
customProperty: 'custom'
|
|
21
|
+
};
|
|
22
|
+
SentryProvider.userIdentification(userId, userProperties);
|
|
23
|
+
expect(Sentry.setUser).toHaveBeenCalledWith({
|
|
24
|
+
id: userId,
|
|
25
|
+
email: userProperties.email,
|
|
26
|
+
username: userProperties.name,
|
|
27
|
+
name: userProperties.name,
|
|
28
|
+
customProperty: 'custom'
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
it('dispatchCustomEvent should add breadcrumb in Sentry', function () {
|
|
32
|
+
var eventName = 'customEvent';
|
|
33
|
+
var properties = {
|
|
34
|
+
key1: 'value1',
|
|
35
|
+
key2: 'value2'
|
|
36
|
+
};
|
|
37
|
+
SentryProvider.customEvent(eventName, properties);
|
|
38
|
+
expect(Sentry.addBreadcrumb).toHaveBeenCalledWith({
|
|
39
|
+
category: 'customEvent',
|
|
40
|
+
message: eventName,
|
|
41
|
+
level: 'info',
|
|
42
|
+
data: properties,
|
|
43
|
+
type: 'info'
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
it('dispatchScreenEvent should add breadcrumb for screen in Sentry', function () {
|
|
47
|
+
var screenName = 'Home';
|
|
48
|
+
SentryProvider.screenEvent(screenName);
|
|
49
|
+
expect(Sentry.addBreadcrumb).toHaveBeenCalledWith({
|
|
50
|
+
category: 'screen',
|
|
51
|
+
message: screenName,
|
|
52
|
+
level: 'info',
|
|
53
|
+
type: 'info'
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAG3D,eAAO,MAAM,oBAAoB,kBAChB,YAAY,EAAE,KAC5B,OAAmE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@useblu/blu-lytics",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"types": "lib/index.d.ts",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": "^16.10.0"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc --declaration",
|
|
13
|
+
"dev": "ts-node src/index.ts",
|
|
14
|
+
"lint": "eslint src/**/*.ts* --fix",
|
|
15
|
+
"test": "TZ=UTC+3 jest",
|
|
16
|
+
"coverage": "TZ=UTC+3 jest --coverage"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@fullstory/browser": "1.7.0",
|
|
20
|
+
"@sentry/integrations": "^6.19.7",
|
|
21
|
+
"@sentry/react": "^6.19.7",
|
|
22
|
+
"@sentry/tracing": "^6.19.7",
|
|
23
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
24
|
+
"mixpanel-browser": "^2.48.1",
|
|
25
|
+
"react": "^18.2.0",
|
|
26
|
+
"react-microsoft-clarity": "^1.2.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/babel__core": "^7.20.5",
|
|
30
|
+
"@types/jest": "^29.2.3",
|
|
31
|
+
"@types/mixpanel-browser": "^2.47.5",
|
|
32
|
+
"@types/react": "^18.0.25",
|
|
33
|
+
"@typescript-eslint/eslint-plugin": "^5.43.0",
|
|
34
|
+
"@typescript-eslint/parser": "^5.43.0",
|
|
35
|
+
"eslint": "^8.27.0",
|
|
36
|
+
"eslint-config-airbnb-base": "^15.0.0",
|
|
37
|
+
"eslint-plugin-import": "^2.26.0",
|
|
38
|
+
"eslint-plugin-react": "^7.31.10",
|
|
39
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
40
|
+
"jest": "^29.2.2",
|
|
41
|
+
"prettier": "^2.3.2",
|
|
42
|
+
"ts-jest": "^29.0.3",
|
|
43
|
+
"ts-node-dev": "^2.0.0",
|
|
44
|
+
"tsup": "^6.4.0",
|
|
45
|
+
"typescript": "^4.8.4"
|
|
46
|
+
},
|
|
47
|
+
"description": "blu-lytics",
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "git+https://github.com/Pagnet/blu-lytics.git"
|
|
51
|
+
},
|
|
52
|
+
"keywords": [
|
|
53
|
+
"blu-lytics"
|
|
54
|
+
],
|
|
55
|
+
"author": "Blu",
|
|
56
|
+
"bugs": {
|
|
57
|
+
"url": "https://github.com/Pagnet/blu-lytics/issues"
|
|
58
|
+
},
|
|
59
|
+
"homepage": "https://github.com/Pagnet/blu-lytics#readme",
|
|
60
|
+
"files": [
|
|
61
|
+
"lib/**/*"
|
|
62
|
+
],
|
|
63
|
+
"publishConfig": {
|
|
64
|
+
"access": "public"
|
|
65
|
+
},
|
|
66
|
+
"sideEffects": false
|
|
67
|
+
}
|