oneentry 1.0.161 → 1.0.163

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.
Files changed (87) hide show
  1. package/README.md +18 -0
  2. package/changelog.md +80 -3
  3. package/dist/admins/adminsInterfaces.d.ts +2 -0
  4. package/dist/admins/adminsSchemas.d.ts +8 -22
  5. package/dist/admins/adminsSchemas.js +3 -9
  6. package/dist/attribute-sets/attributeSetsInterfaces.d.ts +8 -6
  7. package/dist/auth-provider/authProviderSchemas.d.ts +1 -0
  8. package/dist/auth-provider/authProvidersInterfaces.d.ts +4 -4
  9. package/dist/base/attributes.d.ts +105 -0
  10. package/dist/base/attributes.js +172 -0
  11. package/dist/base/utils.d.ts +95 -2
  12. package/dist/base/validation.d.ts +30 -0
  13. package/dist/base/validation.js +94 -1
  14. package/dist/blocks/blocksApi.d.ts +16 -8
  15. package/dist/blocks/blocksApi.js +24 -15
  16. package/dist/blocks/blocksInterfaces.d.ts +17 -9
  17. package/dist/blocks/blocksSchemas.d.ts +6 -6
  18. package/dist/blocks/blocksSchemas.js +2 -1
  19. package/dist/discounts/discountsInterfaces.d.ts +3 -1
  20. package/dist/forms-data/formsDataApi.d.ts +16 -6
  21. package/dist/forms-data/formsDataApi.js +14 -4
  22. package/dist/forms-data/formsDataInterfaces.d.ts +57 -20
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.js +9 -1
  25. package/dist/integration-collections/integrationCollectionsInterfaces.d.ts +6 -6
  26. package/dist/menus/menusInterfaces.d.ts +5 -1
  27. package/dist/menus/menusSchemas.js +4 -1
  28. package/dist/orders/ordersInterfaces.d.ts +3 -1
  29. package/dist/orders/ordersSchemas.d.ts +2 -0
  30. package/dist/orders/ordersSchemas.js +1 -0
  31. package/dist/pages/pagesApi.d.ts +1 -11
  32. package/dist/pages/pagesApi.js +0 -17
  33. package/dist/pages/pagesInterfaces.d.ts +3 -20
  34. package/dist/pages/pagesSchemas.d.ts +6 -10
  35. package/dist/pages/pagesSchemas.js +4 -9
  36. package/dist/product-statuses/productStatusesInterfaces.d.ts +2 -2
  37. package/dist/products/productsSchemas.d.ts +5 -5
  38. package/dist/products/productsSchemas.js +3 -2
  39. package/dist/templates/templatesInterfaces.d.ts +1 -1
  40. package/dist/templates/templatesSchemas.d.ts +3 -3
  41. package/dist/templates/templatesSchemas.js +2 -1
  42. package/dist/templates-preview/templatesPreviewInterfaces.d.ts +2 -2
  43. package/dist/users/usersInterfaces.d.ts +2 -0
  44. package/dist/users/usersSchemas.d.ts +1 -0
  45. package/esm/admins/adminsInterfaces.d.ts +2 -0
  46. package/esm/admins/adminsSchemas.d.ts +8 -22
  47. package/esm/admins/adminsSchemas.js +3 -9
  48. package/esm/attribute-sets/attributeSetsInterfaces.d.ts +8 -6
  49. package/esm/auth-provider/authProviderSchemas.d.ts +1 -0
  50. package/esm/auth-provider/authProvidersInterfaces.d.ts +4 -4
  51. package/esm/base/attributes.d.ts +105 -0
  52. package/esm/base/attributes.js +163 -0
  53. package/esm/base/utils.d.ts +95 -2
  54. package/esm/base/validation.d.ts +30 -0
  55. package/esm/base/validation.js +93 -0
  56. package/esm/blocks/blocksApi.d.ts +16 -8
  57. package/esm/blocks/blocksApi.js +24 -15
  58. package/esm/blocks/blocksInterfaces.d.ts +17 -9
  59. package/esm/blocks/blocksSchemas.d.ts +6 -6
  60. package/esm/blocks/blocksSchemas.js +2 -1
  61. package/esm/discounts/discountsInterfaces.d.ts +3 -1
  62. package/esm/forms-data/formsDataApi.d.ts +16 -6
  63. package/esm/forms-data/formsDataApi.js +14 -4
  64. package/esm/forms-data/formsDataInterfaces.d.ts +57 -20
  65. package/esm/index.d.ts +1 -0
  66. package/esm/index.js +1 -0
  67. package/esm/integration-collections/integrationCollectionsInterfaces.d.ts +6 -6
  68. package/esm/menus/menusInterfaces.d.ts +5 -1
  69. package/esm/menus/menusSchemas.js +4 -1
  70. package/esm/orders/ordersInterfaces.d.ts +3 -1
  71. package/esm/orders/ordersSchemas.d.ts +2 -0
  72. package/esm/orders/ordersSchemas.js +1 -0
  73. package/esm/pages/pagesApi.d.ts +1 -11
  74. package/esm/pages/pagesApi.js +0 -17
  75. package/esm/pages/pagesInterfaces.d.ts +3 -20
  76. package/esm/pages/pagesSchemas.d.ts +6 -10
  77. package/esm/pages/pagesSchemas.js +3 -8
  78. package/esm/product-statuses/productStatusesInterfaces.d.ts +2 -2
  79. package/esm/products/productsSchemas.d.ts +5 -5
  80. package/esm/products/productsSchemas.js +3 -2
  81. package/esm/templates/templatesInterfaces.d.ts +1 -1
  82. package/esm/templates/templatesSchemas.d.ts +3 -3
  83. package/esm/templates/templatesSchemas.js +2 -1
  84. package/esm/templates-preview/templatesPreviewInterfaces.d.ts +2 -2
  85. package/esm/users/usersInterfaces.d.ts +2 -0
  86. package/esm/users/usersSchemas.d.ts +1 -0
  87. package/package.json +2 -2
@@ -0,0 +1,163 @@
1
+ const _FILE_TYPES = ['image', 'file', 'groupOfImages'];
2
+ /**
3
+ * Tests whether a value looks like a file object of an attribute.
4
+ *
5
+ * A file is identified by `downloadLink`: it is the one field every file of
6
+ * every attribute carries, while previews are only generated for images.
7
+ * @param {unknown} value - The value to test.
8
+ * @returns {boolean} True when the value is a file object.
9
+ */
10
+ function _isFile(value) {
11
+ return (!!value &&
12
+ typeof value === 'object' &&
13
+ typeof value.downloadLink === 'string');
14
+ }
15
+ /**
16
+ * Narrows an attribute value to a file-bearing attribute.
17
+ *
18
+ * `IAttributeValue.value` is `unknown` — its shape depends on `type` — so this
19
+ * guard is what lets you reach the files without a cast. It accepts both shapes
20
+ * the SDK produces: a single file object for an `image`/`file` attribute holding
21
+ * exactly one file, an array for several and for every `groupOfImages`.
22
+ * @param {IAttributeValue | undefined} attr - The attribute value to test.
23
+ * @returns {boolean} True when the attribute is an `image`, `file` or `groupOfImages` carrying files (or nothing).
24
+ * @example
25
+ * ```ts
26
+ * const attr = page.attributeValues.cover;
27
+ * if (isFileAttribute(attr)) {
28
+ * // attr.value is IAttributeFile | IAttributeFile[] | null — no cast
29
+ * }
30
+ * ```
31
+ */
32
+ export function isFileAttribute(attr) {
33
+ if (!attr || !_FILE_TYPES.includes(attr.type))
34
+ return false;
35
+ if (attr.value === null || attr.value === undefined)
36
+ return true;
37
+ return Array.isArray(attr.value)
38
+ ? attr.value.every((item) => _isFile(item))
39
+ : _isFile(attr.value);
40
+ }
41
+ /**
42
+ * Reads every file of an attribute as an array.
43
+ *
44
+ * The one-call path for the common case. An `image`/`file` attribute holding a
45
+ * single file has it unwrapped to the object itself, while several files and
46
+ * every `groupOfImages` stay an array — a rule that is easy to get wrong in a
47
+ * way the compiler cannot catch, since `value` is `unknown`: reading `value[0]`
48
+ * off a single file yields `undefined` and nothing anywhere reports an error.
49
+ * This helper collapses both shapes to a list.
50
+ *
51
+ * Anything that is not a file-bearing attribute yields an empty array, so it is
52
+ * safe to call on an arbitrary attribute without checking `type` first.
53
+ * @param {IAttributeValue | undefined} attr - An attribute value, e.g. `page.attributeValues.cover`.
54
+ * @returns {IAttributeFile[]} The files, in the order the API returned them; empty when the attribute holds none or is not file-bearing.
55
+ * @example
56
+ * ```ts
57
+ * import { getAttributeFiles } from 'oneentry';
58
+ *
59
+ * // Works the same for one image and for a gallery.
60
+ * const images = getAttributeFiles(page.attributeValues.cover);
61
+ * images.map((file) => file.downloadLink);
62
+ * ```
63
+ */
64
+ export function getAttributeFiles(attr) {
65
+ if (!attr)
66
+ return [];
67
+ const value = attr.value;
68
+ if (Array.isArray(value))
69
+ return value.filter((item) => _isFile(item));
70
+ return _isFile(value) ? [value] : [];
71
+ }
72
+ /**
73
+ * Reads the first file of an attribute.
74
+ *
75
+ * The single-image counterpart of {@link getAttributeFiles} — same shape
76
+ * handling, but returns the file itself instead of a list. For a gallery it
77
+ * returns the first entry, which is what a preview or a cover usually needs.
78
+ * @param {IAttributeValue | undefined} attr - An attribute value, e.g. `product.attributeValues.img`.
79
+ * @returns {IAttributeFile | null} The first file, or null when the attribute holds none.
80
+ * @example
81
+ * ```ts
82
+ * import { getAttributeFile } from 'oneentry';
83
+ *
84
+ * const cover = getAttributeFile(product.attributeValues.img);
85
+ * const blurDataURL = cover?.previewLink?.default?.[0];
86
+ * ```
87
+ */
88
+ export function getAttributeFile(attr) {
89
+ var _a;
90
+ return (_a = getAttributeFiles(attr)[0]) !== null && _a !== void 0 ? _a : null;
91
+ }
92
+ /**
93
+ * Narrows an attribute value to a text attribute.
94
+ * @param {IAttributeValue | undefined} attr - The attribute value to test.
95
+ * @returns {boolean} True when the attribute is a `string`, `text` or `textEditor` carrying a string (or nothing).
96
+ */
97
+ export function isStringAttribute(attr) {
98
+ return (!!attr &&
99
+ (attr.type === 'string' ||
100
+ attr.type === 'text' ||
101
+ attr.type === 'textEditor') &&
102
+ (attr.value === null || typeof attr.value === 'string'));
103
+ }
104
+ /**
105
+ * Narrows an attribute value to a numeric attribute.
106
+ *
107
+ * The SDK casts `integer`, `float` and `real` values to a JS number, so the
108
+ * guard checks for one — a value that failed to cast is `null`.
109
+ * @param {IAttributeValue | undefined} attr - The attribute value to test.
110
+ * @returns {boolean} True when the attribute is an `integer`, `float` or `real` carrying a number (or nothing).
111
+ */
112
+ export function isNumberAttribute(attr) {
113
+ return (!!attr &&
114
+ (attr.type === 'integer' ||
115
+ attr.type === 'float' ||
116
+ attr.type === 'real') &&
117
+ (attr.value === null || typeof attr.value === 'number'));
118
+ }
119
+ /**
120
+ * Narrows an attribute value to a `list` attribute.
121
+ *
122
+ * The option shape is defined by the attribute set, so the entries stay
123
+ * `unknown` — the guard only promises the array container.
124
+ * @param {IAttributeValue | undefined} attr - The attribute value to test.
125
+ * @returns {boolean} True when the attribute is a `list` carrying an array.
126
+ */
127
+ export function isListAttribute(attr) {
128
+ return !!attr && attr.type === 'list' && Array.isArray(attr.value);
129
+ }
130
+ /**
131
+ * Reads the nested fields of an attribute as a marker map.
132
+ *
133
+ * `additionalFields` is typed `Record<string, IAttributeValue> | unknown[]`
134
+ * because the API returns an empty **array** when an attribute has no nested
135
+ * fields — the union makes every read of a field a type error. This helper
136
+ * collapses that case to an empty map, so the result is always keyed by marker.
137
+ *
138
+ * With `rawData: true` in the config the SDK keeps the API's original array of
139
+ * fields; it is converted here by `marker` as well, so the helper returns the
140
+ * same map in both modes.
141
+ * @param {IAttributeValue | undefined} attr - An attribute value whose nested fields to read.
142
+ * @returns {Record<string, IAttributeValue>} Nested attribute values keyed by marker; empty when there are none.
143
+ * @example
144
+ * ```ts
145
+ * import { getAdditionalFields } from 'oneentry';
146
+ *
147
+ * const alt = getAdditionalFields(page.attributeValues.cover).alt?.value;
148
+ * ```
149
+ */
150
+ export function getAdditionalFields(attr) {
151
+ const fields = attr === null || attr === void 0 ? void 0 : attr.additionalFields;
152
+ if (!fields || typeof fields !== 'object')
153
+ return {};
154
+ if (Array.isArray(fields)) {
155
+ // rawData mode: the API's own array of fields, each carrying its marker.
156
+ return Object.fromEntries(fields
157
+ .filter((field) => !!field &&
158
+ typeof field === 'object' &&
159
+ typeof field.marker === 'string')
160
+ .map((field) => [field.marker, field]));
161
+ }
162
+ return fields;
163
+ }
@@ -266,10 +266,19 @@ interface ITimeIntervalRange {
266
266
  * @property {string} type - Attribute data type (e.g. "string", "integer", "list", "file", "image").
267
267
  * @property {unknown} value - Attribute value — actual TS type depends on `type`, and the SDK normalizes it to the same shape in every module: `string` for "string"/"text"; `number | null` for "integer"/"float"/"real"; the file object itself for a single-file "image"/"file" and an array of them for several; an array for "list" and "groupOfImages". An attribute with no value is always `null`. Example: "Admins text".
268
268
  * @property {number} [position] - Sort position of the value inside its set; the containing collection is returned sorted by it. Example: 0.
269
- * @property {Record<string, IAttributeValue> | unknown[]} [additionalFields] - Nested attribute values keyed by marker; the API may also return an empty array when none are configured. Optional.
269
+ * @property {Record<string, IAttributeValue> | unknown[]} [additionalFields] - Nested attribute values keyed by marker; the API may also return an empty array when none are configured. Read it through `getAdditionalFields`, which collapses that array to an empty map. Optional.
270
270
  * @property {boolean} [isIcon] - Block/preview attribute flag — whether the field is treated as an icon. Optional.
271
271
  * @property {boolean} [isProductPreview] - Block/preview attribute flag — whether the field is shown in product preview. Optional.
272
272
  * @description A single attribute value attached to an entity (admin, user, page, product, …).
273
+ *
274
+ * `value` is `unknown` because its shape is decided by `type` at runtime, which
275
+ * a single interface cannot express. Do not read it by assumption — the type
276
+ * checker cannot catch a wrong guess (an array read on a single file yields
277
+ * `undefined`, silently, with no error anywhere). Reach it through the guards
278
+ * and helpers instead: `isFileAttribute` / `getAttributeFiles`,
279
+ * `isStringAttribute`, `isNumberAttribute`, `isListAttribute`,
280
+ * `isTimeIntervalAttribute`; or annotate with {@link ITypedAttributeValue} to
281
+ * have the compiler enforce the rule.
273
282
  */
274
283
  interface IAttributeValue {
275
284
  type: string;
@@ -286,6 +295,90 @@ interface IAttributeValue {
286
295
  interface IAttributeValues {
287
296
  [key: string]: IAttributeValue;
288
297
  }
298
+ /**
299
+ * @interface IAttributeFile
300
+ * @property {string} filename - Storage-relative path of the file. Example: "files/project/product/2954/image/48853cbf-4462-42c6-8b99-d14f721c21a2.jpeg".
301
+ * @property {string} downloadLink - Public URL of the original file. Example: "https://my-project.oneentry.cloud/cloud-static/files/project/product/2954/image/48853cbf.jpeg".
302
+ * @property {number} size - File size in bytes. Example: 742690.
303
+ * @property {string} contentType - MIME type of the file. Example: "image/jpeg".
304
+ * @property {Record<string, string[]>} [previewLink] - Generated previews keyed by preview template. Each entry is a `[placeholder, url]` pair: the first item is an inline base64 thumbnail (usable as a `blurDataURL`), the second the preview URL. Optional — previews are generated for images; a non-image `file` may arrive without them. Example: { "default": ["data:image/webp;base64,UklGRmwA…", "https://…48853cbf.preview.default.jpeg"] }.
305
+ * @property {string} [defaultPreview] - Key of `previewLink` to use by default. Optional — present alongside `previewLink`. Example: "default".
306
+ * @description One file of an `image`, `file` or `groupOfImages` attribute value. Reach it through {@link IFileAttributeValue} — or, without caring whether the attribute holds one file or many, through `getAttributeFiles`.
307
+ */
308
+ interface IAttributeFile {
309
+ filename: string;
310
+ downloadLink: string;
311
+ size: number;
312
+ contentType: string;
313
+ previewLink?: Record<string, string[]>;
314
+ defaultPreview?: string;
315
+ }
316
+ /**
317
+ * @interface IFileAttributeValue
318
+ * @property {'image' | 'file' | 'groupOfImages'} type - Discriminant identifying the attribute as file-bearing.
319
+ * @property {IAttributeFile | IAttributeFile[] | null} value - The file itself when an `image`/`file` attribute holds exactly one, an array when it holds several, always an array for `groupOfImages`, `null` when nothing is set.
320
+ * @description {@link IAttributeValue} narrowed to attributes that carry files, whose generic `value: unknown` resolves to {@link IAttributeFile}. The single/array split is what the SDK's normalization produces, so it has to be handled: narrow with `isFileAttribute`, or skip the branch entirely with `getAttributeFiles` / `getAttributeFile`.
321
+ */
322
+ interface IFileAttributeValue extends IAttributeValue {
323
+ type: 'image' | 'file' | 'groupOfImages';
324
+ value: IAttributeFile | IAttributeFile[] | null;
325
+ }
326
+ /**
327
+ * @interface IStringAttributeValue
328
+ * @property {'string' | 'text' | 'textEditor'} type - Discriminant identifying the attribute as text-bearing.
329
+ * @property {string | null} value - The text; `null` when no value is set.
330
+ * @description {@link IAttributeValue} narrowed to text attributes. Narrow to it with `isStringAttribute`.
331
+ */
332
+ interface IStringAttributeValue extends IAttributeValue {
333
+ type: 'string' | 'text' | 'textEditor';
334
+ value: string | null;
335
+ }
336
+ /**
337
+ * @interface INumberAttributeValue
338
+ * @property {'integer' | 'float' | 'real'} type - Discriminant identifying the attribute as numeric.
339
+ * @property {number | null} value - The number, cast by the SDK from the API's string form; `null` when no value is set.
340
+ * @description {@link IAttributeValue} narrowed to numeric attributes. Narrow to it with `isNumberAttribute`.
341
+ */
342
+ interface INumberAttributeValue extends IAttributeValue {
343
+ type: 'integer' | 'float' | 'real';
344
+ value: number | null;
345
+ }
346
+ /**
347
+ * @interface IListAttributeValue
348
+ * @property {'list'} type - Discriminant identifying the attribute as a list.
349
+ * @property {unknown[]} value - The selected options. The option shape is defined by the attribute set, so the entries stay `unknown` — only the array container is guaranteed.
350
+ * @description {@link IAttributeValue} narrowed to `list` attributes. Narrow to it with `isListAttribute`.
351
+ */
352
+ interface IListAttributeValue extends IAttributeValue {
353
+ type: 'list';
354
+ value: unknown[];
355
+ }
356
+ /**
357
+ * ITypedAttributeValue — {@link IAttributeValue} as a discriminated union over `type`.
358
+ *
359
+ * Opt-in, and deliberately closed: it lists only the types whose `value` shape
360
+ * the SDK guarantees, so `switch (attr.type)` narrows `value` for you. A loose
361
+ * member (`type: string`) would be assignable to every case and collapse the
362
+ * narrowing back to `unknown`, which is exactly what this type exists to avoid.
363
+ *
364
+ * `IAttributeValues` keeps the loose `IAttributeValue`, so nothing existing
365
+ * changes: narrow into this union with the guards (`isFileAttribute` and the
366
+ * rest), or annotate a value you control. Attribute types the SDK does not
367
+ * model (`entity`, `date`, custom ones) stay on `IAttributeValue`.
368
+ * @example
369
+ * ```ts
370
+ * function render(attr: ITypedAttributeValue) {
371
+ * switch (attr.type) {
372
+ * case 'image':
373
+ * case 'file':
374
+ * return attr.value; // IAttributeFile | IAttributeFile[] | null
375
+ * case 'integer':
376
+ * return attr.value; // number | null
377
+ * }
378
+ * }
379
+ * ```
380
+ */
381
+ type ITypedAttributeValue = IFileAttributeValue | IStringAttributeValue | INumberAttributeValue | IListAttributeValue | ITimeIntervalAttributeValue;
289
382
  /**
290
383
  * @interface IRating
291
384
  * @property {number} [value] - Average rating value. Example: 4.5.
@@ -351,4 +444,4 @@ type LangType = string | Array<string>;
351
444
  * LocalizeType
352
445
  */
353
446
  type LocalizeType = ILocalizeInfo;
354
- export type { IAttributeLocalizeInfo, IAttributes, IAttributeValue, IAttributeValues, IConfig, IError, IHttpHeaders, IHttpOptions, ILocalizeInfo, IRating, ITimeIntervalAttributeValue, ITimeIntervalEntitySchedule, ITimeIntervalGroup, ITimeIntervalPoint, ITimeIntervalRange, ITimeIntervalSchedule, ITimeIntervalWindow, LangType, LocalizeType, TimeIntervalPair, };
447
+ export type { IAttributeFile, IAttributeLocalizeInfo, IAttributes, IAttributeValue, IAttributeValues, IConfig, IError, IFileAttributeValue, IHttpHeaders, IHttpOptions, IListAttributeValue, ILocalizeInfo, INumberAttributeValue, IRating, IStringAttributeValue, ITimeIntervalAttributeValue, ITimeIntervalEntitySchedule, ITimeIntervalGroup, ITimeIntervalPoint, ITimeIntervalRange, ITimeIntervalSchedule, ITimeIntervalWindow, ITypedAttributeValue, LangType, LocalizeType, TimeIntervalPair, };
@@ -36,6 +36,35 @@ export declare const AttributeSchema: z.ZodObject<{
36
36
  }, z.core.$strip>>>;
37
37
  value: z.ZodOptional<z.ZodAny>;
38
38
  }, z.core.$strip>;
39
+ /**
40
+ * Attribute file schema
41
+ *
42
+ * One file of an `image`, `file` or `groupOfImages` attribute value, as the API
43
+ * returns it — mirrors `IAttributeFile`. Loose: the API may add fields, and a
44
+ * new one is not a reason to report a broken response.
45
+ */
46
+ export declare const AttributeFileSchema: z.ZodObject<{
47
+ filename: z.ZodString;
48
+ downloadLink: z.ZodString;
49
+ size: z.ZodNumber;
50
+ contentType: z.ZodString;
51
+ previewLink: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
52
+ defaultPreview: z.ZodOptional<z.ZodString>;
53
+ }, z.core.$loose>;
54
+ /**
55
+ * Attribute values schema
56
+ *
57
+ * The container the API returns under `attributeValues`. Both nestings are
58
+ * accepted, since the raw response wraps the marker map in a locale
59
+ * (`{ en_US: { marker: attr } }`) while some endpoints return it flat.
60
+ *
61
+ * Attribute values are open by design — what `value` holds is decided by the
62
+ * project's attribute set — so the schema validates the one part the API fixes
63
+ * and the SDK relies on: the shape of files. If a future API release renames or
64
+ * drops a file field, `getAttributeFiles` would silently return nothing;
65
+ * validation (`config.validation.enabled`) reports it instead.
66
+ */
67
+ export declare const AttributeValuesSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
39
68
  /**
40
69
  * User entity schema
41
70
  */
@@ -50,6 +79,7 @@ export declare const UserEntitySchema: z.ZodObject<{
50
79
  state: z.ZodRecord<z.ZodString, z.ZodAny>;
51
80
  moduleFormConfigs: z.ZodOptional<z.ZodArray<z.ZodAny>>;
52
81
  rating: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
82
+ distance: z.ZodOptional<z.ZodNumber>;
53
83
  }, z.core.$strip>;
54
84
  /**
55
85
  * Auth entity schema
@@ -33,6 +33,98 @@ export const AttributeSchema = z.object({
33
33
  localizeInfos: z.record(z.string(), LocalizeInfoSchema).optional(),
34
34
  value: z.any().optional(),
35
35
  });
36
+ /**
37
+ * Attribute file schema
38
+ *
39
+ * One file of an `image`, `file` or `groupOfImages` attribute value, as the API
40
+ * returns it — mirrors `IAttributeFile`. Loose: the API may add fields, and a
41
+ * new one is not a reason to report a broken response.
42
+ */
43
+ export const AttributeFileSchema = z.looseObject({
44
+ filename: z.string(),
45
+ downloadLink: z.string(),
46
+ size: z.number(),
47
+ contentType: z.string(),
48
+ previewLink: z.record(z.string(), z.array(z.string())).optional(),
49
+ defaultPreview: z.string().optional(),
50
+ });
51
+ /**
52
+ * Attribute types whose value carries files.
53
+ */
54
+ const FILE_ATTRIBUTE_TYPES = ['image', 'file', 'groupOfImages'];
55
+ /**
56
+ * Reports whether a value is the empty localization map the API sends for an
57
+ * attribute with no value set.
58
+ * @param {unknown} value - The value to test.
59
+ * @returns {boolean} True when the value carries nothing.
60
+ */
61
+ function isEmptyValue(value) {
62
+ if (value === null || value === undefined)
63
+ return true;
64
+ return (typeof value === 'object' &&
65
+ !Array.isArray(value) &&
66
+ Object.keys(value).length === 0);
67
+ }
68
+ /**
69
+ * Validates the files of one attribute value, recursing into nested fields.
70
+ *
71
+ * Only file-bearing attributes are inspected. Everything else is left alone:
72
+ * the shape of `value` is defined per attribute type by the project's own
73
+ * attribute set, so a schema cannot describe it — but the file shape is fixed
74
+ * by the API, and the SDK's own helpers (`getAttributeFiles`) depend on it.
75
+ * @param {unknown} node - An attribute value, or a container of them.
76
+ * @param {string[]} path - Path to the node, for issue reporting.
77
+ * @param {z.RefinementCtx} ctx - Zod refinement context issues are added to.
78
+ */
79
+ function validateAttributeFiles(node, path, ctx) {
80
+ if (!node || typeof node !== 'object')
81
+ return;
82
+ if (Array.isArray(node)) {
83
+ node.forEach((item, index) => validateAttributeFiles(item, [...path, String(index)], ctx));
84
+ return;
85
+ }
86
+ const attr = node;
87
+ const isAttribute = typeof attr.type === 'string' && 'value' in attr;
88
+ if (isAttribute && FILE_ATTRIBUTE_TYPES.includes(attr.type)) {
89
+ if (!isEmptyValue(attr.value)) {
90
+ // The API always sends files as an array; the SDK unwraps a single one
91
+ // afterwards, so both shapes are accepted here.
92
+ const files = Array.isArray(attr.value) ? attr.value : [attr.value];
93
+ files.forEach((file, index) => {
94
+ const result = AttributeFileSchema.safeParse(file);
95
+ if (result.success)
96
+ return;
97
+ result.error.issues.forEach((issue) => ctx.addIssue({
98
+ code: 'custom',
99
+ path: [...path, 'value', index, ...issue.path],
100
+ message: `Attribute of type "${attr.type}" carries an unexpected file shape: ${issue.message}`,
101
+ }));
102
+ });
103
+ }
104
+ }
105
+ // Nested fields carry attribute values of their own, files included.
106
+ if (isAttribute) {
107
+ validateAttributeFiles(attr.additionalFields, [...path, 'additionalFields'], ctx);
108
+ return;
109
+ }
110
+ Object.entries(attr).forEach(([key, value]) => validateAttributeFiles(value, [...path, key], ctx));
111
+ }
112
+ /**
113
+ * Attribute values schema
114
+ *
115
+ * The container the API returns under `attributeValues`. Both nestings are
116
+ * accepted, since the raw response wraps the marker map in a locale
117
+ * (`{ en_US: { marker: attr } }`) while some endpoints return it flat.
118
+ *
119
+ * Attribute values are open by design — what `value` holds is decided by the
120
+ * project's attribute set — so the schema validates the one part the API fixes
121
+ * and the SDK relies on: the shape of files. If a future API release renames or
122
+ * drops a file field, `getAttributeFiles` would silently return nothing;
123
+ * validation (`config.validation.enabled`) reports it instead.
124
+ */
125
+ export const AttributeValuesSchema = z
126
+ .record(z.string(), z.unknown())
127
+ .superRefine((values, ctx) => validateAttributeFiles(values, [], ctx));
36
128
  /**
37
129
  * User entity schema
38
130
  */
@@ -47,6 +139,7 @@ export const UserEntitySchema = z.object({
47
139
  state: z.record(z.string(), z.any()),
48
140
  moduleFormConfigs: z.array(z.any()).optional(),
49
141
  rating: z.record(z.string(), z.unknown()).optional(),
142
+ distance: z.number().optional(),
50
143
  });
51
144
  /**
52
145
  * Auth entity schema
@@ -96,11 +96,12 @@ export default class BlocksApi extends AsyncModules implements IBlocks {
96
96
  * @param {string} [langCode] - Language code. Default: "en_US".
97
97
  * @param {string} [signPrice] - Order storage marker for price fixing. If the parameter is set, the price is fixed for a certain time.
98
98
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/#Fixing-the-price-signPrice Fixing the price} documentation.
99
+ * @param {number} [limit] - Maximum number of products to return. When omitted, the block's own quantity setting applies. Example: 10.
99
100
  * @returns {Promise<IProductsResponse | IError>} Returns a products response with items and total.
100
101
  * @throws {IError} When isShell=false and an error occurs during the fetch
101
102
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/getFrequentlyOrderedProducts getFrequentlyOrderedProducts} documentation.
102
103
  */
103
- getFrequentlyOrderedProducts(productId: number, marker: string, langCode?: string, signPrice?: string): Promise<IProductsResponse | IError>;
104
+ getFrequentlyOrderedProducts(productId: number, marker: string, langCode?: string, signPrice?: string, limit?: number): Promise<IProductsResponse | IError>;
104
105
  /**
105
106
  * Quick search for block objects with limited output.
106
107
  * @handleName searchBlock
@@ -118,11 +119,12 @@ export default class BlocksApi extends AsyncModules implements IBlocks {
118
119
  * @param {string} [langCode] - Language code. Default: "en_US".
119
120
  * @param {string} [signPrice] - Order storage marker for price fixing. If the parameter is set, the price is fixed for a certain time.
120
121
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/#Fixing-the-price-signPrice Fixing the price} documentation.
122
+ * @param {number} [limit] - Maximum number of products to return. When omitted, the block's own quantity setting applies. Example: 10.
121
123
  * @returns {Promise<IProductsResponse | IError>} Returns an object with an array of products, total count and totalFound.
122
124
  * @throws {IError} When isShell=false and an error occurs during the fetch
123
125
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/getCartComplement getCartComplement} documentation.
124
126
  */
125
- getCartComplement(marker: string, langCode?: string, signPrice?: string): Promise<IProductsResponse | IError>;
127
+ getCartComplement(marker: string, langCode?: string, signPrice?: string, limit?: number): Promise<IProductsResponse | IError>;
126
128
  /**
127
129
  * Get "complete your cart" products by an explicit list of productIds (POST body).
128
130
  * @handleName getCartComplementByProductIds
@@ -145,11 +147,12 @@ export default class BlocksApi extends AsyncModules implements IBlocks {
145
147
  * @param {string} [langCode] - Language code. Default: "en_US".
146
148
  * @param {string} [signPrice] - Order storage marker for price fixing. If the parameter is set, the price is fixed for a certain time.
147
149
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/#Fixing-the-price-signPrice Fixing the price} documentation.
150
+ * @param {number} [limit] - Maximum number of products to return. When omitted, the block's own quantity setting applies. Example: 10.
148
151
  * @returns {Promise<IProductsResponse | IError>} Returns an object with an array of products, total count and totalFound.
149
152
  * @throws {IError} When isShell=false and an error occurs during the fetch
150
153
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/getCartSimilar getCartSimilar} documentation.
151
154
  */
152
- getCartSimilar(marker: string, langCode?: string, signPrice?: string): Promise<IProductsResponse | IError>;
155
+ getCartSimilar(marker: string, langCode?: string, signPrice?: string, limit?: number): Promise<IProductsResponse | IError>;
153
156
  /**
154
157
  * Get "similar to cart" products by an explicit list of productIds (POST body).
155
158
  * @handleName getCartSimilarByProductIds
@@ -172,11 +175,12 @@ export default class BlocksApi extends AsyncModules implements IBlocks {
172
175
  * @param {string} [langCode] - Language code. Default: "en_US".
173
176
  * @param {string} [signPrice] - Order storage marker for price fixing. If the parameter is set, the price is fixed for a certain time.
174
177
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/#Fixing-the-price-signPrice Fixing the price} documentation.
178
+ * @param {number} [limit] - Maximum number of products to return. When omitted, the block's own quantity setting applies. Example: 10.
175
179
  * @returns {Promise<IProductsResponse | IError>} Returns an object with an array of products, total count and totalFound.
176
180
  * @throws {IError} When isShell=false and an error occurs during the fetch
177
181
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/getPersonalRecommendations getPersonalRecommendations} documentation.
178
182
  */
179
- getPersonalRecommendations(marker: string, langCode?: string, signPrice?: string): Promise<IProductsResponse | IError>;
183
+ getPersonalRecommendations(marker: string, langCode?: string, signPrice?: string, limit?: number): Promise<IProductsResponse | IError>;
180
184
  /**
181
185
  * Get recently viewed products.
182
186
  * @handleName getRecentlyViewed
@@ -184,11 +188,12 @@ export default class BlocksApi extends AsyncModules implements IBlocks {
184
188
  * @param {string} [langCode] - Language code. Default: "en_US".
185
189
  * @param {string} [signPrice] - Order storage marker for price fixing. If the parameter is set, the price is fixed for a certain time.
186
190
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/#Fixing-the-price-signPrice Fixing the price} documentation.
191
+ * @param {number} [limit] - Maximum number of products to return. When omitted, the block's own quantity setting applies. Example: 10.
187
192
  * @returns {Promise<IProductsResponse | IError>} Returns an object with an array of products, total count and totalFound.
188
193
  * @throws {IError} When isShell=false and an error occurs during the fetch
189
194
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/getRecentlyViewed getRecentlyViewed} documentation.
190
195
  */
191
- getRecentlyViewed(marker: string, langCode?: string, signPrice?: string): Promise<IProductsResponse | IError>;
196
+ getRecentlyViewed(marker: string, langCode?: string, signPrice?: string, limit?: number): Promise<IProductsResponse | IError>;
192
197
  /**
193
198
  * Get products for repeat purchase.
194
199
  * @handleName getRepeatPurchase
@@ -196,11 +201,12 @@ export default class BlocksApi extends AsyncModules implements IBlocks {
196
201
  * @param {string} [langCode] - Language code. Default: "en_US".
197
202
  * @param {string} [signPrice] - Order storage marker for price fixing. If the parameter is set, the price is fixed for a certain time.
198
203
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/#Fixing-the-price-signPrice Fixing the price} documentation.
204
+ * @param {number} [limit] - Maximum number of products to return. When omitted, the block's own quantity setting applies. Example: 10.
199
205
  * @returns {Promise<IProductsResponse | IError>} Returns an object with an array of products, total count and totalFound.
200
206
  * @throws {IError} When isShell=false and an error occurs during the fetch
201
207
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/getRepeatPurchase getRepeatPurchase} documentation.
202
208
  */
203
- getRepeatPurchase(marker: string, langCode?: string, signPrice?: string): Promise<IProductsResponse | IError>;
209
+ getRepeatPurchase(marker: string, langCode?: string, signPrice?: string, limit?: number): Promise<IProductsResponse | IError>;
204
210
  /**
205
211
  * Get the block's slides tree as a flat pre-order array (slider_block only).
206
212
  * @handleName getSlides
@@ -217,11 +223,12 @@ export default class BlocksApi extends AsyncModules implements IBlocks {
217
223
  * @param {string} [langCode] - Language code. Default: "en_US".
218
224
  * @param {string} [signPrice] - Order storage marker for price fixing. If the parameter is set, the price is fixed for a certain time.
219
225
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/#Fixing-the-price-signPrice Fixing the price} documentation.
226
+ * @param {number} [limit] - Maximum number of products to return. When omitted, the block's own quantity setting applies. Example: 10.
220
227
  * @returns {Promise<IProductsResponse | IError>} Returns an object with an array of products, total count and totalFound.
221
228
  * @throws {IError} When isShell=false and an error occurs during the fetch
222
229
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/getTrending getTrending} documentation.
223
230
  */
224
- getTrending(marker: string, langCode?: string, signPrice?: string): Promise<IProductsResponse | IError>;
231
+ getTrending(marker: string, langCode?: string, signPrice?: string, limit?: number): Promise<IProductsResponse | IError>;
225
232
  /**
226
233
  * Get "similar to wishlist" products by the wishlist from context (auth user or guest).
227
234
  * @handleName getWishlistSimilar
@@ -229,11 +236,12 @@ export default class BlocksApi extends AsyncModules implements IBlocks {
229
236
  * @param {string} [langCode] - Language code. Default: "en_US".
230
237
  * @param {string} [signPrice] - Order storage marker for price fixing. If the parameter is set, the price is fixed for a certain time.
231
238
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/#Fixing-the-price-signPrice Fixing the price} documentation.
239
+ * @param {number} [limit] - Maximum number of products to return. When omitted, the block's own quantity setting applies. Example: 10.
232
240
  * @returns {Promise<IProductsResponse | IError>} Returns an object with an array of products, total count and totalFound.
233
241
  * @throws {IError} When isShell=false and an error occurs during the fetch
234
242
  * @see {@link https://js-sdk.oneentry.cloud/docs/blocks/getWishlistSimilar getWishlistSimilar} documentation.
235
243
  */
236
- getWishlistSimilar(marker: string, langCode?: string, signPrice?: string): Promise<IProductsResponse | IError>;
244
+ getWishlistSimilar(marker: string, langCode?: string, signPrice?: string, limit?: number): Promise<IProductsResponse | IError>;
237
245
  /**
238
246
  * Get "similar to wishlist" products by an explicit list of productIds (POST body).
239
247
  * @handleName getWishlistSimilarByProductIds