Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,26 @@ name: Tests

on:
push:
branches: [ master ]
branches: [master]
pull_request:
branches: [ master ]
branches: [master]

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
node-version: [20.x, 22.x, 24.x]

steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm test -- run --coverage
- run: npx tsc
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run check-format
- run: npm run lint
- run: npm test -- run --coverage
- run: npx tsc
5 changes: 5 additions & 0 deletions .oxlintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rules": {
"no-var": "error"
}
}
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
history.md
97 changes: 56 additions & 41 deletions example.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,51 @@
// grab the Mixpanel factory
var Mixpanel = require('./lib/mixpanel-node');
const Mixpanel = require("./lib/mixpanel-node");

// create an instance of the mixpanel client
var mixpanel = Mixpanel.init('962dbca1bbc54701d402c94d65b4a20e');
const mixpanel = Mixpanel.init("962dbca1bbc54701d402c94d65b4a20e");
mixpanel.set_config({ debug: true });

// track an event with optional properties
mixpanel.track("my event", {
distinct_id: "some unique client id",
as: "many",
properties: "as",
you: "want"
distinct_id: "some unique client id",
as: "many",
properties: "as",
you: "want",
});
mixpanel.track("played_game");

// create or update a user in Mixpanel Engage
mixpanel.people.set("billybob", {
$first_name: "Billy",
$last_name: "Bob",
$created: (new Date('jan 1 2013')).toISOString(),
plan: "premium",
games_played: 1,
points: 0
$first_name: "Billy",
$last_name: "Bob",
$created: new Date("jan 1 2013").toISOString(),
plan: "premium",
games_played: 1,
points: 0,
});

// create or update a user in Mixpanel Engage without altering $last_seen
// - pass option `$ignore_time: true` to prevent the $last_seen property from being updated
mixpanel.people.set("billybob", {
mixpanel.people.set(
"billybob",
{
plan: "premium",
games_played: 1
}, {
$ignore_time: true
});
games_played: 1,
},
{
$ignore_time: true,
},
);

// set a single property on a user
mixpanel.people.set("billybob", "plan", "free");

// set a single property on a user, don't override
mixpanel.people.set_once("billybob", "first_game_play", (new Date('jan 1 2013')).toISOString());
mixpanel.people.set_once(
"billybob",
"first_game_play",
new Date("jan 1 2013").toISOString(),
);

// increment a numeric property
mixpanel.people.increment("billybob", "games_played");
Expand All @@ -46,13 +54,16 @@ mixpanel.people.increment("billybob", "games_played");
mixpanel.people.increment("billybob", "points", 15);

// increment multiple properties
mixpanel.people.increment("billybob", {"points": 10, "games_played": 1});
mixpanel.people.increment("billybob", { points: 10, games_played: 1 });

// append value to a list
mixpanel.people.append("billybob", "awards", "Great Player");

// append multiple values to a list
mixpanel.people.append("billybob", {"awards": "Great Player", "levels_finished": "Level 4"});
mixpanel.people.append("billybob", {
awards: "Great Player",
levels_finished: "Level 4",
});

// record a transaction for revenue analytics
mixpanel.people.track_charge("billybob", 39.99);
Expand All @@ -65,38 +76,42 @@ mixpanel.people.delete_user("billybob");

// all functions that send data to mixpanel take an optional
// callback as the last argument
mixpanel.track("test", function(err) { if (err) { throw err; } });
mixpanel.track("test", function (err) {
if (err) {
throw err;
}
});

// import an old event
var mixpanel_importer = Mixpanel.init('valid mixpanel token', {
secret: "valid api secret for project"
const mixpanel_importer = Mixpanel.init("valid mixpanel token", {
secret: "valid api secret for project",
});
mixpanel_importer.set_config({ debug: true });

// needs to be in the system once for it to show up in the interface
mixpanel_importer.track('old event', { gender: '' });
mixpanel_importer.track("old event", { gender: "" });

mixpanel_importer.import("old event", new Date(2012, 4, 20, 12, 34, 56), {
distinct_id: 'billybob',
gender: 'male'
distinct_id: "billybob",
gender: "male",
});

// import multiple events at once
mixpanel_importer.import_batch([
{
event: 'old event',
properties: {
time: new Date(2012, 4, 20, 12, 34, 56),
distinct_id: 'billybob',
gender: 'male'
}
{
event: "old event",
properties: {
time: new Date(2012, 4, 20, 12, 34, 56),
distinct_id: "billybob",
gender: "male",
},
},
{
event: "another old event",
properties: {
time: new Date(2012, 4, 21, 11, 33, 55),
distinct_id: "billybob",
color: "red",
},
{
event: 'another old event',
properties: {
time: new Date(2012, 4, 21, 11, 33, 55),
distinct_id: 'billybob',
color: 'red'
}
}
},
]);
71 changes: 41 additions & 30 deletions lib/flags/flags.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,60 @@
* TypeScript type definitions for Base Feature Flags Provider
*/

import { CustomLogger } from '../mixpanel-node';
import { SelectedVariant, FlagContext } from './types';
import { CustomLogger } from "../mixpanel-node";
import { SelectedVariant, FlagContext } from "./types";

/**
* Configuration for feature flags API requests
*/
export interface FeatureFlagsConfig {
token: string;
api_host: string;
request_timeout_in_seconds: number;
token: string;
api_host: string;
request_timeout_in_seconds: number;
}

/**
* Base Feature Flags Provider
* Contains common methods for feature flag evaluation
*/
export class FeatureFlagsProvider {
providerConfig: FeatureFlagsConfig;
endpoint: string;
logger: CustomLogger | null;
providerConfig: FeatureFlagsConfig;
endpoint: string;
logger: CustomLogger | null;

/**
* @param config - Common configuration for feature flag providers
* @param endpoint - API endpoint path (i.e., '/flags' or '/flags/definitions')
* @param logger - Logger instance
*/
constructor(config: FeatureFlagsConfig, endpoint: string, logger: CustomLogger | null);
/**
* @param config - Common configuration for feature flag providers
* @param endpoint - API endpoint path (i.e., '/flags' or '/flags/definitions')
* @param logger - Logger instance
*/
constructor(
config: FeatureFlagsConfig,
endpoint: string,
logger: CustomLogger | null,
);

/**
* Common HTTP request handler for flags API endpoints
* @param additionalParams - Additional query parameters to append
* @returns Parsed JSON response
*/
callFlagsEndpoint(additionalParams?: Record<string, any> | null): Promise<any>;
/**
* Common HTTP request handler for flags API endpoints
* @param additionalParams - Additional query parameters to append
* @returns Parsed JSON response
*/
callFlagsEndpoint(
additionalParams?: Record<string, any> | null,
): Promise<any>;

/**
* Manually tracks a feature flag exposure event to Mixpanel
* This provides flexibility for reporting individual exposure events when using getAllVariants
* If using getVariantValue or getVariant, exposure events are tracked automatically by default.
* @param {string} flagKey - The key of the feature flag
* @param {SelectedVariant} variant - The selected variant for the feature flag
* @param {FlagContext} context - The user context used to evaluate the feature flag
* @param {number|null} latencyMs - Optionally included latency in milliseconds that assignment took.
*/
trackExposureEvent(flagKey: string, variant: SelectedVariant, context: FlagContext, latencyMs?: number | null): void;
/**
* Manually tracks a feature flag exposure event to Mixpanel
* This provides flexibility for reporting individual exposure events when using getAllVariants
* If using getVariantValue or getVariant, exposure events are tracked automatically by default.
* @param {string} flagKey - The key of the feature flag
* @param {SelectedVariant} variant - The selected variant for the feature flag
* @param {FlagContext} context - The user context used to evaluate the feature flag
* @param {number|null} latencyMs - Optionally included latency in milliseconds that assignment took.
*/
trackExposureEvent(
flagKey: string,
variant: SelectedVariant,
context: FlagContext,
latencyMs?: number | null,
): void;
}
Loading