@constructor-io/constructorio-node 3.10.6 → 4.0.0

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
@@ -11,6 +11,8 @@ A Node.js client for [Constructor.io](http://constructor.io/). [Constructor.io](
11
11
  ## Documentation
12
12
  Full API documentation is available on [Github Pages](https://constructor-io.github.io/constructorio-node)
13
13
 
14
+ Updating from v3 to v4? Be sure to read the [upgrade guide](https://github.com/Constructor-io/constructorio-node/wiki/Migration-Guide---V3-to-V4) for an explanation of changes made to the Catalog module
15
+
14
16
  ## 1. Review the Requirements
15
17
 
16
18
  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 the [Additional Information For Backend Integrations](https://github.com/Constructor-io/constructorio-node/wiki/Additional-Information-For-Backend-Integrations) article within the wiki for more detail.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructor-io/constructorio-node",
3
- "version": "3.10.6",
3
+ "version": "4.0.0",
4
4
  "description": "Constructor.io Node.js client",
5
5
  "main": "src/constructorio.js",
6
6
  "scripts": {
@@ -10,7 +10,7 @@
10
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
- "postcoverage": "serve --listen 8080 --config ./serve.json && rm -rf test",
13
+ "postcoverage": "open coverage/index.html && rm -rf test",
14
14
  "docs": "jsdoc --configure ./.jsdoc.json ./README.md --recurse ./src --destination ./docs",
15
15
  "prepare": "husky install"
16
16
  },
@@ -40,14 +40,11 @@
40
40
  "eslint-plugin-import": "^2.24.2",
41
41
  "husky": "^7.0.4",
42
42
  "jsdoc": "^3.6.7",
43
- "jsdom": "^15.1.1",
44
43
  "license-checker": "^25.0.1",
45
44
  "lodash.clonedeep": "^4.5.0",
46
45
  "minami": "^1.2.3",
47
46
  "mocha": "^9.1.3",
48
- "mocha-jsdom": "^2.0.0",
49
47
  "nyc": "^15.1.0",
50
- "serve": "^13.0.2",
51
48
  "sinon": "^7.5.0",
52
49
  "sinon-chai": "^3.7.0",
53
50
  "uuid": "^8.3.2"
package/src/.DS_Store ADDED
Binary file
@@ -1,3 +1,4 @@
1
+ /* eslint-disable camelcase */
1
2
  /* eslint-disable object-curly-newline, no-underscore-dangle, max-len */
2
3
  const qs = require('qs');
3
4
  const nodeFetch = require('node-fetch').default;
@@ -55,7 +56,7 @@ async function createQueryParamsAndFormData(parameters) {
55
56
  const formData = new FormData();
56
57
 
57
58
  if (parameters) {
58
- const { section, notification_email: notificationEmail, force } = parameters;
59
+ const { section, notificationEmail, force } = parameters;
59
60
  let { items, variations, item_groups: itemGroups } = parameters;
60
61
 
61
62
  try {
@@ -130,54 +131,62 @@ class Catalog {
130
131
  }
131
132
 
132
133
  /**
133
- * Add item to index
134
+ * Adds multiple items to your index whilst replacing existing ones (limit of 1,000)
134
135
  *
135
- * @function addItem
136
+ * @function createOrReplaceItems
136
137
  * @param {object} parameters - Additional parameters for item details
137
- * @param {string} parameters.item_name - The name of the item, as it will appear in the results
138
- * @param {string} parameters.section - Your autosuggest and search results can have multiple sections like "Products" and "Search Suggestions". This indicates which section this item is for
139
- * @param {number} [parameters.suggested_score] - A number between 1 and 100 million that will influence the item's initial ranking relative to other item scores (the higher the score, the higher in the list of suggestions the item will appear)
140
- * @param {string[]} [parameters.keywords] - An array of keywords for this item. Keywords are useful if you want a product name to appear when a user enters a search term that isn't in the product name itself
141
- * @param {string} [parameters.url] - A URL to directly send the user after selecting the item
142
- * @param {string} [parameters.image_url] - A URL that points to an image you'd like displayed next to some item (only applicable when URL is supplied)
143
- * @param {string} [parameters.description] - A description for some item (only applicable when URL is supplied)
144
- * @param {string} [parameters.id] - An arbitrary ID you would like associated with this item. You can use this field to store your own IDs of the items to more easily access them in other API calls
145
- * @param {object} [parameters.facets] - Key/value pairs that can be associated with an item and used to filter them during a search. You can associate multiple values with the same key, by making values a list. Facets can be used as filters in search, autosuggest, and browse requests
146
- * @param {object} [parameters.metadata] - You can associate schema-less data with items by passing in an object of keys and values. To configure search and display of this data reach out to support@constructor.io
147
- * @param {string[]} [parameters.group_ids] - You can associate each item with one or more groups (i.e. categories). To set up a group hierarchy please contact support@constructor.io. group_ids can be used as filters in search, autosuggest, and browse requests
148
- * @param {object[]} [parameters.variations] - List of this item's variations
138
+ * @param {object[]} parameters.items - A list of items with the same attributes as defined in the Item schema resource (https://docs.constructor.io/rest_api/items/items/#item-schema)
139
+ * @param {boolean} [parameters.force=false] - Process the request even if it will invalidate a large number of existing items
140
+ * @param {string} [parameters.notificationEmail] - An email address where you'd like to receive an email notification in case the task fails
141
+ * @param {string} [parameters.section="Products"] - This indicates which section to operate on within the index
149
142
  * @param {object} [networkParameters] - Parameters relevant to the network request
150
143
  * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
151
144
  * @returns {Promise}
152
- * @see https://docs.constructor.io/rest_api/items/v1/add_an_item
145
+ * @see https://docs.constructor.io/rest_api/items/items#create-or-replace-items
153
146
  * @example
154
- * constructorio.catalog.addItem({
155
- * item_name: 'black pullover hoodie',
156
- * section: 'Products',
157
- * keywords: ['black', 'hoodie', 'tops', 'outerwear'],
158
- * url: '/products/blk_pllvr_hd_001'
159
- * image_url: '/products/images/blk_pllvr_hd_001'
160
- * description: 'a short description about the black pullover hoodie',
161
- * id: 'blk_pllvr_hd_001',
162
- * facets: {
163
- * size: 'medium',
164
- * color: 'black',
165
- * },
166
- * metadata: {
167
- * swatch_image_url: '/products/swatch_images/blk_pllvr_hd_001',
168
- * on_sale: true,
169
- * },
170
- * group_ids: ['cat_49203', 'subcat_12891'],
147
+ * constructorio.catalog.createOrReplaceItems({
148
+ * items: [
149
+ * {
150
+ * name: 'midnight black pullover hoodie',
151
+ * id: 'blk_pllvr_hd_001',
152
+ * data: {
153
+ * keywords: ['midnight black', 'black', 'hoodie', 'tops', 'outerwear'],
154
+ * url: '/products/blk_pllvr_hd_001'
155
+ * image_url: '/products/images/blk_pllvr_hd_001'
156
+ * description: 'a modified short description about the black pullover hoodie',
157
+ * }
158
+ * },
159
+ * ...
160
+ * ],
171
161
  * });
172
162
  */
173
- addItem(parameters = {}, networkParameters = {}) {
163
+ createOrReplaceItems(parameters = {}, networkParameters = {}) {
174
164
  let requestUrl;
175
165
  const fetch = (this.options && this.options.fetch) || nodeFetch;
176
166
  const controller = new AbortController();
177
167
  const { signal } = controller;
168
+ const { items, section, force, notificationEmail } = parameters;
169
+ const queryParams = {};
170
+
171
+ // Validate items is provided
172
+ if (!items || !Array.isArray(items)) {
173
+ return Promise.reject(new Error('items is a required parameter of type array'));
174
+ }
175
+
176
+ if (section) {
177
+ queryParams.section = section;
178
+ }
179
+
180
+ if (force) {
181
+ queryParams.force = force;
182
+ }
183
+
184
+ if (notificationEmail) {
185
+ queryParams.notification_email = notificationEmail;
186
+ }
178
187
 
179
188
  try {
180
- requestUrl = createCatalogUrl('item', this.options);
189
+ requestUrl = createCatalogUrl('items', this.options, queryParams, 'v2');
181
190
  } catch (e) {
182
191
  return Promise.reject(e);
183
192
  }
@@ -186,8 +195,8 @@ class Catalog {
186
195
  helpers.applyNetworkTimeout(this.options, networkParameters, controller);
187
196
 
188
197
  return fetch(requestUrl, {
189
- method: 'POST',
190
- body: JSON.stringify(parameters),
198
+ method: 'PUT',
199
+ body: JSON.stringify({ items }),
191
200
  headers: {
192
201
  'Content-Type': 'application/json',
193
202
  ...helpers.createAuthHeader(this.options),
@@ -203,54 +212,63 @@ class Catalog {
203
212
  }
204
213
 
205
214
  /**
206
- * Add item to index or updates it if it already exists
215
+ * Update multiple items to index (limit of 1,000)
207
216
  *
208
- * @function addOrUpdateItem
217
+ * @function updateItems
209
218
  * @param {object} parameters - Additional parameters for item details
210
- * @param {string} parameters.item_name - The name of the item, as it will appear in the results
211
- * @param {string} parameters.section - Your autosuggest and search results can have multiple sections like "Products" and "Search Suggestions". This indicates which section this item is for
212
- * @param {number} [parameters.suggested_score] - A number between 1 and 100 million that will influence the item's initial ranking relative to other item scores (the higher the score, the higher in the list of suggestions the item will appear)
213
- * @param {string[]} [parameters.keywords] - An array of keywords for this item. Keywords are useful if you want a product name to appear when a user enters a searchterm that isn't in the product name itself
214
- * @param {string} [parameters.url] - A URL to directly send the user after selecting the item
215
- * @param {string} [parameters.image_url] - A URL that points to an image you'd like displayed next to some item (only applicable when URL is supplied)
216
- * @param {string} [parameters.description] - A description for some item (only applicable when URL is supplied)
217
- * @param {string} [parameters.id] - An arbitrary ID you would like associated with this item. You can use this field to store your own IDs of the items to more easily access them in other API calls
218
- * @param {object} [parameters.facets] - Key/value pairs that can be associated with an item and used to filter them during a search. You can associate multiple values with the same key, by making values a list. Facets can be used as filters in search, autosuggest, and browse requests
219
- * @param {object} [parameters.metadata] - You can associate schema-less data with items by passing in an object of keys and values. To configure search and display of this data reach out to support@constructor.io
220
- * @param {string[]} [parameters.group_ids] - You can associate each item with one or more groups (i.e. categories). To set up a group hierarchy please contact support@constructor.io. group_ids can be used as filters in search, autosuggest, and browse requests
221
- * @param {object[]} [parameters.variations] - List of this item's variations
219
+ * @param {object[]} parameters.items - A list of items with the same attributes as defined in the Item schema resource (https://docs.constructor.io/rest_api/items/items/#item-schema)
220
+ * @param {boolean} [parameters.force=false] - Process the request even if it will invalidate a large number of existing items
221
+ * @param {string} [parameters.notificationEmail] - An email address where you'd like to receive an email notification in case the task fails
222
+ * @param {string} [parameters.section="Products"] - This indicates which section to operate on within the index
222
223
  * @param {object} [networkParameters] - Parameters relevant to the network request
223
224
  * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
224
225
  * @returns {Promise}
225
- * @see https://docs.constructor.io/rest_api/items/v1/add_or_update_an_item
226
+ * @see https://docs.constructor.io/rest_api/items/items#update-items
226
227
  * @example
227
- * constructorio.catalog.addOrUpdateItem({
228
- * item_name: 'black pullover hoodie',
228
+ * constructorio.catalog.updateItems({
229
+ * items: [
230
+ * {
231
+ * name: 'midnight black pullover hoodie',
232
+ * id: 'blk_pllvr_hd_001',
233
+ * data: {
234
+ * keywords: ['midnight black', 'black', 'hoodie', 'tops', 'outerwear'],
235
+ * url: '/products/blk_pllvr_hd_001'
236
+ * image_url: '/products/images/blk_pllvr_hd_001'
237
+ * description: 'a modified short description about the black pullover hoodie',
238
+ * }
239
+ * },
240
+ * . . .
241
+ * ],
229
242
  * section: 'Products',
230
- * keywords: ['black', 'hoodie', 'tops', 'outerwear'],
231
- * url: '/products/blk_pllvr_hd_001'
232
- * image_url: '/products/images/blk_pllvr_hd_001'
233
- * description: 'a short description about the black pullover hoodie',
234
- * id: 'blk_pllvr_hd_001',
235
- * facets: {
236
- * size: 'medium',
237
- * color: 'black',
238
- * },
239
- * metadata: {
240
- * swatch_image_url: '/products/swatch_images/blk_pllvr_hd_001',
241
- * on_sale: true,
242
- * },
243
- * group_ids: ['cat_49203', 'subcat_12891'],
244
243
  * });
245
244
  */
246
- addOrUpdateItem(parameters = {}, networkParameters = {}) {
245
+ updateItems(parameters = {}, networkParameters = {}) {
247
246
  let requestUrl;
248
247
  const fetch = (this.options && this.options.fetch) || nodeFetch;
249
248
  const controller = new AbortController();
250
249
  const { signal } = controller;
250
+ const { items, section, force, notificationEmail } = parameters;
251
+ const queryParams = {};
252
+
253
+ // Validate items is provided
254
+ if (!items || !Array.isArray(items)) {
255
+ return Promise.reject(new Error('items is a required parameter of type array'));
256
+ }
257
+
258
+ if (notificationEmail) {
259
+ queryParams.notification_email = notificationEmail;
260
+ }
261
+
262
+ if (section) {
263
+ queryParams.section = section;
264
+ }
265
+
266
+ if (force) {
267
+ queryParams.force = force;
268
+ }
251
269
 
252
270
  try {
253
- requestUrl = `${createCatalogUrl('item', this.options)}&force=1`;
271
+ requestUrl = createCatalogUrl('items', this.options, queryParams, 'v2');
254
272
  } catch (e) {
255
273
  return Promise.reject(e);
256
274
  }
@@ -259,8 +277,8 @@ class Catalog {
259
277
  helpers.applyNetworkTimeout(this.options, networkParameters, controller);
260
278
 
261
279
  return fetch(requestUrl, {
262
- method: 'PUT',
263
- body: JSON.stringify(parameters),
280
+ method: 'PATCH',
281
+ body: JSON.stringify({ items }),
264
282
  headers: {
265
283
  'Content-Type': 'application/json',
266
284
  ...helpers.createAuthHeader(this.options),
@@ -276,31 +294,53 @@ class Catalog {
276
294
  }
277
295
 
278
296
  /**
279
- * Remove item from index
297
+ * Remove multiple items from your index (limit of 1,000)
280
298
  *
281
- * @function removeItem
299
+ * @function deleteItems
282
300
  * @param {object} parameters - Additional parameters for item details
283
- * @param {string} parameters.item_name - The name of the item, as it will appear in the results
284
- * @param {string} parameters.section - Your autosuggest and search results can have multiple sections like "Products" and "Search Suggestions". This indicates which section this item is for
285
- * @param {string} parameters.id - An arbitrary ID you optionally specified when adding the item. If supplied, you don't need to pass in item_name
301
+ * @param {object[]} parameters.items - A list of items with the same attributes as defined in the Item schema resource (https://docs.constructor.io/rest_api/items/items/#item-schema)
302
+ * @param {string} [parameters.section="Products"] - This indicates which section to operate on within the index
303
+ * @param {string} [parameters.notificationEmail] - An email address where you'd like to receive an email notification in case the task fails
286
304
  * @param {object} [networkParameters] - Parameters relevant to the network request
287
305
  * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
288
306
  * @returns {Promise}
289
- * @see https://docs.constructor.io/rest_api/items/v1/remove_an_item
307
+ * @see https://docs.constructor.io/rest_api/items/items#delete-items
290
308
  * @example
291
- * constructorio.catalog.removeItem({
292
- * id: 'blk_pllvr_hd_001',
309
+ * constructorio.catalog.deleteItems({
310
+ * items: [
311
+ * { id: 'blk_pllvr_hd_001' },
312
+ * { id: 'red_pllvr_hd_02' },
313
+ * ],
293
314
  * section: 'Products',
294
315
  * });
295
316
  */
296
- removeItem(parameters = {}, networkParameters = {}) {
317
+ deleteItems(parameters = {}, networkParameters = {}) {
297
318
  let requestUrl;
298
319
  const fetch = (this.options && this.options.fetch) || nodeFetch;
299
320
  const controller = new AbortController();
300
321
  const { signal } = controller;
322
+ const { items, section, force, notificationEmail } = parameters;
323
+ const queryParams = {};
324
+
325
+ // Validate items is provided
326
+ if (!items || !Array.isArray(items)) {
327
+ return Promise.reject(new Error('items is a required parameter of type array'));
328
+ }
329
+
330
+ if (section) {
331
+ queryParams.section = section;
332
+ }
333
+
334
+ if (force) {
335
+ queryParams.force = force;
336
+ }
337
+
338
+ if (notificationEmail) {
339
+ queryParams.notification_email = notificationEmail;
340
+ }
301
341
 
302
342
  try {
303
- requestUrl = createCatalogUrl('item', this.options);
343
+ requestUrl = createCatalogUrl('items', this.options, queryParams, 'v2');
304
344
  } catch (e) {
305
345
  return Promise.reject(e);
306
346
  }
@@ -310,7 +350,7 @@ class Catalog {
310
350
 
311
351
  return fetch(requestUrl, {
312
352
  method: 'DELETE',
313
- body: JSON.stringify(parameters),
353
+ body: JSON.stringify({ items }),
314
354
  headers: {
315
355
  'Content-Type': 'application/json',
316
356
  ...helpers.createAuthHeader(this.options),
@@ -326,55 +366,58 @@ class Catalog {
326
366
  }
327
367
 
328
368
  /**
329
- * Modify an item in index
369
+ * Retrieves item(s) from index for the given section or specific item ID
330
370
  *
331
- * @function modifyItem
371
+ * @function retrieveItems
332
372
  * @param {object} parameters - Additional parameters for item details
333
- * @param {string} parameters.item_name - The name of the item, as it will appear in the results
334
- * @param {string} parameters.new_item_name - The new name of the item, as it you'd like it to appear in the results
335
- * @param {string} parameters.section - Your autosuggest and search results can have multiple sections like "Products" and "Search Suggestions". This indicates which section this item is for
336
- * @param {number} [parameters.suggested_score] - A number between 1 and 100 million that will influence the item's initial ranking relative to other item scores (the higher the score, the higher in the list of suggestions the item will appear)
337
- * @param {string[]} [parameters.keywords] - An array of keywords for this item. Keywords are useful if you want a product name to appear when a user enters a searchterm that isn't in the product name itself
338
- * @param {string} [parameters.url] - A URL to directly send the user after selecting the item
339
- * @param {string} [parameters.image_url] - A URL that points to an image you'd like displayed next to some item (only applicable when URL is supplied)
340
- * @param {string} [parameters.description] - A description for some item (only applicable when URL is supplied)
341
- * @param {string} [parameters.id] - An arbitrary ID you would like associated with this item. You can use this field to store your own IDs of the items to more easily access them in other API calls
342
- * @param {object} [parameters.facets] - Key/value pairs that can be associated with an item and used to filter them during a search. You can associate multiple values with the same key, by making values a list. Facets can be used as filters in search, autosuggest, and browse requests
343
- * @param {object} [parameters.metadata] - You can associate schema-less data with items by passing in an object of keys and values. To configure search and display of this data reach out to support@constructor.io
344
- * @param {string[]} [parameters.group_ids] - You can associate each item with one or more groups (i.e. categories). To set up a group hierarchy please contact support@constructor.io. group_ids can be used as filters in search, autosuggest, and browse requests
345
- * @param {object[]} [parameters.variations] - List of this item's variations
373
+ * @param {string[]} [parameters.ids] - Id(s) of items to return (1,000 maximum)
374
+ * @param {string} [parameters.section] - This indicates which section to operate on within the index
375
+ * @param {number} [parameters.numResultsPerPage=100] - The number of items to return
376
+ * @param {number} [parameters.page=1] - The page of results to return
346
377
  * @param {object} [networkParameters] - Parameters relevant to the network request
347
378
  * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
348
379
  * @returns {Promise}
349
- * @see https://docs.constructor.io/rest_api/items/v1/modify_an_item
380
+ * @see https://docs.constructor.io/rest_api/items/items#retrieve-items
350
381
  * @example
351
- * constructorio.catalog.modifyItem({
352
- * item_name: 'midnight black pullover hoodie',
382
+ * constructorio.catalog.retrieveItems({
353
383
  * section: 'Products',
354
- * keywords: ['midnight black', 'black', 'hoodie', 'tops', 'outerwear'],
355
- * url: '/products/blk_pllvr_hd_001'
356
- * image_url: '/products/images/blk_pllvr_hd_001'
357
- * description: 'a modified short description about the black pullover hoodie',
358
- * id: 'blk_pllvr_hd_001',
359
- * facets: {
360
- * size: 'large',
361
- * color: 'midnight black',
362
- * },
363
- * metadata: {
364
- * swatch_image_url: '/products/swatch_images/blk_pllvr_hd_001',
365
- * on_sale: true,
366
- * },
367
- * group_ids: ['cat_49203', 'subcat_12891'],
384
+ * numResultsPerPage: 50,
385
+ * page: 2,
386
+ * });
387
+ * @example
388
+ * constructorio.catalog.retrieveItems({
389
+ * ids: ['blk_pllvr_hd_001', 'blk_pllvr_hd_002']
390
+ * section: 'Products',
391
+ * numResultsPerPage: 50,
392
+ * page: 2,
368
393
  * });
369
394
  */
370
- modifyItem(parameters = {}, networkParameters = {}) {
395
+ retrieveItems(parameters = {}, networkParameters = {}) {
371
396
  let requestUrl;
372
397
  const fetch = (this.options && this.options.fetch) || nodeFetch;
373
398
  const controller = new AbortController();
374
399
  const { signal } = controller;
400
+ const { ids, section, numResultsPerPage, page } = parameters;
401
+ const queryParams = {};
402
+
403
+ if (ids) {
404
+ queryParams.id = ids;
405
+ }
406
+
407
+ if (section) {
408
+ queryParams.section = section;
409
+ }
410
+
411
+ if (numResultsPerPage) {
412
+ queryParams.num_results_per_page = numResultsPerPage;
413
+ }
414
+
415
+ if (page) {
416
+ queryParams.page = page;
417
+ }
375
418
 
376
419
  try {
377
- requestUrl = createCatalogUrl('item', this.options);
420
+ requestUrl = createCatalogUrl('items', this.options, queryParams, 'v2');
378
421
  } catch (e) {
379
422
  return Promise.reject(e);
380
423
  }
@@ -383,8 +426,7 @@ class Catalog {
383
426
  helpers.applyNetworkTimeout(this.options, networkParameters, controller);
384
427
 
385
428
  return fetch(requestUrl, {
386
- method: 'PUT',
387
- body: JSON.stringify(parameters),
429
+ method: 'GET',
388
430
  headers: {
389
431
  'Content-Type': 'application/json',
390
432
  ...helpers.createAuthHeader(this.options),
@@ -392,49 +434,73 @@ class Catalog {
392
434
  signal,
393
435
  }).then((response) => {
394
436
  if (response.ok) {
395
- return Promise.resolve();
437
+
438
+ return response.json();
396
439
  }
397
440
 
398
441
  return helpers.throwHttpErrorFromResponse(new Error(), response);
399
- });
442
+ }).then((json) => json);
400
443
  }
401
444
 
402
445
  /**
403
- * Add multiple items to index (limit of 1,000)
446
+ * Adds multiple variations to your index whilst replacing existing ones (limit of 1,000)
404
447
  *
405
- * @function addItemsBatch
406
- * @param {object} parameters - Additional parameters for item details
407
- * @param {object[]} parameters.items - A list of items with the same attributes as defined in the [addItem]{@link module:catalog~addItem} resource
408
- * @param {string} parameters.section - Your autosuggest and search results can have multiple sections like "Products" and "Search Suggestions". This indicates which section this item is for
448
+ * @function createOrReplaceVariations
449
+ * @param {object} parameters - Additional parameters for variation details
450
+ * @param {object[]} parameters.variations - A list of variations with the same attributes as defined in the Variation schema resource (https://docs.constructor.io/rest_api/items/variations/#variation-schema)
451
+ * @param {boolean} [parameters.force=false] - Process the request even if it will invalidate a large number of existing variations
452
+ * @param {string} [parameters.notificationEmail] - An email address where you'd like to receive an email notification in case the task fails
453
+ * @param {string} [parameters.section="Products"] - This indicates which section to operate on within the index
409
454
  * @param {object} [networkParameters] - Parameters relevant to the network request
410
455
  * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
411
456
  * @returns {Promise}
412
- * @see https://docs.constructor.io/rest_api/items/v1/batch_add_items
457
+ * @see https://docs.constructor.io/rest_api/items/variations/#create-or-replace-variations
413
458
  * @example
414
- * constructorio.catalog.addItemsBatch({
415
- * items: [
459
+ * constructorio.catalog.createOrReplaceVariations({
460
+ * variations: [
416
461
  * {
417
- * item_name: 'midnight black pullover hoodie',
418
- * section: 'Products',
419
- * keywords: ['midnight black', 'black', 'hoodie', 'tops', 'outerwear'],
420
- * url: '/products/blk_pllvr_hd_001'
421
- * image_url: '/products/images/blk_pllvr_hd_001'
422
- * description: 'a modified short description about the black pullover hoodie',
462
+ * name: 'midnight black pullover hoodie',
423
463
  * id: 'blk_pllvr_hd_001',
464
+ * item_id: "nike-shoes-brown",
465
+ * data: {
466
+ * keywords: ['midnight black', 'black', 'hoodie', 'tops', 'outerwear'],
467
+ * url: '/products/blk_pllvr_hd_001'
468
+ * image_url: '/products/images/blk_pllvr_hd_001'
469
+ * description: 'a modified short description about the black pullover hoodie',
470
+ * }
424
471
  * },
425
- * . . .
472
+ * ...
426
473
  * ],
427
474
  * section: 'Products',
428
475
  * });
429
476
  */
430
- addItemsBatch(parameters = {}, networkParameters = {}) {
477
+ createOrReplaceVariations(parameters = {}, networkParameters = {}) {
431
478
  let requestUrl;
432
479
  const fetch = (this.options && this.options.fetch) || nodeFetch;
433
480
  const controller = new AbortController();
434
481
  const { signal } = controller;
482
+ const { section, force, notificationEmail, variations } = parameters;
483
+ const queryParams = {};
484
+
485
+ // Validate variations are provided
486
+ if (!variations || !Array.isArray(variations)) {
487
+ return Promise.reject(new Error('variations is a required parameter of type array'));
488
+ }
489
+
490
+ if (notificationEmail) {
491
+ queryParams.notification_email = notificationEmail;
492
+ }
493
+
494
+ if (section) {
495
+ queryParams.section = section;
496
+ }
497
+
498
+ if (force) {
499
+ queryParams.force = force;
500
+ }
435
501
 
436
502
  try {
437
- requestUrl = createCatalogUrl('batch_items', this.options);
503
+ requestUrl = createCatalogUrl('variations', this.options, queryParams, 'v2');
438
504
  } catch (e) {
439
505
  return Promise.reject(e);
440
506
  }
@@ -443,8 +509,8 @@ class Catalog {
443
509
  helpers.applyNetworkTimeout(this.options, networkParameters, controller);
444
510
 
445
511
  return fetch(requestUrl, {
446
- method: 'POST',
447
- body: JSON.stringify(parameters),
512
+ method: 'PUT',
513
+ body: JSON.stringify({ variations }),
448
514
  headers: {
449
515
  'Content-Type': 'application/json',
450
516
  ...helpers.createAuthHeader(this.options),
@@ -460,41 +526,64 @@ class Catalog {
460
526
  }
461
527
 
462
528
  /**
463
- * Add multiple items to index whilst updating existing ones (limit of 1,000)
529
+ * Update multiple variations to index (limit of 1,000)
464
530
  *
465
- * @function addOrUpdateItemsBatch
466
- * @param {object} parameters - Additional parameters for item details
467
- * @param {object[]} parameters.items - A list of items with the same attributes as defined in the [addItem]{@link module:catalog~addItem} resource
468
- * @param {string} parameters.section - Your autosuggest and search results can have multiple sections like "Products" and "Search Suggestions". This indicates which section this item is for
531
+ * @function updateVariations
532
+ * @param {object} parameters - Additional parameters for variation details
533
+ * @param {object[]} parameters.variations - A list of variations with the same attributes as defined in the Variation schema resource (https://docs.constructor.io/rest_api/items/variations/#variation-schema)
534
+ * @param {boolean} [parameters.force=false] - Process the request even if it will invalidate a large number of existing variations
535
+ * @param {string} [parameters.notificationEmail] - An email address where you'd like to receive an email notification in case the task fails
536
+ * @param {string} [parameters.section="Products"] - This indicates which section to operate on within the index
469
537
  * @param {object} [networkParameters] - Parameters relevant to the network request
470
538
  * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
471
539
  * @returns {Promise}
472
- * @see https://docs.constructor.io/rest_api/items/v1/batch_add_or_update_items
540
+ * @see https://docs.constructor.io/rest_api/items/variations/#update-variations
473
541
  * @example
474
- * constructorio.catalog.addOrUpdateItemsBatch({
475
- * items: [
542
+ * constructorio.catalog.updateVariations({
543
+ * variations: [
476
544
  * {
477
- * item_name: 'midnight black pullover hoodie',
478
- * section: 'Products',
479
- * keywords: ['midnight black', 'black', 'hoodie', 'tops', 'outerwear'],
480
- * url: '/products/blk_pllvr_hd_001'
481
- * image_url: '/products/images/blk_pllvr_hd_001'
482
- * description: 'a modified short description about the black pullover hoodie',
545
+ * name: 'midnight black pullover hoodie',
483
546
  * id: 'blk_pllvr_hd_001',
547
+ * item_id: "nike-shoes-brown",
548
+ * data: {
549
+ * keywords: ['midnight black', 'black', 'hoodie', 'tops', 'outerwear'],
550
+ * url: '/products/blk_pllvr_hd_001'
551
+ * image_url: '/products/images/blk_pllvr_hd_001'
552
+ * description: 'a modified short description about the black pullover hoodie',
553
+ * }
484
554
  * },
485
- * . . .
555
+ * ...
486
556
  * ],
487
557
  * section: 'Products',
488
558
  * });
489
559
  */
490
- addOrUpdateItemsBatch(parameters = {}, networkParameters = {}) {
560
+ updateVariations(parameters = {}, networkParameters = {}) {
491
561
  let requestUrl;
492
562
  const fetch = (this.options && this.options.fetch) || nodeFetch;
493
563
  const controller = new AbortController();
494
564
  const { signal } = controller;
565
+ const { section, force, notificationEmail, variations } = parameters;
566
+ const queryParams = {};
567
+
568
+ // Validate variations are provided
569
+ if (!variations || !Array.isArray(variations)) {
570
+ return Promise.reject(new Error('variations is a required parameter of type array'));
571
+ }
572
+
573
+ if (section) {
574
+ queryParams.section = section;
575
+ }
576
+
577
+ if (force) {
578
+ queryParams.force = force;
579
+ }
580
+
581
+ if (notificationEmail) {
582
+ queryParams.notification_email = notificationEmail;
583
+ }
495
584
 
496
585
  try {
497
- requestUrl = `${createCatalogUrl('batch_items', this.options)}&force=1`;
586
+ requestUrl = createCatalogUrl('variations', this.options, queryParams, 'v2');
498
587
  } catch (e) {
499
588
  return Promise.reject(e);
500
589
  }
@@ -503,8 +592,8 @@ class Catalog {
503
592
  helpers.applyNetworkTimeout(this.options, networkParameters, controller);
504
593
 
505
594
  return fetch(requestUrl, {
506
- method: 'PUT',
507
- body: JSON.stringify(parameters),
595
+ method: 'PATCH',
596
+ body: JSON.stringify({ variations }),
508
597
  headers: {
509
598
  'Content-Type': 'application/json',
510
599
  ...helpers.createAuthHeader(this.options),
@@ -520,94 +609,54 @@ class Catalog {
520
609
  }
521
610
 
522
611
  /**
523
- * Remove multiple items from your index (limit of 1,000)
612
+ * Remove multiple variations from your index (limit of 1,000)
524
613
  *
525
- * @function removeItemsBatch
526
- * @param {object} parameters - Additional parameters for item details
527
- * @param {object[]} parameters.items - A list of items with the same attributes as defined in the [addItem]{@link module:catalog~addItem} resource
528
- * @param {string} parameters.section - Your autosuggest and search results can have multiple sections like "Products" and "Search Suggestions". This indicates which section this item is for
614
+ * @function deleteVariations
615
+ * @param {object} parameters - Additional parameters for variation details
616
+ * @param {object[]} parameters.variations - A list of variations with the same attributes as defined in the Variation schema resource (https://docs.constructor.io/rest_api/items/variations/#variation-schema)
617
+ * @param {boolean} [parameters.force=false] - Process the request even if it will invalidate a large number of existing variations
618
+ * @param {string} [parameters.notificationEmail] - An email address where you'd like to receive an email notification in case the task fails
619
+ * @param {string} [parameters.section="Products"] - This indicates which section to operate on within the index
529
620
  * @param {object} [networkParameters] - Parameters relevant to the network request
530
621
  * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
531
622
  * @returns {Promise}
532
- * @see https://docs.constructor.io/rest_api/items/v1/batch_remove_items
623
+ * @see https://docs.constructor.io/rest_api/items/variations/#delete-variations
533
624
  * @example
534
- * constructorio.catalog.removeItemsBatch({
535
- * items: [
625
+ * constructorio.catalog.deleteVariations({
626
+ * variations: [
536
627
  * { id: 'blk_pllvr_hd_001' },
537
628
  * { id: 'red_pllvr_hd_02' },
538
629
  * ],
539
630
  * section: 'Products',
540
631
  * });
541
632
  */
542
- removeItemsBatch(parameters = {}, networkParameters = {}) {
633
+ deleteVariations(parameters = {}, networkParameters = {}) {
543
634
  let requestUrl;
544
635
  const fetch = (this.options && this.options.fetch) || nodeFetch;
545
636
  const controller = new AbortController();
546
637
  const { signal } = controller;
638
+ const { section, force, notificationEmail, variations } = parameters;
639
+ const queryParams = {};
547
640
 
548
- try {
549
- requestUrl = createCatalogUrl('batch_items', this.options);
550
- } catch (e) {
551
- return Promise.reject(e);
641
+ // Validate variations are provided
642
+ if (!variations || !Array.isArray(variations)) {
643
+ return Promise.reject(new Error('variations is a required parameter of type array'));
552
644
  }
553
645
 
554
- // Handle network timeout if specified
555
- helpers.applyNetworkTimeout(this.options, networkParameters, controller);
556
-
557
- return fetch(requestUrl, {
558
- method: 'DELETE',
559
- body: JSON.stringify(parameters),
560
- headers: {
561
- 'Content-Type': 'application/json',
562
- ...helpers.createAuthHeader(this.options),
563
- },
564
- signal,
565
- }).then((response) => {
566
- if (response.ok) {
567
- return Promise.resolve();
568
- }
569
-
570
- return helpers.throwHttpErrorFromResponse(new Error(), response);
571
- });
572
- }
573
-
574
- /**
575
- * Retrieves item(s) from index for the given section or specific item ID
576
- *
577
- * @function getItem
578
- * @param {object} parameters - Additional parameters for item details
579
- * @param {string} parameters.id - The ID of the item you'd like to retrieve
580
- * @param {object} [networkParameters] - Parameters relevant to the network request
581
- * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
582
- * @returns {Promise}
583
- * @see https://docs.constructor.io/rest_api/items/v1/get_items
584
- * @example
585
- * constructorio.catalog.getItem({
586
- * id: 'blk_pllvr_hd_001',
587
- * });
588
- */
589
- getItem(parameters = {}, networkParameters = {}) {
590
- const queryParams = {};
591
- let requestUrl;
592
- const fetch = (this.options && this.options.fetch) || nodeFetch;
593
- const controller = new AbortController();
594
- const { signal } = controller;
646
+ if (section) {
647
+ queryParams.section = section;
648
+ }
595
649
 
596
- if (parameters) {
597
- const { section } = parameters;
650
+ if (force) {
651
+ queryParams.force = force;
652
+ }
598
653
 
599
- // Pull section from parameters
600
- if (section) {
601
- queryParams.section = section;
602
- }
654
+ if (notificationEmail) {
655
+ queryParams.notification_email = notificationEmail;
603
656
  }
604
657
 
605
658
  try {
606
- if (parameters.id) {
607
- requestUrl = createCatalogUrl(`item/${parameters.id}`, this.options, queryParams);
608
- } else {
609
- requestUrl = createCatalogUrl('item', this.options, queryParams);
610
- }
659
+ requestUrl = createCatalogUrl('variations', this.options, queryParams, 'v2');
611
660
  } catch (e) {
612
661
  return Promise.reject(e);
613
662
  }
@@ -616,7 +665,8 @@ class Catalog {
616
665
  helpers.applyNetworkTimeout(this.options, networkParameters, controller);
617
666
 
618
667
  return fetch(requestUrl, {
619
- method: 'GET',
668
+ method: 'DELETE',
669
+ body: JSON.stringify({ variations }),
620
670
  headers: {
621
671
  'Content-Type': 'application/json',
622
672
  ...helpers.createAuthHeader(this.options),
@@ -624,60 +674,73 @@ class Catalog {
624
674
  signal,
625
675
  }).then((response) => {
626
676
  if (response.ok) {
627
- return response.json();
677
+ return Promise.resolve();
628
678
  }
629
679
 
630
680
  return helpers.throwHttpErrorFromResponse(new Error(), response);
631
- }).then((json) => json);
681
+ });
632
682
  }
633
683
 
634
684
  /**
635
- * Retrieves items from index for the given section
685
+ * Retrieves variation(s) from index for the given section or specific variation ID
636
686
  *
637
- * @function getItems
638
- * @param {object} parameters - Additional parameters for item details
639
- * @param {string} parameters.section - The index section you'd like to retrieve results from
640
- * @param {number} [parameters.num_results_per_page] - The number of items to return. Defaults to 20. Maximum value 1,000
641
- * @param {number} [parameters.page] - The page of results to return. Defaults to 1
687
+ * @function retrieveVariations
688
+ * @param {object} parameters - Additional parameters for variation details
689
+ * @param {string} [parameters.section="Products"] - This indicates which section to operate on within the index
690
+ * @param {string[]} [parameters.ids] - Id(s) of variations to return (1,000 maximum)
691
+ * @param {string} [parameters.itemId] - Parent item id to return descendant variations of
692
+ * @param {number} [parameters.numResultsPerPage=100] - The number of items to return
693
+ * @param {number} [parameters.page=1] - The page of results to return
642
694
  * @param {object} [networkParameters] - Parameters relevant to the network request
643
695
  * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
644
696
  * @returns {Promise}
645
- * @see https://docs.constructor.io/rest_api/items/v1/get_items
697
+ * @see https://docs.constructor.io/rest_api/items/variations/#retrieve-variations
646
698
  * @example
647
- * constructorio.catalog.getItems({
699
+ * constructorio.catalog.retrieveVariations({
648
700
  * section: 'Products',
649
- * num_results_per_page: 50,
701
+ * numResultsPerPage: 50,
702
+ * page: 2,
703
+ * });
704
+ * @example
705
+ * constructorio.catalog.retrieveVariations({
706
+ * ids: ['blk_pllvr_hd_001', 'blk_pllvr_hd_002']
707
+ * section: 'Products',
708
+ * numResultsPerPage: 50,
650
709
  * page: 2,
651
710
  * });
652
711
  */
653
- getItems(parameters = {}, networkParameters = {}) {
654
- const queryParams = {};
712
+ retrieveVariations(parameters = {}, networkParameters = {}) {
713
+ let queryParams = {};
655
714
  let requestUrl;
656
715
  const fetch = (this.options && this.options.fetch) || nodeFetch;
657
716
  const controller = new AbortController();
658
717
  const { signal } = controller;
718
+ const { ids, itemId, section, numResultsPerPage, page } = parameters;
659
719
 
660
- if (parameters) {
661
- const { num_results_per_page: numResultsPerPage, page, section } = parameters;
720
+ queryParams = {};
662
721
 
663
- // Pull number of results per page from parameters
664
- if (numResultsPerPage) {
665
- queryParams.num_results_per_page = numResultsPerPage;
666
- }
722
+ if (ids) {
723
+ queryParams.id = ids;
724
+ }
667
725
 
668
- // Pull page from parameters
669
- if (page) {
670
- queryParams.page = page;
671
- }
726
+ if (itemId) {
727
+ queryParams.item_id = itemId;
728
+ }
672
729
 
673
- // Pull section from parameters
674
- if (section) {
675
- queryParams.section = section;
676
- }
730
+ if (section) {
731
+ queryParams.section = section;
732
+ }
733
+
734
+ if (page) {
735
+ queryParams.page = page;
736
+ }
737
+
738
+ if (numResultsPerPage) {
739
+ queryParams.num_results_per_page = numResultsPerPage;
677
740
  }
678
741
 
679
742
  try {
680
- requestUrl = createCatalogUrl('item', this.options, queryParams);
743
+ requestUrl = createCatalogUrl('variations', this.options, queryParams, 'v2');
681
744
  } catch (e) {
682
745
  return Promise.reject(e);
683
746
  }