Skip to content
This repository has been archived by the owner on Feb 13, 2024. It is now read-only.

Commit

Permalink
Stringify userId and anonymousId
Browse files Browse the repository at this point in the history
Ref: https://segment.atlassian.net/browse/LIB-29

Our API truncates bignum values. This is problematic because this library has historically accepted Numbers as userIds and anonymousIds. To workaround the truncation, this library needs to stringify userId and anonymousId on the client. In the future we can make a breaking change and restrict the library to only accepting String ids, but for now we are keeping backward compatibility.
  • Loading branch information
f2prateek committed Nov 28, 2017
1 parent 1f930f5 commit f204d16
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
11 changes: 11 additions & 0 deletions index.js
Expand Up @@ -8,6 +8,7 @@ const retries = require('axios-retry')
const ms = require('ms')
const uid = require('crypto-token')
const version = require('./package.json').version
const isString = require('lodash.isstring')

const setImmediate = global.setImmediate || process.nextTick.bind(process)
const noop = () => {}
Expand Down Expand Up @@ -158,6 +159,16 @@ class Analytics {
message.messageId = `node-${uid(32)}`
}

// Historically this library has accepted strings and numbers as IDs.
// However, our spec only allows strings. To avoid breaking compatibility,
// we'll coerce these to strings if they aren't already.
if (message.anonymousId && !isString(message.anonymousId)) {
message.anonymousId = JSON.stringify(message.anonymousId)
}
if (message.userId && !isString(message.userId)) {
message.userId = JSON.stringify(message.userId)
}

this.queue.push({ message, callback })

if (!this.flushed) {
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -39,6 +39,7 @@
"axios-retry": "^3.0.1",
"commander": "^2.9.0",
"crypto-token": "^1.0.1",
"lodash.isstring": "^4.0.1",
"ms": "^2.0.0",
"remove-trailing-slash": "^0.1.0"
},
Expand Down
52 changes: 52 additions & 0 deletions test.js
Expand Up @@ -141,6 +141,58 @@ test('enqueue - add a message to the queue', t => {
})
})

test('enqueue - stringify userId', t => {
const client = createClient()

client.track({
userId: 10,
event: 'event'
}, noop)

t.is(client.queue.length, 1)

const item = client.queue.pop()

t.is(item.message.anonymousId, undefined)
t.is(item.message.userId, '10')
})

test('enqueue - stringify anonymousId', t => {
const client = createClient()

client.screen({
anonymousId: 157963456373623802,
name: 'screen name'
}, noop)

t.is(client.queue.length, 1)

const item = client.queue.pop()

t.is(item.message.userId, undefined)
// v8 will lose precision for big numbers.
t.is(item.message.anonymousId, '157963456373623800')
})

test('enqueue - stringify ids handles strings', t => {
const client = createClient()

client.screen({
anonymousId: '15796345',
// We're explicitly testing the behaviour of the library if a customer
// uses a String constructor.
userId: new String('prateek'), // eslint-disable-line no-new-wrappers
name: 'screen name'
}, noop)

t.is(client.queue.length, 1)

const item = client.queue.pop()

t.is(item.message.anonymousId, '15796345')
t.is(item.message.userId.toString(), 'prateek')
})

test('enqueue - don\'t modify the original message', t => {
const client = createClient()
const message = { event: 'test' }
Expand Down

0 comments on commit f204d16

Please sign in to comment.