@ram_28/kf-ai-sdk 1.0.19 → 1.0.21
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 +45 -12
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/datetime.d.ts +59 -10
- package/dist/api/datetime.d.ts.map +1 -1
- package/dist/api/index.d.ts +3 -2
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api.cjs +1 -1
- package/dist/api.d.ts +1 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.mjs +43 -21
- package/dist/api.types.d.ts +2 -1
- package/dist/api.types.d.ts.map +1 -1
- package/dist/auth/AuthProvider.d.ts.map +1 -1
- package/dist/auth.cjs +1 -1
- package/dist/auth.mjs +34 -34
- package/dist/base-types.d.ts +1 -1
- package/dist/base-types.d.ts.map +1 -1
- package/dist/client-BIkaIr2y.js +217 -0
- package/dist/client-DxjRcEtN.cjs +1 -0
- package/dist/components/hooks/useFilter/types.d.ts +14 -11
- package/dist/components/hooks/useFilter/types.d.ts.map +1 -1
- package/dist/components/hooks/useFilter/useFilter.d.ts +1 -1
- package/dist/components/hooks/useFilter/useFilter.d.ts.map +1 -1
- package/dist/components/hooks/useForm/apiClient.d.ts +45 -4
- package/dist/components/hooks/useForm/apiClient.d.ts.map +1 -1
- package/dist/components/hooks/useForm/useForm.d.ts.map +1 -1
- package/dist/components/hooks/useKanban/types.d.ts +5 -22
- package/dist/components/hooks/useKanban/types.d.ts.map +1 -1
- package/dist/components/hooks/useKanban/useKanban.d.ts.map +1 -1
- package/dist/components/hooks/useTable/types.d.ts +19 -31
- package/dist/components/hooks/useTable/types.d.ts.map +1 -1
- package/dist/components/hooks/useTable/useTable.d.ts.map +1 -1
- 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 +1 -1
- package/dist/form.cjs +1 -1
- package/dist/form.mjs +736 -750
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/kanban.cjs +2 -2
- package/dist/kanban.mjs +333 -323
- package/dist/{metadata-0lZAfuTP.cjs → metadata-Bz8zJqC1.cjs} +1 -1
- package/dist/{metadata-B88D_pVS.js → metadata-VbQzyD2C.js} +1 -1
- package/dist/table.cjs +1 -1
- package/dist/table.mjs +113 -96
- package/dist/table.types.d.ts +1 -1
- package/dist/table.types.d.ts.map +1 -1
- package/dist/types/base-fields.d.ts +71 -17
- package/dist/types/base-fields.d.ts.map +1 -1
- package/dist/types/common.d.ts +26 -18
- package/dist/types/common.d.ts.map +1 -1
- package/dist/useFilter-DzpP_ag0.cjs +1 -0
- package/dist/useFilter-H5bgAZQF.js +120 -0
- package/dist/utils/api/buildListOptions.d.ts +43 -0
- package/dist/utils/api/buildListOptions.d.ts.map +1 -0
- package/dist/utils/api/index.d.ts +2 -0
- package/dist/utils/api/index.d.ts.map +1 -0
- package/dist/utils/error-handling.d.ts +41 -0
- package/dist/utils/error-handling.d.ts.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/docs/QUICK_REFERENCE.md +142 -420
- package/docs/useAuth.md +52 -340
- package/docs/useFilter.md +858 -162
- package/docs/useForm.md +712 -501
- package/docs/useKanban.md +534 -279
- package/docs/useTable.md +725 -214
- package/package.json +1 -1
- package/sdk/api/client.ts +3 -41
- package/sdk/api/datetime.ts +98 -14
- package/sdk/api/index.ts +12 -6
- package/sdk/api.ts +6 -3
- package/sdk/api.types.ts +3 -4
- package/sdk/auth/AuthProvider.tsx +22 -24
- package/sdk/base-types.ts +2 -0
- package/sdk/components/hooks/useFilter/types.ts +14 -11
- package/sdk/components/hooks/useFilter/useFilter.ts +20 -18
- package/sdk/components/hooks/useForm/apiClient.ts +120 -5
- package/sdk/components/hooks/useForm/useForm.ts +97 -61
- package/sdk/components/hooks/useKanban/types.ts +7 -23
- package/sdk/components/hooks/useKanban/useKanban.ts +54 -18
- package/sdk/components/hooks/useTable/types.ts +26 -32
- package/sdk/components/hooks/useTable/useTable.llm.txt +8 -22
- package/sdk/components/hooks/useTable/useTable.ts +70 -25
- package/sdk/index.ts +157 -10
- package/sdk/table.types.ts +3 -0
- package/sdk/types/base-fields.ts +71 -17
- package/sdk/types/common.ts +33 -19
- package/sdk/utils/api/buildListOptions.ts +120 -0
- package/sdk/utils/api/index.ts +2 -0
- package/sdk/utils/error-handling.ts +150 -0
- package/sdk/utils/index.ts +6 -0
- package/dist/client-DgtkT50N.cjs +0 -1
- package/dist/client-V-WzUb8H.js +0 -237
- package/dist/useFilter-Dofowpr_.cjs +0 -1
- package/dist/useFilter-Dv-mr9QW.js +0 -117
package/sdk/index.ts
CHANGED
|
@@ -1,16 +1,163 @@
|
|
|
1
|
-
//
|
|
1
|
+
// ============================================================
|
|
2
|
+
// @ram_28/kf-ai-sdk - Main Entry Point
|
|
3
|
+
// ============================================================
|
|
4
|
+
// This is the primary export file for the SDK, providing a unified
|
|
5
|
+
// interface to all hooks, types, utilities, and API functions.
|
|
2
6
|
|
|
3
|
-
//
|
|
4
|
-
|
|
7
|
+
// ============================================================
|
|
8
|
+
// HOOKS - Core functionality for building applications
|
|
9
|
+
// ============================================================
|
|
5
10
|
|
|
6
|
-
//
|
|
7
|
-
export
|
|
11
|
+
// Table hook - Data tables with sorting, pagination, and filtering
|
|
12
|
+
export { useTable } from './components/hooks/useTable';
|
|
13
|
+
export type {
|
|
14
|
+
UseTableOptionsType,
|
|
15
|
+
UseTableReturnType,
|
|
16
|
+
} from './components/hooks/useTable';
|
|
8
17
|
|
|
9
|
-
//
|
|
10
|
-
export
|
|
18
|
+
// Form hook - Schema-driven forms with validation
|
|
19
|
+
export { useForm } from './components/hooks/useForm';
|
|
20
|
+
export type {
|
|
21
|
+
UseFormOptionsType,
|
|
22
|
+
UseFormReturnType,
|
|
23
|
+
FormFieldConfigType,
|
|
24
|
+
FormSchemaConfigType,
|
|
25
|
+
} from './components/hooks/useForm';
|
|
11
26
|
|
|
12
|
-
//
|
|
13
|
-
export
|
|
27
|
+
// Kanban hook - Kanban board state management
|
|
28
|
+
export { useKanban } from './components/hooks/useKanban';
|
|
29
|
+
export type {
|
|
30
|
+
UseKanbanOptionsType,
|
|
31
|
+
UseKanbanReturnType,
|
|
32
|
+
KanbanCardType,
|
|
33
|
+
KanbanColumnType,
|
|
34
|
+
ColumnConfigType,
|
|
35
|
+
} from './components/hooks/useKanban';
|
|
36
|
+
|
|
37
|
+
// Filter hook - Advanced filtering with logical operators
|
|
38
|
+
export { useFilter, isCondition, isConditionGroup } from './components/hooks/useFilter';
|
|
39
|
+
export type {
|
|
40
|
+
UseFilterOptionsType,
|
|
41
|
+
UseFilterReturnType,
|
|
42
|
+
} from './components/hooks/useFilter';
|
|
43
|
+
|
|
44
|
+
// ============================================================
|
|
45
|
+
// AUTHENTICATION - User authentication and authorization
|
|
46
|
+
// ============================================================
|
|
47
|
+
|
|
48
|
+
export { AuthProvider, useAuth } from './auth';
|
|
49
|
+
export type {
|
|
50
|
+
UseAuthReturnType,
|
|
51
|
+
UserDetailsType,
|
|
52
|
+
AuthStatusType,
|
|
53
|
+
AuthProviderPropsType,
|
|
54
|
+
} from './auth/types';
|
|
55
|
+
|
|
56
|
+
// ============================================================
|
|
57
|
+
// API CLIENT - Type-safe CRUD operations
|
|
58
|
+
// ============================================================
|
|
59
|
+
|
|
60
|
+
export { api, setApiBaseUrl, getApiBaseUrl, getBdoSchema } from './api';
|
|
61
|
+
|
|
62
|
+
// ============================================================
|
|
63
|
+
// TYPES - Core type definitions
|
|
64
|
+
// ============================================================
|
|
65
|
+
|
|
66
|
+
// Common types
|
|
67
|
+
export type {
|
|
68
|
+
SortType,
|
|
69
|
+
SortDirectionType,
|
|
70
|
+
FilterType,
|
|
71
|
+
ConditionType,
|
|
72
|
+
ConditionGroupType,
|
|
73
|
+
ConditionOperatorType,
|
|
74
|
+
ConditionGroupOperatorType,
|
|
75
|
+
ListResponseType,
|
|
76
|
+
ListOptionsType,
|
|
77
|
+
ColumnDefinitionType,
|
|
78
|
+
} from './types/common';
|
|
79
|
+
|
|
80
|
+
// Base field types
|
|
81
|
+
export type {
|
|
82
|
+
IdFieldType,
|
|
83
|
+
StringFieldType,
|
|
84
|
+
TextAreaFieldType,
|
|
85
|
+
NumberFieldType,
|
|
86
|
+
LongFieldType,
|
|
87
|
+
BooleanFieldType,
|
|
88
|
+
DateFieldType,
|
|
89
|
+
DateTimeFieldType,
|
|
90
|
+
CurrencyFieldType,
|
|
91
|
+
SelectFieldType,
|
|
92
|
+
LookupFieldType,
|
|
93
|
+
ArrayFieldType,
|
|
94
|
+
JSONFieldType,
|
|
95
|
+
ReferenceFieldType,
|
|
96
|
+
ExtractReferenceType,
|
|
97
|
+
ExtractFetchFieldType,
|
|
98
|
+
} from './types/base-fields';
|
|
14
99
|
|
|
15
|
-
//
|
|
100
|
+
// ============================================================
|
|
101
|
+
// UTILITIES - Helper functions
|
|
102
|
+
// ============================================================
|
|
103
|
+
|
|
104
|
+
// Formatting utilities
|
|
105
|
+
export {
|
|
106
|
+
formatCurrency,
|
|
107
|
+
formatDate,
|
|
108
|
+
formatDateTime,
|
|
109
|
+
formatNumber,
|
|
110
|
+
formatBoolean,
|
|
111
|
+
formatArray,
|
|
112
|
+
formatJSON,
|
|
113
|
+
formatFieldValue,
|
|
114
|
+
} from './utils/formatting';
|
|
115
|
+
|
|
116
|
+
// Class name utility
|
|
117
|
+
export { cn } from './utils/cn';
|
|
118
|
+
|
|
119
|
+
// Error handling utilities
|
|
120
|
+
export {
|
|
121
|
+
toError,
|
|
122
|
+
isError,
|
|
123
|
+
getErrorMessage,
|
|
124
|
+
isNetworkError,
|
|
125
|
+
isTimeoutError,
|
|
126
|
+
isAbortError,
|
|
127
|
+
tryCatch,
|
|
128
|
+
wrapError,
|
|
129
|
+
} from './utils/error-handling';
|
|
130
|
+
|
|
131
|
+
// API utilities
|
|
132
|
+
export {
|
|
133
|
+
buildListOptions,
|
|
134
|
+
buildCountOptions,
|
|
135
|
+
combineFilters,
|
|
136
|
+
} from './utils/api';
|
|
137
|
+
|
|
138
|
+
// ============================================================
|
|
139
|
+
// UI COMPONENTS - Pre-built React components
|
|
140
|
+
// ============================================================
|
|
141
|
+
|
|
142
|
+
export {
|
|
143
|
+
Kanban,
|
|
144
|
+
KanbanColumn,
|
|
145
|
+
KanbanColumnHeader,
|
|
146
|
+
KanbanColumnTitle,
|
|
147
|
+
KanbanColumnContent,
|
|
148
|
+
KanbanCard,
|
|
149
|
+
KanbanCardTitle,
|
|
150
|
+
KanbanCardDescription,
|
|
151
|
+
KanbanColumnFooter,
|
|
152
|
+
} from './components/ui';
|
|
153
|
+
|
|
154
|
+
// ============================================================
|
|
155
|
+
// LEGACY EXPORTS - For backwards compatibility
|
|
156
|
+
// ============================================================
|
|
157
|
+
|
|
158
|
+
// Re-export everything from submodules for backwards compatibility
|
|
159
|
+
export * from './types';
|
|
160
|
+
export * from './api';
|
|
161
|
+
export * from './utils';
|
|
162
|
+
export * from './components';
|
|
16
163
|
export * from './auth';
|
package/sdk/table.types.ts
CHANGED
package/sdk/types/base-fields.ts
CHANGED
|
@@ -67,27 +67,47 @@ export type LongFieldType = number;
|
|
|
67
67
|
*/
|
|
68
68
|
export type BooleanFieldType = boolean;
|
|
69
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Encoded date format from API response
|
|
72
|
+
* API returns: { "$__d__": "YYYY-MM-DD" }
|
|
73
|
+
*/
|
|
74
|
+
export interface DateEncodedType {
|
|
75
|
+
$__d__: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Encoded datetime format from API response
|
|
80
|
+
* API returns: { "$__dt__": unix_timestamp_seconds }
|
|
81
|
+
*/
|
|
82
|
+
export interface DateTimeEncodedType {
|
|
83
|
+
$__dt__: number;
|
|
84
|
+
}
|
|
85
|
+
|
|
70
86
|
/**
|
|
71
87
|
* Date field (date only, no time)
|
|
72
|
-
*
|
|
88
|
+
* API Response Format: { "$__d__": "YYYY-MM-DD" }
|
|
89
|
+
* API Request Format: "YYYY-MM-DD"
|
|
73
90
|
* Storage: DATE in database
|
|
74
91
|
* Use this for birth dates, due dates, calendar events
|
|
75
92
|
*
|
|
76
93
|
* @example
|
|
77
|
-
*
|
|
94
|
+
* // Response from API:
|
|
95
|
+
* { "$__d__": "2025-03-15" }
|
|
78
96
|
*/
|
|
79
|
-
export type DateFieldType =
|
|
97
|
+
export type DateFieldType = DateEncodedType;
|
|
80
98
|
|
|
81
99
|
/**
|
|
82
100
|
* DateTime field (date and time)
|
|
83
|
-
*
|
|
101
|
+
* API Response Format: { "$__dt__": unix_timestamp_seconds }
|
|
102
|
+
* API Request Format: "YYYY-MM-DD HH:MM:SS"
|
|
84
103
|
* Storage: DATETIME/TIMESTAMP in database
|
|
85
104
|
* Use this for created_at, updated_at, event timestamps
|
|
86
105
|
*
|
|
87
106
|
* @example
|
|
88
|
-
*
|
|
107
|
+
* // Response from API:
|
|
108
|
+
* { "$__dt__": 1769110463 }
|
|
89
109
|
*/
|
|
90
|
-
export type DateTimeFieldType =
|
|
110
|
+
export type DateTimeFieldType = DateTimeEncodedType;
|
|
91
111
|
|
|
92
112
|
// ============================================================
|
|
93
113
|
// COMPLEX FIELD TYPES
|
|
@@ -124,7 +144,47 @@ export type CurrencyValueType =
|
|
|
124
144
|
*/
|
|
125
145
|
export type JSONFieldType<T = JSONValueType> = T;
|
|
126
146
|
|
|
127
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Reference/Lookup field for relationships to other Business Data Objects
|
|
149
|
+
*
|
|
150
|
+
* @template TReferencedType - The full type of the referenced BDO record
|
|
151
|
+
*
|
|
152
|
+
* Runtime behavior:
|
|
153
|
+
* - The field stores the full referenced record (e.g., full supplier object)
|
|
154
|
+
* - API returns the complete record from the referenced BDO
|
|
155
|
+
* - On save, the full object is sent in the payload
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* SupplierInfo: ReferenceFieldType<BaseSupplierType>;
|
|
159
|
+
* // At runtime: { _id: "...", SupplierId: "...", SupplierName: "...", ... }
|
|
160
|
+
*/
|
|
161
|
+
export type ReferenceFieldType<TReferencedType = unknown> = TReferencedType;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Extract the referenced type from a ReferenceFieldType
|
|
165
|
+
* Note: Since ReferenceFieldType<T> = T, this just returns T if it has _id
|
|
166
|
+
*/
|
|
167
|
+
export type ExtractReferenceType<T> = T extends { _id: string } ? T : never;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Extract the type that fetchField should return for a given field type
|
|
171
|
+
* - For Reference fields (objects with _id) → the full referenced record type
|
|
172
|
+
* - For other field types → { Value: string; Label: string } (static dropdown)
|
|
173
|
+
*
|
|
174
|
+
* Detection: All BDO types have _id: string, so we check for that property
|
|
175
|
+
* to distinguish reference fields from primitive fields like StringFieldType.
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* type SupplierOptions = ExtractFetchFieldType<BaseProductType["SupplierInfo"]>;
|
|
179
|
+
* // Result: BaseSupplierType (has _id)
|
|
180
|
+
*
|
|
181
|
+
* type CategoryOptions = ExtractFetchFieldType<BaseProductType["Category"]>;
|
|
182
|
+
* // Result: { Value: string; Label: string } (string has no _id)
|
|
183
|
+
*/
|
|
184
|
+
export type ExtractFetchFieldType<T> =
|
|
185
|
+
T extends { _id: string }
|
|
186
|
+
? T
|
|
187
|
+
: { Value: string; Label: string };
|
|
128
188
|
|
|
129
189
|
/**
|
|
130
190
|
* Valid JSON value types
|
|
@@ -156,17 +216,11 @@ export interface JSONArrayType extends Array<JSONValueType> {}
|
|
|
156
216
|
export type SelectFieldType<T extends string> = T;
|
|
157
217
|
|
|
158
218
|
/**
|
|
159
|
-
* Lookup
|
|
160
|
-
* @template
|
|
161
|
-
*
|
|
162
|
-
* Storage: VARCHAR in database (stores the ID)
|
|
163
|
-
* Use this for foreign keys, relationships, references
|
|
164
|
-
*
|
|
165
|
-
* @example
|
|
166
|
-
* LookupFieldType // => string (referenced record ID)
|
|
167
|
-
* LookupFieldType<IdFieldType> // => string (typed as IdFieldType)
|
|
219
|
+
* Alias for ReferenceFieldType (Lookup = Reference in the backend)
|
|
220
|
+
* @template TReferencedType - The full type of the referenced BDO record
|
|
221
|
+
* @deprecated Use ReferenceFieldType instead
|
|
168
222
|
*/
|
|
169
|
-
export type LookupFieldType<
|
|
223
|
+
export type LookupFieldType<TReferencedType = unknown> = ReferenceFieldType<TReferencedType>;
|
|
170
224
|
|
|
171
225
|
// ============================================================
|
|
172
226
|
// CONTAINER AND UTILITY TYPES
|
package/sdk/types/common.ts
CHANGED
|
@@ -37,14 +37,15 @@ export type FilterRHSTypeType = "Constant" | "BOField" | "AppVariable";
|
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* Leaf condition (actual field comparison)
|
|
40
|
+
* @template T - Data type for type-safe field names (defaults to any)
|
|
40
41
|
*/
|
|
41
|
-
export interface ConditionType {
|
|
42
|
+
export interface ConditionType<T = any> {
|
|
42
43
|
/** Optional ID for hook state management (omitted in API payload) */
|
|
43
44
|
id?: string;
|
|
44
45
|
/** Condition operator */
|
|
45
46
|
Operator: ConditionOperatorType;
|
|
46
|
-
/** Left-hand side field name */
|
|
47
|
-
LHSField: string;
|
|
47
|
+
/** Left-hand side field name (keyof T when generic is provided) */
|
|
48
|
+
LHSField: T extends any ? keyof T | string : string;
|
|
48
49
|
/** Right-hand side value */
|
|
49
50
|
RHSValue: any;
|
|
50
51
|
/** Right-hand side type (optional, defaults to Constant) */
|
|
@@ -53,34 +54,25 @@ export interface ConditionType {
|
|
|
53
54
|
|
|
54
55
|
/**
|
|
55
56
|
* Group combining conditions (recursive structure)
|
|
57
|
+
* @template T - Data type for type-safe field names (defaults to any)
|
|
56
58
|
*/
|
|
57
|
-
export interface ConditionGroupType {
|
|
59
|
+
export interface ConditionGroupType<T = any> {
|
|
58
60
|
/** Optional ID for hook state management (omitted in API payload) */
|
|
59
61
|
id?: string;
|
|
60
62
|
/** Group operator (And, Or, Not) */
|
|
61
63
|
Operator: ConditionGroupOperatorType;
|
|
62
64
|
/** Nested conditions (can be Condition or ConditionGroup) */
|
|
63
|
-
Condition: Array<ConditionType | ConditionGroupType
|
|
65
|
+
Condition: Array<ConditionType<T> | ConditionGroupType<T>>;
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
/**
|
|
67
69
|
* Root filter type (alias for ConditionGroup)
|
|
70
|
+
* @template T - Data type for type-safe field names (defaults to any)
|
|
68
71
|
*/
|
|
69
|
-
export type FilterType = ConditionGroupType
|
|
72
|
+
export type FilterType<T = any> = ConditionGroupType<T>;
|
|
70
73
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
*/
|
|
74
|
-
export interface DateTimeEncodedType {
|
|
75
|
-
$__dt__: number;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Date encoding format used by the API
|
|
80
|
-
*/
|
|
81
|
-
export interface DateEncodedType {
|
|
82
|
-
$__d__: string;
|
|
83
|
-
}
|
|
74
|
+
// Note: DateTimeEncodedType and DateEncodedType are now defined in base-fields.ts
|
|
75
|
+
// They are re-exported from api/index.ts for convenience
|
|
84
76
|
|
|
85
77
|
/**
|
|
86
78
|
* Standard paginated list response
|
|
@@ -296,3 +288,25 @@ export interface FetchFieldResponseType {
|
|
|
296
288
|
/** Array of field options */
|
|
297
289
|
Data: FetchFieldOptionType[];
|
|
298
290
|
}
|
|
291
|
+
|
|
292
|
+
// ============================================================
|
|
293
|
+
// SHARED COMPONENT TYPES
|
|
294
|
+
// ============================================================
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Column definition for data display and behavior
|
|
298
|
+
* Used by useTable and useKanban for defining field configurations
|
|
299
|
+
* @template T - Data type for type-safe field names
|
|
300
|
+
*/
|
|
301
|
+
export interface ColumnDefinitionType<T> {
|
|
302
|
+
/** Field name from the data type */
|
|
303
|
+
fieldId: keyof T;
|
|
304
|
+
/** Display label (optional, defaults to fieldId) */
|
|
305
|
+
label?: string;
|
|
306
|
+
/** Enable sorting for this field */
|
|
307
|
+
enableSorting?: boolean;
|
|
308
|
+
/** Enable filtering for this field */
|
|
309
|
+
enableFiltering?: boolean;
|
|
310
|
+
/** Custom transform function (overrides auto-formatting) */
|
|
311
|
+
transform?: (value: any, item: T) => React.ReactNode;
|
|
312
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// BUILD LIST OPTIONS UTILITY
|
|
3
|
+
// ============================================================
|
|
4
|
+
// Shared utility for building API list options across hooks
|
|
5
|
+
|
|
6
|
+
import type { ListOptionsType, FilterType, SortType } from "../../types/common";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Options for building list API request options
|
|
10
|
+
*/
|
|
11
|
+
export interface BuildListOptionsParams<T = any> {
|
|
12
|
+
/** Search query string */
|
|
13
|
+
search?: string;
|
|
14
|
+
/** Filter payload */
|
|
15
|
+
filter?: FilterType<T>;
|
|
16
|
+
/** Sort configuration */
|
|
17
|
+
sort?: {
|
|
18
|
+
field: keyof T | null;
|
|
19
|
+
direction: "asc" | "desc" | null;
|
|
20
|
+
};
|
|
21
|
+
/** Sort array in API format */
|
|
22
|
+
sortArray?: SortType;
|
|
23
|
+
/** Pagination settings */
|
|
24
|
+
pagination?: {
|
|
25
|
+
pageNo: number;
|
|
26
|
+
pageSize: number;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Build list options for count queries
|
|
32
|
+
* Excludes pagination and sorting (they don't affect count)
|
|
33
|
+
*/
|
|
34
|
+
export function buildCountOptions<T = any>(
|
|
35
|
+
params: Pick<BuildListOptionsParams<T>, "search" | "filter">
|
|
36
|
+
): ListOptionsType {
|
|
37
|
+
const opts: ListOptionsType = {};
|
|
38
|
+
|
|
39
|
+
if (params.search) {
|
|
40
|
+
opts.Search = params.search;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (params.filter) {
|
|
44
|
+
opts.Filter = params.filter;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return opts;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Build list options for data queries
|
|
52
|
+
* Includes all options: search, filter, sort, pagination
|
|
53
|
+
*/
|
|
54
|
+
export function buildListOptions<T = any>(
|
|
55
|
+
params: BuildListOptionsParams<T>
|
|
56
|
+
): ListOptionsType {
|
|
57
|
+
const opts: ListOptionsType = buildCountOptions({
|
|
58
|
+
search: params.search,
|
|
59
|
+
filter: params.filter,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Add sorting - convert internal format to API format
|
|
63
|
+
if (params.sort?.field && params.sort?.direction) {
|
|
64
|
+
opts.Sort = [
|
|
65
|
+
{
|
|
66
|
+
[String(params.sort.field)]:
|
|
67
|
+
params.sort.direction === "asc" ? "ASC" : "DESC",
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
} else if (params.sortArray) {
|
|
71
|
+
opts.Sort = params.sortArray;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Add pagination
|
|
75
|
+
if (params.pagination) {
|
|
76
|
+
opts.Page = params.pagination.pageNo;
|
|
77
|
+
opts.PageSize = params.pagination.pageSize;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return opts;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Combine filter payload with additional column filter
|
|
85
|
+
* Used for kanban column-specific queries
|
|
86
|
+
*/
|
|
87
|
+
export function combineFilters<T = any>(
|
|
88
|
+
baseFilter: FilterType<T> | undefined,
|
|
89
|
+
additionalCondition: {
|
|
90
|
+
LHSField: string;
|
|
91
|
+
Operator: string;
|
|
92
|
+
RHSValue: any;
|
|
93
|
+
RHSType?: string;
|
|
94
|
+
}
|
|
95
|
+
): FilterType<T> {
|
|
96
|
+
const columnFilterObject = {
|
|
97
|
+
...additionalCondition,
|
|
98
|
+
RHSType: additionalCondition.RHSType || "Constant",
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
if (!baseFilter) {
|
|
102
|
+
return {
|
|
103
|
+
Operator: "And",
|
|
104
|
+
Condition: [columnFilterObject],
|
|
105
|
+
} as FilterType<T>;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// If base is And, append. If base is Or/Not, wrap in new And.
|
|
109
|
+
if (baseFilter.Operator === "And") {
|
|
110
|
+
return {
|
|
111
|
+
...baseFilter,
|
|
112
|
+
Condition: [...(baseFilter.Condition || []), columnFilterObject],
|
|
113
|
+
} as FilterType<T>;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
Operator: "And",
|
|
118
|
+
Condition: [baseFilter, columnFilterObject],
|
|
119
|
+
} as FilterType<T>;
|
|
120
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// ERROR HANDLING UTILITIES
|
|
3
|
+
// ============================================================
|
|
4
|
+
// Type-safe error handling utilities for the SDK
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Safely convert unknown error to Error object
|
|
8
|
+
* Handles all possible error types that could be thrown
|
|
9
|
+
*/
|
|
10
|
+
export function toError(err: unknown): Error {
|
|
11
|
+
// Already an Error instance
|
|
12
|
+
if (err instanceof Error) {
|
|
13
|
+
return err;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// String error
|
|
17
|
+
if (typeof err === "string") {
|
|
18
|
+
return new Error(err);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Object with message property
|
|
22
|
+
if (
|
|
23
|
+
err !== null &&
|
|
24
|
+
typeof err === "object" &&
|
|
25
|
+
"message" in err &&
|
|
26
|
+
typeof (err as { message: unknown }).message === "string"
|
|
27
|
+
) {
|
|
28
|
+
const error = new Error((err as { message: string }).message);
|
|
29
|
+
// Preserve any additional properties
|
|
30
|
+
Object.assign(error, err);
|
|
31
|
+
return error;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Fallback: convert to string
|
|
35
|
+
return new Error(String(err));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Type guard to check if a value is an Error
|
|
40
|
+
*/
|
|
41
|
+
export function isError(value: unknown): value is Error {
|
|
42
|
+
return value instanceof Error;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Type guard to check if error has a specific code
|
|
47
|
+
*/
|
|
48
|
+
export function hasErrorCode(
|
|
49
|
+
err: unknown,
|
|
50
|
+
code: string
|
|
51
|
+
): err is Error & { code: string } {
|
|
52
|
+
return (
|
|
53
|
+
err instanceof Error &&
|
|
54
|
+
"code" in err &&
|
|
55
|
+
(err as Error & { code: unknown }).code === code
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Type guard to check if error is a network error
|
|
61
|
+
*/
|
|
62
|
+
export function isNetworkError(err: unknown): boolean {
|
|
63
|
+
if (!isError(err)) return false;
|
|
64
|
+
|
|
65
|
+
const message = err.message.toLowerCase();
|
|
66
|
+
return (
|
|
67
|
+
message.includes("network") ||
|
|
68
|
+
message.includes("fetch") ||
|
|
69
|
+
message.includes("connection") ||
|
|
70
|
+
hasErrorCode(err, "NETWORK_ERROR") ||
|
|
71
|
+
hasErrorCode(err, "ENOTFOUND") ||
|
|
72
|
+
hasErrorCode(err, "ECONNREFUSED")
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Type guard to check if error is a timeout error
|
|
78
|
+
*/
|
|
79
|
+
export function isTimeoutError(err: unknown): boolean {
|
|
80
|
+
if (!isError(err)) return false;
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
err.message.toLowerCase().includes("timeout") ||
|
|
84
|
+
hasErrorCode(err, "TIMEOUT") ||
|
|
85
|
+
hasErrorCode(err, "ETIMEDOUT")
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Type guard to check if error is an abort error
|
|
91
|
+
*/
|
|
92
|
+
export function isAbortError(err: unknown): boolean {
|
|
93
|
+
if (!isError(err)) return false;
|
|
94
|
+
|
|
95
|
+
return err.name === "AbortError" || hasErrorCode(err, "ABORT_ERR");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Extract error message from unknown error
|
|
100
|
+
*/
|
|
101
|
+
export function getErrorMessage(err: unknown): string {
|
|
102
|
+
if (isError(err)) {
|
|
103
|
+
return err.message;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (typeof err === "string") {
|
|
107
|
+
return err;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (
|
|
111
|
+
err !== null &&
|
|
112
|
+
typeof err === "object" &&
|
|
113
|
+
"message" in err &&
|
|
114
|
+
typeof (err as { message: unknown }).message === "string"
|
|
115
|
+
) {
|
|
116
|
+
return (err as { message: string }).message;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return String(err);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Safe error handler wrapper for async functions
|
|
124
|
+
* Returns a tuple of [result, error]
|
|
125
|
+
*/
|
|
126
|
+
export async function tryCatch<T>(
|
|
127
|
+
fn: () => Promise<T>
|
|
128
|
+
): Promise<[T, null] | [null, Error]> {
|
|
129
|
+
try {
|
|
130
|
+
const result = await fn();
|
|
131
|
+
return [result, null];
|
|
132
|
+
} catch (err) {
|
|
133
|
+
return [null, toError(err)];
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Create a wrapped error with original error as cause
|
|
139
|
+
*/
|
|
140
|
+
export function wrapError(message: string, cause: unknown): Error {
|
|
141
|
+
const error = new Error(message);
|
|
142
|
+
// Use Object.defineProperty for broader compatibility
|
|
143
|
+
Object.defineProperty(error, 'cause', {
|
|
144
|
+
value: toError(cause),
|
|
145
|
+
writable: true,
|
|
146
|
+
enumerable: false,
|
|
147
|
+
configurable: true,
|
|
148
|
+
});
|
|
149
|
+
return error;
|
|
150
|
+
}
|
package/sdk/utils/index.ts
CHANGED
package/dist/client-DgtkT50N.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";let o={baseUrl:"",headers:{"Content-Type":"application/json"}};function u(e){o.baseUrl=e}function h(e){o.headers={...o.headers,...e}}function d(){return{...o.headers}}function l(){return o.baseUrl||""}function i(e){if(e==null)return e;if(Array.isArray(e))return e.map(s=>i(s));if(typeof e=="object"){if("$__dt__"in e)return new Date(e.$__dt__*1e3);if("$__d__"in e)return new Date(e.$__d__);const s={};for(const[n,t]of Object.entries(e))s[n]=i(t);return s}return e}function w(e){const s=o.baseUrl,n=o.headers;return{async get(t){const r=await fetch(`${s}/api/app/${e}/${t}/read`,{method:"GET",headers:n});if(!r.ok)throw new Error(`Failed to get ${e} ${t}: ${r.statusText}`);const a=await r.json();return i(a.Data)},async create(t){const r=await fetch(`${s}/api/app/${e}/create`,{method:"POST",headers:n,body:JSON.stringify(t)});if(!r.ok)throw new Error(`Failed to create ${e}: ${r.statusText}`);return r.json()},async update(t,r){const a=await fetch(`${s}/api/app/${e}/${t}/update`,{method:"POST",headers:n,body:JSON.stringify(r)});if(!a.ok)throw new Error(`Failed to update ${e} ${t}: ${a.statusText}`);return a.json()},async delete(t){const r=await fetch(`${s}/api/app/${e}/${t}/delete`,{method:"DELETE",headers:n});if(!r.ok)throw new Error(`Failed to delete ${e} ${t}: ${r.statusText}`);return r.json()},async list(t){const r={Type:"List",...t},a=await fetch(`${s}/api/app/${e}/list`,{method:"POST",headers:n,body:JSON.stringify(r)});if(!a.ok)throw new Error(`Failed to list ${e}: ${a.statusText}`);return{Data:(await a.json()).Data.map(f=>i(f))}},async count(t){var p,$;const r={Type:"Metric",GroupBy:[],Metric:[{Field:"_id",Type:"Count"}],...(t==null?void 0:t.Filter)&&{Filter:t.Filter}},a=await fetch(`${s}/api/app/${e}/metric`,{method:"POST",headers:n,body:JSON.stringify(r)});if(!a.ok)throw new Error(`Failed to count ${e}: ${a.statusText}`);return{Count:(($=(p=(await a.json()).Data)==null?void 0:p[0])==null?void 0:$.count__id)??0}},async draft(t){const r=await fetch(`${s}/api/app/${e}/draft`,{method:"POST",headers:n,body:JSON.stringify(t)});if(!r.ok)throw new Error(`Failed to create draft for ${e}: ${r.statusText}`);return r.json()},async draftUpdate(t,r){const a=await fetch(`${s}/api/app/${e}/${t}/draft`,{method:"POST",headers:n,body:JSON.stringify(r)});if(!a.ok)throw new Error(`Failed to update draft for ${e} ${t}: ${a.statusText}`);return a.json()},async draftPatch(t,r){const a=await fetch(`${s}/api/app/${e}/${t}/draft`,{method:"PATCH",headers:n,body:JSON.stringify(r)});if(!a.ok)throw new Error(`Failed to patch draft for ${e} ${t}: ${a.statusText}`);return a.json()},async draftInteraction(t){const r=await fetch(`${s}/api/app/${e}/draft`,{method:"PATCH",headers:n,body:JSON.stringify(t)});if(!r.ok)throw new Error(`Failed to create interactive draft for ${e}: ${r.statusText}`);const a=await r.json();return{...a.Data,_id:a.Data._id}},async metric(t){const r={Type:"Metric",...t},a=await fetch(`${s}/api/app/${e}/metric`,{method:"POST",headers:n,body:JSON.stringify(r)});if(!a.ok)throw new Error(`Failed to get metrics for ${e}: ${a.statusText}`);return a.json()},async pivot(t){const r={Type:"Pivot",...t},a=await fetch(`${s}/api/app/${e}/pivot`,{method:"POST",headers:n,body:JSON.stringify(r)});if(!a.ok)throw new Error(`Failed to get pivot data for ${e}: ${a.statusText}`);return a.json()},async fields(){const t=await fetch(`${s}/api/app/${e}/fields`,{method:"GET",headers:n});if(!t.ok)throw new Error(`Failed to get fields for ${e}: ${t.statusText}`);return t.json()},async fetchField(t,r){const a=await fetch(`${s}/api/app/${e}/${t}/field/${r}/fetch`,{method:"GET",headers:n});if(!a.ok)throw new Error(`Failed to fetch field ${r} for ${e}: ${a.statusText}`);return(await a.json()).Data}}}exports.api=w;exports.getApiBaseUrl=l;exports.getDefaultHeaders=d;exports.setApiBaseUrl=u;exports.setDefaultHeaders=h;
|