@constructor-io/constructorio-node 4.4.4 → 4.4.6

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,11 +1,12 @@
1
1
  {
2
2
  "name": "@constructor-io/constructorio-node",
3
- "version": "4.4.4",
3
+ "version": "4.4.6",
4
4
  "description": "Constructor.io Node.js client",
5
5
  "main": "src/constructorio.js",
6
6
  "types": "src/types/constructorio.d.ts",
7
7
  "scripts": {
8
- "version": "chmod +x ./scripts/verify-node-version.sh && ./scripts/verify-node-version.sh && npm run docs && git add ./docs/*",
8
+ "verify-node-version": "chmod +x ./scripts/verify-node-version.sh && ./scripts/verify-node-version.sh",
9
+ "version": "npm run verify-node-version && npm run docs && git add ./docs/*",
9
10
  "check-lisc": "license-checker --production --onlyAllow 'Apache-2.0;BSD-3-Clause;MIT'",
10
11
  "lint": "eslint 'src/**/*.js' 'spec/**/*.js' 'src/**/*.d.ts'",
11
12
  "test:parallel": "mkdir -p test && cp -rf src/* test && mocha --parallel ./spec/*",
@@ -6,7 +6,7 @@ const helpers = require('../utils/helpers');
6
6
 
7
7
  // Create URL from supplied query (term) and parameters
8
8
  // eslint-disable-next-line complexity
9
- function createSearchUrl(query, parameters, userParameters, options) {
9
+ function createSearchUrl(query, parameters, userParameters, options, isVoiceSearch = false) {
10
10
  const {
11
11
  apiKey,
12
12
  version,
@@ -137,7 +137,9 @@ function createSearchUrl(query, parameters, userParameters, options) {
137
137
 
138
138
  const queryString = qs.stringify(queryParams, { indices: false });
139
139
 
140
- return `${serviceUrl}/search/${helpers.encodeURIComponentRFC3986(helpers.trimNonBreakingSpaces(query))}?${queryString}`;
140
+ const searchUrl = isVoiceSearch ? 'search/natural_language' : 'search';
141
+
142
+ return `${serviceUrl}/${searchUrl}/${helpers.encodeURIComponentRFC3986(helpers.trimNonBreakingSpaces(query))}?${queryString}`;
141
143
  }
142
144
 
143
145
  /**
@@ -255,6 +257,105 @@ class Search {
255
257
  throw new Error('getSearchResults response data is malformed');
256
258
  });
257
259
  }
260
+
261
+ /**
262
+ * Retrieve voice search results from API
263
+ *
264
+ * @function getVoiceSearchResults
265
+ * @param {string} query - Term to use to perform a voice search
266
+ * @param {object} [parameters] - Additional parameters to refine result set
267
+ * @param {number} [parameters.page] - The page number of the results. Can't be used together with 'offset'
268
+ * @param {number} [parameters.offset] - The number of results to skip from the beginning. Can't be used together with 'page'
269
+ * @param {number} [parameters.resultsPerPage] - The number of results per page to return
270
+ * @param {string} [parameters.section='Products'] - The section name for results
271
+ * @param {object} [parameters.fmtOptions] - The format options used to refine result groups
272
+ * @param {string[]} [parameters.hiddenFields] - Hidden metadata fields to return
273
+ * @param {string[]} [parameters.hiddenFacets] - Hidden facet fields to return
274
+ * @param {object} [parameters.variationsMap] - The variations map object to aggregate variations. Please refer to https://docs.constructor.io/rest_api/variations_mapping for details
275
+ * @param {object} [parameters.preFilterExpression] - Faceting expression to scope search results. Please refer to https://docs.constructor.io/rest_api/collections/#add-items-dynamically for details
276
+ * @param {object} [userParameters] - Parameters relevant to the user request
277
+ * @param {number} [userParameters.sessionId] - Session ID, utilized to personalize results
278
+ * @param {number} [userParameters.clientId] - Client ID, utilized to personalize results
279
+ * @param {string} [userParameters.userId] - User ID, utilized to personalize results
280
+ * @param {string} [userParameters.segments] - User segments
281
+ * @param {object} [userParameters.testCells] - User test cells
282
+ * @param {string} [userParameters.userIp] - Origin user IP, from client
283
+ * @param {string} [userParameters.userAgent] - Origin user agent, from client
284
+ * @param {object} [networkParameters] - Parameters relevant to the network request
285
+ * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
286
+ * @returns {Promise}
287
+ * @see https://docs.constructor.io/rest_api/search/natural_language_search/
288
+ * @example
289
+ * constructorio.search.getVoiceSearchResults('show me lipstick', {
290
+ * resultsPerPage: 40,
291
+ * }, {
292
+ * testCells: {
293
+ * testName: 'cellName',
294
+ * },
295
+ * });
296
+ */
297
+
298
+ getVoiceSearchResults(query, parameters = {}, userParameters = {}, networkParameters = {}) {
299
+ let requestUrl;
300
+ const { fetch } = this.options;
301
+ const controller = new AbortController();
302
+ const { signal } = controller;
303
+ const headers = {};
304
+
305
+ try {
306
+ const isVoiceSearch = true;
307
+ requestUrl = createSearchUrl(query, parameters, userParameters, this.options, isVoiceSearch);
308
+ } catch (e) {
309
+ return Promise.reject(e);
310
+ }
311
+
312
+ Object.assign(headers, helpers.combineCustomHeaders(this.options, networkParameters));
313
+
314
+ // Append security token as 'x-cnstrc-token' if available
315
+ if (this.options.securityToken && typeof this.options.securityToken === 'string') {
316
+ headers['x-cnstrc-token'] = this.options.securityToken;
317
+ }
318
+
319
+ // Append user IP as 'X-Forwarded-For' if available
320
+ if (userParameters.userIp && typeof userParameters.userIp === 'string') {
321
+ headers['X-Forwarded-For'] = userParameters.userIp;
322
+ }
323
+
324
+ // Append user agent as 'User-Agent' if available
325
+ if (userParameters.userAgent && typeof userParameters.userAgent === 'string') {
326
+ headers['User-Agent'] = userParameters.userAgent;
327
+ }
328
+
329
+ // Handle network timeout if specified
330
+ helpers.applyNetworkTimeout(this.options, networkParameters, controller);
331
+
332
+ return fetch(requestUrl, { headers, signal }).then((response) => {
333
+ if (response.ok) {
334
+ return response.json();
335
+ }
336
+
337
+ return helpers.throwHttpErrorFromResponse(new Error(), response);
338
+ }).then((json) => {
339
+ // Search results
340
+ if (json.response && json.response.results) {
341
+ if (json.result_id) {
342
+ json.response.results.forEach((result) => {
343
+ // eslint-disable-next-line no-param-reassign
344
+ result.result_id = json.result_id;
345
+ });
346
+ }
347
+
348
+ return json;
349
+ }
350
+
351
+ // Redirect rules
352
+ if (json.response && json.response.redirect) {
353
+ return json;
354
+ }
355
+
356
+ throw new Error('getVoiceSearchResults response data is malformed');
357
+ });
358
+ }
258
359
  }
259
360
 
260
361
  module.exports = Search;
@@ -40,6 +40,13 @@ declare class Search {
40
40
  userParameters?: UserParameters,
41
41
  networkParameters?: NetworkParameters
42
42
  ): Promise<SearchResponse>;
43
+
44
+ getVoiceSearchResults(
45
+ query: string,
46
+ parameters?: Omit<SearchParameters, 'filters' | 'sortBy' | 'sortOrder'>,
47
+ userParameters?: UserParameters,
48
+ networkParameters?: NetworkParameters
49
+ ): Promise<SearchResponse>;
43
50
  }
44
51
 
45
52
  /* search results returned from server */
@@ -66,6 +73,7 @@ export interface SearchRequestType extends Record<string, any> {
66
73
  section: string;
67
74
  blacklist_rules: boolean;
68
75
  term: string;
76
+ original_query?: string;
69
77
  fmt_options: Partial<FmtOption>;
70
78
  sort_by: string;
71
79
  sort_order: string;