oneentry 1.0.154 → 1.0.156

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 CHANGED
@@ -90,6 +90,8 @@ The second parameter of the constructor takes the 'config'. It contains the foll
90
90
 
91
91
  - 'guestId' - Optional guest identifier sent as the "x-guest-id" header on unauthenticated requests. It enables guest cart / wishlist / activity flows. In the browser, if you omit it, the SDK generates a stable id and persists it in localStorage. On the server you must pass a per-visitor "guestId" (or call "setGuestId"): the SDK never auto-generates a server id, to avoid sharing one guest across visitors. The header is omitted once a user is authenticated.
92
92
 
93
+ - 'deviceMetadata' - Optional device-metadata string sent as the "x-device-metadata" header instead of the fingerprint the SDK computes from the current environment. The API binds refresh tokens to this header, so a server that issues tokens on behalf of a browser (for example, an OAuth code exchange keeping the client secret server-side) must pass the browser's string here — otherwise the issued refresh token is bound to the server's fingerprint and cannot be refreshed from the browser. Obtain the string in the browser via "getDeviceMetadata()" and set/clear it at runtime via "setDeviceMetadata".
94
+
93
95
  - 'traficLimit' - Some methods use more than one request to the CMS so that the data you receive is complete and easy to work with. Pass the value "true" for this parameter to save traffic and decide for yourself what data you need. The default value "false".
94
96
 
95
97
  - 'auth' - An object with authorization settings. By default, the SDK is configured to work with tokens inside the user's session and does not require any additional work from you. At the same time, the SDK does not store the session state between sessions. If you are satisfied with such settings, do not pass the variable 'auth' at all.
@@ -179,6 +181,25 @@ const api = defineOneEntry('your-url', {
179
181
 
180
182
  OneEntry SDK supports optional validation of API responses using Zod. This feature is disabled by default and can be enabled for development or critical operations.
181
183
 
184
+ ### Time Intervals
185
+
186
+ Attributes of type `timeInterval` return a compact recurrence rule (an anchor date, daily time ranges and repeat flags), not a ready list of slots. The SDK does not expand it eagerly — a single attribute can materialize into megabytes of slots — so resolve it on demand with `expandAttributeTimeIntervals`, passing the window you actually render:
187
+
188
+ ```js
189
+ import { defineOneEntry, expandAttributeTimeIntervals } from 'oneentry'
190
+
191
+ const { Pages } = defineOneEntry('your-url', { token: 'your-app-token' })
192
+ const page = await Pages.getPageByUrl('booking')
193
+
194
+ const slots = expandAttributeTimeIntervals(page.attributeValues.interval, {
195
+ from: '2025-04-01',
196
+ to: '2025-04-30',
197
+ })
198
+ // [['2025-04-14T09:00:00.000Z', '2025-04-14T10:00:00.000Z'], …]
199
+ ```
200
+
201
+ Also exported: `expandTimeIntervals(schedule, window)` for a single schedule (e.g. a form's `localizeInfos.intervals`), and the `isTimeIntervalAttribute` type guard.
202
+
182
203
  ### Errors
183
204
 
184
205
  If you want to escape errors inside the sc, leave the "errors" property by default.
package/changelog.md CHANGED
@@ -1,5 +1,90 @@
1
1
  # SDK Change Log
2
2
 
3
+ ## v.1.0.156
4
+
5
+ ### What's New
6
+
7
+ - `expandAttributeTimeIntervals(attr, { from, to })` — new top-level export that resolves a whole `timeInterval` attribute into concrete `[start, end]` ISO pairs for a window you choose. This is the one-call replacement for the removed `timeIntervals` field: it walks the attribute's groups and schedules and merges the results (merging matters — deduplication and ordering only hold within a single schedule). Anything that is not a `timeInterval` attribute yields an empty array, so it is safe to call without checking `type` first.
8
+
9
+ ```ts
10
+ import { expandAttributeTimeIntervals } from 'oneentry';
11
+
12
+ const slots = expandAttributeTimeIntervals(page.attributeValues.interval, {
13
+ from: '2025-04-01',
14
+ to: '2025-04-30',
15
+ });
16
+ // [['2025-04-14T09:00:00.000Z', '2025-04-14T10:00:00.000Z'], …]
17
+ ```
18
+
19
+ - `expandTimeIntervals(schedule, { from, to })` — new top-level export that resolves a single schedule. Accepts both shapes the API returns: entity schedules (`attributeValues[marker].value[].values[]` on pages, products, blocks and attribute sets) and form schedules (`attributes[].localizeInfos.intervals[]`). Use it when you already hold one schedule — most notably on forms, whose schedules are already typed:
20
+
21
+ ```ts
22
+ const field = form.attributes.find((a) => a.marker === 'booking');
23
+
24
+ const slots = (field?.localizeInfos.intervals ?? []).flatMap((schedule) =>
25
+ expandTimeIntervals(schedule, { from: '2025-05-01', to: '2025-05-31' }),
26
+ );
27
+ ```
28
+
29
+ Both functions are pure — they do not mutate their input and perform no requests.
30
+
31
+ - `isTimeIntervalAttribute(attr)` — new exported type guard narrowing an `IAttributeValue` to `ITimeIntervalAttributeValue`. `IAttributeValue.value` is `unknown` because its shape depends on `type`; this guard is what lets you reach the schedules without a cast:
32
+
33
+ ```ts
34
+ const attr = page.attributeValues.interval;
35
+ if (isTimeIntervalAttribute(attr)) {
36
+ attr.value[0].values[0].dates; // fully typed
37
+ }
38
+ ```
39
+
40
+ - `ITimeIntervalAttributeValue`, `ITimeIntervalGroup`, `ITimeIntervalEntitySchedule`, `ITimeIntervalWindow` and `TimeIntervalPair` — new exported types covering the whole `timeInterval` payload: the attribute, its groups, an entity schedule, the expansion window and a resolved slot. `ITimeIntervalSchedule` and `IAttributeValue` are now exported for the same reason. The payload previously had no typed representation at all.
41
+
42
+ ### What's Changed
43
+
44
+ - `ITimeIntervalSchedule` — `range` is typed `string[]` instead of `unknown[]` (it is a pair of ISO dates), and the optional `inEveryWeek` flag is documented; the SDK always read it, but the interface omitted it.
45
+
46
+ ### Bug Fixes
47
+
48
+ These affect `expandTimeIntervals`, which replaces the removed built-in expansion:
49
+
50
+ - The expansion horizon is no longer hardcoded. Monthly recurrence stopped exactly 12 months after the anchor and weekly recurrence stopped at the end of the anchor's month, so slots beyond that could not be obtained at all. The window is now the horizon.
51
+ - A schedule with no recurrence flags (`inEveryWeek: false, inEveryMonth: false`) produced no intervals at all — `_processScheduleDates` had no branch for that case. A plain date range now yields slots for every day in it.
52
+ - Weekly recurrence combined with monthly no longer emits dates **before** the schedule's start date. The old branch walked from the 1st of the anchor's month, so a schedule starting Monday 2025-04-14 also emitted 2025-04-07.
53
+ - Weekly recurrence was host-timezone dependent: it computed its end-of-month bound with `getFullYear`/`getMonth` (local time) while every other date operation used UTC, so the result shifted with the machine's timezone. All arithmetic is now UTC.
54
+ - Weekly+monthly recurrence silently dropped months: it advanced the month before pinning the day to the 1st, so an anchor on the 31st overflowed short months and lost 5 of 12 months.
55
+ - Identical intervals are now actually deduplicated. The old code collected into a `Set` of array references, which compares by identity, so duplicates always survived despite the intent.
56
+ - A range with a non-positive `period` no longer hangs. The slot loop never advanced its cursor and spun forever; such ranges are now skipped.
57
+ - Malformed input no longer throws. `_addTimeIntervalsToFormSchedules` dereferenced its argument unguarded (`TypeError` on `undefined`), and both expanders read `dates[0]` / `range[0]` without checking the array existed. `expandTimeIntervals` returns an empty array instead.
58
+
59
+ ### What's Deleted
60
+
61
+ - **Breaking** — the computed `timeIntervals` field is no longer added to `timeInterval` attribute values. It was injected into every response carrying a `timeInterval` attribute (pages, products, blocks, attribute sets and forms) and materialized a full year of slots regardless of what the caller needed: a single attribute with hourly slots expanded to roughly 2,000 lines of JSON, and finer slot periods reached megabytes — enough to blow past framework data-cache limits. The field was never declared in any interface or Zod schema, so TypeScript consumers could only reach it through a cast.
62
+
63
+ Migrate by calling `expandAttributeTimeIntervals(attr, window)` with the window you actually render. The source data it expands (`dates`/`range`, `times`/`intervals`, `inEveryWeek`, `inEveryMonth`) is unchanged and still on every schedule, so nothing is lost — it is now resolved on demand instead of eagerly, and the compact rule is what gets cached.
64
+
65
+ - `_addTimeIntervalsToSchedules` and `_addTimeIntervalsToFormSchedules` — removed from every module. Despite the `_` prefix these were public and callable (e.g. `Pages._addTimeIntervalsToSchedules`). Use `expandTimeIntervals`.
66
+
67
+ ## v.1.0.155
68
+
69
+ ### What's New
70
+
71
+ - Config > `deviceMetadata` — new optional config parameter that overrides the `x-device-metadata` header (sent on POST requests and token refresh) instead of the fingerprint computed from the current environment. The API binds refresh tokens to this header, so a server issuing tokens on behalf of a browser (e.g. an OAuth code exchange that keeps the client secret server-side) can now stamp the browser's fingerprint and the issued refresh token stays refreshable from that browser. Previously this required bypassing the SDK with a raw `fetch`.
72
+ - `setDeviceMetadata(deviceMetadata)` — new public method on every module: sets the `x-device-metadata` override at runtime (empty string clears it and falls back to the computed fingerprint).
73
+ - `getDeviceMetadata()` — new public method on every module: returns the `x-device-metadata` string the SDK sends (the override when set, otherwise the environment-derived fingerprint). Use it in the browser to obtain the value that a server-side token-issuing flow must forward; previously this required reaching into the protected `_getDeviceMetadata`.
74
+
75
+ ### Bug Fixes
76
+
77
+ - `Blocks.getBlocks` — error responses no longer crash block enrichment. On an API error (e.g. `403` without list permission, or `422`) the normalized value is an `IError` without an `items` array; the method previously called `.items.map(...)` unconditionally and threw a `TypeError`. Enrichment now runs only when `items` is an array, and the error response is returned as-is.
78
+
79
+ - `Pages.getRootPages`, `getPages`, `getChildPagesByParentUrl`, `searchPage` — error responses no longer crash template enrichment. The shared `addTemplateToPages` helper called `.filter(...)` / `.map(...)` on its input; on an API error (e.g. `403` / `422`) that input is an `IError` object, not an array, which threw a `TypeError`. The helper now returns the error response as-is when the input is not an array.
80
+
81
+ - `Blocks.getProductsByBlockMarker` (used internally by block enrichment) — on an API error the method read `result.items` (which is `undefined` for an `IError`) and returned `undefined` instead of the error. It now returns the normalized error response when there is no `items` array.
82
+
83
+ ### What's Deleted
84
+
85
+ - AttributesSets > `IAttributeSetsEntity.typeId` and `IAttributeSetsEntity.properties` — removed: the API no longer returns these fields for `getAttributes` / `getAttributeSetByMarker`. The attribute set type is available via the `type` object (`type.id`, `type.type`). The Zod schema (`AttributeSetEntitySchema`) is updated accordingly. The `typeId` **query parameter** of `getAttributes` is unaffected.
86
+ - TemplatePreviews > `ITemplatesPreviewEntity.attributeValues` — removed: the API no longer returns this field for `getTemplatePreviews` / `getTemplatePreviewByMarker` (it was always an empty object). The Zod schema (`TemplatePreviewEntitySchema`) is updated accordingly.
87
+
3
88
  ## v.1.0.154
4
89
 
5
90
  ### What's New
@@ -226,7 +311,7 @@
226
311
 
227
312
  - Discounts > `getAllDiscounts` — removed `'PERSONAL_BONUS'` from type filter parameter.
228
313
 
229
- - Forms > `IFormsEntity` — type narrowed to `'order' | 'sing_in_up' | 'collection' | 'data' | 'rating'`, removed `moduleFormConfigs` field.
314
+ - Forms > `IFormsEntity` — type narrowed to `'order' | 'sign_in_up' | 'collection' | 'data' | 'rating'`, removed `moduleFormConfigs` field.
230
315
 
231
316
  - Products > `getProductsEmptyPage` — changed from GET to POST, added `body` parameter, return type changed to `IAggregatedProductGroup[]`.
232
317
 
@@ -206,7 +206,6 @@ interface IAttributeValidators {
206
206
  * @property {string} updatedDate - The date when the attribute set was last updated. Example: "2023-10-01T12:00:00Z".
207
207
  * @property {number} version - The version number of the attribute set, used for tracking changes or updates. Example: 1.
208
208
  * @property {string} identifier - A string that uniquely identifies the attribute set. Example: "attributeSet1".
209
- * @property {number} typeId - The numerical identifier representing the type of the attribute set. Example: 1.
210
209
  * @property {string} title - The title or name of the attribute set. Example: "Product Attributes".
211
210
  * @property {Record<string, IAttributeSchemaItem>} schema - Schema fields keyed by marker.
212
211
  * @example
@@ -223,12 +222,6 @@ interface IAttributeValidators {
223
222
  }
224
223
  }
225
224
  * @property {boolean} isVisible - Indicates whether the attribute set is visible or not. Example: true.
226
- * @property {Record<string, unknown>} properties - Additional properties associated with the attribute set; empty object when none.
227
- * @example
228
- {
229
- "color": "red",
230
- "size": "M"
231
- }
232
225
  * @property {string} type - The type of the attribute set, which could be a specific classification or category. Example: "product", "user", "etc".
233
226
  * @property {number} position - The position number for sorting the attribute set. Example: 1.
234
227
  * @description This interface defines the structure of an attribute set entity.
@@ -239,11 +232,9 @@ interface IAttributeSetsEntity {
239
232
  updatedDate: string;
240
233
  version: number;
241
234
  identifier: string;
242
- typeId: number;
243
235
  title: string;
244
236
  schema: Record<string, IAttributeSchemaItem>;
245
237
  isVisible: boolean;
246
- properties: Record<string, unknown>;
247
238
  type: IAttributeSetTypeRef;
248
239
  position: number;
249
240
  }
@@ -38,11 +38,9 @@ export declare const AttributeSetEntitySchema: z.ZodObject<{
38
38
  updatedDate: z.ZodString;
39
39
  version: z.ZodNumber;
40
40
  identifier: z.ZodString;
41
- typeId: z.ZodNumber;
42
41
  title: z.ZodString;
43
42
  schema: z.ZodObject<{}, z.core.$loose>;
44
43
  isVisible: z.ZodBoolean;
45
- properties: z.ZodObject<{}, z.core.$loose>;
46
44
  type: z.ZodObject<{
47
45
  id: z.ZodNumber;
48
46
  type: z.ZodString;
@@ -60,11 +58,9 @@ export declare const AttributeSetsResponseSchema: z.ZodObject<{
60
58
  updatedDate: z.ZodString;
61
59
  version: z.ZodNumber;
62
60
  identifier: z.ZodString;
63
- typeId: z.ZodNumber;
64
61
  title: z.ZodString;
65
62
  schema: z.ZodObject<{}, z.core.$loose>;
66
63
  isVisible: z.ZodBoolean;
67
- properties: z.ZodObject<{}, z.core.$loose>;
68
64
  type: z.ZodObject<{
69
65
  id: z.ZodNumber;
70
66
  type: z.ZodString;
@@ -47,11 +47,9 @@ exports.AttributeSetEntitySchema = zod_1.z.object({
47
47
  updatedDate: zod_1.z.string(),
48
48
  version: zod_1.z.number(),
49
49
  identifier: zod_1.z.string(),
50
- typeId: zod_1.z.number(),
51
50
  title: zod_1.z.string(),
52
51
  schema: zod_1.z.object({}).passthrough(),
53
52
  isVisible: zod_1.z.boolean(),
54
- properties: zod_1.z.object({}).passthrough(),
55
53
  type: zod_1.z.object({
56
54
  id: zod_1.z.number(),
57
55
  type: zod_1.z.string(),
@@ -10,6 +10,7 @@ export default class StateModule {
10
10
  lang: string | undefined;
11
11
  token: string | undefined;
12
12
  guestId: string | undefined;
13
+ deviceMetadata: string | undefined;
13
14
  accessToken: string | undefined;
14
15
  traficLimit: boolean;
15
16
  refreshToken: string | undefined;
@@ -27,6 +27,9 @@ class StateModule {
27
27
  // Normalize empty string to undefined: an explicit '' must not masquerade
28
28
  // as a set guest id (it would otherwise suppress id resolution).
29
29
  this.guestId = config.guestId || undefined;
30
+ // Same normalization as guestId: an explicit '' must not suppress the
31
+ // environment-derived fingerprint.
32
+ this.deviceMetadata = config.deviceMetadata || undefined;
30
33
  this.traficLimit = config.traficLimit || false;
31
34
  this.validationEnabled = (_c = (_b = config.validation) === null || _b === void 0 ? void 0 : _b.enabled) !== null && _c !== void 0 ? _c : false;
32
35
  this.validationStrictMode = (_e = (_d = config.validation) === null || _d === void 0 ? void 0 : _d.strictMode) !== null && _e !== void 0 ? _e : false;
@@ -111,113 +111,6 @@ export default abstract class SyncModules {
111
111
  * @returns {any} Sorted attributes.
112
112
  */
113
113
  protected _sortAttributes: (data: any) => any;
114
- /**
115
- * Adds a specified number of days to a date.
116
- * @param {Date} date - The initial date.
117
- * @param {number} days - The number of days to add.
118
- * @returns {any} The new date with added days.
119
- */
120
- protected _addDays(date: Date, days: number): any;
121
- /**
122
- * Common logic for processing schedule dates (weekly, monthly, or both).
123
- *
124
- * Abstracts date iteration for three scheduling modes:
125
- *
126
- * - **`inEveryWeek` only**: starting from the start date, generates dates
127
- * with a 7-day step until the end of the current month.
128
- *
129
- * - **`inEveryMonth` only**: pins the day-of-month from the start date
130
- * and repeats it for each of the next 12 months. If the month does not
131
- * have that day (e.g. Feb 31), the iteration is skipped.
132
- *
133
- * - **`inEveryWeek` + `inEveryMonth`**: for each of the next 12 months finds
134
- * the first occurrence of the target weekday (from the start date), then
135
- * iterates all occurrences of that weekday in the month with a 7-day step.
136
- *
137
- * `processDate(currentDate)` is called for every resolved date.
138
- * @param {Date} date - The date for which to process intervals.
139
- * @param {object} config - Configuration for schedule repetition.
140
- * @param {boolean} config.inEveryWeek - Whether to repeat weekly.
141
- * @param {boolean} config.inEveryMonth - Whether to repeat monthly.
142
- * @param {(currentDate: Date) => void} processDate - Callback function to process each date.
143
- */
144
- protected _processScheduleDates(date: Date, config: {
145
- inEveryWeek: boolean;
146
- inEveryMonth: boolean;
147
- }, processDate: (currentDate: Date) => void): void;
148
- /**
149
- * Generates intervals for a specific date based on a schedule.
150
- *
151
- * For each date resolved by `_processScheduleDates`, iterates over
152
- * the `schedule.times` array of time ranges. Each range is a pair
153
- * `[startTime, endTime]` with `{ hours, minutes }` fields.
154
- * Creates an ISO interval `[start.toISOString(), end.toISOString()]`
155
- * and adds it to `utcIntervals` (Set deduplicates automatically).
156
- * @param {Date} date - The date for which to generate intervals.
157
- * @param {object} schedule - The schedule defining the intervals.
158
- * @param {boolean} schedule.inEveryWeek - The number of weeks between intervals.
159
- * @param {any[]} schedule.times - The times for each interval.
160
- * @param {boolean} schedule.inEveryMonth - The month intervals for each interval.
161
- * @param {Set<Array<string>>} utcIntervals - A set to store unique intervals.
162
- */
163
- protected _generateIntervalsForDate(date: Date, schedule: {
164
- inEveryWeek: boolean;
165
- times: any[];
166
- inEveryMonth: boolean;
167
- }, utcIntervals: Set<Array<string>>): void;
168
- /**
169
- * Adds time intervals to schedules.
170
- *
171
- * Accepts an array of schedule groups (structure of `timeInterval` attributes
172
- * for pages/products). For each group iterates over `values` — the set of
173
- * concrete schedules. Each schedule contains a date range `dates[0..1]`.
174
- *
175
- * If both boundaries are equal (`isSameDay`), intervals are generated only
176
- * for that single date. Otherwise — for every day in the range inclusive.
177
- *
178
- * The result (`schedule.timeIntervals`) is a sorted array of ISO pairs,
179
- * ready to pass to UI components.
180
- * @param {any[]} schedules - The schedules to process.
181
- * @returns {any} Schedules with added time intervals.
182
- */
183
- _addTimeIntervalsToSchedules(schedules: any[]): any;
184
- /**
185
- * Generates intervals for a specific date for form schedules.
186
- *
187
- * Unlike `_generateIntervalsForDate`, time ranges here have a different shape:
188
- * each `timeInterval` contains `start`, `end` and `period`
189
- * (slot length in minutes). The method slices the [start, end) window into
190
- * fixed-length slots of `period` minutes:
191
- *
192
- * start=09:00, end=12:00, period=30 → [09:00–09:30], [09:30–10:00], …, [11:30–12:00]
193
- *
194
- * Generation stops if the next slot would exceed `end`.
195
- * Each slot is added to `utcIntervals` (Set deduplicates automatically).
196
- * @param {Date} date - The date for which to generate intervals.
197
- * @param {object} interval - The interval configuration.
198
- * @param {boolean} interval.inEveryWeek - Indicates whether the schedule is weekly.
199
- * @param {boolean} interval.inEveryMonth - Indicates whether the schedule is monthly.
200
- * @param {any[]} timeIntervals - The time intervals to process.
201
- * @param {Set<Array<string>>} utcIntervals - A set to store unique intervals.
202
- */
203
- protected _generateIntervalsForFormDate(date: Date, interval: {
204
- inEveryWeek: boolean;
205
- inEveryMonth: boolean;
206
- }, timeIntervals: any[], utcIntervals: Set<Array<string>>): void;
207
- /**
208
- * Adds time intervals to form schedules (different structure).
209
- *
210
- * Same as `_addTimeIntervalsToSchedules` but for `timeInterval` attributes
211
- * in **forms** (different API data structure):
212
- * - `interval.range[0..1]` instead of `schedule.dates[0..1]`
213
- * - `interval.intervals` — array of time ranges with slots (`period`)
214
- * instead of `[startTime, endTime]` pairs
215
- *
216
- * Result is written to `interval.timeIntervals`.
217
- * @param {any[]} intervals - The intervals to process.
218
- * @returns {any} Intervals with added time intervals.
219
- */
220
- _addTimeIntervalsToFormSchedules(intervals: any[]): any;
221
114
  /**
222
115
  * Transforms additionalFields from array to object keyed by marker.
223
116
  *
@@ -238,16 +131,20 @@ export default abstract class SyncModules {
238
131
  * Contains an object `{ marker: AttrObject }`. For each attribute:
239
132
  * - `_normalizeAdditionalFields` is called;
240
133
  * - numeric types (`integer`, `float`) are cast to a JS number (or `null`);
241
- * - `timeInterval` attributes are enriched with computed `timeIntervals`;
242
134
  * - the whole object is re-sorted by `position`.
243
135
  *
244
136
  * **2. `attributes`** — form attributes (different API structure).
245
- * Same `additionalFields` and `timeInterval` processing,
137
+ * Same `additionalFields` processing,
246
138
  * but numbers are not normalized here (commented out — logic differs).
247
139
  *
248
140
  * **3. `type`** — a single attribute from an attribute set.
249
141
  * Same transformations as in case 1, but without sorting.
250
142
  *
143
+ * `timeInterval` attributes are left exactly as the API returned them — a
144
+ * compact recurrence rule. Resolving one into concrete slots is the caller's
145
+ * job, via `expandTimeIntervals`: the rule is open-ended, so only the caller
146
+ * knows how wide a window it needs.
147
+ *
251
148
  * If none of the keys are found — data is returned unchanged.
252
149
  * @param {any} data - The data to normalize.
253
150
  * @returns {any} Normalized attributes.
@@ -287,6 +184,30 @@ export default abstract class SyncModules {
287
184
  * @returns {any} The instance of SyncModules for chaining.
288
185
  */
289
186
  setGuestId(guestId: string): any;
187
+ /**
188
+ * Sets the device-metadata override in the state.
189
+ *
190
+ * Once set, the string is sent as the `x-device-metadata` header on POST
191
+ * requests and token refresh instead of the environment-derived fingerprint.
192
+ * The API binds refresh tokens to this header, so server-side flows that issue
193
+ * tokens on behalf of a browser (e.g. an OAuth code exchange) must set the
194
+ * browser's string (obtained there via `getDeviceMetadata`). Pass an empty
195
+ * string to clear the override and fall back to the computed fingerprint.
196
+ * @param {string} deviceMetadata - The metadata string to send (empty string clears the override).
197
+ * @returns {any} The instance of SyncModules for chaining.
198
+ */
199
+ setDeviceMetadata(deviceMetadata: string): any;
200
+ /**
201
+ * Returns the device-metadata string the SDK sends as the `x-device-metadata` header.
202
+ *
203
+ * Public counterpart of `_getDeviceMetadata`: an explicit override (config or
204
+ * `setDeviceMetadata`) wins, otherwise the environment-derived fingerprint is
205
+ * computed. Use it in the browser to obtain the string that a server-side
206
+ * token-issuing flow (OAuth code exchange) must forward, so the issued refresh
207
+ * token stays refreshable from this browser.
208
+ * @returns {string} The metadata string sent with requests from this instance.
209
+ */
210
+ getDeviceMetadata(): string;
290
211
  /**
291
212
  * Get deviceMetadata
292
213
  *
@@ -313,6 +234,10 @@ export default abstract class SyncModules {
313
234
  * lives until the process restarts.
314
235
  *
315
236
  * In a Node.js environment (no `window`) returns a simplified object without screen/navigator.
237
+ *
238
+ * An explicitly provided string (`deviceMetadata` in config or `setDeviceMetadata`)
239
+ * takes precedence over the environment-derived fingerprint — this lets a server
240
+ * issue tokens bound to the browser's fingerprint (see `IConfig.deviceMetadata`).
316
241
  * @returns {string} - Returns an object containing device metadata.
317
242
  */
318
243
  protected _getDeviceMetadata(): string;