@ram_28/kf-ai-sdk 2.0.1 → 2.0.3
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 +36 -39
- package/dist/BaseField-B6da88U7.js +40 -0
- package/dist/BaseField-Drp0-OxL.cjs +1 -0
- package/dist/api/client.d.ts +7 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/index.d.ts +1 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/metadata.d.ts +26 -22
- package/dist/api/metadata.d.ts.map +1 -1
- package/dist/api.cjs +1 -1
- package/dist/api.mjs +3 -3
- package/dist/auth.cjs +1 -1
- package/dist/auth.mjs +2 -2
- package/dist/base-types.d.ts +1 -1
- package/dist/base-types.d.ts.map +1 -1
- package/dist/bdo/core/BaseBdo.d.ts +12 -20
- package/dist/bdo/core/BaseBdo.d.ts.map +1 -1
- package/dist/bdo/core/Item.d.ts +8 -44
- package/dist/bdo/core/Item.d.ts.map +1 -1
- package/dist/bdo/core/types.d.ts +124 -41
- package/dist/bdo/core/types.d.ts.map +1 -1
- package/dist/bdo/fields/ArrayField.d.ts +5 -4
- package/dist/bdo/fields/ArrayField.d.ts.map +1 -1
- package/dist/bdo/fields/BaseField.d.ts +14 -19
- package/dist/bdo/fields/BaseField.d.ts.map +1 -1
- package/dist/bdo/fields/BooleanField.d.ts +3 -4
- package/dist/bdo/fields/BooleanField.d.ts.map +1 -1
- package/dist/bdo/fields/DateField.d.ts +3 -4
- package/dist/bdo/fields/DateField.d.ts.map +1 -1
- package/dist/bdo/fields/DateTimeField.d.ts +5 -4
- package/dist/bdo/fields/DateTimeField.d.ts.map +1 -1
- package/dist/bdo/fields/FileField.d.ts +18 -0
- package/dist/bdo/fields/FileField.d.ts.map +1 -0
- package/dist/bdo/fields/NumberField.d.ts +6 -4
- package/dist/bdo/fields/NumberField.d.ts.map +1 -1
- package/dist/bdo/fields/ObjectField.d.ts +5 -4
- package/dist/bdo/fields/ObjectField.d.ts.map +1 -1
- package/dist/bdo/fields/ReferenceField.d.ts +13 -14
- package/dist/bdo/fields/ReferenceField.d.ts.map +1 -1
- package/dist/bdo/fields/SelectField.d.ts +9 -16
- package/dist/bdo/fields/SelectField.d.ts.map +1 -1
- package/dist/bdo/fields/StringField.d.ts +6 -4
- package/dist/bdo/fields/StringField.d.ts.map +1 -1
- package/dist/bdo/fields/TextAreaField.d.ts +1 -18
- package/dist/bdo/fields/TextAreaField.d.ts.map +1 -1
- package/dist/bdo/fields/TextField.d.ts +22 -0
- package/dist/bdo/fields/TextField.d.ts.map +1 -0
- package/dist/bdo/fields/UserField.d.ts +20 -0
- package/dist/bdo/fields/UserField.d.ts.map +1 -0
- package/dist/bdo/fields/index.d.ts +5 -2
- package/dist/bdo/fields/index.d.ts.map +1 -1
- package/dist/bdo/index.d.ts +2 -2
- package/dist/bdo/index.d.ts.map +1 -1
- package/dist/bdo.cjs +1 -1
- package/dist/bdo.d.ts +1 -5
- package/dist/bdo.d.ts.map +1 -1
- package/dist/bdo.mjs +286 -243
- package/dist/bdo.types.d.ts +2 -3
- package/dist/bdo.types.d.ts.map +1 -1
- package/dist/{client-BIkaIr2y.js → client-BULEEaCP.js} +84 -79
- package/dist/client-DtPpfJc1.cjs +1 -0
- package/dist/components/hooks/useFilter/useFilter.d.ts.map +1 -1
- package/dist/components/hooks/useForm/createItemProxy.d.ts.map +1 -1
- package/dist/components/hooks/useForm/createResolver.d.ts +12 -2
- package/dist/components/hooks/useForm/createResolver.d.ts.map +1 -1
- package/dist/components/hooks/useForm/index.d.ts +1 -1
- package/dist/components/hooks/useForm/index.d.ts.map +1 -1
- package/dist/components/hooks/useForm/types.d.ts +77 -8
- package/dist/components/hooks/useForm/types.d.ts.map +1 -1
- package/dist/components/hooks/useForm/useDraftInteraction.d.ts +26 -0
- package/dist/components/hooks/useForm/useDraftInteraction.d.ts.map +1 -0
- package/dist/components/hooks/useForm/useForm.d.ts +2 -27
- package/dist/components/hooks/useForm/useForm.d.ts.map +1 -1
- package/dist/components/hooks/useTable/useTable.d.ts.map +1 -1
- package/dist/{constants-DaX7GLgl.js → constants-BQrBcCON.js} +37 -13
- package/dist/constants-D0J69if5.cjs +1 -0
- package/dist/error-handling-CAoD0Kwb.cjs +1 -0
- package/dist/error-handling-CrhTtD88.js +14 -0
- package/dist/filter.cjs +1 -1
- package/dist/filter.mjs +2 -2
- package/dist/form.cjs +1 -1
- package/dist/form.d.ts +1 -1
- package/dist/form.d.ts.map +1 -1
- package/dist/form.mjs +333 -1142
- package/dist/form.types.d.ts +1 -1
- package/dist/form.types.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm-Cj63v5ny.js +1014 -0
- package/dist/index.esm-DuwT11sx.cjs +1 -0
- package/dist/{metadata-Bz8zJqC1.cjs → metadata-BJWukIqS.cjs} +1 -1
- package/dist/{metadata-VbQzyD2C.js → metadata-CJuFxytC.js} +1 -1
- package/dist/table.cjs +1 -1
- package/dist/table.mjs +116 -122
- package/dist/types/base-fields.d.ts +24 -59
- package/dist/types/base-fields.d.ts.map +1 -1
- package/dist/types/constants.d.ts +2 -2
- package/dist/types/constants.d.ts.map +1 -1
- package/dist/useFilter-Bg0jvIL6.cjs +1 -0
- package/dist/useFilter-DPNLKY3H.js +118 -0
- package/dist/utils/formatting.d.ts +10 -1
- package/dist/utils/formatting.d.ts.map +1 -1
- package/dist/workflow/Activity.d.ts +85 -0
- package/dist/workflow/Activity.d.ts.map +1 -0
- package/dist/workflow/ActivityInstance.d.ts +96 -0
- package/dist/workflow/ActivityInstance.d.ts.map +1 -0
- package/dist/workflow/client.d.ts +39 -0
- package/dist/workflow/client.d.ts.map +1 -0
- package/dist/workflow/components/useActivityForm/createActivityItemProxy.d.ts +16 -0
- package/dist/workflow/components/useActivityForm/createActivityItemProxy.d.ts.map +1 -0
- package/dist/workflow/components/useActivityForm/createActivityResolver.d.ts +22 -0
- package/dist/workflow/components/useActivityForm/createActivityResolver.d.ts.map +1 -0
- package/dist/workflow/components/useActivityForm/index.d.ts +3 -0
- package/dist/workflow/components/useActivityForm/index.d.ts.map +1 -0
- package/dist/workflow/components/useActivityForm/types.d.ts +80 -0
- package/dist/workflow/components/useActivityForm/types.d.ts.map +1 -0
- package/dist/workflow/components/useActivityForm/useActivityForm.d.ts +4 -0
- package/dist/workflow/components/useActivityForm/useActivityForm.d.ts.map +1 -0
- package/dist/workflow/index.d.ts +8 -0
- package/dist/workflow/index.d.ts.map +1 -0
- package/dist/workflow/types.d.ts +53 -0
- package/dist/workflow/types.d.ts.map +1 -0
- package/dist/workflow.cjs +1 -0
- package/dist/workflow.d.ts +8 -0
- package/dist/workflow.d.ts.map +1 -0
- package/dist/workflow.mjs +565 -0
- package/dist/workflow.types.cjs +1 -0
- package/dist/workflow.types.d.ts +2 -0
- package/dist/workflow.types.d.ts.map +1 -0
- package/dist/workflow.types.mjs +1 -0
- package/docs/api.md +140 -572
- package/docs/bdo.md +742 -0
- package/docs/useAuth.md +10 -4
- package/docs/useFilter.md +40 -40
- package/docs/useForm.md +91 -62
- package/docs/useTable.md +38 -38
- package/docs/workflow.md +703 -0
- package/package.json +21 -1
- package/sdk/api/client.ts +77 -57
- package/sdk/api/index.ts +1 -0
- package/sdk/api/metadata.ts +22 -20
- package/sdk/base-types.ts +5 -9
- package/sdk/bdo/core/BaseBdo.ts +23 -38
- package/sdk/bdo/core/Item.ts +34 -56
- package/sdk/bdo/core/types.ts +147 -45
- package/sdk/bdo/fields/ArrayField.ts +9 -5
- package/sdk/bdo/fields/BaseField.ts +19 -29
- package/sdk/bdo/fields/BooleanField.ts +4 -5
- package/sdk/bdo/fields/DateField.ts +4 -5
- package/sdk/bdo/fields/DateTimeField.ts +9 -5
- package/sdk/bdo/fields/FileField.ts +39 -0
- package/sdk/bdo/fields/NumberField.ts +8 -5
- package/sdk/bdo/fields/ObjectField.ts +9 -5
- package/sdk/bdo/fields/ReferenceField.ts +22 -28
- package/sdk/bdo/fields/SelectField.ts +13 -26
- package/sdk/bdo/fields/StringField.ts +10 -5
- package/sdk/bdo/fields/TextAreaField.ts +3 -32
- package/sdk/bdo/fields/TextField.ts +42 -0
- package/sdk/bdo/fields/UserField.ts +52 -0
- package/sdk/bdo/fields/index.ts +5 -2
- package/sdk/bdo/index.ts +19 -4
- package/sdk/bdo.ts +4 -31
- package/sdk/bdo.types.ts +26 -21
- package/sdk/components/hooks/useFilter/useFilter.ts +13 -30
- package/sdk/components/hooks/useForm/createItemProxy.ts +47 -11
- package/sdk/components/hooks/useForm/createResolver.ts +65 -6
- package/sdk/components/hooks/useForm/index.ts +4 -0
- package/sdk/components/hooks/useForm/types.ts +92 -9
- package/sdk/components/hooks/useForm/useDraftInteraction.ts +251 -0
- package/sdk/components/hooks/useForm/useForm.ts +132 -60
- package/sdk/components/hooks/useTable/useTable.ts +10 -2
- package/sdk/form.ts +1 -12
- package/sdk/form.types.ts +1 -0
- package/sdk/index.ts +9 -3
- package/sdk/types/base-fields.ts +28 -72
- package/sdk/types/constants.ts +2 -2
- package/sdk/utils/formatting.ts +13 -1
- package/sdk/workflow/Activity.ts +181 -0
- package/sdk/workflow/ActivityInstance.ts +339 -0
- package/sdk/workflow/client.ts +208 -0
- package/sdk/workflow/components/useActivityForm/createActivityItemProxy.ts +126 -0
- package/sdk/workflow/components/useActivityForm/createActivityResolver.ts +61 -0
- package/sdk/workflow/components/useActivityForm/index.ts +5 -0
- package/sdk/workflow/components/useActivityForm/types.ts +166 -0
- package/sdk/workflow/components/useActivityForm/useActivityForm.ts +386 -0
- package/sdk/workflow/index.ts +20 -0
- package/sdk/workflow/types.ts +84 -0
- package/sdk/workflow.ts +25 -0
- package/sdk/workflow.types.ts +11 -0
- package/dist/client-DxjRcEtN.cjs +0 -1
- package/dist/constants-C49b9Exc.cjs +0 -1
- package/dist/useFilter-DzpP_ag0.cjs +0 -1
- package/dist/useFilter-H5bgAZQF.js +0 -120
package/docs/bdo.md
ADDED
|
@@ -0,0 +1,742 @@
|
|
|
1
|
+
# BDO SDK API
|
|
2
|
+
|
|
3
|
+
Type-safe, role-based data access layer for business objects.
|
|
4
|
+
|
|
5
|
+
## Imports
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// BDO class (from your generated code)
|
|
9
|
+
import { AdminProduct } from "../bdo/admin/Product";
|
|
10
|
+
|
|
11
|
+
// Field types (from your generated code)
|
|
12
|
+
import type {
|
|
13
|
+
AdminProductEditableFieldType,
|
|
14
|
+
AdminProductReadonlyFieldType,
|
|
15
|
+
AdminProductFieldType,
|
|
16
|
+
} from "../bdo/admin/Product";
|
|
17
|
+
|
|
18
|
+
// SDK types
|
|
19
|
+
import type {
|
|
20
|
+
ItemType,
|
|
21
|
+
BdoMetaType,
|
|
22
|
+
ValidationResultType,
|
|
23
|
+
SelectOptionType,
|
|
24
|
+
EditableFieldAccessorType,
|
|
25
|
+
ReadonlyFieldAccessorType,
|
|
26
|
+
BaseFieldMetaType,
|
|
27
|
+
} from "@ram_28/kf-ai-sdk/bdo/types";
|
|
28
|
+
|
|
29
|
+
// System fields
|
|
30
|
+
import type { SystemFieldsType } from "@ram_28/kf-ai-sdk/bdo/types";
|
|
31
|
+
|
|
32
|
+
// API types (for method params/responses)
|
|
33
|
+
import type {
|
|
34
|
+
ListOptionsType,
|
|
35
|
+
CreateUpdateResponseType,
|
|
36
|
+
DeleteResponseType,
|
|
37
|
+
DraftResponseType,
|
|
38
|
+
MetricOptionsType,
|
|
39
|
+
MetricResponseType,
|
|
40
|
+
PivotOptionsType,
|
|
41
|
+
PivotResponseType,
|
|
42
|
+
} from "@ram_28/kf-ai-sdk/api/types";
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## BDO Meta
|
|
46
|
+
|
|
47
|
+
Every BDO has a `meta` property identifying the business object.
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
const product = new AdminProduct();
|
|
51
|
+
|
|
52
|
+
product.meta._id; // "BDO_Product"
|
|
53
|
+
product.meta.name; // "Product"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Use `meta._id` anywhere a source identifier is needed (e.g., `useTable`, `useFilter`).
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Field Definitions
|
|
61
|
+
|
|
62
|
+
Fields are readonly properties on the BDO class, constructed with raw backend meta JSON.
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
// In the generated BDO class
|
|
66
|
+
readonly Title = new StringField({
|
|
67
|
+
_id: "Title",
|
|
68
|
+
Name: "Product Title",
|
|
69
|
+
Type: "String",
|
|
70
|
+
Constraint: { Required: true, Length: 255 },
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### BaseField Getters
|
|
75
|
+
|
|
76
|
+
Every field exposes these getters:
|
|
77
|
+
|
|
78
|
+
| Getter | Type | Source |
|
|
79
|
+
|--------|------|--------|
|
|
80
|
+
| `field.id` | `string` | `_meta._id` |
|
|
81
|
+
| `field.label` | `string` | `_meta.Name` |
|
|
82
|
+
| `field.readOnly` | `boolean` | `_meta.ReadOnly` |
|
|
83
|
+
| `field.required` | `boolean` | `_meta.Constraint.Required` or `_meta.Required` |
|
|
84
|
+
| `field.defaultValue` | `unknown` | `_meta.DefaultValue` or `_meta.Constraint.DefaultValue` |
|
|
85
|
+
| `field.primaryKey` | `boolean` | `_meta.Constraint.PrimaryKey` |
|
|
86
|
+
| `field.meta` | `BaseFieldMetaType` | Full raw backend meta object |
|
|
87
|
+
|
|
88
|
+
### Usage
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
const product = new AdminProduct();
|
|
92
|
+
|
|
93
|
+
// react-hook-form register
|
|
94
|
+
register(product.Title.id);
|
|
95
|
+
|
|
96
|
+
// UI labels
|
|
97
|
+
<label>{product.Title.label}</label>
|
|
98
|
+
|
|
99
|
+
// Required indicator
|
|
100
|
+
{product.Title.required && <span>*</span>}
|
|
101
|
+
|
|
102
|
+
// Filter by field
|
|
103
|
+
const items = await product.list({
|
|
104
|
+
Filter: {
|
|
105
|
+
Operator: "And",
|
|
106
|
+
Condition: [{
|
|
107
|
+
LHSField: product.Price.id,
|
|
108
|
+
Operator: "GT",
|
|
109
|
+
RHSValue: 50,
|
|
110
|
+
RHSType: "Constant",
|
|
111
|
+
}],
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Methods
|
|
119
|
+
|
|
120
|
+
All `BaseBdo` methods are `protected`. Role BDOs selectively re-expose them as `public` based on permissions. For full request/response type definitions, see [api.md](api.md).
|
|
121
|
+
|
|
122
|
+
### get
|
|
123
|
+
|
|
124
|
+
Fetches a single record by ID.
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
async get(id: string): Promise<ItemType<TEditable, TReadonly>>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Returns an [ItemType](#itemtype--runtime-accessor-pattern) with field accessors.
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
const item = await product.get("prod_abc123");
|
|
134
|
+
|
|
135
|
+
console.log(item._id); // "prod_abc123"
|
|
136
|
+
console.log(item.Title.get()); // "Wireless Headphones"
|
|
137
|
+
console.log(item.Title.label); // "Product Title"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
### list
|
|
143
|
+
|
|
144
|
+
Fetches paginated records with optional filtering, sorting, and pagination.
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
async list(options?: ListOptionsType): Promise<ItemType<TEditable, TReadonly>[]>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Returns an array of [ItemType](#itemtype--runtime-accessor-pattern).
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
const items = await product.list({
|
|
154
|
+
Filter: {
|
|
155
|
+
Operator: "And",
|
|
156
|
+
Condition: [{
|
|
157
|
+
LHSField: product.Category.id,
|
|
158
|
+
Operator: "EQ",
|
|
159
|
+
RHSValue: "Electronics",
|
|
160
|
+
RHSType: "Constant",
|
|
161
|
+
}],
|
|
162
|
+
},
|
|
163
|
+
Sort: [{ [product.Price.id]: "ASC" }],
|
|
164
|
+
Page: 1,
|
|
165
|
+
PageSize: 20,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
items.forEach((item) => {
|
|
169
|
+
console.log(item.Title.get(), item.Price.get());
|
|
170
|
+
});
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
### count
|
|
176
|
+
|
|
177
|
+
Returns the count of records matching filter criteria.
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
async count(options?: ListOptionsType): Promise<number>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Uses the same `ListOptionsType` for filtering. Returns the count directly as a `number`.
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
const total = await product.count();
|
|
187
|
+
console.log(`Total products: ${total}`);
|
|
188
|
+
|
|
189
|
+
// With filter
|
|
190
|
+
const lowStock = await product.count({
|
|
191
|
+
Filter: {
|
|
192
|
+
Operator: "And",
|
|
193
|
+
Condition: [{
|
|
194
|
+
LHSField: product.Stock.id,
|
|
195
|
+
Operator: "LT",
|
|
196
|
+
RHSValue: 10,
|
|
197
|
+
RHSType: "Constant",
|
|
198
|
+
}],
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
### create
|
|
206
|
+
|
|
207
|
+
Creates a new record.
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
async create(data: Partial<TEditable>): Promise<ItemType<TEditable, TReadonly>>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Returns an [ItemType](#itemtype--runtime-accessor-pattern) with the new `_id` from the API response and the input data as field accessors.
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
const newItem = await product.create({
|
|
217
|
+
Title: "Wireless Headphones",
|
|
218
|
+
Price: 99.99,
|
|
219
|
+
Category: "Electronics",
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
console.log(newItem._id); // New record ID
|
|
223
|
+
console.log(newItem.Title.get()); // "Wireless Headphones"
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
### update
|
|
229
|
+
|
|
230
|
+
Updates an existing record.
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
async update(id: string, data: Partial<TEditable>): Promise<CreateUpdateResponseType>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Returns `{ _id: string }`.
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
const result = await product.update("prod_abc123", {
|
|
240
|
+
Price: 79.99,
|
|
241
|
+
Stock: 45,
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
console.log("Updated:", result._id);
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
### delete
|
|
250
|
+
|
|
251
|
+
Deletes a record by ID.
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
async delete(id: string): Promise<DeleteResponseType>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Returns `{ status: "success" }`.
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
const result = await product.delete("prod_abc123");
|
|
261
|
+
|
|
262
|
+
if (result.status === "success") {
|
|
263
|
+
console.log("Deleted successfully");
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
### draft
|
|
270
|
+
|
|
271
|
+
Previews computed field values for a new record without saving.
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
async draft(data: Partial<TEditable>): Promise<DraftResponseType>
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Returns computed field values as `{ [fieldName: string]: any }`.
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
const draftResult = await product.draft({
|
|
281
|
+
Price: 100,
|
|
282
|
+
DiscountPercent: 15,
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
console.log("Computed discount:", draftResult.DiscountAmount);
|
|
286
|
+
console.log("Computed final price:", draftResult.FinalPrice);
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
### draftPatch
|
|
292
|
+
|
|
293
|
+
Previews computed field values for an existing record being edited.
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
async draftPatch(id: string, data: Partial<TEditable>): Promise<DraftResponseType>
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
const draftResult = await product.draftPatch("prod_abc123", {
|
|
301
|
+
Price: 120,
|
|
302
|
+
DiscountPercent: 20,
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
console.log("Updated discount:", draftResult.DiscountAmount);
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
### draftInteraction
|
|
311
|
+
|
|
312
|
+
Creates/updates a draft without requiring an instance ID. Returns computed fields along with a temporary `_id`.
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
async draftInteraction(data: Partial<TEditable>): Promise<DraftResponseType & { _id: string }>
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
const result = await product.draftInteraction({
|
|
320
|
+
Price: 100,
|
|
321
|
+
DiscountPercent: 10,
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
console.log(result._id); // Temporary draft ID
|
|
325
|
+
console.log(result.DiscountAmount); // Computed value
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
### createItem
|
|
331
|
+
|
|
332
|
+
Creates an `ItemType` wrapper synchronously (no API call). Useful for creating an empty item for form binding.
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
createItem(data?: Partial<TEditable>): ItemType<TEditable, TReadonly>
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
```typescript
|
|
339
|
+
const emptyItem = product.createItem();
|
|
340
|
+
emptyItem.Title.set("Draft Product");
|
|
341
|
+
emptyItem.Price.set(0);
|
|
342
|
+
|
|
343
|
+
const validation = emptyItem.validate();
|
|
344
|
+
console.log(validation.valid); // false (required fields missing)
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
### metric
|
|
350
|
+
|
|
351
|
+
Performs aggregation queries on records.
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
async metric(options: Omit<MetricOptionsType, "Type">): Promise<MetricResponseType>
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
The `Type` field is added internally. Pass only `GroupBy`, `Metric`, and optional `Filter`.
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
// Total count
|
|
361
|
+
const response = await product.metric({
|
|
362
|
+
GroupBy: [],
|
|
363
|
+
Metric: [{ Field: "_id", Type: "Count" }],
|
|
364
|
+
});
|
|
365
|
+
console.log("Total:", response.Data[0]["count__id"]);
|
|
366
|
+
|
|
367
|
+
// Group by category with multiple metrics
|
|
368
|
+
const byCategory = await product.metric({
|
|
369
|
+
GroupBy: ["Category"],
|
|
370
|
+
Metric: [
|
|
371
|
+
{ Field: "Stock", Type: "Sum" },
|
|
372
|
+
{ Field: "Price", Type: "Avg" },
|
|
373
|
+
],
|
|
374
|
+
});
|
|
375
|
+
byCategory.Data.forEach((row) => {
|
|
376
|
+
console.log(`${row.Category}: ${row["sum_Stock"]} stock, $${row["avg_Price"]} avg`);
|
|
377
|
+
});
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
### pivot
|
|
383
|
+
|
|
384
|
+
Creates pivot table aggregations with row and column dimensions.
|
|
385
|
+
|
|
386
|
+
```typescript
|
|
387
|
+
async pivot(options: Omit<PivotOptionsType, "Type">): Promise<PivotResponseType>
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
The `Type` field is added internally. Pass only `Row`, `Column`, `Metric`, and optional `Filter`.
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
const response = await product.pivot({
|
|
394
|
+
Row: ["Category"],
|
|
395
|
+
Column: ["Region"],
|
|
396
|
+
Metric: [{ Field: "Stock", Type: "Sum" }],
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
const { RowHeader, ColumnHeader, Value } = response.Data;
|
|
400
|
+
|
|
401
|
+
RowHeader.forEach((row, ri) => {
|
|
402
|
+
ColumnHeader.forEach((col, ci) => {
|
|
403
|
+
console.log(`${row.Key} - ${col.Key}: ${Value[ri][ci]}`);
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
## Field Classes
|
|
411
|
+
|
|
412
|
+
All field classes extend `BaseField<T>` and accept raw backend meta JSON as the constructor parameter.
|
|
413
|
+
|
|
414
|
+
| Class | Backend Type | Extra Getters |
|
|
415
|
+
|-------|-------------|---------------|
|
|
416
|
+
| `StringField` | `"String"` | `length` |
|
|
417
|
+
| `NumberField` | `"Number"` | `integerPart`, `fractionPart` |
|
|
418
|
+
| `BooleanField` | `"Boolean"` | — |
|
|
419
|
+
| `DateField` | `"Date"` | — |
|
|
420
|
+
| `DateTimeField` | `"DateTime"` | `precision` |
|
|
421
|
+
| `SelectField<T>` | `"String"` | `options`, `fetchOptions()` |
|
|
422
|
+
| `ReferenceField<T>` | `"Reference"` | `referenceBdo`, `referenceFields`, `searchFields`, `fetchOptions()` |
|
|
423
|
+
| `TextField` | `"Text"` | `format` |
|
|
424
|
+
| `UserField` | `"User"` | `businessEntity` |
|
|
425
|
+
| `FileField` | `"File"` | — |
|
|
426
|
+
| `ArrayField<T>` | `"Array"` | `elementType` |
|
|
427
|
+
| `ObjectField<T>` | `"Object"` | `properties` |
|
|
428
|
+
|
|
429
|
+
### SelectField
|
|
430
|
+
|
|
431
|
+
Options from `Constraint.Enum` are available synchronously via the `options` getter:
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
product.Status.options;
|
|
435
|
+
// [{ value: "active", label: "active" }, { value: "inactive", label: "inactive" }]
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
Dynamic options can be fetched from the backend via `fetchOptions()`:
|
|
439
|
+
|
|
440
|
+
```typescript
|
|
441
|
+
async fetchOptions(instanceId?: string): Promise<SelectOptionType<T>[]>
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
const statusOptions = await product.Status.fetchOptions();
|
|
446
|
+
// [{ value: "active", label: "Active" }, { value: "inactive", label: "Inactive" }]
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
### ReferenceField
|
|
450
|
+
|
|
451
|
+
Reference configuration is derived from `View.DataObject` in the raw meta:
|
|
452
|
+
|
|
453
|
+
```typescript
|
|
454
|
+
product.SupplierInfo.referenceBdo; // "BDO_Supplier"
|
|
455
|
+
product.SupplierInfo.referenceFields; // ["_id", "SupplierName", "Email"]
|
|
456
|
+
product.SupplierInfo.searchFields; // ["SupplierName"]
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
Referenced records can be fetched via `fetchOptions()`:
|
|
460
|
+
|
|
461
|
+
```typescript
|
|
462
|
+
async fetchOptions(instanceId?: string): Promise<TRef[]>
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
const suppliers = await product.SupplierInfo.fetchOptions();
|
|
467
|
+
// [{ _id: "sup_1", SupplierName: "Acme Corp", Email: "contact@acme.com" }, ...]
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
---
|
|
471
|
+
|
|
472
|
+
## ItemType — Runtime Accessor Pattern
|
|
473
|
+
|
|
474
|
+
`ItemType<TEditable, TReadonly>` is what `get()`, `list()`, `create()`, and `createItem()` return. It wraps API response data with a Proxy, providing field accessors for every field.
|
|
475
|
+
|
|
476
|
+
### Field Accessor Access
|
|
477
|
+
|
|
478
|
+
```typescript
|
|
479
|
+
const item = await product.get("prod_abc123");
|
|
480
|
+
|
|
481
|
+
// Get value (NOT direct access — always use .get())
|
|
482
|
+
item.Title.get(); // "Wireless Headphones"
|
|
483
|
+
|
|
484
|
+
// Field metadata
|
|
485
|
+
item.Title.label; // "Product Title"
|
|
486
|
+
item.Title.required; // true
|
|
487
|
+
item.Title.readOnly; // false
|
|
488
|
+
item.Title.defaultValue; // undefined
|
|
489
|
+
item.Title.meta; // full raw backend meta (BaseFieldMetaType)
|
|
490
|
+
|
|
491
|
+
// Set value (only on editable fields)
|
|
492
|
+
item.Title.set("New Title");
|
|
493
|
+
|
|
494
|
+
// Validate (type + expression rules)
|
|
495
|
+
const result = item.Title.validate();
|
|
496
|
+
// { valid: true, errors: [] }
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### Direct `_id` Access
|
|
500
|
+
|
|
501
|
+
`_id` is the only field accessed directly (not as an accessor):
|
|
502
|
+
|
|
503
|
+
```typescript
|
|
504
|
+
item._id; // "prod_abc123"
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### Editable vs Readonly Accessors
|
|
508
|
+
|
|
509
|
+
Fields in `TEditable` get a `set()` method. Fields in `TReadonly` do not.
|
|
510
|
+
|
|
511
|
+
**Editable field accessor:**
|
|
512
|
+
|
|
513
|
+
```typescript
|
|
514
|
+
{
|
|
515
|
+
label: string,
|
|
516
|
+
required: boolean,
|
|
517
|
+
readOnly: false, // always false for editable
|
|
518
|
+
defaultValue: unknown,
|
|
519
|
+
meta: BaseFieldMetaType,
|
|
520
|
+
get(): T | undefined,
|
|
521
|
+
set(value: T): void, // only on editable fields
|
|
522
|
+
validate(): ValidationResultType,
|
|
523
|
+
}
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
**Readonly field accessor:**
|
|
527
|
+
|
|
528
|
+
```typescript
|
|
529
|
+
{
|
|
530
|
+
label: string,
|
|
531
|
+
required: boolean,
|
|
532
|
+
readOnly: true, // always true for readonly
|
|
533
|
+
defaultValue: unknown,
|
|
534
|
+
meta: BaseFieldMetaType,
|
|
535
|
+
get(): T | undefined,
|
|
536
|
+
validate(): ValidationResultType,
|
|
537
|
+
// no set()
|
|
538
|
+
}
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
### Item Methods
|
|
542
|
+
|
|
543
|
+
```typescript
|
|
544
|
+
// Validate all non-readonly fields
|
|
545
|
+
item.validate();
|
|
546
|
+
// { valid: boolean, errors: string[] }
|
|
547
|
+
|
|
548
|
+
// Convert to plain object
|
|
549
|
+
item.toJSON();
|
|
550
|
+
// Partial<T> — raw data without accessors
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
---
|
|
554
|
+
|
|
555
|
+
## Type Definitions
|
|
556
|
+
|
|
557
|
+
### BdoMetaType
|
|
558
|
+
|
|
559
|
+
```typescript
|
|
560
|
+
interface BdoMetaType {
|
|
561
|
+
readonly _id: string; // Business object ID (e.g., "BDO_Product")
|
|
562
|
+
readonly name: string; // Display name (e.g., "Product")
|
|
563
|
+
}
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
### ValidationResultType
|
|
567
|
+
|
|
568
|
+
```typescript
|
|
569
|
+
interface ValidationResultType {
|
|
570
|
+
valid: boolean;
|
|
571
|
+
errors: string[];
|
|
572
|
+
}
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### SelectOptionType
|
|
576
|
+
|
|
577
|
+
```typescript
|
|
578
|
+
interface SelectOptionType<T = string> {
|
|
579
|
+
value: T;
|
|
580
|
+
label: string;
|
|
581
|
+
disabled?: boolean;
|
|
582
|
+
}
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
### SystemFieldsType
|
|
586
|
+
|
|
587
|
+
```typescript
|
|
588
|
+
type SystemFieldsType = {
|
|
589
|
+
_id: string;
|
|
590
|
+
_created_at: DateTimeFieldType;
|
|
591
|
+
_modified_at: DateTimeFieldType;
|
|
592
|
+
_created_by: UserFieldType; // { _id: string; _name: string }
|
|
593
|
+
_modified_by: UserFieldType;
|
|
594
|
+
_version: string;
|
|
595
|
+
_m_version: string;
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
// Union of system field names (for Omit<> operations)
|
|
599
|
+
type SystemFields = keyof SystemFieldsType;
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
### BaseFieldMetaType
|
|
603
|
+
|
|
604
|
+
The raw backend meta shape stored by every field:
|
|
605
|
+
|
|
606
|
+
```typescript
|
|
607
|
+
interface BaseFieldMetaType {
|
|
608
|
+
_id: string; // Field identifier
|
|
609
|
+
Name: string; // Display name
|
|
610
|
+
Type: string; // Field type ("String", "Number", "Reference", etc.)
|
|
611
|
+
ReadOnly?: boolean;
|
|
612
|
+
Required?: boolean;
|
|
613
|
+
Constraint?: BaseConstraintType;
|
|
614
|
+
DefaultValue?: unknown;
|
|
615
|
+
}
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
### BaseConstraintType
|
|
619
|
+
|
|
620
|
+
```typescript
|
|
621
|
+
interface BaseConstraintType {
|
|
622
|
+
Required?: boolean;
|
|
623
|
+
PrimaryKey?: boolean;
|
|
624
|
+
DefaultValue?: unknown;
|
|
625
|
+
}
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### EditableFieldAccessorType
|
|
629
|
+
|
|
630
|
+
```typescript
|
|
631
|
+
interface EditableFieldAccessorType<T> {
|
|
632
|
+
readonly label: string;
|
|
633
|
+
readonly required: boolean;
|
|
634
|
+
readonly readOnly: boolean;
|
|
635
|
+
readonly defaultValue: unknown;
|
|
636
|
+
readonly meta: BaseFieldMetaType;
|
|
637
|
+
get(): T | undefined;
|
|
638
|
+
set(value: T): void;
|
|
639
|
+
validate(): ValidationResultType;
|
|
640
|
+
}
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### ReadonlyFieldAccessorType
|
|
644
|
+
|
|
645
|
+
```typescript
|
|
646
|
+
type ReadonlyFieldAccessorType<T> = {
|
|
647
|
+
readonly label: string;
|
|
648
|
+
readonly required: boolean;
|
|
649
|
+
readonly readOnly: boolean;
|
|
650
|
+
readonly defaultValue: unknown;
|
|
651
|
+
readonly meta: BaseFieldMetaType;
|
|
652
|
+
get(): T | undefined;
|
|
653
|
+
validate(): ValidationResultType;
|
|
654
|
+
};
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
---
|
|
658
|
+
|
|
659
|
+
## Complete Example
|
|
660
|
+
|
|
661
|
+
```typescript
|
|
662
|
+
import { AdminProduct } from "../bdo/admin/Product";
|
|
663
|
+
import type {
|
|
664
|
+
AdminProductEditableFieldType,
|
|
665
|
+
AdminProductFieldType,
|
|
666
|
+
} from "../bdo/admin/Product";
|
|
667
|
+
|
|
668
|
+
const product = new AdminProduct();
|
|
669
|
+
|
|
670
|
+
// ---- Field metadata ----
|
|
671
|
+
console.log(product.meta._id); // "BDO_Product"
|
|
672
|
+
console.log(product.Title.label); // "Product Title"
|
|
673
|
+
console.log(product.Title.required); // true
|
|
674
|
+
|
|
675
|
+
// ---- Get a single item ----
|
|
676
|
+
const item = await product.get("prod_abc123");
|
|
677
|
+
console.log(item._id); // "prod_abc123"
|
|
678
|
+
console.log(item.Title.get()); // "Wireless Headphones"
|
|
679
|
+
console.log(item.Price.get()); // 99.99
|
|
680
|
+
|
|
681
|
+
// ---- List items with filter ----
|
|
682
|
+
const items = await product.list({
|
|
683
|
+
Filter: {
|
|
684
|
+
Operator: "And",
|
|
685
|
+
Condition: [{
|
|
686
|
+
LHSField: product.Category.id,
|
|
687
|
+
Operator: "EQ",
|
|
688
|
+
RHSValue: "Electronics",
|
|
689
|
+
RHSType: "Constant",
|
|
690
|
+
}],
|
|
691
|
+
},
|
|
692
|
+
Sort: [{ [product.Price.id]: "ASC" }],
|
|
693
|
+
Page: 1,
|
|
694
|
+
PageSize: 20,
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
for (const item of items) {
|
|
698
|
+
console.log(item.Title.get(), item.Price.get());
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// ---- Count ----
|
|
702
|
+
const total = await product.count();
|
|
703
|
+
console.log(`Total products: ${total}`);
|
|
704
|
+
|
|
705
|
+
// ---- Create ----
|
|
706
|
+
const newItem = await product.create({
|
|
707
|
+
Title: "New Product",
|
|
708
|
+
Price: 49.99,
|
|
709
|
+
Category: "Books",
|
|
710
|
+
});
|
|
711
|
+
console.log(newItem._id); // New record ID
|
|
712
|
+
console.log(newItem.Title.get()); // "New Product"
|
|
713
|
+
|
|
714
|
+
// ---- Update ----
|
|
715
|
+
const updateResult = await product.update("prod_abc123", {
|
|
716
|
+
Price: 79.99,
|
|
717
|
+
});
|
|
718
|
+
console.log(updateResult._id); // "prod_abc123"
|
|
719
|
+
|
|
720
|
+
// ---- Delete ----
|
|
721
|
+
const deleteResult = await product.delete("prod_abc123");
|
|
722
|
+
console.log(deleteResult.status); // "success"
|
|
723
|
+
|
|
724
|
+
// ---- Validate ----
|
|
725
|
+
const emptyItem = product.createItem();
|
|
726
|
+
emptyItem.Title.set("");
|
|
727
|
+
const validation = emptyItem.validate();
|
|
728
|
+
console.log(validation.valid); // false
|
|
729
|
+
console.log(validation.errors); // ["Product Title is required"]
|
|
730
|
+
|
|
731
|
+
// ---- SelectField options ----
|
|
732
|
+
const statusOptions = await product.Status.fetchOptions();
|
|
733
|
+
statusOptions.forEach((opt) => {
|
|
734
|
+
console.log(`${opt.value}: ${opt.label}`);
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
// ---- ReferenceField options ----
|
|
738
|
+
const suppliers = await product.SupplierInfo.fetchOptions();
|
|
739
|
+
suppliers.forEach((sup) => {
|
|
740
|
+
console.log(`${sup._id}: ${sup.SupplierName}`);
|
|
741
|
+
});
|
|
742
|
+
```
|