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/esm/base/syncModules.js
CHANGED
|
@@ -9,31 +9,46 @@ const _persistentIds = {};
|
|
|
9
9
|
*
|
|
10
10
|
* Prefers a cryptographically secure source (Web Crypto, exposed as
|
|
11
11
|
* `globalThis.crypto` in browsers and Node.js >= 18): `randomUUID()` when
|
|
12
|
-
* available, otherwise
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* The result contains no special characters, so it is safe to use both in
|
|
16
|
-
* localStorage and in HTTP headers.
|
|
17
|
-
* @returns {string} A freshly generated identifier.
|
|
12
|
+
* available, otherwise a UUID v4 built from `getRandomValues`, and from
|
|
13
|
+
* `Math.random()` only when no CSPRNG exists (e.g. very old Node).
|
|
14
|
+
* @returns {string} A freshly generated UUID v4.
|
|
18
15
|
*/
|
|
19
16
|
function _generateId() {
|
|
20
17
|
const cryptoObj = typeof globalThis !== 'undefined' ? globalThis.crypto : undefined;
|
|
21
18
|
if (cryptoObj === null || cryptoObj === void 0 ? void 0 : cryptoObj.randomUUID) {
|
|
22
19
|
return cryptoObj.randomUUID();
|
|
23
20
|
}
|
|
21
|
+
// `randomUUID` is missing on pages served over plain http (not a secure context): the id
|
|
22
|
+
// must still be a UUID v4 — the platform silently replaces any other guest id on every
|
|
23
|
+
// request, and the guest cart was lost
|
|
24
|
+
const bytes = new Uint8Array(16);
|
|
24
25
|
if (cryptoObj === null || cryptoObj === void 0 ? void 0 : cryptoObj.getRandomValues) {
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
cryptoObj.getRandomValues(bytes);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
// Last-resort fallback for environments without Web Crypto: non-cryptographic.
|
|
27
30
|
for (let i = 0; i < bytes.length; i++) {
|
|
28
|
-
|
|
31
|
+
bytes[i] = Math.floor(Math.random() * 256);
|
|
29
32
|
}
|
|
30
|
-
return result;
|
|
31
33
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
|
35
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
36
|
+
const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
|
|
37
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The UUID v4 shape the platform requires of a guest id (it replaces any other value).
|
|
41
|
+
*/
|
|
42
|
+
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;
|
|
43
|
+
/**
|
|
44
|
+
* Warns about a caller's guest id the platform will not keep.
|
|
45
|
+
* @param {string | undefined} guestId - The id passed in config or to `setGuestId`.
|
|
46
|
+
*/
|
|
47
|
+
export function _warnGuestId(guestId) {
|
|
48
|
+
if (guestId && !_UUID.test(guestId)) {
|
|
49
|
+
// eslint-disable-next-line no-undef, no-console
|
|
50
|
+
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');
|
|
51
|
+
}
|
|
37
52
|
}
|
|
38
53
|
/**
|
|
39
54
|
* Returns a stable identifier for the browser environment, persisted in localStorage.
|
|
@@ -57,7 +72,9 @@ function _getPersistentBrowserId(storageKey) {
|
|
|
57
72
|
return _persistentIds[storageKey];
|
|
58
73
|
try {
|
|
59
74
|
const stored = win.localStorage.getItem(storageKey);
|
|
60
|
-
|
|
75
|
+
// A guest id stored by an older SDK may not be a UUID: replace it, the platform ignores it
|
|
76
|
+
if (stored &&
|
|
77
|
+
(storageKey !== _GUEST_ID_STORAGE_KEY || _UUID.test(stored))) {
|
|
61
78
|
_persistentIds[storageKey] = stored;
|
|
62
79
|
return _persistentIds[storageKey];
|
|
63
80
|
}
|
|
@@ -77,6 +94,21 @@ function _getPersistentBrowserId(storageKey) {
|
|
|
77
94
|
}
|
|
78
95
|
return _persistentIds[storageKey];
|
|
79
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Attribute types for which the API's `""` means "not set": none of them has an empty-string value.
|
|
99
|
+
*/
|
|
100
|
+
const EMPTY_STRING_UNSET_TYPES = new Set([
|
|
101
|
+
'image',
|
|
102
|
+
'groupOfImages',
|
|
103
|
+
'file',
|
|
104
|
+
'timeInterval',
|
|
105
|
+
'date',
|
|
106
|
+
'dateTime',
|
|
107
|
+
'time',
|
|
108
|
+
'list',
|
|
109
|
+
'radioButton',
|
|
110
|
+
'entity',
|
|
111
|
+
]);
|
|
80
112
|
/**
|
|
81
113
|
* Abstract class representing synchronization modules.
|
|
82
114
|
*/
|
|
@@ -102,7 +134,12 @@ export default class SyncModules {
|
|
|
102
134
|
: Object.fromEntries(Object.entries(data).sort(([, a], [, b]) => a.position - b.position));
|
|
103
135
|
this.state = state;
|
|
104
136
|
this._url = state.url;
|
|
105
|
-
|
|
137
|
+
// Fallback device ID for Node.js and cases where localStorage is unavailable.
|
|
138
|
+
// Kept on the shared state, so every module of one client sends the same one:
|
|
139
|
+
// generated per module, the token issued by AuthProvider was refreshed from
|
|
140
|
+
// another module with another fingerprint and answered `400 Provided token is incorrect`.
|
|
141
|
+
if (!state.nodeDeviceId)
|
|
142
|
+
state.nodeDeviceId = _generateId();
|
|
106
143
|
}
|
|
107
144
|
/**
|
|
108
145
|
* Resolves the guest identifier for the current request, or `undefined`.
|
|
@@ -266,9 +303,26 @@ export default class SyncModules {
|
|
|
266
303
|
* numeric branch already produced.
|
|
267
304
|
* 3. **Numbers** (`integer`, `float`, `real`) — cast to a JS number; anything
|
|
268
305
|
* that is not a number (including an empty value) becomes `null`.
|
|
306
|
+
* 4. **Empty strings** of non-text types (`image`, `groupOfImages`, `file`,
|
|
307
|
+
* `timeInterval`, `date`, `dateTime`, `time`) — the API sends an unset value as
|
|
308
|
+
* `""`; it is replaced with `null`. For text types `""` is a real value and stays.
|
|
269
309
|
* @param {any} attr - The attribute object to normalize in place.
|
|
310
|
+
* @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.
|
|
270
311
|
*/
|
|
271
|
-
_normalizeAttrValue(attr) {
|
|
312
|
+
_normalizeAttrValue(attr, isEntityValue = false) {
|
|
313
|
+
// A non-object entry is not an attribute: leave it as it is instead of throwing
|
|
314
|
+
if (!attr || typeof attr !== 'object')
|
|
315
|
+
return;
|
|
316
|
+
// Only an attribute (it has a `type`): a locale map left by a missing translation is not one
|
|
317
|
+
if (isEntityValue && 'type' in attr && !('value' in attr)) {
|
|
318
|
+
attr.value = null;
|
|
319
|
+
}
|
|
320
|
+
// Only for entity values: form data of orders and users types these fields without `null`
|
|
321
|
+
if (isEntityValue &&
|
|
322
|
+
attr.value === '' &&
|
|
323
|
+
EMPTY_STRING_UNSET_TYPES.has(attr.type)) {
|
|
324
|
+
attr.value = null;
|
|
325
|
+
}
|
|
272
326
|
if ((attr.type === 'image' || attr.type === 'file') &&
|
|
273
327
|
Array.isArray(attr.value) &&
|
|
274
328
|
attr.value.length === 1) {
|
|
@@ -281,9 +335,11 @@ export default class SyncModules {
|
|
|
281
335
|
Object.keys(attr.value).length === 0) {
|
|
282
336
|
attr.value = null;
|
|
283
337
|
}
|
|
284
|
-
if (attr.type === 'integer' ||
|
|
338
|
+
if ((attr.type === 'integer' ||
|
|
285
339
|
attr.type === 'float' ||
|
|
286
|
-
attr.type === 'real')
|
|
340
|
+
attr.type === 'real') &&
|
|
341
|
+
// A form attribute describes a field and carries no `value` key — don't add one
|
|
342
|
+
'value' in attr) {
|
|
287
343
|
// Number(null) is 0 and Number('') is 0 — an empty value must stay empty.
|
|
288
344
|
const isEmpty = attr.value === null || attr.value === undefined || attr.value === '';
|
|
289
345
|
const numValue = isEmpty ? NaN : Number(attr.value);
|
|
@@ -301,7 +357,7 @@ export default class SyncModules {
|
|
|
301
357
|
* @param {any} attr - The attribute object that may contain additionalFields.
|
|
302
358
|
*/
|
|
303
359
|
_normalizeAdditionalFields(attr) {
|
|
304
|
-
if (!this.state.rawData && Array.isArray(attr.additionalFields)) {
|
|
360
|
+
if (attr && !this.state.rawData && Array.isArray(attr.additionalFields)) {
|
|
305
361
|
attr.additionalFields = Object.fromEntries(attr.additionalFields.map((field) => [field.marker, field]));
|
|
306
362
|
}
|
|
307
363
|
}
|
|
@@ -341,10 +397,17 @@ export default class SyncModules {
|
|
|
341
397
|
_normalizeAttr(data) {
|
|
342
398
|
// For regular attributes collections - pages, products, etc.
|
|
343
399
|
if ('attributeValues' in data) {
|
|
400
|
+
// `null` (or any non-object) is not a collection: `Object.keys(null)` threw past
|
|
401
|
+
// isShell and took a whole list down with one record
|
|
402
|
+
if (!data.attributeValues ||
|
|
403
|
+
typeof data.attributeValues !== 'object' ||
|
|
404
|
+
Array.isArray(data.attributeValues)) {
|
|
405
|
+
return data;
|
|
406
|
+
}
|
|
344
407
|
Object.keys(data.attributeValues).forEach((attr) => {
|
|
345
408
|
const d = data.attributeValues[attr];
|
|
346
409
|
this._normalizeAdditionalFields(d);
|
|
347
|
-
this._normalizeAttrValue(d);
|
|
410
|
+
this._normalizeAttrValue(d, true);
|
|
348
411
|
});
|
|
349
412
|
return {
|
|
350
413
|
...data,
|
|
@@ -361,6 +424,9 @@ export default class SyncModules {
|
|
|
361
424
|
// for forms attributes - forms attributes collections
|
|
362
425
|
if ('attributes' in data) {
|
|
363
426
|
const d = data.attributes;
|
|
427
|
+
if (!d || typeof d !== 'object') {
|
|
428
|
+
return data;
|
|
429
|
+
}
|
|
364
430
|
// A form with no attributes arrives as an empty object `{}` — normalize
|
|
365
431
|
// it to an empty array, the container every non-empty form uses.
|
|
366
432
|
if (d &&
|
|
@@ -373,7 +439,10 @@ export default class SyncModules {
|
|
|
373
439
|
this._normalizeAdditionalFields(d[attr]);
|
|
374
440
|
this._normalizeAttrValue(d[attr]);
|
|
375
441
|
for (const field of booleanFields) {
|
|
376
|
-
if (
|
|
442
|
+
if (d[attr] &&
|
|
443
|
+
typeof d[attr] === 'object' &&
|
|
444
|
+
field in d[attr] &&
|
|
445
|
+
d[attr][field] === null) {
|
|
377
446
|
d[attr][field] = false;
|
|
378
447
|
}
|
|
379
448
|
}
|
|
@@ -395,7 +464,7 @@ export default class SyncModules {
|
|
|
395
464
|
/**
|
|
396
465
|
* Sets the access token in the state.
|
|
397
466
|
* @param {string} accessToken - The access token to set.
|
|
398
|
-
* @returns {
|
|
467
|
+
* @returns {this} The same module, for chaining.
|
|
399
468
|
*/
|
|
400
469
|
setAccessToken(accessToken) {
|
|
401
470
|
this.state.accessToken = accessToken;
|
|
@@ -404,7 +473,7 @@ export default class SyncModules {
|
|
|
404
473
|
/**
|
|
405
474
|
* Sets the refresh token in the state.
|
|
406
475
|
* @param {string} refreshToken - The refresh token to set.
|
|
407
|
-
* @returns {
|
|
476
|
+
* @returns {this} The same module, for chaining.
|
|
408
477
|
*/
|
|
409
478
|
setRefreshToken(refreshToken) {
|
|
410
479
|
this.state.refreshToken = refreshToken;
|
|
@@ -418,9 +487,10 @@ export default class SyncModules {
|
|
|
418
487
|
* (the SDK then falls back to the localStorage-backed id in the browser, or to
|
|
419
488
|
* no guest id at all on the server).
|
|
420
489
|
* @param {string} guestId - The guest identifier to set (empty string clears it).
|
|
421
|
-
* @returns {
|
|
490
|
+
* @returns {this} The same module, for chaining.
|
|
422
491
|
*/
|
|
423
492
|
setGuestId(guestId) {
|
|
493
|
+
_warnGuestId(guestId);
|
|
424
494
|
this.state.guestId = guestId || undefined;
|
|
425
495
|
return this;
|
|
426
496
|
}
|
|
@@ -434,7 +504,7 @@ export default class SyncModules {
|
|
|
434
504
|
* browser's string (obtained there via `getDeviceMetadata`). Pass an empty
|
|
435
505
|
* string to clear the override and fall back to the computed fingerprint.
|
|
436
506
|
* @param {string} deviceMetadata - The metadata string to send (empty string clears the override).
|
|
437
|
-
* @returns {
|
|
507
|
+
* @returns {this} The same module, for chaining.
|
|
438
508
|
*/
|
|
439
509
|
setDeviceMetadata(deviceMetadata) {
|
|
440
510
|
this.state.deviceMetadata = deviceMetadata || undefined;
|
|
@@ -475,7 +545,7 @@ export default class SyncModules {
|
|
|
475
545
|
*
|
|
476
546
|
* **instanceId strategy:**
|
|
477
547
|
* - Browser: `_getPersistentBrowserId('oneentry_device_id')` — read from localStorage, stable across sessions.
|
|
478
|
-
* - Node.js / no localStorage: `
|
|
548
|
+
* - Node.js / no localStorage: `state.nodeDeviceId` — generated once per client (shared by its modules),
|
|
479
549
|
* lives until the process restarts.
|
|
480
550
|
*
|
|
481
551
|
* In a Node.js environment (no `window`) returns a simplified object without screen/navigator.
|
|
@@ -497,7 +567,7 @@ export default class SyncModules {
|
|
|
497
567
|
}
|
|
498
568
|
// Access navigator through globalThis.window object to avoid direct reference
|
|
499
569
|
const win = globalThis.window;
|
|
500
|
-
const instanceId = (_a = _getPersistentBrowserId(_DEVICE_ID_STORAGE_KEY)) !== null && _a !== void 0 ? _a : this.
|
|
570
|
+
const instanceId = (_a = _getPersistentBrowserId(_DEVICE_ID_STORAGE_KEY)) !== null && _a !== void 0 ? _a : this.state.nodeDeviceId;
|
|
501
571
|
// Node.js environment
|
|
502
572
|
if (!win) {
|
|
503
573
|
return JSON.stringify({
|
package/esm/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;
|
package/esm/base/validation.d.ts
CHANGED
|
@@ -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/esm/base/validation.js
CHANGED
|
@@ -18,7 +18,8 @@ export const ErrorSchema = z.object({
|
|
|
18
18
|
export const LocalizeInfoSchema = z.object({
|
|
19
19
|
title: z.string(),
|
|
20
20
|
content: z.string().optional(),
|
|
21
|
-
|
|
21
|
+
// `string | null` as in ILocalizeInfo
|
|
22
|
+
menuTitle: z.string().nullable().optional(),
|
|
22
23
|
});
|
|
23
24
|
/**
|
|
24
25
|
* Attribute schema
|
|
@@ -205,13 +206,11 @@ export function validateResponse(schema, data, options) {
|
|
|
205
206
|
* @param {z.ZodSchema<T>} schema - Zod schema to validate against
|
|
206
207
|
* @param {unknown} data - Data to validate
|
|
207
208
|
* @param {boolean} logErrors - Whether to log errors
|
|
208
|
-
* @returns {T}
|
|
209
|
+
* @returns {T} The original data, whether or not it passed validation
|
|
209
210
|
*/
|
|
210
211
|
export function validateResponseSafe(schema, data, logErrors = false) {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
215
|
-
// Return original data if validation fails in non-strict mode
|
|
212
|
+
validateResponse(schema, data, { logErrors });
|
|
213
|
+
// Always return the original data: Zod objects strip keys the schema does
|
|
214
|
+
// not describe, and the result must not depend on whether validation is on
|
|
216
215
|
return data;
|
|
217
216
|
}
|
|
@@ -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
|
/**
|