oneentry 1.0.162 → 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.
- package/README.md +18 -0
- package/changelog.md +59 -0
- package/dist/admins/adminsSchemas.d.ts +6 -22
- package/dist/admins/adminsSchemas.js +2 -9
- package/dist/attribute-sets/attributeSetsInterfaces.d.ts +6 -6
- package/dist/auth-provider/authProvidersInterfaces.d.ts +4 -4
- package/dist/base/attributes.d.ts +105 -0
- package/dist/base/attributes.js +172 -0
- package/dist/base/utils.d.ts +95 -2
- package/dist/base/validation.d.ts +29 -0
- package/dist/base/validation.js +93 -1
- package/dist/blocks/blocksInterfaces.d.ts +1 -1
- package/dist/blocks/blocksSchemas.d.ts +6 -6
- package/dist/blocks/blocksSchemas.js +2 -1
- package/dist/discounts/discountsInterfaces.d.ts +1 -1
- package/dist/forms-data/formsDataApi.d.ts +16 -6
- package/dist/forms-data/formsDataApi.js +14 -4
- package/dist/forms-data/formsDataInterfaces.d.ts +48 -15
- package/dist/index.d.ts +1 -0
- package/dist/index.js +9 -1
- package/dist/integration-collections/integrationCollectionsInterfaces.d.ts +6 -6
- package/dist/menus/menusInterfaces.d.ts +1 -1
- package/dist/menus/menusSchemas.js +2 -1
- package/dist/orders/ordersInterfaces.d.ts +1 -1
- package/dist/pages/pagesSchemas.d.ts +3 -3
- package/dist/pages/pagesSchemas.js +2 -1
- package/dist/product-statuses/productStatusesInterfaces.d.ts +2 -2
- package/dist/products/productsSchemas.d.ts +5 -5
- package/dist/products/productsSchemas.js +3 -2
- package/dist/templates/templatesInterfaces.d.ts +1 -1
- package/dist/templates/templatesSchemas.d.ts +3 -3
- package/dist/templates/templatesSchemas.js +2 -1
- package/dist/templates-preview/templatesPreviewInterfaces.d.ts +2 -2
- package/esm/admins/adminsSchemas.d.ts +6 -22
- package/esm/admins/adminsSchemas.js +2 -9
- package/esm/attribute-sets/attributeSetsInterfaces.d.ts +6 -6
- package/esm/auth-provider/authProvidersInterfaces.d.ts +4 -4
- package/esm/base/attributes.d.ts +105 -0
- package/esm/base/attributes.js +163 -0
- package/esm/base/utils.d.ts +95 -2
- package/esm/base/validation.d.ts +29 -0
- package/esm/base/validation.js +92 -0
- package/esm/blocks/blocksInterfaces.d.ts +1 -1
- package/esm/blocks/blocksSchemas.d.ts +6 -6
- package/esm/blocks/blocksSchemas.js +2 -1
- package/esm/discounts/discountsInterfaces.d.ts +1 -1
- package/esm/forms-data/formsDataApi.d.ts +16 -6
- package/esm/forms-data/formsDataApi.js +14 -4
- package/esm/forms-data/formsDataInterfaces.d.ts +48 -15
- package/esm/index.d.ts +1 -0
- package/esm/index.js +1 -0
- package/esm/integration-collections/integrationCollectionsInterfaces.d.ts +6 -6
- package/esm/menus/menusInterfaces.d.ts +1 -1
- package/esm/menus/menusSchemas.js +2 -1
- package/esm/orders/ordersInterfaces.d.ts +1 -1
- package/esm/pages/pagesSchemas.d.ts +3 -3
- package/esm/pages/pagesSchemas.js +2 -1
- package/esm/product-statuses/productStatusesInterfaces.d.ts +2 -2
- package/esm/products/productsSchemas.d.ts +5 -5
- package/esm/products/productsSchemas.js +3 -2
- package/esm/templates/templatesInterfaces.d.ts +1 -1
- package/esm/templates/templatesSchemas.d.ts +3 -3
- package/esm/templates/templatesSchemas.js +2 -1
- package/esm/templates-preview/templatesPreviewInterfaces.d.ts +2 -2
- 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,64 @@
|
|
|
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
|
+
|
|
3
62
|
## v.1.0.162
|
|
4
63
|
|
|
5
64
|
### What's New
|
|
@@ -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,17 +14,7 @@ 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.
|
|
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>>;
|
|
25
19
|
distance: z.ZodOptional<z.ZodNumber>;
|
|
26
20
|
}, z.core.$strip>;
|
|
@@ -34,17 +28,7 @@ export declare const AdminsResponseSchema: z.ZodArray<z.ZodObject<{
|
|
|
34
28
|
attributeSetIdentifier: z.ZodNullable<z.ZodString>;
|
|
35
29
|
position: z.ZodNullable<z.ZodNumber>;
|
|
36
30
|
isSync: z.ZodBoolean;
|
|
37
|
-
attributeValues: z.ZodRecord<z.ZodString, z.
|
|
38
|
-
type: string;
|
|
39
|
-
value: unknown;
|
|
40
|
-
position?: number;
|
|
41
|
-
additionalFields?: Record<string, unknown> | unknown[];
|
|
42
|
-
}, unknown, z.core.$ZodTypeInternals<{
|
|
43
|
-
type: string;
|
|
44
|
-
value: unknown;
|
|
45
|
-
position?: number;
|
|
46
|
-
additionalFields?: Record<string, unknown> | unknown[];
|
|
47
|
-
}, unknown>>>>;
|
|
31
|
+
attributeValues: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
48
32
|
moduleFormConfigs: z.ZodOptional<z.ZodArray<z.ZodAny>>;
|
|
49
33
|
distance: z.ZodOptional<z.ZodNumber>;
|
|
50
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,7 +18,7 @@ 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:
|
|
21
|
+
attributeValues: validation_1.AttributeValuesSchema,
|
|
29
22
|
moduleFormConfigs: zod_1.z.array(zod_1.z.any()).optional(),
|
|
30
23
|
distance: zod_1.z.number().optional(),
|
|
31
24
|
});
|
|
@@ -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
|
|
17
|
+
getAttributesByMarker(marker: string, langCode?: string): Promise<IAttributesSetsEntity[] | IError>;
|
|
18
18
|
/**
|
|
19
|
-
* Fetches a single attribute by
|
|
19
|
+
* Fetches a single attribute by the set marker and the attribute marker.
|
|
20
20
|
* @handleName getSingleAttributeByMarkerSet
|
|
21
|
-
* @param {string}
|
|
22
|
-
* @param {string}
|
|
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
|
|
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(
|
|
28
|
+
getSingleAttributeByMarkerSet(setMarker: string, attributeMarker: string, langCode?: string): Promise<IAttributesSetsEntity | IError>;
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* Represents the structure of a list item.
|
|
@@ -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}
|
|
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,
|
|
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}
|
|
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,
|
|
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
|
+
}
|
package/dist/base/utils.d.ts
CHANGED
|
@@ -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, };
|