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.
- package/README.md +12 -5
- package/changelog.md +116 -0
- package/dist/admins/adminsApi.js +2 -9
- package/dist/admins/adminsInterfaces.d.ts +5 -5
- package/dist/admins/adminsSchemas.d.ts +4 -4
- package/dist/admins/adminsSchemas.js +2 -2
- package/dist/attribute-sets/attributeSetsApi.d.ts +1 -1
- package/dist/attribute-sets/attributeSetsApi.js +4 -4
- package/dist/attribute-sets/attributeSetsInterfaces.d.ts +65 -14
- package/dist/attribute-sets/attributeSetsSchemas.d.ts +8 -6
- package/dist/attribute-sets/attributeSetsSchemas.js +6 -9
- package/dist/auth-provider/authProviderApi.d.ts +4 -4
- package/dist/auth-provider/authProviderApi.js +90 -23
- package/dist/auth-provider/authProviderSchemas.d.ts +1 -0
- package/dist/auth-provider/authProviderSchemas.js +1 -0
- package/dist/auth-provider/authProvidersInterfaces.d.ts +8 -6
- package/dist/base/asyncModules.d.ts +62 -1
- package/dist/base/asyncModules.js +219 -37
- package/dist/base/stateModule.d.ts +2 -0
- package/dist/base/stateModule.js +22 -12
- package/dist/base/syncModules.d.ts +18 -10
- package/dist/base/syncModules.js +100 -29
- package/dist/base/utils.d.ts +26 -21
- package/dist/base/validation.d.ts +3 -3
- package/dist/base/validation.js +6 -7
- package/dist/blocks/blocksApi.d.ts +20 -17
- package/dist/blocks/blocksApi.js +82 -64
- package/dist/blocks/blocksInterfaces.d.ts +8 -8
- package/dist/discounts/discountsApi.d.ts +9 -7
- package/dist/discounts/discountsApi.js +16 -13
- package/dist/discounts/discountsInterfaces.d.ts +14 -10
- package/dist/events/eventsApi.d.ts +3 -3
- package/dist/events/eventsApi.js +3 -3
- package/dist/events/eventsInterfaces.d.ts +10 -14
- package/dist/file-uploading/fileUploadingApi.d.ts +4 -4
- package/dist/file-uploading/fileUploadingApi.js +13 -5
- package/dist/file-uploading/fileUploadingInterfaces.d.ts +5 -6
- package/dist/filters/filtersApi.js +2 -2
- package/dist/forms/formsApi.js +2 -2
- package/dist/forms/formsInterfaces.d.ts +1 -3
- package/dist/forms/formsSchemas.d.ts +3 -6
- package/dist/forms/formsSchemas.js +2 -4
- package/dist/forms-data/formsDataApi.d.ts +16 -0
- package/dist/forms-data/formsDataApi.js +32 -5
- package/dist/forms-data/formsDataInterfaces.d.ts +17 -13
- package/dist/general-types/generalTypesInterfaces.d.ts +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.js +50 -7
- package/dist/integration-collections/integrationCollectionsApi.d.ts +15 -4
- package/dist/integration-collections/integrationCollectionsApi.js +41 -14
- package/dist/integration-collections/integrationCollectionsInterfaces.d.ts +8 -9
- package/dist/integration-collections/integrationCollectionsSchemas.d.ts +0 -2
- package/dist/integration-collections/integrationCollectionsSchemas.js +0 -1
- package/dist/menus/menusApi.js +1 -1
- package/dist/orders/ordersApi.d.ts +1 -13
- package/dist/orders/ordersApi.js +21 -42
- package/dist/orders/ordersInterfaces.d.ts +21 -14
- package/dist/pages/pagesApi.d.ts +6 -5
- package/dist/pages/pagesApi.js +44 -31
- package/dist/pages/pagesInterfaces.d.ts +18 -15
- package/dist/pages/pagesSchemas.d.ts +0 -3
- package/dist/pages/pagesSchemas.js +0 -1
- package/dist/payments/paymentsApi.d.ts +10 -11
- package/dist/payments/paymentsApi.js +22 -18
- package/dist/payments/paymentsInterfaces.d.ts +12 -14
- package/dist/payments/paymentsSchemas.d.ts +21 -20
- package/dist/payments/paymentsSchemas.js +5 -8
- package/dist/product-statuses/productStatusesApi.d.ts +1 -1
- package/dist/product-statuses/productStatusesApi.js +3 -3
- package/dist/product-statuses/productStatusesInterfaces.d.ts +1 -4
- package/dist/products/productsApi.d.ts +38 -58
- package/dist/products/productsApi.js +59 -72
- package/dist/products/productsInterfaces.d.ts +48 -85
- package/dist/search/searchApi.d.ts +1 -1
- package/dist/search/searchApi.js +4 -3
- package/dist/sitemap/sitemapInterfaces.d.ts +10 -6
- package/dist/subscriptions/subscriptionsApi.d.ts +1 -1
- package/dist/subscriptions/subscriptionsApi.js +1 -1
- package/dist/subscriptions/subscriptionsInterfaces.d.ts +1 -1
- package/dist/system/systemApi.d.ts +2 -0
- package/dist/system/systemApi.js +2 -0
- package/dist/system/systemInterfaces.d.ts +2 -0
- package/dist/templates/templatesApi.d.ts +2 -2
- package/dist/templates/templatesApi.js +12 -11
- package/dist/templates/templatesInterfaces.d.ts +2 -2
- package/dist/templates-preview/templatesPreviewApi.js +2 -2
- package/dist/templates-preview/templatesPreviewInterfaces.d.ts +23 -13
- package/dist/templates-preview/templatesPreviewSchemas.d.ts +7 -0
- package/dist/templates-preview/templatesPreviewSchemas.js +2 -0
- package/dist/user-groups/userGroupsApi.js +5 -5
- package/dist/user-groups/userGroupsSchemas.d.ts +4 -4
- package/dist/users/usersApi.d.ts +1 -1
- package/dist/users/usersApi.js +28 -15
- package/dist/users/usersInterfaces.d.ts +2 -9
- package/dist/web-socket/lazySocket.d.ts +6 -5
- package/dist/web-socket/lazySocket.js +212 -15
- package/dist/web-socket/wsApi.d.ts +7 -4
- package/dist/web-socket/wsApi.js +49 -12
- package/dist/web-socket/wsInterfaces.d.ts +41 -4
- package/esm/admins/adminsApi.js +2 -9
- package/esm/admins/adminsInterfaces.d.ts +5 -5
- package/esm/admins/adminsSchemas.d.ts +4 -4
- package/esm/admins/adminsSchemas.js +2 -2
- package/esm/attribute-sets/attributeSetsApi.d.ts +1 -1
- package/esm/attribute-sets/attributeSetsApi.js +4 -4
- package/esm/attribute-sets/attributeSetsInterfaces.d.ts +65 -14
- package/esm/attribute-sets/attributeSetsSchemas.d.ts +8 -6
- package/esm/attribute-sets/attributeSetsSchemas.js +6 -9
- package/esm/auth-provider/authProviderApi.d.ts +4 -4
- package/esm/auth-provider/authProviderApi.js +90 -23
- package/esm/auth-provider/authProviderSchemas.d.ts +1 -0
- package/esm/auth-provider/authProviderSchemas.js +1 -0
- package/esm/auth-provider/authProvidersInterfaces.d.ts +8 -6
- package/esm/base/asyncModules.d.ts +62 -1
- package/esm/base/asyncModules.js +219 -37
- package/esm/base/stateModule.d.ts +2 -0
- package/esm/base/stateModule.js +22 -12
- package/esm/base/syncModules.d.ts +18 -10
- package/esm/base/syncModules.js +99 -29
- package/esm/base/utils.d.ts +26 -21
- package/esm/base/validation.d.ts +3 -3
- package/esm/base/validation.js +6 -7
- package/esm/blocks/blocksApi.d.ts +20 -17
- package/esm/blocks/blocksApi.js +82 -64
- package/esm/blocks/blocksInterfaces.d.ts +8 -8
- package/esm/discounts/discountsApi.d.ts +9 -7
- package/esm/discounts/discountsApi.js +16 -13
- package/esm/discounts/discountsInterfaces.d.ts +14 -10
- package/esm/events/eventsApi.d.ts +3 -3
- package/esm/events/eventsApi.js +3 -3
- package/esm/events/eventsInterfaces.d.ts +10 -14
- package/esm/file-uploading/fileUploadingApi.d.ts +4 -4
- package/esm/file-uploading/fileUploadingApi.js +13 -5
- package/esm/file-uploading/fileUploadingInterfaces.d.ts +5 -6
- package/esm/filters/filtersApi.js +2 -2
- package/esm/forms/formsApi.js +2 -2
- package/esm/forms/formsInterfaces.d.ts +1 -3
- package/esm/forms/formsSchemas.d.ts +3 -6
- package/esm/forms/formsSchemas.js +2 -4
- package/esm/forms-data/formsDataApi.d.ts +16 -0
- package/esm/forms-data/formsDataApi.js +32 -5
- package/esm/forms-data/formsDataInterfaces.d.ts +17 -13
- package/esm/general-types/generalTypesInterfaces.d.ts +1 -1
- package/esm/index.d.ts +7 -6
- package/esm/index.js +50 -7
- package/esm/integration-collections/integrationCollectionsApi.d.ts +15 -4
- package/esm/integration-collections/integrationCollectionsApi.js +41 -14
- package/esm/integration-collections/integrationCollectionsInterfaces.d.ts +8 -9
- package/esm/integration-collections/integrationCollectionsSchemas.d.ts +0 -2
- package/esm/integration-collections/integrationCollectionsSchemas.js +0 -1
- package/esm/menus/menusApi.js +1 -1
- package/esm/orders/ordersApi.d.ts +1 -13
- package/esm/orders/ordersApi.js +21 -42
- package/esm/orders/ordersInterfaces.d.ts +21 -14
- package/esm/pages/pagesApi.d.ts +6 -5
- package/esm/pages/pagesApi.js +44 -31
- package/esm/pages/pagesInterfaces.d.ts +18 -15
- package/esm/pages/pagesSchemas.d.ts +0 -3
- package/esm/pages/pagesSchemas.js +0 -1
- package/esm/payments/paymentsApi.d.ts +10 -11
- package/esm/payments/paymentsApi.js +22 -18
- package/esm/payments/paymentsInterfaces.d.ts +12 -14
- package/esm/payments/paymentsSchemas.d.ts +21 -20
- package/esm/payments/paymentsSchemas.js +5 -8
- package/esm/product-statuses/productStatusesApi.d.ts +1 -1
- package/esm/product-statuses/productStatusesApi.js +3 -3
- package/esm/product-statuses/productStatusesInterfaces.d.ts +1 -4
- package/esm/products/productsApi.d.ts +38 -58
- package/esm/products/productsApi.js +59 -72
- package/esm/products/productsInterfaces.d.ts +48 -85
- package/esm/search/searchApi.d.ts +1 -1
- package/esm/search/searchApi.js +4 -3
- package/esm/sitemap/sitemapInterfaces.d.ts +10 -6
- package/esm/subscriptions/subscriptionsApi.d.ts +1 -1
- package/esm/subscriptions/subscriptionsApi.js +1 -1
- package/esm/subscriptions/subscriptionsInterfaces.d.ts +1 -1
- package/esm/system/systemApi.d.ts +2 -0
- package/esm/system/systemApi.js +2 -0
- package/esm/system/systemInterfaces.d.ts +2 -0
- package/esm/templates/templatesApi.d.ts +2 -2
- package/esm/templates/templatesApi.js +11 -10
- package/esm/templates/templatesInterfaces.d.ts +2 -2
- package/esm/templates-preview/templatesPreviewApi.js +2 -2
- package/esm/templates-preview/templatesPreviewInterfaces.d.ts +23 -13
- package/esm/templates-preview/templatesPreviewSchemas.d.ts +7 -0
- package/esm/templates-preview/templatesPreviewSchemas.js +2 -0
- package/esm/user-groups/userGroupsApi.js +5 -5
- package/esm/user-groups/userGroupsSchemas.d.ts +4 -4
- package/esm/users/usersApi.d.ts +1 -1
- package/esm/users/usersApi.js +28 -15
- package/esm/users/usersInterfaces.d.ts +2 -9
- package/esm/web-socket/lazySocket.d.ts +6 -5
- package/esm/web-socket/lazySocket.js +212 -15
- package/esm/web-socket/wsApi.d.ts +7 -4
- package/esm/web-socket/wsApi.js +49 -12
- package/esm/web-socket/wsInterfaces.d.ts +41 -4
- package/package.json +2 -2
package/dist/base/syncModules.js
CHANGED
|
@@ -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
|
|
15
|
-
*
|
|
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
|
-
|
|
28
|
-
|
|
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
|
-
|
|
34
|
+
bytes[i] = Math.floor(Math.random() * 256);
|
|
31
35
|
}
|
|
32
|
-
return result;
|
|
33
36
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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: `
|
|
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.
|
|
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({
|
package/dist/base/utils.d.ts
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @interface IConfig
|
|
3
|
-
* @property {string}
|
|
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
|
|
13
|
-
* @property {boolean} [
|
|
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 {
|
|
16
|
-
* @property {
|
|
17
|
-
* @property {
|
|
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
|
|
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
|
|
70
|
-
401?: (data
|
|
71
|
-
403?: (data
|
|
72
|
-
404?: (data
|
|
73
|
-
429?: (data
|
|
74
|
-
500?: (data
|
|
75
|
-
502?: (data
|
|
76
|
-
503?: (data
|
|
77
|
-
504?: (data
|
|
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
|
|
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}
|
|
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;
|
package/dist/base/validation.js
CHANGED
|
@@ -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
|
-
|
|
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}
|
|
215
|
+
* @returns {T} The original data, whether or not it passed validation
|
|
215
216
|
*/
|
|
216
217
|
function validateResponseSafe(schema, data, logErrors = false) {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
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: '
|
|
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
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* `
|
|
52
|
-
*
|
|
53
|
-
*
|
|
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
|
|
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
|
/**
|