@constructor-io/constructorio-node 5.5.1 → 5.7.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.
@@ -31,7 +31,9 @@ function createCatalogUrl(path, options, additionalQueryParams = {}, apiVersion
31
31
 
32
32
  const queryString = qs.stringify(queryParams, { indices: false });
33
33
 
34
- return `${serviceUrl}/${encodeURIComponent(apiVersion)}/${encodeURIComponent(path)}?${queryString}`;
34
+ const encodedPath = path.split('/').map(encodeURIComponent).join('/');
35
+
36
+ return `${serviceUrl}/${encodeURIComponent(apiVersion)}/${encodedPath}?${queryString}`;
35
37
  }
36
38
 
37
39
  // Convert a read stream to buffer
@@ -59,7 +61,7 @@ async function createQueryParamsAndFormData(parameters) {
59
61
  const formData = new FormData();
60
62
 
61
63
  if (parameters) {
62
- const { section, notification_email, notificationEmail = notification_email, force, item_groups, onMissing } = parameters;
64
+ const { section, notification_email, notificationEmail = notification_email, force, item_groups, onMissing, format = 'csv' } = parameters;
63
65
  let { items, variations, itemGroups = item_groups } = parameters;
64
66
 
65
67
  try {
@@ -106,24 +108,32 @@ async function createQueryParamsAndFormData(parameters) {
106
108
  queryParams.on_missing = onMissing;
107
109
  }
108
110
 
111
+ if (typeof format !== 'string' || !['csv', 'jsonl'].includes(format.toLowerCase())) {
112
+ throw new Error('format must be csv or jsonl');
113
+ }
114
+
115
+ const normalizedFormat = format.toLowerCase();
116
+
117
+ queryParams.format = normalizedFormat;
118
+
109
119
  // Pull items from parameters
110
120
  if (items) {
111
121
  formData.append('items', items, {
112
- filename: 'items.csv',
122
+ filename: `items.${normalizedFormat}`,
113
123
  });
114
124
  }
115
125
 
116
126
  // Pull variations from parameters
117
127
  if (variations) {
118
128
  formData.append('variations', variations, {
119
- filename: 'variations.csv',
129
+ filename: `variations.${normalizedFormat}`,
120
130
  });
121
131
  }
122
132
 
123
133
  // Pull item groups from parameters
124
134
  if (itemGroups) {
125
135
  formData.append('item_groups', itemGroups, {
126
- filename: 'item_groups.csv',
136
+ filename: `item_groups.${normalizedFormat}`,
127
137
  });
128
138
  }
129
139
  }
@@ -201,8 +211,8 @@ class Catalog {
201
211
  * id: 'blk_pllvr_hd_001',
202
212
  * data: {
203
213
  * keywords: ['midnight black', 'black', 'hoodie', 'tops', 'outerwear'],
204
- * url: '/products/blk_pllvr_hd_001'
205
- * image_url: '/products/images/blk_pllvr_hd_001'
214
+ * url: '/products/blk_pllvr_hd_001',
215
+ * image_url: '/products/images/blk_pllvr_hd_001',
206
216
  * description: 'a modified short description about the black pullover hoodie',
207
217
  * }
208
218
  * },
@@ -2553,9 +2563,10 @@ class Catalog {
2553
2563
  * @param {string} parameters.section - The section to update
2554
2564
  * @param {string} [parameters.notificationEmail] - An email address to receive an email notification if the task fails
2555
2565
  * @param {boolean} [parameters.force=false] - Process the catalog even if it will invalidate a large number of existing items
2556
- * @param {file} [parameters.items] - The CSV file with all new items
2557
- * @param {file} [parameters.variations] - The CSV file with all new variations
2558
- * @param {file} [parameters.itemGroups] - The CSV file with all new itemGroups
2566
+ * @param {file} [parameters.items] - The file with all new items (csv or jsonl, depending on the format parameter)
2567
+ * @param {file} [parameters.variations] - The file with all new variations (csv or jsonl, depending on the format parameter)
2568
+ * @param {file} [parameters.itemGroups] - The file with all new itemGroups (csv or jsonl, depending on the format parameter)
2569
+ * @param {string} [parameters.format] - File format of all uploaded catalog files (items, variations, and itemGroups). Can be either csv or jsonl.
2559
2570
  * @param {object} [networkParameters] - Parameters relevant to the network request
2560
2571
  * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
2561
2572
  * @returns {Promise}
@@ -2567,6 +2578,7 @@ class Catalog {
2567
2578
  * items: itemsFileBufferOrStream,
2568
2579
  * variations: variationsFileBufferOrStream,
2569
2580
  * itemGroups: itemGroupsFileBufferOrStream,
2581
+ * format: 'csv'
2570
2582
  * });
2571
2583
  */
2572
2584
  async replaceCatalog(parameters = {}, networkParameters = {}) {
@@ -2605,9 +2617,10 @@ class Catalog {
2605
2617
  * @param {string} parameters.section - The section to update
2606
2618
  * @param {string} [parameters.notificationEmail] - An email address to receive an email notification if the task fails
2607
2619
  * @param {boolean} [parameters.force=false] - Process the catalog even if it will invalidate a large number of existing items
2608
- * @param {file} [parameters.items] - The CSV file with all new items
2609
- * @param {file} [parameters.variations] - The CSV file with all new variations
2610
- * @param {file} [parameters.itemGroups] - The CSV file with all new itemGroups
2620
+ * @param {file} [parameters.items] - The file with all new items (csv or jsonl, depending on the format parameter)
2621
+ * @param {file} [parameters.variations] - The file with all new variations (csv or jsonl, depending on the format parameter)
2622
+ * @param {file} [parameters.itemGroups] - The file with all new itemGroups (csv or jsonl, depending on the format parameter)
2623
+ * @param {string} [parameters.format] - File format of the uploaded items and variations files. Can be either csv or jsonl.
2611
2624
  * @param {object} [networkParameters] - Parameters relevant to the network request
2612
2625
  * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
2613
2626
  * @returns {Promise}
@@ -2619,6 +2632,7 @@ class Catalog {
2619
2632
  * items: itemsFileBufferOrStream,
2620
2633
  * variations: variationsFileBufferOrStream,
2621
2634
  * itemGroups: itemGroupsFileBufferOrStream,
2635
+ * format: 'csv'
2622
2636
  * });
2623
2637
  */
2624
2638
  async updateCatalog(parameters = {}, networkParameters = {}) {
@@ -2658,9 +2672,10 @@ class Catalog {
2658
2672
  * @param {string} [parameters.notificationEmail] - An email address to receive an email notification if the task fails
2659
2673
  * @param {boolean} [parameters.force=false] - Process the catalog even if it will invalidate a large number of existing items
2660
2674
  * @param {string} [parameters.onMissing="FAIL"] - Defines the strategy for handling items which are present in the file and missing in the system. IGNORE silently prevents adding them to the system, CREATE creates them, FAIL fails the ingestion in case of their presence
2661
- * @param {file} [parameters.items] - The CSV file with all new items
2662
- * @param {file} [parameters.variations] - The CSV file with all new variations
2663
- * @param {file} [parameters.itemGroups] - The CSV file with all new itemGroups
2675
+ * @param {file} [parameters.items] - The file with all new items (csv or jsonl, depending on the format parameter)
2676
+ * @param {file} [parameters.variations] - The file with all new variations (csv or jsonl, depending on the format parameter)
2677
+ * @param {file} [parameters.itemGroups] - The file with all new itemGroups (csv or jsonl, depending on the format parameter)
2678
+ * @param {string} [parameters.format] - File format of the uploaded items and variations files. Can be either csv or jsonl.
2664
2679
  * @param {object} [networkParameters] - Parameters relevant to the network request
2665
2680
  * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
2666
2681
  * @returns {Promise}
@@ -2672,6 +2687,7 @@ class Catalog {
2672
2687
  * items: itemsFileBufferOrStream,
2673
2688
  * variations: variationsFileBufferOrStream,
2674
2689
  * itemGroups: itemGroupsFileBufferOrStream,
2690
+ * format: 'csv'
2675
2691
  * });
2676
2692
  */
2677
2693
  async patchCatalog(parameters = {}, networkParameters = {}) {
@@ -2710,7 +2726,8 @@ class Catalog {
2710
2726
  * @param {string} parameters.section - The section to update
2711
2727
  * @param {string} [parameters.notificationEmail] - An email address to receive an email notification if the task fails
2712
2728
  * @param {boolean} [parameters.force=false] - Process the catalog even if it will invalidate a large number of existing items
2713
- * @param {file} [parameters.tarArchive] - The tar file that includes csv files
2729
+ * @param {file} [parameters.tarArchive] - The tar file that includes catalog files (csv or jsonl, depending on the format parameter)
2730
+ * @param {string} [parameters.format] - File format of the uploaded items and variations files. Can be either csv or jsonl.
2714
2731
  * @param {object} [networkParameters] - Parameters relevant to the network request
2715
2732
  * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
2716
2733
  * @returns {Promise}
@@ -2720,6 +2737,7 @@ class Catalog {
2720
2737
  * section: 'Products',
2721
2738
  * notificationEmail: 'notifications@example.com',
2722
2739
  * tarArchive: tarArchiveBufferOrStream,
2740
+ * format: 'csv'
2723
2741
  * });
2724
2742
  */
2725
2743
  async replaceCatalogUsingTarArchive(parameters = {}, networkParameters = {}) {
@@ -2766,7 +2784,8 @@ class Catalog {
2766
2784
  * @param {string} parameters.section - The section to update
2767
2785
  * @param {string} [parameters.notificationEmail] - An email address to receive an email notification if the task fails
2768
2786
  * @param {boolean} [parameters.force=false] - Process the catalog even if it will invalidate a large number of existing items
2769
- * @param {file} [parameters.tarArchive] - The tar file that includes csv files
2787
+ * @param {file} [parameters.tarArchive] - The tar file that includes catalog files (csv or jsonl, depending on the format parameter)
2788
+ * @param {string} [parameters.format] - File format of the uploaded items and variations files. Can be either csv or jsonl.
2770
2789
  * @param {object} [networkParameters] - Parameters relevant to the network request
2771
2790
  * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
2772
2791
  * @returns {Promise}
@@ -2776,6 +2795,7 @@ class Catalog {
2776
2795
  * section: 'Products',
2777
2796
  * notificationEmail: 'notifications@example.com',
2778
2797
  * tarArchive: tarArchiveBufferOrStream,
2798
+ * format: 'csv'
2779
2799
  * });
2780
2800
  */
2781
2801
  async updateCatalogUsingTarArchive(parameters = {}, networkParameters = {}) {
@@ -2825,7 +2845,8 @@ class Catalog {
2825
2845
  * @param {string} [parameters.notificationEmail] - An email address to receive an email notification if the task fails
2826
2846
  * @param {boolean} [parameters.force=false] - Process the catalog even if it will invalidate a large number of existing items
2827
2847
  * @param {string} [parameters.onMissing="FAIL"] - Defines the strategy for handling items which are present in the file and missing in the system. IGNORE silently prevents adding them to the system, CREATE creates them, FAIL fails the ingestion in case of their presence
2828
- * @param {file} [parameters.tarArchive] - The tar file that includes csv files
2848
+ * @param {file} [parameters.tarArchive] - The tar file that includes catalog files (csv or jsonl, depending on the format parameter)
2849
+ * @param {string} [parameters.format] - File format of the uploaded items and variations files. Can be either csv or jsonl.
2829
2850
  * @param {object} [networkParameters] - Parameters relevant to the network request
2830
2851
  * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
2831
2852
  * @returns {Promise}
@@ -2835,6 +2856,7 @@ class Catalog {
2835
2856
  * section: 'Products',
2836
2857
  * notificationEmail: 'notifications@example.com',
2837
2858
  * tarArchive: tarArchiveBufferOrStream,
2859
+ * format: 'csv'
2838
2860
  * });
2839
2861
  */
2840
2862
  async patchCatalogUsingTarArchive(parameters = {}, networkParameters = {}) {
@@ -2909,8 +2931,12 @@ class Catalog {
2909
2931
  * sortDescending: false,
2910
2932
  * position: 1,
2911
2933
  * });
2934
+ * @deprecated Use [addFacetConfigurationV2]{@link module:catalog~addFacetConfigurationV2} instead. This method will be removed in the next major version.
2912
2935
  */
2913
2936
  addFacetConfiguration(parameters = {}, networkParameters = {}) {
2937
+ // eslint-disable-next-line no-console
2938
+ console.warn('ConstructorIO: addFacetConfiguration is deprecated and will be removed in the next major version. Use addFacetConfigurationV2 instead.');
2939
+
2914
2940
  let requestUrl;
2915
2941
  const { fetch } = this.options;
2916
2942
  const controller = new AbortController();
@@ -2962,8 +2988,12 @@ class Catalog {
2962
2988
  * page: 2,
2963
2989
  * numResultsPerPage: 50,
2964
2990
  * });
2991
+ * @deprecated Use [getFacetConfigurationsV2]{@link module:catalog~getFacetConfigurationsV2} instead. This method will be removed in the next major version.
2965
2992
  */
2966
2993
  getFacetConfigurations(parameters = {}, networkParameters = {}) {
2994
+ // eslint-disable-next-line no-console
2995
+ console.warn('ConstructorIO: getFacetConfigurations is deprecated and will be removed in the next major version. Use getFacetConfigurationsV2 instead.');
2996
+
2967
2997
  let requestUrl;
2968
2998
  const { fetch } = this.options;
2969
2999
  const controller = new AbortController();
@@ -3021,8 +3051,12 @@ class Catalog {
3021
3051
  * constructorio.catalog.getFacetConfiguration({
3022
3052
  * name: 'color',
3023
3053
  * });
3054
+ * @deprecated Use [getFacetConfigurationV2]{@link module:catalog~getFacetConfigurationV2} instead. This method will be removed in the next major version.
3024
3055
  */
3025
3056
  getFacetConfiguration(parameters = {}, networkParameters = {}) {
3057
+ // eslint-disable-next-line no-console
3058
+ console.warn('ConstructorIO: getFacetConfiguration is deprecated and will be removed in the next major version. Use getFacetConfigurationV2 instead.');
3059
+
3026
3060
  let requestUrl;
3027
3061
  const { fetch } = this.options;
3028
3062
  const controller = new AbortController();
@@ -3084,8 +3118,12 @@ class Catalog {
3084
3118
  * }
3085
3119
  * ],
3086
3120
  * });
3121
+ * @deprecated Use [modifyFacetConfigurationsV2]{@link module:catalog~modifyFacetConfigurationsV2} instead. This method will be removed in the next major version.
3087
3122
  */
3088
3123
  modifyFacetConfigurations(parameters = {}, networkParameters = {}) {
3124
+ // eslint-disable-next-line no-console
3125
+ console.warn('ConstructorIO: modifyFacetConfigurations is deprecated and will be removed in the next major version. Use modifyFacetConfigurationsV2 instead.');
3126
+
3089
3127
  let requestUrl;
3090
3128
  const { fetch } = this.options;
3091
3129
  const controller = new AbortController();
@@ -3159,8 +3197,12 @@ class Catalog {
3159
3197
  * sortDescending: false,
3160
3198
  * position: 1,
3161
3199
  * });
3200
+ * @deprecated Use [replaceFacetConfigurationV2]{@link module:catalog~replaceFacetConfigurationV2} instead. This method will be removed in the next major version.
3162
3201
  */
3163
3202
  replaceFacetConfiguration(parameters = {}, networkParameters = {}) {
3203
+ // eslint-disable-next-line no-console
3204
+ console.warn('ConstructorIO: replaceFacetConfiguration is deprecated and will be removed in the next major version. Use replaceFacetConfigurationV2 instead.');
3205
+
3164
3206
  let requestUrl;
3165
3207
  const { fetch } = this.options;
3166
3208
  const controller = new AbortController();
@@ -3231,8 +3273,12 @@ class Catalog {
3231
3273
  * sortDescending: true,
3232
3274
  * position: 1,
3233
3275
  * });
3276
+ * @deprecated Use [modifyFacetConfigurationV2]{@link module:catalog~modifyFacetConfigurationV2} instead. This method will be removed in the next major version.
3234
3277
  */
3235
3278
  modifyFacetConfiguration(parameters = {}, networkParameters = {}) {
3279
+ // eslint-disable-next-line no-console
3280
+ console.warn('ConstructorIO: modifyFacetConfiguration is deprecated and will be removed in the next major version. Use modifyFacetConfigurationV2 instead.');
3281
+
3236
3282
  let requestUrl;
3237
3283
  const { fetch } = this.options;
3238
3284
  const controller = new AbortController();
@@ -3285,8 +3331,12 @@ class Catalog {
3285
3331
  * constructorio.catalog.removeFacetConfiguration({
3286
3332
  * name: 'color',
3287
3333
  * });
3334
+ * @deprecated Use [removeFacetConfigurationV2]{@link module:catalog~removeFacetConfigurationV2} instead. This method will be removed in the next major version.
3288
3335
  */
3289
3336
  removeFacetConfiguration(parameters = {}, networkParameters = {}) {
3337
+ // eslint-disable-next-line no-console
3338
+ console.warn('ConstructorIO: removeFacetConfiguration is deprecated and will be removed in the next major version. Use removeFacetConfigurationV2 instead.');
3339
+
3290
3340
  let requestUrl;
3291
3341
  const { fetch } = this.options;
3292
3342
  const controller = new AbortController();
@@ -3764,8 +3814,12 @@ class Catalog {
3764
3814
  * numResultsPerPage: 50,
3765
3815
  * filters: { exactSearchable: true }
3766
3816
  * });
3817
+ * @deprecated Use [retrieveSearchabilitiesV2]{@link module:catalog~retrieveSearchabilitiesV2} instead. This method will be removed in the next major version.
3767
3818
  */
3768
3819
  retrieveSearchabilities(parameters = {}, networkParameters = {}) {
3820
+ // eslint-disable-next-line no-console
3821
+ console.warn('ConstructorIO: retrieveSearchabilities is deprecated and will be removed in the next major version. Use retrieveSearchabilitiesV2 instead.');
3822
+
3769
3823
  let requestUrl;
3770
3824
  const { fetch } = this.options;
3771
3825
  const controller = new AbortController();
@@ -3866,8 +3920,12 @@ class Catalog {
3866
3920
  * },
3867
3921
  * ],
3868
3922
  * });
3923
+ * @deprecated Use [patchSearchabilitiesV2]{@link module:catalog~patchSearchabilitiesV2} instead. This method will be removed in the next major version.
3869
3924
  */
3870
3925
  patchSearchabilities(parameters = {}, networkParameters = {}) {
3926
+ // eslint-disable-next-line no-console
3927
+ console.warn('ConstructorIO: patchSearchabilities is deprecated and will be removed in the next major version. Use patchSearchabilitiesV2 instead.');
3928
+
3871
3929
  let requestUrl;
3872
3930
  const { fetch } = this.options;
3873
3931
  const controller = new AbortController();
@@ -3903,6 +3961,1033 @@ class Catalog {
3903
3961
  return helpers.throwHttpErrorFromResponse(new Error(), response);
3904
3962
  });
3905
3963
  }
3964
+
3965
+ // -------------------- V2 Facet Configuration Methods --------------------
3966
+
3967
+ /**
3968
+ * Create a facet configuration (V2)
3969
+ *
3970
+ * @function addFacetConfigurationV2
3971
+ * @param {object} parameters - Additional parameters for facet configuration details
3972
+ * @param {string} parameters.name - Unique facet name used to refer to the facet in your catalog
3973
+ * @param {string} parameters.pathInMetadata - The path in metadata of each item where this facet is present
3974
+ * @param {string} parameters.type - Type of facet. Must be one of multiple, hierarchical, or range
3975
+ * @param {string} [parameters.displayName] - The name of the facet presented to the end users
3976
+ * @param {string} [parameters.sortOrder] - Defines the criterion by which the options of this facet group are sorted
3977
+ * @param {boolean} [parameters.sortDescending] - Set to true if the options should be sorted in descending order
3978
+ * @param {string} [parameters.rangeType] - Should be 'static' if a facet is configured as range
3979
+ * @param {string} [parameters.rangeFormat] - Format of range facets: 'boundaries' for sliders, 'options' for buckets
3980
+ * @param {string} [parameters.rangeInclusive] - Used to create inclusive buckets: 'above', 'below', or null
3981
+ * @param {number[]} [parameters.rangeLimits] - Defines the cut-off points for generating static range buckets
3982
+ * @param {string} [parameters.matchType] - Specifies the behavior of filters: 'any', 'all', or 'none'
3983
+ * @param {number} [parameters.position] - Slot facet groups to fixed positions
3984
+ * @param {boolean} [parameters.hidden] - Specifies whether the facet is hidden from users
3985
+ * @param {boolean} [parameters.protected] - Specifies whether the facet is protected from users
3986
+ * @param {boolean} [parameters.countable] - Specifies whether counts for each facet option should be calculated
3987
+ * @param {number} [parameters.optionsLimit] - Maximum number of options to return in search responses
3988
+ * @param {object} [parameters.data] - Dictionary/Object with any extra facet data
3989
+ * @param {string} [parameters.section] - The section in which your facet is defined. Default value is Products.
3990
+ * @param {object} [networkParameters] - Parameters relevant to the network request
3991
+ * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
3992
+ * @returns {Promise<object>} - Facet configuration response with name, path_in_metadata, type, and other fields
3993
+ * @see https://docs.constructor.com/reference/configuration-facets
3994
+ * @example
3995
+ * constructorio.catalog.addFacetConfigurationV2({
3996
+ * name: 'color',
3997
+ * pathInMetadata: 'color',
3998
+ * type: 'multiple',
3999
+ * displayName: 'Color',
4000
+ * });
4001
+ */
4002
+ addFacetConfigurationV2(parameters = {}, networkParameters = {}) {
4003
+ let requestUrl;
4004
+ const { fetch } = this.options;
4005
+ const controller = new AbortController();
4006
+ const { signal } = controller;
4007
+ const { section, name, pathInMetadata, ...rest } = parameters;
4008
+
4009
+ if (!name || typeof name !== 'string') {
4010
+ return Promise.reject(new Error('name is a required parameter of type string'));
4011
+ }
4012
+
4013
+ if (!pathInMetadata || typeof pathInMetadata !== 'string') {
4014
+ return Promise.reject(new Error('pathInMetadata is a required parameter of type string'));
4015
+ }
4016
+
4017
+ const validFacetTypes = ['multiple', 'hierarchical', 'range'];
4018
+
4019
+ if (!rest.type || !validFacetTypes.includes(rest.type)) {
4020
+ return Promise.reject(new Error('type is a required parameter and must be one of: multiple, hierarchical, or range'));
4021
+ }
4022
+
4023
+ const additionalQueryParams = {};
4024
+
4025
+ if (!helpers.isNil(section)) {
4026
+ additionalQueryParams.section = section;
4027
+ }
4028
+
4029
+ try {
4030
+ requestUrl = createCatalogUrl('facets', this.options, additionalQueryParams, 'v2');
4031
+ } catch (e) {
4032
+ return Promise.reject(e);
4033
+ }
4034
+
4035
+ // Handle network timeout if specified
4036
+ helpers.applyNetworkTimeout(this.options, networkParameters, controller);
4037
+ return fetch(requestUrl, {
4038
+ method: 'POST',
4039
+ body: JSON.stringify(toSnakeCaseKeys({ name, pathInMetadata, ...rest })),
4040
+ headers: {
4041
+ 'Content-Type': 'application/json',
4042
+ ...helpers.createAuthHeader(this.options),
4043
+ },
4044
+ signal,
4045
+ }).then((response) => {
4046
+ if (response.ok) {
4047
+ return response.json();
4048
+ }
4049
+
4050
+ return helpers.throwHttpErrorFromResponse(new Error(), response);
4051
+ });
4052
+ }
4053
+
4054
+ /**
4055
+ * Get all facet configurations (V2)
4056
+ *
4057
+ * @function getFacetConfigurationsV2
4058
+ * @param {object} parameters - Additional parameters for retrieving facet configurations.
4059
+ * @param {number} [parameters.page] - Page number you'd like to request. Defaults to 1.
4060
+ * @param {number} [parameters.numResultsPerPage] - Number of facets per page in paginated response. Default value is 100.
4061
+ * @param {number} [parameters.offset] - The number of results to skip from the beginning. Cannot be used together with page.
4062
+ * @param {string} [parameters.section] - The section in which your facet is defined. Default value is Products.
4063
+ * @param {object} [networkParameters] - Parameters relevant to the network request
4064
+ * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
4065
+ * @returns {Promise<{facets: object[], total_count: number}>} - Paginated list of facet configurations
4066
+ * @see https://docs.constructor.com/reference/configuration-facets
4067
+ * @example
4068
+ * constructorio.catalog.getFacetConfigurationsV2({
4069
+ * page: 2,
4070
+ * numResultsPerPage: 50,
4071
+ * });
4072
+ */
4073
+ getFacetConfigurationsV2(parameters = {}, networkParameters = {}) {
4074
+ let requestUrl;
4075
+ const { fetch } = this.options;
4076
+ const controller = new AbortController();
4077
+ const { signal } = controller;
4078
+ const { numResultsPerPage, page, offset, section } = parameters;
4079
+ const additionalQueryParams = {};
4080
+
4081
+ if (!helpers.isNil(section)) {
4082
+ additionalQueryParams.section = section;
4083
+ }
4084
+
4085
+ if (!helpers.isNil(numResultsPerPage)) {
4086
+ additionalQueryParams.num_results_per_page = numResultsPerPage;
4087
+ }
4088
+
4089
+ if (!helpers.isNil(page)) {
4090
+ additionalQueryParams.page = page;
4091
+ }
4092
+
4093
+ if (!helpers.isNil(offset)) {
4094
+ additionalQueryParams.offset = offset;
4095
+ }
4096
+
4097
+ try {
4098
+ requestUrl = createCatalogUrl('facets', this.options, additionalQueryParams, 'v2');
4099
+ } catch (e) {
4100
+ return Promise.reject(e);
4101
+ }
4102
+
4103
+ // Handle network timeout if specified
4104
+ helpers.applyNetworkTimeout(this.options, networkParameters, controller);
4105
+
4106
+ return fetch(requestUrl, {
4107
+ method: 'GET',
4108
+ headers: {
4109
+ 'Content-Type': 'application/json',
4110
+ ...helpers.createAuthHeader(this.options),
4111
+ },
4112
+ signal,
4113
+ }).then((response) => {
4114
+ if (response.ok) {
4115
+ return response.json();
4116
+ }
4117
+
4118
+ return helpers.throwHttpErrorFromResponse(new Error(), response);
4119
+ });
4120
+ }
4121
+
4122
+ /**
4123
+ * Get a single facet's configuration (V2)
4124
+ *
4125
+ * @function getFacetConfigurationV2
4126
+ * @param {object} parameters - Additional parameters for retrieving a facet configuration.
4127
+ * @param {string} parameters.name - Unique facet name used to refer to the facet in your catalog
4128
+ * @param {string} [parameters.section] - The section in which your facet is defined. Default value is Products.
4129
+ * @param {object} [networkParameters] - Parameters relevant to the network request
4130
+ * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
4131
+ * @returns {Promise<object>} - Facet configuration response with name, path_in_metadata, type, and other fields
4132
+ * @see https://docs.constructor.com/reference/configuration-facets
4133
+ * @example
4134
+ * constructorio.catalog.getFacetConfigurationV2({
4135
+ * name: 'color',
4136
+ * });
4137
+ */
4138
+ getFacetConfigurationV2(parameters = {}, networkParameters = {}) {
4139
+ let requestUrl;
4140
+ const { fetch } = this.options;
4141
+ const controller = new AbortController();
4142
+ const { signal } = controller;
4143
+ const { section, name } = parameters;
4144
+
4145
+ if (!name || typeof name !== 'string') {
4146
+ return Promise.reject(new Error('name is a required parameter of type string'));
4147
+ }
4148
+
4149
+ const additionalQueryParams = {};
4150
+
4151
+ if (!helpers.isNil(section)) {
4152
+ additionalQueryParams.section = section;
4153
+ }
4154
+
4155
+ try {
4156
+ requestUrl = createCatalogUrl(`facets/${name}`, this.options, additionalQueryParams, 'v2');
4157
+ } catch (e) {
4158
+ return Promise.reject(e);
4159
+ }
4160
+
4161
+ // Handle network timeout if specified
4162
+ helpers.applyNetworkTimeout(this.options, networkParameters, controller);
4163
+
4164
+ return fetch(requestUrl, {
4165
+ method: 'GET',
4166
+ headers: {
4167
+ 'Content-Type': 'application/json',
4168
+ ...helpers.createAuthHeader(this.options),
4169
+ },
4170
+ signal,
4171
+ }).then((response) => {
4172
+ if (response.ok) {
4173
+ return response.json();
4174
+ }
4175
+
4176
+ return helpers.throwHttpErrorFromResponse(new Error(), response);
4177
+ });
4178
+ }
4179
+
4180
+ /**
4181
+ * Create or replace facet configurations (V2)
4182
+ *
4183
+ * Caution: Replacing will overwrite all other configurations you may have defined for the facet group,
4184
+ * resetting them to their defaults, except facet options - they will not be affected.
4185
+ *
4186
+ * @function createOrReplaceFacetConfigurationsV2
4187
+ * @param {object} parameters - Additional parameters for creating or replacing facet configurations
4188
+ * @param {array} parameters.facetConfigurations - List of facet configurations to create or replace (max 25 items)
4189
+ * @param {string} [parameters.section] - The section in which your facet is defined. Default value is Products.
4190
+ * @param {object} [networkParameters] - Parameters relevant to the network request
4191
+ * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
4192
+ * @returns {Promise<{facets: object[]}>} - List of created/replaced facet configurations
4193
+ * @see https://docs.constructor.com/reference/configuration-facets
4194
+ * @example
4195
+ * constructorio.catalog.createOrReplaceFacetConfigurationsV2({
4196
+ * facetConfigurations: [
4197
+ * {
4198
+ * name: 'color',
4199
+ * pathInMetadata: 'color',
4200
+ * type: 'multiple',
4201
+ * displayName: 'Color',
4202
+ * },
4203
+ * ],
4204
+ * });
4205
+ */
4206
+ createOrReplaceFacetConfigurationsV2(parameters = {}, networkParameters = {}) {
4207
+ let requestUrl;
4208
+ const { fetch } = this.options;
4209
+ const controller = new AbortController();
4210
+ const { signal } = controller;
4211
+ const { section, facetConfigurations: facetConfigurationsRaw } = parameters;
4212
+
4213
+ if (!facetConfigurationsRaw || !Array.isArray(facetConfigurationsRaw)) {
4214
+ return Promise.reject(new Error('facetConfigurations is a required parameter of type array'));
4215
+ }
4216
+
4217
+ const facetConfigurations = facetConfigurationsRaw.map((config) => toSnakeCaseKeys(config));
4218
+ const additionalQueryParams = {};
4219
+
4220
+ if (!helpers.isNil(section)) {
4221
+ additionalQueryParams.section = section;
4222
+ }
4223
+
4224
+ try {
4225
+ requestUrl = createCatalogUrl('facets', this.options, additionalQueryParams, 'v2');
4226
+ } catch (e) {
4227
+ return Promise.reject(e);
4228
+ }
4229
+
4230
+ // Handle network timeout if specified
4231
+ helpers.applyNetworkTimeout(this.options, networkParameters, controller);
4232
+
4233
+ return fetch(requestUrl, {
4234
+ method: 'PUT',
4235
+ body: JSON.stringify({ facets: facetConfigurations }),
4236
+ headers: {
4237
+ 'Content-Type': 'application/json',
4238
+ ...helpers.createAuthHeader(this.options),
4239
+ },
4240
+ signal,
4241
+ }).then((response) => {
4242
+ if (response.ok) {
4243
+ return response.json();
4244
+ }
4245
+
4246
+ return helpers.throwHttpErrorFromResponse(new Error(), response);
4247
+ });
4248
+ }
4249
+
4250
+ /**
4251
+ * Modify the configurations of multiple facets (partially) at once (V2)
4252
+ *
4253
+ * @function modifyFacetConfigurationsV2
4254
+ * @param {object} parameters - Additional parameters for modifying facet configurations
4255
+ * @param {array} parameters.facetConfigurations - List of facet configurations you would like to update (max 1000 items)
4256
+ * @param {string} [parameters.section] - The section in which your facet is defined. Default value is Products.
4257
+ * @param {object} [networkParameters] - Parameters relevant to the network request
4258
+ * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
4259
+ * @returns {Promise<{facets: object[]}>} - List of modified facet configurations
4260
+ * @see https://docs.constructor.com/reference/configuration-facets
4261
+ * @example
4262
+ * constructorio.catalog.modifyFacetConfigurationsV2({
4263
+ * facetConfigurations: [
4264
+ * {
4265
+ * name: 'color',
4266
+ * displayName: 'Color',
4267
+ * sortOrder: 'value',
4268
+ * },
4269
+ * ],
4270
+ * });
4271
+ */
4272
+ modifyFacetConfigurationsV2(parameters = {}, networkParameters = {}) {
4273
+ let requestUrl;
4274
+ const { fetch } = this.options;
4275
+ const controller = new AbortController();
4276
+ const { signal } = controller;
4277
+ const { section, facetConfigurations: facetConfigurationsRaw } = parameters;
4278
+
4279
+ if (!facetConfigurationsRaw || !Array.isArray(facetConfigurationsRaw)) {
4280
+ return Promise.reject(new Error('facetConfigurations is a required parameter of type array'));
4281
+ }
4282
+
4283
+ const facetConfigurations = facetConfigurationsRaw.map((config) => toSnakeCaseKeys(config));
4284
+ const additionalQueryParams = {};
4285
+
4286
+ if (!helpers.isNil(section)) {
4287
+ additionalQueryParams.section = section;
4288
+ }
4289
+
4290
+ try {
4291
+ requestUrl = createCatalogUrl('facets', this.options, additionalQueryParams, 'v2');
4292
+ } catch (e) {
4293
+ return Promise.reject(e);
4294
+ }
4295
+
4296
+ // Handle network timeout if specified
4297
+ helpers.applyNetworkTimeout(this.options, networkParameters, controller);
4298
+
4299
+ return fetch(requestUrl, {
4300
+ method: 'PATCH',
4301
+ body: JSON.stringify({ facets: facetConfigurations }),
4302
+ headers: {
4303
+ 'Content-Type': 'application/json',
4304
+ ...helpers.createAuthHeader(this.options),
4305
+ },
4306
+ signal,
4307
+ }).then((response) => {
4308
+ if (response.ok) {
4309
+ return response.json();
4310
+ }
4311
+
4312
+ return helpers.throwHttpErrorFromResponse(new Error(), response);
4313
+ });
4314
+ }
4315
+
4316
+ /**
4317
+ * Replace the configuration of a facet (completely) (V2)
4318
+ *
4319
+ * Caution: This will overwrite all other configurations you may have defined for the facet group,
4320
+ * resetting them to their defaults, except facet options - they will not be affected.
4321
+ *
4322
+ * @function replaceFacetConfigurationV2
4323
+ * @param {object} parameters - Additional parameters for facet configuration details
4324
+ * @param {string} parameters.name - Unique facet name used to refer to the facet in your catalog
4325
+ * @param {string} parameters.pathInMetadata - The path in metadata of each item where this facet is present
4326
+ * @param {string} parameters.type - Type of facet. Must be one of multiple, hierarchical, or range
4327
+ * @param {string} [parameters.displayName] - The name of the facet presented to the end users
4328
+ * @param {string} [parameters.sortOrder] - Defines the criterion by which the options are sorted
4329
+ * @param {boolean} [parameters.sortDescending] - Set to true if the options should be sorted in descending order
4330
+ * @param {string} [parameters.rangeType] - Should be 'static' if a facet is configured as range
4331
+ * @param {string} [parameters.rangeFormat] - Format of range facets: 'boundaries' or 'options'
4332
+ * @param {string} [parameters.rangeInclusive] - Used to create inclusive buckets: 'above', 'below', or null
4333
+ * @param {number[]} [parameters.rangeLimits] - Defines the cut-off points for generating static range buckets
4334
+ * @param {string} [parameters.matchType] - Specifies the behavior of filters: 'any', 'all', or 'none'
4335
+ * @param {number} [parameters.position] - Slot facet groups to fixed positions
4336
+ * @param {boolean} [parameters.hidden] - Specifies whether the facet is hidden from users
4337
+ * @param {boolean} [parameters.protected] - Specifies whether the facet is protected from users
4338
+ * @param {boolean} [parameters.countable] - Specifies whether counts for each facet option should be calculated
4339
+ * @param {number} [parameters.optionsLimit] - Maximum number of options to return in search responses
4340
+ * @param {object} [parameters.data] - Dictionary/Object with any extra facet data
4341
+ * @param {string} [parameters.section] - The section in which your facet is defined. Default value is Products.
4342
+ * @param {object} [networkParameters] - Parameters relevant to the network request
4343
+ * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
4344
+ * @returns {Promise<object>} - Replaced facet configuration response
4345
+ * @see https://docs.constructor.com/reference/configuration-facets
4346
+ * @example
4347
+ * constructorio.catalog.replaceFacetConfigurationV2({
4348
+ * name: 'color',
4349
+ * pathInMetadata: 'color',
4350
+ * type: 'multiple',
4351
+ * displayName: 'Color',
4352
+ * });
4353
+ */
4354
+ replaceFacetConfigurationV2(parameters = {}, networkParameters = {}) {
4355
+ let requestUrl;
4356
+ const { fetch } = this.options;
4357
+ const controller = new AbortController();
4358
+ const { signal } = controller;
4359
+ const { section, name, pathInMetadata, ...rest } = parameters;
4360
+
4361
+ if (!name || typeof name !== 'string') {
4362
+ return Promise.reject(new Error('name is a required parameter of type string'));
4363
+ }
4364
+
4365
+ if (!pathInMetadata || typeof pathInMetadata !== 'string') {
4366
+ return Promise.reject(new Error('pathInMetadata is a required parameter of type string'));
4367
+ }
4368
+
4369
+ const validFacetTypes = ['multiple', 'hierarchical', 'range'];
4370
+
4371
+ if (!rest.type || !validFacetTypes.includes(rest.type)) {
4372
+ return Promise.reject(new Error('type is a required parameter and must be one of: multiple, hierarchical, or range'));
4373
+ }
4374
+
4375
+ const additionalQueryParams = {};
4376
+
4377
+ if (!helpers.isNil(section)) {
4378
+ additionalQueryParams.section = section;
4379
+ }
4380
+
4381
+ try {
4382
+ requestUrl = createCatalogUrl(`facets/${name}`, this.options, additionalQueryParams, 'v2');
4383
+ } catch (e) {
4384
+ return Promise.reject(e);
4385
+ }
4386
+
4387
+ // Handle network timeout if specified
4388
+ helpers.applyNetworkTimeout(this.options, networkParameters, controller);
4389
+
4390
+ return fetch(requestUrl, {
4391
+ method: 'PUT',
4392
+ body: JSON.stringify(toSnakeCaseKeys({ name, pathInMetadata, ...rest })),
4393
+ headers: {
4394
+ 'Content-Type': 'application/json',
4395
+ ...helpers.createAuthHeader(this.options),
4396
+ },
4397
+ signal,
4398
+ }).then((response) => {
4399
+ if (response.ok) {
4400
+ return response.json();
4401
+ }
4402
+
4403
+ return helpers.throwHttpErrorFromResponse(new Error(), response);
4404
+ });
4405
+ }
4406
+
4407
+ /**
4408
+ * Modify the configuration of a facet (partially) (V2)
4409
+ *
4410
+ * @function modifyFacetConfigurationV2
4411
+ * @param {object} parameters - Additional parameters for facet configuration details
4412
+ * @param {string} parameters.name - Unique facet name used to refer to the facet in your catalog
4413
+ * @param {string} [parameters.pathInMetadata] - The path in metadata of each item where this facet is present
4414
+ * @param {string} [parameters.type] - Type of facet. Must be one of multiple, hierarchical, or range
4415
+ * @param {string} [parameters.displayName] - The name of the facet presented to the end users
4416
+ * @param {string} [parameters.sortOrder] - Defines the criterion by which the options are sorted
4417
+ * @param {boolean} [parameters.sortDescending] - Set to true if the options should be sorted in descending order
4418
+ * @param {string} [parameters.rangeType] - Should be 'static' if a facet is configured as range
4419
+ * @param {string} [parameters.rangeFormat] - Format of range facets: 'boundaries' or 'options'
4420
+ * @param {string} [parameters.rangeInclusive] - Used to create inclusive buckets: 'above', 'below', or null
4421
+ * @param {number[]} [parameters.rangeLimits] - Defines the cut-off points for generating static range buckets
4422
+ * @param {string} [parameters.matchType] - Specifies the behavior of filters: 'any', 'all', or 'none'
4423
+ * @param {number} [parameters.position] - Slot facet groups to fixed positions
4424
+ * @param {boolean} [parameters.hidden] - Specifies whether the facet is hidden from users
4425
+ * @param {boolean} [parameters.protected] - Specifies whether the facet is protected from users
4426
+ * @param {boolean} [parameters.countable] - Specifies whether counts for each facet option should be calculated
4427
+ * @param {number} [parameters.optionsLimit] - Maximum number of options to return in search responses
4428
+ * @param {object} [parameters.data] - Dictionary/Object with any extra facet data
4429
+ * @param {string} [parameters.section] - The section in which your facet is defined. Default value is Products.
4430
+ * @param {object} [networkParameters] - Parameters relevant to the network request
4431
+ * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
4432
+ * @returns {Promise<object>} - Modified facet configuration response
4433
+ * @see https://docs.constructor.com/reference/configuration-facets
4434
+ * @example
4435
+ * constructorio.catalog.modifyFacetConfigurationV2({
4436
+ * name: 'color',
4437
+ * displayName: 'Color',
4438
+ * sortOrder: 'num_matches',
4439
+ * });
4440
+ */
4441
+ modifyFacetConfigurationV2(parameters = {}, networkParameters = {}) {
4442
+ let requestUrl;
4443
+ const { fetch } = this.options;
4444
+ const controller = new AbortController();
4445
+ const { signal } = controller;
4446
+ const { section, name, ...rest } = parameters;
4447
+
4448
+ if (!name || typeof name !== 'string') {
4449
+ return Promise.reject(new Error('name is a required parameter of type string'));
4450
+ }
4451
+
4452
+ const additionalQueryParams = {};
4453
+
4454
+ if (!helpers.isNil(section)) {
4455
+ additionalQueryParams.section = section;
4456
+ }
4457
+
4458
+ try {
4459
+ requestUrl = createCatalogUrl(`facets/${name}`, this.options, additionalQueryParams, 'v2');
4460
+ } catch (e) {
4461
+ return Promise.reject(e);
4462
+ }
4463
+
4464
+ // Handle network timeout if specified
4465
+ helpers.applyNetworkTimeout(this.options, networkParameters, controller);
4466
+
4467
+ return fetch(requestUrl, {
4468
+ method: 'PATCH',
4469
+ body: JSON.stringify(toSnakeCaseKeys(rest)),
4470
+ headers: {
4471
+ 'Content-Type': 'application/json',
4472
+ ...helpers.createAuthHeader(this.options),
4473
+ },
4474
+ signal,
4475
+ }).then((response) => {
4476
+ if (response.ok) {
4477
+ return response.json();
4478
+ }
4479
+
4480
+ return helpers.throwHttpErrorFromResponse(new Error(), response);
4481
+ });
4482
+ }
4483
+
4484
+ /**
4485
+ * Remove a facet configuration (V2)
4486
+ *
4487
+ * Caution: Once a facet group's configuration is removed, all configurations will return to their default values.
4488
+ * This includes all facet option configurations (display name, position, etc) you may have defined.
4489
+ *
4490
+ * @function removeFacetConfigurationV2
4491
+ * @param {object} parameters - Additional parameters for facet configuration details
4492
+ * @param {string} parameters.name - Unique facet name used to refer to the facet in your catalog
4493
+ * @param {string} [parameters.section] - The section in which your facet is defined. Default value is Products.
4494
+ * @param {object} [networkParameters] - Parameters relevant to the network request
4495
+ * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
4496
+ * @returns {Promise<object>} - Removed facet configuration response
4497
+ * @see https://docs.constructor.com/reference/configuration-facets
4498
+ * @example
4499
+ * constructorio.catalog.removeFacetConfigurationV2({
4500
+ * name: 'color',
4501
+ * });
4502
+ */
4503
+ removeFacetConfigurationV2(parameters = {}, networkParameters = {}) {
4504
+ let requestUrl;
4505
+ const { fetch } = this.options;
4506
+ const controller = new AbortController();
4507
+ const { signal } = controller;
4508
+ const { section, name } = parameters;
4509
+
4510
+ if (!name || typeof name !== 'string') {
4511
+ return Promise.reject(new Error('name is a required parameter of type string'));
4512
+ }
4513
+
4514
+ const additionalQueryParams = {};
4515
+
4516
+ if (!helpers.isNil(section)) {
4517
+ additionalQueryParams.section = section;
4518
+ }
4519
+
4520
+ try {
4521
+ requestUrl = createCatalogUrl(`facets/${name}`, this.options, additionalQueryParams, 'v2');
4522
+ } catch (e) {
4523
+ return Promise.reject(e);
4524
+ }
4525
+
4526
+ // Handle network timeout if specified
4527
+ helpers.applyNetworkTimeout(this.options, networkParameters, controller);
4528
+
4529
+ return fetch(requestUrl, {
4530
+ method: 'DELETE',
4531
+ headers: {
4532
+ ...helpers.createAuthHeader(this.options),
4533
+ },
4534
+ signal,
4535
+ }).then((response) => {
4536
+ if (response.ok) {
4537
+ return response.json();
4538
+ }
4539
+
4540
+ return helpers.throwHttpErrorFromResponse(new Error(), response);
4541
+ });
4542
+ }
4543
+
4544
+ // -------------------- V2 Searchabilities Methods --------------------
4545
+
4546
+ /**
4547
+ * Retrieve all searchabilities (V2)
4548
+ *
4549
+ * @function retrieveSearchabilitiesV2
4550
+ * @param {object} parameters - Additional parameters for retrieving searchabilities
4551
+ * @param {string} [parameters.name] - Name of searchability field to filter for
4552
+ * @param {number} [parameters.page] - Page number you'd like to request
4553
+ * @param {number} [parameters.offset] - The number of results to skip from the beginning
4554
+ * @param {number} [parameters.numResultsPerPage] - Number of searchabilities per page. Default value is 20.
4555
+ * @param {boolean} [parameters.fuzzySearchable] - Filter by fuzzy_searchable
4556
+ * @param {boolean} [parameters.exactSearchable] - Filter by exact_searchable
4557
+ * @param {boolean} [parameters.displayable] - Filter by displayable
4558
+ * @param {string} [parameters.matchType] - Whether filters should be ANDed or ORed ('and' or 'or')
4559
+ * @param {string} [parameters.sortBy] - The criteria by which searchabilities should be sorted ('name')
4560
+ * @param {string} [parameters.sortOrder] - The sort order ('ascending' or 'descending')
4561
+ * @param {string} [parameters.section] - The section in which the searchability is defined. Default value is Products.
4562
+ * @param {object} [networkParameters] - Parameters relevant to the network request
4563
+ * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
4564
+ * @returns {Promise<{searchabilities: object[], total_count: number}>} - Paginated list of searchability configurations
4565
+ * @see https://docs.constructor.com/reference/configuration-searchabilities
4566
+ * @example
4567
+ * constructorio.catalog.retrieveSearchabilitiesV2({
4568
+ * page: 1,
4569
+ * numResultsPerPage: 50,
4570
+ * });
4571
+ */
4572
+ retrieveSearchabilitiesV2(parameters = {}, networkParameters = {}) {
4573
+ let requestUrl;
4574
+ const { fetch } = this.options;
4575
+ const controller = new AbortController();
4576
+ const { signal } = controller;
4577
+ const {
4578
+ name,
4579
+ page,
4580
+ offset,
4581
+ numResultsPerPage,
4582
+ fuzzySearchable,
4583
+ exactSearchable,
4584
+ displayable,
4585
+ matchType,
4586
+ sortBy,
4587
+ sortOrder,
4588
+ section,
4589
+ } = parameters;
4590
+ const additionalQueryParams = {};
4591
+
4592
+ if (!helpers.isNil(section)) {
4593
+ additionalQueryParams.section = section;
4594
+ }
4595
+
4596
+ if (!helpers.isNil(page)) {
4597
+ additionalQueryParams.page = page;
4598
+ }
4599
+
4600
+ if (!helpers.isNil(offset)) {
4601
+ additionalQueryParams.offset = offset;
4602
+ }
4603
+
4604
+ if (!helpers.isNil(numResultsPerPage)) {
4605
+ additionalQueryParams.num_results_per_page = numResultsPerPage;
4606
+ }
4607
+
4608
+ if (!helpers.isNil(name)) {
4609
+ additionalQueryParams.name = name;
4610
+ }
4611
+
4612
+ if (!helpers.isNil(fuzzySearchable)) {
4613
+ additionalQueryParams.fuzzy_searchable = fuzzySearchable;
4614
+ }
4615
+
4616
+ if (!helpers.isNil(exactSearchable)) {
4617
+ additionalQueryParams.exact_searchable = exactSearchable;
4618
+ }
4619
+
4620
+ if (!helpers.isNil(displayable)) {
4621
+ additionalQueryParams.displayable = displayable;
4622
+ }
4623
+
4624
+ if (!helpers.isNil(matchType)) {
4625
+ additionalQueryParams.match_type = matchType;
4626
+ }
4627
+
4628
+ if (!helpers.isNil(sortBy)) {
4629
+ additionalQueryParams.sort_by = sortBy;
4630
+ }
4631
+
4632
+ if (!helpers.isNil(sortOrder)) {
4633
+ additionalQueryParams.sort_order = sortOrder;
4634
+ }
4635
+
4636
+ try {
4637
+ requestUrl = createCatalogUrl('searchabilities', this.options, additionalQueryParams, 'v2');
4638
+ } catch (e) {
4639
+ return Promise.reject(e);
4640
+ }
4641
+
4642
+ // Handle network timeout if specified
4643
+ helpers.applyNetworkTimeout(this.options, networkParameters, controller);
4644
+
4645
+ return fetch(requestUrl, {
4646
+ method: 'GET',
4647
+ headers: {
4648
+ 'Content-Type': 'application/json',
4649
+ ...helpers.createAuthHeader(this.options),
4650
+ },
4651
+ signal,
4652
+ }).then((response) => {
4653
+ if (response.ok) {
4654
+ return response.json();
4655
+ }
4656
+
4657
+ return helpers.throwHttpErrorFromResponse(new Error(), response);
4658
+ });
4659
+ }
4660
+
4661
+ /**
4662
+ * Get a single searchability configuration (V2)
4663
+ *
4664
+ * @function retrieveSearchabilityV2
4665
+ * @param {object} parameters - Additional parameters for retrieving a searchability
4666
+ * @param {string} parameters.name - Name of the searchability field
4667
+ * @param {string} [parameters.section] - The section in which the searchability is defined. Default value is Products.
4668
+ * @param {object} [networkParameters] - Parameters relevant to the network request
4669
+ * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
4670
+ * @returns {Promise<object>} - Searchability configuration response
4671
+ * @see https://docs.constructor.com/reference/configuration-searchabilities
4672
+ * @example
4673
+ * constructorio.catalog.retrieveSearchabilityV2({
4674
+ * name: 'keywords',
4675
+ * });
4676
+ */
4677
+ retrieveSearchabilityV2(parameters = {}, networkParameters = {}) {
4678
+ let requestUrl;
4679
+ const { fetch } = this.options;
4680
+ const controller = new AbortController();
4681
+ const { signal } = controller;
4682
+ const { name, section } = parameters;
4683
+
4684
+ if (!name || typeof name !== 'string') {
4685
+ return Promise.reject(new Error('name is a required parameter of type string'));
4686
+ }
4687
+
4688
+ const additionalQueryParams = {};
4689
+
4690
+ if (!helpers.isNil(section)) {
4691
+ additionalQueryParams.section = section;
4692
+ }
4693
+
4694
+ try {
4695
+ requestUrl = createCatalogUrl(`searchabilities/${name}`, this.options, additionalQueryParams, 'v2');
4696
+ } catch (e) {
4697
+ return Promise.reject(e);
4698
+ }
4699
+
4700
+ // Handle network timeout if specified
4701
+ helpers.applyNetworkTimeout(this.options, networkParameters, controller);
4702
+
4703
+ return fetch(requestUrl, {
4704
+ method: 'GET',
4705
+ headers: {
4706
+ 'Content-Type': 'application/json',
4707
+ ...helpers.createAuthHeader(this.options),
4708
+ },
4709
+ signal,
4710
+ }).then((response) => {
4711
+ if (response.ok) {
4712
+ return response.json();
4713
+ }
4714
+
4715
+ return helpers.throwHttpErrorFromResponse(new Error(), response);
4716
+ });
4717
+ }
4718
+
4719
+ /**
4720
+ * Create or update searchabilities (V2)
4721
+ *
4722
+ * @function patchSearchabilitiesV2
4723
+ * @param {object} parameters - Additional parameters for patching searchabilities
4724
+ * @param {object[]} parameters.searchabilities - Array of searchabilities to create or update (1-60 items)
4725
+ * @param {boolean} [parameters.skipRebuild] - Skip index rebuild. Default value is false.
4726
+ * @param {string} [parameters.section] - The section in which the searchability is defined. Default value is Products.
4727
+ * @param {object} [networkParameters] - Parameters relevant to the network request
4728
+ * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
4729
+ * @returns {Promise<{searchabilities: object[], total_count: number}>} - Updated searchability configurations
4730
+ * @see https://docs.constructor.com/reference/configuration-searchabilities
4731
+ * @example
4732
+ * constructorio.catalog.patchSearchabilitiesV2({
4733
+ * searchabilities: [
4734
+ * {
4735
+ * name: 'style_id',
4736
+ * exactSearchable: true,
4737
+ * },
4738
+ * {
4739
+ * name: 'keywords',
4740
+ * fuzzySearchable: true,
4741
+ * },
4742
+ * ],
4743
+ * });
4744
+ */
4745
+ patchSearchabilitiesV2(parameters = {}, networkParameters = {}) {
4746
+ let requestUrl;
4747
+ const { fetch } = this.options;
4748
+ const controller = new AbortController();
4749
+ const { signal } = controller;
4750
+ const { searchabilities: searchabilitiesRaw, skipRebuild, section } = parameters;
4751
+
4752
+ if (!searchabilitiesRaw || !Array.isArray(searchabilitiesRaw)) {
4753
+ return Promise.reject(new Error('searchabilities is a required parameter of type array'));
4754
+ }
4755
+
4756
+ const searchabilities = searchabilitiesRaw.map((config) => toSnakeCaseKeys(config));
4757
+ const additionalQueryParams = {};
4758
+
4759
+ if (!helpers.isNil(section)) {
4760
+ additionalQueryParams.section = section;
4761
+ }
4762
+
4763
+ if (!helpers.isNil(skipRebuild)) {
4764
+ additionalQueryParams.skip_rebuild = skipRebuild;
4765
+ }
4766
+
4767
+ try {
4768
+ requestUrl = createCatalogUrl('searchabilities', this.options, additionalQueryParams, 'v2');
4769
+ } catch (e) {
4770
+ return Promise.reject(e);
4771
+ }
4772
+
4773
+ // Handle network timeout if specified
4774
+ helpers.applyNetworkTimeout(this.options, networkParameters, controller);
4775
+
4776
+ return fetch(requestUrl, {
4777
+ method: 'PATCH',
4778
+ body: JSON.stringify({ searchabilities }),
4779
+ headers: {
4780
+ 'Content-Type': 'application/json',
4781
+ ...helpers.createAuthHeader(this.options),
4782
+ },
4783
+ signal,
4784
+ }).then((response) => {
4785
+ if (response.ok) {
4786
+ return response.json();
4787
+ }
4788
+
4789
+ return helpers.throwHttpErrorFromResponse(new Error(), response);
4790
+ });
4791
+ }
4792
+
4793
+ /**
4794
+ * Update a single searchability configuration (V2)
4795
+ *
4796
+ * @function patchSearchabilityV2
4797
+ * @param {object} parameters - Additional parameters for patching a searchability
4798
+ * @param {string} parameters.name - Name of the searchability field
4799
+ * @param {boolean} [parameters.fuzzySearchable] - Whether the field is fuzzy searchable
4800
+ * @param {boolean} [parameters.exactSearchable] - Whether the field is exact searchable
4801
+ * @param {boolean} [parameters.displayable] - Whether the field is displayable
4802
+ * @param {boolean} [parameters.hidden] - Whether the field is hidden
4803
+ * @param {boolean} [parameters.skipRebuild] - Skip index rebuild. Default value is false.
4804
+ * @param {string} [parameters.section] - The section in which the searchability is defined. Default value is Products.
4805
+ * @param {object} [networkParameters] - Parameters relevant to the network request
4806
+ * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
4807
+ * @returns {Promise<object>} - Updated searchability configuration response
4808
+ * @see https://docs.constructor.com/reference/configuration-searchabilities
4809
+ * @example
4810
+ * constructorio.catalog.patchSearchabilityV2({
4811
+ * name: 'keywords',
4812
+ * fuzzySearchable: true,
4813
+ * });
4814
+ */
4815
+ patchSearchabilityV2(parameters = {}, networkParameters = {}) {
4816
+ let requestUrl;
4817
+ const { fetch } = this.options;
4818
+ const controller = new AbortController();
4819
+ const { signal } = controller;
4820
+ const { name, skipRebuild, section, ...rest } = parameters;
4821
+
4822
+ if (!name || typeof name !== 'string') {
4823
+ return Promise.reject(new Error('name is a required parameter of type string'));
4824
+ }
4825
+
4826
+ const additionalQueryParams = {};
4827
+
4828
+ if (!helpers.isNil(section)) {
4829
+ additionalQueryParams.section = section;
4830
+ }
4831
+
4832
+ if (!helpers.isNil(skipRebuild)) {
4833
+ additionalQueryParams.skip_rebuild = skipRebuild;
4834
+ }
4835
+
4836
+ try {
4837
+ requestUrl = createCatalogUrl(`searchabilities/${name}`, this.options, additionalQueryParams, 'v2');
4838
+ } catch (e) {
4839
+ return Promise.reject(e);
4840
+ }
4841
+
4842
+ // Handle network timeout if specified
4843
+ helpers.applyNetworkTimeout(this.options, networkParameters, controller);
4844
+
4845
+ return fetch(requestUrl, {
4846
+ method: 'PATCH',
4847
+ body: JSON.stringify(toSnakeCaseKeys(rest)),
4848
+ headers: {
4849
+ 'Content-Type': 'application/json',
4850
+ ...helpers.createAuthHeader(this.options),
4851
+ },
4852
+ signal,
4853
+ }).then((response) => {
4854
+ if (response.ok) {
4855
+ return response.json();
4856
+ }
4857
+
4858
+ return helpers.throwHttpErrorFromResponse(new Error(), response);
4859
+ });
4860
+ }
4861
+
4862
+ /**
4863
+ * Delete searchabilities (V2)
4864
+ *
4865
+ * @function deleteSearchabilitiesV2
4866
+ * @param {object} parameters - Additional parameters for deleting searchabilities
4867
+ * @param {object[]} parameters.searchabilities - Array of searchabilities names to delete (1-60 items)
4868
+ * @param {boolean} [parameters.skipRebuild] - Skip index rebuild. Default value is false.
4869
+ * @param {string} [parameters.section] - The section in which the searchability is defined. Default value is Products.
4870
+ * @param {object} [networkParameters] - Parameters relevant to the network request
4871
+ * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
4872
+ * @returns {Promise<{searchabilities: object[], total_count: number}>} - Deleted searchability configurations
4873
+ * @see https://docs.constructor.com/reference/configuration-searchabilities
4874
+ * @example
4875
+ * constructorio.catalog.deleteSearchabilitiesV2({
4876
+ * searchabilities: [
4877
+ * { name: 'style_id' },
4878
+ * { name: 'keywords' },
4879
+ * ],
4880
+ * });
4881
+ */
4882
+ deleteSearchabilitiesV2(parameters = {}, networkParameters = {}) {
4883
+ let requestUrl;
4884
+ const { fetch } = this.options;
4885
+ const controller = new AbortController();
4886
+ const { signal } = controller;
4887
+ const { searchabilities: searchabilitiesRaw, skipRebuild, section } = parameters;
4888
+
4889
+ if (!searchabilitiesRaw || !Array.isArray(searchabilitiesRaw)) {
4890
+ return Promise.reject(new Error('searchabilities is a required parameter of type array'));
4891
+ }
4892
+
4893
+ const searchabilities = searchabilitiesRaw.map((config) => toSnakeCaseKeys(config));
4894
+ const additionalQueryParams = {};
4895
+
4896
+ if (!helpers.isNil(section)) {
4897
+ additionalQueryParams.section = section;
4898
+ }
4899
+
4900
+ if (!helpers.isNil(skipRebuild)) {
4901
+ additionalQueryParams.skip_rebuild = skipRebuild;
4902
+ }
4903
+
4904
+ try {
4905
+ requestUrl = createCatalogUrl('searchabilities', this.options, additionalQueryParams, 'v2');
4906
+ } catch (e) {
4907
+ return Promise.reject(e);
4908
+ }
4909
+
4910
+ // Handle network timeout if specified
4911
+ helpers.applyNetworkTimeout(this.options, networkParameters, controller);
4912
+
4913
+ return fetch(requestUrl, {
4914
+ method: 'DELETE',
4915
+ body: JSON.stringify({ searchabilities }),
4916
+ headers: {
4917
+ 'Content-Type': 'application/json',
4918
+ ...helpers.createAuthHeader(this.options),
4919
+ },
4920
+ signal,
4921
+ }).then((response) => {
4922
+ if (response.ok) {
4923
+ return response.json();
4924
+ }
4925
+
4926
+ return helpers.throwHttpErrorFromResponse(new Error(), response);
4927
+ });
4928
+ }
4929
+
4930
+ /**
4931
+ * Delete a single searchability configuration (V2)
4932
+ *
4933
+ * @function deleteSearchabilityV2
4934
+ * @param {object} parameters - Additional parameters for deleting a searchability
4935
+ * @param {string} parameters.name - Name of the searchability field to delete
4936
+ * @param {boolean} [parameters.skipRebuild] - Skip index rebuild. Default value is false.
4937
+ * @param {string} [parameters.section] - The section in which the searchability is defined. Default value is Products.
4938
+ * @param {object} [networkParameters] - Parameters relevant to the network request
4939
+ * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
4940
+ * @returns {Promise<object>} - Deleted searchability configuration response
4941
+ * @see https://docs.constructor.com/reference/configuration-searchabilities
4942
+ * @example
4943
+ * constructorio.catalog.deleteSearchabilityV2({
4944
+ * name: 'keywords',
4945
+ * });
4946
+ */
4947
+ deleteSearchabilityV2(parameters = {}, networkParameters = {}) {
4948
+ let requestUrl;
4949
+ const { fetch } = this.options;
4950
+ const controller = new AbortController();
4951
+ const { signal } = controller;
4952
+ const { name, skipRebuild, section } = parameters;
4953
+
4954
+ if (!name || typeof name !== 'string') {
4955
+ return Promise.reject(new Error('name is a required parameter of type string'));
4956
+ }
4957
+
4958
+ const additionalQueryParams = {};
4959
+
4960
+ if (!helpers.isNil(section)) {
4961
+ additionalQueryParams.section = section;
4962
+ }
4963
+
4964
+ if (!helpers.isNil(skipRebuild)) {
4965
+ additionalQueryParams.skip_rebuild = skipRebuild;
4966
+ }
4967
+
4968
+ try {
4969
+ requestUrl = createCatalogUrl(`searchabilities/${name}`, this.options, additionalQueryParams, 'v2');
4970
+ } catch (e) {
4971
+ return Promise.reject(e);
4972
+ }
4973
+
4974
+ // Handle network timeout if specified
4975
+ helpers.applyNetworkTimeout(this.options, networkParameters, controller);
4976
+
4977
+ return fetch(requestUrl, {
4978
+ method: 'DELETE',
4979
+ headers: {
4980
+ ...helpers.createAuthHeader(this.options),
4981
+ },
4982
+ signal,
4983
+ }).then((response) => {
4984
+ if (response.ok) {
4985
+ return response.json();
4986
+ }
4987
+
4988
+ return helpers.throwHttpErrorFromResponse(new Error(), response);
4989
+ });
4990
+ }
3906
4991
  }
3907
4992
 
3908
4993
  module.exports = Catalog;