oneentry 1.0.159 → 1.0.161
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 +2 -0
- package/changelog.md +56 -1
- package/dist/admins/adminsApi.d.ts +15 -1
- package/dist/admins/adminsApi.js +29 -0
- package/dist/admins/adminsInterfaces.d.ts +37 -1
- package/dist/base/lazySchema.d.ts +15 -0
- package/dist/base/lazySchema.js +20 -0
- package/dist/discounts/discountsApi.d.ts +14 -1
- package/dist/discounts/discountsApi.js +21 -0
- package/dist/discounts/discountsInterfaces.d.ts +27 -1
- package/dist/filters/filtersInterfaces.d.ts +2 -2
- package/dist/filters/filtersSchemas.d.ts +1 -1
- package/dist/filters/filtersSchemas.js +4 -1
- package/dist/forms-data/formsDataApi.d.ts +14 -1
- package/dist/forms-data/formsDataApi.js +21 -0
- package/dist/forms-data/formsDataInterfaces.d.ts +74 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/orders/ordersApi.d.ts +15 -1
- package/dist/orders/ordersApi.js +22 -0
- package/dist/orders/ordersInterfaces.d.ts +27 -1
- package/dist/pages/pagesApi.d.ts +14 -1
- package/dist/pages/pagesApi.js +21 -0
- package/dist/pages/pagesInterfaces.d.ts +38 -1
- package/dist/payments/paymentsInterfaces.d.ts +2 -2
- package/dist/products/productsInterfaces.d.ts +1 -1
- package/dist/search/searchApi.d.ts +35 -0
- package/dist/search/searchApi.js +86 -0
- package/dist/search/searchInterfaces.d.ts +94 -0
- package/dist/search/searchInterfaces.js +2 -0
- package/dist/search/searchSchemas.d.ts +73 -0
- package/dist/search/searchSchemas.js +44 -0
- package/dist/templates-preview/templatesPreviewInterfaces.d.ts +0 -2
- package/dist/templates-preview/templatesPreviewSchemas.d.ts +0 -2
- package/dist/templates-preview/templatesPreviewSchemas.js +0 -1
- package/dist/types.d.ts +35 -0
- package/dist/types.js +2 -0
- package/dist/users/usersApi.d.ts +15 -1
- package/dist/users/usersApi.js +22 -0
- package/dist/users/usersInterfaces.d.ts +39 -1
- package/dist/web-socket/lazySocket.d.ts +18 -0
- package/dist/web-socket/lazySocket.js +70 -0
- package/esm/admins/adminsApi.d.ts +66 -0
- package/esm/admins/adminsApi.js +90 -0
- package/esm/admins/adminsInterfaces.d.ts +137 -0
- package/esm/admins/adminsInterfaces.js +1 -0
- package/esm/admins/adminsSchemas.d.ts +48 -0
- package/esm/admins/adminsSchemas.js +31 -0
- package/esm/attribute-sets/attributeSetsApi.d.ts +67 -0
- package/esm/attribute-sets/attributeSetsApi.js +97 -0
- package/esm/attribute-sets/attributeSetsInterfaces.d.ts +285 -0
- package/esm/attribute-sets/attributeSetsInterfaces.js +1 -0
- package/esm/attribute-sets/attributeSetsSchemas.d.ts +84 -0
- package/esm/attribute-sets/attributeSetsSchemas.js +66 -0
- package/esm/auth-provider/authProviderApi.d.ts +262 -0
- package/esm/auth-provider/authProviderApi.js +362 -0
- package/esm/auth-provider/authProviderSchemas.d.ts +124 -0
- package/esm/auth-provider/authProviderSchemas.js +92 -0
- package/esm/auth-provider/authProvidersInterfaces.d.ts +430 -0
- package/esm/auth-provider/authProvidersInterfaces.js +1 -0
- package/esm/base/asyncModules.d.ts +123 -0
- package/esm/base/asyncModules.js +382 -0
- package/esm/base/lazySchema.d.ts +15 -0
- package/esm/base/lazySchema.js +17 -0
- package/esm/base/stateModule.d.ts +35 -0
- package/esm/base/stateModule.js +51 -0
- package/esm/base/syncModules.d.ts +245 -0
- package/esm/base/syncModules.js +555 -0
- package/esm/base/timeIntervals.d.ts +95 -0
- package/esm/base/timeIntervals.js +317 -0
- package/esm/base/utils.d.ts +354 -0
- package/esm/base/utils.js +1 -0
- package/esm/base/validation.d.ts +98 -0
- package/esm/base/validation.js +118 -0
- package/esm/blocks/blocksApi.d.ts +252 -0
- package/esm/blocks/blocksApi.js +394 -0
- package/esm/blocks/blocksInterfaces.d.ts +361 -0
- package/esm/blocks/blocksInterfaces.js +1 -0
- package/esm/blocks/blocksSchemas.d.ts +213 -0
- package/esm/blocks/blocksSchemas.js +40 -0
- package/esm/discounts/discountsApi.d.ts +94 -0
- package/esm/discounts/discountsApi.js +136 -0
- package/esm/discounts/discountsInterfaces.d.ts +293 -0
- package/esm/discounts/discountsInterfaces.js +1 -0
- package/esm/events/eventsApi.d.ts +108 -0
- package/esm/events/eventsApi.js +141 -0
- package/esm/events/eventsInterfaces.d.ts +176 -0
- package/esm/events/eventsInterfaces.js +1 -0
- package/esm/file-uploading/fileUploadingApi.d.ts +91 -0
- package/esm/file-uploading/fileUploadingApi.js +127 -0
- package/esm/file-uploading/fileUploadingInterfaces.d.ts +116 -0
- package/esm/file-uploading/fileUploadingInterfaces.js +1 -0
- package/esm/file-uploading/fileUploadingSchemas.d.ts +24 -0
- package/esm/file-uploading/fileUploadingSchemas.js +19 -0
- package/esm/filters/filtersApi.d.ts +32 -0
- package/esm/filters/filtersApi.js +36 -0
- package/esm/filters/filtersInterfaces.d.ts +56 -0
- package/esm/filters/filtersInterfaces.js +1 -0
- package/esm/filters/filtersSchemas.d.ts +32 -0
- package/esm/filters/filtersSchemas.js +29 -0
- package/esm/forms/formsApi.d.ts +44 -0
- package/esm/forms/formsApi.js +54 -0
- package/esm/forms/formsInterfaces.d.ts +237 -0
- package/esm/forms/formsInterfaces.js +1 -0
- package/esm/forms/formsSchemas.d.ts +56 -0
- package/esm/forms/formsSchemas.js +32 -0
- package/esm/forms-data/formsDataApi.d.ts +124 -0
- package/esm/forms-data/formsDataApi.js +210 -0
- package/esm/forms-data/formsDataInterfaces.d.ts +670 -0
- package/esm/forms-data/formsDataInterfaces.js +1 -0
- package/esm/forms-data/formsDataSchemas.d.ts +107 -0
- package/esm/forms-data/formsDataSchemas.js +83 -0
- package/esm/general-types/generalTypesApi.d.ts +29 -0
- package/esm/general-types/generalTypesApi.js +34 -0
- package/esm/general-types/generalTypesInterfaces.d.ts +29 -0
- package/esm/general-types/generalTypesInterfaces.js +1 -0
- package/esm/general-types/generalTypesSchemas.d.ts +68 -0
- package/esm/general-types/generalTypesSchemas.js +42 -0
- package/esm/index.d.ts +143 -0
- package/esm/index.js +124 -0
- package/esm/integration-collections/integrationCollectionsApi.d.ts +172 -0
- package/esm/integration-collections/integrationCollectionsApi.js +224 -0
- package/esm/integration-collections/integrationCollectionsInterfaces.d.ts +317 -0
- package/esm/integration-collections/integrationCollectionsInterfaces.js +1 -0
- package/esm/integration-collections/integrationCollectionsSchemas.d.ts +84 -0
- package/esm/integration-collections/integrationCollectionsSchemas.js +60 -0
- package/esm/locales/localesApi.d.ts +28 -0
- package/esm/locales/localesApi.js +33 -0
- package/esm/locales/localesInterfaces.d.ts +40 -0
- package/esm/locales/localesInterfaces.js +1 -0
- package/esm/locales/localesSchemas.d.ts +32 -0
- package/esm/locales/localesSchemas.js +23 -0
- package/esm/menus/menusApi.d.ts +30 -0
- package/esm/menus/menusApi.js +35 -0
- package/esm/menus/menusInterfaces.d.ts +87 -0
- package/esm/menus/menusInterfaces.js +2 -0
- package/esm/menus/menusSchemas.d.ts +16 -0
- package/esm/menus/menusSchemas.js +25 -0
- package/esm/orders/ordersApi.d.ts +213 -0
- package/esm/orders/ordersApi.js +288 -0
- package/esm/orders/ordersInterfaces.d.ts +763 -0
- package/esm/orders/ordersInterfaces.js +1 -0
- package/esm/orders/ordersSchemas.d.ts +312 -0
- package/esm/orders/ordersSchemas.js +171 -0
- package/esm/package.json +4 -0
- package/esm/pages/pagesApi.d.ts +173 -0
- package/esm/pages/pagesApi.js +414 -0
- package/esm/pages/pagesInterfaces.d.ts +344 -0
- package/esm/pages/pagesInterfaces.js +1 -0
- package/esm/pages/pagesSchemas.d.ts +121 -0
- package/esm/pages/pagesSchemas.js +60 -0
- package/esm/payments/paymentsApi.d.ts +88 -0
- package/esm/payments/paymentsApi.js +122 -0
- package/esm/payments/paymentsInterfaces.d.ts +189 -0
- package/esm/payments/paymentsInterfaces.js +1 -0
- package/esm/payments/paymentsSchemas.d.ts +94 -0
- package/esm/payments/paymentsSchemas.js +53 -0
- package/esm/product-statuses/productStatusesApi.d.ts +50 -0
- package/esm/product-statuses/productStatusesApi.js +68 -0
- package/esm/product-statuses/productStatusesInterfaces.d.ts +62 -0
- package/esm/product-statuses/productStatusesInterfaces.js +1 -0
- package/esm/product-statuses/productStatusesSchemas.d.ts +34 -0
- package/esm/product-statuses/productStatusesSchemas.js +27 -0
- package/esm/products/productsApi.d.ts +366 -0
- package/esm/products/productsApi.js +468 -0
- package/esm/products/productsInterfaces.d.ts +723 -0
- package/esm/products/productsInterfaces.js +1 -0
- package/esm/products/productsSchemas.d.ts +234 -0
- package/esm/products/productsSchemas.js +121 -0
- package/esm/search/searchApi.d.ts +35 -0
- package/esm/search/searchApi.js +47 -0
- package/esm/search/searchInterfaces.d.ts +94 -0
- package/esm/search/searchInterfaces.js +1 -0
- package/esm/search/searchSchemas.d.ts +73 -0
- package/esm/search/searchSchemas.js +41 -0
- package/esm/sitemap/sitemapApi.d.ts +37 -0
- package/esm/sitemap/sitemapApi.js +41 -0
- package/esm/sitemap/sitemapInterfaces.d.ts +51 -0
- package/esm/sitemap/sitemapInterfaces.js +1 -0
- package/esm/subscriptions/subscriptionsApi.d.ts +74 -0
- package/esm/subscriptions/subscriptionsApi.js +90 -0
- package/esm/subscriptions/subscriptionsInterfaces.d.ts +111 -0
- package/esm/subscriptions/subscriptionsInterfaces.js +1 -0
- package/esm/subscriptions/subscriptionsSchemas.d.ts +46 -0
- package/esm/subscriptions/subscriptionsSchemas.js +38 -0
- package/esm/system/systemApi.d.ts +46 -0
- package/esm/system/systemApi.js +53 -0
- package/esm/system/systemInterfaces.d.ts +29 -0
- package/esm/system/systemInterfaces.js +1 -0
- package/esm/templates/templatesApi.d.ts +53 -0
- package/esm/templates/templatesApi.js +78 -0
- package/esm/templates/templatesInterfaces.d.ts +68 -0
- package/esm/templates/templatesInterfaces.js +1 -0
- package/esm/templates/templatesSchemas.d.ts +48 -0
- package/esm/templates/templatesSchemas.js +28 -0
- package/esm/templates-preview/templatesPreviewApi.d.ts +40 -0
- package/esm/templates-preview/templatesPreviewApi.js +50 -0
- package/esm/templates-preview/templatesPreviewInterfaces.d.ts +129 -0
- package/esm/templates-preview/templatesPreviewInterfaces.js +1 -0
- package/esm/templates-preview/templatesPreviewSchemas.d.ts +79 -0
- package/esm/templates-preview/templatesPreviewSchemas.js +43 -0
- package/esm/types.d.ts +35 -0
- package/esm/types.js +1 -0
- package/esm/user-activity/userActivityApi.d.ts +31 -0
- package/esm/user-activity/userActivityApi.js +37 -0
- package/esm/user-activity/userActivityInterfaces.d.ts +42 -0
- package/esm/user-activity/userActivityInterfaces.js +1 -0
- package/esm/users/usersApi.d.ts +249 -0
- package/esm/users/usersApi.js +312 -0
- package/esm/users/usersInterfaces.d.ts +419 -0
- package/esm/users/usersInterfaces.js +1 -0
- package/esm/users/usersSchemas.d.ts +72 -0
- package/esm/users/usersSchemas.js +55 -0
- package/esm/web-socket/lazySocket.d.ts +18 -0
- package/esm/web-socket/lazySocket.js +67 -0
- package/esm/web-socket/wsApi.d.ts +27 -0
- package/esm/web-socket/wsApi.js +43 -0
- package/esm/web-socket/wsInterfaces.d.ts +16 -0
- package/esm/web-socket/wsInterfaces.js +1 -0
- package/package.json +47 -2
- package/types.d.ts +1 -0
- package/types.js +1 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import type StateModule from './stateModule.js';
|
|
3
|
+
import SyncModules from './syncModules.js';
|
|
4
|
+
import type { IError } from './utils.js';
|
|
5
|
+
/**
|
|
6
|
+
* Abstract class AsyncModules extends SyncModules to provide asynchronous HTTP request functionalities.
|
|
7
|
+
* @description Abstract class AsyncModules extends SyncModules to provide asynchronous HTTP request functionalities.
|
|
8
|
+
*/
|
|
9
|
+
export default abstract class AsyncModules extends SyncModules {
|
|
10
|
+
protected state: StateModule;
|
|
11
|
+
protected _url: string;
|
|
12
|
+
/**
|
|
13
|
+
* Constructor initializes the AsyncModules with a given state.
|
|
14
|
+
* @param {StateModule} state - Instance of StateModule containing configuration and state data.
|
|
15
|
+
* @description Constructor initializes the AsyncModules with a given state.
|
|
16
|
+
*/
|
|
17
|
+
protected constructor(state: StateModule);
|
|
18
|
+
/**
|
|
19
|
+
* Detects an API error returned as a value instead of being thrown.
|
|
20
|
+
*
|
|
21
|
+
* With `isShell` enabled (the default) `browserResponse` returns the error
|
|
22
|
+
* body — and a caught exception — instead of throwing, so a failed request
|
|
23
|
+
* is indistinguishable from a successful one by control flow alone.
|
|
24
|
+
* @param {unknown} value - Value returned by a request.
|
|
25
|
+
* @returns {boolean} True when the value is an API error (statusCode >= 400) or a thrown error object.
|
|
26
|
+
* @description Recognizes both the OneEntry error body and errors caught by browserResponse (e.g. a network failure).
|
|
27
|
+
*/
|
|
28
|
+
protected _isErrorResponse(value: unknown): value is IError;
|
|
29
|
+
/**
|
|
30
|
+
* Validates API response against a Zod schema (optional)
|
|
31
|
+
* @param {unknown} data - The data to validate
|
|
32
|
+
* @param {() => Promise<z.ZodSchema<T>>} [loadSchema] - Optional loader resolving to the Zod schema for validation
|
|
33
|
+
* @returns {Promise<T | IError>} Validated data or error object
|
|
34
|
+
* @description Validates response data if validation is enabled in config.
|
|
35
|
+
* The schema — and Zod itself — are imported on demand, so a project that leaves
|
|
36
|
+
* validation disabled (the default) never pulls Zod into its bundle.
|
|
37
|
+
*/
|
|
38
|
+
protected _validateResponse<T>(data: unknown, loadSchema?: () => Promise<z.ZodSchema<T>>): Promise<T | IError>;
|
|
39
|
+
/**
|
|
40
|
+
* Performs an HTTP GET request.
|
|
41
|
+
* @param {string} path - The path to append to the base URL.
|
|
42
|
+
* @returns {Promise<T>} A promise resolving to the response data.
|
|
43
|
+
* @description Define a protected asynchronous method '_fetchGet' that performs a GET request
|
|
44
|
+
*/
|
|
45
|
+
protected _fetchGet<T = unknown>(path: string): Promise<T>;
|
|
46
|
+
/**
|
|
47
|
+
* Performs an HTTP POST request.
|
|
48
|
+
* @param {string} path - The path to append to the base URL.
|
|
49
|
+
* @param {unknown} [data] - The data to send in the request body.
|
|
50
|
+
* @returns {Promise<T>} A promise resolving to the response data.
|
|
51
|
+
* @description Define a protected asynchronous method '_fetchPost' that performs a POST request
|
|
52
|
+
*/
|
|
53
|
+
protected _fetchPost<T = unknown>(path: string, data?: unknown): Promise<T>;
|
|
54
|
+
/**
|
|
55
|
+
* Performs an HTTP PUT request.
|
|
56
|
+
* @param {string} path - The path to append to the base URL.
|
|
57
|
+
* @param {unknown} body - The data to send in the request body.
|
|
58
|
+
* @returns {Promise<T>} A promise resolving to the response data.
|
|
59
|
+
* @description Define a protected asynchronous method '_fetchPut' that performs a PUT request
|
|
60
|
+
*/
|
|
61
|
+
protected _fetchPut<T = unknown>(path: string, body: unknown): Promise<T>;
|
|
62
|
+
/**
|
|
63
|
+
* Performs an HTTP DELETE request.
|
|
64
|
+
* @param {string} path - The path to append to the base URL.
|
|
65
|
+
* @param {unknown} body - The body of the request.
|
|
66
|
+
* @returns {Promise<T>} A promise resolving to the response data.
|
|
67
|
+
* @description Define a protected asynchronous method '_fetchDelete' that performs a DELETE request
|
|
68
|
+
*/
|
|
69
|
+
protected _fetchDelete<T = unknown>(path: string, body?: unknown): Promise<T>;
|
|
70
|
+
/**
|
|
71
|
+
* Wraps a fetch call whose only meaningful outcome is success or failure.
|
|
72
|
+
*
|
|
73
|
+
* Several endpoints (cancel/recover subscription, subscribe/unsubscribe to
|
|
74
|
+
* events) return no useful body — callers only care whether the request
|
|
75
|
+
* succeeded. This helper resolves to `true` on success and to the error
|
|
76
|
+
* (as IError) on failure, centralizing the repeated try/catch.
|
|
77
|
+
*
|
|
78
|
+
* The returned value has to be inspected as well: with `isShell` enabled
|
|
79
|
+
* (the default) browserResponse returns the API error instead of throwing
|
|
80
|
+
* it, so relying on the catch alone would report every failed call — a 404
|
|
81
|
+
* from cancelSubscription, a 403 from recoverSubscriptions — as a success.
|
|
82
|
+
* @param {() => Promise<unknown>} request - Thunk performing the fetch call.
|
|
83
|
+
* @returns {Promise<boolean | IError>} `true` on success, IError on failure.
|
|
84
|
+
*/
|
|
85
|
+
protected _fetchBoolean(request: () => Promise<unknown>): Promise<boolean | IError>;
|
|
86
|
+
/**
|
|
87
|
+
* Refreshes the authentication token (single-flight).
|
|
88
|
+
* @returns {Promise<boolean>} A promise resolving to a boolean indicating success or failure.
|
|
89
|
+
* @description De-duplicates concurrent refreshes — the refresh token is single-use, so parallel requests must share one refresh call instead of each burning a rotated token.
|
|
90
|
+
*/
|
|
91
|
+
protected refreshToken(): Promise<boolean>;
|
|
92
|
+
/**
|
|
93
|
+
* Performs the actual token refresh request (without de-duplication).
|
|
94
|
+
* @returns {Promise<boolean>} A promise resolving to a boolean indicating success or failure.
|
|
95
|
+
* @description Sends POST /users/refresh and, on success, stores the rotated access/refresh tokens and calls saveFunction.
|
|
96
|
+
*/
|
|
97
|
+
private _performRefresh;
|
|
98
|
+
/**
|
|
99
|
+
* Creates options for HTTP requests.
|
|
100
|
+
* @param {string} method - The HTTP method (GET, POST, PUT, DELETE, etc.).
|
|
101
|
+
* @param {unknown} data - Optional data to include in the request body.
|
|
102
|
+
* @returns {IHttpOptions} An object representing the request options.
|
|
103
|
+
*/
|
|
104
|
+
private makeOptions;
|
|
105
|
+
/**
|
|
106
|
+
* Reads a response body as JSON, tolerating an empty body.
|
|
107
|
+
*
|
|
108
|
+
* `Response.json()` throws on an empty body (e.g. 204 or an empty error
|
|
109
|
+
* payload); this helper mirrors the OK-path guard (`text ? JSON.parse : {}`)
|
|
110
|
+
* so both the success and the error branches handle empty bodies the same way.
|
|
111
|
+
* @param {Response} response - The fetch Response to read.
|
|
112
|
+
* @returns {Promise<unknown>} Parsed JSON, or an empty object when the body is empty/unparsable.
|
|
113
|
+
*/
|
|
114
|
+
private _parseJson;
|
|
115
|
+
/**
|
|
116
|
+
* Handles responses from the browser's fetch API.
|
|
117
|
+
* @param {string} path - The path to append to the base URL.
|
|
118
|
+
* @param {IHttpOptions} options - The options for the fetch request.
|
|
119
|
+
* @returns {Promise<T>} A promise resolving to the response data.
|
|
120
|
+
* @description Define an asynchronous method 'browserResponse' that takes a path and options as parameters
|
|
121
|
+
*/
|
|
122
|
+
private browserResponse;
|
|
123
|
+
}
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import SyncModules from './syncModules.js';
|
|
2
|
+
/**
|
|
3
|
+
* Abstract class AsyncModules extends SyncModules to provide asynchronous HTTP request functionalities.
|
|
4
|
+
* @description Abstract class AsyncModules extends SyncModules to provide asynchronous HTTP request functionalities.
|
|
5
|
+
*/
|
|
6
|
+
export default class AsyncModules extends SyncModules {
|
|
7
|
+
/**
|
|
8
|
+
* Constructor initializes the AsyncModules with a given state.
|
|
9
|
+
* @param {StateModule} state - Instance of StateModule containing configuration and state data.
|
|
10
|
+
* @description Constructor initializes the AsyncModules with a given state.
|
|
11
|
+
*/
|
|
12
|
+
constructor(state) {
|
|
13
|
+
super(state);
|
|
14
|
+
this.state = state;
|
|
15
|
+
this._url = this.state.url;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Detects an API error returned as a value instead of being thrown.
|
|
19
|
+
*
|
|
20
|
+
* With `isShell` enabled (the default) `browserResponse` returns the error
|
|
21
|
+
* body — and a caught exception — instead of throwing, so a failed request
|
|
22
|
+
* is indistinguishable from a successful one by control flow alone.
|
|
23
|
+
* @param {unknown} value - Value returned by a request.
|
|
24
|
+
* @returns {boolean} True when the value is an API error (statusCode >= 400) or a thrown error object.
|
|
25
|
+
* @description Recognizes both the OneEntry error body and errors caught by browserResponse (e.g. a network failure).
|
|
26
|
+
*/
|
|
27
|
+
_isErrorResponse(value) {
|
|
28
|
+
if (value instanceof Error) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
return (value !== null &&
|
|
32
|
+
typeof value === 'object' &&
|
|
33
|
+
'statusCode' in value &&
|
|
34
|
+
typeof value.statusCode === 'number' &&
|
|
35
|
+
value.statusCode >= 400);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Validates API response against a Zod schema (optional)
|
|
39
|
+
* @param {unknown} data - The data to validate
|
|
40
|
+
* @param {() => Promise<z.ZodSchema<T>>} [loadSchema] - Optional loader resolving to the Zod schema for validation
|
|
41
|
+
* @returns {Promise<T | IError>} Validated data or error object
|
|
42
|
+
* @description Validates response data if validation is enabled in config.
|
|
43
|
+
* The schema — and Zod itself — are imported on demand, so a project that leaves
|
|
44
|
+
* validation disabled (the default) never pulls Zod into its bundle.
|
|
45
|
+
*/
|
|
46
|
+
async _validateResponse(data, loadSchema) {
|
|
47
|
+
// Skip validation if not enabled or no schema provided
|
|
48
|
+
if (!this.state.validationEnabled || !loadSchema) {
|
|
49
|
+
return data;
|
|
50
|
+
}
|
|
51
|
+
// Skip validation for error responses (statusCode indicates API error)
|
|
52
|
+
if (this._isErrorResponse(data)) {
|
|
53
|
+
return data;
|
|
54
|
+
}
|
|
55
|
+
// Pull the schema and the Zod-backed validators only now that they are needed
|
|
56
|
+
const [schema, { validateResponse, validateResponseSafe }] = await Promise.all([loadSchema(), import('./validation.js')]);
|
|
57
|
+
// Use strict or safe validation based on config
|
|
58
|
+
if (this.state.validationStrictMode) {
|
|
59
|
+
const result = validateResponse(schema, data, {
|
|
60
|
+
logErrors: this.state.validationLogErrors,
|
|
61
|
+
});
|
|
62
|
+
if (!result.success) {
|
|
63
|
+
// Return error object compatible with IError interface
|
|
64
|
+
return {
|
|
65
|
+
statusCode: 422,
|
|
66
|
+
message: 'Response validation failed',
|
|
67
|
+
pageData: null,
|
|
68
|
+
timestamp: new Date().toISOString(),
|
|
69
|
+
localizeMessage: result.error.issues
|
|
70
|
+
.map((e) => `${e.path.join('.')}: ${e.message}`)
|
|
71
|
+
.join(', '),
|
|
72
|
+
validationErrors: result.error.issues,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return result.data;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
// Non-strict mode: log errors but return original data
|
|
79
|
+
return validateResponseSafe(schema, data, this.state.validationLogErrors);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Performs an HTTP GET request.
|
|
84
|
+
* @param {string} path - The path to append to the base URL.
|
|
85
|
+
* @returns {Promise<T>} A promise resolving to the response data.
|
|
86
|
+
* @description Define a protected asynchronous method '_fetchGet' that performs a GET request
|
|
87
|
+
*/
|
|
88
|
+
async _fetchGet(path) {
|
|
89
|
+
return this.browserResponse(path, this.makeOptions('GET'));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Performs an HTTP POST request.
|
|
93
|
+
* @param {string} path - The path to append to the base URL.
|
|
94
|
+
* @param {unknown} [data] - The data to send in the request body.
|
|
95
|
+
* @returns {Promise<T>} A promise resolving to the response data.
|
|
96
|
+
* @description Define a protected asynchronous method '_fetchPost' that performs a POST request
|
|
97
|
+
*/
|
|
98
|
+
async _fetchPost(path, data) {
|
|
99
|
+
return this.browserResponse(path, this.makeOptions('POST', data));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Performs an HTTP PUT request.
|
|
103
|
+
* @param {string} path - The path to append to the base URL.
|
|
104
|
+
* @param {unknown} body - The data to send in the request body.
|
|
105
|
+
* @returns {Promise<T>} A promise resolving to the response data.
|
|
106
|
+
* @description Define a protected asynchronous method '_fetchPut' that performs a PUT request
|
|
107
|
+
*/
|
|
108
|
+
async _fetchPut(path, body) {
|
|
109
|
+
return this.browserResponse(path, this.makeOptions('PUT', body));
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Performs an HTTP DELETE request.
|
|
113
|
+
* @param {string} path - The path to append to the base URL.
|
|
114
|
+
* @param {unknown} body - The body of the request.
|
|
115
|
+
* @returns {Promise<T>} A promise resolving to the response data.
|
|
116
|
+
* @description Define a protected asynchronous method '_fetchDelete' that performs a DELETE request
|
|
117
|
+
*/
|
|
118
|
+
async _fetchDelete(path, body) {
|
|
119
|
+
return this.browserResponse(path, this.makeOptions('DELETE', body));
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Wraps a fetch call whose only meaningful outcome is success or failure.
|
|
123
|
+
*
|
|
124
|
+
* Several endpoints (cancel/recover subscription, subscribe/unsubscribe to
|
|
125
|
+
* events) return no useful body — callers only care whether the request
|
|
126
|
+
* succeeded. This helper resolves to `true` on success and to the error
|
|
127
|
+
* (as IError) on failure, centralizing the repeated try/catch.
|
|
128
|
+
*
|
|
129
|
+
* The returned value has to be inspected as well: with `isShell` enabled
|
|
130
|
+
* (the default) browserResponse returns the API error instead of throwing
|
|
131
|
+
* it, so relying on the catch alone would report every failed call — a 404
|
|
132
|
+
* from cancelSubscription, a 403 from recoverSubscriptions — as a success.
|
|
133
|
+
* @param {() => Promise<unknown>} request - Thunk performing the fetch call.
|
|
134
|
+
* @returns {Promise<boolean | IError>} `true` on success, IError on failure.
|
|
135
|
+
*/
|
|
136
|
+
async _fetchBoolean(request) {
|
|
137
|
+
try {
|
|
138
|
+
const result = await request();
|
|
139
|
+
if (this._isErrorResponse(result)) {
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
catch (e) {
|
|
145
|
+
return e;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Refreshes the authentication token (single-flight).
|
|
150
|
+
* @returns {Promise<boolean>} A promise resolving to a boolean indicating success or failure.
|
|
151
|
+
* @description De-duplicates concurrent refreshes — the refresh token is single-use, so parallel requests must share one refresh call instead of each burning a rotated token.
|
|
152
|
+
*/
|
|
153
|
+
async refreshToken() {
|
|
154
|
+
// Reuse an in-flight refresh if one is already running (shared via state
|
|
155
|
+
// across all module instances). Prevents parallel requests from each firing
|
|
156
|
+
// their own refresh and invalidating the single-use refresh token.
|
|
157
|
+
if (this.state._refreshPromise) {
|
|
158
|
+
return this.state._refreshPromise;
|
|
159
|
+
}
|
|
160
|
+
const promise = this._performRefresh();
|
|
161
|
+
this.state._refreshPromise = promise;
|
|
162
|
+
try {
|
|
163
|
+
return await promise;
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
// Clear so the next genuine 401 (e.g. mid-session expiry) can refresh again.
|
|
167
|
+
this.state._refreshPromise = null;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Performs the actual token refresh request (without de-duplication).
|
|
172
|
+
* @returns {Promise<boolean>} A promise resolving to a boolean indicating success or failure.
|
|
173
|
+
* @description Sends POST /users/refresh and, on success, stores the rotated access/refresh tokens and calls saveFunction.
|
|
174
|
+
*/
|
|
175
|
+
async _performRefresh() {
|
|
176
|
+
const url = this.state.url +
|
|
177
|
+
`/api/content/users-auth-providers/marker/` +
|
|
178
|
+
this.state.providerMarker +
|
|
179
|
+
`/users/refresh`;
|
|
180
|
+
/**
|
|
181
|
+
* Perform a fetch request to the specified URL to refresh the token
|
|
182
|
+
* @param {string} url - The URL to which the request will be sent
|
|
183
|
+
* @param {object} options - The options for the fetch request
|
|
184
|
+
* @param {string} options.method - The HTTP method to use for the request (default: 'POST')
|
|
185
|
+
* @param {object} options.headers - Set the necessary headers for the request
|
|
186
|
+
* @param {object} options.body - Send the current refresh token in the request body as a JSON string
|
|
187
|
+
*/
|
|
188
|
+
const response = await fetch(url, {
|
|
189
|
+
method: 'POST',
|
|
190
|
+
headers: {
|
|
191
|
+
// Indicate that the request body is in JSON format
|
|
192
|
+
'Content-Type': 'application/json',
|
|
193
|
+
// Include the application token from the state
|
|
194
|
+
'x-app-token': this.state.token,
|
|
195
|
+
// Include the device fingerprint
|
|
196
|
+
'x-device-metadata': this._getDeviceMetadata(),
|
|
197
|
+
// x-guest-id is intentionally omitted: refresh is an auth-only call
|
|
198
|
+
// (a pure guest has no refresh token), so guest scoping does not apply.
|
|
199
|
+
},
|
|
200
|
+
body: JSON.stringify({ refreshToken: this.state.refreshToken }),
|
|
201
|
+
});
|
|
202
|
+
// Check if the response status is OK (status code 200-299)
|
|
203
|
+
if (response.ok) {
|
|
204
|
+
// Parse the response body as JSON and store the result
|
|
205
|
+
const result = await response.json();
|
|
206
|
+
// Update the state's refreshToken and accessToken with the new tokens from the response
|
|
207
|
+
this.state.refreshToken = result.refreshToken;
|
|
208
|
+
this.state.accessToken = result.accessToken;
|
|
209
|
+
// If a save function is defined in the state, call it with the new refresh token
|
|
210
|
+
if (this.state.saveFunction) {
|
|
211
|
+
this.state.saveFunction(result.refreshToken);
|
|
212
|
+
}
|
|
213
|
+
// Return true to indicate that the token refresh was successful
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
// Return false to indicate that the token refresh failed
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Creates options for HTTP requests.
|
|
223
|
+
* @param {string} method - The HTTP method (GET, POST, PUT, DELETE, etc.).
|
|
224
|
+
* @param {unknown} data - Optional data to include in the request body.
|
|
225
|
+
* @returns {IHttpOptions} An object representing the request options.
|
|
226
|
+
*/
|
|
227
|
+
makeOptions(method, data) {
|
|
228
|
+
const options = {
|
|
229
|
+
method: method,
|
|
230
|
+
headers: {
|
|
231
|
+
'Content-Type': 'application/json',
|
|
232
|
+
'x-app-token': this.state.token,
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
// Guest identifier — enables guest cart/wishlist/activity flows.
|
|
236
|
+
// Only sent for unauthenticated requests: once a user is logged in their
|
|
237
|
+
// own identity scopes the data, and sending the guest id would link the
|
|
238
|
+
// anonymous trail to the account. Omitted entirely when no id is available
|
|
239
|
+
// (e.g. server-side without an explicit guestId — see _getGuestId).
|
|
240
|
+
if (!this.state.accessToken) {
|
|
241
|
+
const guestId = this._getGuestId();
|
|
242
|
+
if (guestId) {
|
|
243
|
+
options.headers['x-guest-id'] = guestId;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// if method = 'POST' add x-device-metadata
|
|
247
|
+
if (method === 'POST') {
|
|
248
|
+
options.headers = {
|
|
249
|
+
...options.headers,
|
|
250
|
+
'x-device-metadata': this._getDeviceMetadata(),
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
// Check if 'data' is an instance of FormData or Blob
|
|
254
|
+
if (data instanceof FormData || data instanceof Blob) {
|
|
255
|
+
// Remove the 'Content-Type' header from options.headers
|
|
256
|
+
delete options.headers['Content-Type'];
|
|
257
|
+
// Set the 'accept' header to 'application/json', while preserving existing headers
|
|
258
|
+
options.headers = {
|
|
259
|
+
...options.headers,
|
|
260
|
+
accept: 'application/json',
|
|
261
|
+
};
|
|
262
|
+
// Assign 'data' to options.body for sending as request payload
|
|
263
|
+
options.body = data;
|
|
264
|
+
}
|
|
265
|
+
else if (data) {
|
|
266
|
+
// If 'data' exists and is not FormData or Blob, convert it to a JSON string
|
|
267
|
+
// and assign it to options.body
|
|
268
|
+
options.body = JSON.stringify(data);
|
|
269
|
+
}
|
|
270
|
+
// Check if there is an access token available in the state
|
|
271
|
+
if (this.state.accessToken) {
|
|
272
|
+
// Add an 'Authorization' header with the Bearer token to options.headers
|
|
273
|
+
options.headers['Authorization'] = 'Bearer ' + this.state.accessToken;
|
|
274
|
+
}
|
|
275
|
+
return options;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Reads a response body as JSON, tolerating an empty body.
|
|
279
|
+
*
|
|
280
|
+
* `Response.json()` throws on an empty body (e.g. 204 or an empty error
|
|
281
|
+
* payload); this helper mirrors the OK-path guard (`text ? JSON.parse : {}`)
|
|
282
|
+
* so both the success and the error branches handle empty bodies the same way.
|
|
283
|
+
* @param {Response} response - The fetch Response to read.
|
|
284
|
+
* @returns {Promise<unknown>} Parsed JSON, or an empty object when the body is empty/unparsable.
|
|
285
|
+
*/
|
|
286
|
+
async _parseJson(response) {
|
|
287
|
+
try {
|
|
288
|
+
const text = await response.text();
|
|
289
|
+
return text ? JSON.parse(text) : {};
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
return {};
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Handles responses from the browser's fetch API.
|
|
297
|
+
* @param {string} path - The path to append to the base URL.
|
|
298
|
+
* @param {IHttpOptions} options - The options for the fetch request.
|
|
299
|
+
* @returns {Promise<T>} A promise resolving to the response data.
|
|
300
|
+
* @description Define an asynchronous method 'browserResponse' that takes a path and options as parameters
|
|
301
|
+
*/
|
|
302
|
+
async browserResponse(path, options) {
|
|
303
|
+
// Set when a proactive refresh ran and failed (dead/expired refresh token):
|
|
304
|
+
// used below to skip the reactive refresh so we don't fire a second,
|
|
305
|
+
// equally-doomed refresh on the 401 that the request is about to return.
|
|
306
|
+
let proactiveRefreshFailed = false;
|
|
307
|
+
try {
|
|
308
|
+
// Proactive (eager) refresh: a session restored from storage has a refresh
|
|
309
|
+
// token but no access token yet. Sending the first authenticated request
|
|
310
|
+
// without an access token GUARANTEES a 401 (then a reactive refresh + retry)
|
|
311
|
+
// — a spurious 401 logged on every page load even for a perfectly valid
|
|
312
|
+
// session. Obtaining the access token up-front turns that into a clean 200.
|
|
313
|
+
// Fires at most once per session (skipped once accessToken is set), and is
|
|
314
|
+
// off for custom-auth callers who manage tokens themselves.
|
|
315
|
+
if (!this.state.accessToken &&
|
|
316
|
+
this.state.refreshToken &&
|
|
317
|
+
!this.state.customAuth) {
|
|
318
|
+
const refreshed = await this.refreshToken();
|
|
319
|
+
if (refreshed) {
|
|
320
|
+
// Authenticated now — attach the bearer and drop the guest scoping
|
|
321
|
+
// that makeOptions added while no access token was present.
|
|
322
|
+
options.headers['Authorization'] = 'Bearer ' + this.state.accessToken;
|
|
323
|
+
delete options.headers['x-guest-id'];
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
proactiveRefreshFailed = true;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
// Perform a fetch request using the full URL obtained from '_getFullPath' and the provided options
|
|
330
|
+
let response = await fetch(this._getFullPath(path), options);
|
|
331
|
+
// Reactive refresh for mid-session expiry: access token was present but
|
|
332
|
+
// the server rejected it. Skipped when a proactive refresh already ran
|
|
333
|
+
// and failed (the refresh token is dead — retrying would 400 again).
|
|
334
|
+
// On success the request is retried once; the retry response then flows
|
|
335
|
+
// through the SAME ok / error handling below (status check, errorsFunctions,
|
|
336
|
+
// isShell) instead of being returned blindly.
|
|
337
|
+
if (!response.ok &&
|
|
338
|
+
response.status === 401 &&
|
|
339
|
+
!this.state.customAuth &&
|
|
340
|
+
!proactiveRefreshFailed) {
|
|
341
|
+
const refresh = await this.refreshToken();
|
|
342
|
+
if (refresh) {
|
|
343
|
+
// Update the Authorization header with the new access token and retry.
|
|
344
|
+
options.headers['Authorization'] = 'Bearer ' + this.state.accessToken;
|
|
345
|
+
response = await fetch(this._getFullPath(path), options);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
// Check if the response status is OK (status code 200-299)
|
|
349
|
+
if (response.ok) {
|
|
350
|
+
// Read the body as text; if it is empty return an empty object,
|
|
351
|
+
// otherwise parse it as JSON. A parse failure propagates to the
|
|
352
|
+
// catch below and is handled according to isShell.
|
|
353
|
+
const text = await response.text();
|
|
354
|
+
return (text ? JSON.parse(text) : {});
|
|
355
|
+
}
|
|
356
|
+
// Handle non-OK responses (applies to the first response and to a failed retry).
|
|
357
|
+
const status = response.status;
|
|
358
|
+
const res = await this._parseJson(response);
|
|
359
|
+
const statusKey = status;
|
|
360
|
+
if (this.state.errorsFunctions && this.state.errorsFunctions[statusKey]) {
|
|
361
|
+
this.state.errorsFunctions[statusKey](res);
|
|
362
|
+
}
|
|
363
|
+
// Determine whether to return or throw the response based on 'isShell' state
|
|
364
|
+
if (this.state.isShell) {
|
|
365
|
+
return res;
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
throw res;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
catch (e) {
|
|
372
|
+
// Handle any errors that occur during the fetch process
|
|
373
|
+
// Determine whether to return or throw the error based on 'isShell' state
|
|
374
|
+
if (this.state.isShell) {
|
|
375
|
+
return e;
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
throw e;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a lazy schema loader bound to a module of Zod schemas.
|
|
3
|
+
*
|
|
4
|
+
* Validation is opt-in (`config.validation.enabled`, `false` by default), yet a static
|
|
5
|
+
* `import { PageEntitySchema } from './pagesSchemas'` would put Zod into the import graph
|
|
6
|
+
* of every consumer regardless. Binding the module behind a dynamic `import()` keeps it —
|
|
7
|
+
* and Zod — out of the bundle until a request actually needs to be validated.
|
|
8
|
+
* @param {() => Promise<TSchemas>} importSchemas - Dynamic import of the module holding the schemas.
|
|
9
|
+
* @returns {(name: keyof TSchemas) => () => Promise<TSchemas[keyof TSchemas]>} Function that takes
|
|
10
|
+
* a schema name and returns a loader for that schema.
|
|
11
|
+
* @description Usage: `const schema = createSchemaLoader(() => import('./pagesSchemas'))`,
|
|
12
|
+
* then `this._validateResponse(data, schema('PageEntitySchema'))`. The schema name is
|
|
13
|
+
* checked against the module's exports, so a typo is a compile-time error.
|
|
14
|
+
*/
|
|
15
|
+
export default function createSchemaLoader<TSchemas>(importSchemas: () => Promise<TSchemas>): <TName extends keyof TSchemas>(name: TName) => () => Promise<TSchemas[TName]>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a lazy schema loader bound to a module of Zod schemas.
|
|
3
|
+
*
|
|
4
|
+
* Validation is opt-in (`config.validation.enabled`, `false` by default), yet a static
|
|
5
|
+
* `import { PageEntitySchema } from './pagesSchemas'` would put Zod into the import graph
|
|
6
|
+
* of every consumer regardless. Binding the module behind a dynamic `import()` keeps it —
|
|
7
|
+
* and Zod — out of the bundle until a request actually needs to be validated.
|
|
8
|
+
* @param {() => Promise<TSchemas>} importSchemas - Dynamic import of the module holding the schemas.
|
|
9
|
+
* @returns {(name: keyof TSchemas) => () => Promise<TSchemas[keyof TSchemas]>} Function that takes
|
|
10
|
+
* a schema name and returns a loader for that schema.
|
|
11
|
+
* @description Usage: `const schema = createSchemaLoader(() => import('./pagesSchemas'))`,
|
|
12
|
+
* then `this._validateResponse(data, schema('PageEntitySchema'))`. The schema name is
|
|
13
|
+
* checked against the module's exports, so a typo is a compile-time error.
|
|
14
|
+
*/
|
|
15
|
+
export default function createSchemaLoader(importSchemas) {
|
|
16
|
+
return (name) => () => importSchemas().then((schemas) => schemas[name]);
|
|
17
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { IConfig, IError } from './utils.js';
|
|
2
|
+
declare const ERROR_STATUS_CODES: readonly [400, 401, 403, 404, 429, 500, 502, 503, 504];
|
|
3
|
+
type ErrorStatusCode = (typeof ERROR_STATUS_CODES)[number];
|
|
4
|
+
/**
|
|
5
|
+
* State module for managing application state and configuration.
|
|
6
|
+
* @description State module for managing application state and configuration.
|
|
7
|
+
*/
|
|
8
|
+
export default class StateModule {
|
|
9
|
+
url: string | undefined;
|
|
10
|
+
lang: string | undefined;
|
|
11
|
+
token: string | undefined;
|
|
12
|
+
guestId: string | undefined;
|
|
13
|
+
deviceMetadata: string | undefined;
|
|
14
|
+
accessToken: string | undefined;
|
|
15
|
+
traficLimit: boolean;
|
|
16
|
+
refreshToken: string | undefined;
|
|
17
|
+
_refreshPromise: Promise<boolean> | null;
|
|
18
|
+
providerMarker: string;
|
|
19
|
+
customAuth: boolean;
|
|
20
|
+
isShell: boolean;
|
|
21
|
+
validationEnabled: boolean;
|
|
22
|
+
validationStrictMode: boolean;
|
|
23
|
+
validationLogErrors: boolean;
|
|
24
|
+
rawData: boolean;
|
|
25
|
+
errorsFunctions: Partial<Record<ErrorStatusCode, (data: IError) => any>>;
|
|
26
|
+
saveFunction: (param: string) => void | null;
|
|
27
|
+
/**
|
|
28
|
+
* Constructor for StateModule
|
|
29
|
+
* @param {string} url - Base URL for API requests.
|
|
30
|
+
* @param {IConfig} config - Configuration object.
|
|
31
|
+
* @description Constructor for StateModule.
|
|
32
|
+
*/
|
|
33
|
+
constructor(url: string, config: IConfig);
|
|
34
|
+
}
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// HTTP status codes for which a custom error handler may be configured.
|
|
2
|
+
const ERROR_STATUS_CODES = [
|
|
3
|
+
400, 401, 403, 404, 429, 500, 502, 503, 504,
|
|
4
|
+
];
|
|
5
|
+
/**
|
|
6
|
+
* State module for managing application state and configuration.
|
|
7
|
+
* @description State module for managing application state and configuration.
|
|
8
|
+
*/
|
|
9
|
+
export default class StateModule {
|
|
10
|
+
/**
|
|
11
|
+
* Constructor for StateModule
|
|
12
|
+
* @param {string} url - Base URL for API requests.
|
|
13
|
+
* @param {IConfig} config - Configuration object.
|
|
14
|
+
* @description Constructor for StateModule.
|
|
15
|
+
*/
|
|
16
|
+
constructor(url, config) {
|
|
17
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
18
|
+
// In-flight token refresh, shared across all module instances (they share this
|
|
19
|
+
// state object). De-duplicates concurrent refreshes so the single-use refresh
|
|
20
|
+
// token is not burned by parallel requests. Null when no refresh is running.
|
|
21
|
+
this._refreshPromise = null;
|
|
22
|
+
this.url = url;
|
|
23
|
+
this.lang = (_a = config.langCode) !== null && _a !== void 0 ? _a : 'en_US';
|
|
24
|
+
this.token = config.token;
|
|
25
|
+
// Normalize empty string to undefined: an explicit '' must not masquerade
|
|
26
|
+
// as a set guest id (it would otherwise suppress id resolution).
|
|
27
|
+
this.guestId = config.guestId || undefined;
|
|
28
|
+
// Same normalization as guestId: an explicit '' must not suppress the
|
|
29
|
+
// environment-derived fingerprint.
|
|
30
|
+
this.deviceMetadata = config.deviceMetadata || undefined;
|
|
31
|
+
this.traficLimit = config.traficLimit || false;
|
|
32
|
+
this.validationEnabled = (_c = (_b = config.validation) === null || _b === void 0 ? void 0 : _b.enabled) !== null && _c !== void 0 ? _c : false;
|
|
33
|
+
this.validationStrictMode = (_e = (_d = config.validation) === null || _d === void 0 ? void 0 : _d.strictMode) !== null && _e !== void 0 ? _e : false;
|
|
34
|
+
this.validationLogErrors = (_g = (_f = config.validation) === null || _f === void 0 ? void 0 : _f.logErrors) !== null && _g !== void 0 ? _g : true;
|
|
35
|
+
this.rawData = (_h = config.rawData) !== null && _h !== void 0 ? _h : false;
|
|
36
|
+
this.refreshToken = (_k = (_j = config.auth) === null || _j === void 0 ? void 0 : _j.refreshToken) !== null && _k !== void 0 ? _k : undefined;
|
|
37
|
+
this.providerMarker = (_m = (_l = config.auth) === null || _l === void 0 ? void 0 : _l.providerMarker) !== null && _m !== void 0 ? _m : 'email';
|
|
38
|
+
this.customAuth = (_p = (_o = config.auth) === null || _o === void 0 ? void 0 : _o.customAuth) !== null && _p !== void 0 ? _p : false;
|
|
39
|
+
this.errorsFunctions = {};
|
|
40
|
+
this.saveFunction = (_r = (_q = config.auth) === null || _q === void 0 ? void 0 : _q.saveFunction) !== null && _r !== void 0 ? _r : null;
|
|
41
|
+
this.isShell = (_t = (_s = config.errors) === null || _s === void 0 ? void 0 : _s.isShell) !== null && _t !== void 0 ? _t : true;
|
|
42
|
+
const customErrors = (_u = config.errors) === null || _u === void 0 ? void 0 : _u.customErrors;
|
|
43
|
+
if (customErrors) {
|
|
44
|
+
for (const code of ERROR_STATUS_CODES) {
|
|
45
|
+
if (customErrors[code]) {
|
|
46
|
+
this.errorsFunctions[code] = customErrors[code];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|