@constructor-io/constructorio-node 3.5.6 → 3.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,21 +3,26 @@
3
3
  [![npm](https://img.shields.io/npm/v/@constructor-io/constructorio-node)](https://www.npmjs.com/package/@constructor-io/constructorio-node)
4
4
  [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/Constructor-io/constructorio-node/blob/master/LICENSE)
5
5
  [![Minzipped Size](https://img.shields.io/bundlephobia/minzip/@constructor-io/constructorio-node)](https://bundlephobia.com/result?p=@constructor-io/constructorio-node)
6
- [![Dependencies](https://img.shields.io/david/Constructor-io/constructorio-node)](https://david-dm.org/constructor-io/constructorio-node)
7
6
 
8
7
  A Node.js client for [Constructor.io](http://constructor.io/). [Constructor.io](http://constructor.io/) provides search as a service that optimizes results using artificial intelligence (including natural language processing, re-ranking to optimize for conversions, and user personalization).
9
8
 
10
- ## 1. Install
9
+ > This client is intended for use in server side integrations. If you want a JavaScript client for client side (i.e. front end) integrations please use [@constructor-io/constructorio-client-javascript](https://github.com/Constructor-io/constructorio-client-javascript)
10
+
11
+ ## 1. Review the Requirements
12
+
13
+ Requesting results from your Node.js back-end can be useful in order to control result rendering logic on your server, or augment/hydrate results with data from another system. However, a back-end integration has additional requirements compared to a front-end integration. Please review [Back End API Integration](https://constructorio.zendesk.com/hc/en-us/articles/360047993194-Back-end-API-Integration) for more detail.
14
+
15
+ ## 2. Install
11
16
 
12
17
  This package can be installed via npm: `npm i @constructor-io/constructorio-node`. Once installed, simply import or require the package into your repository.
13
18
 
14
19
  **Important**: this library should only be used in a server-side context.
15
20
 
16
- ## 2. Retrieve an API key and token
21
+ ## 3. Retrieve an API key and token
17
22
 
18
23
  You can find this in your [Constructor.io dashboard](https://constructor.io/dashboard). Contact sales if you'd like to sign up, or support if you believe your company already has an account.
19
24
 
20
- ## 3. Implement the Client
25
+ ## 4. Implement the Client
21
26
 
22
27
  Once imported, an instance of the client can be created as follows:
23
28
 
@@ -29,7 +34,7 @@ var constructorio = new ConstructorIOClient({
29
34
  });
30
35
  ```
31
36
 
32
- ## 4. Retrieve Results
37
+ ## 5. Retrieve Results
33
38
 
34
39
  After instantiating an instance of the client, four modules will be exposed as properties to help retrieve data from Constructor.io: `search`, `browse`, `autocomplete`, `recommendations`, `catalog` and `tracker`.
35
40
 
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@constructor-io/constructorio-node",
3
- "version": "3.5.6",
3
+ "version": "3.7.1",
4
4
  "description": "Constructor.io Node.js client",
5
5
  "main": "src/constructorio.js",
6
6
  "scripts": {
7
7
  "version": "chmod +x ./scripts/verify-node-version.sh && ./scripts/verify-node-version.sh && npm run docs && git add ./docs/*",
8
8
  "check-lisc": "license-checker --production --onlyAllow 'Apache-2.0;BSD-3-Clause;MIT'",
9
9
  "lint": "chmod 766 .git/hooks/pre-push && eslint 'src/**/*.js' 'spec/**/*.js'",
10
- "test": "mkdir -p test && cp -rf src/* test && mocha ./spec/* --opts ./mocha.opts --recursive",
10
+ "test": "mkdir -p test && cp -rf src/* test && mocha ./spec/*",
11
11
  "precoverage": "rm -rf ./coverage && rm -rf ./.nyc_output",
12
12
  "coverage": "nyc --all --reporter=html npm run test",
13
13
  "postcoverage": "serve --listen 8080 --config ./serve.json && rm -rf test",
@@ -36,19 +36,19 @@
36
36
  "chai": "^4.3.4",
37
37
  "chai-as-promised": "^7.1.1",
38
38
  "dotenv": "^8.6.0",
39
- "eslint": "^5.12.1",
40
- "eslint-config-airbnb-base": "^13.1.0",
39
+ "eslint": "^8.2.0",
40
+ "eslint-config-airbnb-base": "^15.0.0",
41
41
  "eslint-plugin-import": "^2.24.2",
42
42
  "jsdoc": "^3.6.7",
43
43
  "jsdom": "^15.1.1",
44
44
  "license-checker": "^25.0.1",
45
45
  "lodash.clonedeep": "^4.5.0",
46
46
  "minami": "^1.2.3",
47
- "mocha": "^6.2.0",
47
+ "mocha": "^9.1.3",
48
48
  "mocha-jsdom": "^2.0.0",
49
- "nyc": "^14.1.1",
49
+ "nyc": "^15.1.0",
50
50
  "pre-push": "^0.1.1",
51
- "serve": "^11.3.2",
51
+ "serve": "^13.0.2",
52
52
  "sinon": "^7.5.0",
53
53
  "sinon-chai": "^3.7.0",
54
54
  "uuid": "^8.3.2"
@@ -14,19 +14,20 @@ const { version: packageVersion } = require('../package.json');
14
14
  */
15
15
  class ConstructorIO {
16
16
  /**
17
- * @param {string} apiKey - Constructor.io API key
18
- * @param {string} [apiToken] - Constructor.io API token (required for catalog methods)
19
- * @param {string} [securityToken] - Constructor security token
20
- * @param {string} [serviceUrl='https://ac.cnstrc.com'] - API URL endpoint
21
- * @param {function} [fetch] - If supplied, will be utilized for requests rather than default Fetch API
22
- * @param {object} [networkParameters] - Parameters relevant to network requests
23
- * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds) - may be overridden within individual method calls
24
- * @property {object} [search] - Interface to {@link module:search}
25
- * @property {object} [browse] - Interface to {@link module:browse}
26
- * @property {object} [autocomplete] - Interface to {@link module:autocomplete}
27
- * @property {object} [recommendations] - Interface to {@link module:recommendations}
28
- * @property {object} [tracker] - Interface to {@link module:tracker}
29
- * @property {object} [catalog] - Interface to {@link module:catalog}
17
+ * @param {object} parameters - Parameters for client instantiation
18
+ * @param {string} parameters.apiKey - Constructor.io API key
19
+ * @param {string} [parameters.apiToken] - Constructor.io API token (required for catalog methods)
20
+ * @param {string} [parameters.securityToken] - Constructor security token
21
+ * @param {string} [parameters.serviceUrl='https://ac.cnstrc.com'] - API URL endpoint
22
+ * @param {function} [parameters.fetch] - If supplied, will be utilized for requests rather than default Fetch API
23
+ * @param {object} [parameters.networkParameters] - Parameters relevant to network requests
24
+ * @param {number} [parameters.networkParameters.timeout] - Request timeout (in milliseconds) - may be overridden within individual method calls
25
+ * @property {object} search - Interface to {@link module:search}
26
+ * @property {object} browse - Interface to {@link module:browse}
27
+ * @property {object} autocomplete - Interface to {@link module:autocomplete}
28
+ * @property {object} recommendations - Interface to {@link module:recommendations}
29
+ * @property {object} tracker - Interface to {@link module:tracker}
30
+ * @property {object} catalog - Interface to {@link module:catalog}
30
31
  * @returns {class}
31
32
  */
32
33
  constructor(options = {}) {
@@ -49,7 +50,7 @@ class ConstructorIO {
49
50
  apiToken: apiToken || '',
50
51
  securityToken: securityToken || '',
51
52
  version: version || global.CLIENT_VERSION || `cio-node-${packageVersion}`,
52
- serviceUrl: serviceUrl || 'https://ac.cnstrc.com',
53
+ serviceUrl: (serviceUrl && serviceUrl.replace(/\/$/, '')) || 'https://ac.cnstrc.com',
53
54
  fetch,
54
55
  networkParameters: networkParameters || {},
55
56
  };
@@ -96,6 +96,7 @@ class Autocomplete {
96
96
  * Retrieve autocomplete results from API
97
97
  *
98
98
  * @function getAutocompleteResults
99
+ * @param {string} query - Term to use to perform an autocomplete search
99
100
  * @param {object} [parameters] - Additional parameters to refine result set
100
101
  * @param {number} [parameters.numResults] - The total number of results to return
101
102
  * @param {object} [parameters.filters] - Filters used to refine search
@@ -104,7 +105,7 @@ class Autocomplete {
104
105
  * @param {object} [userParameters] - Parameters relevant to the user request
105
106
  * @param {number} [userParameters.sessionId] - Session ID, utilized to personalize results
106
107
  * @param {number} [userParameters.clientId] - Client ID, utilized to personalize results
107
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
108
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
108
109
  * @param {string} [userParameters.segments] - User segments
109
110
  * @param {string} [userParameters.testCells] - User test cells
110
111
  * @param {string} [userParameters.userIp] - Origin user IP, from client
@@ -195,7 +195,7 @@ class Browse {
195
195
  * @param {object} [userParameters] - Parameters relevant to the user request
196
196
  * @param {number} [userParameters.sessionId] - Session ID, utilized to personalize results
197
197
  * @param {number} [userParameters.clientId] - Client ID, utilized to personalize results
198
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
198
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
199
199
  * @param {string} [userParameters.segments] - User segments
200
200
  * @param {string} [userParameters.testCells] - User test cells
201
201
  * @param {string} [userParameters.userIp] - Origin user IP, from client
@@ -272,7 +272,7 @@ class Browse {
272
272
  * @param {object} [userParameters] - Parameters relevant to the user request
273
273
  * @param {number} [userParameters.sessionId] - Session ID, utilized to personalize results
274
274
  * @param {number} [userParameters.clientId] - Client ID, utilized to personalize results
275
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
275
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
276
276
  * @param {string} [userParameters.segments] - User segments
277
277
  * @param {string} [userParameters.testCells] - User test cells
278
278
  * @param {string} [userParameters.userIp] - Origin user IP, from client
@@ -336,7 +336,7 @@ class Browse {
336
336
  * @param {object} [userParameters] - Parameters relevant to the user request
337
337
  * @param {number} [userParameters.sessionId] - Session ID, utilized to personalize results
338
338
  * @param {number} [userParameters.clientId] - Client ID, utilized to personalize results
339
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
339
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
340
340
  * @param {string} [userParameters.segments] - User segments
341
341
  * @param {string} [userParameters.testCells] - User test cells
342
342
  * @param {string} [userParameters.userIp] - Origin user IP, from client
@@ -393,7 +393,7 @@ class Browse {
393
393
  * @param {object} [userParameters] - Parameters relevant to the user request
394
394
  * @param {number} [userParameters.sessionId] - Session ID, utilized to personalize results
395
395
  * @param {number} [userParameters.clientId] - Client ID, utilized to personalize results
396
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
396
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
397
397
  * @param {string} [userParameters.segments] - User segments
398
398
  * @param {string} [userParameters.testCells] - User test cells
399
399
  * @param {string} [userParameters.userIp] - Origin user IP, from client
@@ -517,7 +517,7 @@ class Catalog {
517
517
  }
518
518
 
519
519
  return helpers.throwHttpErrorFromResponse(new Error(), response);
520
- }).then(json => json);
520
+ }).then((json) => json);
521
521
  }
522
522
 
523
523
  /**
@@ -581,7 +581,7 @@ class Catalog {
581
581
  }
582
582
 
583
583
  return helpers.throwHttpErrorFromResponse(new Error(), response);
584
- }).then(json => json);
584
+ }).then((json) => json);
585
585
  }
586
586
 
587
587
  /**
@@ -712,7 +712,7 @@ class Catalog {
712
712
  }
713
713
 
714
714
  return helpers.throwHttpErrorFromResponse(new Error(), response);
715
- }).then(json => json);
715
+ }).then((json) => json);
716
716
  }
717
717
 
718
718
  /**
@@ -752,7 +752,7 @@ class Catalog {
752
752
  }
753
753
 
754
754
  return helpers.throwHttpErrorFromResponse(new Error(), response);
755
- }).then(json => json);
755
+ }).then((json) => json);
756
756
  }
757
757
 
758
758
  /**
@@ -795,7 +795,7 @@ class Catalog {
795
795
  }
796
796
 
797
797
  return helpers.throwHttpErrorFromResponse(new Error(), response);
798
- }).then(json => json);
798
+ }).then((json) => json);
799
799
  }
800
800
 
801
801
  /**
@@ -842,7 +842,7 @@ class Catalog {
842
842
  }
843
843
 
844
844
  return helpers.throwHttpErrorFromResponse(new Error(), response);
845
- }).then(json => json);
845
+ }).then((json) => json);
846
846
  }
847
847
 
848
848
  /**
@@ -879,7 +879,7 @@ class Catalog {
879
879
  }
880
880
 
881
881
  return helpers.throwHttpErrorFromResponse(new Error(), response);
882
- }).then(json => json);
882
+ }).then((json) => json);
883
883
  }
884
884
 
885
885
  /**
@@ -1013,7 +1013,7 @@ class Catalog {
1013
1013
  }
1014
1014
 
1015
1015
  return helpers.throwHttpErrorFromResponse(new Error(), response);
1016
- }).then(json => json);
1016
+ }).then((json) => json);
1017
1017
  }
1018
1018
 
1019
1019
  /**
@@ -1071,7 +1071,7 @@ class Catalog {
1071
1071
  }
1072
1072
 
1073
1073
  return helpers.throwHttpErrorFromResponse(new Error(), response);
1074
- }).then(json => json);
1074
+ }).then((json) => json);
1075
1075
  }
1076
1076
 
1077
1077
  /**
@@ -1197,7 +1197,7 @@ class Catalog {
1197
1197
  }
1198
1198
 
1199
1199
  return helpers.throwHttpErrorFromResponse(new Error(), response);
1200
- }).then(json => json);
1200
+ }).then((json) => json);
1201
1201
  }
1202
1202
 
1203
1203
  /**
@@ -1281,7 +1281,7 @@ class Catalog {
1281
1281
  }
1282
1282
 
1283
1283
  return helpers.throwHttpErrorFromResponse(new Error(), response);
1284
- }).then(json => json);
1284
+ }).then((json) => json);
1285
1285
  }
1286
1286
 
1287
1287
  /**
@@ -1338,10 +1338,9 @@ class Catalog {
1338
1338
  }
1339
1339
 
1340
1340
  return helpers.throwHttpErrorFromResponse(new Error(), response);
1341
- }).then(json => json);
1341
+ }).then((json) => json);
1342
1342
  }
1343
1343
 
1344
-
1345
1344
  /**
1346
1345
  * Remove synonym group for supplied ID
1347
1346
  *
@@ -1464,7 +1463,7 @@ class Catalog {
1464
1463
  }
1465
1464
 
1466
1465
  return helpers.throwHttpErrorFromResponse(new Error(), response);
1467
- }).then(json => json);
1466
+ }).then((json) => json);
1468
1467
  }
1469
1468
 
1470
1469
  /**
@@ -1514,7 +1513,7 @@ class Catalog {
1514
1513
  }
1515
1514
 
1516
1515
  return helpers.throwHttpErrorFromResponse(new Error(), response);
1517
- }).then(json => json);
1516
+ }).then((json) => json);
1518
1517
  }
1519
1518
 
1520
1519
  /**
@@ -1564,7 +1563,7 @@ class Catalog {
1564
1563
  }
1565
1564
 
1566
1565
  return helpers.throwHttpErrorFromResponse(new Error(), response);
1567
- }).then(json => json);
1566
+ }).then((json) => json);
1568
1567
  }
1569
1568
 
1570
1569
  /**
@@ -1603,7 +1602,7 @@ class Catalog {
1603
1602
  }
1604
1603
 
1605
1604
  return helpers.throwHttpErrorFromResponse(new Error(), response);
1606
- }).then(json => json);
1605
+ }).then((json) => json);
1607
1606
  }
1608
1607
 
1609
1608
  /**
@@ -1670,7 +1669,7 @@ class Catalog {
1670
1669
  }
1671
1670
 
1672
1671
  return helpers.throwHttpErrorFromResponse(new Error(), response);
1673
- }).then(json => json);
1672
+ }).then((json) => json);
1674
1673
  }
1675
1674
 
1676
1675
  /**
@@ -1709,7 +1708,7 @@ class Catalog {
1709
1708
  }
1710
1709
 
1711
1710
  return helpers.throwHttpErrorFromResponse(new Error(), response);
1712
- }).then(json => json);
1711
+ }).then((json) => json);
1713
1712
  }
1714
1713
 
1715
1714
  /**
@@ -100,7 +100,7 @@ class Recommendations {
100
100
  * @param {object} [userParameters] - Parameters relevant to the user request
101
101
  * @param {number} [userParameters.sessionId] - Session ID, utilized to personalize results
102
102
  * @param {number} [userParameters.clientId] - Client ID, utilized to personalize results
103
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
103
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
104
104
  * @param {string} [userParameters.segments] - User segments
105
105
  * @param {string} [userParameters.testCells] - User test cells
106
106
  * @param {string} [userParameters.userIp] - Origin user IP, from client
@@ -54,7 +54,6 @@ function createSearchUrl(query, parameters, userParameters, options) {
54
54
  sortBy,
55
55
  sortOrder,
56
56
  section,
57
- collectionId,
58
57
  fmtOptions,
59
58
  hiddenFields,
60
59
  } = parameters;
@@ -89,11 +88,6 @@ function createSearchUrl(query, parameters, userParameters, options) {
89
88
  queryParams.section = section;
90
89
  }
91
90
 
92
- // Pull collection id from parameters
93
- if (collectionId) {
94
- queryParams.collection_id = collectionId;
95
- }
96
-
97
91
  // Pull format options from parameters
98
92
  if (fmtOptions) {
99
93
  queryParams.fmt_options = fmtOptions;
@@ -136,12 +130,13 @@ class Search {
136
130
  * @param {object} [parameters.filters] - Filters used to refine search
137
131
  * @param {string} [parameters.sortBy='relevance'] - The sort method for results
138
132
  * @param {string} [parameters.sortOrder='descending'] - The sort order for results
133
+ * @param {string} [parameters.section='Products'] - The section name for results
139
134
  * @param {object} [parameters.fmtOptions] - The format options used to refine result groups
140
135
  * @param {string[]} [parameters.hiddenFields] - Hidden metadata fields to return
141
136
  * @param {object} [userParameters] - Parameters relevant to the user request
142
137
  * @param {number} [userParameters.sessionId] - Session ID, utilized to personalize results
143
138
  * @param {number} [userParameters.clientId] - Client ID, utilized to personalize results
144
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
139
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
145
140
  * @param {string} [userParameters.segments] - User segments
146
141
  * @param {string} [userParameters.testCells] - User test cells
147
142
  * @param {string} [userParameters.userIp] - Origin user IP, from client
@@ -77,7 +77,7 @@ function applyParamsAsString(parameters, userParameters, options) {
77
77
  }
78
78
 
79
79
  // Send request to server
80
- function send(url, userParameters, networkParameters, method = 'GET', body) { // eslint-disable-line max-params
80
+ function send(url, userParameters, networkParameters, method = 'GET', body = {}) { // eslint-disable-line max-params
81
81
  let request;
82
82
  const fetch = (this.options && this.options.fetch) || nodeFetch;
83
83
  const controller = new AbortController();
@@ -190,7 +190,7 @@ class Tracker {
190
190
  * @param {object} userParameters - Parameters relevant to the user request
191
191
  * @param {number} userParameters.sessionId - Session ID, utilized to personalize results
192
192
  * @param {number} userParameters.clientId - Client ID, utilized to personalize results
193
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
193
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
194
194
  * @param {string} [userParameters.segments] - User segments
195
195
  * @param {string} [userParameters.testCells] - User test cells
196
196
  * @param {string} [userParameters.originReferrer] - Client page URL (including path)
@@ -229,7 +229,7 @@ class Tracker {
229
229
  * @param {object} userParameters - Parameters relevant to the user request
230
230
  * @param {number} userParameters.sessionId - Session ID, utilized to personalize results
231
231
  * @param {number} userParameters.clientId - Client ID, utilized to personalize results
232
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
232
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
233
233
  * @param {string} [userParameters.segments] - User segments
234
234
  * @param {string} [userParameters.testCells] - User test cells
235
235
  * @param {string} [userParameters.originReferrer] - Client page URL (including path)
@@ -276,7 +276,7 @@ class Tracker {
276
276
  * @param {object} userParameters - Parameters relevant to the user request
277
277
  * @param {number} userParameters.sessionId - Session ID, utilized to personalize results
278
278
  * @param {number} userParameters.clientId - Client ID, utilized to personalize results
279
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
279
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
280
280
  * @param {string} [userParameters.segments] - User segments
281
281
  * @param {string} [userParameters.testCells] - User test cells
282
282
  * @param {string} [userParameters.originReferrer] - Client page URL (including path)
@@ -369,7 +369,7 @@ class Tracker {
369
369
  * @param {object} userParameters - Parameters relevant to the user request
370
370
  * @param {number} userParameters.sessionId - Session ID, utilized to personalize results
371
371
  * @param {number} userParameters.clientId - Client ID, utilized to personalize results
372
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
372
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
373
373
  * @param {string} [userParameters.segments] - User segments
374
374
  * @param {string} [userParameters.testCells] - User test cells
375
375
  * @param {string} [userParameters.originReferrer] - Client page URL (including path)
@@ -444,7 +444,7 @@ class Tracker {
444
444
  * @param {object} userParameters - Parameters relevant to the user request
445
445
  * @param {number} userParameters.sessionId - Session ID, utilized to personalize results
446
446
  * @param {number} userParameters.clientId - Client ID, utilized to personalize results
447
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
447
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
448
448
  * @param {string} [userParameters.segments] - User segments
449
449
  * @param {string} [userParameters.testCells] - User test cells
450
450
  * @param {string} [userParameters.originReferrer] - Client page URL (including path)
@@ -477,6 +477,7 @@ class Tracker {
477
477
  const url = `${this.options.serviceUrl}/behavior?`;
478
478
  const queryParams = { action: 'search-results', term };
479
479
  const { num_results, customer_ids, item_ids } = parameters;
480
+ let customerIDs;
480
481
 
481
482
  if (!helpers.isNil(num_results)) {
482
483
  queryParams.num_results = num_results;
@@ -484,9 +485,13 @@ class Tracker {
484
485
 
485
486
  // Ensure support for both item_ids and customer_ids as parameters
486
487
  if (item_ids && Array.isArray(item_ids)) {
487
- queryParams.customer_ids = item_ids.join(',');
488
+ customerIDs = item_ids;
488
489
  } else if (customer_ids && Array.isArray(customer_ids)) {
489
- queryParams.customer_ids = customer_ids.join(',');
490
+ customerIDs = customer_ids;
491
+ }
492
+
493
+ if (customerIDs && Array.isArray(customerIDs) && customerIDs.length) {
494
+ queryParams.customer_ids = customerIDs.slice(0, 100).join(',');
490
495
  }
491
496
 
492
497
  const requestUrl = `${url}${applyParamsAsString(queryParams, userParameters, this.options)}`;
@@ -520,7 +525,7 @@ class Tracker {
520
525
  * @param {object} userParameters - Parameters relevant to the user request
521
526
  * @param {number} userParameters.sessionId - Session ID, utilized to personalize results
522
527
  * @param {number} userParameters.clientId - Client ID, utilized to personalize results
523
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
528
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
524
529
  * @param {string} [userParameters.segments] - User segments
525
530
  * @param {string} [userParameters.testCells] - User test cells
526
531
  * @param {string} [userParameters.originReferrer] - Client page URL (including path)
@@ -602,7 +607,7 @@ class Tracker {
602
607
  * @param {string} [term] - Search results query term that led to conversion event
603
608
  * @param {object} parameters - Additional parameters to be sent with request
604
609
  * @param {string} parameters.item_id - Product item unique identifier
605
- * @param {number} parameters.revenue - Revenue (price) of product item
610
+ * @param {number} [parameters.revenue] - Sale price if available, otherwise the regular (retail) price of item
606
611
  * @param {string} [parameters.item_name] - Product item name
607
612
  * @param {string} [parameters.variation_id] - Product item variation unique identifier
608
613
  * @param {string} [parameters.type='add_to_cart'] - Conversion type
@@ -613,7 +618,7 @@ class Tracker {
613
618
  * @param {object} userParameters - Parameters relevant to the user request
614
619
  * @param {number} userParameters.sessionId - Session ID, utilized to personalize results
615
620
  * @param {number} userParameters.clientId - Client ID, utilized to personalize results
616
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
621
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
617
622
  * @param {string} [userParameters.segments] - User segments
618
623
  * @param {string} [userParameters.testCells] - User test cells
619
624
  * @param {string} [userParameters.originReferrer] - Client page URL (including path)
@@ -732,13 +737,13 @@ class Tracker {
732
737
  * @function trackPurchase
733
738
  * @param {object} parameters - Additional parameters to be sent with request
734
739
  * @param {object[]} parameters.items - List of product item objects
735
- * @param {number} parameters.revenue - Revenue
740
+ * @param {number} parameters.revenue - The subtotal (excluding taxes, shipping, etc.) of the entire order
736
741
  * @param {string} [parameters.order_id] - Unique order identifier
737
742
  * @param {string} [parameters.section] - Index section
738
743
  * @param {object} userParameters - Parameters relevant to the user request
739
744
  * @param {number} userParameters.sessionId - Session ID, utilized to personalize results
740
745
  * @param {number} userParameters.clientId - Client ID, utilized to personalize results
741
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
746
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
742
747
  * @param {string} [userParameters.segments] - User segments
743
748
  * @param {string} [userParameters.testCells] - User test cells
744
749
  * @param {string} [userParameters.originReferrer] - Client page URL (including path)
@@ -824,7 +829,7 @@ class Tracker {
824
829
  * @param {object} userParameters - Parameters relevant to the user request
825
830
  * @param {number} userParameters.sessionId - Session ID, utilized to personalize results
826
831
  * @param {number} userParameters.clientId - Client ID, utilized to personalize results
827
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
832
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
828
833
  * @param {string} [userParameters.segments] - User segments
829
834
  * @param {string} [userParameters.testCells] - User test cells
830
835
  * @param {string} [userParameters.originReferrer] - Client page URL (including path)
@@ -933,7 +938,7 @@ class Tracker {
933
938
  * @param {object} userParameters - Parameters relevant to the user request
934
939
  * @param {number} userParameters.sessionId - Session ID, utilized to personalize results
935
940
  * @param {number} userParameters.clientId - Client ID, utilized to personalize results
936
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
941
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
937
942
  * @param {string} [userParameters.segments] - User segments
938
943
  * @param {string} [userParameters.testCells] - User test cells
939
944
  * @param {string} [userParameters.originReferrer] - Client page URL (including path)
@@ -1062,7 +1067,7 @@ class Tracker {
1062
1067
  * @param {object} userParameters - Parameters relevant to the user request
1063
1068
  * @param {number} userParameters.sessionId - Session ID, utilized to personalize results
1064
1069
  * @param {number} userParameters.clientId - Client ID, utilized to personalize results
1065
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
1070
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
1066
1071
  * @param {string} [userParameters.segments] - User segments
1067
1072
  * @param {string} [userParameters.testCells] - User test cells
1068
1073
  * @param {string} [userParameters.originReferrer] - Client page URL (including path)
@@ -1156,7 +1161,7 @@ class Tracker {
1156
1161
  }
1157
1162
 
1158
1163
  if (items && Array.isArray(items)) {
1159
- bodyParams.items = items;
1164
+ bodyParams.items = items.slice(0, 100);
1160
1165
  }
1161
1166
 
1162
1167
  const requestUrl = `${requestPath}${applyParamsAsString({}, userParameters, this.options)}`;
@@ -1197,7 +1202,7 @@ class Tracker {
1197
1202
  * @param {object} userParameters - Parameters relevant to the user request
1198
1203
  * @param {number} userParameters.sessionId - Session ID, utilized to personalize results
1199
1204
  * @param {number} userParameters.clientId - Client ID, utilized to personalize results
1200
- * @param {object} [userParameters.userId] - User ID, utilized to personalize results
1205
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
1201
1206
  * @param {string} [userParameters.segments] - User segments
1202
1207
  * @param {string} [userParameters.testCells] - User test cells
1203
1208
  * @param {string} [userParameters.originReferrer] - Client page URL (including path)
@@ -1325,7 +1330,7 @@ class Tracker {
1325
1330
  * @param {object} [userParameters] - Parameters relevant to the user request
1326
1331
  * @param {number} userParameters.sessionId - Session ID, utilized to personalize results
1327
1332
  * @param {number} userParameters.clientId - Client ID, utilized to personalize results
1328
- * @param {object} userParameters.userId - User ID, utilized to personalize results
1333
+ * @param {string} userParameters.userId - User ID, utilized to personalize results
1329
1334
  * @param {string} [userParameters.segments] - User segments
1330
1335
  * @param {string} [userParameters.testCells] - User test cells
1331
1336
  * @param {string} [userParameters.originReferrer] - Client page URL (including path)
@@ -46,7 +46,7 @@ const utils = {
46
46
  throw error;
47
47
  }),
48
48
 
49
- isNil: value => value == null,
49
+ isNil: (value) => value == null,
50
50
 
51
51
  // Create authorization header to be transmitted with requests
52
52
  createAuthHeader: (options) => {
@@ -57,8 +57,10 @@ const utils = {
57
57
 
58
58
  // Abort network request based on supplied timeout interval (in milliseconds)
59
59
  // - method call parameter takes precedence over global options parameter
60
- applyNetworkTimeout: (options = {}, networkParameters = {}, controller) => {
61
- const timeout = options.networkParameters.timeout || networkParameters.timeout;
60
+ applyNetworkTimeout: (options = {}, networkParameters = {}, controller = undefined) => {
61
+ const optionsTimeout = options && options.networkParameters && options.networkParameters.timeout;
62
+ const networkParametersTimeout = networkParameters && networkParameters.timeout;
63
+ const timeout = optionsTimeout || networkParametersTimeout;
62
64
 
63
65
  if (typeof timeout === 'number') {
64
66
  setTimeout(() => controller.abort(), timeout);