oneentry 1.0.176 → 1.0.177

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 (197) hide show
  1. package/README.md +12 -5
  2. package/changelog.md +116 -0
  3. package/dist/admins/adminsApi.js +2 -9
  4. package/dist/admins/adminsInterfaces.d.ts +5 -5
  5. package/dist/admins/adminsSchemas.d.ts +4 -4
  6. package/dist/admins/adminsSchemas.js +2 -2
  7. package/dist/attribute-sets/attributeSetsApi.d.ts +1 -1
  8. package/dist/attribute-sets/attributeSetsApi.js +4 -4
  9. package/dist/attribute-sets/attributeSetsInterfaces.d.ts +65 -14
  10. package/dist/attribute-sets/attributeSetsSchemas.d.ts +8 -6
  11. package/dist/attribute-sets/attributeSetsSchemas.js +6 -9
  12. package/dist/auth-provider/authProviderApi.d.ts +4 -4
  13. package/dist/auth-provider/authProviderApi.js +90 -23
  14. package/dist/auth-provider/authProviderSchemas.d.ts +1 -0
  15. package/dist/auth-provider/authProviderSchemas.js +1 -0
  16. package/dist/auth-provider/authProvidersInterfaces.d.ts +8 -6
  17. package/dist/base/asyncModules.d.ts +62 -1
  18. package/dist/base/asyncModules.js +219 -37
  19. package/dist/base/stateModule.d.ts +2 -0
  20. package/dist/base/stateModule.js +22 -12
  21. package/dist/base/syncModules.d.ts +18 -10
  22. package/dist/base/syncModules.js +100 -29
  23. package/dist/base/utils.d.ts +26 -21
  24. package/dist/base/validation.d.ts +3 -3
  25. package/dist/base/validation.js +6 -7
  26. package/dist/blocks/blocksApi.d.ts +20 -17
  27. package/dist/blocks/blocksApi.js +82 -64
  28. package/dist/blocks/blocksInterfaces.d.ts +8 -8
  29. package/dist/discounts/discountsApi.d.ts +9 -7
  30. package/dist/discounts/discountsApi.js +16 -13
  31. package/dist/discounts/discountsInterfaces.d.ts +14 -10
  32. package/dist/events/eventsApi.d.ts +3 -3
  33. package/dist/events/eventsApi.js +3 -3
  34. package/dist/events/eventsInterfaces.d.ts +10 -14
  35. package/dist/file-uploading/fileUploadingApi.d.ts +4 -4
  36. package/dist/file-uploading/fileUploadingApi.js +13 -5
  37. package/dist/file-uploading/fileUploadingInterfaces.d.ts +5 -6
  38. package/dist/filters/filtersApi.js +2 -2
  39. package/dist/forms/formsApi.js +2 -2
  40. package/dist/forms/formsInterfaces.d.ts +1 -3
  41. package/dist/forms/formsSchemas.d.ts +3 -6
  42. package/dist/forms/formsSchemas.js +2 -4
  43. package/dist/forms-data/formsDataApi.d.ts +16 -0
  44. package/dist/forms-data/formsDataApi.js +32 -5
  45. package/dist/forms-data/formsDataInterfaces.d.ts +17 -13
  46. package/dist/general-types/generalTypesInterfaces.d.ts +1 -1
  47. package/dist/index.d.ts +7 -6
  48. package/dist/index.js +50 -7
  49. package/dist/integration-collections/integrationCollectionsApi.d.ts +15 -4
  50. package/dist/integration-collections/integrationCollectionsApi.js +41 -14
  51. package/dist/integration-collections/integrationCollectionsInterfaces.d.ts +8 -9
  52. package/dist/integration-collections/integrationCollectionsSchemas.d.ts +0 -2
  53. package/dist/integration-collections/integrationCollectionsSchemas.js +0 -1
  54. package/dist/menus/menusApi.js +1 -1
  55. package/dist/orders/ordersApi.d.ts +1 -13
  56. package/dist/orders/ordersApi.js +21 -42
  57. package/dist/orders/ordersInterfaces.d.ts +21 -14
  58. package/dist/pages/pagesApi.d.ts +6 -5
  59. package/dist/pages/pagesApi.js +44 -31
  60. package/dist/pages/pagesInterfaces.d.ts +18 -15
  61. package/dist/pages/pagesSchemas.d.ts +0 -3
  62. package/dist/pages/pagesSchemas.js +0 -1
  63. package/dist/payments/paymentsApi.d.ts +10 -11
  64. package/dist/payments/paymentsApi.js +22 -18
  65. package/dist/payments/paymentsInterfaces.d.ts +12 -14
  66. package/dist/payments/paymentsSchemas.d.ts +21 -20
  67. package/dist/payments/paymentsSchemas.js +5 -8
  68. package/dist/product-statuses/productStatusesApi.d.ts +1 -1
  69. package/dist/product-statuses/productStatusesApi.js +3 -3
  70. package/dist/product-statuses/productStatusesInterfaces.d.ts +1 -4
  71. package/dist/products/productsApi.d.ts +38 -58
  72. package/dist/products/productsApi.js +59 -72
  73. package/dist/products/productsInterfaces.d.ts +48 -85
  74. package/dist/search/searchApi.d.ts +1 -1
  75. package/dist/search/searchApi.js +4 -3
  76. package/dist/sitemap/sitemapInterfaces.d.ts +10 -6
  77. package/dist/subscriptions/subscriptionsApi.d.ts +1 -1
  78. package/dist/subscriptions/subscriptionsApi.js +1 -1
  79. package/dist/subscriptions/subscriptionsInterfaces.d.ts +1 -1
  80. package/dist/system/systemApi.d.ts +2 -0
  81. package/dist/system/systemApi.js +2 -0
  82. package/dist/system/systemInterfaces.d.ts +2 -0
  83. package/dist/templates/templatesApi.d.ts +2 -2
  84. package/dist/templates/templatesApi.js +12 -11
  85. package/dist/templates/templatesInterfaces.d.ts +2 -2
  86. package/dist/templates-preview/templatesPreviewApi.js +2 -2
  87. package/dist/templates-preview/templatesPreviewInterfaces.d.ts +23 -13
  88. package/dist/templates-preview/templatesPreviewSchemas.d.ts +7 -0
  89. package/dist/templates-preview/templatesPreviewSchemas.js +2 -0
  90. package/dist/user-groups/userGroupsApi.js +5 -5
  91. package/dist/user-groups/userGroupsSchemas.d.ts +4 -4
  92. package/dist/users/usersApi.d.ts +1 -1
  93. package/dist/users/usersApi.js +28 -15
  94. package/dist/users/usersInterfaces.d.ts +2 -9
  95. package/dist/web-socket/lazySocket.d.ts +6 -5
  96. package/dist/web-socket/lazySocket.js +212 -15
  97. package/dist/web-socket/wsApi.d.ts +7 -4
  98. package/dist/web-socket/wsApi.js +49 -12
  99. package/dist/web-socket/wsInterfaces.d.ts +41 -4
  100. package/esm/admins/adminsApi.js +2 -9
  101. package/esm/admins/adminsInterfaces.d.ts +5 -5
  102. package/esm/admins/adminsSchemas.d.ts +4 -4
  103. package/esm/admins/adminsSchemas.js +2 -2
  104. package/esm/attribute-sets/attributeSetsApi.d.ts +1 -1
  105. package/esm/attribute-sets/attributeSetsApi.js +4 -4
  106. package/esm/attribute-sets/attributeSetsInterfaces.d.ts +65 -14
  107. package/esm/attribute-sets/attributeSetsSchemas.d.ts +8 -6
  108. package/esm/attribute-sets/attributeSetsSchemas.js +6 -9
  109. package/esm/auth-provider/authProviderApi.d.ts +4 -4
  110. package/esm/auth-provider/authProviderApi.js +90 -23
  111. package/esm/auth-provider/authProviderSchemas.d.ts +1 -0
  112. package/esm/auth-provider/authProviderSchemas.js +1 -0
  113. package/esm/auth-provider/authProvidersInterfaces.d.ts +8 -6
  114. package/esm/base/asyncModules.d.ts +62 -1
  115. package/esm/base/asyncModules.js +219 -37
  116. package/esm/base/stateModule.d.ts +2 -0
  117. package/esm/base/stateModule.js +22 -12
  118. package/esm/base/syncModules.d.ts +18 -10
  119. package/esm/base/syncModules.js +99 -29
  120. package/esm/base/utils.d.ts +26 -21
  121. package/esm/base/validation.d.ts +3 -3
  122. package/esm/base/validation.js +6 -7
  123. package/esm/blocks/blocksApi.d.ts +20 -17
  124. package/esm/blocks/blocksApi.js +82 -64
  125. package/esm/blocks/blocksInterfaces.d.ts +8 -8
  126. package/esm/discounts/discountsApi.d.ts +9 -7
  127. package/esm/discounts/discountsApi.js +16 -13
  128. package/esm/discounts/discountsInterfaces.d.ts +14 -10
  129. package/esm/events/eventsApi.d.ts +3 -3
  130. package/esm/events/eventsApi.js +3 -3
  131. package/esm/events/eventsInterfaces.d.ts +10 -14
  132. package/esm/file-uploading/fileUploadingApi.d.ts +4 -4
  133. package/esm/file-uploading/fileUploadingApi.js +13 -5
  134. package/esm/file-uploading/fileUploadingInterfaces.d.ts +5 -6
  135. package/esm/filters/filtersApi.js +2 -2
  136. package/esm/forms/formsApi.js +2 -2
  137. package/esm/forms/formsInterfaces.d.ts +1 -3
  138. package/esm/forms/formsSchemas.d.ts +3 -6
  139. package/esm/forms/formsSchemas.js +2 -4
  140. package/esm/forms-data/formsDataApi.d.ts +16 -0
  141. package/esm/forms-data/formsDataApi.js +32 -5
  142. package/esm/forms-data/formsDataInterfaces.d.ts +17 -13
  143. package/esm/general-types/generalTypesInterfaces.d.ts +1 -1
  144. package/esm/index.d.ts +7 -6
  145. package/esm/index.js +50 -7
  146. package/esm/integration-collections/integrationCollectionsApi.d.ts +15 -4
  147. package/esm/integration-collections/integrationCollectionsApi.js +41 -14
  148. package/esm/integration-collections/integrationCollectionsInterfaces.d.ts +8 -9
  149. package/esm/integration-collections/integrationCollectionsSchemas.d.ts +0 -2
  150. package/esm/integration-collections/integrationCollectionsSchemas.js +0 -1
  151. package/esm/menus/menusApi.js +1 -1
  152. package/esm/orders/ordersApi.d.ts +1 -13
  153. package/esm/orders/ordersApi.js +21 -42
  154. package/esm/orders/ordersInterfaces.d.ts +21 -14
  155. package/esm/pages/pagesApi.d.ts +6 -5
  156. package/esm/pages/pagesApi.js +44 -31
  157. package/esm/pages/pagesInterfaces.d.ts +18 -15
  158. package/esm/pages/pagesSchemas.d.ts +0 -3
  159. package/esm/pages/pagesSchemas.js +0 -1
  160. package/esm/payments/paymentsApi.d.ts +10 -11
  161. package/esm/payments/paymentsApi.js +22 -18
  162. package/esm/payments/paymentsInterfaces.d.ts +12 -14
  163. package/esm/payments/paymentsSchemas.d.ts +21 -20
  164. package/esm/payments/paymentsSchemas.js +5 -8
  165. package/esm/product-statuses/productStatusesApi.d.ts +1 -1
  166. package/esm/product-statuses/productStatusesApi.js +3 -3
  167. package/esm/product-statuses/productStatusesInterfaces.d.ts +1 -4
  168. package/esm/products/productsApi.d.ts +38 -58
  169. package/esm/products/productsApi.js +59 -72
  170. package/esm/products/productsInterfaces.d.ts +48 -85
  171. package/esm/search/searchApi.d.ts +1 -1
  172. package/esm/search/searchApi.js +4 -3
  173. package/esm/sitemap/sitemapInterfaces.d.ts +10 -6
  174. package/esm/subscriptions/subscriptionsApi.d.ts +1 -1
  175. package/esm/subscriptions/subscriptionsApi.js +1 -1
  176. package/esm/subscriptions/subscriptionsInterfaces.d.ts +1 -1
  177. package/esm/system/systemApi.d.ts +2 -0
  178. package/esm/system/systemApi.js +2 -0
  179. package/esm/system/systemInterfaces.d.ts +2 -0
  180. package/esm/templates/templatesApi.d.ts +2 -2
  181. package/esm/templates/templatesApi.js +11 -10
  182. package/esm/templates/templatesInterfaces.d.ts +2 -2
  183. package/esm/templates-preview/templatesPreviewApi.js +2 -2
  184. package/esm/templates-preview/templatesPreviewInterfaces.d.ts +23 -13
  185. package/esm/templates-preview/templatesPreviewSchemas.d.ts +7 -0
  186. package/esm/templates-preview/templatesPreviewSchemas.js +2 -0
  187. package/esm/user-groups/userGroupsApi.js +5 -5
  188. package/esm/user-groups/userGroupsSchemas.d.ts +4 -4
  189. package/esm/users/usersApi.d.ts +1 -1
  190. package/esm/users/usersApi.js +28 -15
  191. package/esm/users/usersInterfaces.d.ts +2 -9
  192. package/esm/web-socket/lazySocket.d.ts +6 -5
  193. package/esm/web-socket/lazySocket.js +212 -15
  194. package/esm/web-socket/wsApi.d.ts +7 -4
  195. package/esm/web-socket/wsApi.js +49 -12
  196. package/esm/web-socket/wsInterfaces.d.ts +41 -4
  197. package/package.json +2 -2
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._warnGuestId = _warnGuestId;
3
4
  // localStorage keys for the persistent browser-side identifiers.
4
5
  const _DEVICE_ID_STORAGE_KEY = 'oneentry_device_id';
5
6
  const _GUEST_ID_STORAGE_KEY = 'oneentry_guest_id';
@@ -11,31 +12,46 @@ const _persistentIds = {};
11
12
  *
12
13
  * Prefers a cryptographically secure source (Web Crypto, exposed as
13
14
  * `globalThis.crypto` in browsers and Node.js >= 18): `randomUUID()` when
14
- * available, otherwise random bytes rendered as a base-36 string. Falls back to
15
- * a timestamp + `Math.random()` only when no CSPRNG exists (e.g. very old Node).
16
- *
17
- * The result contains no special characters, so it is safe to use both in
18
- * localStorage and in HTTP headers.
19
- * @returns {string} A freshly generated identifier.
15
+ * available, otherwise a UUID v4 built from `getRandomValues`, and from
16
+ * `Math.random()` only when no CSPRNG exists (e.g. very old Node).
17
+ * @returns {string} A freshly generated UUID v4.
20
18
  */
21
19
  function _generateId() {
22
20
  const cryptoObj = typeof globalThis !== 'undefined' ? globalThis.crypto : undefined;
23
21
  if (cryptoObj === null || cryptoObj === void 0 ? void 0 : cryptoObj.randomUUID) {
24
22
  return cryptoObj.randomUUID();
25
23
  }
24
+ // `randomUUID` is missing on pages served over plain http (not a secure context): the id
25
+ // must still be a UUID v4 — the platform silently replaces any other guest id on every
26
+ // request, and the guest cart was lost
27
+ const bytes = new Uint8Array(16);
26
28
  if (cryptoObj === null || cryptoObj === void 0 ? void 0 : cryptoObj.getRandomValues) {
27
- const bytes = cryptoObj.getRandomValues(new Uint8Array(18));
28
- let result = '';
29
+ cryptoObj.getRandomValues(bytes);
30
+ }
31
+ else {
32
+ // Last-resort fallback for environments without Web Crypto: non-cryptographic.
29
33
  for (let i = 0; i < bytes.length; i++) {
30
- result += bytes[i].toString(36).padStart(2, '0');
34
+ bytes[i] = Math.floor(Math.random() * 256);
31
35
  }
32
- return result;
33
36
  }
34
- // Last-resort fallback for environments without Web Crypto.
35
- // Non-cryptographic, but adequate when nothing better is available.
36
- return (Date.now().toString(36) +
37
- Math.random().toString(36).substring(2, 15) +
38
- Math.random().toString(36).substring(2, 15));
37
+ bytes[6] = (bytes[6] & 0x0f) | 0x40;
38
+ bytes[8] = (bytes[8] & 0x3f) | 0x80;
39
+ const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
40
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
41
+ }
42
+ /**
43
+ * The UUID v4 shape the platform requires of a guest id (it replaces any other value).
44
+ */
45
+ const _UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
46
+ /**
47
+ * Warns about a caller's guest id the platform will not keep.
48
+ * @param {string | undefined} guestId - The id passed in config or to `setGuestId`.
49
+ */
50
+ function _warnGuestId(guestId) {
51
+ if (guestId && !_UUID.test(guestId)) {
52
+ // eslint-disable-next-line no-undef, no-console
53
+ console.warn('OneEntry SDK: guestId must be a UUID v4 — the platform replaces any other value on every request, and the guest cart is lost');
54
+ }
39
55
  }
40
56
  /**
41
57
  * Returns a stable identifier for the browser environment, persisted in localStorage.
@@ -59,7 +75,9 @@ function _getPersistentBrowserId(storageKey) {
59
75
  return _persistentIds[storageKey];
60
76
  try {
61
77
  const stored = win.localStorage.getItem(storageKey);
62
- if (stored) {
78
+ // A guest id stored by an older SDK may not be a UUID: replace it, the platform ignores it
79
+ if (stored &&
80
+ (storageKey !== _GUEST_ID_STORAGE_KEY || _UUID.test(stored))) {
63
81
  _persistentIds[storageKey] = stored;
64
82
  return _persistentIds[storageKey];
65
83
  }
@@ -79,6 +97,21 @@ function _getPersistentBrowserId(storageKey) {
79
97
  }
80
98
  return _persistentIds[storageKey];
81
99
  }
100
+ /**
101
+ * Attribute types for which the API's `""` means "not set": none of them has an empty-string value.
102
+ */
103
+ const EMPTY_STRING_UNSET_TYPES = new Set([
104
+ 'image',
105
+ 'groupOfImages',
106
+ 'file',
107
+ 'timeInterval',
108
+ 'date',
109
+ 'dateTime',
110
+ 'time',
111
+ 'list',
112
+ 'radioButton',
113
+ 'entity',
114
+ ]);
82
115
  /**
83
116
  * Abstract class representing synchronization modules.
84
117
  */
@@ -104,7 +137,12 @@ class SyncModules {
104
137
  : Object.fromEntries(Object.entries(data).sort(([, a], [, b]) => a.position - b.position));
105
138
  this.state = state;
106
139
  this._url = state.url;
107
- this._nodeDeviceId = _generateId();
140
+ // Fallback device ID for Node.js and cases where localStorage is unavailable.
141
+ // Kept on the shared state, so every module of one client sends the same one:
142
+ // generated per module, the token issued by AuthProvider was refreshed from
143
+ // another module with another fingerprint and answered `400 Provided token is incorrect`.
144
+ if (!state.nodeDeviceId)
145
+ state.nodeDeviceId = _generateId();
108
146
  }
109
147
  /**
110
148
  * Resolves the guest identifier for the current request, or `undefined`.
@@ -268,9 +306,26 @@ class SyncModules {
268
306
  * numeric branch already produced.
269
307
  * 3. **Numbers** (`integer`, `float`, `real`) — cast to a JS number; anything
270
308
  * that is not a number (including an empty value) becomes `null`.
309
+ * 4. **Empty strings** of non-text types (`image`, `groupOfImages`, `file`,
310
+ * `timeInterval`, `date`, `dateTime`, `time`) — the API sends an unset value as
311
+ * `""`; it is replaced with `null`. For text types `""` is a real value and stays.
271
312
  * @param {any} attr - The attribute object to normalize in place.
313
+ * @param {boolean} [isEntityValue] - The attribute is a value of an entity (`attributeValues`): one without a `value` key is unset and gets `null`. Form fields and attribute-set schemas describe a field and get no key.
272
314
  */
273
- _normalizeAttrValue(attr) {
315
+ _normalizeAttrValue(attr, isEntityValue = false) {
316
+ // A non-object entry is not an attribute: leave it as it is instead of throwing
317
+ if (!attr || typeof attr !== 'object')
318
+ return;
319
+ // Only an attribute (it has a `type`): a locale map left by a missing translation is not one
320
+ if (isEntityValue && 'type' in attr && !('value' in attr)) {
321
+ attr.value = null;
322
+ }
323
+ // Only for entity values: form data of orders and users types these fields without `null`
324
+ if (isEntityValue &&
325
+ attr.value === '' &&
326
+ EMPTY_STRING_UNSET_TYPES.has(attr.type)) {
327
+ attr.value = null;
328
+ }
274
329
  if ((attr.type === 'image' || attr.type === 'file') &&
275
330
  Array.isArray(attr.value) &&
276
331
  attr.value.length === 1) {
@@ -283,9 +338,11 @@ class SyncModules {
283
338
  Object.keys(attr.value).length === 0) {
284
339
  attr.value = null;
285
340
  }
286
- if (attr.type === 'integer' ||
341
+ if ((attr.type === 'integer' ||
287
342
  attr.type === 'float' ||
288
- attr.type === 'real') {
343
+ attr.type === 'real') &&
344
+ // A form attribute describes a field and carries no `value` key — don't add one
345
+ 'value' in attr) {
289
346
  // Number(null) is 0 and Number('') is 0 — an empty value must stay empty.
290
347
  const isEmpty = attr.value === null || attr.value === undefined || attr.value === '';
291
348
  const numValue = isEmpty ? NaN : Number(attr.value);
@@ -303,7 +360,7 @@ class SyncModules {
303
360
  * @param {any} attr - The attribute object that may contain additionalFields.
304
361
  */
305
362
  _normalizeAdditionalFields(attr) {
306
- if (!this.state.rawData && Array.isArray(attr.additionalFields)) {
363
+ if (attr && !this.state.rawData && Array.isArray(attr.additionalFields)) {
307
364
  attr.additionalFields = Object.fromEntries(attr.additionalFields.map((field) => [field.marker, field]));
308
365
  }
309
366
  }
@@ -343,10 +400,17 @@ class SyncModules {
343
400
  _normalizeAttr(data) {
344
401
  // For regular attributes collections - pages, products, etc.
345
402
  if ('attributeValues' in data) {
403
+ // `null` (or any non-object) is not a collection: `Object.keys(null)` threw past
404
+ // isShell and took a whole list down with one record
405
+ if (!data.attributeValues ||
406
+ typeof data.attributeValues !== 'object' ||
407
+ Array.isArray(data.attributeValues)) {
408
+ return data;
409
+ }
346
410
  Object.keys(data.attributeValues).forEach((attr) => {
347
411
  const d = data.attributeValues[attr];
348
412
  this._normalizeAdditionalFields(d);
349
- this._normalizeAttrValue(d);
413
+ this._normalizeAttrValue(d, true);
350
414
  });
351
415
  return {
352
416
  ...data,
@@ -363,6 +427,9 @@ class SyncModules {
363
427
  // for forms attributes - forms attributes collections
364
428
  if ('attributes' in data) {
365
429
  const d = data.attributes;
430
+ if (!d || typeof d !== 'object') {
431
+ return data;
432
+ }
366
433
  // A form with no attributes arrives as an empty object `{}` — normalize
367
434
  // it to an empty array, the container every non-empty form uses.
368
435
  if (d &&
@@ -375,7 +442,10 @@ class SyncModules {
375
442
  this._normalizeAdditionalFields(d[attr]);
376
443
  this._normalizeAttrValue(d[attr]);
377
444
  for (const field of booleanFields) {
378
- if (field in d[attr] && d[attr][field] === null) {
445
+ if (d[attr] &&
446
+ typeof d[attr] === 'object' &&
447
+ field in d[attr] &&
448
+ d[attr][field] === null) {
379
449
  d[attr][field] = false;
380
450
  }
381
451
  }
@@ -397,7 +467,7 @@ class SyncModules {
397
467
  /**
398
468
  * Sets the access token in the state.
399
469
  * @param {string} accessToken - The access token to set.
400
- * @returns {any} The instance of SyncModules for chaining.
470
+ * @returns {this} The same module, for chaining.
401
471
  */
402
472
  setAccessToken(accessToken) {
403
473
  this.state.accessToken = accessToken;
@@ -406,7 +476,7 @@ class SyncModules {
406
476
  /**
407
477
  * Sets the refresh token in the state.
408
478
  * @param {string} refreshToken - The refresh token to set.
409
- * @returns {any} The instance of SyncModules for chaining.
479
+ * @returns {this} The same module, for chaining.
410
480
  */
411
481
  setRefreshToken(refreshToken) {
412
482
  this.state.refreshToken = refreshToken;
@@ -420,9 +490,10 @@ class SyncModules {
420
490
  * (the SDK then falls back to the localStorage-backed id in the browser, or to
421
491
  * no guest id at all on the server).
422
492
  * @param {string} guestId - The guest identifier to set (empty string clears it).
423
- * @returns {any} The instance of SyncModules for chaining.
493
+ * @returns {this} The same module, for chaining.
424
494
  */
425
495
  setGuestId(guestId) {
496
+ _warnGuestId(guestId);
426
497
  this.state.guestId = guestId || undefined;
427
498
  return this;
428
499
  }
@@ -436,7 +507,7 @@ class SyncModules {
436
507
  * browser's string (obtained there via `getDeviceMetadata`). Pass an empty
437
508
  * string to clear the override and fall back to the computed fingerprint.
438
509
  * @param {string} deviceMetadata - The metadata string to send (empty string clears the override).
439
- * @returns {any} The instance of SyncModules for chaining.
510
+ * @returns {this} The same module, for chaining.
440
511
  */
441
512
  setDeviceMetadata(deviceMetadata) {
442
513
  this.state.deviceMetadata = deviceMetadata || undefined;
@@ -477,7 +548,7 @@ class SyncModules {
477
548
  *
478
549
  * **instanceId strategy:**
479
550
  * - Browser: `_getPersistentBrowserId('oneentry_device_id')` — read from localStorage, stable across sessions.
480
- * - Node.js / no localStorage: `_nodeDeviceId` — generated at instance creation,
551
+ * - Node.js / no localStorage: `state.nodeDeviceId` — generated once per client (shared by its modules),
481
552
  * lives until the process restarts.
482
553
  *
483
554
  * In a Node.js environment (no `window`) returns a simplified object without screen/navigator.
@@ -499,7 +570,7 @@ class SyncModules {
499
570
  }
500
571
  // Access navigator through globalThis.window object to avoid direct reference
501
572
  const win = globalThis.window;
502
- const instanceId = (_a = _getPersistentBrowserId(_DEVICE_ID_STORAGE_KEY)) !== null && _a !== void 0 ? _a : this._nodeDeviceId;
573
+ const instanceId = (_a = _getPersistentBrowserId(_DEVICE_ID_STORAGE_KEY)) !== null && _a !== void 0 ? _a : this.state.nodeDeviceId;
503
574
  // Node.js environment
504
575
  if (!win) {
505
576
  return JSON.stringify({
@@ -1,21 +1,26 @@
1
1
  /**
2
2
  * @interface IConfig
3
- * @property {string} [token] - If your project is protected by a token, specify this token in this parameter.
4
- * @property {string} [guestId] - Guest identifier sent as the `x-guest-id` header on unauthenticated requests. Lets cart/wishlist/activity endpoints work for a guest. In the browser a stable id is auto-generated (localStorage) when omitted; on the server pass a per-visitor id. Can also be set later via `setGuestId`.
3
+ * @property {string} token - App token of the project. Required: `defineOneEntry` throws without it.
4
+ * @property {string} [guestId] - Guest identifier sent as the `x-guest-id` header on unauthenticated requests. Must be a UUID v4 — the platform replaces any other value with a new id on every request, so a guest cart is silently lost. Lets cart/wishlist/activity endpoints work for a guest. In the browser a stable id is auto-generated (localStorage) when omitted; on the server pass a per-visitor id. Can also be set later via `setGuestId`.
5
5
  * @property {string} [deviceMetadata] - Device-metadata string sent as the `x-device-metadata` header on POST requests and token refresh, overriding the environment-derived fingerprint. The API binds refresh tokens to this header, so server-side flows that issue tokens on behalf of a browser (e.g. an OAuth code exchange) must pass the browser's string here — otherwise the token is bound to the server's fingerprint and cannot be refreshed from the browser. Obtain the string in the browser via `getDeviceMetadata()`. Can also be set later via `setDeviceMetadata`.
6
- * @property {string} [langCode] - specify the default language to avoid specifying it in every request.
6
+ * @property {string} [langCode] - specify the default language to avoid specifying it in every request. Default: 'en_US' (an empty string counts as not set).
7
7
  * @property {boolean} [traficLimit] - Some methods use multiple queries to make it easier to work with the API. Set it to `true` to save traffic and decide for yourself what data you need: the SDK then skips its follow-up requests (full pages behind quick search results, products of page blocks), and some results change shape — e.g. `searchPage` returns short `{ id, title }` cards. Default: false.
8
8
  * @property {boolean} [rawData] - Set to true to keep an attribute's nested `additionalFields` as the
9
9
  * array the API sends, instead of the marker-keyed map the SDK builds by default. It turns off only that
10
10
  * transformation — locale unwrapping, sorting by `position`, single-file unwrapping and number casting
11
11
  * still apply. `getAdditionalFields` returns the same marker map in either mode.
12
- * @property {object} [validation] - Validation settings for API responses.
13
- * @property {boolean} [auth] - An object with authorization settings.
12
+ * @property {object} [validation] - Validation of API responses against the SDK's Zod schemas. Off by default; Zod is loaded only when it is on.
13
+ * @property {boolean} [validation.enabled] - Turns validation on. Default: false. `strictMode` and `logErrors` take effect only together with it.
14
+ * @property {boolean} [validation.strictMode] - With validation enabled, a response that does not match its schema is returned as an `IError` with `statusCode: 422` instead of the data. Default: false (mismatches are only logged). The data itself is never altered by validation.
15
+ * @property {boolean} [validation.logErrors] - With validation enabled, logs schema mismatches to the console. Default: true.
16
+ * @property {object} [auth] - An object with authorization settings.
14
17
  * @property {boolean} [auth.customAuth] - Set this flag to true if you want to configure the authorization process yourself. Set the flag to false, or do not pass it at all to have automatic authorization and token renewal.
15
- * @property {boolean} [auth.refreshToken] - Transfer the refresh token here, for example from the local storage, to resume the user's session. Otherwise, the user will need to log in every time a new session is created.
16
- * @property {boolean} [auth.providerMarker] - The marker of the provider, for example, email, google, facebook, etc. Default 'email';
17
- * @property {boolean} [auth.saveFunction] - If you want to store the token between sessions, for example in local storage, create a custom function that takes refreshToken as a parameter and executes the necessary instructions. This function will be called every time the tokens are updated.
18
+ * @property {string | null} [auth.refreshToken] - Transfer the refresh token here, for example from the local storage, to resume the user's session. Otherwise, the user will need to log in every time a new session is created. The API binds a refresh token to the device fingerprint sent in `x-device-metadata`: on the server (Node.js, SSR) every `defineOneEntry` call gets a new random fingerprint, so store `getDeviceMetadata()` next to the refresh token and pass it back as `deviceMetadata`, or the refresh is rejected with `400 Provided token is incorrect`.
19
+ * @property {string} [auth.providerMarker] - The marker of the provider used to refresh a restored session, for example, email, google, facebook, etc. Default 'email'. After `AuthProvider.auth`/`oauth`/`refresh` the marker of that call is used.
20
+ * @property {function(string): void} [auth.saveFunction] - If you want to store the token between sessions, for example in local storage, create a custom function that takes refreshToken as a parameter and executes the necessary instructions. This function will be called every time the tokens are updated.
18
21
  * @property {object} [errors] - Error handling settings.
22
+ * @property {boolean} [errors.isShell] - `true` (default): a failed request resolves to an `IError` object instead of throwing. `false`: the `IError` is thrown (a request that got no answer throws an `IError` with `statusCode: 0` and the original error in `cause`).
23
+ * @property {object} [errors.customErrors] - Handlers called with the `IError` of a failed request, keyed by HTTP status. Supported codes: 400, 401, 403, 404, 429, 500, 502, 503, 504. A handler may be async (it is awaited); an exception it throws (e.g. Next.js `redirect()`/`notFound()`) reaches the caller.
19
24
  * @example
20
25
  * ```ts
21
26
  * const saveToken = (token) => {
@@ -46,7 +51,7 @@
46
51
  * ```
47
52
  */
48
53
  interface IConfig {
49
- token?: string;
54
+ token: string;
50
55
  guestId?: string;
51
56
  deviceMetadata?: string;
52
57
  langCode?: string;
@@ -59,22 +64,22 @@ interface IConfig {
59
64
  };
60
65
  auth?: {
61
66
  customAuth?: boolean;
62
- refreshToken?: string;
67
+ refreshToken?: string | null;
63
68
  providerMarker?: string;
64
69
  saveFunction?: (refreshToken: string) => void;
65
70
  };
66
71
  errors?: {
67
72
  isShell?: boolean;
68
73
  customErrors?: {
69
- 400?: (data?: IError) => unknown;
70
- 401?: (data?: IError) => unknown;
71
- 403?: (data?: IError) => unknown;
72
- 404?: (data?: IError) => unknown;
73
- 429?: (data?: IError) => unknown;
74
- 500?: (data?: IError) => unknown;
75
- 502?: (data?: IError) => unknown;
76
- 503?: (data?: IError) => unknown;
77
- 504?: (data?: IError) => unknown;
74
+ 400?: (data: IError) => unknown;
75
+ 401?: (data: IError) => unknown;
76
+ 403?: (data: IError) => unknown;
77
+ 404?: (data: IError) => unknown;
78
+ 429?: (data: IError) => unknown;
79
+ 500?: (data: IError) => unknown;
80
+ 502?: (data: IError) => unknown;
81
+ 503?: (data: IError) => unknown;
82
+ 504?: (data: IError) => unknown;
78
83
  };
79
84
  };
80
85
  }
@@ -399,7 +404,7 @@ interface IRating {
399
404
  /**
400
405
  * @interface IError
401
406
  * @property {string} message - Error message.
402
- * @property {unknown} pageData - Page data.
407
+ * @property {unknown} [pageData] - Page data; `null` on most errors. Absent on the errors of the subscriptions module and of `/files/search` (CMS-1177).
403
408
  * @property {number} statusCode - Status code.
404
409
  * @property {string} timestamp - Timestamp.
405
410
  * @property {string} [localizeMessage] - Human-readable localized error message; populated by the SDK when response validation fails. Optional.
@@ -408,7 +413,7 @@ interface IRating {
408
413
  */
409
414
  interface IError {
410
415
  message: string;
411
- pageData: unknown;
416
+ pageData?: unknown;
412
417
  statusCode: number;
413
418
  timestamp: string;
414
419
  localizeMessage?: string;
@@ -17,7 +17,7 @@ export declare const ErrorSchema: z.ZodObject<{
17
17
  export declare const LocalizeInfoSchema: z.ZodObject<{
18
18
  title: z.ZodString;
19
19
  content: z.ZodOptional<z.ZodString>;
20
- menuTitle: z.ZodOptional<z.ZodString>;
20
+ menuTitle: z.ZodOptional<z.ZodNullable<z.ZodString>>;
21
21
  }, z.core.$strip>;
22
22
  /**
23
23
  * Attribute schema
@@ -32,7 +32,7 @@ export declare const AttributeSchema: z.ZodObject<{
32
32
  localizeInfos: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
33
33
  title: z.ZodString;
34
34
  content: z.ZodOptional<z.ZodString>;
35
- menuTitle: z.ZodOptional<z.ZodString>;
35
+ menuTitle: z.ZodOptional<z.ZodNullable<z.ZodString>>;
36
36
  }, z.core.$strip>>>;
37
37
  value: z.ZodOptional<z.ZodAny>;
38
38
  }, z.core.$strip>;
@@ -125,6 +125,6 @@ export declare function validateResponse<T>(schema: z.ZodSchema<T>, data: unknow
125
125
  * @param {z.ZodSchema<T>} schema - Zod schema to validate against
126
126
  * @param {unknown} data - Data to validate
127
127
  * @param {boolean} logErrors - Whether to log errors
128
- * @returns {T} Validated data or original data if validation fails in non-strict mode
128
+ * @returns {T} The original data, whether or not it passed validation
129
129
  */
130
130
  export declare function validateResponseSafe<T>(schema: z.ZodSchema<T>, data: unknown, logErrors?: boolean): T;
@@ -24,7 +24,8 @@ exports.ErrorSchema = zod_1.z.object({
24
24
  exports.LocalizeInfoSchema = zod_1.z.object({
25
25
  title: zod_1.z.string(),
26
26
  content: zod_1.z.string().optional(),
27
- menuTitle: zod_1.z.string().optional(),
27
+ // `string | null` as in ILocalizeInfo
28
+ menuTitle: zod_1.z.string().nullable().optional(),
28
29
  });
29
30
  /**
30
31
  * Attribute schema
@@ -211,13 +212,11 @@ function validateResponse(schema, data, options) {
211
212
  * @param {z.ZodSchema<T>} schema - Zod schema to validate against
212
213
  * @param {unknown} data - Data to validate
213
214
  * @param {boolean} logErrors - Whether to log errors
214
- * @returns {T} Validated data or original data if validation fails in non-strict mode
215
+ * @returns {T} The original data, whether or not it passed validation
215
216
  */
216
217
  function validateResponseSafe(schema, data, logErrors = false) {
217
- const result = validateResponse(schema, data, { logErrors });
218
- if (result.success) {
219
- return result.data;
220
- }
221
- // Return original data if validation fails in non-strict mode
218
+ validateResponse(schema, data, { logErrors });
219
+ // Always return the original data: Zod objects strip keys the schema does
220
+ // not describe, and the result must not depend on whether validation is on
222
221
  return data;
223
222
  }
@@ -21,7 +21,7 @@ export default class BlocksApi extends AsyncModules implements IBlocks {
21
21
  /**
22
22
  * Get blocks by parameters.
23
23
  * @handleName getBlocks
24
- * @param {BlockType} [type] - Optional block type to filter by. Available values: "product" | "error_page" | "catalog_page" | "product_preview" | "similar_products_block" | "product_block" | "frequently_ordered_block" | "trending_block" | "recently_viewed_block" | "repeat_purchase_block" | "slider_block" | "personal_recommendations_block" | "cart_complement_block" | "cart_similar_block" | "wishlist_similar_block" | "form" | "common_page" | "common_block" | "order" | "service" | "external_page" | "discount" (see BlockType). When omitted, blocks of all types are returned. Example: 'product'.
24
+ * @param {BlockType} [type] - Optional block type to filter by. Available values: "product" | "error_page" | "catalog_page" | "product_preview" | "similar_products_block" | "product_block" | "frequently_ordered_block" | "trending_block" | "recently_viewed_block" | "repeat_purchase_block" | "slider_block" | "personal_recommendations_block" | "cart_complement_block" | "cart_similar_block" | "wishlist_similar_block" | "form" | "common_page" | "common_block" | "order" | "service" | "external_page" | "discount" (see BlockType). When omitted, blocks of all types are returned. A type no block has (e.g. "product", which is a product type, not a block type) gives an empty list, not an error. Example: 'product_block'.
25
25
  * @param {string} [langCode] - Language code. Default: "en_US".
26
26
  * @param {number} [offset] - Number of records to skip. Default: 0.
27
27
  * @param {number} [limit] - Maximum number of records to return. Default: 30.
@@ -44,21 +44,26 @@ export default class BlocksApi extends AsyncModules implements IBlocks {
44
44
  */
45
45
  getBlockByMarker(marker: string, langCode?: string, offset?: number, limit?: number): Promise<IBlockEntity | IError>;
46
46
  /**
47
- * Enrich a single block in place.
48
- *
49
- * Lifts product display settings from `customSettings.productConfig` to
50
- * numeric top-level fields, strips internal-only fields, and — when
51
- * `loadProducts` is true — fetches the related products for
52
- * `similar_products_block` / `product_block` blocks. Shared by `getBlocks`
53
- * (array) and `getBlockByMarker` (single block). Mutates `block` in place.
54
- * @param {any} block - Normalized block to enrich (mutated in place).
55
- * @param {string} langCode - Language code passed to product sub-requests.
56
- * @param {number} offset - Pagination offset for product sub-requests.
57
- * @param {number} limit - Pagination limit for product sub-requests.
58
- * @param {boolean} loadProducts - Whether to fetch related products.
59
- * @returns {Promise<void>} Resolves when enrichment (incl. sub-requests) is done.
47
+ * Lifts the product display settings of a block to top-level fields and drops internal ones.
48
+ * @param {any} block - A block as the API sent it.
49
+ * @description `customSettings.productConfig` holds `countElementsPerRow` and `quantity`
50
+ * as strings; they become numbers on the block. `customSettings`, `attributeSetIdentifier`
51
+ * and `productPageUrls` are internal and removed — in traffic-saving mode as well, which
52
+ * used to return them as they came; the set marker was misspelt (`attributesSetIdentifier`)
53
+ * and stayed in every block.
60
54
  */
61
- private _enrichBlock;
55
+ private _liftBlockSettings;
56
+ /**
57
+ * Attaches the products of a product or similar-products block.
58
+ * @param {any} block - A normalized block.
59
+ * @param {string} langCode - Language of the products.
60
+ * @param {number} [offset] - Products to skip.
61
+ * @param {number} [limit] - Products to return.
62
+ * @description A failed sub-request leaves an empty value of the declared type —
63
+ * `{ items: [], total: 0 }` for `similarProducts`, `[]` for `products` — instead of
64
+ * the error object or an array where a container is declared.
65
+ */
66
+ private _loadBlockProducts;
62
67
  /**
63
68
  * Get similar products by block marker.
64
69
  * @handleName getSimilarProducts
@@ -71,7 +76,6 @@ export default class BlocksApi extends AsyncModules implements IBlocks {
71
76
  * @param {number} [productId] - Optional product id to find similar products for.
72
77
  * @returns {Promise<IProductsResponse | IError>} Returns the total count and an array of product items in object by specified block marker.
73
78
  * @throws {IError} When isShell=false and an error occurs during the fetch
74
- * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/getSimilarProducts getSimilarProducts} documentation.
75
79
  */
76
80
  private getSimilarProducts;
77
81
  /**
@@ -85,7 +89,6 @@ export default class BlocksApi extends AsyncModules implements IBlocks {
85
89
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/#Fixing-the-price-signPrice Fixing the price} documentation.
86
90
  * @returns {Promise<IProductsEntity[] | IError>} Return array of BlocksEntity object.
87
91
  * @throws {IError} When isShell=false and an error occurs during the fetch
88
- * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/getProductsByBlockMarker getProductsByBlockMarker} documentation.
89
92
  */
90
93
  private getProductsByBlockMarker;
91
94
  /**