oneentry 1.0.177 → 1.0.178

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.
@@ -136,11 +136,21 @@ export default class FormsDataApi extends AsyncModules implements IFormsData {
136
136
  * @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/getFormsDataByMarker getFormsDataByMarker} documentation.
137
137
  */
138
138
  getFormsDataByMarker(marker: string, formModuleConfigId: number, body?: IFormsDataFilter, isExtended?: number, langCode?: string, offset?: number, limit?: number): Promise<IFormsByMarkerDataEntity | IError>;
139
+ /**
140
+ * Wrap the caller's flat `formData` array under its language code and upload any
141
+ * file fields, so the submit endpoints receive `{ [langCode]: [...] }`. Shared by
142
+ * postFormsData and updateFormsDataByid so the two never diverge.
143
+ * @param {FormDataType[]} rawFormData - Flat array of form fields.
144
+ * @param {string} langCode - Language code the fields are wrapped under.
145
+ * @returns {Promise<object>} The locale-keyed formData and the first upload error, if any.
146
+ */
147
+ private _buildLocalizedFormData;
139
148
  /**
140
149
  * Update one object of form data by id. Requires user authentication.
141
150
  * @handleName updateFormsDataByid
142
151
  * @param {number} id - Form data ID. Example: 1.
143
- * @param {object} [body] - Form data to save: the same fields as in `postFormsData` (`formIdentifier`, `formModuleConfigId`, `moduleEntityIdentifier`, `replayTo`, `status`, `formData`). Default: `{}`.
152
+ * @param {IBodyPostFormData} body - Form data to save: the same fields as in `postFormsData` (`formIdentifier`, `formModuleConfigId`, `moduleEntityIdentifier`, `replayTo`, `status`, `formData`). The flat `formData` array is wrapped under `langCode` before sending, exactly like `postFormsData`.
153
+ * @param {string} [langCode] - Language code the form fields are saved under. Default: "en_US".
144
154
  * @example
145
155
  {
146
156
  "formIdentifier": "test-form",
@@ -159,7 +169,7 @@ export default class FormsDataApi extends AsyncModules implements IFormsData {
159
169
  * @returns {Promise<IUpdateFormsData | IError>} Returns an object containing the updated form data or an error object if there was an issue.
160
170
  * @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/updateFormsDataByid updateFormsDataByid} documentation.
161
171
  */
162
- updateFormsDataByid(id: number, body?: object): Promise<IUpdateFormsData | IError>;
172
+ updateFormsDataByid(id: number, body: IBodyPostFormData, langCode?: string): Promise<IUpdateFormsData | IError>;
163
173
  /**
164
174
  * Update form data status by id. Requires user authentication.
165
175
  * @handleName updateFormsDataStatusByid
@@ -66,73 +66,8 @@ export default class FormsDataApi extends AsyncModules {
66
66
  * @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/postFormsData postFormsData} documentation.
67
67
  */
68
68
  async postFormsData(body, langCode = this.state.lang) {
69
- const formData = {};
70
- // filter button fields; keep spam fields so the captcha token in their `value` reaches the server
71
- formData[langCode] = Array.isArray(body.formData)
72
- ? body.formData.filter((fd) => fd.type !== 'button')
73
- : [body.formData].filter((fd) => fd.type !== 'button');
74
- /**
75
- * Handle file uploads if fileQuery is present
76
- * Check if there is any element in formData[langCode] that contains one of the specified types
77
- */
78
- if (formData[langCode].find((fd) => ['file', 'image', 'groupOfImages'].includes(fd.type))) {
79
- // Create an instance of FileUploadingApi with the current state
80
- const fileUploader = new FileUploadingApi(this.state);
81
- // Process each element in formData[langCode] asynchronously
82
- formData[langCode] = await Promise.all(formData[langCode].map(async (field) => {
83
- // Check if the type is one of the specified types
84
- if (['file', 'image', 'groupOfImages'].includes(field.type)) {
85
- // Work on a copy: the caller's field keeps its File and its fileQuery,
86
- // so a reused body sends the same form again (CMS-1071)
87
- const fd = { ...field };
88
- // If fileQuery does not exist, we create it and assign it to an object with the following properties:
89
- if (!fd.fileQuery) {
90
- const fileQuery = {
91
- type: 'page',
92
- entity: 'editor',
93
- // Generate a random 4-digit ID
94
- id: Number(Math.floor(Math.random() * 10000)
95
- .toString()
96
- .padStart(4, '0')),
97
- };
98
- fd.fileQuery = fileQuery;
99
- }
100
- // Convert fd.value to an array if it is a FileList, otherwise use it directly
101
- const filesArray = typeof FileList !== 'undefined' && fd.value instanceof FileList
102
- ? Array.from(fd.value)
103
- : fd.value;
104
- // If filesArray is an array, upload the files it holds asynchronously
105
- if (Array.isArray(filesArray)) {
106
- const uploadPromises = filesArray.map((file) =>
107
- // An entry that is already in storage is passed through: a
108
- // second upload would send the descriptor itself as the file
109
- // and the endpoint answers `value[0].filename is required`.
110
- this._isUploadable(file)
111
- ? fileUploader.upload(file, fd.fileQuery).catch((e) => e)
112
- : file);
113
- fd.value = (await Promise.all(uploadPromises)).flat();
114
- }
115
- // If fd.value is a single File or Blob, upload it
116
- else if (this._isUploadable(fd.value)) {
117
- fd.value = await fileUploader
118
- .upload(fd.value, fd.fileQuery)
119
- .catch((e) => e); // Catch any errors during upload
120
- }
121
- // Remove the 'fileQuery' property from the object after processing
122
- delete fd.fileQuery;
123
- // Remove the 'contentType' property from the file object because it is not needed and not valid
124
- fd.value = this._stripContentType(fd.value);
125
- return fd;
126
- }
127
- // Return the form data element untouched
128
- return field;
129
- }));
130
- }
131
- // A failed upload used to be sent to the platform as the field's value, and the caller
132
- // got a success: the form is not sent, the upload's error is the answer
133
- const uploadError = formData[langCode]
134
- .flatMap((field) => Array.isArray(field === null || field === void 0 ? void 0 : field.value) ? field.value : [field === null || field === void 0 ? void 0 : field.value])
135
- .find((value) => this._isErrorResponse(value));
69
+ // Wrap the flat formData under langCode (and upload any files) before sending
70
+ const { formData, uploadError } = await this._buildLocalizedFormData(body.formData, langCode);
136
71
  if (uploadError) {
137
72
  if (this.state.isShell) {
138
73
  return uploadError;
@@ -250,11 +185,90 @@ export default class FormsDataApi extends AsyncModules {
250
185
  const validated = await this._validateResponse(result, schema('FormsByMarkerDataResponseSchema'));
251
186
  return this._normalizeData(validated, langCode);
252
187
  }
188
+ /**
189
+ * Wrap the caller's flat `formData` array under its language code and upload any
190
+ * file fields, so the submit endpoints receive `{ [langCode]: [...] }`. Shared by
191
+ * postFormsData and updateFormsDataByid so the two never diverge.
192
+ * @param {FormDataType[]} rawFormData - Flat array of form fields.
193
+ * @param {string} langCode - Language code the fields are wrapped under.
194
+ * @returns {Promise<object>} The locale-keyed formData and the first upload error, if any.
195
+ */
196
+ async _buildLocalizedFormData(rawFormData, langCode) {
197
+ const formData = {};
198
+ // filter button fields; keep spam fields so the captcha token in their `value` reaches the server
199
+ formData[langCode] = Array.isArray(rawFormData)
200
+ ? rawFormData.filter((fd) => fd.type !== 'button')
201
+ : [rawFormData].filter((fd) => fd.type !== 'button');
202
+ /**
203
+ * Handle file uploads if fileQuery is present
204
+ * Check if there is any element in formData[langCode] that contains one of the specified types
205
+ */
206
+ if (formData[langCode].find((fd) => ['file', 'image', 'groupOfImages'].includes(fd.type))) {
207
+ // Create an instance of FileUploadingApi with the current state
208
+ const fileUploader = new FileUploadingApi(this.state);
209
+ // Process each element in formData[langCode] asynchronously
210
+ formData[langCode] = await Promise.all(formData[langCode].map(async (field) => {
211
+ // Check if the type is one of the specified types
212
+ if (['file', 'image', 'groupOfImages'].includes(field.type)) {
213
+ // Work on a copy: the caller's field keeps its File and its fileQuery,
214
+ // so a reused body sends the same form again (CMS-1071)
215
+ const fd = { ...field };
216
+ // If fileQuery does not exist, we create it and assign it to an object with the following properties:
217
+ if (!fd.fileQuery) {
218
+ const fileQuery = {
219
+ type: 'page',
220
+ entity: 'editor',
221
+ // Generate a random 4-digit ID
222
+ id: Number(Math.floor(Math.random() * 10000)
223
+ .toString()
224
+ .padStart(4, '0')),
225
+ };
226
+ fd.fileQuery = fileQuery;
227
+ }
228
+ // Convert fd.value to an array if it is a FileList, otherwise use it directly
229
+ const filesArray = typeof FileList !== 'undefined' && fd.value instanceof FileList
230
+ ? Array.from(fd.value)
231
+ : fd.value;
232
+ // If filesArray is an array, upload the files it holds asynchronously
233
+ if (Array.isArray(filesArray)) {
234
+ const uploadPromises = filesArray.map((file) =>
235
+ // An entry that is already in storage is passed through: a
236
+ // second upload would send the descriptor itself as the file
237
+ // and the endpoint answers `value[0].filename is required`.
238
+ this._isUploadable(file)
239
+ ? fileUploader.upload(file, fd.fileQuery).catch((e) => e)
240
+ : file);
241
+ fd.value = (await Promise.all(uploadPromises)).flat();
242
+ }
243
+ // If fd.value is a single File or Blob, upload it
244
+ else if (this._isUploadable(fd.value)) {
245
+ fd.value = await fileUploader
246
+ .upload(fd.value, fd.fileQuery)
247
+ .catch((e) => e); // Catch any errors during upload
248
+ }
249
+ // Remove the 'fileQuery' property from the object after processing
250
+ delete fd.fileQuery;
251
+ // Remove the 'contentType' property from the file object because it is not needed and not valid
252
+ fd.value = this._stripContentType(fd.value);
253
+ return fd;
254
+ }
255
+ // Return the form data element untouched
256
+ return field;
257
+ }));
258
+ }
259
+ // A failed upload used to be sent to the platform as the field's value, and the caller
260
+ // got a success: the form is not sent, the upload's error is the answer
261
+ const uploadError = formData[langCode]
262
+ .flatMap((field) => Array.isArray(field === null || field === void 0 ? void 0 : field.value) ? field.value : [field === null || field === void 0 ? void 0 : field.value])
263
+ .find((value) => this._isErrorResponse(value));
264
+ return { formData, uploadError };
265
+ }
253
266
  /**
254
267
  * Update one object of form data by id. Requires user authentication.
255
268
  * @handleName updateFormsDataByid
256
269
  * @param {number} id - Form data ID. Example: 1.
257
- * @param {object} [body] - Form data to save: the same fields as in `postFormsData` (`formIdentifier`, `formModuleConfigId`, `moduleEntityIdentifier`, `replayTo`, `status`, `formData`). Default: `{}`.
270
+ * @param {IBodyPostFormData} body - Form data to save: the same fields as in `postFormsData` (`formIdentifier`, `formModuleConfigId`, `moduleEntityIdentifier`, `replayTo`, `status`, `formData`). The flat `formData` array is wrapped under `langCode` before sending, exactly like `postFormsData`.
271
+ * @param {string} [langCode] - Language code the form fields are saved under. Default: "en_US".
258
272
  * @example
259
273
  {
260
274
  "formIdentifier": "test-form",
@@ -273,11 +287,21 @@ export default class FormsDataApi extends AsyncModules {
273
287
  * @returns {Promise<IUpdateFormsData | IError>} Returns an object containing the updated form data or an error object if there was an issue.
274
288
  * @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/updateFormsDataByid updateFormsDataByid} documentation.
275
289
  */
276
- async updateFormsDataByid(id, body = {}) {
277
- const result = await this._fetchPut(`/${this._pathSegment(String(id))}`, body);
290
+ async updateFormsDataByid(id, body, langCode = this.state.lang) {
291
+ // Wrap the flat formData under langCode (and upload any files) — the endpoint
292
+ // rejects a flat array with `400 formData must be ... keyed by lang code`
293
+ const { formData, uploadError } = await this._buildLocalizedFormData(body.formData, langCode);
294
+ if (uploadError) {
295
+ if (this.state.isShell) {
296
+ return uploadError;
297
+ }
298
+ throw uploadError;
299
+ }
300
+ const result = await this._fetchPut(`/${this._pathSegment(String(id))}`, { ...body, formData });
278
301
  // Validate response if validation is enabled
279
302
  const validated = await this._validateResponse(result, schema('UpdateFormsDataSchema'));
280
- return validated;
303
+ // The fields went in under `langCode`, so unwrap the response from the same locale
304
+ return this._normalizeData(validated, langCode);
281
305
  }
282
306
  /**
283
307
  * Update form data status by id. Requires user authentication.
@@ -86,12 +86,13 @@ export default class PagesApi extends AsyncModules implements IPagesApi {
86
86
  * @param {string} name - Text to search for in page titles (`localizeInfos.title`) in the requested language. Example: "About Us".
87
87
  * @param {string} [url] - Page URL. Example: "catalog".
88
88
  * @param {string} [langCode] - Language code. Default: "en_US".
89
+ * @param {boolean} [correct] - Correct typos by the project's search dictionary first. The API defaults to `true`; pass `false` to search the query as is.
89
90
  * @returns {Promise<IPagesEntity[] | IPageSearchResult[] | IError>} Returns found pages as an array of PageEntity objects, an array of short PageSearchResult cards when the traficLimit config option is enabled, or an empty array [] (if there is no data)
90
91
  * @throws {IError} When isShell=false and an error occurs during the fetch
91
92
  * @description Quick search for page objects with limited output. The quick search endpoint returns short cards ({ id, title }); with traficLimit enabled they are returned as is, otherwise full page entities are fetched for the found ids. The search runs in `langCode`, and a found page that cannot be loaded in that language is left out of the result.
92
93
  * @see {@link https://js-sdk.oneentry.cloud/docs/pages/searchPage searchPage} documentation.
93
94
  */
94
- searchPage(name: string, url?: string, langCode?: string): Promise<IPagesEntity[] | IPageSearchResult[] | IError>;
95
+ searchPage(name: string, url?: string, langCode?: string, correct?: boolean): Promise<IPagesEntity[] | IPageSearchResult[] | IError>;
95
96
  /**
96
97
  * Semantic (vector) search for pages.
97
98
  * @handleName getPagesByVectorSearch
@@ -185,15 +185,17 @@ export default class PagesApi extends AsyncModules {
185
185
  * @param {string} name - Text to search for in page titles (`localizeInfos.title`) in the requested language. Example: "About Us".
186
186
  * @param {string} [url] - Page URL. Example: "catalog".
187
187
  * @param {string} [langCode] - Language code. Default: "en_US".
188
+ * @param {boolean} [correct] - Correct typos by the project's search dictionary first. The API defaults to `true`; pass `false` to search the query as is.
188
189
  * @returns {Promise<IPagesEntity[] | IPageSearchResult[] | IError>} Returns found pages as an array of PageEntity objects, an array of short PageSearchResult cards when the traficLimit config option is enabled, or an empty array [] (if there is no data)
189
190
  * @throws {IError} When isShell=false and an error occurs during the fetch
190
191
  * @description Quick search for page objects with limited output. The quick search endpoint returns short cards ({ id, title }); with traficLimit enabled they are returned as is, otherwise full page entities are fetched for the found ids. The search runs in `langCode`, and a found page that cannot be loaded in that language is left out of the result.
191
192
  * @see {@link https://js-sdk.oneentry.cloud/docs/pages/searchPage searchPage} documentation.
192
193
  */
193
- async searchPage(name, url, langCode = this.state.lang) {
194
+ async searchPage(name, url, langCode = this.state.lang, correct) {
194
195
  // Fetch data from the server using a GET request to perform a quick search by page name and language code
195
196
  const urlPart = url ? `url=${encodeURIComponent(url)}&` : '';
196
- const searchPages = await this._fetchGet(`/quick/search?${urlPart}langCode=${encodeURIComponent(langCode)}&name=${encodeURIComponent(name)}`);
197
+ const correctPart = correct !== undefined ? `&correct=${correct}` : '';
198
+ const searchPages = await this._fetchGet(`/quick/search?${urlPart}langCode=${encodeURIComponent(langCode)}&name=${encodeURIComponent(name)}${correctPart}`);
197
199
  // Validate response if validation is enabled
198
200
  const data = (await this._validateResponse(searchPages, schema('PageSearchResponseSchema')));
199
201
  // Check if there is no traffic limit set in the state
@@ -72,11 +72,12 @@ interface IPagesApi {
72
72
  * @param {string} name - Text to search for in page titles (`localizeInfos.title`) in the requested language. Example: "About Us".
73
73
  * @param {string} [url] - Optional page URL to filter search results. Example: "catalog".
74
74
  * @param {string} [langCode] - Language code. Default: "en_US".
75
+ * @param {boolean} [correct] - Correct typos by the project's search dictionary first. The API defaults to `true`; pass `false` to search the query as is.
75
76
  * @returns {IPagesEntity[] | IPageSearchResult[]} Returns found pages as an array of PageEntity objects, an array of short PageSearchResult cards when the traficLimit config option is enabled, or an empty array [] (if there is no data)
76
77
  * @throws {IError} - If there is an error during the fetch operation, it will return an error object.
77
78
  * @description This method performs a quick search for page objects with limited output. With traficLimit enabled the raw quick search response is returned as short cards; otherwise full page entities are fetched for the found ids.
78
79
  */
79
- searchPage(name: string, url?: string, langCode?: LangType): Promise<IPagesEntity[] | IPageSearchResult[] | IError>;
80
+ searchPage(name: string, url?: string, langCode?: LangType, correct?: boolean): Promise<IPagesEntity[] | IPageSearchResult[] | IError>;
80
81
  /**
81
82
  * Semantic (vector) search for pages.
82
83
  * @handleName getPagesByVectorSearch
@@ -247,12 +247,13 @@ export default class ProductsApi extends AsyncModules implements IProductsApi {
247
247
  * @param {number} id - Product ID. Example: 12345.
248
248
  * @param {string} [langCode] - Language code. Default: "en_US".
249
249
  * @param {boolean} [isNormalized] - Deprecated: the API no longer reads it, the answer is the same with `true`, `false` or without it. Kept for compatibility.
250
+ * @param {string} [signPrice] - Marker of an orders storage to fix the price for. When set, the product comes with a `signedPrice` holding the price for a limited time; an unknown marker fails the request with `404 Specified orders storage for price signature not found`.
250
251
  * @returns {Promise<IProductsEntity | IError>} ProductEntity object.
251
252
  * @throws {IError} When isShell=false and an error occurs during the fetch
252
253
  * @description Retrieve one product object. A product with no translation in `langCode` answers `404 Product not found` — there is no fallback to another language.
253
254
  * @see {@link https://js-sdk.oneentry.cloud/docs/products/getProductById getProductById} documentation.
254
255
  */
255
- getProductById(id: number, langCode?: string, isNormalized?: boolean): Promise<IProductsEntity | IError>;
256
+ getProductById(id: number, langCode?: string, isNormalized?: boolean, signPrice?: string): Promise<IProductsEntity | IError>;
256
257
  /**
257
258
  * Getting a product block object by product id.
258
259
  * @handleName getProductBlockById
@@ -269,16 +270,19 @@ export default class ProductsApi extends AsyncModules implements IProductsApi {
269
270
  * @handleName searchProduct
270
271
  * @param {string} name - Text to search for in product titles (`localizeInfos.title`) in the requested language. Example: "laminat".
271
272
  * @param {string} [langCode] - Language code. Default: "en_US".
273
+ * @param {string} [url] - URL of a catalog page to search within that category. Default: the whole catalog.
274
+ * @param {boolean} [correct] - Correct typos by the project's search dictionary first. The API defaults to `true`; pass `false` to search the query as is.
272
275
  * @returns {Promise<IProductsEntity[] | IProductSearchResult[] | IError>} Array with ProductEntity objects, or an array with short ProductSearchResult cards when the traficLimit config option is enabled
273
276
  * @throws {IError} When isShell=false and an error occurs during the fetch
274
277
  * @description Quick search for product page objects with limited output. The quick search endpoint returns short cards ({ id, title, pageId }); with traficLimit enabled they are returned as is, otherwise full product entities are fetched for the found ids.
275
278
  * @see {@link https://js-sdk.oneentry.cloud/docs/products/searchProduct searchProduct} documentation.
276
279
  */
277
- searchProduct(name: string, langCode?: string): Promise<IProductsEntity[] | IProductSearchResult[] | IError>;
280
+ searchProduct(name: string, langCode?: string, url?: string, correct?: boolean): Promise<IProductsEntity[] | IProductSearchResult[] | IError>;
278
281
  /**
279
282
  * Getting the number of products for the entire catalog.
280
283
  * @handleName getProductsCount
281
284
  * @param {any[]} [body] - Filter objects with search conditions. Default: `[]`.
285
+ * @param {string} [langCode] - Language code. Default: "en_US". Must be one of the project's active languages — an inactive one answers `400 langCode must be one of the active languages`. The count reflects the products visible in that language.
282
286
  * @example
283
287
  [
284
288
  {
@@ -289,15 +293,16 @@ export default class ProductsApi extends AsyncModules implements IProductsApi {
289
293
  ]
290
294
  * @returns {Promise<IProductsCount | IError>} Object with product items count.
291
295
  * @throws {IError} When isShell=false and an error occurs during the fetch
292
- * @description This method calculates and returns the total number of products present across the entire catalog, optionally applying specified filters.
296
+ * @description This method calculates and returns the total number of products present across the entire catalog, optionally applying specified filters. The request carries `langCode`; it must be an active language of the project, otherwise the API answers `400`.
293
297
  * @see {@link https://js-sdk.oneentry.cloud/docs/products/getProductsCount getProductsCount} documentation.
294
298
  */
295
- getProductsCount(body?: any[]): Promise<IProductsCount | IError>;
299
+ getProductsCount(body?: any[], langCode?: string): Promise<IProductsCount | IError>;
296
300
  /**
297
301
  * Getting the number of products on a catalog page by page ID.
298
302
  * @handleName getProductsCountByPageId
299
303
  * @param {number | string} id - Page ID. Example: 12345.
300
304
  * @param {any[]} [body] - Filter objects with search conditions. Default: `[]`.
305
+ * @param {string} [langCode] - Language code. Default: "en_US". Must be one of the project's active languages — an inactive one answers `400 langCode must be one of the active languages`. The count reflects the products visible in that language.
301
306
  * @example
302
307
  [
303
308
  {
@@ -308,10 +313,10 @@ export default class ProductsApi extends AsyncModules implements IProductsApi {
308
313
  ]
309
314
  * @returns {Promise<IProductsCount | IError>} Object with product items count.
310
315
  * @throws {IError} When isShell=false and an error occurs during the fetch
311
- * @description This method calculates and returns the number of products available on a given catalog page, identified by its page ID, with optional filtering. The counts do not depend on the language: on a language where the catalog is empty they still count every product (CMS-1201).
316
+ * @description This method calculates and returns the number of products available on a given catalog page, identified by its page ID, with optional filtering. The request carries `langCode`; it must be an active language of the project (an inactive one answers `400`), and the count reflects the products visible in that language.
312
317
  * @see {@link https://js-sdk.oneentry.cloud/docs/products/getProductsCountByPageId getProductsCountByPageId} documentation.
313
318
  */
314
- getProductsCountByPageId(id: number | string, body?: any[]): Promise<IProductsCount | IError>;
319
+ getProductsCountByPageId(id: number | string, body?: any[], langCode?: string): Promise<IProductsCount | IError>;
315
320
  /**
316
321
  * Semantic (vector) search for products.
317
322
  * @handleName getProductsByVectorSearch
@@ -330,6 +335,7 @@ export default class ProductsApi extends AsyncModules implements IProductsApi {
330
335
  * @handleName getProductsCountByPageUrl
331
336
  * @param {string} url - Page URL. Example: "catalog".
332
337
  * @param {any[]} [body] - Filter objects with search conditions. Default: `[]`.
338
+ * @param {string} [langCode] - Language code. Default: "en_US". Must be one of the project's active languages — an inactive one answers `400 langCode must be one of the active languages`. The count reflects the products visible in that language.
333
339
  * @example
334
340
  [
335
341
  {
@@ -340,8 +346,8 @@ export default class ProductsApi extends AsyncModules implements IProductsApi {
340
346
  ]
341
347
  * @returns {Promise<IProductsCount | IError>} Object with product items count.
342
348
  * @throws {IError} When isShell=false and an error occurs during the fetch
343
- * @description This method calculates and returns the number of products available on a given catalog page, identified by its URL, with optional filtering. The counts do not depend on the language: on a language where the catalog is empty they still count every product (CMS-1201).
349
+ * @description This method calculates and returns the number of products available on a given catalog page, identified by its URL, with optional filtering. The request carries `langCode`; it must be an active language of the project (an inactive one answers `400`), and the count reflects the products visible in that language.
344
350
  * @see {@link https://js-sdk.oneentry.cloud/docs/products/getProductsCountByPageUrl getProductsCountByPageUrl} documentation.
345
351
  */
346
- getProductsCountByPageUrl(url: string, body?: any[]): Promise<IProductsCount | IError>;
352
+ getProductsCountByPageUrl(url: string, body?: any[], langCode?: string): Promise<IProductsCount | IError>;
347
353
  }
@@ -301,15 +301,18 @@ export default class ProductsApi extends AsyncModules {
301
301
  * @param {number} id - Product ID. Example: 12345.
302
302
  * @param {string} [langCode] - Language code. Default: "en_US".
303
303
  * @param {boolean} [isNormalized] - Deprecated: the API no longer reads it, the answer is the same with `true`, `false` or without it. Kept for compatibility.
304
+ * @param {string} [signPrice] - Marker of an orders storage to fix the price for. When set, the product comes with a `signedPrice` holding the price for a limited time; an unknown marker fails the request with `404 Specified orders storage for price signature not found`.
304
305
  * @returns {Promise<IProductsEntity | IError>} ProductEntity object.
305
306
  * @throws {IError} When isShell=false and an error occurs during the fetch
306
307
  * @description Retrieve one product object. A product with no translation in `langCode` answers `404 Product not found` — there is no fallback to another language.
307
308
  * @see {@link https://js-sdk.oneentry.cloud/docs/products/getProductById getProductById} documentation.
308
309
  */
309
- async getProductById(id, langCode = this.state.lang, isNormalized) {
310
+ async getProductById(id, langCode = this.state.lang, isNormalized, signPrice) {
310
311
  const query = { langCode };
311
312
  if (isNormalized !== undefined)
312
313
  query.isNormalized = isNormalized;
314
+ if (signPrice !== undefined)
315
+ query.signPrice = signPrice;
313
316
  const result = await this._fetchGet(`/${this._pathSegment(String(id))}?` + this._queryParamsToString(query));
314
317
  // Validate response if validation is enabled
315
318
  const validated = await this._validateResponse(result, schema('ProductEntitySchema'));
@@ -337,13 +340,17 @@ export default class ProductsApi extends AsyncModules {
337
340
  * @handleName searchProduct
338
341
  * @param {string} name - Text to search for in product titles (`localizeInfos.title`) in the requested language. Example: "laminat".
339
342
  * @param {string} [langCode] - Language code. Default: "en_US".
343
+ * @param {string} [url] - URL of a catalog page to search within that category. Default: the whole catalog.
344
+ * @param {boolean} [correct] - Correct typos by the project's search dictionary first. The API defaults to `true`; pass `false` to search the query as is.
340
345
  * @returns {Promise<IProductsEntity[] | IProductSearchResult[] | IError>} Array with ProductEntity objects, or an array with short ProductSearchResult cards when the traficLimit config option is enabled
341
346
  * @throws {IError} When isShell=false and an error occurs during the fetch
342
347
  * @description Quick search for product page objects with limited output. The quick search endpoint returns short cards ({ id, title, pageId }); with traficLimit enabled they are returned as is, otherwise full product entities are fetched for the found ids.
343
348
  * @see {@link https://js-sdk.oneentry.cloud/docs/products/searchProduct searchProduct} documentation.
344
349
  */
345
- async searchProduct(name, langCode = this.state.lang) {
346
- const result = await this._fetchGet(`/quick/search?langCode=${encodeURIComponent(langCode)}&name=${encodeURIComponent(name)}`);
350
+ async searchProduct(name, langCode = this.state.lang, url, correct) {
351
+ const extra = (url ? `&url=${encodeURIComponent(url)}` : '') +
352
+ (correct !== undefined ? `&correct=${correct}` : '');
353
+ const result = await this._fetchGet(`/quick/search?langCode=${encodeURIComponent(langCode)}&name=${encodeURIComponent(name)}${extra}`);
347
354
  // Validate response if validation is enabled
348
355
  const searchProducts = (await this._validateResponse(result, schema('ProductSearchResponseSchema')));
349
356
  if (!this.state.traficLimit && Array.isArray(searchProducts)) {
@@ -367,6 +374,7 @@ export default class ProductsApi extends AsyncModules {
367
374
  * Getting the number of products for the entire catalog.
368
375
  * @handleName getProductsCount
369
376
  * @param {any[]} [body] - Filter objects with search conditions. Default: `[]`.
377
+ * @param {string} [langCode] - Language code. Default: "en_US". Must be one of the project's active languages — an inactive one answers `400 langCode must be one of the active languages`. The count reflects the products visible in that language.
370
378
  * @example
371
379
  [
372
380
  {
@@ -377,13 +385,13 @@ export default class ProductsApi extends AsyncModules {
377
385
  ]
378
386
  * @returns {Promise<IProductsCount | IError>} Object with product items count.
379
387
  * @throws {IError} When isShell=false and an error occurs during the fetch
380
- * @description This method calculates and returns the total number of products present across the entire catalog, optionally applying specified filters.
388
+ * @description This method calculates and returns the total number of products present across the entire catalog, optionally applying specified filters. The request carries `langCode`; it must be an active language of the project, otherwise the API answers `400`.
381
389
  * @see {@link https://js-sdk.oneentry.cloud/docs/products/getProductsCount getProductsCount} documentation.
382
390
  */
383
391
  async getProductsCount(
384
392
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
385
- body = []) {
386
- const result = await this._fetchPost(`/all/counts`, body);
393
+ body = [], langCode = this.state.lang) {
394
+ const result = await this._fetchPost(`/all/counts?` + this._queryParamsToString({ langCode }), body);
387
395
  return result;
388
396
  }
389
397
  /**
@@ -391,6 +399,7 @@ export default class ProductsApi extends AsyncModules {
391
399
  * @handleName getProductsCountByPageId
392
400
  * @param {number | string} id - Page ID. Example: 12345.
393
401
  * @param {any[]} [body] - Filter objects with search conditions. Default: `[]`.
402
+ * @param {string} [langCode] - Language code. Default: "en_US". Must be one of the project's active languages — an inactive one answers `400 langCode must be one of the active languages`. The count reflects the products visible in that language.
394
403
  * @example
395
404
  [
396
405
  {
@@ -401,13 +410,14 @@ export default class ProductsApi extends AsyncModules {
401
410
  ]
402
411
  * @returns {Promise<IProductsCount | IError>} Object with product items count.
403
412
  * @throws {IError} When isShell=false and an error occurs during the fetch
404
- * @description This method calculates and returns the number of products available on a given catalog page, identified by its page ID, with optional filtering. The counts do not depend on the language: on a language where the catalog is empty they still count every product (CMS-1201).
413
+ * @description This method calculates and returns the number of products available on a given catalog page, identified by its page ID, with optional filtering. The request carries `langCode`; it must be an active language of the project (an inactive one answers `400`), and the count reflects the products visible in that language.
405
414
  * @see {@link https://js-sdk.oneentry.cloud/docs/products/getProductsCountByPageId getProductsCountByPageId} documentation.
406
415
  */
407
416
  async getProductsCountByPageId(id,
408
417
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
409
- body = []) {
410
- const result = await this._fetchPost(`/page/${this._pathSegment(String(id))}/counts`, body);
418
+ body = [], langCode = this.state.lang) {
419
+ const result = await this._fetchPost(`/page/${this._pathSegment(String(id))}/counts?` +
420
+ this._queryParamsToString({ langCode }), body);
411
421
  return result;
412
422
  }
413
423
  /**
@@ -436,6 +446,7 @@ export default class ProductsApi extends AsyncModules {
436
446
  * @handleName getProductsCountByPageUrl
437
447
  * @param {string} url - Page URL. Example: "catalog".
438
448
  * @param {any[]} [body] - Filter objects with search conditions. Default: `[]`.
449
+ * @param {string} [langCode] - Language code. Default: "en_US". Must be one of the project's active languages — an inactive one answers `400 langCode must be one of the active languages`. The count reflects the products visible in that language.
439
450
  * @example
440
451
  [
441
452
  {
@@ -446,13 +457,14 @@ export default class ProductsApi extends AsyncModules {
446
457
  ]
447
458
  * @returns {Promise<IProductsCount | IError>} Object with product items count.
448
459
  * @throws {IError} When isShell=false and an error occurs during the fetch
449
- * @description This method calculates and returns the number of products available on a given catalog page, identified by its URL, with optional filtering. The counts do not depend on the language: on a language where the catalog is empty they still count every product (CMS-1201).
460
+ * @description This method calculates and returns the number of products available on a given catalog page, identified by its URL, with optional filtering. The request carries `langCode`; it must be an active language of the project (an inactive one answers `400`), and the count reflects the products visible in that language.
450
461
  * @see {@link https://js-sdk.oneentry.cloud/docs/products/getProductsCountByPageUrl getProductsCountByPageUrl} documentation.
451
462
  */
452
463
  async getProductsCountByPageUrl(url,
453
464
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
454
- body = []) {
455
- const result = await this._fetchPost(`/page/url/${this._pathSegments(url)}/counts`, body);
465
+ body = [], langCode = this.state.lang) {
466
+ const result = await this._fetchPost(`/page/url/${this._pathSegments(url)}/counts?` +
467
+ this._queryParamsToString({ langCode }), body);
456
468
  return result;
457
469
  }
458
470
  }
@@ -170,11 +170,12 @@ interface IProductsApi {
170
170
  * @param {number} id - Product ID. Example: 12345.
171
171
  * @param {string} [langCode] - Language code. Default: "en_US".
172
172
  * @param {boolean} [isNormalized] - Deprecated: the API no longer reads it, the answer is the same with `true`, `false` or without it. Kept for compatibility.
173
+ * @param {string} [signPrice] - Marker of an orders storage to fix the price for; the product then carries a `signedPrice`. An unknown marker answers `404`.
173
174
  * @returns {IProductsEntity} ProductEntity object.
174
175
  * @throws {IError} If there is an error during the fetch operation, it will return an error object.
175
176
  * @description This method retrieves one product object.
176
177
  */
177
- getProductById(id: number, langCode?: string, isNormalized?: boolean): Promise<IProductsEntity | IError>;
178
+ getProductById(id: number, langCode?: string, isNormalized?: boolean, signPrice?: string): Promise<IProductsEntity | IError>;
178
179
  /**
179
180
  * Getting a product block object by product id.
180
181
  * @handleName getProductBlockById
@@ -190,11 +191,13 @@ interface IProductsApi {
190
191
  * @handleName searchProduct
191
192
  * @param {string} name - Text to search for in product titles (`localizeInfos.title`) in the requested language. Example: 'laminat'.
192
193
  * @param {string} [langCode] - Language code. Default: "en_US".
194
+ * @param {string} [url] - URL of a catalog page to search within that category. Default: the whole catalog.
195
+ * @param {boolean} [correct] - Correct typos by the project's search dictionary first. The API defaults to `true`; pass `false` to search the query as is.
193
196
  * @returns {IProductsEntity[] | IProductSearchResult[]} Array with ProductEntity objects, or an array with short ProductSearchResult cards when the traficLimit config option is enabled
194
197
  * @throws {IError} - If there is an error during the fetch operation, it will return an error object.
195
198
  * @description This method performs a quick search for product page objects with limited output. With traficLimit enabled the raw quick search response is returned as short cards; otherwise full product entities are fetched for the found ids.
196
199
  */
197
- searchProduct(name: string, langCode?: string): Promise<IProductsEntity[] | IProductSearchResult[] | IError>;
200
+ searchProduct(name: string, langCode?: string, url?: string, correct?: boolean): Promise<IProductsEntity[] | IProductSearchResult[] | IError>;
198
201
  /**
199
202
  * Getting the number of products for the entire catalog.
200
203
  * @handleName getProductsCount
@@ -209,9 +212,10 @@ interface IProductsApi {
209
212
  ]
210
213
  * @returns {IProductsCount} Object with product items count.
211
214
  * @throws {IError} - If there is an error during the fetch operation, it will return an error object.
215
+ * @param {string} [langCode] - Language code. Default: "en_US". Must be an active language of the project — an inactive one answers `400`; the count reflects products visible in that language.
212
216
  * @description This method calculates and returns the total number of products present across the entire catalog, optionally applying specified filters.
213
217
  */
214
- getProductsCount(body?: object[]): Promise<IProductsCount | IError>;
218
+ getProductsCount(body?: object[], langCode?: string): Promise<IProductsCount | IError>;
215
219
  /**
216
220
  * Getting the number of products on a catalog page by page ID.
217
221
  * @handleName getProductsCountByPageId
@@ -227,9 +231,10 @@ interface IProductsApi {
227
231
  ]
228
232
  * @returns {IProductsCount} Object with product items count.
229
233
  * @throws {IError} - If there is an error during the fetch operation, it will return an error object.
234
+ * @param {string} [langCode] - Language code. Default: "en_US". Must be an active language of the project — an inactive one answers `400`; the count reflects products visible in that language.
230
235
  * @description This method calculates and returns the number of products available on a given catalog page, identified by its page ID, with optional filtering.
231
236
  */
232
- getProductsCountByPageId(id: number | string, body?: object[]): Promise<IProductsCount | IError>;
237
+ getProductsCountByPageId(id: number | string, body?: object[], langCode?: string): Promise<IProductsCount | IError>;
233
238
  /**
234
239
  * Getting the number of products on a catalog page by page URL.
235
240
  * @handleName getProductsCountByPageUrl
@@ -245,9 +250,10 @@ interface IProductsApi {
245
250
  ]
246
251
  * @returns {IProductsCount} Object with product items count.
247
252
  * @throws {IError} - If there is an error during the fetch operation, it will return an error object.
253
+ * @param {string} [langCode] - Language code. Default: "en_US". Must be an active language of the project — an inactive one answers `400`; the count reflects products visible in that language.
248
254
  * @description This method calculates and returns the number of products available on a given catalog page, identified by its URL, with optional filtering.
249
255
  */
250
- getProductsCountByPageUrl(url: string, body?: object[]): Promise<IProductsCount | IError>;
256
+ getProductsCountByPageUrl(url: string, body?: object[], langCode?: string): Promise<IProductsCount | IError>;
251
257
  /**
252
258
  * Semantic (vector) search for products.
253
259
  * @handleName getProductsByVectorSearch
@@ -27,10 +27,11 @@ export default class SearchApi extends AsyncModules implements ISearchApi {
27
27
  * @param {number} [offset] - Offset for drilldown mode. Pass it only together with exactly one accessible type in `types`.
28
28
  * @param {number} [limit] - Page size for drilldown mode. Pass it only together with exactly one accessible type in `types`; otherwise the API responds with `400 Drilldown mode (limit/offset) requires exactly one accessible type in types`. Without it, every group is returned in full.
29
29
  * @param {string} [langCode] - Language code. Default: "en_US". The search index is built per language: words in another locale are found only when you pass that locale's `langCode`.
30
+ * @param {number} [limitPerType] - Dropdown mode: maximum items per type group (API default 5, max 20). Independent from `limit`/`offset`, which page a single type in drilldown mode.
30
31
  * @returns {Promise<IGlobalSearchResponse | IError>} Returns the query and the found records grouped by entity type.
31
32
  * @throws {IError} When isShell=false and an error occurs during the fetch
32
33
  * @description Searches names and attribute values of visible records across entity types. The index is per language — the request carries `langCode`, so a bilingual project finds a word of either locale.
33
34
  * @see {@link https://js-sdk.oneentry.cloud/docs/search/globalSearch globalSearch} documentation.
34
35
  */
35
- globalSearch(query: string, types?: TGlobalSearchEntityType[], visibility?: 'all' | 'visible' | 'hidden', offset?: number, limit?: number, langCode?: string): Promise<IGlobalSearchResponse | IError>;
36
+ globalSearch(query: string, types?: TGlobalSearchEntityType[], visibility?: 'all' | 'visible' | 'hidden', offset?: number, limit?: number, langCode?: string, limitPerType?: number): Promise<IGlobalSearchResponse | IError>;
36
37
  }
@@ -27,12 +27,13 @@ export default class SearchApi extends AsyncModules {
27
27
  * @param {number} [offset] - Offset for drilldown mode. Pass it only together with exactly one accessible type in `types`.
28
28
  * @param {number} [limit] - Page size for drilldown mode. Pass it only together with exactly one accessible type in `types`; otherwise the API responds with `400 Drilldown mode (limit/offset) requires exactly one accessible type in types`. Without it, every group is returned in full.
29
29
  * @param {string} [langCode] - Language code. Default: "en_US". The search index is built per language: words in another locale are found only when you pass that locale's `langCode`.
30
+ * @param {number} [limitPerType] - Dropdown mode: maximum items per type group (API default 5, max 20). Independent from `limit`/`offset`, which page a single type in drilldown mode.
30
31
  * @returns {Promise<IGlobalSearchResponse | IError>} Returns the query and the found records grouped by entity type.
31
32
  * @throws {IError} When isShell=false and an error occurs during the fetch
32
33
  * @description Searches names and attribute values of visible records across entity types. The index is per language — the request carries `langCode`, so a bilingual project finds a word of either locale.
33
34
  * @see {@link https://js-sdk.oneentry.cloud/docs/search/globalSearch globalSearch} documentation.
34
35
  */
35
- async globalSearch(query, types, visibility, offset, limit, langCode = this.state.lang) {
36
+ async globalSearch(query, types, visibility, offset, limit, langCode = this.state.lang, limitPerType) {
36
37
  // `types` is sent comma-separated — the array stringifies to exactly that.
37
38
  // `langCode` is not optional decoration: the index is per language, and
38
39
  // without it a word of a second locale answers an empty group (CMS-912).
@@ -43,6 +44,7 @@ export default class SearchApi extends AsyncModules {
43
44
  visibility,
44
45
  offset,
45
46
  limit,
47
+ limitPerType,
46
48
  langCode,
47
49
  };
48
50
  const data = await this._fetchGet(`?` + this._queryParamsToString(params));
@@ -14,11 +14,12 @@ interface ISearchApi {
14
14
  * @param {number} [offset] - Offset for drilldown mode. Pass it only together with exactly one accessible type in `types`.
15
15
  * @param {number} [limit] - Page size for drilldown mode. Pass it only together with exactly one accessible type in `types`; otherwise the API responds with `400 Drilldown mode (limit/offset) requires exactly one accessible type in types`. Without it, every group is returned in full.
16
16
  * @param {string} [langCode] - Language code. Default: "en_US". The search index is built per language: words in another locale are found only when you pass that locale's `langCode`.
17
+ * @param {number} [limitPerType] - Dropdown mode: maximum items per type group (API default 5, max 20). Independent from `limit`/`offset`, which page a single type in drilldown mode.
17
18
  * @returns {Promise<IGlobalSearchResponse | IError>} Returns the query and the found records grouped by entity type.
18
19
  * @throws {IError} When isShell=false and an error occurs during the fetch
19
20
  * @description Searches names and attribute values of visible records across entity types. The index is per language — the request carries `langCode`, so a bilingual project finds a word of either locale.
20
21
  */
21
- globalSearch(query: string, types?: TGlobalSearchEntityType[], visibility?: 'all' | 'visible' | 'hidden', offset?: number, limit?: number, langCode?: string): Promise<IGlobalSearchResponse | IError>;
22
+ globalSearch(query: string, types?: TGlobalSearchEntityType[], visibility?: 'all' | 'visible' | 'hidden', offset?: number, limit?: number, langCode?: string, limitPerType?: number): Promise<IGlobalSearchResponse | IError>;
22
23
  }
23
24
  /**
24
25
  * Entity type a global search group or item belongs to.