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
package/README.md CHANGED
@@ -202,6 +202,24 @@ Zod and the response schemas are loaded on demand, the first time a response act
202
202
 
203
203
  Together that means a project calling a single SDK method loads about **43 kB minified (9.7 kB gzip)** instead of 536 kB, with Zod, the schemas and Socket.io landing in chunks that are never requested. The SDK is published as both CommonJS and ESM (`sideEffects: false`), so bundlers can tree-shake the rest.
204
204
 
205
+ ### Attribute Values
206
+
207
+ `IAttributeValue.value` is typed `unknown` — its shape is decided by `type` at runtime. The trap is files: an `image`/`file` attribute holding **one** file has its value unwrapped to the file object itself, while several files and every `groupOfImages` stay an array. Reading the wrong shape is not a compile error, it is a silently missing image. Read files through the helpers instead:
208
+
209
+ ```js
210
+ import { defineOneEntry, getAttributeFile, getAttributeFiles } from 'oneentry'
211
+
212
+ const { Pages } = defineOneEntry('your-url', { token: 'your-app-token' })
213
+ const page = await Pages.getPageByUrl('catalog')
214
+
215
+ // Same call whether the attribute holds one file or a gallery.
216
+ const images = getAttributeFiles(page.attributeValues.gallery) // IAttributeFile[]
217
+ const cover = getAttributeFile(page.attributeValues.cover) // IAttributeFile | null
218
+ const blurDataURL = cover?.previewLink?.default?.[0]
219
+ ```
220
+
221
+ Also exported: `getAdditionalFields(attr)` for an attribute's nested fields as a marker map, the type guards `isFileAttribute`, `isStringAttribute`, `isNumberAttribute`, `isListAttribute`, the file type `IAttributeFile`, and `ITypedAttributeValue` — `IAttributeValue` as a discriminated union over `type`, to annotate with where you want the compiler to enforce the shape.
222
+
205
223
  ### Time Intervals
206
224
 
207
225
  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:
package/changelog.md CHANGED
@@ -1,5 +1,84 @@
1
1
  # SDK Change Log
2
2
 
3
+ ## v.1.0.163
4
+
5
+ ### What's Fixed
6
+
7
+ - **FormData > `getFormsDataByMarker` — the filter body is typed.** It was `body?: object`, so nothing about it was checked or suggested. That is worse than merely inconvenient: the API **ignores** a field it does not recognize, so `statuses: ['approved']` (note the "s") returned every record — unmoderated ones included — while the code looked correct. The new `IFormsDataFilter` declares the fields the endpoint actually applies, each verified against a live project:
8
+
9
+ ```ts
10
+ await FormData.getFormsDataByMarker('review', 12, {
11
+ entityIdentifier: 'blog',
12
+ parentId: 10,
13
+ userIdentifier: '',
14
+ status: ['approved'],
15
+ dateFrom: '2025-01-01',
16
+ dateTo: '',
17
+ })
18
+ ```
19
+
20
+ Note `entityparentIdentifier` from the old JSDoc example is **not** among them: the API ignores it (filtering by it changes nothing), so it is not declared. Use `parentId` to fetch replies to a submission. Also exported: `FormDataStatus`.
21
+
22
+ - **FormData > the JSDoc example used a status that does not exist.** It showed `"status": ["new", "approved"]`; copied as-is it answers `400 each value in status must be a valid enum value`, without naming the valid ones. The set is `sent`, `moderation`, `approved`, `banned`, `deleted` — now spelled out next to `status` in the JSDoc, and enforced by `FormDataStatus`. `status` must also be an array; a bare string is a `400`.
23
+
24
+ - **FormData > the locale unwrapping of `formData` is now documented.** The API returns `formData: { "en_US": [ … ] }`, the SDK normalizes it and hands over the array for the requested `langCode`. Nothing said so, so code written against the raw API response — the one you see first, through curl or the panel — read `formData[langCode]`, got `undefined`, and rendered an empty list with no error anywhere. It is now stated in the method's JSDoc and on `formData` in `IFormByMarkerDataEntity` / `IFormDataEntity`. Behaviour is unchanged.
25
+
26
+ - **FormData > `IBodyTypeImageGroupOfImages.type` had a typo: `'groupOfImage'`**, a value the API rejects (`400 formData's marker '…' type must be one of […]`). Worse than a plain typo — the editor autocompleted it. It is now `'groupOfImages'`, matching the attribute type and the SDK's own upload branch, which has always checked for the plural.
27
+
28
+ - **FormData > `postFormsData` JSDoc now points at `IImageValue` / `IFileValue`** — the shape an attached file must take, which is *not* what `FileUploading.upload` returns (that one carries `contentType`, which form data rejects; the SDK strips it for you when it uploads the file itself). These interfaces were the only place that shape was written down, and nothing linked to them.
29
+
30
+ - **AttributesSets > `getSingleAttributeByMarkerSet` — the interface declared its arguments in the reverse order of the implementation.** `IAttributesSets` (and its JSDoc) said `(attributeMarker, setMarker, langCode)`, while `AttributesSetsApi` — and the request path `/{setMarker}/attributes/{attributeMarker}` — take `(setMarker, attributeMarker, langCode)`. Both parameters are `string`, so `implements` did not catch it and neither did any caller's compiler: a call written from the interface built `/icon/attributes/page_content` and the API answered `404 Attribute not found`, which reads like a missing attribute rather than a wrong call. The interface now matches the implementation; no runtime behaviour changed.
31
+
32
+ - **15 module interfaces declared `langCode` as required** while the implementing method defaults it — Blocks > `getBlockByMarker`, Discounts > `getDiscountByMarker`, IntegrationCollections > `getICollections` / `getICollectionById` / `getICollectionRowsById` / `getICollectionRowByMarkerAndId` / `createICollectionRow` / `updateICollectionRow`, Menus > `getMenusByMarker`, Orders > `getAllStatusesByStorageMarker`, ProductStatuses > `getProductStatuses` / `getProductsByStatusMarker`, Templates > `getTemplateByType`, TemplatePreviews > `getTemplatePreviews` / `getTemplatePreviewByMarker`. All are now optional, as the JSDoc already stated.
33
+
34
+ - **Two parameters were named differently in the interface than in the implementation**: AuthProvider > `signUp` / `auth` took `data` (now `body`), and FormData > `getFormsDataByMarker` took `isNested`, documented as "hierarchical data", while the method sends `isExtended` — a flag for additional fields. Names and docs now follow the implementation.
35
+
36
+ - **A test now guards this whole class of defect.** `src/base/tests/signatures.spec.ts` parses the sources with the TypeScript compiler API and compares every `*Api` class against the interface it `implements` — parameter names, order and optionality. The compiler cannot do this: it matches parameters positionally by type, so a swapped pair of `string`s is a valid implementation to it.
37
+
38
+ ### What's New
39
+
40
+ - **Typed access to attribute values.** `IAttributeValue.value` is `unknown` — its shape is decided by `type` at runtime — and the rule for that shape lived only in a JSDoc comment, so breaking it cost nothing at compile time. The classic case: an `image` attribute holding **one** file has its `value` unwrapped to the file object itself, so a helper written as `Array.isArray(v) ? v[0] : undefined` returns `undefined` for every single-image attribute, builds cleanly, and shows an empty page. The SDK now ships the missing pieces:
41
+
42
+ ```ts
43
+ import { getAttributeFiles, getAttributeFile } from 'oneentry'
44
+
45
+ // Same call for one image and for a gallery — no branching on the shape.
46
+ const images = getAttributeFiles(page.attributeValues.cover)
47
+ const cover = getAttributeFile(product.attributeValues.img)
48
+ const blurDataURL = cover?.previewLink?.default?.[0]
49
+ ```
50
+
51
+ - `getAttributeFiles(attr)` → `IAttributeFile[]` — every file of an `image`, `file` or `groupOfImages` attribute, collapsing the single-file and array shapes to one list; empty for anything else.
52
+ - `getAttributeFile(attr)` → `IAttributeFile | null` — the first file, for covers and previews.
53
+ - `getAdditionalFields(attr)` → `Record<string, IAttributeValue>` — nested fields as a marker map. `additionalFields` is typed `Record<string, IAttributeValue> | unknown[]` because the API returns an empty **array** when there are none, and that union makes every field read a type error; the helper collapses it (and converts the `rawData: true` array by `marker`).
54
+ - Type guards `isFileAttribute`, `isStringAttribute`, `isNumberAttribute`, `isListAttribute` — alongside the existing `isTimeIntervalAttribute`.
55
+
56
+ - **`IAttributeFile`** — the file object of an attribute value is now an exported type: `filename`, `downloadLink`, `size`, `contentType`, plus the optional `previewLink` (previews keyed by template, each a `[base64 placeholder, url]` pair — the placeholder is what a `blurDataURL` needs) and `defaultPreview`. It had to be re-declared by hand in every project until now.
57
+
58
+ - **Attribute values are now validated.** Every schema carrying `attributeValues` used `z.record(z.string(), z.any())` — the whole attribute payload passed validation unconditionally, so a change in the API's file shape reached consumers as an empty gallery, not as an error. The shared `AttributeValuesSchema` (`base/validation.ts`) replaces it in the admins, blocks, menus, pages, products and templates schemas. It stays open where the data is open — what `value` holds is defined by the project's own attribute set — and checks the one part the API fixes and the SDK's helpers depend on: the files of `image` / `file` / `groupOfImages` attributes, nested `additionalFields` included. A renamed or dropped `downloadLink` is reported as a validation issue naming the marker and index; unknown new fields on a file are accepted. Exported alongside it: `AttributeFileSchema`.
59
+
60
+ - **`ITypedAttributeValue`** — `IAttributeValue` as a discriminated union over `type` (`IFileAttributeValue`, `IStringAttributeValue`, `INumberAttributeValue`, `IListAttributeValue`, `ITimeIntervalAttributeValue`), so `switch (attr.type)` narrows `value` for you. The union is closed on purpose: a loose member (`type: string`) would match every case and collapse the narrowing back to `unknown`; types the SDK does not model (`entity`, `date`, custom ones) stay on `IAttributeValue`. Opt-in — `IAttributeValues` keeps the loose `IAttributeValue`, so nothing existing changes.
61
+
62
+ ## v.1.0.162
63
+
64
+ ### What's New
65
+
66
+ - `distance?: number` is now declared on the entities the vector search endpoints return — `IAdminEntity`, `IDiscountsEntity`, `IOrderByMarkerEntity`, `IPagesEntity`, `IUserEntity`, `IFormDataSearchEntity` — and validated by the matching Zod schemas, mirroring `IProductsEntity.distance`. The field is the cosine distance to the query and is returned **only** when the search body carries `debug: true`.
67
+
68
+ - AttributeSets > `IAttributeSchemaItem.multiselect?: boolean` — for `list` fields, whether several options from `listTitles` may be selected. The panel has always stored the flag; the API only now declares it. Note it is still absent from every attribute the test project returns, so the field is declared but not yet observed in real data.
69
+
70
+ - Menus > `IMenusPages` — `parentType?: 'page' | 'custom' | null` and `itemType?: 'page' | 'custom'` are now declared (and validated by `MenusPagesSchema`). Page ids and custom item ids overlap, so `parentId` alone addresses a parent ambiguously; `itemType` is the value an item's children must pass in `parentType`. Both are already returned by the API.
71
+
72
+ ### What's Changed
73
+
74
+ - Blocks > the eight recommendation methods (`getCartComplement`, `getCartSimilar`, `getPersonalRecommendations`, `getRecentlyViewed`, `getRepeatPurchase`, `getTrending`, `getWishlistSimilar`, `getFrequentlyOrderedProducts`) accept a trailing optional `limit` — the query parameter the endpoints now support. It is not defaulted: when omitted, the block's own quantity setting keeps applying, so existing calls are unchanged.
75
+
76
+ - FormData > `IFormDataSearchEntity` — `formModuleId?: number` is added, and `userIdentifier` / `parentId` are widened to `string | null` / `number | null`. `formModuleId` is absent from the swagger schema but present in every record the endpoint returns; the two nullable fields are declared non-nullable there while the real data returns `null`.
77
+
78
+ ### What's Deleted
79
+
80
+ - **Breaking** — Pages > `getConfigPageByUrl` is removed, along with the `IPageConfig` type and `PageConfigSchema`. The API dropped `GET /api/content/pages/{url}/config` (and its `ConfigPageDto`); the route now answers `404`. Page display settings are available through the `config` field of a page entity.
81
+
3
82
  ## v.1.0.161
4
83
 
5
84
  ### What's New
@@ -10,7 +89,7 @@
10
89
  const { Search } = defineOneEntry('your-url', config)
11
90
 
12
91
  const all = await Search.globalSearch('winter')
13
- // drilldown: offset/limit are applied by the API only when a single type is requested
92
+ // drilldown: offset/limit require exactly one accessible type, else the API answers 400
14
93
  const products = await Search.globalSearch('winter', ['products'], 'visible', 0, 20)
15
94
  ```
16
95
 
@@ -27,8 +106,6 @@
27
106
  - Pages > `getPagesByVectorSearch` → `IPagesResponse`;
28
107
  - Users > `getUsersByVectorSearch` → `IUsersResponse` (requires user authorization).
29
108
 
30
- All six answer `500` on the test project at the time of release — the SDK side follows the documented contract, which is the same `ItemsWithTotal` container the working products endpoint returns.
31
-
32
109
  - FormData > `IFormDataSearchEntity` — new exported type for the records returned by the form data vector search. It carries the moderation and sender fields of the raw record (`status`, `ip`, `fingerprint`, `isUserAdmin`, `userIdentifier`, `entityIdentifier`, `parentId`), which `IFormDataEntity` does not declare.
33
110
 
34
111
  ### What's Changed
@@ -109,6 +109,7 @@ interface IPosition {
109
109
  }
110
110
  ]
111
111
  * @property {IFormConfig[]} [moduleFormConfigs] - Array of module form configurations associated with the admin.
112
+ * @property {number} [distance] - Cosine distance to the query. Returned only by the semantic (vector) search endpoint when `debug: true` is passed in the search body. Example: 0.12.
112
113
  * @description This interface captures the essential details and additional attributes of an admin entity.
113
114
  */
114
115
  interface IAdminEntity {
@@ -120,6 +121,7 @@ interface IAdminEntity {
120
121
  isSync: boolean;
121
122
  attributeValues: IAttributeValues;
122
123
  moduleFormConfigs?: IFormConfig[];
124
+ distance?: number;
123
125
  }
124
126
  /**
125
127
  * Interface representing a query for fetching admin data.
@@ -3,6 +3,10 @@
3
3
  * @description Zod schemas for validating admins-related API responses
4
4
  */
5
5
  import { z } from 'zod';
6
+ /**
7
+ * Admin entity schema
8
+ * Includes all fields returned by the API
9
+ */
6
10
  export declare const AdminEntitySchema: z.ZodObject<{
7
11
  id: z.ZodNumber;
8
12
  attributeSetId: z.ZodNullable<z.ZodNumber>;
@@ -10,18 +14,9 @@ export declare const AdminEntitySchema: z.ZodObject<{
10
14
  attributeSetIdentifier: z.ZodNullable<z.ZodString>;
11
15
  position: z.ZodNullable<z.ZodNumber>;
12
16
  isSync: z.ZodBoolean;
13
- attributeValues: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodType<{
14
- type: string;
15
- value: unknown;
16
- position?: number;
17
- additionalFields?: Record<string, unknown> | unknown[];
18
- }, unknown, z.core.$ZodTypeInternals<{
19
- type: string;
20
- value: unknown;
21
- position?: number;
22
- additionalFields?: Record<string, unknown> | unknown[];
23
- }, unknown>>>>;
17
+ attributeValues: z.ZodRecord<z.ZodString, z.ZodUnknown>;
24
18
  moduleFormConfigs: z.ZodOptional<z.ZodArray<z.ZodAny>>;
19
+ distance: z.ZodOptional<z.ZodNumber>;
25
20
  }, z.core.$strip>;
26
21
  /**
27
22
  * Admins response schema (array of admin entities)
@@ -33,16 +28,7 @@ export declare const AdminsResponseSchema: z.ZodArray<z.ZodObject<{
33
28
  attributeSetIdentifier: z.ZodNullable<z.ZodString>;
34
29
  position: z.ZodNullable<z.ZodNumber>;
35
30
  isSync: z.ZodBoolean;
36
- attributeValues: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodType<{
37
- type: string;
38
- value: unknown;
39
- position?: number;
40
- additionalFields?: Record<string, unknown> | unknown[];
41
- }, unknown, z.core.$ZodTypeInternals<{
42
- type: string;
43
- value: unknown;
44
- position?: number;
45
- additionalFields?: Record<string, unknown> | unknown[];
46
- }, unknown>>>>;
31
+ attributeValues: z.ZodRecord<z.ZodString, z.ZodUnknown>;
47
32
  moduleFormConfigs: z.ZodOptional<z.ZodArray<z.ZodAny>>;
33
+ distance: z.ZodOptional<z.ZodNumber>;
48
34
  }, z.core.$strip>>;
@@ -6,18 +6,11 @@ exports.AdminsResponseSchema = exports.AdminEntitySchema = void 0;
6
6
  * @description Zod schemas for validating admins-related API responses
7
7
  */
8
8
  const zod_1 = require("zod");
9
+ const validation_1 = require("../base/validation");
9
10
  /**
10
11
  * Admin entity schema
11
12
  * Includes all fields returned by the API
12
13
  */
13
- const AttributeValueSchema = zod_1.z.object({
14
- type: zod_1.z.string(),
15
- value: zod_1.z.unknown(),
16
- position: zod_1.z.number().optional(),
17
- additionalFields: zod_1.z
18
- .union([zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()), zod_1.z.array(zod_1.z.unknown())])
19
- .optional(),
20
- });
21
14
  exports.AdminEntitySchema = zod_1.z.object({
22
15
  id: zod_1.z.number(),
23
16
  attributeSetId: zod_1.z.number().nullable(),
@@ -25,8 +18,9 @@ exports.AdminEntitySchema = zod_1.z.object({
25
18
  attributeSetIdentifier: zod_1.z.string().nullable(),
26
19
  position: zod_1.z.number().nullable(),
27
20
  isSync: zod_1.z.boolean(),
28
- attributeValues: zod_1.z.record(zod_1.z.string(), zod_1.z.record(zod_1.z.string(), AttributeValueSchema)),
21
+ attributeValues: validation_1.AttributeValuesSchema,
29
22
  moduleFormConfigs: zod_1.z.array(zod_1.z.any()).optional(),
23
+ distance: zod_1.z.number().optional(),
30
24
  });
31
25
  /**
32
26
  * Admins response schema (array of admin entities)
@@ -14,18 +14,18 @@ interface IAttributesSets {
14
14
  * @throws {IError} - If there is an error during the fetch operation, it will return an error object.
15
15
  * @description This method fetches attributes by a specific marker.
16
16
  */
17
- getAttributesByMarker(marker: string, langCode: string): Promise<IAttributesSetsEntity[] | IError>;
17
+ getAttributesByMarker(marker: string, langCode?: string): Promise<IAttributesSetsEntity[] | IError>;
18
18
  /**
19
- * Fetches a single attribute by its marker and the set marker.
19
+ * Fetches a single attribute by the set marker and the attribute marker.
20
20
  * @handleName getSingleAttributeByMarkerSet
21
- * @param {string} attributeMarker - The marker identifying the attribute. Example: "color".
22
- * @param {string} setMarker - The marker identifying the attribute set. Example: "productAttributes".
21
+ * @param {string} setMarker - The marker identifying the attribute set — the first path segment. Example: "productAttributes".
22
+ * @param {string} attributeMarker - The marker identifying the attribute inside that set. Example: "color".
23
23
  * @param {string} [langCode] - The language code for localization purposes. Default: "en_US".
24
24
  * @returns {IAttributesSetsEntity} A promise that resolves to an attribute set entity or an error.
25
25
  * @throws {IError} - If there is an error during the fetch operation, it will return an error object.
26
- * @description This method fetches a single attribute by its marker and the set marker.
26
+ * @description This method fetches a single attribute of an attribute set. The order matches the request path `/{setMarker}/attributes/{attributeMarker}`: the set comes first. Both parameters are strings, so swapping them type-checks and answers `404 Attribute not found`.
27
27
  */
28
- getSingleAttributeByMarkerSet(attributeMarker: string, setMarker: string, langCode: string): Promise<IAttributesSetsEntity | IError>;
28
+ getSingleAttributeByMarkerSet(setMarker: string, attributeMarker: string, langCode?: string): Promise<IAttributesSetsEntity | IError>;
29
29
  }
30
30
  /**
31
31
  * Represents the structure of a list item.
@@ -146,6 +146,7 @@ interface IAttributesSetsEntity {
146
146
  * @property {number} [position] - Sort position of the field inside the set. Optional. Example: 1.
147
147
  * @property {IListTitle[]} [listTitles] - Options for `list`/`radioButton`/`entity` fields (with extended data or linked-entity values). Optional.
148
148
  * @property {string} [listType] - For `entity` fields — how the option list is organized. Optional. Example: "nested".
149
+ * @property {boolean} [multiselect] - For `list` fields — whether several options from `listTitles` may be selected. Optional. Example: false.
149
150
  * @property {string} [moduleIdentifier] - For `entity` fields — identifier of the module the linked entities are taken from. Optional. Example: "catalog".
150
151
  * @property {number | null} [parentId] - Identifier of the parent field, `null` for top-level. Optional, seen on `groupOfImages` fields.
151
152
  * @property {Record<string, IAttributeSchemaItem>} [additionalFields] - Nested sub-fields keyed by marker. Optional.
@@ -171,6 +172,7 @@ interface IAttributeSchemaItem {
171
172
  type: AttributeType;
172
173
  position?: number;
173
174
  listTitles?: IListTitle[];
175
+ multiselect?: boolean;
174
176
  listType?: string;
175
177
  moduleIdentifier?: string;
176
178
  parentId?: number | null;
@@ -54,6 +54,7 @@ export declare const UserResponseSchema: z.ZodObject<{
54
54
  state: z.ZodRecord<z.ZodString, z.ZodAny>;
55
55
  moduleFormConfigs: z.ZodOptional<z.ZodArray<z.ZodAny>>;
56
56
  rating: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
57
+ distance: z.ZodOptional<z.ZodNumber>;
57
58
  }, z.core.$strip>;
58
59
  /**
59
60
  * Auth provider entity schema
@@ -8,7 +8,7 @@ interface IAuthProvider {
8
8
  * Registers a new user.
9
9
  * @handleName signUp
10
10
  * @param {string} marker - The marker identifying the auth provider. Example: "email".
11
- * @param {ISignUpData} data - The data required for user registration.
11
+ * @param {ISignUpData} body - The data required for user registration.
12
12
  * @example
13
13
  {
14
14
  "formIdentifier": "reg",
@@ -40,7 +40,7 @@ interface IAuthProvider {
40
40
  * @throws {IError} - If there is an error during the fetch operation, it will return an error object.
41
41
  * @description This method registers a new user.
42
42
  */
43
- signUp(marker: string, data: ISignUpData, langCode?: string): Promise<ISignUpEntity | IError>;
43
+ signUp(marker: string, body: ISignUpData, langCode?: string): Promise<ISignUpEntity | IError>;
44
44
  /**
45
45
  * Generates an activation code for a user.
46
46
  * @handleName generateCode
@@ -79,12 +79,12 @@ interface IAuthProvider {
79
79
  * Authorizes a user.
80
80
  * @handleName auth
81
81
  * @param {string} marker - The marker identifying the auth provider. Example: "email".
82
- * @param {IAuthPostBody} data - The data required for user authorization. Example: .
82
+ * @param {IAuthPostBody} body - The data required for user authorization. Example: .
83
83
  * @returns {IAuthEntity} A promise that resolves to an auth entity or an error.
84
84
  * @throws {IError} - If there is an error during the fetch operation, it will return an error object.
85
85
  * @description This method authorizes a user.
86
86
  */
87
- auth(marker: string, data: IAuthPostBody): Promise<IAuthEntity | IError>;
87
+ auth(marker: string, body: IAuthPostBody): Promise<IAuthEntity | IError>;
88
88
  /**
89
89
  * Refreshes a user's access token.
90
90
  * @handleName refresh
@@ -0,0 +1,105 @@
1
+ import type { IAttributeFile, IAttributeValue, IFileAttributeValue, IListAttributeValue, INumberAttributeValue, IStringAttributeValue } from './utils';
2
+ /**
3
+ * Narrows an attribute value to a file-bearing attribute.
4
+ *
5
+ * `IAttributeValue.value` is `unknown` — its shape depends on `type` — so this
6
+ * guard is what lets you reach the files without a cast. It accepts both shapes
7
+ * the SDK produces: a single file object for an `image`/`file` attribute holding
8
+ * exactly one file, an array for several and for every `groupOfImages`.
9
+ * @param {IAttributeValue | undefined} attr - The attribute value to test.
10
+ * @returns {boolean} True when the attribute is an `image`, `file` or `groupOfImages` carrying files (or nothing).
11
+ * @example
12
+ * ```ts
13
+ * const attr = page.attributeValues.cover;
14
+ * if (isFileAttribute(attr)) {
15
+ * // attr.value is IAttributeFile | IAttributeFile[] | null — no cast
16
+ * }
17
+ * ```
18
+ */
19
+ export declare function isFileAttribute(attr: IAttributeValue | undefined): attr is IFileAttributeValue;
20
+ /**
21
+ * Reads every file of an attribute as an array.
22
+ *
23
+ * The one-call path for the common case. An `image`/`file` attribute holding a
24
+ * single file has it unwrapped to the object itself, while several files and
25
+ * every `groupOfImages` stay an array — a rule that is easy to get wrong in a
26
+ * way the compiler cannot catch, since `value` is `unknown`: reading `value[0]`
27
+ * off a single file yields `undefined` and nothing anywhere reports an error.
28
+ * This helper collapses both shapes to a list.
29
+ *
30
+ * Anything that is not a file-bearing attribute yields an empty array, so it is
31
+ * safe to call on an arbitrary attribute without checking `type` first.
32
+ * @param {IAttributeValue | undefined} attr - An attribute value, e.g. `page.attributeValues.cover`.
33
+ * @returns {IAttributeFile[]} The files, in the order the API returned them; empty when the attribute holds none or is not file-bearing.
34
+ * @example
35
+ * ```ts
36
+ * import { getAttributeFiles } from 'oneentry';
37
+ *
38
+ * // Works the same for one image and for a gallery.
39
+ * const images = getAttributeFiles(page.attributeValues.cover);
40
+ * images.map((file) => file.downloadLink);
41
+ * ```
42
+ */
43
+ export declare function getAttributeFiles(attr: IAttributeValue | undefined): IAttributeFile[];
44
+ /**
45
+ * Reads the first file of an attribute.
46
+ *
47
+ * The single-image counterpart of {@link getAttributeFiles} — same shape
48
+ * handling, but returns the file itself instead of a list. For a gallery it
49
+ * returns the first entry, which is what a preview or a cover usually needs.
50
+ * @param {IAttributeValue | undefined} attr - An attribute value, e.g. `product.attributeValues.img`.
51
+ * @returns {IAttributeFile | null} The first file, or null when the attribute holds none.
52
+ * @example
53
+ * ```ts
54
+ * import { getAttributeFile } from 'oneentry';
55
+ *
56
+ * const cover = getAttributeFile(product.attributeValues.img);
57
+ * const blurDataURL = cover?.previewLink?.default?.[0];
58
+ * ```
59
+ */
60
+ export declare function getAttributeFile(attr: IAttributeValue | undefined): IAttributeFile | null;
61
+ /**
62
+ * Narrows an attribute value to a text attribute.
63
+ * @param {IAttributeValue | undefined} attr - The attribute value to test.
64
+ * @returns {boolean} True when the attribute is a `string`, `text` or `textEditor` carrying a string (or nothing).
65
+ */
66
+ export declare function isStringAttribute(attr: IAttributeValue | undefined): attr is IStringAttributeValue;
67
+ /**
68
+ * Narrows an attribute value to a numeric attribute.
69
+ *
70
+ * The SDK casts `integer`, `float` and `real` values to a JS number, so the
71
+ * guard checks for one — a value that failed to cast is `null`.
72
+ * @param {IAttributeValue | undefined} attr - The attribute value to test.
73
+ * @returns {boolean} True when the attribute is an `integer`, `float` or `real` carrying a number (or nothing).
74
+ */
75
+ export declare function isNumberAttribute(attr: IAttributeValue | undefined): attr is INumberAttributeValue;
76
+ /**
77
+ * Narrows an attribute value to a `list` attribute.
78
+ *
79
+ * The option shape is defined by the attribute set, so the entries stay
80
+ * `unknown` — the guard only promises the array container.
81
+ * @param {IAttributeValue | undefined} attr - The attribute value to test.
82
+ * @returns {boolean} True when the attribute is a `list` carrying an array.
83
+ */
84
+ export declare function isListAttribute(attr: IAttributeValue | undefined): attr is IListAttributeValue;
85
+ /**
86
+ * Reads the nested fields of an attribute as a marker map.
87
+ *
88
+ * `additionalFields` is typed `Record<string, IAttributeValue> | unknown[]`
89
+ * because the API returns an empty **array** when an attribute has no nested
90
+ * fields — the union makes every read of a field a type error. This helper
91
+ * collapses that case to an empty map, so the result is always keyed by marker.
92
+ *
93
+ * With `rawData: true` in the config the SDK keeps the API's original array of
94
+ * fields; it is converted here by `marker` as well, so the helper returns the
95
+ * same map in both modes.
96
+ * @param {IAttributeValue | undefined} attr - An attribute value whose nested fields to read.
97
+ * @returns {Record<string, IAttributeValue>} Nested attribute values keyed by marker; empty when there are none.
98
+ * @example
99
+ * ```ts
100
+ * import { getAdditionalFields } from 'oneentry';
101
+ *
102
+ * const alt = getAdditionalFields(page.attributeValues.cover).alt?.value;
103
+ * ```
104
+ */
105
+ export declare function getAdditionalFields(attr: IAttributeValue | undefined): Record<string, IAttributeValue>;
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isFileAttribute = isFileAttribute;
4
+ exports.getAttributeFiles = getAttributeFiles;
5
+ exports.getAttributeFile = getAttributeFile;
6
+ exports.isStringAttribute = isStringAttribute;
7
+ exports.isNumberAttribute = isNumberAttribute;
8
+ exports.isListAttribute = isListAttribute;
9
+ exports.getAdditionalFields = getAdditionalFields;
10
+ const _FILE_TYPES = ['image', 'file', 'groupOfImages'];
11
+ /**
12
+ * Tests whether a value looks like a file object of an attribute.
13
+ *
14
+ * A file is identified by `downloadLink`: it is the one field every file of
15
+ * every attribute carries, while previews are only generated for images.
16
+ * @param {unknown} value - The value to test.
17
+ * @returns {boolean} True when the value is a file object.
18
+ */
19
+ function _isFile(value) {
20
+ return (!!value &&
21
+ typeof value === 'object' &&
22
+ typeof value.downloadLink === 'string');
23
+ }
24
+ /**
25
+ * Narrows an attribute value to a file-bearing attribute.
26
+ *
27
+ * `IAttributeValue.value` is `unknown` — its shape depends on `type` — so this
28
+ * guard is what lets you reach the files without a cast. It accepts both shapes
29
+ * the SDK produces: a single file object for an `image`/`file` attribute holding
30
+ * exactly one file, an array for several and for every `groupOfImages`.
31
+ * @param {IAttributeValue | undefined} attr - The attribute value to test.
32
+ * @returns {boolean} True when the attribute is an `image`, `file` or `groupOfImages` carrying files (or nothing).
33
+ * @example
34
+ * ```ts
35
+ * const attr = page.attributeValues.cover;
36
+ * if (isFileAttribute(attr)) {
37
+ * // attr.value is IAttributeFile | IAttributeFile[] | null — no cast
38
+ * }
39
+ * ```
40
+ */
41
+ function isFileAttribute(attr) {
42
+ if (!attr || !_FILE_TYPES.includes(attr.type))
43
+ return false;
44
+ if (attr.value === null || attr.value === undefined)
45
+ return true;
46
+ return Array.isArray(attr.value)
47
+ ? attr.value.every((item) => _isFile(item))
48
+ : _isFile(attr.value);
49
+ }
50
+ /**
51
+ * Reads every file of an attribute as an array.
52
+ *
53
+ * The one-call path for the common case. An `image`/`file` attribute holding a
54
+ * single file has it unwrapped to the object itself, while several files and
55
+ * every `groupOfImages` stay an array — a rule that is easy to get wrong in a
56
+ * way the compiler cannot catch, since `value` is `unknown`: reading `value[0]`
57
+ * off a single file yields `undefined` and nothing anywhere reports an error.
58
+ * This helper collapses both shapes to a list.
59
+ *
60
+ * Anything that is not a file-bearing attribute yields an empty array, so it is
61
+ * safe to call on an arbitrary attribute without checking `type` first.
62
+ * @param {IAttributeValue | undefined} attr - An attribute value, e.g. `page.attributeValues.cover`.
63
+ * @returns {IAttributeFile[]} The files, in the order the API returned them; empty when the attribute holds none or is not file-bearing.
64
+ * @example
65
+ * ```ts
66
+ * import { getAttributeFiles } from 'oneentry';
67
+ *
68
+ * // Works the same for one image and for a gallery.
69
+ * const images = getAttributeFiles(page.attributeValues.cover);
70
+ * images.map((file) => file.downloadLink);
71
+ * ```
72
+ */
73
+ function getAttributeFiles(attr) {
74
+ if (!attr)
75
+ return [];
76
+ const value = attr.value;
77
+ if (Array.isArray(value))
78
+ return value.filter((item) => _isFile(item));
79
+ return _isFile(value) ? [value] : [];
80
+ }
81
+ /**
82
+ * Reads the first file of an attribute.
83
+ *
84
+ * The single-image counterpart of {@link getAttributeFiles} — same shape
85
+ * handling, but returns the file itself instead of a list. For a gallery it
86
+ * returns the first entry, which is what a preview or a cover usually needs.
87
+ * @param {IAttributeValue | undefined} attr - An attribute value, e.g. `product.attributeValues.img`.
88
+ * @returns {IAttributeFile | null} The first file, or null when the attribute holds none.
89
+ * @example
90
+ * ```ts
91
+ * import { getAttributeFile } from 'oneentry';
92
+ *
93
+ * const cover = getAttributeFile(product.attributeValues.img);
94
+ * const blurDataURL = cover?.previewLink?.default?.[0];
95
+ * ```
96
+ */
97
+ function getAttributeFile(attr) {
98
+ var _a;
99
+ return (_a = getAttributeFiles(attr)[0]) !== null && _a !== void 0 ? _a : null;
100
+ }
101
+ /**
102
+ * Narrows an attribute value to a text attribute.
103
+ * @param {IAttributeValue | undefined} attr - The attribute value to test.
104
+ * @returns {boolean} True when the attribute is a `string`, `text` or `textEditor` carrying a string (or nothing).
105
+ */
106
+ function isStringAttribute(attr) {
107
+ return (!!attr &&
108
+ (attr.type === 'string' ||
109
+ attr.type === 'text' ||
110
+ attr.type === 'textEditor') &&
111
+ (attr.value === null || typeof attr.value === 'string'));
112
+ }
113
+ /**
114
+ * Narrows an attribute value to a numeric attribute.
115
+ *
116
+ * The SDK casts `integer`, `float` and `real` values to a JS number, so the
117
+ * guard checks for one — a value that failed to cast is `null`.
118
+ * @param {IAttributeValue | undefined} attr - The attribute value to test.
119
+ * @returns {boolean} True when the attribute is an `integer`, `float` or `real` carrying a number (or nothing).
120
+ */
121
+ function isNumberAttribute(attr) {
122
+ return (!!attr &&
123
+ (attr.type === 'integer' ||
124
+ attr.type === 'float' ||
125
+ attr.type === 'real') &&
126
+ (attr.value === null || typeof attr.value === 'number'));
127
+ }
128
+ /**
129
+ * Narrows an attribute value to a `list` attribute.
130
+ *
131
+ * The option shape is defined by the attribute set, so the entries stay
132
+ * `unknown` — the guard only promises the array container.
133
+ * @param {IAttributeValue | undefined} attr - The attribute value to test.
134
+ * @returns {boolean} True when the attribute is a `list` carrying an array.
135
+ */
136
+ function isListAttribute(attr) {
137
+ return !!attr && attr.type === 'list' && Array.isArray(attr.value);
138
+ }
139
+ /**
140
+ * Reads the nested fields of an attribute as a marker map.
141
+ *
142
+ * `additionalFields` is typed `Record<string, IAttributeValue> | unknown[]`
143
+ * because the API returns an empty **array** when an attribute has no nested
144
+ * fields — the union makes every read of a field a type error. This helper
145
+ * collapses that case to an empty map, so the result is always keyed by marker.
146
+ *
147
+ * With `rawData: true` in the config the SDK keeps the API's original array of
148
+ * fields; it is converted here by `marker` as well, so the helper returns the
149
+ * same map in both modes.
150
+ * @param {IAttributeValue | undefined} attr - An attribute value whose nested fields to read.
151
+ * @returns {Record<string, IAttributeValue>} Nested attribute values keyed by marker; empty when there are none.
152
+ * @example
153
+ * ```ts
154
+ * import { getAdditionalFields } from 'oneentry';
155
+ *
156
+ * const alt = getAdditionalFields(page.attributeValues.cover).alt?.value;
157
+ * ```
158
+ */
159
+ function getAdditionalFields(attr) {
160
+ const fields = attr === null || attr === void 0 ? void 0 : attr.additionalFields;
161
+ if (!fields || typeof fields !== 'object')
162
+ return {};
163
+ if (Array.isArray(fields)) {
164
+ // rawData mode: the API's own array of fields, each carrying its marker.
165
+ return Object.fromEntries(fields
166
+ .filter((field) => !!field &&
167
+ typeof field === 'object' &&
168
+ typeof field.marker === 'string')
169
+ .map((field) => [field.marker, field]));
170
+ }
171
+ return fields;
172
+ }