Skip to content

Commit d8b877f

Browse files
ChesterSimclaude
andauthored
feat: add @drift-labs/posthog-types package (#327)
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
1 parent 797f4c7 commit d8b877f

File tree

17 files changed

+581
-0
lines changed

17 files changed

+581
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
name: posthog-types
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
branches: [master]
8+
9+
defaults:
10+
run:
11+
shell: bash
12+
working-directory: .
13+
14+
jobs:
15+
build:
16+
runs-on: ubicloud
17+
timeout-minutes: 10
18+
defaults:
19+
run:
20+
working-directory: ./posthog-types
21+
steps:
22+
- uses: actions/checkout@v4
23+
24+
- name: Setup Node
25+
uses: actions/setup-node@v4
26+
with:
27+
node-version: '24.x.x'
28+
registry-url: 'https://registry.npmjs.org'
29+
30+
- name: Setup bun
31+
uses: oven-sh/setup-bun@v1
32+
with:
33+
bun-version: 1.2.15
34+
35+
- name: Install dependencies
36+
run: bun install
37+
38+
- name: Build
39+
run: bun run build
40+
41+
check-for-posthog-types-changes:
42+
runs-on: ubicloud
43+
outputs:
44+
posthog-types: ${{ steps.filter.outputs.posthog-types }}
45+
steps:
46+
- uses: actions/checkout@v4
47+
- uses: dorny/paths-filter@v2
48+
id: filter
49+
with:
50+
filters: |
51+
posthog-types:
52+
- 'posthog-types/**'
53+
54+
release:
55+
runs-on: ubicloud
56+
needs: [build, check-for-posthog-types-changes]
57+
if: ${{ github.ref == 'refs/heads/master' && needs.check-for-posthog-types-changes.outputs.posthog-types == 'true' }}
58+
defaults:
59+
run:
60+
working-directory: ./posthog-types
61+
steps:
62+
- uses: actions/checkout@v4
63+
with:
64+
token: ${{ secrets.GH_PAT }}
65+
66+
- name: Setup Node
67+
uses: actions/setup-node@v4
68+
with:
69+
node-version: '24.x.x'
70+
registry-url: 'https://registry.npmjs.org'
71+
72+
- name: Setup bun
73+
uses: oven-sh/setup-bun@v1
74+
with:
75+
bun-version: 1.2.15
76+
77+
- name: Install dependencies
78+
run: bun install
79+
80+
- name: Build
81+
run: bun run build
82+
83+
- name: Update package version
84+
run: |
85+
VERSION=$(node -e "console.log(require('./package.json').version);")
86+
npm version patch
87+
echo "PACKAGE_VERSION=$(node -e "console.log(require('./package.json').version);")" >> $GITHUB_ENV
88+
89+
- name: Git commit
90+
id: git-commit
91+
run: |
92+
git config user.name "GitHub Actions"
93+
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
94+
git add ..
95+
git commit -a -m "posthog-types: release v$PACKAGE_VERSION [skip ci]"
96+
git pull --rebase origin master
97+
git push origin HEAD || {
98+
echo "Push failed. Retrying after pulling latest changes..."
99+
git pull --rebase origin master
100+
git push origin HEAD
101+
}
102+
echo "version=$PACKAGE_VERSION" >> $GITHUB_OUTPUT
103+
104+
- name: Publish to npm
105+
run: npm publish --access=public
106+
env:
107+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
108+
109+
- name: Notify Slack on failure
110+
if: failure()
111+
uses: slackapi/[email protected]
112+
env:
113+
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
114+
with:
115+
channel-id: '#code-review'
116+
slack-message: '<!here> ❌ posthog-types deployment failed! Check the logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'

posthog-types/package.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "@drift-labs/posthog-types",
3+
"version": "0.0.1",
4+
"description": "Shared PostHog event type definitions for Drift",
5+
"types": "./lib/index.d.ts",
6+
"license": "MIT",
7+
"repository": {
8+
"type": "git",
9+
"url": "https://github.com/drift-labs/drift-common/tree/master/posthog-types"
10+
},
11+
"author": "Drift Labs",
12+
"scripts": {
13+
"build": "bun run clean && tsc",
14+
"clean": "rm -rf lib",
15+
"prepublishOnly": "bun run build"
16+
},
17+
"files": [
18+
"lib"
19+
],
20+
"publishConfig": {
21+
"access": "public"
22+
},
23+
"devDependencies": {
24+
"typescript": "5.4.5"
25+
}
26+
}

posthog-types/src/eventMap.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import type { CollateralEvents } from './events/collateral';
2+
import type { TradeEvents } from './events/trade';
3+
import type { VaultEvents } from './events/vault';
4+
import type { IfStakingEvents } from './events/ifStaking';
5+
import type { EarnEvents } from './events/earn';
6+
import type { AmplifyEvents } from './events/amplify';
7+
import type { OnboardingEvents } from './events/onboarding';
8+
import type { SurveyEvents } from './events/survey';
9+
import type { PnlEvents } from './events/pnl';
10+
import type { SystemEvents } from './events/system';
11+
12+
/**
13+
* Marker type for events that require no properties.
14+
* We use {} rather than Record<string, never> because Record<string, never>
15+
* collapses optional fields to never under intersection with platform extensions.
16+
*/
17+
// eslint-disable-next-line @typescript-eslint/ban-types
18+
export type NoProperties = {};
19+
20+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
21+
export interface PostHogEventMap
22+
extends CollateralEvents,
23+
TradeEvents,
24+
VaultEvents,
25+
IfStakingEvents,
26+
EarnEvents,
27+
AmplifyEvents,
28+
OnboardingEvents,
29+
SurveyEvents,
30+
PnlEvents,
31+
SystemEvents {}
32+
33+
export type PostHogEvent = keyof PostHogEventMap;
34+
35+
/**
36+
* Extracts event names whose property type has no required keys (i.e., empty `{}`).
37+
* These events can be captured without passing a properties argument.
38+
*/
39+
type EmptyEventsOf<TMap extends PostHogEventMap> = {
40+
[K in keyof TMap]: keyof TMap[K] extends never ? K : never;
41+
}[keyof TMap];
42+
43+
/**
44+
* Typed capture function. Overloads are ordered so that:
45+
* 1. Events with no properties can be called with just the event name
46+
* 2. Events with properties require the properties argument
47+
*
48+
* TypeScript resolves overloads top-to-bottom — the zero-argument overload
49+
* must come first, otherwise it would never match.
50+
*/
51+
export type CaptureEvent<TMap extends PostHogEventMap = PostHogEventMap> = {
52+
<E extends EmptyEventsOf<TMap> & string>(event: E): void;
53+
<E extends keyof TMap & string>(event: E, properties: TMap[E]): void;
54+
};
55+
56+
/**
57+
* Extend the shared event map with platform-specific overrides and new events.
58+
*
59+
* @typeParam TOverrides - Properties to intersect onto existing events (use optional fields)
60+
* @typeParam TNew - Entirely new platform-specific events
61+
*
62+
* @example
63+
* ```ts
64+
* type WebEventMap = ExtendEventMap<
65+
* { collateral_deposit_submitted: { source?: string } },
66+
* { web_only_event: { detail: string } }
67+
* >;
68+
* ```
69+
*/
70+
export type ExtendEventMap<
71+
TOverrides extends Partial<Record<PostHogEvent, object>> = NoProperties,
72+
TNew extends Record<string, object> = NoProperties
73+
> = {
74+
[K in PostHogEvent]: K extends keyof TOverrides
75+
? PostHogEventMap[K] & TOverrides[K]
76+
: PostHogEventMap[K];
77+
} & TNew;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
type AmplifyDepositProperties = {
2+
amplify_deposit_amount: number;
3+
amplify_deposit_leverage: number;
4+
amplify_deposit_asset: string;
5+
amplify_deposit_pair: string;
6+
};
7+
8+
export type AmplifyEvents = {
9+
amplify_deposit_cta_clicked: AmplifyDepositProperties;
10+
amplify_deposit_succeeded: AmplifyDepositProperties & {
11+
amplify_last_withdrawal_quote_30_mins: number;
12+
};
13+
};
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import type { NoProperties } from '../eventMap';
2+
3+
export type CollateralEvents = {
4+
collateral_deposit_submitted: {
5+
spot_market_symbol?: string;
6+
newAccount: boolean;
7+
depositAmount: number;
8+
};
9+
collateral_withdrawal_submitted: {
10+
spot_market_symbol: string;
11+
withdrawal_amount: string;
12+
};
13+
collateral_borrow_submitted: {
14+
spot_market_symbol: string;
15+
borrow_amount: string;
16+
};
17+
collateral_transfer_submitted: NoProperties;
18+
collateral_deposit_modal_opened: {
19+
cta: string;
20+
from: string;
21+
};
22+
collateral_funxyz_address_copied: {
23+
from_chain_id: number | string | null;
24+
from_chain_name?: string | null;
25+
from_asset_symbol: string | null;
26+
to_chain: string;
27+
to_asset_symbol: string;
28+
receiving_address: string;
29+
};
30+
};

posthog-types/src/events/earn.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { NoProperties } from '../eventMap';
2+
3+
export type EarnEvents = {
4+
earn_if_stake_clicked: NoProperties;
5+
earn_vaults_clicked: NoProperties;
6+
earn_dsol_staking_clicked: NoProperties;
7+
earn_amplify_clicked: NoProperties;
8+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export type IfStakingEvents = {
2+
if_staking_stake_submitted: {
3+
spot_market_symbol: string;
4+
};
5+
if_staking_unstake_submitted: {
6+
spot_market_symbol: string;
7+
};
8+
if_staking_unstake_canceled: {
9+
spot_market_symbol: string;
10+
};
11+
if_staking_unstaked_assets_withdrawn: {
12+
spot_market_symbol: string;
13+
};
14+
};

posthog-types/src/events/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export type { CollateralEvents } from './collateral';
2+
export type { TradeEvents } from './trade';
3+
export type { VaultEvents } from './vault';
4+
export type { IfStakingEvents } from './ifStaking';
5+
export type { EarnEvents } from './earn';
6+
export type { AmplifyEvents } from './amplify';
7+
export type { OnboardingEvents } from './onboarding';
8+
export type { SurveyEvents } from './survey';
9+
export type { PnlEvents } from './pnl';
10+
export type { SystemEvents } from './system';
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import type { NoProperties } from '../eventMap';
2+
3+
type PrivyErrorProperties = {
4+
error_message: string;
5+
error_stack?: string;
6+
error_name?: string;
7+
error_raw: string;
8+
env: string;
9+
wallet_address: string;
10+
use_fee_payer: boolean;
11+
};
12+
13+
export type OnboardingEvents = {
14+
onboarding_wallet_connected: {
15+
name: string;
16+
};
17+
onboarding_magic_auth_login: {
18+
auth_type: 'email' | 'other';
19+
success: boolean;
20+
};
21+
onboarding_subaccount_created: NoProperties;
22+
onboarding_signless_modal_opened: NoProperties;
23+
onboarding_signless_delegated_confirmed: {
24+
success: boolean;
25+
delegated_selected_option: string;
26+
};
27+
onboarding_signless_setup_succeeded: {
28+
is_ledger: boolean;
29+
};
30+
onboarding_wallet_connection_error: {
31+
provider: string;
32+
error: unknown;
33+
};
34+
onboarding_referral_creation_error: {
35+
error: unknown;
36+
};
37+
onboarding_privy_sign_send_error: PrivyErrorProperties;
38+
onboarding_privy_build_sign_error: PrivyErrorProperties;
39+
onboarding_account_deleted: NoProperties;
40+
};

posthog-types/src/events/pnl.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export type PnlEvents = {
2+
pnl_action_performed: {
3+
action: 'download' | 'copy' | 'share_on_x';
4+
};
5+
pnl_history_exported: {
6+
statement_type: string;
7+
date_from: string;
8+
date_to: string;
9+
};
10+
};

0 commit comments

Comments
 (0)