@constructor-io/constructorio-node 3.8.9 → 3.10.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructor-io/constructorio-node",
3
- "version": "3.8.9",
3
+ "version": "3.10.1",
4
4
  "description": "Constructor.io Node.js client",
5
5
  "main": "src/constructorio.js",
6
6
  "scripts": {
package/src/.DS_Store ADDED
Binary file
@@ -47,7 +47,7 @@ function createAutocompleteUrl(query, parameters, userParameters, options) {
47
47
  }
48
48
 
49
49
  if (parameters) {
50
- const { numResults, resultsPerSection, filters, hiddenFields } = parameters;
50
+ const { numResults, resultsPerSection, filters, hiddenFields, variationsMap } = parameters;
51
51
 
52
52
  // Pull results number from parameters
53
53
  if (numResults) {
@@ -74,14 +74,20 @@ function createAutocompleteUrl(query, parameters, userParameters, options) {
74
74
  queryParams.fmt_options = { hidden_fields: hiddenFields };
75
75
  }
76
76
  }
77
+
78
+ // Pull variations map from parameters
79
+ if (variationsMap) {
80
+ queryParams.variations_map = JSON.stringify(variationsMap);
81
+ }
77
82
  }
78
83
 
79
84
  queryParams._dt = Date.now();
80
85
  queryParams = helpers.cleanParams(queryParams);
81
86
 
82
87
  const queryString = qs.stringify(queryParams, { indices: false });
88
+ const cleanedQuery = query.replace(/^\//, '|'); // For compatibility with backend API
83
89
 
84
- return `${serviceUrl}/autocomplete/${encodeURIComponent(query)}?${queryString}`;
90
+ return `${serviceUrl}/autocomplete/${helpers.encodeURIComponentRFC3986(helpers.trimNonBreakingSpaces(cleanedQuery))}?${queryString}`;
85
91
  }
86
92
 
87
93
  /**
@@ -106,6 +112,7 @@ class Autocomplete {
106
112
  * @param {object} [parameters.filters] - Filters used to refine search
107
113
  * @param {object} [parameters.resultsPerSection] - Number of results to return (value) per section (key)
108
114
  * @param {string[]} [parameters.hiddenFields] - Hidden metadata fields to return
115
+ * @param {object} [parameters.variationsMap] - The variations map object to aggregate variations. Please refer to https://docs.constructor.io/rest_api/variations_mapping for details
109
116
  * @param {object} [userParameters] - Parameters relevant to the user request
110
117
  * @param {number} [userParameters.sessionId] - Session ID, utilized to personalize results
111
118
  * @param {number} [userParameters.clientId] - Client ID, utilized to personalize results
@@ -1,3 +1,4 @@
1
+ /* eslint-disable max-len */
1
2
  /* eslint-disable object-curly-newline, no-underscore-dangle, max-params */
2
3
  const qs = require('qs');
3
4
  const nodeFetch = require('node-fetch').default;
@@ -26,6 +27,7 @@ function createQueryParams(parameters, userParameters, options) {
26
27
  if (parameters) {
27
28
  const {
28
29
  page,
30
+ offset,
29
31
  resultsPerPage,
30
32
  filters,
31
33
  sortBy,
@@ -34,6 +36,7 @@ function createQueryParams(parameters, userParameters, options) {
34
36
  fmtOptions,
35
37
  hiddenFields,
36
38
  hiddenFacets,
39
+ variationsMap,
37
40
  } = parameters;
38
41
 
39
42
  // Pull page from parameters
@@ -41,6 +44,11 @@ function createQueryParams(parameters, userParameters, options) {
41
44
  queryParams.page = page;
42
45
  }
43
46
 
47
+ // Pull offset from parameters
48
+ if (!helpers.isNil(offset)) {
49
+ queryParams.offset = offset;
50
+ }
51
+
44
52
  // Pull results per page from parameters
45
53
  if (!helpers.isNil(resultsPerPage)) {
46
54
  queryParams.num_results_per_page = resultsPerPage;
@@ -87,6 +95,11 @@ function createQueryParams(parameters, userParameters, options) {
87
95
  queryParams.fmt_options = { hidden_facets: hiddenFacets };
88
96
  }
89
97
  }
98
+
99
+ // Pull variations map from parameters
100
+ if (variationsMap) {
101
+ queryParams.variations_map = JSON.stringify(variationsMap);
102
+ }
90
103
  }
91
104
 
92
105
  // Pull test cells from options
@@ -129,7 +142,7 @@ function createBrowseUrlFromFilter(filterName, filterValue, parameters, userPara
129
142
  const queryParams = createQueryParams(parameters, userParameters, options);
130
143
  const queryString = qs.stringify(queryParams, { indices: false });
131
144
 
132
- return `${serviceUrl}/browse/${encodeURIComponent(filterName)}/${encodeURIComponent(filterValue)}?${queryString}`;
145
+ return `${serviceUrl}/browse/${helpers.encodeURIComponentRFC3986(helpers.trimNonBreakingSpaces(filterName))}/${helpers.encodeURIComponentRFC3986(helpers.trimNonBreakingSpaces(filterValue))}?${queryString}`;
133
146
  }
134
147
 
135
148
  // Create URL from supplied IDs and parameters
@@ -170,11 +183,13 @@ function createBrowseUrlForFacetOptions(facetName, parameters, userParameters, o
170
183
 
171
184
  const queryParams = { ...createQueryParams(parameters, userParameters, options) };
172
185
 
186
+ queryParams.facet_name = facetName;
187
+
173
188
  delete queryParams._dt;
174
189
 
175
190
  const queryString = qs.stringify(queryParams, { indices: false });
176
191
 
177
- return `${serviceUrl}/browse/facet_options?facet_name=${facetName}&${queryString}`;
192
+ return `${serviceUrl}/browse/facet_options?${queryString}`;
178
193
  }
179
194
 
180
195
  // Create request headers using supplied options and user parameters
@@ -218,7 +233,8 @@ class Browse {
218
233
  * @param {string} filterName - Filter name to display results from
219
234
  * @param {string} filterValue - Filter value to display results from
220
235
  * @param {object} [parameters] - Additional parameters to refine result set
221
- * @param {number} [parameters.page] - The page number of the results
236
+ * @param {number} [parameters.page] - The page number of the results. Can't be used together with 'offset'
237
+ * @param {number} [parameters.offset] - The number of results to skip from the beginning. Can't be used together with 'page'
222
238
  * @param {number} [parameters.resultsPerPage] - The number of results per page to return
223
239
  * @param {object} [parameters.filters] - Filters used to refine results
224
240
  * @param {string} [parameters.sortBy='relevance'] - The sort method for results
@@ -227,6 +243,7 @@ class Browse {
227
243
  * @param {object} [parameters.fmtOptions] - The format options used to refine result groups
228
244
  * @param {string[]} [parameters.hiddenFields] - Hidden metadata fields to return
229
245
  * @param {string[]} [parameters.hiddenFacets] - Hidden facet fields to return
246
+ * @param {object} [parameters.variationsMap] - The variations map object to aggregate variations. Please refer to https://docs.constructor.io/rest_api/variations_mapping for details
230
247
  * @param {object} [userParameters] - Parameters relevant to the user request
231
248
  * @param {number} [userParameters.sessionId] - Session ID, utilized to personalize results
232
249
  * @param {number} [userParameters.clientId] - Client ID, utilized to personalize results
@@ -301,7 +318,8 @@ class Browse {
301
318
  * @function getBrowseResultsForItemIds
302
319
  * @param {string[]} itemIds - Item IDs of results to fetch
303
320
  * @param {object} [parameters] - Additional parameters to refine result set
304
- * @param {number} [parameters.page] - The page number of the results
321
+ * @param {number} [parameters.page] - The page number of the results. Can't be used together with 'offset'
322
+ * @param {number} [parameters.offset] - The number of results to skip from the beginning. Can't be used together with 'page'
305
323
  * @param {number} [parameters.resultsPerPage] - The number of results per page to return
306
324
  * @param {object} [parameters.filters] - Filters used to refine results
307
325
  * @param {string} [parameters.sortBy='relevance'] - The sort method for results
@@ -310,6 +328,7 @@ class Browse {
310
328
  * @param {object} [parameters.fmtOptions] - The format options used to refine result groups
311
329
  * @param {string[]} [parameters.hiddenFields] - Hidden metadata fields to return
312
330
  * @param {string[]} [parameters.hiddenFacets] - Hidden facet fields to return
331
+ * @param {object} [parameters.variationsMap] - The variations map object to aggregate variations. Please refer to https://docs.constructor.io/rest_api/variations_mapping for details
313
332
  * @param {object} [userParameters] - Parameters relevant to the user request
314
333
  * @param {number} [userParameters.sessionId] - Session ID, utilized to personalize results
315
334
  * @param {number} [userParameters.clientId] - Client ID, utilized to personalize results
@@ -435,7 +454,8 @@ class Browse {
435
454
  *
436
455
  * @function getBrowseFacets
437
456
  * @param {object} [parameters] - Additional parameters to refine result set
438
- * @param {number} [parameters.page] - The page number of the results
457
+ * @param {number} [parameters.page] - The page number of the results. Can't be used together with 'offset'
458
+ * @param {number} [parameters.offset] - The number of results to skip from the beginning. Can't be used together with 'page'
439
459
  * @param {string} [parameters.section='Products'] - The section name for results
440
460
  * @param {number} [parameters.resultsPerPage] - The number of results per page to return
441
461
  * @param {object} [parameters.fmtOptions] - The format options used to refine result groups
@@ -39,7 +39,7 @@ function createRecommendationsUrl(podId, parameters, userParameters, options) {
39
39
  }
40
40
 
41
41
  if (parameters) {
42
- const { numResults, itemIds, section, term, filters } = parameters;
42
+ const { numResults, itemIds, section, term, filters, variationsMap } = parameters;
43
43
 
44
44
  // Pull num results number from parameters
45
45
  if (!helpers.isNil(numResults)) {
@@ -65,13 +65,18 @@ function createRecommendationsUrl(podId, parameters, userParameters, options) {
65
65
  if (filters) {
66
66
  queryParams.filters = filters;
67
67
  }
68
+
69
+ // Pull variations map from parameters
70
+ if (variationsMap) {
71
+ queryParams.variations_map = JSON.stringify(variationsMap);
72
+ }
68
73
  }
69
74
 
70
75
  queryParams = helpers.cleanParams(queryParams);
71
76
 
72
77
  const queryString = qs.stringify(queryParams, { indices: false });
73
78
 
74
- return `${serviceUrl}/recommendations/v1/pods/${podId}?${queryString}`;
79
+ return `${serviceUrl}/recommendations/v1/pods/${helpers.encodeURIComponentRFC3986(helpers.trimNonBreakingSpaces(podId))}?${queryString}`;
75
80
  }
76
81
 
77
82
  /**
@@ -97,6 +102,7 @@ class Recommendations {
97
102
  * @param {string} [parameters.section] - The section to return results from
98
103
  * @param {string} [parameters.term] - The term to use to refine results (strategy specific)
99
104
  * @param {object} [parameters.filters] - Filters used to refine results (strategy specific)
105
+ * @param {object} [parameters.variationsMap] - The variations map object to aggregate variations. Please refer to https://docs.constructor.io/rest_api/variations_mapping for details
100
106
  * @param {object} [userParameters] - Parameters relevant to the user request
101
107
  * @param {number} [userParameters.sessionId] - Session ID, utilized to personalize results
102
108
  * @param {number} [userParameters.clientId] - Client ID, utilized to personalize results
@@ -1,3 +1,4 @@
1
+ /* eslint-disable max-len */
1
2
  /* eslint-disable object-curly-newline, no-underscore-dangle */
2
3
  const qs = require('qs');
3
4
  const nodeFetch = require('node-fetch').default;
@@ -5,6 +6,7 @@ const { AbortController } = require('node-abort-controller');
5
6
  const helpers = require('../utils/helpers');
6
7
 
7
8
  // Create URL from supplied query (term) and parameters
9
+ // eslint-disable-next-line complexity
8
10
  function createSearchUrl(query, parameters, userParameters, options) {
9
11
  const {
10
12
  apiKey,
@@ -49,6 +51,7 @@ function createSearchUrl(query, parameters, userParameters, options) {
49
51
  if (parameters) {
50
52
  const {
51
53
  page,
54
+ offset,
52
55
  resultsPerPage,
53
56
  filters,
54
57
  sortBy,
@@ -57,6 +60,7 @@ function createSearchUrl(query, parameters, userParameters, options) {
57
60
  fmtOptions,
58
61
  hiddenFields,
59
62
  hiddenFacets,
63
+ variationsMap,
60
64
  } = parameters;
61
65
 
62
66
  // Pull page from parameters
@@ -64,6 +68,11 @@ function createSearchUrl(query, parameters, userParameters, options) {
64
68
  queryParams.page = page;
65
69
  }
66
70
 
71
+ // Pull offset from parameters
72
+ if (!helpers.isNil(offset)) {
73
+ queryParams.offset = offset;
74
+ }
75
+
67
76
  // Pull results per page from parameters
68
77
  if (!helpers.isNil(resultsPerPage)) {
69
78
  queryParams.num_results_per_page = resultsPerPage;
@@ -111,6 +120,11 @@ function createSearchUrl(query, parameters, userParameters, options) {
111
120
  queryParams.fmt_options = { hidden_facets: hiddenFacets };
112
121
  }
113
122
  }
123
+
124
+ // Pull variations map from parameters
125
+ if (variationsMap) {
126
+ queryParams.variations_map = JSON.stringify(variationsMap);
127
+ }
114
128
  }
115
129
 
116
130
  queryParams._dt = Date.now();
@@ -118,7 +132,7 @@ function createSearchUrl(query, parameters, userParameters, options) {
118
132
 
119
133
  const queryString = qs.stringify(queryParams, { indices: false });
120
134
 
121
- return `${serviceUrl}/search/${encodeURIComponent(query)}?${queryString}`;
135
+ return `${serviceUrl}/search/${helpers.encodeURIComponentRFC3986(helpers.trimNonBreakingSpaces(query))}?${queryString}`;
122
136
  }
123
137
 
124
138
  /**
@@ -139,7 +153,8 @@ class Search {
139
153
  * @function getSearchResults
140
154
  * @param {string} query - Term to use to perform a search
141
155
  * @param {object} [parameters] - Additional parameters to refine result set
142
- * @param {number} [parameters.page] - The page number of the results
156
+ * @param {number} [parameters.page] - The page number of the results. Can't be used together with 'offset'
157
+ * @param {number} [parameters.offset] - The number of results to skip from the beginning. Can't be used together with 'page'
143
158
  * @param {number} [parameters.resultsPerPage] - The number of results per page to return
144
159
  * @param {object} [parameters.filters] - Filters used to refine search
145
160
  * @param {string} [parameters.sortBy='relevance'] - The sort method for results
@@ -148,6 +163,7 @@ class Search {
148
163
  * @param {object} [parameters.fmtOptions] - The format options used to refine result groups
149
164
  * @param {string[]} [parameters.hiddenFields] - Hidden metadata fields to return
150
165
  * @param {string[]} [parameters.hiddenFacets] - Hidden facet fields to return
166
+ * @param {object} [parameters.variationsMap] - The variations map object to aggregate variations. Please refer to https://docs.constructor.io/rest_api/variations_mapping for details
151
167
  * @param {object} [userParameters] - Parameters relevant to the user request
152
168
  * @param {number} [userParameters.sessionId] - Session ID, utilized to personalize results
153
169
  * @param {number} [userParameters.clientId] - Client ID, utilized to personalize results
@@ -385,7 +385,7 @@ class Tracker {
385
385
  if (term && typeof term === 'string') {
386
386
  // Ensure parameters are provided (required)
387
387
  if (parameters && typeof parameters === 'object' && !Array.isArray(parameters)) {
388
- const url = `${this.options.serviceUrl}/autocomplete/${helpers.ourEncodeURIComponent(term)}/select?`;
388
+ const url = `${this.options.serviceUrl}/autocomplete/${helpers.encodeURIComponentRFC3986(helpers.trimNonBreakingSpaces(term))}/select?`;
389
389
  const queryParams = {};
390
390
  const {
391
391
  original_query,
@@ -479,7 +479,7 @@ class Tracker {
479
479
  if (term && typeof term === 'string') {
480
480
  // Ensure parameters are provided (required)
481
481
  if (parameters && typeof parameters === 'object' && !Array.isArray(parameters)) {
482
- const url = `${this.options.serviceUrl}/autocomplete/${helpers.ourEncodeURIComponent(term)}/search?`;
482
+ const url = `${this.options.serviceUrl}/autocomplete/${helpers.encodeURIComponentRFC3986(helpers.trimNonBreakingSpaces(term))}/search?`;
483
483
  const queryParams = {};
484
484
  const { original_query, group_id, display_name } = parameters;
485
485
 
@@ -641,7 +641,7 @@ class Tracker {
641
641
  if (term && typeof term === 'string') {
642
642
  // Ensure parameters are provided (required)
643
643
  if (parameters && typeof parameters === 'object' && !Array.isArray(parameters)) {
644
- const url = `${this.options.serviceUrl}/autocomplete/${helpers.ourEncodeURIComponent(term)}/click_through?`;
644
+ const url = `${this.options.serviceUrl}/autocomplete/${helpers.encodeURIComponentRFC3986(helpers.trimNonBreakingSpaces(term))}/click_through?`;
645
645
  const queryParams = {};
646
646
  const { item_name, name, item_id, customer_id, variation_id, result_id } = parameters;
647
647
 
@@ -740,7 +740,7 @@ class Tracker {
740
740
  trackConversion(term, parameters, userParameters, networkParameters = {}) {
741
741
  // Ensure parameters are provided (required)
742
742
  if (parameters && typeof parameters === 'object' && !Array.isArray(parameters)) {
743
- const searchTerm = helpers.ourEncodeURIComponent(term) || 'TERM_UNKNOWN';
743
+ const searchTerm = term || 'TERM_UNKNOWN';
744
744
  const requestPath = `${this.options.serviceUrl}/v2/behavioral_action/conversion?`;
745
745
  const queryParams = {};
746
746
  const bodyParams = {};
@@ -1,22 +1,9 @@
1
1
  /* eslint-disable no-param-reassign */
2
- const qs = require('qs');
3
-
4
2
  const utils = {
5
- ourEncodeURIComponent: (str) => {
6
- if (str && typeof str === 'string') {
7
- const cleanedString = str
8
- .replace(/\[/g, '%5B') // Replace [
9
- .replace(/\]/g, '%5D') // Replace ]
10
- .replace(/&/g, '%26'); // Replace &
11
- const trimmedCleanedString = cleanedString.trim();
12
- const parsedStrObj = qs.parse(`s=${trimmedCleanedString}`);
13
-
14
- parsedStrObj.s = parsedStrObj.s.replace(/\s/g, ' ');
3
+ trimNonBreakingSpaces: (string) => string.replace(/\s/g, ' ').trim(),
15
4
 
16
- return qs.stringify(parsedStrObj).split('=')[1];
17
- }
18
- return null;
19
- },
5
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
6
+ encodeURIComponentRFC3986: (string) => encodeURIComponent(string).replace(/[!'()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`),
20
7
 
21
8
  cleanParams: (paramsObj) => {
22
9
  const cleanedParams = {};
@@ -27,7 +14,7 @@ const utils = {
27
14
  if (typeof paramValue === 'string') {
28
15
  // Replace non-breaking spaces (or any other type of spaces caught by the regex)
29
16
  // - with a regular white space
30
- cleanedParams[paramKey] = decodeURIComponent(utils.ourEncodeURIComponent(paramValue));
17
+ cleanedParams[paramKey] = utils.trimNonBreakingSpaces(paramValue);
31
18
  } else {
32
19
  cleanedParams[paramKey] = paramValue;
33
20
  }