From 8409007d3e20b8d462d945b5c3c9d86d2e6bbf06 Mon Sep 17 00:00:00 2001 From: Andrew F Date: Wed, 19 Aug 2015 11:35:40 -0700 Subject: [PATCH 1/4] Add interface typing --- segment-analytics/segment-analytics.d.ts | 98 ++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100755 segment-analytics/segment-analytics.d.ts diff --git a/segment-analytics/segment-analytics.d.ts b/segment-analytics/segment-analytics.d.ts new file mode 100755 index 0000000000..6d5f4465f8 --- /dev/null +++ b/segment-analytics/segment-analytics.d.ts @@ -0,0 +1,98 @@ +// Type definitions for Segment's analytics.js +// Project: https://segment.com/docs/libraries/analytics.js/ +// Definitions by: Andrew Fong +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +declare module SegmentAnalytics { + + // Generic options object with integrations + interface ISegmentOpts { + integrations: Integrations; + }; + + // The actual analytics.js object + interface AnalyticsJS { + + /* Configure Segment with write key */ + load(writeKey: string); + + /* The identify method is how you tie one of your users and their actions + to a recognizable userId and traits. */ + identify(userId: string, traits?: Object, + options?: ISegmentOpts, + callback?: () => void): void; + identify(userId: string, traits: Object, callback?: () => void): void; + identify(userId: string, callback?: () => void): void; + identify(traits?: Object, + options?: ISegmentOpts, + callback?: () => void): void; + identify(traits?: Object, + callback?: () => void): void; + identify(callback: () => void): void; + + /* The track method lets you record any actions your users perform. */ + track(event: string, properties?: Object, + options?: ISegmentOpts, + callback?: () => void): void; + track(event: string, properties?: Object, + callback?: () => void): void; + track(event: string, callback?: () => void): void; + + /* The page method lets you record page views on your website, along with + optional extra information about the page being viewed. */ + page(category: string, name: string, properties?: Object, + options?: ISegmentOpts, + callback?: () => void): void; + page(name?: string, properties?: Object, + options?: ISegmentOpts, + callback?: () => void): void; + page(name?: string, properties?: Object, callback?: () => void): void; + page(name?: string, callback?: () => void): void; + page(properties?: Object, + options?: ISegmentOpts, + callback?: () => void): void; + page(callback?: () => void): void; + + /* The alias method combines two previously unassociated user identities. + This comes in handy if the same user visits from two different devices + and you want to combine their history. + + Some providers also don’t alias automatically for you when an anonymous + user signs up (like Mixpanel), so you need to call alias manually right + after sign up with their brand new userId. */ + alias(userId: string, previousId?: string, + options?: ISegmentOpts, + callback?: () => void): void; + alias(userId: string, previousId?: string, callback?: () => void): void; + alias(userId: string, callback?: () => void): void; + alias(userId: string, options?: ISegmentOpts, + callback?: () => void): void; + + /* trackLink is a helper that binds a track call to whenever a link is + clicked. Usually the page would change before you could call track, but + with trackLink a small timeout is inserted to give the track call enough + time to fire. */ + trackLink(elements: Element|Element[], event: string, properties?: Object); + + /* trackForm is a helper that binds a track call to a form submission. + Usually the page would change before you could call track, but with + trackForm a small timeout is inserted to give the track call enough + time to fire. */ + trackForm(elements: Element|Element[], event: string, properties?: Object); + + /* The ready method allows you to pass in a callback that will be called as + soon as all of your enabled integrations have loaded. It’s like jQuery’s + ready method, except for integrations. */ + ready(callback: () => void); + + // Cookie-based user object + user(): { + id(): string; + logout(): void; + reset(): void; + }; + } +} + + +// declare var analytics: ISegment; \ No newline at end of file From 42edb17991ae0d38eb41325637e81d6e728c2da8 Mon Sep 17 00:00:00 2001 From: Andrew F Date: Wed, 19 Aug 2015 12:03:08 -0700 Subject: [PATCH 2/4] Group method --- segment-analytics/segment-analytics.d.ts | 34 +++++++++++++++--------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/segment-analytics/segment-analytics.d.ts b/segment-analytics/segment-analytics.d.ts index 6d5f4465f8..1b8cc8bf57 100755 --- a/segment-analytics/segment-analytics.d.ts +++ b/segment-analytics/segment-analytics.d.ts @@ -6,8 +6,9 @@ declare module SegmentAnalytics { // Generic options object with integrations - interface ISegmentOpts { - integrations: Integrations; + interface SegmentOpts { + integrations?: Integrations; + anonymousId?: string; }; // The actual analytics.js object @@ -19,12 +20,12 @@ declare module SegmentAnalytics { /* The identify method is how you tie one of your users and their actions to a recognizable userId and traits. */ identify(userId: string, traits?: Object, - options?: ISegmentOpts, + options?: SegmentOpts, callback?: () => void): void; identify(userId: string, traits: Object, callback?: () => void): void; identify(userId: string, callback?: () => void): void; identify(traits?: Object, - options?: ISegmentOpts, + options?: SegmentOpts, callback?: () => void): void; identify(traits?: Object, callback?: () => void): void; @@ -32,7 +33,7 @@ declare module SegmentAnalytics { /* The track method lets you record any actions your users perform. */ track(event: string, properties?: Object, - options?: ISegmentOpts, + options?: SegmentOpts, callback?: () => void): void; track(event: string, properties?: Object, callback?: () => void): void; @@ -41,18 +42,27 @@ declare module SegmentAnalytics { /* The page method lets you record page views on your website, along with optional extra information about the page being viewed. */ page(category: string, name: string, properties?: Object, - options?: ISegmentOpts, + options?: SegmentOpts, callback?: () => void): void; page(name?: string, properties?: Object, - options?: ISegmentOpts, + options?: SegmentOpts, callback?: () => void): void; page(name?: string, properties?: Object, callback?: () => void): void; page(name?: string, callback?: () => void): void; page(properties?: Object, - options?: ISegmentOpts, + options?: SegmentOpts, callback?: () => void): void; page(callback?: () => void): void; + /* The group method associates an individual user with a group. The group + can a company, organization, account, project, team or any other name + you came up with for the same concept. */ + group(groupId: string, traits?: Object, + options?: SegemntOpts, + callback?: () => void): void; + group(groupId: string, traits?: Object, callback?: () => void): void; + group(groupId: string, callback?: () => void): void; + /* The alias method combines two previously unassociated user identities. This comes in handy if the same user visits from two different devices and you want to combine their history. @@ -61,11 +71,11 @@ declare module SegmentAnalytics { user signs up (like Mixpanel), so you need to call alias manually right after sign up with their brand new userId. */ alias(userId: string, previousId?: string, - options?: ISegmentOpts, + options?: SegmentOpts, callback?: () => void): void; alias(userId: string, previousId?: string, callback?: () => void): void; alias(userId: string, callback?: () => void): void; - alias(userId: string, options?: ISegmentOpts, + alias(userId: string, options?: SegmentOpts, callback?: () => void): void; /* trackLink is a helper that binds a track call to whenever a link is @@ -90,9 +100,9 @@ declare module SegmentAnalytics { id(): string; logout(): void; reset(): void; + anonymousId(newId?: string): string; }; } } - -// declare var analytics: ISegment; \ No newline at end of file +declare var analytics: SegmentAnalytics.AnalyticsJS; From 763b5865d4d69da428f3ad65258d7b31be1e7058 Mon Sep 17 00:00:00 2001 From: Andrew F Date: Wed, 19 Aug 2015 13:35:56 -0700 Subject: [PATCH 3/4] Add tests and additional definitions --- segment-analytics/segment-analytics-tests.ts | 211 +++++++++++++++++++ segment-analytics/segment-analytics.d.ts | 84 +++++--- 2 files changed, 265 insertions(+), 30 deletions(-) create mode 100755 segment-analytics/segment-analytics-tests.ts diff --git a/segment-analytics/segment-analytics-tests.ts b/segment-analytics/segment-analytics-tests.ts new file mode 100755 index 0000000000..56df14e280 --- /dev/null +++ b/segment-analytics/segment-analytics-tests.ts @@ -0,0 +1,211 @@ +/// +/// + +// Some random vals to use + +// Use for page props or user traits +var testProps = { + favoriteCheese: "brie", + favoritePie: "apple" +}; + +// Segment options +var testOpts = { + integrations: { + Mixpanel: true + } +}; + +var testCb = function() {}; + + +///////////// + +function test_identify() { + // userId and traits + analytics.identify('1e810c197e', { + name: 'Bill Lumbergh', + email: 'bill@initech.com' + }); + + // No traits + analytics.identify('1e810c197e'); + + // No userId + analytics.identify({ + email: 'bill@initech.com', + newsletter: true, + industry: 'Technology' + }); + + // Callback + analytics.identify('1e810c197e', function(){ + // Do something after the identify request has been sent, like + // submit a form or redirect to a new page. + }); + + // With options + analytics.identify('1e810c197e', testProps, testOpts); + + // All args + analytics.identify('1e810c197e', testProps, testOpts, testCb); +} + +function testTrack() { + analytics.track('Signed Up'); + + analytics.track('Signed Up', { + plan: 'Startup', + source: 'Analytics Academy' + }); + + analytics.track('Signed Up', testProps, testOpts, testCb); +} + +function testPage() { + analytics.page('Signup'); + + analytics.page('Pricing', { + title: 'Segment Pricing', + url: 'https://segment.com/pricing', + path: '/pricing', + referrer: 'https://segment.com' + }); + + analytics.page('Category', 'Signup'); + + analytics.page('Signup', testProps, testOpts, testCb); +} + +function testAlias() { + analytics.alias('019mr8mf4r'); + analytics.alias('newId', 'oldId'); + analytics.alias('019mr8mf4r', testOpts, testCb); +} + +function testGroup() { + analytics.group('test_group'); + analytics.group('test_group', { + name: "Initech", + industry: "Technology", + employees: 329 + }); + analytics.group('test_group', testProps, testOpts, testCb); +} + +function testTrackLink() { + var link1 = document.getElementById('free-trial-link'); + var link2 = document.getElementById('free-trial-link-2'); + var links = $('.free-trial-links'); + + analytics.trackLink(link1, 'Clicked Free-Trial Link'); + analytics.trackLink(link1, 'Clicked Free-Trial Link', { + plan: 'Enterprise' + }); + + analytics.trackLink([link1, link2], 'Clicked Free-Trial Link', testProps); + analytics.trackLink(links, 'Clicked Free-Trial Link', testProps); + + // With function name and properties + analytics.trackLink(links, + function(elm) { + return String(elm); + }, + function(elm) { + return { + x: 123, + y: 456 + }; + }); +} + +function testTrackForm() { + var form1 = document.getElementById('signup-form'); + var form2 = document.getElementById('signin-form'); + var forms = $('.forms'); + + analytics.trackForm(form1, 'Signed up'); + analytics.trackForm(form1, 'Signed Up', { + plan: 'Premium', + revenue: 99.00 + }); + + analytics.trackForm([form1, form2], 'Clicked Free-Trial Link', testProps); + analytics.trackForm(forms, 'Clicked Free-Trial Link', testProps); + + // With function name and properties + analytics.trackForm(forms, + function(elm) { + return String(elm); + }, + function(elm) { + return { + x: 123, + y: 456 + }; + }); +} + +function testReady() { + analytics.ready(function(){ + ( window).mixpanel.set_config({ verbose: true }); + }); +} + +function testUserGroup() { + analytics.ready(function(){ + var user = analytics.user(); + var id = user.id(); + var traits = user.traits(); + }); + + analytics.ready(function(){ + var group = analytics.group(); + var id = group.id(); + var traits = group.traits(); + }); +} + +function testClearTraits() { + analytics.user().traits({}); + analytics.group().traits({}); +} + +function testResetLogout() { + analytics.reset(); +} + +function testAnonId() { + analytics.user().anonymousId(); + analytics.user().anonymousId('ABC-123-XYZ'); + + analytics.identify('123', { + gender: 'Male', + }, { + anonymousId: 'ABC-123-XYZ' + }); + + analytics.page({}, { anonymousId: 'ABC-123-XYZ' }); + + analytics.track('Clicked CTA', { + callToAction: 'Signup' + }, { + anonymousId: 'ABC-123-XYZ' + }); +} + +function testDebug() { + analytics.debug(); + analytics.debug(false); +} + +declare var bigdata: any; +function testEmitter() { + analytics.on('track', function(event, properties, options){ + bigdata.push(['recordEvent', event]); + }); +} + +function testTimeout() { + analytics.timeout(500); +} \ No newline at end of file diff --git a/segment-analytics/segment-analytics.d.ts b/segment-analytics/segment-analytics.d.ts index 1b8cc8bf57..f2de558464 100755 --- a/segment-analytics/segment-analytics.d.ts +++ b/segment-analytics/segment-analytics.d.ts @@ -3,37 +3,35 @@ // Definitions by: Andrew Fong // Definitions: https://github.com/borisyankov/DefinitelyTyped +/// + declare module SegmentAnalytics { // Generic options object with integrations - interface SegmentOpts { - integrations?: Integrations; + interface SegmentOpts { + integrations?: any; anonymousId?: string; - }; + } // The actual analytics.js object - interface AnalyticsJS { + interface AnalyticsJS { /* Configure Segment with write key */ load(writeKey: string); /* The identify method is how you tie one of your users and their actions to a recognizable userId and traits. */ - identify(userId: string, traits?: Object, - options?: SegmentOpts, + identify(userId: string, traits?: Object, options?: SegmentOpts, callback?: () => void): void; identify(userId: string, traits: Object, callback?: () => void): void; identify(userId: string, callback?: () => void): void; - identify(traits?: Object, - options?: SegmentOpts, - callback?: () => void): void; - identify(traits?: Object, + identify(traits?: Object, options?: SegmentOpts, callback?: () => void): void; + identify(traits?: Object, callback?: () => void): void; identify(callback: () => void): void; /* The track method lets you record any actions your users perform. */ - track(event: string, properties?: Object, - options?: SegmentOpts, + track(event: string, properties?: Object, options?: SegmentOpts, callback?: () => void): void; track(event: string, properties?: Object, callback?: () => void): void; @@ -42,23 +40,19 @@ declare module SegmentAnalytics { /* The page method lets you record page views on your website, along with optional extra information about the page being viewed. */ page(category: string, name: string, properties?: Object, - options?: SegmentOpts, - callback?: () => void): void; + options?: SegmentOpts, callback?: () => void): void; page(name?: string, properties?: Object, - options?: SegmentOpts, - callback?: () => void): void; + options?: SegmentOpts, callback?: () => void): void; page(name?: string, properties?: Object, callback?: () => void): void; page(name?: string, callback?: () => void): void; - page(properties?: Object, - options?: SegmentOpts, + page(properties?: Object, options?: SegmentOpts, callback?: () => void): void; page(callback?: () => void): void; /* The group method associates an individual user with a group. The group - can a company, organization, account, project, team or any other name + can a company, organization, account, project, team or any other name you came up with for the same concept. */ - group(groupId: string, traits?: Object, - options?: SegemntOpts, + group(groupId: string, traits?: Object, options?: SegmentOpts, callback?: () => void): void; group(groupId: string, traits?: Object, callback?: () => void): void; group(groupId: string, callback?: () => void): void; @@ -70,39 +64,69 @@ declare module SegmentAnalytics { Some providers also don’t alias automatically for you when an anonymous user signs up (like Mixpanel), so you need to call alias manually right after sign up with their brand new userId. */ - alias(userId: string, previousId?: string, - options?: SegmentOpts, + alias(userId: string, previousId?: string, options?: SegmentOpts, callback?: () => void): void; alias(userId: string, previousId?: string, callback?: () => void): void; alias(userId: string, callback?: () => void): void; - alias(userId: string, options?: SegmentOpts, - callback?: () => void): void; + alias(userId: string, options?: SegmentOpts, callback?: () => void): void; /* trackLink is a helper that binds a track call to whenever a link is clicked. Usually the page would change before you could call track, but with trackLink a small timeout is inserted to give the track call enough time to fire. */ - trackLink(elements: Element|Element[], event: string, properties?: Object); + trackLink(elements: JQuery|Element[]|Element, + event: string|{ (elm: Element): string }, + properties?: Object|{ (elm: Element): Object }); /* trackForm is a helper that binds a track call to a form submission. Usually the page would change before you could call track, but with trackForm a small timeout is inserted to give the track call enough time to fire. */ - trackForm(elements: Element|Element[], event: string, properties?: Object); + trackForm(elements: JQuery|Element[]|Element, + event: string|{ (Element): string }, + properties?: Object|{ (elm: Element): Object }); /* The ready method allows you to pass in a callback that will be called as soon as all of your enabled integrations have loaded. It’s like jQuery’s ready method, except for integrations. */ ready(callback: () => void); - // Cookie-based user object + /* If you need to clear the user and group id and traits we’ve added a + reset function that is most commonly used when your identified users + logout of your application. */ + reset(); + + /* Once Analytics.js loaded, you can retrieve information about the + currently identified user or group like their id and traits. */ user(): { id(): string; logout(): void; reset(): void; anonymousId(newId?: string): string; - }; + traits(newTraits?: Object): void; + } + + group(): { + id(): string; + traits(newTraits?: Object): void; + } + + /* Analytics.js has a debug mode that logs helpful messages to the + console. */ + debug(state?: boolean): void; + + /* The global analytics object emits events whenever you call alias, group, + identify, track or page. That way you can listen to those events and run + your own custom code. */ + on(event: string, + callback: { + (event: string, properties: Object, options: SegmentOpts): void + }); + + /* You can extend the length (in milliseconds) of the method callbacks and + helpers */ + timeout(milliseconds: number); } } -declare var analytics: SegmentAnalytics.AnalyticsJS; +declare var analytics: SegmentAnalytics.AnalyticsJS; From 68374669bf0ef6eb20d5aff2ea4d96dca83e4621 Mon Sep 17 00:00:00 2001 From: Andrew F Date: Wed, 19 Aug 2015 13:42:59 -0700 Subject: [PATCH 4/4] load test; fix implicit any errors --- segment-analytics/segment-analytics-tests.ts | 5 +++++ segment-analytics/segment-analytics.d.ts | 16 ++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/segment-analytics/segment-analytics-tests.ts b/segment-analytics/segment-analytics-tests.ts index 56df14e280..b876ea1bed 100755 --- a/segment-analytics/segment-analytics-tests.ts +++ b/segment-analytics/segment-analytics-tests.ts @@ -21,6 +21,10 @@ var testCb = function() {}; ///////////// +function test_load() { + analytics.load("YOUR_WRITE_KEY"); +} + function test_identify() { // userId and traits analytics.identify('1e810c197e', { @@ -63,6 +67,7 @@ function testTrack() { } function testPage() { + analytics.page(); analytics.page('Signup'); analytics.page('Pricing', { diff --git a/segment-analytics/segment-analytics.d.ts b/segment-analytics/segment-analytics.d.ts index f2de558464..3cdfbbc560 100755 --- a/segment-analytics/segment-analytics.d.ts +++ b/segment-analytics/segment-analytics.d.ts @@ -17,7 +17,7 @@ declare module SegmentAnalytics { interface AnalyticsJS { /* Configure Segment with write key */ - load(writeKey: string); + load(writeKey: string): void; /* The identify method is how you tie one of your users and their actions to a recognizable userId and traits. */ @@ -76,25 +76,25 @@ declare module SegmentAnalytics { time to fire. */ trackLink(elements: JQuery|Element[]|Element, event: string|{ (elm: Element): string }, - properties?: Object|{ (elm: Element): Object }); + properties?: Object|{ (elm: Element): Object }): void; /* trackForm is a helper that binds a track call to a form submission. Usually the page would change before you could call track, but with trackForm a small timeout is inserted to give the track call enough time to fire. */ trackForm(elements: JQuery|Element[]|Element, - event: string|{ (Element): string }, - properties?: Object|{ (elm: Element): Object }); + event: string|{ (elm: Element): string }, + properties?: Object|{ (elm: Element): Object }): void; /* The ready method allows you to pass in a callback that will be called as soon as all of your enabled integrations have loaded. It’s like jQuery’s ready method, except for integrations. */ - ready(callback: () => void); + ready(callback: () => void): void; /* If you need to clear the user and group id and traits we’ve added a reset function that is most commonly used when your identified users logout of your application. */ - reset(); + reset(): void; /* Once Analytics.js loaded, you can retrieve information about the currently identified user or group like their id and traits. */ @@ -121,11 +121,11 @@ declare module SegmentAnalytics { on(event: string, callback: { (event: string, properties: Object, options: SegmentOpts): void - }); + }): void; /* You can extend the length (in milliseconds) of the method callbacks and helpers */ - timeout(milliseconds: number); + timeout(milliseconds: number): void; } }