oneentry 1.0.176 → 1.0.178
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +27 -1
- package/dist/forms-data/formsDataApi.js +119 -68
- 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 +8 -6
- package/dist/pages/pagesApi.js +48 -33
- package/dist/pages/pagesInterfaces.d.ts +20 -16
- 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 +50 -64
- package/dist/products/productsApi.js +79 -80
- package/dist/products/productsInterfaces.d.ts +59 -90
- package/dist/search/searchApi.d.ts +3 -2
- package/dist/search/searchApi.js +7 -4
- package/dist/search/searchInterfaces.d.ts +2 -1
- 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 +27 -1
- package/esm/forms-data/formsDataApi.js +119 -68
- 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 +8 -6
- package/esm/pages/pagesApi.js +48 -33
- package/esm/pages/pagesInterfaces.d.ts +20 -16
- 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 +50 -64
- package/esm/products/productsApi.js +79 -80
- package/esm/products/productsInterfaces.d.ts +59 -90
- package/esm/search/searchApi.d.ts +3 -2
- package/esm/search/searchApi.js +7 -4
- package/esm/search/searchInterfaces.d.ts +2 -1
- 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
|
@@ -37,6 +37,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
const syncModules_1 = __importDefault(require("./syncModules"));
|
|
40
|
+
/**
|
|
41
|
+
* A refresh that does not answer within this time (ms) counts as failed.
|
|
42
|
+
*/
|
|
43
|
+
const REFRESH_TIMEOUT_MS = 30000;
|
|
40
44
|
/**
|
|
41
45
|
* Abstract class AsyncModules extends SyncModules to provide asynchronous HTTP request functionalities.
|
|
42
46
|
* @description Abstract class AsyncModules extends SyncModules to provide asynchronous HTTP request functionalities.
|
|
@@ -49,6 +53,14 @@ class AsyncModules extends syncModules_1.default {
|
|
|
49
53
|
*/
|
|
50
54
|
constructor(state) {
|
|
51
55
|
super(state);
|
|
56
|
+
/**
|
|
57
|
+
* Set on the view `_asSignIn` returns: the request is a sign-in or sign-up.
|
|
58
|
+
*/
|
|
59
|
+
this._signIn = false;
|
|
60
|
+
/**
|
|
61
|
+
* Set on the view `_asSubRequest` returns.
|
|
62
|
+
*/
|
|
63
|
+
this._subRequest = false;
|
|
52
64
|
this.state = state;
|
|
53
65
|
this._url = this.state.url;
|
|
54
66
|
}
|
|
@@ -59,7 +71,7 @@ class AsyncModules extends syncModules_1.default {
|
|
|
59
71
|
* body — and a caught exception — instead of throwing, so a failed request
|
|
60
72
|
* is indistinguishable from a successful one by control flow alone.
|
|
61
73
|
* @param {unknown} value - Value returned by a request.
|
|
62
|
-
* @returns {boolean} True when the value is an API error (statusCode >= 400) or a thrown error object.
|
|
74
|
+
* @returns {boolean} True when the value is an API error (statusCode >= 400), the shell error of a request that got no answer (statusCode 0) or a thrown error object.
|
|
63
75
|
* @description Recognizes both the OneEntry error body and errors caught by browserResponse (e.g. a network failure).
|
|
64
76
|
*/
|
|
65
77
|
_isErrorResponse(value) {
|
|
@@ -70,7 +82,10 @@ class AsyncModules extends syncModules_1.default {
|
|
|
70
82
|
typeof value === 'object' &&
|
|
71
83
|
'statusCode' in value &&
|
|
72
84
|
typeof value.statusCode === 'number' &&
|
|
73
|
-
|
|
85
|
+
// `0` is the shell error of a request that never got an answer (`_toShellError`):
|
|
86
|
+
// a dropped connection used to make `_fetchBoolean` report success
|
|
87
|
+
(value.statusCode >= 400 ||
|
|
88
|
+
(value.statusCode === 0 && 'pageData' in value)));
|
|
74
89
|
}
|
|
75
90
|
/**
|
|
76
91
|
* Validates API response against a Zod schema (optional)
|
|
@@ -110,13 +125,82 @@ class AsyncModules extends syncModules_1.default {
|
|
|
110
125
|
validationErrors: result.error.issues,
|
|
111
126
|
};
|
|
112
127
|
}
|
|
113
|
-
|
|
128
|
+
// Return the original data: the parsed copy lacks keys the schema does not describe
|
|
129
|
+
return data;
|
|
114
130
|
}
|
|
115
131
|
else {
|
|
116
132
|
// Non-strict mode: log errors but return original data
|
|
117
133
|
return validateResponseSafe(schema, data, this.state.validationLogErrors);
|
|
118
134
|
}
|
|
119
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* A view of this module for sign-in and sign-up requests.
|
|
138
|
+
* @returns {this} An object that shares the module's state but sends the request without the current session.
|
|
139
|
+
* @description A sign-in with a wrong password answers `401`, the status of an expired token:
|
|
140
|
+
* with a session open the SDK used to refresh that session and send the same wrong password
|
|
141
|
+
* again — two failed attempts for one, and a rotated refresh token. Such a request carries
|
|
142
|
+
* no `Authorization` header and never triggers a token refresh.
|
|
143
|
+
*/
|
|
144
|
+
_asSignIn() {
|
|
145
|
+
const view = Object.create(this);
|
|
146
|
+
view._signIn = true;
|
|
147
|
+
return view;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* A view of this module for requests the SDK makes on its own behalf.
|
|
151
|
+
* @returns {this} An object that shares the module's state but does not call `errors.customErrors`.
|
|
152
|
+
* @description The products of page blocks and the templates of pages are loaded by the SDK
|
|
153
|
+
* itself, and a failure there leaves an empty value. A `customErrors` handler (a Next.js
|
|
154
|
+
* `notFound()`) used to fire for them as if the page itself had failed.
|
|
155
|
+
*/
|
|
156
|
+
_asSubRequest() {
|
|
157
|
+
const view = Object.create(this);
|
|
158
|
+
view._subRequest = true;
|
|
159
|
+
return view;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* `_asSubRequest` for another module the SDK calls on its own behalf.
|
|
163
|
+
* @param {T} module - A module created by the SDK for a nested request.
|
|
164
|
+
* @returns {T} Its view that does not call `errors.customErrors`.
|
|
165
|
+
*/
|
|
166
|
+
static _subRequestOf(module) {
|
|
167
|
+
return module._asSubRequest();
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Reads the answer of a call that returns `true` on success.
|
|
171
|
+
* @param {T} result - What the request returned.
|
|
172
|
+
* @returns {T | true} `true` for an empty 2xx body (read as `{}`), the value otherwise.
|
|
173
|
+
*/
|
|
174
|
+
_asBoolean(result) {
|
|
175
|
+
return result &&
|
|
176
|
+
typeof result === 'object' &&
|
|
177
|
+
!this._isErrorResponse(result) &&
|
|
178
|
+
Object.keys(result).length === 0
|
|
179
|
+
? true
|
|
180
|
+
: result;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Whether a refresh may be attempted now.
|
|
184
|
+
* @returns {boolean} False while the device metadata is the one the platform rejected as malformed.
|
|
185
|
+
*/
|
|
186
|
+
_canRefresh() {
|
|
187
|
+
return (!!this.state.refreshToken &&
|
|
188
|
+
this.state._rejectedMetadata !== this._getDeviceMetadata());
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* A view of this module whose requests go to another base URL.
|
|
192
|
+
* @param {string} url - The base URL for the view's requests.
|
|
193
|
+
* @returns {this} An object that shares the module's state and methods but has its own `_url`.
|
|
194
|
+
* @description For the few endpoints that live outside the module's base path. The base URL
|
|
195
|
+
* used to be swapped on the module itself for the duration of the call; two calls in flight
|
|
196
|
+
* at once (`Promise.all`) then sent one of them to the other base path, and the second
|
|
197
|
+
* `finally` restored the swapped URL — every later call of the instance went there too.
|
|
198
|
+
*/
|
|
199
|
+
_withBaseUrl(url) {
|
|
200
|
+
const view = Object.create(this);
|
|
201
|
+
view._url = url;
|
|
202
|
+
return view;
|
|
203
|
+
}
|
|
120
204
|
/**
|
|
121
205
|
* Prepares a caller value (a marker) to be one segment of a request path.
|
|
122
206
|
* @param {string} value - The value to put into the path.
|
|
@@ -131,6 +215,20 @@ class AsyncModules extends syncModules_1.default {
|
|
|
131
215
|
const encoded = encodeURIComponent(value);
|
|
132
216
|
return /^\.{1,2}$/.test(value) ? encoded.replace(/\./g, '%252E') : encoded;
|
|
133
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Prepares a caller path (a page URL) for a request path, keeping its `/`.
|
|
220
|
+
* @param {string} value - The path to put into the request path.
|
|
221
|
+
* @returns {string} Each `/`-separated part encoded by `_pathSegment`.
|
|
222
|
+
* @description A page URL may hold `/`, so it cannot be one segment; each part is
|
|
223
|
+
* encoded instead. `getProductsByPageUrl('../../all')` resolved to
|
|
224
|
+
* `POST /products/all` — the whole catalogue instead of one page.
|
|
225
|
+
*/
|
|
226
|
+
_pathSegments(value) {
|
|
227
|
+
return String(value)
|
|
228
|
+
.split('/')
|
|
229
|
+
.map((part) => this._pathSegment(part))
|
|
230
|
+
.join('/');
|
|
231
|
+
}
|
|
134
232
|
/**
|
|
135
233
|
* Performs an HTTP GET request.
|
|
136
234
|
* @param {string} path - The path to append to the base URL.
|
|
@@ -233,6 +331,7 @@ class AsyncModules extends syncModules_1.default {
|
|
|
233
331
|
* @description Sends POST /users/refresh and, on success, stores the rotated access/refresh tokens and calls saveFunction.
|
|
234
332
|
*/
|
|
235
333
|
async _performRefresh() {
|
|
334
|
+
var _a, _b;
|
|
236
335
|
const url = this.state.url +
|
|
237
336
|
`/api/content/users-auth-providers/marker/` +
|
|
238
337
|
this.state.providerMarker +
|
|
@@ -245,20 +344,45 @@ class AsyncModules extends syncModules_1.default {
|
|
|
245
344
|
* @param {object} options.headers - Set the necessary headers for the request
|
|
246
345
|
* @param {object} options.body - Send the current refresh token in the request body as a JSON string
|
|
247
346
|
*/
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
347
|
+
// `AbortSignal.timeout` is missing in older runtimes (Safari < 16, Node < 17.3)
|
|
348
|
+
let signal;
|
|
349
|
+
if (typeof AbortSignal !== 'undefined' &&
|
|
350
|
+
typeof AbortSignal.timeout === 'function') {
|
|
351
|
+
signal = AbortSignal.timeout(REFRESH_TIMEOUT_MS);
|
|
352
|
+
}
|
|
353
|
+
else if (typeof AbortController !== 'undefined') {
|
|
354
|
+
const controller = new AbortController();
|
|
355
|
+
// eslint-disable-next-line no-undef
|
|
356
|
+
const timer = setTimeout(() => controller.abort(), REFRESH_TIMEOUT_MS);
|
|
357
|
+
// Not cleared when the headers arrive: the body is read under the same signal.
|
|
358
|
+
// Must not keep a Node process alive for the timeout.
|
|
359
|
+
(_a = timer === null || timer === void 0 ? void 0 : timer.unref) === null || _a === void 0 ? void 0 : _a.call(timer);
|
|
360
|
+
signal = controller.signal;
|
|
361
|
+
}
|
|
362
|
+
let response;
|
|
363
|
+
try {
|
|
364
|
+
response = await fetch(url, {
|
|
365
|
+
method: 'POST',
|
|
366
|
+
headers: {
|
|
367
|
+
// Indicate that the request body is in JSON format
|
|
368
|
+
'Content-Type': 'application/json',
|
|
369
|
+
// Include the application token from the state
|
|
370
|
+
'x-app-token': this.state.token,
|
|
371
|
+
// Include the device fingerprint
|
|
372
|
+
'x-device-metadata': this._getDeviceMetadata(),
|
|
373
|
+
// x-guest-id is intentionally omitted: refresh is an auth-only call
|
|
374
|
+
// (a pure guest has no refresh token), so guest scoping does not apply.
|
|
375
|
+
},
|
|
376
|
+
body: JSON.stringify({ refreshToken: this.state.refreshToken }),
|
|
377
|
+
// Every request of the client waits on this one refresh (`_refreshPromise`):
|
|
378
|
+
// a refresh that never answered froze the whole client
|
|
379
|
+
...(signal ? { signal } : {}),
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
catch {
|
|
383
|
+
// No answer (network, timeout): the token may still be valid, keep it
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
262
386
|
// Check if the response status is OK (status code 200-299)
|
|
263
387
|
if (response.ok) {
|
|
264
388
|
// Parsed through the shared helper rather than `response.json()`: a `200` whose body is
|
|
@@ -270,6 +394,7 @@ class AsyncModules extends syncModules_1.default {
|
|
|
270
394
|
return false;
|
|
271
395
|
}
|
|
272
396
|
// Update the state's refreshToken and accessToken with the new tokens from the response
|
|
397
|
+
this.state._rejectedMetadata = undefined;
|
|
273
398
|
this.state.refreshToken = result.refreshToken;
|
|
274
399
|
this.state.accessToken = result.accessToken;
|
|
275
400
|
// If a save function is defined in the state, call it with the new refresh token
|
|
@@ -280,6 +405,21 @@ class AsyncModules extends syncModules_1.default {
|
|
|
280
405
|
return true;
|
|
281
406
|
}
|
|
282
407
|
else {
|
|
408
|
+
// The platform rejected the token itself (`400 Provided token is incorrect`: expired,
|
|
409
|
+
// revoked, another device): drop it from this client, or every following request fired
|
|
410
|
+
// the same doomed refresh first. A 400 about the request (`Invalid x-device-metadata
|
|
411
|
+
// format`, `Missing x-device-metadata header`) says nothing about the token — keep it.
|
|
412
|
+
// `saveFunction` is not called: on another device the stored token is still valid.
|
|
413
|
+
if (response.status === 400) {
|
|
414
|
+
const body = await this._parseJson(response);
|
|
415
|
+
if (!/x-device-metadata/i.test(String((_b = body === null || body === void 0 ? void 0 : body.message) !== null && _b !== void 0 ? _b : ''))) {
|
|
416
|
+
this.state.refreshToken = undefined;
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
// Kept, but not retried with the same metadata before every request
|
|
420
|
+
this.state._rejectedMetadata = this._getDeviceMetadata();
|
|
421
|
+
}
|
|
422
|
+
}
|
|
283
423
|
// Return false to indicate that the token refresh failed
|
|
284
424
|
return false;
|
|
285
425
|
}
|
|
@@ -317,7 +457,10 @@ class AsyncModules extends syncModules_1.default {
|
|
|
317
457
|
};
|
|
318
458
|
}
|
|
319
459
|
// Check if 'data' is an instance of FormData or Blob
|
|
320
|
-
|
|
460
|
+
// Runtimes without FormData/Blob (older Node, some workers): `instanceof` on an
|
|
461
|
+
// undefined global threw on every request, a GET included
|
|
462
|
+
if ((typeof FormData !== 'undefined' && data instanceof FormData) ||
|
|
463
|
+
(typeof Blob !== 'undefined' && data instanceof Blob)) {
|
|
321
464
|
// Remove the 'Content-Type' header from options.headers
|
|
322
465
|
delete options.headers['Content-Type'];
|
|
323
466
|
// Set the 'accept' header to 'application/json', while preserving existing headers
|
|
@@ -334,7 +477,7 @@ class AsyncModules extends syncModules_1.default {
|
|
|
334
477
|
options.body = JSON.stringify(data);
|
|
335
478
|
}
|
|
336
479
|
// Check if there is an access token available in the state
|
|
337
|
-
if (this.state.accessToken) {
|
|
480
|
+
if (this.state.accessToken && !this._signIn) {
|
|
338
481
|
// Add an 'Authorization' header with the Bearer token to options.headers
|
|
339
482
|
options.headers['Authorization'] = 'Bearer ' + this.state.accessToken;
|
|
340
483
|
}
|
|
@@ -381,10 +524,13 @@ class AsyncModules extends syncModules_1.default {
|
|
|
381
524
|
* @description Define an asynchronous method 'browserResponse' that takes a path and options as parameters
|
|
382
525
|
*/
|
|
383
526
|
async browserResponse(path, options) {
|
|
527
|
+
var _a;
|
|
384
528
|
// Set when a proactive refresh ran and failed (dead/expired refresh token):
|
|
385
529
|
// used below to skip the reactive refresh so we don't fire a second,
|
|
386
530
|
// equally-doomed refresh on the 401 that the request is about to return.
|
|
387
531
|
let proactiveRefreshFailed = false;
|
|
532
|
+
let status = 0;
|
|
533
|
+
let failure;
|
|
388
534
|
try {
|
|
389
535
|
// Proactive (eager) refresh: a session restored from storage has a refresh
|
|
390
536
|
// token but no access token yet. Sending the first authenticated request
|
|
@@ -394,8 +540,9 @@ class AsyncModules extends syncModules_1.default {
|
|
|
394
540
|
// Fires at most once per session (skipped once accessToken is set), and is
|
|
395
541
|
// off for custom-auth callers who manage tokens themselves.
|
|
396
542
|
if (!this.state.accessToken &&
|
|
397
|
-
this.
|
|
398
|
-
!this.state.customAuth
|
|
543
|
+
this._canRefresh() &&
|
|
544
|
+
!this.state.customAuth &&
|
|
545
|
+
!this._signIn) {
|
|
399
546
|
const refreshed = await this.refreshToken();
|
|
400
547
|
if (refreshed) {
|
|
401
548
|
// Authenticated now — attach the bearer and drop the guest scoping
|
|
@@ -418,7 +565,11 @@ class AsyncModules extends syncModules_1.default {
|
|
|
418
565
|
if (!response.ok &&
|
|
419
566
|
response.status === 401 &&
|
|
420
567
|
!this.state.customAuth &&
|
|
421
|
-
!proactiveRefreshFailed
|
|
568
|
+
!proactiveRefreshFailed &&
|
|
569
|
+
!this._signIn &&
|
|
570
|
+
// Without a refresh token there is nothing to refresh: the call went out
|
|
571
|
+
// as `{}` and every 401 of a guest or a wrong app token cost two requests
|
|
572
|
+
this._canRefresh()) {
|
|
422
573
|
const refresh = await this.refreshToken();
|
|
423
574
|
if (refresh) {
|
|
424
575
|
// Update the Authorization header with the new access token and retry.
|
|
@@ -443,19 +594,33 @@ class AsyncModules extends syncModules_1.default {
|
|
|
443
594
|
}
|
|
444
595
|
}
|
|
445
596
|
// Handle non-OK responses (applies to the first response and to a failed retry).
|
|
446
|
-
|
|
447
|
-
const
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
597
|
+
status = response.status;
|
|
598
|
+
const body = await this._parseJson(response);
|
|
599
|
+
// A failing answer whose body is not the platform's error (`{"error":…}`, `[]`,
|
|
600
|
+
// `null` from a gateway) used to be returned as data — `_fetchBoolean` read a 503 as `true`
|
|
601
|
+
const hasMessage = (value) => typeof (value === null || value === void 0 ? void 0 : value.message) === 'string' && value.message.trim() !== '';
|
|
602
|
+
failure =
|
|
603
|
+
body &&
|
|
604
|
+
typeof body === 'object' &&
|
|
605
|
+
typeof body.statusCode === 'number'
|
|
606
|
+
? // The platform's own error: keep it, with a message to show
|
|
607
|
+
hasMessage(body)
|
|
608
|
+
? body
|
|
609
|
+
: { ...body, message: `HTTP ${status}` }
|
|
610
|
+
: {
|
|
611
|
+
...(body && typeof body === 'object' && !Array.isArray(body)
|
|
612
|
+
? body
|
|
613
|
+
: {}),
|
|
614
|
+
statusCode: status,
|
|
615
|
+
// The text the server sent wins over the bare status
|
|
616
|
+
message: typeof body === 'string' && body
|
|
617
|
+
? body
|
|
618
|
+
: hasMessage(body)
|
|
619
|
+
? body.message
|
|
620
|
+
: `HTTP ${status}`,
|
|
621
|
+
pageData: null,
|
|
622
|
+
timestamp: new Date().toISOString(),
|
|
623
|
+
};
|
|
459
624
|
}
|
|
460
625
|
catch (e) {
|
|
461
626
|
// Handle any errors that occur during the fetch process
|
|
@@ -463,10 +628,27 @@ class AsyncModules extends syncModules_1.default {
|
|
|
463
628
|
if (this.state.isShell) {
|
|
464
629
|
return this._toShellError(e);
|
|
465
630
|
}
|
|
466
|
-
|
|
467
|
-
|
|
631
|
+
// `@throws {IError}`: a dropped connection used to escape as a raw TypeError
|
|
632
|
+
const error = this._toShellError(e);
|
|
633
|
+
if (error !== e) {
|
|
634
|
+
error.cause = e;
|
|
468
635
|
}
|
|
636
|
+
throw error;
|
|
637
|
+
}
|
|
638
|
+
// Called outside the try block: an exception from the handler (Next.js `redirect()`,
|
|
639
|
+
// `notFound()`) has to reach the caller, not turn into a `statusCode: 0` error
|
|
640
|
+
const statusKey = status;
|
|
641
|
+
const handler = this._subRequest
|
|
642
|
+
? undefined
|
|
643
|
+
: (_a = this.state.errorsFunctions) === null || _a === void 0 ? void 0 : _a[statusKey];
|
|
644
|
+
if (handler) {
|
|
645
|
+
await handler(failure);
|
|
646
|
+
}
|
|
647
|
+
// Determine whether to return or throw the response based on 'isShell' state
|
|
648
|
+
if (this.state.isShell) {
|
|
649
|
+
return failure;
|
|
469
650
|
}
|
|
651
|
+
throw failure;
|
|
470
652
|
}
|
|
471
653
|
/**
|
|
472
654
|
* Describes a response whose body is not the JSON the API is supposed to send.
|
|
@@ -11,10 +11,12 @@ export default class StateModule {
|
|
|
11
11
|
token: string | undefined;
|
|
12
12
|
guestId: string | undefined;
|
|
13
13
|
deviceMetadata: string | undefined;
|
|
14
|
+
nodeDeviceId: string | undefined;
|
|
14
15
|
accessToken: string | undefined;
|
|
15
16
|
traficLimit: boolean;
|
|
16
17
|
refreshToken: string | undefined;
|
|
17
18
|
_refreshPromise: Promise<boolean> | null;
|
|
19
|
+
_rejectedMetadata: string | undefined;
|
|
18
20
|
providerMarker: string;
|
|
19
21
|
customAuth: boolean;
|
|
20
22
|
isShell: boolean;
|
package/dist/base/stateModule.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
|
+
const syncModules_1 = require("./syncModules");
|
|
3
5
|
// HTTP status codes for which a custom error handler may be configured.
|
|
4
6
|
const ERROR_STATUS_CODES = [
|
|
5
7
|
400, 401, 403, 404, 429, 500, 502, 503, 504,
|
|
@@ -16,32 +18,40 @@ class StateModule {
|
|
|
16
18
|
* @description Constructor for StateModule.
|
|
17
19
|
*/
|
|
18
20
|
constructor(url, config) {
|
|
19
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t
|
|
21
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
20
22
|
// In-flight token refresh, shared across all module instances (they share this
|
|
21
23
|
// state object). De-duplicates concurrent refreshes so the single-use refresh
|
|
22
24
|
// token is not burned by parallel requests. Null when no refresh is running.
|
|
23
25
|
this._refreshPromise = null;
|
|
24
26
|
this.url = url;
|
|
25
|
-
|
|
27
|
+
// `''` is not a language: it went out as `?langCode=` and every call answered 400
|
|
28
|
+
this.lang =
|
|
29
|
+
(typeof config.langCode === 'string' && config.langCode.trim()) ||
|
|
30
|
+
'en_US';
|
|
26
31
|
this.token = config.token;
|
|
27
32
|
// Normalize empty string to undefined: an explicit '' must not masquerade
|
|
28
33
|
// as a set guest id (it would otherwise suppress id resolution).
|
|
34
|
+
(0, syncModules_1._warnGuestId)(config.guestId);
|
|
29
35
|
this.guestId = config.guestId || undefined;
|
|
30
36
|
// Same normalization as guestId: an explicit '' must not suppress the
|
|
31
37
|
// environment-derived fingerprint.
|
|
32
38
|
this.deviceMetadata = config.deviceMetadata || undefined;
|
|
33
39
|
this.traficLimit = config.traficLimit || false;
|
|
34
|
-
this.validationEnabled = (
|
|
35
|
-
this.validationStrictMode = (
|
|
36
|
-
this.validationLogErrors = (
|
|
37
|
-
this.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
this.validationEnabled = (_b = (_a = config.validation) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : false;
|
|
41
|
+
this.validationStrictMode = (_d = (_c = config.validation) === null || _c === void 0 ? void 0 : _c.strictMode) !== null && _d !== void 0 ? _d : false;
|
|
42
|
+
this.validationLogErrors = (_f = (_e = config.validation) === null || _e === void 0 ? void 0 : _e.logErrors) !== null && _f !== void 0 ? _f : true;
|
|
43
|
+
if (this.validationStrictMode && !this.validationEnabled) {
|
|
44
|
+
// eslint-disable-next-line no-undef, no-console
|
|
45
|
+
console.warn('OneEntry SDK: validation.strictMode has no effect without validation.enabled: true');
|
|
46
|
+
}
|
|
47
|
+
this.rawData = (_g = config.rawData) !== null && _g !== void 0 ? _g : false;
|
|
48
|
+
this.refreshToken = (_j = (_h = config.auth) === null || _h === void 0 ? void 0 : _h.refreshToken) !== null && _j !== void 0 ? _j : undefined;
|
|
49
|
+
this.providerMarker = (_l = (_k = config.auth) === null || _k === void 0 ? void 0 : _k.providerMarker) !== null && _l !== void 0 ? _l : 'email';
|
|
50
|
+
this.customAuth = (_o = (_m = config.auth) === null || _m === void 0 ? void 0 : _m.customAuth) !== null && _o !== void 0 ? _o : false;
|
|
41
51
|
this.errorsFunctions = {};
|
|
42
|
-
this.saveFunction = (
|
|
43
|
-
this.isShell = (
|
|
44
|
-
const customErrors = (
|
|
52
|
+
this.saveFunction = (_q = (_p = config.auth) === null || _p === void 0 ? void 0 : _p.saveFunction) !== null && _q !== void 0 ? _q : null;
|
|
53
|
+
this.isShell = (_s = (_r = config.errors) === null || _r === void 0 ? void 0 : _r.isShell) !== null && _s !== void 0 ? _s : true;
|
|
54
|
+
const customErrors = (_t = config.errors) === null || _t === void 0 ? void 0 : _t.customErrors;
|
|
45
55
|
if (customErrors) {
|
|
46
56
|
for (const code of ERROR_STATUS_CODES) {
|
|
47
57
|
if (customErrors[code]) {
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { IUploadingQuery } from '../file-uploading/fileUploadingInterfaces';
|
|
2
2
|
import type { IProductsQuery } from '../products/productsInterfaces';
|
|
3
3
|
import type StateModule from './stateModule';
|
|
4
|
+
/**
|
|
5
|
+
* Warns about a caller's guest id the platform will not keep.
|
|
6
|
+
* @param {string | undefined} guestId - The id passed in config or to `setGuestId`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function _warnGuestId(guestId: string | undefined): void;
|
|
4
9
|
/**
|
|
5
10
|
* Abstract class representing synchronization modules.
|
|
6
11
|
*/
|
|
@@ -8,7 +13,6 @@ export default abstract class SyncModules {
|
|
|
8
13
|
/** Protected properties for state and URL */
|
|
9
14
|
protected state: StateModule;
|
|
10
15
|
protected _url: string;
|
|
11
|
-
private readonly _nodeDeviceId;
|
|
12
16
|
/**
|
|
13
17
|
* Constructor to initialize state and URL.
|
|
14
18
|
* @param {StateModule} state - StateModule instance.
|
|
@@ -109,7 +113,11 @@ export default abstract class SyncModules {
|
|
|
109
113
|
* numeric branch already produced.
|
|
110
114
|
* 3. **Numbers** (`integer`, `float`, `real`) — cast to a JS number; anything
|
|
111
115
|
* that is not a number (including an empty value) becomes `null`.
|
|
116
|
+
* 4. **Empty strings** of non-text types (`image`, `groupOfImages`, `file`,
|
|
117
|
+
* `timeInterval`, `date`, `dateTime`, `time`) — the API sends an unset value as
|
|
118
|
+
* `""`; it is replaced with `null`. For text types `""` is a real value and stays.
|
|
112
119
|
* @param {any} attr - The attribute object to normalize in place.
|
|
120
|
+
* @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.
|
|
113
121
|
*/
|
|
114
122
|
private _normalizeAttrValue;
|
|
115
123
|
/**
|
|
@@ -172,15 +180,15 @@ export default abstract class SyncModules {
|
|
|
172
180
|
/**
|
|
173
181
|
* Sets the access token in the state.
|
|
174
182
|
* @param {string} accessToken - The access token to set.
|
|
175
|
-
* @returns {
|
|
183
|
+
* @returns {this} The same module, for chaining.
|
|
176
184
|
*/
|
|
177
|
-
setAccessToken(accessToken: string):
|
|
185
|
+
setAccessToken(accessToken: string): this;
|
|
178
186
|
/**
|
|
179
187
|
* Sets the refresh token in the state.
|
|
180
188
|
* @param {string} refreshToken - The refresh token to set.
|
|
181
|
-
* @returns {
|
|
189
|
+
* @returns {this} The same module, for chaining.
|
|
182
190
|
*/
|
|
183
|
-
setRefreshToken(refreshToken: string):
|
|
191
|
+
setRefreshToken(refreshToken: string): this;
|
|
184
192
|
/**
|
|
185
193
|
* Sets the guest identifier in the state.
|
|
186
194
|
*
|
|
@@ -189,9 +197,9 @@ export default abstract class SyncModules {
|
|
|
189
197
|
* (the SDK then falls back to the localStorage-backed id in the browser, or to
|
|
190
198
|
* no guest id at all on the server).
|
|
191
199
|
* @param {string} guestId - The guest identifier to set (empty string clears it).
|
|
192
|
-
* @returns {
|
|
200
|
+
* @returns {this} The same module, for chaining.
|
|
193
201
|
*/
|
|
194
|
-
setGuestId(guestId: string):
|
|
202
|
+
setGuestId(guestId: string): this;
|
|
195
203
|
/**
|
|
196
204
|
* Sets the device-metadata override in the state.
|
|
197
205
|
*
|
|
@@ -202,9 +210,9 @@ export default abstract class SyncModules {
|
|
|
202
210
|
* browser's string (obtained there via `getDeviceMetadata`). Pass an empty
|
|
203
211
|
* string to clear the override and fall back to the computed fingerprint.
|
|
204
212
|
* @param {string} deviceMetadata - The metadata string to send (empty string clears the override).
|
|
205
|
-
* @returns {
|
|
213
|
+
* @returns {this} The same module, for chaining.
|
|
206
214
|
*/
|
|
207
|
-
setDeviceMetadata(deviceMetadata: string):
|
|
215
|
+
setDeviceMetadata(deviceMetadata: string): this;
|
|
208
216
|
/**
|
|
209
217
|
* Returns the device-metadata string the SDK sends as the `x-device-metadata` header.
|
|
210
218
|
*
|
|
@@ -238,7 +246,7 @@ export default abstract class SyncModules {
|
|
|
238
246
|
*
|
|
239
247
|
* **instanceId strategy:**
|
|
240
248
|
* - Browser: `_getPersistentBrowserId('oneentry_device_id')` — read from localStorage, stable across sessions.
|
|
241
|
-
* - Node.js / no localStorage: `
|
|
249
|
+
* - Node.js / no localStorage: `state.nodeDeviceId` — generated once per client (shared by its modules),
|
|
242
250
|
* lives until the process restarts.
|
|
243
251
|
*
|
|
244
252
|
* In a Node.js environment (no `window`) returns a simplified object without screen/navigator.
|