UNPKG

@clearbit-dcp/clearbit.js-core

Version:

The hassle-free way to integrate analytics into any web application.

177 lines (144 loc) 3.61 kB
'use strict'; /* * Module dependencies. */ var Entity = require('./entity'); var bindAll = require('bind-all'); var cookie = require('./cookie'); var debug = require('debug')('analytics:user'); var inherit = require('inherits'); var rawCookie = require('component-cookie'); var uuid = require('uuid'); /** * User defaults */ User.defaults = { persist: true, cookie: { key: 'cb_user_id', oldKey: 'cb_user' }, localStorage: { key: 'cb_user_traits' } }; /** * Initialize a new `User` with `options`. * * @param {Object} options */ function User(options) { this.defaults = User.defaults; this.debug = debug; Entity.call(this, options); } /** * Inherit `Entity` */ inherit(User, Entity); /** * Set/get the user id. * * When the user id changes, the method will reset his anonymousId to a new one. * * // FIXME: What are the mixed types? * @param {string} id * @return {Mixed} * @example * // didn't change because the user didn't have previous id. * anonymousId = user.anonymousId(); * user.id('foo'); * assert.equal(anonymousId, user.anonymousId()); * * // didn't change because the user id changed to null. * anonymousId = user.anonymousId(); * user.id('foo'); * user.id(null); * assert.equal(anonymousId, user.anonymousId()); * * // change because the user had previous id. * anonymousId = user.anonymousId(); * user.id('foo'); * user.id('baz'); // triggers change * user.id('baz'); // no change * assert.notEqual(anonymousId, user.anonymousId()); */ User.prototype.id = function(id) { var prev = this._getId(); var ret = Entity.prototype.id.apply(this, arguments); if (prev == null) return ret; // FIXME: We're relying on coercion here (1 == "1"), but our API treats these // two values differently. Figure out what will break if we remove this and // change to strict equality /* eslint-disable eqeqeq */ if (prev != id && id) this.anonymousId(null); /* eslint-enable eqeqeq */ return ret; }; /** * Set / get / remove anonymousId. * * @param {String} anonymousId * @return {String|User} */ User.prototype.anonymousId = function(anonymousId) { var store = this.storage(); // set / remove if (arguments.length) { store.set('cb_anonymous_id', anonymousId); return this; } // new anonymousId = store.get('cb_anonymous_id'); if (anonymousId) { return anonymousId; } // old - it is not stringified so we use the raw cookie. anonymousId = rawCookie('_cb'); if (anonymousId) { anonymousId = anonymousId.split('----')[0]; store.set('cb_anonymous_id', anonymousId); store.remove('_cb'); return anonymousId; } // empty anonymousId = uuid.v4(); store.set('cb_anonymous_id', anonymousId); return store.get('cb_anonymous_id'); }; /** * Remove anonymous id on logout too. */ User.prototype.logout = function() { Entity.prototype.logout.call(this); this.anonymousId(null); }; /** * Load saved user `id` or `traits` from storage. */ User.prototype.load = function() { if (this._loadOldCookie()) return; Entity.prototype.load.call(this); }; /** * BACKWARDS COMPATIBILITY: Load the old user from the cookie. * * @api private * @return {boolean} */ User.prototype._loadOldCookie = function() { var user = cookie.get(this._options.cookie.oldKey); if (!user) return false; this.id(user.id); this.traits(user.traits); cookie.remove(this._options.cookie.oldKey); return true; }; /** * Expose the user singleton. */ module.exports = bindAll(new User()); /** * Expose the `User` constructor. */ module.exports.User = User;