Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mixpanel

Package Overview
Dependencies
Maintainers
3
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mixpanel - npm Package Compare versions

Comparing version 0.5.0 to 0.6.0

4

history.md

@@ -0,1 +1,5 @@

0.6.0 / 2017-01-03
===================
* support for `time` field in `mixpanel.track()` (thanks cruzanmo)
0.5.0 / 2016-09-15

@@ -2,0 +6,0 @@ ===================

87

lib/mixpanel-node.js

@@ -119,20 +119,9 @@ /*

/**
track(event, properties, callback)
---
this function sends an event to mixpanel.
event:string the event name
properties:object additional event properties to send
callback:function(err:Error) callback is called when the request is
finished or an error occurs
*/
metrics.track = function(event, properties, callback) {
if (typeof(properties) === 'function' || !properties) {
callback = properties;
properties = {};
}
// if properties.time exists, use import endpoint
var endpoint = (typeof(properties.time) === 'number') ? '/import' : '/track';
* Send an event to Mixpanel, using the specified endpoint (e.g., track/import)
* @param {string} endpoint - API endpoint name
* @param {string} event - event name
* @param {object} properties - event properties
* @param {Function} [callback] - callback for request completion/error
*/
metrics.send_event_request = function(endpoint, event, properties, callback) {
properties.token = metrics.token;

@@ -142,9 +131,8 @@ properties.mp_lib = "node";

var data = {
'event' : event,
'properties' : properties
event: event,
properties: properties
};
if (metrics.config.debug) {
console.log("Sending the following event to Mixpanel:");
console.log(data);
console.log("Sending the following event to Mixpanel:\n", data);
}

@@ -155,13 +143,44 @@

var parse_time = function(time) {
if (time === void 0) {
throw new Error("Import methods require you to specify the time of the event");
} else if (Object.prototype.toString.call(time) === '[object Date]') {
time = Math.floor(time.getTime() / 1000);
/**
* Validate type of time property, and convert to Unix timestamp if necessary
* @param {Date|number} time - value to check
* @returns {number} Unix timestamp
*/
var ensure_timestamp = function(time) {
if (!(time instanceof Date || typeof time === "number")) {
throw new Error("`time` property must be a Date or Unix timestamp and is only required for `import` endpoint");
}
return time;
return time instanceof Date ? Math.floor(time.getTime() / 1000) : time;
};
/**
import(event, properties, callback)
track(event, properties, callback)
---
this function sends an event to mixpanel.
event:string the event name
properties:object additional event properties to send
callback:function(err:Error) callback is called when the request is
finished or an error occurs
*/
var TRACK_AGE_LIMIT = 60 * 60 * 24 * 5; // 5 days in seconds
metrics.track = function(event, properties, callback) {
if (!properties || typeof properties === "function") {
callback = properties;
properties = {};
}
// time is optional for `track` but must be less than 5 days old if set
if (properties.time) {
properties.time = ensure_timestamp(properties.time);
if (properties.time < Date.now() / 1000 - TRACK_AGE_LIMIT) {
throw new Error("`track` not allowed for event more than 5 days old; use `mixpanel.import()`");
}
}
metrics.send_event_request("/track", event, properties, callback);
};
/**
import(event, time, properties, callback)
---

@@ -186,3 +205,3 @@ This function sends an event to mixpanel using the import

metrics.import = function(event, time, properties, callback) {
if (typeof(properties) === 'function' || !properties) {
if (!properties || typeof properties === "function") {
callback = properties;

@@ -192,5 +211,5 @@ properties = {};

properties.time = parse_time(time);
properties.time = ensure_timestamp(time);
metrics.track(event, properties, callback);
metrics.send_event_request("/import", event, properties, callback);
};

@@ -264,3 +283,3 @@

properties = event_list[ei].properties;
properties.time = parse_time(properties.time);
properties.time = ensure_timestamp(properties.time);
if (!properties.token) {

@@ -796,3 +815,3 @@ properties.token = metrics.token;

if (modifiers.hasOwnProperty("$time")) {
data.$time = parse_time(modifiers.$time);
data.$time = ensure_timestamp(modifiers.$time);
}

@@ -799,0 +818,0 @@ }

@@ -10,3 +10,3 @@ {

],
"version": "0.5.0",
"version": "0.6.0",
"homepage": "https://github.com/mixpanel/mixpanel-node",

@@ -13,0 +13,0 @@ "author": "Carl Sverre",

@@ -37,2 +37,9 @@ Mixpanel-node

// set an IP address to get automatic geolocation info
mixpanel.track('my event', {ip: '127.0.0.1'});
// track an event with a specific timestamp (up to 5 days old;
// use mixpanel.import() for older events)
mixpanel.track('timed event', {time: new Date()});
// create or update a user in Mixpanel Engage

@@ -57,2 +64,10 @@ mixpanel.people.set('billybob', {

// set a user profile's IP address to get automatic geolocation info
mixpanel.people.set('billybob', {
plan: 'premium',
games_played: 1
}, {
$ip: '127.0.0.1'
});
// set a single property on a user

@@ -168,2 +183,9 @@ mixpanel.people.set('billybob', 'plan', 'free');

Alternative Clients and Related Tools
-------------------------------------
- [Mixpanel-CLI](https://github.com/FGRibreau/mixpanel-cli) - CLI for Mixpanel API (currently only supports tracking functions)
- [Mixpanel Data Export](https://github.com/michaelcarter/mixpanel-data-export-js) - Supports various query and data-management APIs; runs in both Node.js and browser
- [Mixpanel Data Export (strawbrary)](https://github.com/strawbrary/mixpanel-data-export-js) - Fork of previous library, optimized for Node.js with support for streaming large raw exports
Attribution/Credits

@@ -198,2 +220,3 @@ -------------------

- [Frank Chiang](https://github.com/chiangf)
- [Morgan Croney](https://github.com/cruzanmo)

@@ -200,0 +223,0 @@ License

var Mixpanel = require('../lib/mixpanel-node'),
Sinon = require('sinon'),
http = require('http'),
events = require('events');
events = require('events'),
mock_now_time = new Date(2016, 1, 1).getTime(),
six_days_ago_timestamp = Math.floor(mock_now_time / 1000) - 60 * 60 * 24 * 6;

@@ -9,3 +11,3 @@ exports.import = {

this.mixpanel = Mixpanel.init('token', { key: 'key' });
this.clock = Sinon.useFakeTimers();
this.clock = Sinon.useFakeTimers(mock_now_time);

@@ -26,3 +28,3 @@ Sinon.stub(this.mixpanel, 'send_request');

var event = "test",
time = 500,
time = six_days_ago_timestamp,
props = { key1: 'val1' },

@@ -35,3 +37,3 @@ expected_endpoint = "/import",

token: 'token',
time: 500
time: time
}

@@ -50,5 +52,5 @@ };

"supports a Date instance": function(test) {
"supports a Date instance greater than 5 days old": function(test) {
var event = "test",
time = new Date,
time = new Date(six_days_ago_timestamp * 1000),
props = { key1: 'val1' },

@@ -61,3 +63,3 @@ expected_endpoint = "/import",

token: 'token',
time: 0
time: six_days_ago_timestamp
}

@@ -76,6 +78,61 @@ };

"requires the time argument": function(test) {
"supports a Date instance less than 5 days old": function(test) {
var event = "test",
time = new Date(mock_now_time),
props = { key1: 'val1' },
expected_endpoint = "/import",
expected_data = {
event: 'test',
properties: {
key1: 'val1',
token: 'token',
time: Math.floor(mock_now_time / 1000)
}
};
this.mixpanel.import(event, time, props);
test.ok(
this.mixpanel.send_request.calledWithMatch(expected_endpoint, expected_data),
"import didn't call send_request with correct arguments"
);
test.done();
},
"supports a unix timestamp": function(test) {
var event = "test",
time = mock_now_time / 1000,
props = { key1: 'val1' },
expected_endpoint = "/import",
expected_data = {
event: 'test',
properties: {
key1: 'val1',
token: 'token',
time: time
}
};
this.mixpanel.import(event, time, props);
test.ok(
this.mixpanel.send_request.calledWithMatch(expected_endpoint, expected_data),
"import didn't call send_request with correct arguments"
);
test.done();
},
"requires the time argument to be a number or Date": function(test) {
test.doesNotThrow(this.mixpanel.import.bind(this, 'test', new Date()));
test.doesNotThrow(this.mixpanel.import.bind(this, 'test', Date.now()/1000));
test.throws(
function() { this.mixpanel.import('test'); },
"Import methods require you to specify the time of the event",
this.mixpanel.import.bind(this, 'test', 'not a number or Date'),
/`time` property must be a Date or Unix timestamp/,
"import didn't throw an error when time wasn't a number or Date"
);
test.throws(
this.mixpanel.import.bind(this, 'test'),
/`time` property must be a Date or Unix timestamp/,
"import didn't throw an error when time wasn't specified"

@@ -82,0 +139,0 @@ );

var Mixpanel = require('../lib/mixpanel-node'),
Sinon = require('sinon');
Sinon = require('sinon'),
mock_now_time = new Date(2016, 1, 1).getTime();

@@ -7,2 +8,3 @@ exports.track = {

this.mixpanel = Mixpanel.init('token');
this.clock = Sinon.useFakeTimers(mock_now_time);

@@ -16,2 +18,3 @@ Sinon.stub(this.mixpanel, 'send_request');

this.mixpanel.send_request.restore();
this.clock.restore();

@@ -77,3 +80,82 @@ next();

});
},
"supports Date object for time": function(test) {
var event = 'test',
time = new Date(mock_now_time),
props = { time: time },
expected_endpoint = "/track",
expected_data = {
event: 'test',
properties: {
token: 'token',
time: time.getTime() / 1000,
mp_lib: 'node'
}
};
this.mixpanel.track(event, props);
test.ok(
this.mixpanel.send_request.calledWithMatch(expected_endpoint, expected_data),
"track didn't call send_request with correct arguments"
);
test.done();
},
"supports unix timestamp for time": function(test) {
var event = 'test',
time = mock_now_time / 1000,
props = { time: time },
expected_endpoint = "/track",
expected_data = {
event: 'test',
properties: {
token: 'token',
time: time,
mp_lib: 'node'
}
};
this.mixpanel.track(event, props);
test.ok(
this.mixpanel.send_request.calledWithMatch(expected_endpoint, expected_data),
"track didn't call send_request with correct arguments"
);
test.done();
},
"throws error if time property is older than 5 days": function(test) {
var event = 'test',
time = (mock_now_time - 1000 * 60 * 60 * 24 * 6) / 1000,
props = { time: time };
test.throws(
this.mixpanel.track.bind(this, event, props),
/`track` not allowed for event more than 5 days old/,
"track didn't throw an error when time was more than 5 days ago"
);
test.done();
},
"throws error if time is not a number or Date": function(test) {
var event = 'test',
props = { time: 'not a number or Date' };
test.throws(
this.mixpanel.track.bind(this, event, props),
/`time` property must be a Date or Unix timestamp/,
"track didn't throw an error when time wasn't a number or Date"
);
test.done();
},
"does not require time property": function(test) {
var event = 'test',
props = {};
test.doesNotThrow(this.mixpanel.track.bind(this, event, props));
test.done();
}
};

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc