@ram_28/kf-ai-sdk 2.0.19 → 2.0.20-beta.1

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 (93) hide show
  1. package/README.md +8 -16
  2. package/dist/api.cjs +1 -1
  3. package/dist/api.mjs +1 -1
  4. package/dist/auth/authConfig.d.ts +1 -1
  5. package/dist/auth/types.d.ts +1 -1
  6. package/dist/auth/types.d.ts.map +1 -1
  7. package/dist/auth.cjs +1 -1
  8. package/dist/auth.mjs +1 -1
  9. package/dist/bdo/core/Item.d.ts.map +1 -1
  10. package/dist/bdo.cjs +1 -1
  11. package/dist/bdo.mjs +32 -32
  12. package/dist/components/hooks/useActivityForm/types.d.ts +5 -4
  13. package/dist/components/hooks/useActivityForm/types.d.ts.map +1 -1
  14. package/dist/components/hooks/useActivityForm/useActivityForm.d.ts.map +1 -1
  15. package/dist/components/hooks/useActivityTable/types.d.ts +4 -5
  16. package/dist/components/hooks/useActivityTable/types.d.ts.map +1 -1
  17. package/dist/components/hooks/useActivityTable/useActivityTable.d.ts.map +1 -1
  18. package/dist/components/hooks/useBDOForm/createItemProxy.d.ts +2 -2
  19. package/dist/components/hooks/useBDOForm/createItemProxy.d.ts.map +1 -1
  20. package/dist/components/hooks/useBDOTable/types.d.ts +12 -20
  21. package/dist/components/hooks/useBDOTable/types.d.ts.map +1 -1
  22. package/dist/components/hooks/useBDOTable/useBDOTable.d.ts +2 -2
  23. package/dist/components/hooks/useBDOTable/useBDOTable.d.ts.map +1 -1
  24. package/dist/{constants-Cyi942Yr.js → constants-ConHc1oS.js} +5 -5
  25. package/dist/constants-QX2RX-wu.cjs +1 -0
  26. package/dist/filter.cjs +1 -1
  27. package/dist/filter.mjs +1 -1
  28. package/dist/form.cjs +1 -1
  29. package/dist/form.mjs +1 -1
  30. package/dist/table.cjs +1 -1
  31. package/dist/table.mjs +16 -15
  32. package/dist/table.types.d.ts +1 -1
  33. package/dist/table.types.d.ts.map +1 -1
  34. package/dist/types/constants.d.ts +1 -1
  35. package/dist/workflow/Activity.d.ts +5 -8
  36. package/dist/workflow/Activity.d.ts.map +1 -1
  37. package/dist/workflow.cjs +1 -1
  38. package/dist/workflow.mjs +476 -461
  39. package/docs/api.md +95 -0
  40. package/docs/bdo.md +224 -0
  41. package/docs/gaps.md +360 -0
  42. package/docs/useActivityForm.md +393 -0
  43. package/docs/useActivityTable.md +418 -0
  44. package/docs/useBDOForm.md +498 -0
  45. package/docs/useBDOTable.md +284 -0
  46. package/docs/useFilter.md +188 -0
  47. package/docs/workflow.md +560 -0
  48. package/package.json +14 -15
  49. package/sdk/auth/authConfig.ts +1 -1
  50. package/sdk/auth/types.ts +1 -1
  51. package/sdk/bdo/core/Item.ts +1 -2
  52. package/sdk/components/hooks/useActivityForm/types.ts +6 -4
  53. package/sdk/components/hooks/useActivityForm/useActivityForm.ts +73 -10
  54. package/sdk/components/hooks/useActivityTable/types.ts +5 -4
  55. package/sdk/components/hooks/useActivityTable/useActivityTable.ts +8 -10
  56. package/sdk/components/hooks/useBDOForm/createItemProxy.ts +5 -9
  57. package/sdk/components/hooks/useBDOTable/types.ts +10 -20
  58. package/sdk/components/hooks/useBDOTable/useBDOTable.ts +8 -12
  59. package/sdk/table.types.ts +0 -2
  60. package/sdk/types/constants.ts +1 -1
  61. package/sdk/workflow/Activity.ts +7 -39
  62. package/dist/constants-DEmYwKfC.cjs +0 -1
  63. package/docs/README.md +0 -57
  64. package/docs/bdo/README.md +0 -161
  65. package/docs/bdo/api_reference.md +0 -281
  66. package/docs/examples/bdo/create-product.md +0 -69
  67. package/docs/examples/bdo/edit-product-dialog.md +0 -95
  68. package/docs/examples/bdo/filtered-product-table.md +0 -100
  69. package/docs/examples/bdo/product-listing.md +0 -73
  70. package/docs/examples/bdo/supplier-dropdown.md +0 -60
  71. package/docs/examples/fields/complex-fields.md +0 -248
  72. package/docs/examples/fields/primitive-fields.md +0 -217
  73. package/docs/examples/workflow/approve-leave-request.md +0 -76
  74. package/docs/examples/workflow/filtered-activity-table.md +0 -101
  75. package/docs/examples/workflow/my-pending-requests.md +0 -90
  76. package/docs/examples/workflow/start-new-workflow.md +0 -47
  77. package/docs/examples/workflow/submit-leave-request.md +0 -72
  78. package/docs/examples/workflow/workflow-progress.md +0 -49
  79. package/docs/fields/README.md +0 -141
  80. package/docs/fields/api_reference.md +0 -134
  81. package/docs/useActivityForm/README.md +0 -244
  82. package/docs/useActivityForm/api_reference.md +0 -279
  83. package/docs/useActivityTable/README.md +0 -263
  84. package/docs/useActivityTable/api_reference.md +0 -294
  85. package/docs/useBDOForm/README.md +0 -175
  86. package/docs/useBDOForm/api_reference.md +0 -244
  87. package/docs/useBDOTable/README.md +0 -242
  88. package/docs/useBDOTable/api_reference.md +0 -253
  89. package/docs/useFilter/README.md +0 -323
  90. package/docs/useFilter/api_reference.md +0 -228
  91. package/docs/workflow/README.md +0 -158
  92. package/docs/workflow/api_reference.md +0 -161
  93. /package/docs/{useAuth/README.md → useAuth.md} +0 -0
@@ -1,90 +0,0 @@
1
- # My Pending Requests
2
-
3
- > Employee views leave requests in In Progress / Completed tabs using `useActivityTable`.
4
-
5
- ```tsx
6
- import { useState, useMemo } from "react";
7
- import { useActivityTable, ActivityTableStatus } from "@ram_28/kf-ai-sdk/workflow";
8
- import type { UseActivityTableReturnType } from "@ram_28/kf-ai-sdk/workflow";
9
- import { EmployeeInputActivity } from "@/workflow/leave";
10
-
11
- export default function MyPendingRequests({ onOpenForm }: { onOpenForm: (instanceId: string, bpInstanceId: string) => void }) {
12
- const [status, setStatus] = useState(ActivityTableStatus.InProgress);
13
- const activity = useMemo(() => new EmployeeInputActivity(), []);
14
-
15
- const table: UseActivityTableReturnType<EmployeeInputActivity> = useActivityTable({
16
- activity,
17
- status,
18
- initialState: { sort: [{ StartDate: "DESC" }], pagination: { pageNo: 1, pageSize: 10 } },
19
- });
20
-
21
- if (table.isLoading) return <p>Loading...</p>;
22
- if (table.error) return <p>Error: {table.error.message}</p>;
23
-
24
- return (
25
- <div>
26
- {/* Tab switcher */}
27
- <div>
28
- <button onClick={() => setStatus(ActivityTableStatus.InProgress)}
29
- style={{ fontWeight: status === ActivityTableStatus.InProgress ? "bold" : "normal" }}>
30
- My Requests
31
- </button>
32
- <button onClick={() => setStatus(ActivityTableStatus.Completed)}
33
- style={{ fontWeight: status === ActivityTableStatus.Completed ? "bold" : "normal" }}>
34
- Completed
35
- </button>
36
- </div>
37
-
38
- <table>
39
- <thead>
40
- <tr>
41
- <th onClick={() => table.sort.toggle(activity.StartDate.id)} style={{ cursor: "pointer" }}>
42
- {activity.StartDate.label}
43
- </th>
44
- <th>{activity.EndDate.label}</th>
45
- <th>{activity.LeaveType.label}</th>
46
- <th>{activity.LeaveDays.label}</th>
47
- <th>Status</th>
48
- {status === ActivityTableStatus.Completed && <th>Completed At</th>}
49
- </tr>
50
- </thead>
51
- <tbody>
52
- {table.rows.map((row) => (
53
- <tr
54
- key={row._id}
55
- style={{ cursor: status === ActivityTableStatus.InProgress ? "pointer" : "default" }}
56
- onClick={() => {
57
- if (status === ActivityTableStatus.InProgress) {
58
- onOpenForm(row._id, row.BPInstanceId.get());
59
- }
60
- }}
61
- >
62
- <td>{row.StartDate.get()}</td>
63
- <td>{row.EndDate.get()}</td>
64
- <td>{row.LeaveType.get()}</td>
65
- <td>{row.LeaveDays.get()}</td>
66
- <td>{row.Status.get()}</td>
67
- {status === ActivityTableStatus.Completed && <td>{row.CompletedAt.get()}</td>}
68
- </tr>
69
- ))}
70
- </tbody>
71
- </table>
72
-
73
- {/* Pagination */}
74
- <div>
75
- <button onClick={table.pagination.goToPrevious} disabled={!table.pagination.canGoPrevious}>Previous</button>
76
- <span>Page {table.pagination.pageNo} of {table.pagination.totalPages}</span>
77
- <button onClick={table.pagination.goToNext} disabled={!table.pagination.canGoNext}>Next</button>
78
- </div>
79
- </div>
80
- );
81
- }
82
- ```
83
-
84
- ## Key Patterns
85
-
86
- - **`ActivityTableStatus.InProgress` / `Completed`** -- changing `status` state triggers an automatic refetch
87
- - **Activity system fields** -- `row.Status.get()`, `row.CompletedAt.get()`, `row.BPInstanceId.get()` are available on every row
88
- - **Conditional `CompletedAt` column** -- only rendered in the Completed tab
89
- - **Clickable rows only in InProgress** -- completed rows are read-only and don't open a form dialog
90
- - **`row.BPInstanceId.get()`** -- passed along when opening a form, needed for workflow progress tracking
@@ -1,47 +0,0 @@
1
- # Start New Workflow
2
-
3
- > "New Request" button calls `workflow.start()` and opens the form with the returned instance ID.
4
-
5
- ```tsx
6
- import { useState, useMemo, useCallback } from "react";
7
- import { Workflow } from "@ram_28/kf-ai-sdk/workflow";
8
- import type { WorkflowStartResponseType } from "@ram_28/kf-ai-sdk/workflow";
9
- import type { EmployeeInputEntityType } from "@/workflow/leave";
10
-
11
- export default function StartNewWorkflow({ onOpenForm }: { onOpenForm: (instanceId: string, bpInstanceId: string) => void }) {
12
- const [isStarting, setIsStarting] = useState(false);
13
- const [error, setError] = useState<string | null>(null);
14
-
15
- const workflow = useMemo(() => new Workflow<EmployeeInputEntityType>("SimpleLeaveProcess"), []);
16
-
17
- const handleNewRequest = useCallback(async () => {
18
- try {
19
- setIsStarting(true);
20
- setError(null);
21
- const result: WorkflowStartResponseType = await workflow.start();
22
- // result: { BPInstanceId, ActivityId, _id }
23
- onOpenForm(result._id, result.BPInstanceId);
24
- } catch (err) {
25
- setError(err instanceof Error ? err.message : "Failed to start workflow");
26
- } finally {
27
- setIsStarting(false);
28
- }
29
- }, [workflow, onOpenForm]);
30
-
31
- return (
32
- <div>
33
- <button onClick={handleNewRequest} disabled={isStarting}>
34
- {isStarting ? "Starting..." : "New Request"}
35
- </button>
36
- {error && <p>{error}</p>}
37
- </div>
38
- );
39
- }
40
- ```
41
-
42
- ## Key Patterns
43
-
44
- - **`workflow.start()`** -- creates a new process instance and returns `{ BPInstanceId, ActivityId, _id }`
45
- - **`BPInstanceId`** -- identifies the workflow instance; used for `workflow.progress()`
46
- - **`_id`** -- the first activity instance ID; passed to `useActivityForm` as `activity_instance_id`
47
- - **Workflow constructor** -- `new Workflow<TEntity>("BusinessProcessId")` takes the process ID string
@@ -1,72 +0,0 @@
1
- # Submit Leave Request
2
-
3
- > Employee fills in dates, leave type, and reason, then submits using `useActivityForm`.
4
-
5
- ```tsx
6
- import { useMemo } from "react";
7
- import { useActivityForm } from "@ram_28/kf-ai-sdk/workflow";
8
- import type { UseActivityFormReturn } from "@ram_28/kf-ai-sdk/workflow";
9
- import { EmployeeInputActivity } from "@/workflow/leave";
10
-
11
- export default function LeaveRequestForm({ instanceId, onClose }: { instanceId: string; onClose: () => void }) {
12
- const activity = useMemo(() => new EmployeeInputActivity(), []);
13
-
14
- const { register, handleSubmit, errors, isLoading, isSubmitting, watch, setValue }: UseActivityFormReturn<EmployeeInputActivity> =
15
- useActivityForm(activity, { activity_instance_id: instanceId, mode: "onBlur" });
16
-
17
- if (isLoading) return <p>Loading...</p>;
18
-
19
- return (
20
- <form>
21
- <div>
22
- <label>{activity.StartDate.label} {activity.StartDate.required && <span>*</span>}</label>
23
- <input type="date" {...register(activity.StartDate.id)} />
24
- {errors.StartDate && <p>{errors.StartDate.message}</p>}
25
- </div>
26
-
27
- <div>
28
- <label>{activity.EndDate.label} {activity.EndDate.required && <span>*</span>}</label>
29
- <input type="date" {...register(activity.EndDate.id)} />
30
- {errors.EndDate && <p>{errors.EndDate.message}</p>}
31
- </div>
32
-
33
- {/* Select field — watch/setValue, not register */}
34
- <div>
35
- <label>{activity.LeaveType.label} {activity.LeaveType.required && <span>*</span>}</label>
36
- <select value={watch(activity.LeaveType.id) ?? ""} onChange={(e) => setValue(activity.LeaveType.id, e.target.value)}>
37
- <option value="">Select leave type</option>
38
- {activity.LeaveType.options.map((opt) => (
39
- <option key={opt.value} value={opt.value}>{opt.label}</option>
40
- ))}
41
- </select>
42
- {errors.LeaveType && <p>{errors.LeaveType.message}</p>}
43
- </div>
44
-
45
- <div>
46
- <label>{activity.Reason.label}</label>
47
- <textarea {...register(activity.Reason.id)} rows={3} placeholder="Reason for leave..." />
48
- {errors.Reason && <p>{errors.Reason.message}</p>}
49
- </div>
50
-
51
- {/* Readonly computed field — auto-disabled by register() */}
52
- <div>
53
- <label>{activity.LeaveDays.label} (computed)</label>
54
- <input type="number" {...register(activity.LeaveDays.id)} />
55
- </div>
56
-
57
- <button type="button" onClick={onClose}>Cancel</button>
58
- <button type="button" disabled={isSubmitting} onClick={handleSubmit(() => onClose(), console.error)}>
59
- Submit Request
60
- </button>
61
- </form>
62
- );
63
- }
64
- ```
65
-
66
- ## Key Patterns
67
-
68
- - **`useActivityForm(activity, { activity_instance_id })`** -- the instance ID comes from `workflow.start()` or a table row
69
- - **`handleSubmit` completes the activity** -- validates, sends dirty fields, then completes to advance the workflow
70
- - **Readonly fields auto-disabled** -- `LeaveDays` has `ReadOnly: true`, so `register()` returns `{ disabled: true }`
71
- - **`watch()` + `setValue()` for selects** -- custom components that don't fire native change events
72
- - **Per-field sync** -- changes are auto-saved on blur/change; no manual save button needed
@@ -1,49 +0,0 @@
1
- # Workflow Progress
2
-
3
- > Display progress badges for each activity in a workflow instance using `workflow.progress()`.
4
-
5
- ```tsx
6
- import { useMemo } from "react";
7
- import { useQuery } from "@tanstack/react-query";
8
- import { Workflow } from "@ram_28/kf-ai-sdk/workflow";
9
- import type { ActivityProgressType } from "@ram_28/kf-ai-sdk/workflow";
10
- import type { EmployeeInputEntityType } from "@/workflow/leave";
11
-
12
- export default function WorkflowProgressBadges({ bpInstanceId }: { bpInstanceId: string }) {
13
- const workflow = useMemo(() => new Workflow<EmployeeInputEntityType>("SimpleLeaveProcess"), []);
14
-
15
- const { data: progress } = useQuery<ActivityProgressType[]>({
16
- queryKey: ["workflow-progress", bpInstanceId],
17
- queryFn: () => workflow.progress(bpInstanceId),
18
- staleTime: 0,
19
- });
20
-
21
- if (!progress) return null;
22
-
23
- return (
24
- <div style={{ display: "flex", gap: "8px" }}>
25
- {progress.map((entry: ActivityProgressType) => (
26
- <span
27
- key={entry.ActivityId}
28
- style={{
29
- padding: "4px 12px",
30
- borderRadius: "12px",
31
- fontSize: "12px",
32
- backgroundColor: entry.Status === "COMPLETED" ? "#dcfce7" : "#fef9c3",
33
- color: entry.Status === "COMPLETED" ? "#166534" : "#854d0e",
34
- }}
35
- >
36
- {entry._name} — {entry.Status === "COMPLETED" ? "Done" : "In Progress"}
37
- </span>
38
- ))}
39
- </div>
40
- );
41
- }
42
- ```
43
-
44
- ## Key Patterns
45
-
46
- - **`workflow.progress(bpInstanceId)`** -- returns `ActivityProgressType[]`, one entry per activity in the process
47
- - **`ActivityProgressType`** -- each entry has `ActivityId`, `_name`, `Status` (`"COMPLETED"` or `"IN_PROGRESS"`), `CompletedAt`, `CompletedBy`
48
- - **`BPInstanceId`** -- comes from `workflow.start()` (new requests) or `row.BPInstanceId.get()` (existing table rows)
49
- - **`staleTime: 0`** -- always refetch progress when the component mounts (progress changes as activities complete)
@@ -1,141 +0,0 @@
1
- # Fields
2
-
3
- Field classes are the typed metadata layer for BDO properties. 13 classes extend `BaseField<T>`, each storing raw backend meta and exposing getters + `validate()`.
4
-
5
- ## Imports
6
-
7
- ```typescript
8
- import {
9
- StringField,
10
- NumberField,
11
- BooleanField,
12
- DateField,
13
- DateTimeField,
14
- TextField,
15
- SelectField,
16
- ReferenceField,
17
- UserField,
18
- FileField,
19
- ImageField,
20
- ArrayField,
21
- ObjectField,
22
- } from "@ram_28/kf-ai-sdk/bdo";
23
- import type {
24
- StringFieldType,
25
- NumberFieldType,
26
- BooleanFieldType,
27
- DateFieldType,
28
- DateTimeFieldType,
29
- TextFieldType,
30
- SelectFieldType,
31
- ReferenceFieldType,
32
- UserFieldType,
33
- FileFieldType,
34
- ImageFieldType,
35
- FileType,
36
- ArrayFieldType,
37
- ObjectFieldType,
38
- } from "@ram_28/kf-ai-sdk/types";
39
- ```
40
-
41
- ## Common Mistakes (READ FIRST)
42
-
43
- 1. **`item.Title` is not the value** — Use `item.Title.get()` to read, `.set()` to write.
44
- 2. **Don't confuse `StringField` (class) with `StringFieldType` (type alias)** — Different modules.
45
- 3. **`fetchOptions()` requires a parent BDO** — Standalone fields will throw.
46
- 4. **SelectField meta `Type` is `"String"`** — `Constraint.Enum` differentiates it.
47
- 5. **Always use pre-built components for File/Image** — `<FileUpload>`, `<ImageUpload>`, `<FilePreview>`, `<ImageThumbnail>`.
48
-
49
- ## Quick Start
50
-
51
- ```typescript
52
- // Declare on a BDO class
53
- readonly Title = new StringField({
54
- _id: "Title", Name: "Title", Type: "String",
55
- Constraint: { Required: true, Length: 255 },
56
- });
57
-
58
- // Access metadata
59
- bdo.Title.id; // "Title"
60
- bdo.Title.label; // "Title"
61
- bdo.Title.required; // true
62
- bdo.Title.length; // 255
63
-
64
- // Read/write via Item proxy
65
- const item = await bdo.get("abc123");
66
- item.Title.get(); // "My Product"
67
- item.Title.set("New"); // update
68
-
69
- // Form binding
70
- <input {...register(bdo.Title.id)} />
71
- ```
72
-
73
- ## BaseField Contract
74
-
75
- All fields share these getters: `id`, `label`, `readOnly`, `required`, `defaultValue`, `primaryKey`, `meta`.
76
-
77
- Abstract method: `validate(value: T | undefined): ValidationResultType` → `{ valid, errors }`.
78
-
79
- ## Quick Reference
80
-
81
- | Class | Value Type | Extra Getters | Async |
82
- | ---------------------- | ------------------ | ------------------------------------------------- | ---------------- |
83
- | `StringField` | `string` | `length` | — |
84
- | `NumberField` | `number` | `integerPart`, `fractionPart` | — |
85
- | `BooleanField` | `boolean` | — | — |
86
- | `DateField` | `YYYY-MM-DD` | — | — |
87
- | `DateTimeField` | ISO string | `precision` | — |
88
- | `TextField` | `string` | `format` | — |
89
- | `SelectField<T>` | `T` | `options` | `fetchOptions()` |
90
- | `ReferenceField<TRef>` | `TRef` | `referenceBdo`, `referenceFields`, `searchFields` | `fetchOptions()` |
91
- | `UserField` | `{ _id, _name }` | `businessEntity` | `fetchOptions()` |
92
- | `FileField` | `FileType[]` | — | — |
93
- | `ImageField` | `FileType \| null` | — | — |
94
- | `ArrayField<T>` | `T[]` | `elementType` | — |
95
- | `ObjectField<T>` | `T` | `properties` | — |
96
-
97
- ## Form Binding Patterns
98
-
99
- | Field Type | Pattern | Key Detail |
100
- | ---------- | ----------------------------------------- | ------------------------------------------------------------------------------ |
101
- | String | `register()` | `maxLength={field.length}` |
102
- | Number | `register()` with `type="number"` | `step` from `fractionPart` (e.g. `2` → `"0.01"`, none → `"1"`) |
103
- | Boolean | `watch()` + `setValue()` | Checkboxes don't fire native change — never use `register()` |
104
- | Date | `register()` with `type="date"` | Strict `YYYY-MM-DD` — never default to `""` |
105
- | DateTime | `register()` with `type="datetime-local"` | `step="0.001"` for `"Millisecond"` precision — never default to `""` |
106
- | Text | `register()` with `<textarea>` | Check `field.format` (`"Plain"` \| `"Markdown"`) for conditional rendering |
107
- | Select | `watch()` + `setValue()` | Static `field.options` from `Constraint.Enum`, or dynamic via `fetchOptions()` |
108
- | Reference | `watch()` + `setValue()` | Stores **full object**, not just ID — use `<ReferenceSelect>` component |
109
- | User | `watch()` + `setValue()` | `{ _id, _name }` shape — use `fetchOptions()` + dropdown |
110
- | File | Component only | `<FileUpload>` (edit) / `<FilePreview>` (read-only) |
111
- | Image | Component only | `<ImageUpload>` (edit) / `<ImageThumbnail>` (read-only) |
112
-
113
- ## fetchOptions() Pattern
114
-
115
- SelectField, ReferenceField, and UserField share this pattern:
116
-
117
- ```tsx
118
- const [dropdownOpen, setDropdownOpen] = useState(false);
119
- const { data: options = [] } = useQuery({
120
- queryKey: ["options", bdo.meta._id, field.id, item._id],
121
- queryFn: () => field.fetchOptions(item._id!),
122
- enabled: dropdownOpen && !!item._id,
123
- staleTime: Infinity,
124
- });
125
- ```
126
-
127
- ## UI Components
128
-
129
- | Component | Field | Mode | Key Props |
130
- | ------------------- | --------- | --------- | ------------------------------------------------- |
131
- | `<ReferenceSelect>` | Reference | Edit | `bdoField`, `instanceId`, `value`, `onChange` |
132
- | `<FileUpload>` | File | Edit | `field`, `value`, `boId`, `instanceId`, `fieldId` |
133
- | `<ImageUpload>` | Image | Edit | `field`, `value`, `boId`, `instanceId`, `fieldId` |
134
- | `<FilePreview>` | File | Read-only | `boId`, `instanceId`, `fieldId`, `value` |
135
- | `<ImageThumbnail>` | Image | Read-only | `boId`, `instanceId`, `fieldId`, `value` |
136
-
137
- ## Further Reading
138
-
139
- - [API Reference](./api_reference.md) — Type signatures for BaseField and all 13 classes
140
- - [Primitive Fields](../examples/fields/primitive-fields.md) · [Complex Fields](../examples/fields/complex-fields.md)
141
- - [BDO](../bdo/README.md) · [useBDOForm](../useBDOForm/README.md)
@@ -1,134 +0,0 @@
1
- # Fields API Reference
2
-
3
- ```typescript
4
- import { StringField, NumberField, BooleanField, DateField, DateTimeField,
5
- TextField, SelectField, ReferenceField, UserField,
6
- FileField, ImageField, ArrayField, ObjectField } from "@ram_28/kf-ai-sdk/bdo";
7
- import type { BaseFieldMetaType, ValidationResultType, SelectOptionType,
8
- EditableFieldAccessorType, ReadonlyFieldAccessorType } from "@ram_28/kf-ai-sdk/bdo/types";
9
- import type { StringFieldType, NumberFieldType, BooleanFieldType,
10
- DateFieldType, DateTimeFieldType, TextFieldType, SelectFieldType,
11
- ReferenceFieldType, UserFieldType, FileFieldType, ImageFieldType, FileType,
12
- ArrayFieldType, ObjectFieldType } from "@ram_28/kf-ai-sdk/types";
13
- ```
14
-
15
- ## BaseField\<T\>
16
-
17
- Abstract base class for all field definitions. Constructor: `new(meta: BaseFieldMetaType)`.
18
-
19
- | Property | Type | Description |
20
- |----------|------|-------------|
21
- | `id` | `string` | `meta._id` |
22
- | `label` | `string` | `meta.Name` (falls back to `id`) |
23
- | `readOnly` | `boolean` | `meta.ReadOnly ?? false` |
24
- | `required` | `boolean` | `meta.Constraint?.Required ?? meta.Required ?? false` |
25
- | `defaultValue` | `unknown` | `meta.DefaultValue ?? meta.Constraint?.DefaultValue` |
26
- | `primaryKey` | `boolean` | `meta.Constraint?.PrimaryKey ?? false` |
27
- | `meta` | `BaseFieldMetaType` | Full raw backend meta |
28
- | `validate()` | `(value: T \| undefined) => ValidationResultType` | Abstract — overridden per subclass |
29
-
30
- ## All Fields
31
-
32
- | Class | Meta Type | Extra Properties | validate() |
33
- |-------|-----------|-----------------|------------|
34
- | `StringField` | `StringFieldMetaType` | `length: number \| undefined` | Rejects non-string |
35
- | `NumberField` | `NumberFieldMetaType` | `integerPart: number` (default 9), `fractionPart: number \| undefined` | Rejects NaN, non-number |
36
- | `BooleanField` | `BooleanFieldMetaType` | — | Rejects non-boolean |
37
- | `DateField` | `DateFieldMetaType` | — | Rejects non-`YYYY-MM-DD`, invalid dates |
38
- | `DateTimeField` | `DateTimeFieldMetaType` | `precision: "Second" \| "Millisecond"` | Rejects unparseable date strings |
39
- | `TextField` | `TextFieldMetaType` | `format: "Plain" \| "Markdown"` | Rejects non-string |
40
- | `SelectField<T>` | `SelectFieldMetaType` | `options: readonly SelectOptionType<T>[]` | Rejects values not in options (skipped if empty) |
41
- | `ReferenceField<TRef>` | `ReferenceFieldMetaType` | `referenceBdo: string`, `referenceFields: readonly string[]`, `searchFields: readonly string[]` | Rejects non-object, missing `_id` |
42
- | `UserField` | `UserFieldMetaType` | `businessEntity: string \| undefined` | Rejects non-object, missing `_id` |
43
- | `FileField` | `FileFieldMetaType` | — | Rejects non-array, items without `_id` |
44
- | `ImageField` | `ImageFieldMetaType` | — | Rejects non-object, missing `_id`/`FileName` |
45
- | `ArrayField<T>` | `ArrayFieldMetaType` | `elementType: BaseFieldMetaType \| undefined` | Rejects non-array |
46
- | `ObjectField<T>` | `ObjectFieldMetaType` | `properties: Record<string, unknown> \| undefined` | Rejects non-object, arrays |
47
-
48
- All validate() methods accept `undefined` and `null`.
49
-
50
- ## Async Methods
51
-
52
- | Class | Method | Signature |
53
- |-------|--------|-----------|
54
- | `SelectField<T>` | `fetchOptions` | `(instanceId?: string) => Promise<SelectOptionType<T>[]>` |
55
- | `ReferenceField<TRef>` | `fetchOptions` | `(instanceId?: string) => Promise<TRef[]>` |
56
- | `UserField` | `fetchOptions` | `(instanceId?: string) => Promise<UserFieldType[]>` |
57
-
58
- `instanceId` defaults to `"draft"`. Requires field to be bound to a parent BDO.
59
-
60
- ## Types
61
-
62
- ### SelectOptionType\<T\>
63
-
64
- ```typescript
65
- interface SelectOptionType<T = string> {
66
- value: T;
67
- label: string;
68
- disabled?: boolean;
69
- }
70
- ```
71
-
72
- ### FileType
73
-
74
- ```typescript
75
- interface FileType {
76
- _id: string;
77
- _name: string;
78
- FileName: string;
79
- FileExtension: string;
80
- Size: number;
81
- ContentType: string;
82
- }
83
- ```
84
-
85
- ### ValidationResultType
86
-
87
- ```typescript
88
- interface ValidationResultType {
89
- valid: boolean;
90
- errors: string[];
91
- }
92
- ```
93
-
94
- ### Runtime Accessor Types
95
-
96
- ```typescript
97
- interface EditableFieldAccessorType<T> {
98
- get(): T | undefined;
99
- getOrDefault(fallback: T): T;
100
- set(value: T): void;
101
- validate(): ValidationResultType;
102
- readonly label: string;
103
- readonly required: boolean;
104
- readonly readOnly: boolean;
105
- readonly defaultValue: unknown;
106
- readonly meta: BaseFieldMetaType;
107
- }
108
-
109
- // ReadonlyFieldAccessorType<T> — same but no set()
110
- ```
111
-
112
- ### Value Type Aliases
113
-
114
- | Type | Resolves To |
115
- |------|-------------|
116
- | `StringFieldType` | `string` |
117
- | `TextFieldType` | `string` |
118
- | `NumberFieldType` | `number` |
119
- | `BooleanFieldType` | `boolean` |
120
- | `DateFieldType` | `YYYY-MM-DD` (template literal) |
121
- | `DateTimeFieldType` | `YYYY-MM-DDThh:mm:ssZ` (template literal) |
122
- | `SelectFieldType<T>` | `T` |
123
- | `ReferenceFieldType<TRef>` | `TRef` |
124
- | `UserFieldType` | `{ _id: string; _name: string }` |
125
- | `ImageFieldType` | `FileType \| null` |
126
- | `FileFieldType` | `FileType[]` |
127
- | `ArrayFieldType<T>` | `T[]` |
128
- | `ObjectFieldType<T>` | `T` |
129
-
130
- ### Supported File Extensions
131
-
132
- **Image fields** — jpg, jpeg, png, gif, webp, bmp, tiff, tif, heic, heif
133
-
134
- **File fields** — all image extensions plus: mp4, mov, avi, webm, mkv, m4v, wmv, flv, pdf, doc, docx, xls, xlsx, ppt, pptx, txt, csv, zip