oneentry 1.0.174 → 1.0.176

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.
Files changed (60) hide show
  1. package/changelog.md +36 -0
  2. package/dist/attribute-sets/attributeSetsApi.js +3 -3
  3. package/dist/auth-provider/authProviderApi.d.ts +1 -1
  4. package/dist/auth-provider/authProviderApi.js +13 -13
  5. package/dist/auth-provider/authProviderSchemas.d.ts +1 -1
  6. package/dist/auth-provider/authProvidersInterfaces.d.ts +3 -2
  7. package/dist/base/asyncModules.d.ts +11 -0
  8. package/dist/base/asyncModules.js +14 -0
  9. package/dist/base/validation.d.ts +1 -1
  10. package/dist/base/validation.js +1 -1
  11. package/dist/blocks/blocksApi.js +24 -15
  12. package/dist/discounts/discountsApi.js +2 -1
  13. package/dist/events/eventsApi.js +4 -4
  14. package/dist/filters/filtersApi.js +1 -1
  15. package/dist/forms/formsApi.js +1 -1
  16. package/dist/forms-data/formsDataApi.d.ts +10 -8
  17. package/dist/forms-data/formsDataApi.js +14 -10
  18. package/dist/forms-data/formsDataInterfaces.d.ts +75 -54
  19. package/dist/integration-collections/integrationCollectionsApi.js +7 -6
  20. package/dist/menus/menusApi.js +1 -1
  21. package/dist/orders/ordersApi.js +7 -6
  22. package/dist/pages/pagesApi.js +2 -2
  23. package/dist/product-statuses/productStatusesApi.js +2 -2
  24. package/dist/templates/templatesApi.js +1 -1
  25. package/dist/templates-preview/templatesPreviewApi.js +1 -1
  26. package/dist/user-groups/userGroupsApi.js +2 -2
  27. package/dist/users/usersApi.d.ts +2 -2
  28. package/dist/users/usersApi.js +2 -2
  29. package/dist/users/usersInterfaces.d.ts +8 -7
  30. package/dist/users/usersSchemas.d.ts +1 -1
  31. package/esm/attribute-sets/attributeSetsApi.js +3 -3
  32. package/esm/auth-provider/authProviderApi.d.ts +1 -1
  33. package/esm/auth-provider/authProviderApi.js +13 -13
  34. package/esm/auth-provider/authProviderSchemas.d.ts +1 -1
  35. package/esm/auth-provider/authProvidersInterfaces.d.ts +3 -2
  36. package/esm/base/asyncModules.d.ts +11 -0
  37. package/esm/base/asyncModules.js +14 -0
  38. package/esm/base/validation.d.ts +1 -1
  39. package/esm/base/validation.js +1 -1
  40. package/esm/blocks/blocksApi.js +24 -15
  41. package/esm/discounts/discountsApi.js +2 -1
  42. package/esm/events/eventsApi.js +4 -4
  43. package/esm/filters/filtersApi.js +1 -1
  44. package/esm/forms/formsApi.js +1 -1
  45. package/esm/forms-data/formsDataApi.d.ts +10 -8
  46. package/esm/forms-data/formsDataApi.js +14 -10
  47. package/esm/forms-data/formsDataInterfaces.d.ts +75 -54
  48. package/esm/integration-collections/integrationCollectionsApi.js +7 -6
  49. package/esm/menus/menusApi.js +1 -1
  50. package/esm/orders/ordersApi.js +7 -6
  51. package/esm/pages/pagesApi.js +2 -2
  52. package/esm/product-statuses/productStatusesApi.js +2 -2
  53. package/esm/templates/templatesApi.js +1 -1
  54. package/esm/templates-preview/templatesPreviewApi.js +1 -1
  55. package/esm/user-groups/userGroupsApi.js +2 -2
  56. package/esm/users/usersApi.d.ts +2 -2
  57. package/esm/users/usersApi.js +2 -2
  58. package/esm/users/usersInterfaces.d.ts +8 -7
  59. package/esm/users/usersSchemas.d.ts +1 -1
  60. package/package.json +2 -2
@@ -62,7 +62,7 @@ export default class AuthProviderApi extends AsyncModules {
62
62
  "value": "12345"
63
63
  }
64
64
  ]
65
- * @param {IAuthFormData} body.formData - The form data for the registration, which can be a single object or an array of objects.
65
+ * @param {FormDataType | FormDataType[]} body.formData - Registration form fields: one object or an array. Field values: {@link FormDataType} — a value shaped by the field type (a string, a date object, a text object, a list, a file descriptor), not only a string. A file goes in as the descriptor `FileUploading.upload` returns: these methods do not upload a `File`/`Blob` themselves.
66
66
  * @example
67
67
  {
68
68
  "marker": "last_name",
@@ -88,7 +88,7 @@ export default class AuthProviderApi extends AsyncModules {
88
88
  async signUp(marker, body, langCode = this.state.lang) {
89
89
  // `langCode` goes onto our own copy — the caller's body stays as it was
90
90
  // given, so a retry or a second parallel call sends the same thing (CMS-909).
91
- const result = await this._fetchPost(`/marker/${marker}/users/sign-up`, this._normalizePostBody({ ...body, langCode }, langCode));
91
+ const result = await this._fetchPost(`/marker/${this._pathSegment(marker)}/users/sign-up`, this._normalizePostBody({ ...body, langCode }, langCode));
92
92
  // Validate response if validation is enabled
93
93
  const validated = await this._validateResponse(result, schema('SignUpResponseSchema'));
94
94
  return this._normalizeData(validated);
@@ -109,7 +109,7 @@ export default class AuthProviderApi extends AsyncModules {
109
109
  userIdentifier,
110
110
  eventIdentifier,
111
111
  };
112
- const result = await this._fetchPost(`/marker/${marker}/users/generate-code`, data);
112
+ const result = await this._fetchPost(`/marker/${this._pathSegment(marker)}/users/generate-code`, data);
113
113
  return result;
114
114
  }
115
115
  /**
@@ -130,7 +130,7 @@ export default class AuthProviderApi extends AsyncModules {
130
130
  eventIdentifier,
131
131
  code,
132
132
  };
133
- const result = await this._fetchPost(`/marker/${marker}/users/check-code`, data);
133
+ const result = await this._fetchPost(`/marker/${this._pathSegment(marker)}/users/check-code`, data);
134
134
  return result;
135
135
  }
136
136
  /**
@@ -149,7 +149,7 @@ export default class AuthProviderApi extends AsyncModules {
149
149
  userIdentifier: userIdentifier,
150
150
  code: code,
151
151
  };
152
- const result = await this._fetchPost(`/marker/${marker}/users/activate`, data);
152
+ const result = await this._fetchPost(`/marker/${this._pathSegment(marker)}/users/activate`, data);
153
153
  return result;
154
154
  }
155
155
  /**
@@ -186,7 +186,7 @@ export default class AuthProviderApi extends AsyncModules {
186
186
  * @see {@link https://js-sdk.oneentry.cloud/docs/auth-provider/auth auth} documentation.
187
187
  */
188
188
  async auth(marker, body) {
189
- const result = await this._fetchPost(`/marker/${marker}/users/auth`, body);
189
+ const result = await this._fetchPost(`/marker/${this._pathSegment(marker)}/users/auth`, body);
190
190
  // Validate response if validation is enabled
191
191
  const validated = await this._validateResponse(result, schema('AuthResponseSchema'));
192
192
  if (!('statusCode' in validated)) {
@@ -210,7 +210,7 @@ export default class AuthProviderApi extends AsyncModules {
210
210
  */
211
211
  async refresh(marker, token) {
212
212
  const data = { refreshToken: token };
213
- const result = await this._fetchPost(`/marker/${marker}/users/refresh`, data);
213
+ const result = await this._fetchPost(`/marker/${this._pathSegment(marker)}/users/refresh`, data);
214
214
  if (!('statusCode' in result)) {
215
215
  this.state.accessToken = result.accessToken;
216
216
  this.state.refreshToken = result.refreshToken;
@@ -235,7 +235,7 @@ export default class AuthProviderApi extends AsyncModules {
235
235
  const data = {
236
236
  refreshToken: token,
237
237
  };
238
- const result = await this._fetchPost(`/marker/${marker}/users/logout`, data);
238
+ const result = await this._fetchPost(`/marker/${this._pathSegment(marker)}/users/logout`, data);
239
239
  if (result) {
240
240
  this.state.accessToken = undefined;
241
241
  this.state.refreshToken = undefined;
@@ -256,7 +256,7 @@ export default class AuthProviderApi extends AsyncModules {
256
256
  * @see {@link https://js-sdk.oneentry.cloud/docs/auth-provider/logoutAll logoutAll} documentation.
257
257
  */
258
258
  async logoutAll(marker) {
259
- const result = await this._fetchPost(`/marker/${marker}/users/logout-all`);
259
+ const result = await this._fetchPost(`/marker/${this._pathSegment(marker)}/users/logout-all`);
260
260
  if (result) {
261
261
  this.state.accessToken = undefined;
262
262
  this.state.refreshToken = undefined;
@@ -290,7 +290,7 @@ export default class AuthProviderApi extends AsyncModules {
290
290
  password1: newPassword,
291
291
  password2: repeatPassword !== null && repeatPassword !== void 0 ? repeatPassword : newPassword,
292
292
  };
293
- const result = await this._fetchPost(`/marker/${marker}/users/change-password`, data);
293
+ const result = await this._fetchPost(`/marker/${this._pathSegment(marker)}/users/change-password`, data);
294
294
  return result;
295
295
  }
296
296
  /**
@@ -321,7 +321,7 @@ export default class AuthProviderApi extends AsyncModules {
321
321
  * @see {@link https://js-sdk.oneentry.cloud/docs/auth-provider/getAuthProviderByMarker getAuthProviderByMarker} documentation.
322
322
  */
323
323
  async getAuthProviderByMarker(marker, langCode = this.state.lang) {
324
- const result = await this._fetchGet(`/marker/${marker}?langCode=${langCode}`);
324
+ const result = await this._fetchGet(`/marker/${this._pathSegment(marker)}?langCode=${langCode}`);
325
325
  return this._normalizeData(result);
326
326
  }
327
327
  /**
@@ -334,7 +334,7 @@ export default class AuthProviderApi extends AsyncModules {
334
334
  * @see {@link https://js-sdk.oneentry.cloud/docs/auth-provider/getActiveSessionsByMarker getActiveSessionsByMarker} documentation.
335
335
  */
336
336
  async getActiveSessionsByMarker(marker) {
337
- const result = await this._fetchGet(`/marker/${marker}/users/sessions`);
337
+ const result = await this._fetchGet(`/marker/${this._pathSegment(marker)}/users/sessions`);
338
338
  return this._normalizeData(result);
339
339
  }
340
340
  /**
@@ -357,7 +357,7 @@ export default class AuthProviderApi extends AsyncModules {
357
357
  * @see {@link https://js-sdk.oneentry.cloud/docs/auth-provider/oauth oauth} documentation.
358
358
  */
359
359
  async oauth(marker, body, langCode = this.state.lang) {
360
- const result = await this._fetchPost(`/marker/${marker}/oauth`, this._normalizePostBody(body, langCode));
360
+ const result = await this._fetchPost(`/marker/${this._pathSegment(marker)}/oauth`, this._normalizePostBody(body, langCode));
361
361
  return result;
362
362
  }
363
363
  }
@@ -49,7 +49,7 @@ export declare const UserResponseSchema: z.ZodObject<{
49
49
  authProviderIdentifier: z.ZodString;
50
50
  formData: z.ZodUnion<readonly [z.ZodArray<z.ZodAny>, z.ZodRecord<z.ZodString, z.ZodAny>]>;
51
51
  formIdentifier: z.ZodString;
52
- total: z.ZodString;
52
+ total: z.ZodOptional<z.ZodString>;
53
53
  groups: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
54
54
  state: z.ZodRecord<z.ZodString, z.ZodAny>;
55
55
  moduleFormConfigs: z.ZodOptional<z.ZodArray<z.ZodAny>>;
@@ -1,4 +1,5 @@
1
1
  import type { IError, ILocalizeInfo, IRating } from '../base/utils.js';
2
+ import type { FormDataType } from '../forms-data/formsDataInterfaces.js';
2
3
  /**
3
4
  * @interface IAuthProvider
4
5
  * @description This interface defines methods for user authentication and registration through various auth providers.
@@ -198,7 +199,7 @@ interface IAuthFormData {
198
199
  * @property {string} formIdentifier - Marker of the registration form. Example: "reg".
199
200
  * @property {string} [langCode] - Language code. Default: "en_US".
200
201
  * @property {Array} authData - Authentication fields, each with a `marker` and a `value`.
201
- * @property {IAuthFormData | IAuthFormData[]} formData - Registration form fields.
202
+ * @property {FormDataType | FormDataType[]} formData - Registration form fields. Field values: {@link FormDataType} — a value shaped by the field type (a string, a date object, a text object, a list, a file descriptor), not only a string. A file goes in as the descriptor `FileUploading.upload` returns: these methods do not upload a `File`/`Blob` themselves.
202
203
  * @property {INotificationData} notificationData - Notification contacts: `email`, `phonePush` and `phoneSMS`.
203
204
  * @description User registration (❗️For a provider with user activation, the activation code is sent through the corresponding user notification method).
204
205
  */
@@ -206,7 +207,7 @@ interface ISignUpData {
206
207
  formIdentifier: string;
207
208
  langCode?: string;
208
209
  authData: IAuthData[];
209
- formData: IAuthFormData | IAuthFormData[];
210
+ formData: FormDataType | FormDataType[];
210
211
  notificationData: INotificationData;
211
212
  }
212
213
  /**
@@ -36,6 +36,17 @@ export default abstract class AsyncModules extends SyncModules {
36
36
  * validation disabled (the default) never pulls Zod into its bundle.
37
37
  */
38
38
  protected _validateResponse<T>(data: unknown, loadSchema?: () => Promise<z.ZodSchema<T>>): Promise<T | IError>;
39
+ /**
40
+ * Prepares a caller value (a marker) to be one segment of a request path.
41
+ * @param {string} value - The value to put into the path.
42
+ * @returns {string} The value encoded as a single path segment.
43
+ * @description `encodeURIComponent` keeps `?`, `#` and `/` from cutting the query or
44
+ * adding segments, but leaves `.` alone, and `URL` resolves a `.` or `..` segment
45
+ * (`%2E` included) — `form-data/marker/..` turned a read into `POST /form-data/`,
46
+ * the create endpoint. A dot-only value is sent with its `%` escaped instead, so the
47
+ * API gets a marker it rejects as invalid rather than another route.
48
+ */
49
+ protected _pathSegment(value: string): string;
39
50
  /**
40
51
  * Performs an HTTP GET request.
41
52
  * @param {string} path - The path to append to the base URL.
@@ -79,6 +79,20 @@ export default class AsyncModules extends SyncModules {
79
79
  return validateResponseSafe(schema, data, this.state.validationLogErrors);
80
80
  }
81
81
  }
82
+ /**
83
+ * Prepares a caller value (a marker) to be one segment of a request path.
84
+ * @param {string} value - The value to put into the path.
85
+ * @returns {string} The value encoded as a single path segment.
86
+ * @description `encodeURIComponent` keeps `?`, `#` and `/` from cutting the query or
87
+ * adding segments, but leaves `.` alone, and `URL` resolves a `.` or `..` segment
88
+ * (`%2E` included) — `form-data/marker/..` turned a read into `POST /form-data/`,
89
+ * the create endpoint. A dot-only value is sent with its `%` escaped instead, so the
90
+ * API gets a marker it rejects as invalid rather than another route.
91
+ */
92
+ _pathSegment(value) {
93
+ const encoded = encodeURIComponent(value);
94
+ return /^\.{1,2}$/.test(value) ? encoded.replace(/\./g, '%252E') : encoded;
95
+ }
82
96
  /**
83
97
  * Performs an HTTP GET request.
84
98
  * @param {string} path - The path to append to the base URL.
@@ -74,7 +74,7 @@ export declare const UserEntitySchema: z.ZodObject<{
74
74
  authProviderIdentifier: z.ZodString;
75
75
  formData: z.ZodUnion<readonly [z.ZodArray<z.ZodAny>, z.ZodRecord<z.ZodString, z.ZodAny>]>;
76
76
  formIdentifier: z.ZodString;
77
- total: z.ZodString;
77
+ total: z.ZodOptional<z.ZodString>;
78
78
  groups: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
79
79
  state: z.ZodRecord<z.ZodString, z.ZodAny>;
80
80
  moduleFormConfigs: z.ZodOptional<z.ZodArray<z.ZodAny>>;
@@ -137,7 +137,7 @@ export const UserEntitySchema = z.object({
137
137
  authProviderIdentifier: z.string(),
138
138
  formData: z.union([z.array(z.any()), z.record(z.string(), z.any())]),
139
139
  formIdentifier: z.string(),
140
- total: z.string(),
140
+ total: z.string().optional(),
141
141
  groups: z.array(z.union([z.string(), z.number()])),
142
142
  state: z.record(z.string(), z.any()),
143
143
  moduleFormConfigs: z.array(z.any()).optional(),
@@ -62,7 +62,7 @@ export default class BlocksApi extends AsyncModules {
62
62
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/getBlockByMarker getBlockByMarker} documentation.
63
63
  */
64
64
  async getBlockByMarker(marker, langCode = this.state.lang, offset = 0, limit = 30) {
65
- const response = await this._fetchGet(`/marker/${marker}?langCode=${langCode}`);
65
+ const response = await this._fetchGet(`/marker/${this._pathSegment(marker)}?langCode=${langCode}`);
66
66
  // Validate response if validation is enabled
67
67
  const validated = await this._validateResponse(response, schema('BlockEntitySchema'));
68
68
  const normalizeResponse = this._normalizeData(validated);
@@ -146,7 +146,8 @@ export default class BlocksApi extends AsyncModules {
146
146
  signPrice,
147
147
  productId,
148
148
  };
149
- const result = await this._fetchGet(`/${marker}/similar-products?` + this._queryParamsToString(query));
149
+ const result = await this._fetchGet(`/${this._pathSegment(marker)}/similar-products?` +
150
+ this._queryParamsToString(query));
150
151
  return this._normalizeData(result);
151
152
  }
152
153
  /**
@@ -169,7 +170,8 @@ export default class BlocksApi extends AsyncModules {
169
170
  limit,
170
171
  signPrice,
171
172
  };
172
- const result = await this._fetchGet(`/${marker}/products?` + this._queryParamsToString(query));
173
+ const result = await this._fetchGet(`/${this._pathSegment(marker)}/products?` +
174
+ this._queryParamsToString(query));
173
175
  // On API error responses there is no `items` array — return the (normalized)
174
176
  // error as-is instead of producing `undefined` from `result.items`.
175
177
  if (!Array.isArray(result === null || result === void 0 ? void 0 : result.items)) {
@@ -196,7 +198,7 @@ export default class BlocksApi extends AsyncModules {
196
198
  signPrice,
197
199
  limit,
198
200
  };
199
- const data = await this._fetchGet(`/${marker}/products/${productId}/frequently-ordered?` +
201
+ const data = await this._fetchGet(`/${this._pathSegment(marker)}/products/${productId}/frequently-ordered?` +
200
202
  this._queryParamsToString(query));
201
203
  return this._normalizeData(data);
202
204
  }
@@ -229,7 +231,8 @@ export default class BlocksApi extends AsyncModules {
229
231
  */
230
232
  async getCartComplement(marker, langCode = this.state.lang, signPrice, limit) {
231
233
  const query = { langCode, signPrice, limit };
232
- const data = await this._fetchGet(`/${marker}/cart-complement?` + this._queryParamsToString(query));
234
+ const data = await this._fetchGet(`/${this._pathSegment(marker)}/cart-complement?` +
235
+ this._queryParamsToString(query));
233
236
  return this._normalizeData(data);
234
237
  }
235
238
  /**
@@ -247,7 +250,7 @@ export default class BlocksApi extends AsyncModules {
247
250
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/getCartComplementByProductIds getCartComplementByProductIds} documentation.
248
251
  */
249
252
  async getCartComplementByProductIds(marker, body) {
250
- const data = await this._fetchPost(`/${marker}/cart-complement`, { langCode: this.state.lang, ...body });
253
+ const data = await this._fetchPost(`/${this._pathSegment(marker)}/cart-complement`, { langCode: this.state.lang, ...body });
251
254
  return this._normalizeData(data);
252
255
  }
253
256
  /**
@@ -264,7 +267,8 @@ export default class BlocksApi extends AsyncModules {
264
267
  */
265
268
  async getCartSimilar(marker, langCode = this.state.lang, signPrice, limit) {
266
269
  const query = { langCode, signPrice, limit };
267
- const data = await this._fetchGet(`/${marker}/cart-similar?` + this._queryParamsToString(query));
270
+ const data = await this._fetchGet(`/${this._pathSegment(marker)}/cart-similar?` +
271
+ this._queryParamsToString(query));
268
272
  return this._normalizeData(data);
269
273
  }
270
274
  /**
@@ -282,7 +286,7 @@ export default class BlocksApi extends AsyncModules {
282
286
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/getCartSimilarByProductIds getCartSimilarByProductIds} documentation.
283
287
  */
284
288
  async getCartSimilarByProductIds(marker, body) {
285
- const data = await this._fetchPost(`/${marker}/cart-similar`, { langCode: this.state.lang, ...body });
289
+ const data = await this._fetchPost(`/${this._pathSegment(marker)}/cart-similar`, { langCode: this.state.lang, ...body });
286
290
  return this._normalizeData(data);
287
291
  }
288
292
  /**
@@ -299,7 +303,8 @@ export default class BlocksApi extends AsyncModules {
299
303
  */
300
304
  async getPersonalRecommendations(marker, langCode = this.state.lang, signPrice, limit) {
301
305
  const query = { langCode, signPrice, limit };
302
- const data = await this._fetchGet(`/${marker}/personal-recommendations?` + this._queryParamsToString(query));
306
+ const data = await this._fetchGet(`/${this._pathSegment(marker)}/personal-recommendations?` +
307
+ this._queryParamsToString(query));
303
308
  return this._normalizeData(data);
304
309
  }
305
310
  /**
@@ -316,7 +321,8 @@ export default class BlocksApi extends AsyncModules {
316
321
  */
317
322
  async getRecentlyViewed(marker, langCode = this.state.lang, signPrice, limit) {
318
323
  const query = { langCode, signPrice, limit };
319
- const data = await this._fetchGet(`/${marker}/recently-viewed?` + this._queryParamsToString(query));
324
+ const data = await this._fetchGet(`/${this._pathSegment(marker)}/recently-viewed?` +
325
+ this._queryParamsToString(query));
320
326
  return this._normalizeData(data);
321
327
  }
322
328
  /**
@@ -333,7 +339,8 @@ export default class BlocksApi extends AsyncModules {
333
339
  */
334
340
  async getRepeatPurchase(marker, langCode = this.state.lang, signPrice, limit) {
335
341
  const query = { langCode, signPrice, limit };
336
- const data = await this._fetchGet(`/${marker}/repeat-purchase?` + this._queryParamsToString(query));
342
+ const data = await this._fetchGet(`/${this._pathSegment(marker)}/repeat-purchase?` +
343
+ this._queryParamsToString(query));
337
344
  return this._normalizeData(data);
338
345
  }
339
346
  /**
@@ -345,7 +352,7 @@ export default class BlocksApi extends AsyncModules {
345
352
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/getSlides getSlides} documentation.
346
353
  */
347
354
  async getSlides(marker) {
348
- const data = await this._fetchGet(`/${marker}/slides`);
355
+ const data = await this._fetchGet(`/${this._pathSegment(marker)}/slides`);
349
356
  return this._normalizeData(data);
350
357
  }
351
358
  /**
@@ -362,7 +369,8 @@ export default class BlocksApi extends AsyncModules {
362
369
  */
363
370
  async getTrending(marker, langCode = this.state.lang, signPrice, limit) {
364
371
  const query = { langCode, signPrice, limit };
365
- const data = await this._fetchGet(`/${marker}/trending?` + this._queryParamsToString(query));
372
+ const data = await this._fetchGet(`/${this._pathSegment(marker)}/trending?` +
373
+ this._queryParamsToString(query));
366
374
  return this._normalizeData(data);
367
375
  }
368
376
  /**
@@ -379,7 +387,8 @@ export default class BlocksApi extends AsyncModules {
379
387
  */
380
388
  async getWishlistSimilar(marker, langCode = this.state.lang, signPrice, limit) {
381
389
  const query = { langCode, signPrice, limit };
382
- const data = await this._fetchGet(`/${marker}/wishlist-similar?` + this._queryParamsToString(query));
390
+ const data = await this._fetchGet(`/${this._pathSegment(marker)}/wishlist-similar?` +
391
+ this._queryParamsToString(query));
383
392
  return this._normalizeData(data);
384
393
  }
385
394
  /**
@@ -397,7 +406,7 @@ export default class BlocksApi extends AsyncModules {
397
406
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/getWishlistSimilarByProductIds getWishlistSimilarByProductIds} documentation.
398
407
  */
399
408
  async getWishlistSimilarByProductIds(marker, body) {
400
- const data = await this._fetchPost(`/${marker}/wishlist-similar`, { langCode: this.state.lang, ...body });
409
+ const data = await this._fetchPost(`/${this._pathSegment(marker)}/wishlist-similar`, { langCode: this.state.lang, ...body });
401
410
  return this._normalizeData(data);
402
411
  }
403
412
  }
@@ -57,7 +57,8 @@ export default class DiscountsApi extends AsyncModules {
57
57
  marker: '',
58
58
  langCode,
59
59
  };
60
- const data = await this._fetchGet(`/marker/${marker}?` + this._queryParamsToString(query));
60
+ const data = await this._fetchGet(`/marker/${this._pathSegment(marker)}?` +
61
+ this._queryParamsToString(query));
61
62
  return this._normalizeData(data);
62
63
  }
63
64
  /**
@@ -57,7 +57,7 @@ export default class EventsApi extends AsyncModules {
57
57
  locale: langCode,
58
58
  productId,
59
59
  };
60
- return this._fetchBoolean(() => this._fetchPost(`/subscribe/marker/${marker}`, body));
60
+ return this._fetchBoolean(() => this._fetchPost(`/subscribe/marker/${this._pathSegment(marker)}`, body));
61
61
  }
62
62
  /**
63
63
  * Unsubscribing to an event on a product.
@@ -76,7 +76,7 @@ export default class EventsApi extends AsyncModules {
76
76
  productId: productId,
77
77
  locale: langCode,
78
78
  };
79
- return this._fetchBoolean(() => this._fetchDelete(`/unsubscribe/marker/${marker}`, body));
79
+ return this._fetchBoolean(() => this._fetchDelete(`/unsubscribe/marker/${this._pathSegment(marker)}`, body));
80
80
  }
81
81
  /**
82
82
  * Returns all available events.
@@ -102,7 +102,7 @@ export default class EventsApi extends AsyncModules {
102
102
  * @see {@link https://js-sdk.oneentry.cloud/docs/events/subscribeToForm subscribeToForm} documentation.
103
103
  */
104
104
  async subscribeToForm(marker, body) {
105
- return this._fetchBoolean(() => this._fetchPost(`/forms/subscribe/marker/${marker}`, body));
105
+ return this._fetchBoolean(() => this._fetchPost(`/forms/subscribe/marker/${this._pathSegment(marker)}`, body));
106
106
  }
107
107
  /**
108
108
  * Returns all form subscriptions.
@@ -135,6 +135,6 @@ export default class EventsApi extends AsyncModules {
135
135
  * @see {@link https://js-sdk.oneentry.cloud/docs/events/unsubscribeFromForm unsubscribeFromForm} documentation.
136
136
  */
137
137
  async unsubscribeFromForm(marker, body) {
138
- return this._fetchBoolean(() => this._fetchDelete(`/forms/unsubscribe/marker/${marker}`, body));
138
+ return this._fetchBoolean(() => this._fetchDelete(`/forms/unsubscribe/marker/${this._pathSegment(marker)}`, body));
139
139
  }
140
140
  }
@@ -29,7 +29,7 @@ export default class FiltersApi extends AsyncModules {
29
29
  * @see {@link https://js-sdk.oneentry.cloud/docs/filters/getFilterByMarker getFilterByMarker} documentation.
30
30
  */
31
31
  async getFilterByMarker(marker, langCode = this.state.lang) {
32
- const data = await this._fetchGet(`/marker/${marker}?langCode=${langCode}`);
32
+ const data = await this._fetchGet(`/marker/${this._pathSegment(marker)}?langCode=${langCode}`);
33
33
  const validated = await this._validateResponse(data, schema('ContentFilterSchema'));
34
34
  return this._normalizeData(validated);
35
35
  }
@@ -46,7 +46,7 @@ export default class FormsApi extends AsyncModules {
46
46
  * @see {@link https://js-sdk.oneentry.cloud/docs/forms/getFormByMarker getFormByMarker} documentation.
47
47
  */
48
48
  async getFormByMarker(marker, langCode = this.state.lang) {
49
- const result = await this._fetchGet(`/marker/${marker}?langCode=${langCode}`);
49
+ const result = await this._fetchGet(`/marker/${this._pathSegment(marker)}?langCode=${langCode}`);
50
50
  // Validate response if validation is enabled
51
51
  const validated = await this._validateResponse(result, schema('FormEntitySchema'));
52
52
  return this._normalizeData(validated, langCode);
@@ -118,17 +118,19 @@ export default class FormsDataApi extends AsyncModules implements IFormsData {
118
118
  * @param {number} [body.parentId] - Identifier of the parent record, to fetch replies to one submission. Example: 10.
119
119
  * @param {string} [body.userIdentifier] - Text identifier of the sender. Example: "admin".
120
120
  * @param {FormDataStatus[]} [body.status] - Moderation statuses to keep: "sent", "moderation", "approved", "banned", "deleted". Must be an array; anything outside the set is rejected with `400 each value in status must be a valid enum value`. Example: ["approved"].
121
- * @param {string} [body.dateFrom] - Lower bound of the submission date, `YYYY-MM-DD`. An empty string means "no bound" — the SDK removes it from the body, because the endpoint answers `400 dateFrom must be a valid date in format "YYYY-MM-DD"` to one. An unparsable non-empty value still fails the request. Example: "2025-01-01".
122
- * @param {string} [body.dateTo] - Upper bound of the submission date, `YYYY-MM-DD`. An empty string means "no bound", handled like `dateFrom`. Example: "2025-12-31".
121
+ * @param {string} [body.dateFrom] - Lower bound of the submission date, `YYYY-MM-DD` or `YYYY-MM-DD HH:MM:SS`. An empty string means "no bound" — the SDK removes it from the body, because the endpoint answers `400 dateFrom must be a valid date in format "YYYY-MM-DD"` to one. An unparsable non-empty value still fails the request. Example: "2025-01-01".
122
+ * @param {string} [body.dateTo] - Upper bound of the submission date, `YYYY-MM-DD` or `YYYY-MM-DD HH:MM:SS`. An empty string means "no bound", handled like `dateFrom`. Example: "2025-12-31".
123
123
  * @param {number} [isExtended] - Pass `1` to return additional fields for each record. Default: `0`. Example: 1.
124
124
  * @param {string} [langCode] - Language code. Default: "en_US".
125
- * @param {number} [offset] - Number of records to skip. Default: 0.
126
- * @param {number} [limit] - Maximum number of records to return. Default: 30.
125
+ * @param {number} [offset] - Number of records to skip, `0` or more (a negative one answers `400 offset must not be less than 0`). Default: 0.
126
+ * @param {number} [limit] - Maximum number of records to return, `1` or more (`0` answers `400 limit must not be less than 1`). Default: 30.
127
127
  * @returns {Promise<IFormsByMarkerDataEntity | IError>} Returns an object containing the form data or an error object if there was an issue.
128
128
  * @throws {IError} When isShell=false and an error occurs during the fetch
129
129
  * @description Each record's `formData` comes back **already unwrapped from its locale**. The API sends `formData: { "en_US": [ … ] }`; the SDK normalizes the response and hands over the array for `langCode`, so read `record.formData` — `record.formData[langCode]` is `undefined` and yields an empty list with no error. This holds for both values of `isExtended`.
130
130
  *
131
- * The filter body is typed for a reason: the API silently ignores a field it does not know, so a misspelled `statuses` returns every record — unmoderated ones included — and the code looks like it works.
131
+ * The filter body is typed because the API refuses a field it does not know: a misspelled `statuses` answers `400 property statuses should not exist`.
132
+ *
133
+ * A marker or `formModuleConfigId` that matches nothing answers `200` with `{ items: [], total: 0 }`, not `404` — an empty list does not prove the form exists.
132
134
  *
133
135
  * Empty `dateFrom` / `dateTo` are stripped from the body before it is sent: the endpoint validates the pair as dates and rejects an empty string with a `400`, while every other field still treats "" as "no filter".
134
136
  * @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/getFormsDataByMarker getFormsDataByMarker} documentation.
@@ -164,11 +166,11 @@ export default class FormsDataApi extends AsyncModules implements IFormsData {
164
166
  * @handleName getFormsDataByVectorSearch
165
167
  * @param {IFormsDataVectorSearch} body - Vector search parameters. Example: `{ queryText: "order confirmation" }`.
166
168
  * @param {string} [langCode] - Language code. Default: "en_US".
167
- * @param {number} [offset] - Number of records to skip. Default: 0.
168
- * @param {number} [limit] - Maximum number of records to return. Default: 30.
169
+ * @param {number} [offset] - Number of records to skip, `0` or more. Default: 0.
170
+ * @param {number} [limit] - Maximum number of records to return, `1` or more. Default: 30.
169
171
  * @returns {Promise<IVectorSearchResponse<IFormsDataSearchResponse> | IError>} Returns an object with an array of found form data records and total count.
170
172
  * @throws {IError} When isShell=false and an error occurs during the fetch
171
- * @description This method performs a semantic (vector) search for form data.
173
+ * @description This method performs a semantic (vector) search for form data. The body is checked by the API: an empty `queryText` or one longer than 512 characters, a negative `vectorDistanceThreshold` and a `maxHits` below `1` each answer `400`.
172
174
  * @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/getFormsDataByVectorSearch getFormsDataByVectorSearch} documentation.
173
175
  */
174
176
  getFormsDataByVectorSearch(body: IFormsDataVectorSearch, langCode?: string, offset?: number, limit?: number): Promise<IVectorSearchResponse<IFormsDataSearchResponse> | IError>;
@@ -133,7 +133,9 @@ export default class FormsDataApi extends AsyncModules {
133
133
  const result = await this._fetchPost(``, { ...body, formData });
134
134
  // Validate response if validation is enabled
135
135
  const validated = await this._validateResponse(result, schema('PostFormResponseSchema'));
136
- return this._normalizeData(validated);
136
+ // The fields went in under `langCode`, so the response is unwrapped from the same
137
+ // locale; without it a call in another language returned `formData` still keyed by it
138
+ return this._normalizeData(validated, langCode);
137
139
  }
138
140
  /**
139
141
  * Tells a file the SDK still has to upload from one already in storage.
@@ -214,23 +216,25 @@ export default class FormsDataApi extends AsyncModules {
214
216
  * @param {number} [body.parentId] - Identifier of the parent record, to fetch replies to one submission. Example: 10.
215
217
  * @param {string} [body.userIdentifier] - Text identifier of the sender. Example: "admin".
216
218
  * @param {FormDataStatus[]} [body.status] - Moderation statuses to keep: "sent", "moderation", "approved", "banned", "deleted". Must be an array; anything outside the set is rejected with `400 each value in status must be a valid enum value`. Example: ["approved"].
217
- * @param {string} [body.dateFrom] - Lower bound of the submission date, `YYYY-MM-DD`. An empty string means "no bound" — the SDK removes it from the body, because the endpoint answers `400 dateFrom must be a valid date in format "YYYY-MM-DD"` to one. An unparsable non-empty value still fails the request. Example: "2025-01-01".
218
- * @param {string} [body.dateTo] - Upper bound of the submission date, `YYYY-MM-DD`. An empty string means "no bound", handled like `dateFrom`. Example: "2025-12-31".
219
+ * @param {string} [body.dateFrom] - Lower bound of the submission date, `YYYY-MM-DD` or `YYYY-MM-DD HH:MM:SS`. An empty string means "no bound" — the SDK removes it from the body, because the endpoint answers `400 dateFrom must be a valid date in format "YYYY-MM-DD"` to one. An unparsable non-empty value still fails the request. Example: "2025-01-01".
220
+ * @param {string} [body.dateTo] - Upper bound of the submission date, `YYYY-MM-DD` or `YYYY-MM-DD HH:MM:SS`. An empty string means "no bound", handled like `dateFrom`. Example: "2025-12-31".
219
221
  * @param {number} [isExtended] - Pass `1` to return additional fields for each record. Default: `0`. Example: 1.
220
222
  * @param {string} [langCode] - Language code. Default: "en_US".
221
- * @param {number} [offset] - Number of records to skip. Default: 0.
222
- * @param {number} [limit] - Maximum number of records to return. Default: 30.
223
+ * @param {number} [offset] - Number of records to skip, `0` or more (a negative one answers `400 offset must not be less than 0`). Default: 0.
224
+ * @param {number} [limit] - Maximum number of records to return, `1` or more (`0` answers `400 limit must not be less than 1`). Default: 30.
223
225
  * @returns {Promise<IFormsByMarkerDataEntity | IError>} Returns an object containing the form data or an error object if there was an issue.
224
226
  * @throws {IError} When isShell=false and an error occurs during the fetch
225
227
  * @description Each record's `formData` comes back **already unwrapped from its locale**. The API sends `formData: { "en_US": [ … ] }`; the SDK normalizes the response and hands over the array for `langCode`, so read `record.formData` — `record.formData[langCode]` is `undefined` and yields an empty list with no error. This holds for both values of `isExtended`.
226
228
  *
227
- * The filter body is typed for a reason: the API silently ignores a field it does not know, so a misspelled `statuses` returns every record — unmoderated ones included — and the code looks like it works.
229
+ * The filter body is typed because the API refuses a field it does not know: a misspelled `statuses` answers `400 property statuses should not exist`.
230
+ *
231
+ * A marker or `formModuleConfigId` that matches nothing answers `200` with `{ items: [], total: 0 }`, not `404` — an empty list does not prove the form exists.
228
232
  *
229
233
  * Empty `dateFrom` / `dateTo` are stripped from the body before it is sent: the endpoint validates the pair as dates and rejects an empty string with a `400`, while every other field still treats "" as "no filter".
230
234
  * @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/getFormsDataByMarker getFormsDataByMarker} documentation.
231
235
  */
232
236
  async getFormsDataByMarker(marker, formModuleConfigId, body = {}, isExtended = 0, langCode = this.state.lang, offset = 0, limit = 30) {
233
- const result = await this._fetchPost(`/marker/${marker}?formModuleConfigId=${formModuleConfigId}&isExtended=${isExtended}&langCode=${langCode}&offset=${offset}&limit=${limit}`, this._stripEmptyDates(body));
237
+ const result = await this._fetchPost(`/marker/${this._pathSegment(marker)}?formModuleConfigId=${formModuleConfigId}&isExtended=${isExtended}&langCode=${langCode}&offset=${offset}&limit=${limit}`, this._stripEmptyDates(body));
234
238
  // Validate response if validation is enabled
235
239
  const validated = await this._validateResponse(result, schema('FormsByMarkerDataResponseSchema'));
236
240
  return this._normalizeData(validated, langCode);
@@ -276,11 +280,11 @@ export default class FormsDataApi extends AsyncModules {
276
280
  * @handleName getFormsDataByVectorSearch
277
281
  * @param {IFormsDataVectorSearch} body - Vector search parameters. Example: `{ queryText: "order confirmation" }`.
278
282
  * @param {string} [langCode] - Language code. Default: "en_US".
279
- * @param {number} [offset] - Number of records to skip. Default: 0.
280
- * @param {number} [limit] - Maximum number of records to return. Default: 30.
283
+ * @param {number} [offset] - Number of records to skip, `0` or more. Default: 0.
284
+ * @param {number} [limit] - Maximum number of records to return, `1` or more. Default: 30.
281
285
  * @returns {Promise<IVectorSearchResponse<IFormsDataSearchResponse> | IError>} Returns an object with an array of found form data records and total count.
282
286
  * @throws {IError} When isShell=false and an error occurs during the fetch
283
- * @description This method performs a semantic (vector) search for form data.
287
+ * @description This method performs a semantic (vector) search for form data. The body is checked by the API: an empty `queryText` or one longer than 512 characters, a negative `vectorDistanceThreshold` and a `maxHits` below `1` each answer `400`.
284
288
  * @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/getFormsDataByVectorSearch getFormsDataByVectorSearch} documentation.
285
289
  */
286
290
  async getFormsDataByVectorSearch(body, langCode = this.state.lang, offset = 0, limit = 30) {