Skip to content

Commit

Permalink
Added Posthog package
Browse files Browse the repository at this point in the history
  • Loading branch information
dlymonk committed Apr 30, 2024
1 parent faf6dec commit f831c6a
Show file tree
Hide file tree
Showing 14 changed files with 399 additions and 0 deletions.
8 changes: 8 additions & 0 deletions configs/test-utils/src/__mocks__/@monkvision/posthog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import analyticsMock from './analytics';

export = {
/* Actual exports */

/* Mocks */
PosthogAnalyticsAdapter: analyticsMock.AnalyticsAdapterMock,
};
1 change: 1 addition & 0 deletions packages/posthog/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lib
17 changes: 17 additions & 0 deletions packages/posthog/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const OFF = 0;
const WARN = 1;
const ERROR = 2;

module.exports = {
extends: ['@monkvision/eslint-config-typescript'],
parserOptions: {
project: ['./tsconfig.json'],
},
rules: {
'import/no-extraneous-dependencies': OFF,
'no-console': OFF,
'@typescript-eslint/no-explicit-any': OFF,
'class-methods-use-this': OFF,
'@typescript-eslint/no-empty-function': OFF,
}
}
6 changes: 6 additions & 0 deletions packages/posthog/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules
coverage
.eslintcache
yarn-error.log
.idea
lib
Empty file added packages/posthog/.npmignore
Empty file.
32 changes: 32 additions & 0 deletions packages/posthog/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
The Clear BSD License

Copyright (c) [2022] [Monk](http://monk.ai)
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the disclaimer
below) provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
79 changes: 79 additions & 0 deletions packages/posthog/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# @monkvision/posthog

This package exports a analytics adapter that can be used to configure the analytics of MonkJs projects using the @monkvision/analytics project. The adapter exported by this package uses posthog, a analytics platform used by MonkJs to track event in its project. If you want to know more about analytics adapters and the features they offer, please refer to the official documentation of the @monkvision/analytics package.

# Installing

To install the package, you can run the following command :

```shell
yarn add @monkvision/analytics @monkvision/posthog
```

If you are using TypeScript, this package comes with its type definitions integrated, so you don't need to install anything else!

# Basic Usage

## Set Up

In order to configure the posthog inside your application, you first need to instantiate the Posthog Adapter and then wrap your root component in the `AnalyticsProvider` and passing it the adapter as a prop :

```tsx
import { PosthogAnalyticsAdapter } from '@monkvision/posthog';
import { AnalyticsProvider } from '@monkvision/analytics';

const adapter = new PosthogAnalyticsAdapter({
token: 'phc_iNzK7jyK2bLtRi9vNWnzQqy74rIPlXPdgGs0qgJrSfL',
api_host: 'https://eu.posthog.com',
environnement: 'development',
projectName: 'test',
release: '1.0.0',
});

const container = document.getElementById('root');
render((
<AnalyticsProvider adapter={adapter}>
<App/>
</AnalyticsProvider>
), container);
```

# API

## PosthogAnalyticsAdapter

### Description

A Posthog Adapter logs everything in the posthog platform. This can be used in your app when you want to implement posthog for advanced analytics Features such tracking events, and behavior of the user.

### Config Options

| Option | Description | Required | Default Value |
| ------------- | ----------------------------------------------------------------------------------------------------------- | -------- | ----------------------- |
| `token` | Token key for posthog.com project with which your application will connect for sending all the information. || `NULL` |
| `environment` | The environment of your application (e.g. "production"). | | `local` |
| `api_host` | The URL of the Posthog application. | | `https://eu.pothog.com` |
| `release` | Release version of application | | `1.0.0` |
| `projectName` | The name of the project or client. | | `monkjs` |

### Examples of Usage

```tsx
import { PosthogAnalyticsAdapter } from '@monkvision/posthog';
import { AnalyticsProvider } from '@monkvision/analytics';

const adapter = new PosthogAnalyticsAdapter({
token: '',
api_host: 'https://eu.posthog.com',
environnement: '',
projectName: '',
release: '',
});

const container = document.getElementById('root');
render((
<AnalyticsProvider adapter={adapter}>
<App/>
</AnalyticsProvider>
), container);
```
7 changes: 7 additions & 0 deletions packages/posthog/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/test/**/*.test.ts'],
coverageDirectory: 'coverage',
coverageReporters: ['lcov'],
};
78 changes: 78 additions & 0 deletions packages/posthog/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"name": "@monkvision/posthog",
"version": "4.0.0",
"license": "BSD-3-Clause-Clear",
"packageManager": "[email protected]",
"description": "MonkJs posthog package",
"author": "monkvision",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"files": [
"package.json",
"README.md",
"lib"
],
"installConfig": {
"hoistingLimits": "workspaces"
},
"scripts": {
"clean": "rimraf lib && mkdirp lib",
"build": "yarn run clean && tsc -p tsconfig.build.json",
"test": "jest",
"test:coverage": "jest --coverage",
"prettier": "prettier --check ./src ./test",
"prettier:fix": "prettier --write ./src ./test",
"eslint": "eslint --format=pretty ./src ./test",
"eslint:fix": "eslint --fix --format=pretty ./src ./test",
"lint": "yarn run prettier && yarn run eslint",
"lint:fix": "yarn run prettier:fix && yarn run eslint:fix"
},
"dependencies": {
"@monkvision/analytics": "4.0.0",
"@monkvision/types": "4.0.0",
"posthog-js": "^1.121.1"
},
"peerDependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@monkvision/eslint-config-base": "4.0.0",
"@monkvision/eslint-config-typescript": "4.0.0",
"@monkvision/prettier-config": "4.0.0",
"@monkvision/typescript-config": "4.0.0",
"@types/jest": "^29.2.2",
"@types/node": "^18.11.9",
"@typescript-eslint/eslint-plugin": "^5.43.0",
"@typescript-eslint/parser": "^5.43.0",
"eslint": "^8.29.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^8.5.0",
"eslint-formatter-pretty": "^4.1.0",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jest": "^25.3.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-promise": "^6.1.1",
"eslint-utils": "^3.0.0",
"jest": "^29.3.1",
"mkdirp": "^1.0.4",
"prettier": "^2.7.1",
"regexpp": "^3.2.0",
"rimraf": "^3.0.2",
"ts-jest": "^29.0.3",
"typescript": "^4.8.4"
},
"prettier": "@monkvision/prettier-config",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/monkvision/monkjs.git"
},
"bugs": {
"url": "https://github.com/monkvision/monkjs/issues"
},
"homepage": "https://github.com/monkvision/monkjs"
}
101 changes: 101 additions & 0 deletions packages/posthog/src/adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { AnalyticsAdapter } from '@monkvision/analytics';
import { Primitive } from '@monkvision/types';
import posthog from 'posthog-js';

/**
* Config required when instantiating the Posthog Analytics Adapter.
*/
export interface PosthogConfig {
/**
* Token key for Posthog application.
*/
token: string;
/**
* The URL of the Posthog application.
*
* @default 'local'
*/
api_host: string;
/**
* The environment of your application (e.g. "production").
*
* @default 'local'
*/
environnement: string;
/**
* The project name or client.
*
* @default 'monkjs'
*/
projectName: string;
/**
* Release version of application.
*
* @default '1.0.0'
*/
release: string;
}

/**
* Type definition for the config options given to the PosthogAnalyticsAdapter constructor.
*/
export interface PosthogAdapterConfig extends Partial<PosthogConfig> {
/**
* Token key for Posthog application.
*/
token: string;
}

const defaultOptions: Omit<PosthogConfig, 'token'> = {
api_host: 'https://eu.posthog.com',
environnement: 'local',
projectName: 'monkjs',
release: '1.0.0',
};

/**
* This is a Analytics Adapter that connects the app to the Posthog platform.
* There are four methods implemented which are `setUserId`, `setUserProperties`, `resetUser` and `trackEvent`,
*
* When initializing the adapter, the user have to pass required Posthog configuration keys to make connection between
* the application and Posthog. The `trackEvent` method will log the event in the Posthog dashboards.
*/
export class PosthogAnalyticsAdapter implements AnalyticsAdapter {
private readonly posthogOptions: PosthogConfig;

constructor(optionsParam: PosthogAdapterConfig) {
this.posthogOptions = {
...defaultOptions,
...optionsParam,
};

posthog.init(this.posthogOptions.token, {
api_host: this.posthogOptions.api_host,
});
posthog.setPersonProperties({
environnement: this.posthogOptions?.environnement,
projectName: this.posthogOptions?.projectName,
release: this.posthogOptions?.release,
});
}

setUserId(id: string, context?: Record<string, Primitive>): void {
posthog.identify(id, context);
}

setUserProperties(context: Record<string, Primitive>): void {
posthog.setPersonProperties(context);
}

resetUser(): void {
posthog.reset();
}

trackEvent(name: string, context?: Record<string, Primitive>): void {
posthog.capture(name, context);
}

setEventsProperties(context: Record<string, Primitive>): void {
posthog.register(context);
}
}
1 change: 1 addition & 0 deletions packages/posthog/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './adapter';
58 changes: 58 additions & 0 deletions packages/posthog/test/adapter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
jest.mock('posthog-js');

import posthog from 'posthog-js';
import { PosthogAnalyticsAdapter } from '../src';

const defaultConfiguration = {
token: 'phc_iNzK7jyK2bLtRi9vNWnzQqy74rIPlXPdgGs0qgJrSfL',
api_host: 'https://eu.posthog.com',
environnement: 'test',
projectName: 'test',
release: '1.0',
};

describe('Posthog Analytics Adapter', () => {
afterEach(() => {
jest.clearAllMocks();
});

describe('setUserId function', () => {
it('should set a user id in posthog', () => {
const adapter = new PosthogAnalyticsAdapter(defaultConfiguration);
adapter.setUserId('test id', { token: 'test' });
expect(posthog.identify).toHaveBeenCalledWith('test id', { token: 'test' });
});
});

describe('setUserProperties function', () => {
it('should set a user properties in posthog', () => {
const adapter = new PosthogAnalyticsAdapter(defaultConfiguration);
adapter.setUserProperties({ test: 'test properties' });
expect(posthog.setPersonProperties).toHaveBeenCalledWith({ test: 'test properties' });
});
});

describe('reset function', () => {
it('should reset the user in posthog', () => {
const adapter = new PosthogAnalyticsAdapter(defaultConfiguration);
adapter.resetUser();
expect(posthog.reset).toHaveBeenCalled();
});
});

describe('trackEvent function', () => {
it('should set a user properties in posthog', () => {
const adapter = new PosthogAnalyticsAdapter(defaultConfiguration);
adapter.trackEvent('test', { test: 'test properties' });
expect(posthog.capture).toHaveBeenCalledWith('test', { test: 'test properties' });
});
});

describe('setEventsProperties function', () => {
it('should set events properties in posthog', () => {
const adapter = new PosthogAnalyticsAdapter(defaultConfiguration);
adapter.setEventsProperties({ test: 'test properties' });
expect(posthog.register).toHaveBeenCalledWith({ test: 'test properties' });
});
});
});
Loading

0 comments on commit f831c6a

Please sign in to comment.