Skip to content

Commit 15063ad

Browse files
Add integration heap This commit copies the content of the integration repo into the "integrations" folder. Original repo: https://github.com/segment-integrations/analytics.js-integration-heap Readme: https://github.com/segment-integrations/analytics.js-integration-heap/blob/master/README.md
1 parent 6a6a663 commit 15063ad

File tree

6 files changed

+566
-0
lines changed

6 files changed

+566
-0
lines changed

integrations/heap/HISTORY.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
2+
2.1.1 / 2018-07-06
3+
==================
4+
5+
* Merge pull request #14 from segment-integrations/revert_heap_issue
6+
7+
2.1.0 / 2018-05-21
8+
==================
9+
10+
* Update heap integration for heap.js v4 (#12)
11+
* Bump a.js-int-tester version to ^3.1.0 (#10)
12+
* Pin karma, karma-mocha dev dependencies (#9)
13+
14+
2.0.3 / 2016-09-07
15+
==================
16+
17+
* update analytics.js-integration
18+
* fix flattening
19+
20+
2.0.2 / 2016-07-08
21+
==================
22+
23+
* bump version for npm
24+
25+
2.0.1 / 2016-07-08
26+
==================
27+
28+
* fix uncaught bug when sending undefined properties
29+
30+
2.0.0 / 2016-06-21
31+
==================
32+
33+
* Remove Duo compatibility
34+
* Add CI setup (coverage, linting, cross-browser compatibility, etc.)
35+
* Update eslint configuration
36+
37+
1.1.1 / 2016-05-07
38+
==================
39+
40+
* Bump Analytics.js core, tester, integration to use Facade 2.x
41+
42+
1.1.0 / 2016-04-11
43+
==================
44+
45+
* Update to use new identify and addUserProperties
46+
47+
1.0.5 / 2016-02-23
48+
==================
49+
50+
* support nested objects and arrays
51+
52+
1.0.4 / 2015-06-30
53+
==================
54+
55+
* Replace analytics.js dependency with analytics.js-core
56+
57+
1.0.3 / 2015-06-30
58+
==================
59+
60+
* Replace analytics.js dependency with analytics.js-core
61+
62+
1.0.2 / 2015-06-24
63+
==================
64+
65+
* Bump analytics.js-integration version
66+
67+
1.0.1 / 2015-06-24
68+
==================
69+
70+
* Bump analytics.js-integration version
71+
72+
1.0.0 / 2015-06-09
73+
==================
74+
75+
* Initial commit :sparkles:

integrations/heap/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# analytics.js-integration-heap [![Build Status][ci-badge]][ci-link]
2+
3+
Heap integration for [Analytics.js][].
4+
5+
## License
6+
7+
Released under the [MIT license](LICENSE).
8+
9+
10+
[Analytics.js]: https://segment.com/docs/libraries/analytics.js/
11+
[ci-link]: https://circleci.com/gh/segment-integrations/analytics.js-integration-heap
12+
[ci-badge]: https://circleci.com/gh/segment-integrations/analytics.js-integration-heap.svg?style=svg

integrations/heap/lib/index.js

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
'use strict';
2+
/* global JSON */
3+
/* eslint no-restricted-globals: [0] */
4+
5+
/**
6+
* Module dependencies.
7+
*/
8+
9+
var integration = require('@segment/analytics.js-integration');
10+
var each = require('component-each');
11+
var is = require('is');
12+
var extend = require('@ndhoule/extend');
13+
var toISOString = require('@segment/to-iso-string');
14+
var toString = Object.prototype.toString; // in case this method has been overridden by the user
15+
16+
/**
17+
* Expose `Heap` integration.
18+
*/
19+
20+
var Heap = module.exports = integration('Heap')
21+
.global('heap')
22+
.option('appId', '')
23+
.tag('<script src="//cdn.heapanalytics.com/js/heap-{{ appId }}.js">');
24+
25+
/**
26+
* Initialize.
27+
*
28+
* https://heapanalytics.com/docs/installation#web
29+
*
30+
* @api public
31+
*/
32+
33+
Heap.prototype.initialize = function() {
34+
window.heap = window.heap || [];
35+
window.heap.load = function(appid, config) {
36+
window.heap.appid = appid;
37+
window.heap.config = config;
38+
39+
var methodFactory = function(type) {
40+
return function() {
41+
window.heap.push([type].concat(Array.prototype.slice.call(arguments, 0)));
42+
};
43+
};
44+
45+
var heapMethods = ['addEventProperties', 'addUserProperties', 'clearEventProperties', 'identify', 'removeEventProperty', 'setEventProperties', 'track', 'unsetEventProperty', 'resetIdentity'];
46+
each(heapMethods, function(method) {
47+
window.heap[method] = methodFactory(method);
48+
});
49+
};
50+
51+
window.heap.load(this.options.appId);
52+
this.load(this.ready);
53+
};
54+
55+
/**
56+
* Loaded?
57+
*
58+
* @api private
59+
* @return {boolean}
60+
*/
61+
62+
Heap.prototype.loaded = function() {
63+
return !!(window.heap && window.heap.appid);
64+
};
65+
66+
/**
67+
* Identify.
68+
*
69+
* https://heapanalytics.com/docs#identify
70+
*
71+
* @api public
72+
* @param {Identify} identify
73+
*/
74+
75+
Heap.prototype.identify = function(identify) {
76+
var traits = identify.traits({ email: '_email' });
77+
var id = identify.userId();
78+
if (id) window.heap.identify(id);
79+
window.heap.addUserProperties(clean(traits));
80+
};
81+
82+
/**
83+
* Track.
84+
*
85+
* https://heapanalytics.com/docs#track
86+
*
87+
* @api public
88+
* @param {Track} track
89+
*/
90+
91+
Heap.prototype.track = function(track) {
92+
window.heap.track(track.event(), clean(track.properties()));
93+
};
94+
95+
/**
96+
* Clean all nested objects and arrays.
97+
*
98+
* @param {Object} obj
99+
* @return {Object}
100+
* @api private
101+
*/
102+
103+
function clean(obj) {
104+
var ret = {};
105+
106+
for (var k in obj) {
107+
if (obj.hasOwnProperty(k)) {
108+
var value = obj[k];
109+
// Heap's natively library will drop null and undefined properties anyway
110+
// so no need to send these
111+
// also prevents uncaught errors since we call .toString() on non objects
112+
if (value === null || value === undefined) continue;
113+
114+
// date
115+
if (is.date(value)) {
116+
ret[k] = toISOString(value);
117+
continue;
118+
}
119+
120+
// leave boolean as is
121+
if (is.bool(value)) {
122+
ret[k] = value;
123+
continue;
124+
}
125+
126+
// leave numbers as is
127+
if (is.number(value)) {
128+
ret[k] = value;
129+
continue;
130+
}
131+
132+
// arrays of objects (eg. `products` array)
133+
if (toString.call(value) === '[object Array]') {
134+
ret = extend(ret, trample(k, value));
135+
continue;
136+
}
137+
138+
// non objects
139+
if (toString.call(value) !== '[object Object]') {
140+
ret[k] = value.toString();
141+
continue;
142+
}
143+
144+
ret = extend(ret, trample(k, value));
145+
}
146+
}
147+
// json
148+
// must flatten including the name of the original trait/property
149+
function trample(key, value) {
150+
var nestedObj = {};
151+
nestedObj[key] = value;
152+
var flattenedObj = flatten(nestedObj, { safe: true });
153+
154+
// stringify arrays inside nested object to be consistent with top level behavior of arrays
155+
for (var k in flattenedObj) {
156+
if (is.array(flattenedObj[k])) flattenedObj[k] = JSON.stringify(flattenedObj[k]);
157+
}
158+
159+
return flattenedObj;
160+
}
161+
162+
return ret;
163+
}
164+
165+
/**
166+
* Flatten nested objects
167+
* taken from https://www.npmjs.com/package/flat
168+
* @param {Object} obj
169+
* @return {Object} obj
170+
* @api public
171+
*/
172+
173+
function flatten(target, opts) {
174+
opts = opts || {};
175+
176+
var delimiter = opts.delimiter || '.';
177+
var maxDepth = opts.maxDepth;
178+
var currentDepth = 1;
179+
var output = {};
180+
181+
function step(object, prev) {
182+
Object.keys(object).forEach(function(key) {
183+
var value = object[key];
184+
var isarray = opts.safe && Array.isArray(value);
185+
var type = Object.prototype.toString.call(value);
186+
var isobject = type === '[object Object]' || type === '[object Array]';
187+
188+
var newKey = prev
189+
? prev + delimiter + key
190+
: key;
191+
192+
if (!opts.maxDepth) {
193+
maxDepth = currentDepth + 1;
194+
}
195+
196+
if (!isarray && isobject && Object.keys(value).length && currentDepth < maxDepth) {
197+
++currentDepth;
198+
return step(value, newKey);
199+
}
200+
201+
output[newKey] = value;
202+
});
203+
}
204+
205+
step(target);
206+
207+
return output;
208+
}
209+
210+
/**
211+
* Polyfill Object.keys
212+
* // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
213+
* Note: Had to do this because for some reason, the above will not work properly without using Object.keys
214+
*/
215+
216+
if (!Object.keys) {
217+
Object.keys = function(o) {
218+
if (o !== Object(o)) {
219+
throw new TypeError('Object.keys called on a non-object');
220+
}
221+
var k = [];
222+
var p;
223+
for (p in o) if (Object.prototype.hasOwnProperty.call(o, p)) k.push(p);
224+
return k;
225+
};
226+
}

integrations/heap/package.json

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{
2+
"name": "@segment/analytics.js-integration-heap",
3+
"description": "The Heap analytics.js integration.",
4+
"version": "2.1.1",
5+
"keywords": [
6+
"analytics.js",
7+
"analytics.js-integration",
8+
"segment",
9+
"heap"
10+
],
11+
"main": "lib/index.js",
12+
"scripts": {
13+
"test": "make test"
14+
},
15+
"author": "Segment \u003c[email protected]\u003e",
16+
"license": "SEE LICENSE IN LICENSE",
17+
"homepage": "https://github.com/segmentio/analytics.js-integrations/blob/master/integrations/heap#readme",
18+
"bugs": {
19+
"url": "https://github.com/segmentio/analytics.js-integrations/issues"
20+
},
21+
"repository": {
22+
"type": "git",
23+
"url": "git+https://github.com/segmentio/analytics.js-integrations.git"
24+
},
25+
"dependencies": {
26+
"@ndhoule/extend": "^2.0.0",
27+
"@segment/analytics.js-integration": "^3.0.0",
28+
"@segment/to-iso-string": "^1.0.1",
29+
"component-each": "^0.2.6",
30+
"is": "^3.1.0"
31+
},
32+
"devDependencies": {
33+
"@segment/analytics.js-core": "^3.0.0",
34+
"@segment/analytics.js-integration-tester": "^3.1.0",
35+
"@segment/clear-env": "^2.0.0",
36+
"@segment/eslint-config": "^3.1.1",
37+
"browserify": "^13.0.0",
38+
"browserify-istanbul": "^2.0.0",
39+
"eslint": "^2.9.0",
40+
"eslint-plugin-mocha": "^2.2.0",
41+
"eslint-plugin-require-path-exists": "^1.1.5",
42+
"istanbul": "^0.4.3",
43+
"karma": "1.3.0",
44+
"karma-browserify": "^5.0.4",
45+
"karma-chrome-launcher": "^1.0.1",
46+
"karma-coverage": "^1.0.0",
47+
"karma-junit-reporter": "^1.0.0",
48+
"karma-mocha": "1.0.1",
49+
"karma-phantomjs-launcher": "^1.0.0",
50+
"karma-sauce-launcher": "^1.0.0",
51+
"karma-spec-reporter": "0.0.26",
52+
"mocha": "^2.2.5",
53+
"npm-check": "^5.2.1",
54+
"phantomjs-prebuilt": "^2.1.7",
55+
"watchify": "^3.7.0"
56+
}
57+
}

integrations/heap/test/.eslintrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "@segment/eslint-config/mocha"
3+
}

0 commit comments

Comments
 (0)