@ram_28/kf-ai-sdk 1.0.0

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 (126) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +840 -0
  3. package/dist/api/client.d.ts +78 -0
  4. package/dist/api/client.d.ts.map +1 -0
  5. package/dist/api/datetime.d.ts +21 -0
  6. package/dist/api/datetime.d.ts.map +1 -0
  7. package/dist/api/index.d.ts +7 -0
  8. package/dist/api/index.d.ts.map +1 -0
  9. package/dist/api/metadata.d.ts +75 -0
  10. package/dist/api/metadata.d.ts.map +1 -0
  11. package/dist/components/hooks/index.d.ts +8 -0
  12. package/dist/components/hooks/index.d.ts.map +1 -0
  13. package/dist/components/hooks/useFilter/index.d.ts +5 -0
  14. package/dist/components/hooks/useFilter/index.d.ts.map +1 -0
  15. package/dist/components/hooks/useFilter/payloadBuilder.utils.d.ts +33 -0
  16. package/dist/components/hooks/useFilter/payloadBuilder.utils.d.ts.map +1 -0
  17. package/dist/components/hooks/useFilter/types.d.ts +137 -0
  18. package/dist/components/hooks/useFilter/types.d.ts.map +1 -0
  19. package/dist/components/hooks/useFilter/useFilter.d.ts +3 -0
  20. package/dist/components/hooks/useFilter/useFilter.d.ts.map +1 -0
  21. package/dist/components/hooks/useFilter/validation.utils.d.ts +38 -0
  22. package/dist/components/hooks/useFilter/validation.utils.d.ts.map +1 -0
  23. package/dist/components/hooks/useForm/apiClient.d.ts +71 -0
  24. package/dist/components/hooks/useForm/apiClient.d.ts.map +1 -0
  25. package/dist/components/hooks/useForm/expressionValidator.utils.d.ts +28 -0
  26. package/dist/components/hooks/useForm/expressionValidator.utils.d.ts.map +1 -0
  27. package/dist/components/hooks/useForm/index.d.ts +6 -0
  28. package/dist/components/hooks/useForm/index.d.ts.map +1 -0
  29. package/dist/components/hooks/useForm/optimizedExpressionValidator.utils.d.ts +88 -0
  30. package/dist/components/hooks/useForm/optimizedExpressionValidator.utils.d.ts.map +1 -0
  31. package/dist/components/hooks/useForm/ruleClassifier.utils.d.ts +28 -0
  32. package/dist/components/hooks/useForm/ruleClassifier.utils.d.ts.map +1 -0
  33. package/dist/components/hooks/useForm/schemaParser.utils.d.ts +29 -0
  34. package/dist/components/hooks/useForm/schemaParser.utils.d.ts.map +1 -0
  35. package/dist/components/hooks/useForm/types.d.ts +412 -0
  36. package/dist/components/hooks/useForm/types.d.ts.map +1 -0
  37. package/dist/components/hooks/useForm/useForm.d.ts +3 -0
  38. package/dist/components/hooks/useForm/useForm.d.ts.map +1 -0
  39. package/dist/components/hooks/useKanban/apiClient.d.ts +99 -0
  40. package/dist/components/hooks/useKanban/apiClient.d.ts.map +1 -0
  41. package/dist/components/hooks/useKanban/context.d.ts +4 -0
  42. package/dist/components/hooks/useKanban/context.d.ts.map +1 -0
  43. package/dist/components/hooks/useKanban/dragDropManager.d.ts +27 -0
  44. package/dist/components/hooks/useKanban/dragDropManager.d.ts.map +1 -0
  45. package/dist/components/hooks/useKanban/index.d.ts +6 -0
  46. package/dist/components/hooks/useKanban/index.d.ts.map +1 -0
  47. package/dist/components/hooks/useKanban/types.d.ts +438 -0
  48. package/dist/components/hooks/useKanban/types.d.ts.map +1 -0
  49. package/dist/components/hooks/useKanban/useKanban.d.ts +3 -0
  50. package/dist/components/hooks/useKanban/useKanban.d.ts.map +1 -0
  51. package/dist/components/hooks/useKanban/useKanbanSimple.d.ts +62 -0
  52. package/dist/components/hooks/useKanban/useKanbanSimple.d.ts.map +1 -0
  53. package/dist/components/hooks/useTable/index.d.ts +3 -0
  54. package/dist/components/hooks/useTable/index.d.ts.map +1 -0
  55. package/dist/components/hooks/useTable/types.d.ts +107 -0
  56. package/dist/components/hooks/useTable/types.d.ts.map +1 -0
  57. package/dist/components/hooks/useTable/useTable.d.ts +8 -0
  58. package/dist/components/hooks/useTable/useTable.d.ts.map +1 -0
  59. package/dist/components/index.d.ts +3 -0
  60. package/dist/components/index.d.ts.map +1 -0
  61. package/dist/components/ui/index.d.ts +2 -0
  62. package/dist/components/ui/index.d.ts.map +1 -0
  63. package/dist/components/ui/kanban/Kanban.d.ts +12 -0
  64. package/dist/components/ui/kanban/Kanban.d.ts.map +1 -0
  65. package/dist/components/ui/kanban/index.d.ts +2 -0
  66. package/dist/components/ui/kanban/index.d.ts.map +1 -0
  67. package/dist/index.cjs +45 -0
  68. package/dist/index.d.ts +5 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.mjs +6522 -0
  71. package/dist/types/base-fields.d.ts +182 -0
  72. package/dist/types/base-fields.d.ts.map +1 -0
  73. package/dist/types/common.d.ts +238 -0
  74. package/dist/types/common.d.ts.map +1 -0
  75. package/dist/types/index.d.ts +3 -0
  76. package/dist/types/index.d.ts.map +1 -0
  77. package/dist/utils/cn.d.ts +7 -0
  78. package/dist/utils/cn.d.ts.map +1 -0
  79. package/dist/utils/formatting.d.ts +52 -0
  80. package/dist/utils/formatting.d.ts.map +1 -0
  81. package/dist/utils/index.d.ts +3 -0
  82. package/dist/utils/index.d.ts.map +1 -0
  83. package/package.json +98 -0
  84. package/sdk/api/client.ts +447 -0
  85. package/sdk/api/datetime.ts +33 -0
  86. package/sdk/api/index.ts +61 -0
  87. package/sdk/api/metadata.ts +148 -0
  88. package/sdk/components/hooks/index.ts +34 -0
  89. package/sdk/components/hooks/useFilter/index.ts +37 -0
  90. package/sdk/components/hooks/useFilter/payloadBuilder.utils.ts +298 -0
  91. package/sdk/components/hooks/useFilter/types.ts +158 -0
  92. package/sdk/components/hooks/useFilter/useFilter.llm.txt +497 -0
  93. package/sdk/components/hooks/useFilter/useFilter.ts +494 -0
  94. package/sdk/components/hooks/useFilter/validation.utils.ts +401 -0
  95. package/sdk/components/hooks/useForm/apiClient.ts +441 -0
  96. package/sdk/components/hooks/useForm/expressionValidator.utils.ts +444 -0
  97. package/sdk/components/hooks/useForm/index.ts +64 -0
  98. package/sdk/components/hooks/useForm/optimizedExpressionValidator.utils.ts +482 -0
  99. package/sdk/components/hooks/useForm/ruleClassifier.utils.ts +424 -0
  100. package/sdk/components/hooks/useForm/schemaParser.utils.ts +519 -0
  101. package/sdk/components/hooks/useForm/types.ts +630 -0
  102. package/sdk/components/hooks/useForm/useForm.llm.txt +340 -0
  103. package/sdk/components/hooks/useForm/useForm.ts +821 -0
  104. package/sdk/components/hooks/useKanban/apiClient.ts +494 -0
  105. package/sdk/components/hooks/useKanban/context.ts +14 -0
  106. package/sdk/components/hooks/useKanban/dragDropManager.ts +529 -0
  107. package/sdk/components/hooks/useKanban/index.ts +63 -0
  108. package/sdk/components/hooks/useKanban/types.ts +606 -0
  109. package/sdk/components/hooks/useKanban/useKanban.llm.txt +482 -0
  110. package/sdk/components/hooks/useKanban/useKanban.ts +725 -0
  111. package/sdk/components/hooks/useKanban/useKanbanSimple.ts +389 -0
  112. package/sdk/components/hooks/useTable/index.ts +5 -0
  113. package/sdk/components/hooks/useTable/types.ts +154 -0
  114. package/sdk/components/hooks/useTable/useTable.llm.txt +344 -0
  115. package/sdk/components/hooks/useTable/useTable.ts +413 -0
  116. package/sdk/components/index.ts +15 -0
  117. package/sdk/components/ui/index.ts +2 -0
  118. package/sdk/components/ui/kanban/Kanban.tsx +134 -0
  119. package/sdk/components/ui/kanban/index.ts +11 -0
  120. package/sdk/index.ts +13 -0
  121. package/sdk/types/base-fields.ts +221 -0
  122. package/sdk/types/common.ts +306 -0
  123. package/sdk/types/index.ts +5 -0
  124. package/sdk/utils/cn.ts +10 -0
  125. package/sdk/utils/formatting.ts +212 -0
  126. package/sdk/utils/index.ts +5 -0
@@ -0,0 +1,519 @@
1
+ // ============================================================
2
+ // SCHEMA PARSER
3
+ // ============================================================
4
+ // Converts backend field schemas to react-hook-form validation rules
5
+
6
+ import type {
7
+ BackendSchema,
8
+ BDOSchema,
9
+ BackendFieldDefinition,
10
+ ProcessedField,
11
+ ProcessedSchema,
12
+ ValidationRule,
13
+ FieldPermission,
14
+ } from "./types";
15
+ import {
16
+ calculateDefaultValue,
17
+ calculateComputedValue,
18
+ } from "./expressionValidator.utils";
19
+ import {
20
+ classifyRules,
21
+ createFieldRuleMapping,
22
+ calculateFieldPermissions,
23
+ convertLegacySchema,
24
+ normalizeBDOSchema,
25
+ } from "./ruleClassifier.utils";
26
+
27
+ // ============================================================
28
+ // FIELD TYPE MAPPING
29
+ // ============================================================
30
+
31
+ /**
32
+ * Map backend field types to HTML input types
33
+ */
34
+ function mapFieldType(backendType: string, fieldName: string): string {
35
+ switch (backendType) {
36
+ case "String":
37
+ // Infer specific string types from field name
38
+ if (fieldName.toLowerCase().includes("email")) {
39
+ return "email";
40
+ }
41
+ if (fieldName.toLowerCase().includes("password")) {
42
+ return "password";
43
+ }
44
+ return "text";
45
+
46
+ case "Number":
47
+ return "number";
48
+
49
+ case "Boolean":
50
+ return "checkbox";
51
+
52
+ case "Date":
53
+ return "date";
54
+
55
+ case "DateTime":
56
+ return "datetime-local";
57
+
58
+ case "Reference":
59
+ return "reference";
60
+
61
+ case "Array":
62
+ case "Object":
63
+ return "textarea"; // JSON string representation
64
+
65
+ default:
66
+ return "text";
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Generate field label from field name
72
+ */
73
+ function generateLabel(fieldName: string): string {
74
+ return fieldName
75
+ .replace(/([A-Z])/g, " $1") // Add space before capital letters
76
+ .replace(/^./, (str) => str.toUpperCase()) // Capitalize first letter
77
+ .replace(/_/g, " ") // Replace underscores with spaces
78
+ .trim();
79
+ }
80
+
81
+ // ============================================================
82
+ // VALIDATION RULE CONVERSION
83
+ // ============================================================
84
+
85
+ /**
86
+ * Convert backend validation rules to react-hook-form validation
87
+ */
88
+ function convertValidationRules(
89
+ fieldName: string,
90
+ fieldDef: BackendFieldDefinition,
91
+ _allFields: Record<string, BackendFieldDefinition>
92
+ ): any {
93
+ const validation: any = {};
94
+
95
+ // Required validation
96
+ if (fieldDef.Required) {
97
+ validation.required = {
98
+ value: true,
99
+ message: `${generateLabel(fieldName)} is required`,
100
+ };
101
+ }
102
+
103
+ // Type-specific validation
104
+ switch (fieldDef.Type) {
105
+ case "Number":
106
+ validation.valueAsNumber = true;
107
+ break;
108
+
109
+ case "Date":
110
+ case "DateTime":
111
+ validation.valueAsDate = true;
112
+ break;
113
+ }
114
+
115
+ // Custom validation using expression trees
116
+ // Note: fieldDef.Validation contains rule IDs (string[]), not ValidationRule[]
117
+ // Validation is handled by the form hook which has access to the full schema rules
118
+ if (fieldDef.Validation && fieldDef.Validation.length > 0) {
119
+ // Validation rules will be applied by the form hook
120
+ // This is just a placeholder to mark that validation exists
121
+ validation.validate = () => true;
122
+ }
123
+
124
+ return validation;
125
+ }
126
+
127
+ // ============================================================
128
+ // SELECT OPTIONS PROCESSING
129
+ // ============================================================
130
+
131
+ /**
132
+ * Process field options for select/reference fields
133
+ */
134
+ function processFieldOptions(
135
+ fieldDef: BackendFieldDefinition
136
+ ): Array<{ value: any; label: string }> {
137
+ if (!fieldDef.Values) {
138
+ return [];
139
+ }
140
+
141
+ // Static options
142
+ if (fieldDef.Values.Mode === "Static" && fieldDef.Values.Items) {
143
+ return fieldDef.Values.Items.map((item: any) => ({
144
+ value: item.Value,
145
+ label: item.Label,
146
+ }));
147
+ }
148
+
149
+ // Dynamic options (reference field)
150
+ if (fieldDef.Values.Mode === "Dynamic" && fieldDef.Values.Reference) {
151
+ // For now, return empty array - will be populated by form hook
152
+ return [];
153
+ }
154
+
155
+ return [];
156
+ }
157
+
158
+ // ============================================================
159
+ // DEFAULT VALUE PROCESSING
160
+ // ============================================================
161
+
162
+ /**
163
+ * Calculate default value for a field
164
+ */
165
+ function processDefaultValue(
166
+ fieldDef: BackendFieldDefinition,
167
+ formValues: Record<string, any> = {}
168
+ ): any {
169
+ if (!fieldDef.DefaultValue) {
170
+ // Type-specific defaults
171
+ switch (fieldDef.Type) {
172
+ case "Boolean":
173
+ return false;
174
+ case "Number":
175
+ return 0;
176
+ case "String":
177
+ return "";
178
+ case "Array":
179
+ return [];
180
+ case "Object":
181
+ return {};
182
+ default:
183
+ return undefined;
184
+ }
185
+ }
186
+
187
+ return calculateDefaultValue(
188
+ fieldDef.DefaultValue.ExpressionTree,
189
+ formValues
190
+ );
191
+ }
192
+
193
+ // ============================================================
194
+ // FIELD PROCESSING
195
+ // ============================================================
196
+
197
+ /**
198
+ * Process a single field definition
199
+ */
200
+ function processField(
201
+ fieldName: string,
202
+ fieldDef: BackendFieldDefinition,
203
+ allFields: Record<string, BackendFieldDefinition>,
204
+ formValues: Record<string, any> = {},
205
+ permission?: FieldPermission,
206
+ rules?: {
207
+ validation: string[];
208
+ computation: string[];
209
+ businessLogic: string[];
210
+ }
211
+ ): ProcessedField {
212
+ const defaultPermission: FieldPermission = {
213
+ editable: true,
214
+ readable: true,
215
+ hidden: false,
216
+ };
217
+
218
+ const defaultRules = {
219
+ validation: [],
220
+ computation: [],
221
+ businessLogic: [],
222
+ };
223
+
224
+ const fieldRules = rules || defaultRules;
225
+ const isComputed =
226
+ fieldDef.Computed ||
227
+ !!fieldDef.Formula ||
228
+ fieldRules.computation.length > 0;
229
+
230
+ const validation = convertValidationRules(fieldName, fieldDef, allFields);
231
+
232
+ // Mark computed fields as disabled so they cannot be manually edited
233
+ if (isComputed) {
234
+ validation.disabled = true;
235
+ }
236
+
237
+ return {
238
+ name: fieldName,
239
+ type: mapFieldType(fieldDef.Type, fieldName) as any,
240
+ label: fieldDef.Name || generateLabel(fieldName),
241
+ required: fieldDef.Required || false,
242
+ computed: isComputed,
243
+ defaultValue: processDefaultValue(fieldDef, formValues),
244
+ options: processFieldOptions(fieldDef),
245
+ validation,
246
+ description: fieldDef.Description,
247
+ backendField: fieldDef,
248
+ permission: permission || defaultPermission,
249
+ rules: fieldRules,
250
+ };
251
+ }
252
+
253
+ // ============================================================
254
+ // SCHEMA PROCESSING
255
+ // ============================================================
256
+
257
+ /**
258
+ * Process complete backend schema
259
+ */
260
+ export function processSchema(
261
+ schema: BackendSchema | BDOSchema,
262
+ formValues: Record<string, any> = {},
263
+ userRole?: string
264
+ ): ProcessedSchema {
265
+ // Convert legacy schema to BDO format if needed
266
+ let bdoSchema =
267
+ "Kind" in schema && schema.Kind === "BusinessObject"
268
+ ? (schema as BDOSchema)
269
+ : convertLegacySchema(schema as BackendSchema);
270
+
271
+ // Normalize BDO schema to ensure inline validation rules are centralized
272
+ bdoSchema = normalizeBDOSchema(bdoSchema);
273
+
274
+ const fields: Record<string, ProcessedField> = {};
275
+ const fieldOrder: string[] = [];
276
+ const computedFields: string[] = [];
277
+ const requiredFields: string[] = [];
278
+ const crossFieldValidation: ValidationRule[] = [];
279
+
280
+ // Classify rules by type
281
+ const classifiedRules = classifyRules(bdoSchema);
282
+
283
+ // Create field-to-rule mapping
284
+ const fieldRules = createFieldRuleMapping(bdoSchema, classifiedRules);
285
+
286
+ // Calculate field permissions
287
+ const fieldPermissions = calculateFieldPermissions(bdoSchema, userRole);
288
+
289
+ // Process each field
290
+ for (const [fieldName, fieldDef] of Object.entries(bdoSchema.Fields)) {
291
+ // Skip system fields that shouldn't be in forms
292
+ if (fieldName.startsWith("_") && !["_id"].includes(fieldName)) {
293
+ continue;
294
+ }
295
+
296
+ // Skip hidden fields
297
+ const permission = fieldPermissions[fieldName];
298
+ if (permission.hidden) {
299
+ continue;
300
+ }
301
+
302
+ const processedField = processField(
303
+ fieldName,
304
+ fieldDef,
305
+ bdoSchema.Fields,
306
+ formValues,
307
+ permission,
308
+ fieldRules[fieldName] || {
309
+ validation: [],
310
+ computation: [],
311
+ businessLogic: [],
312
+ }
313
+ );
314
+
315
+ fields[fieldName] = processedField;
316
+ fieldOrder.push(fieldName);
317
+
318
+ if (processedField.computed) {
319
+ computedFields.push(fieldName);
320
+ }
321
+
322
+ if (processedField.required) {
323
+ requiredFields.push(fieldName);
324
+ }
325
+ }
326
+
327
+ return {
328
+ fields,
329
+ fieldOrder,
330
+ computedFields,
331
+ requiredFields,
332
+ crossFieldValidation,
333
+ rules: classifiedRules,
334
+ fieldRules,
335
+ rolePermissions: bdoSchema.RolePermission,
336
+ };
337
+ }
338
+
339
+ // ============================================================
340
+ // COMPUTED FIELD UPDATES
341
+ // ============================================================
342
+
343
+ /**
344
+ * Update computed field values based on current form values
345
+ */
346
+ export function updateComputedFields(
347
+ processedSchema: ProcessedSchema,
348
+ currentValues: Record<string, any>
349
+ ): Record<string, any> {
350
+ const computedValues: Record<string, any> = {};
351
+
352
+ for (const fieldName of processedSchema.computedFields) {
353
+ const field = processedSchema.fields[fieldName];
354
+ const backendField = field.backendField;
355
+
356
+ if (backendField.Formula) {
357
+ try {
358
+ const computedValue = calculateComputedValue(
359
+ backendField.Formula.ExpressionTree,
360
+ currentValues
361
+ );
362
+
363
+ computedValues[fieldName] = computedValue;
364
+ } catch (error) {
365
+ console.warn(`Failed to compute value for ${fieldName}:`, error);
366
+ }
367
+ }
368
+ }
369
+
370
+ return computedValues;
371
+ }
372
+
373
+ // ============================================================
374
+ // FIELD DEPENDENCIES
375
+ // ============================================================
376
+
377
+ /**
378
+ * Extract field dependencies from expression trees
379
+ */
380
+ function extractFieldDependencies(expressionTree: any): string[] {
381
+ const dependencies: Set<string> = new Set();
382
+
383
+ function traverse(node: any): void {
384
+ if (!node || typeof node !== "object") {
385
+ return;
386
+ }
387
+
388
+ if (node.Type === "Identifier" && node.Name) {
389
+ dependencies.add(node.Name);
390
+ }
391
+
392
+ if (node.Arguments && Array.isArray(node.Arguments)) {
393
+ node.Arguments.forEach(traverse);
394
+ }
395
+
396
+ if (node.Property) {
397
+ traverse(node.Property);
398
+ }
399
+ }
400
+
401
+ traverse(expressionTree);
402
+ return Array.from(dependencies);
403
+ }
404
+
405
+ /**
406
+ * Build field dependency map
407
+ */
408
+ export function buildDependencyMap(
409
+ processedSchema: ProcessedSchema
410
+ ): Record<string, string[]> {
411
+ const dependencyMap: Record<string, string[]> = {};
412
+
413
+ for (const [fieldName, field] of Object.entries(processedSchema.fields)) {
414
+ const dependencies: Set<string> = new Set();
415
+
416
+ // Check formula dependencies
417
+ if (field.backendField.Formula) {
418
+ const formulaDeps = extractFieldDependencies(
419
+ field.backendField.Formula.ExpressionTree
420
+ );
421
+ formulaDeps.forEach((dep) => dependencies.add(dep));
422
+ }
423
+
424
+ // Check validation dependencies
425
+ // Note: field.backendField.Validation contains rule IDs (string[])
426
+ // To extract validation dependencies, we would need access to the full schema rules
427
+ // This is skipped for now as validation dependencies are tracked separately
428
+ if (field.backendField.Validation) {
429
+ // Validation rule dependencies would be extracted here if we had access to the rules
430
+ }
431
+
432
+ // Check default value dependencies
433
+ if (field.backendField.DefaultValue) {
434
+ const defaultDeps = extractFieldDependencies(
435
+ field.backendField.DefaultValue.ExpressionTree
436
+ );
437
+ defaultDeps.forEach((dep) => dependencies.add(dep));
438
+ }
439
+
440
+ dependencyMap[fieldName] = Array.from(dependencies);
441
+ }
442
+
443
+ return dependencyMap;
444
+ }
445
+
446
+ // ============================================================
447
+ // VALIDATION HELPERS
448
+ // ============================================================
449
+
450
+ /**
451
+ * Validate processed schema
452
+ */
453
+ export function validateSchema(processedSchema: ProcessedSchema): {
454
+ isValid: boolean;
455
+ errors: string[];
456
+ } {
457
+ const errors: string[] = [];
458
+
459
+ // Check for required fields
460
+ if (processedSchema.fieldOrder.length === 0) {
461
+ errors.push("Schema contains no fields");
462
+ }
463
+
464
+ // Check for circular dependencies in computed fields
465
+ const dependencyMap = buildDependencyMap(processedSchema);
466
+
467
+ for (const [fieldName, dependencies] of Object.entries(dependencyMap)) {
468
+ if (dependencies.includes(fieldName)) {
469
+ errors.push(`Field ${fieldName} has circular dependency`);
470
+ }
471
+ }
472
+
473
+ return {
474
+ isValid: errors.length === 0,
475
+ errors,
476
+ };
477
+ }
478
+
479
+ // ============================================================
480
+ // REFERENCE FIELD PROCESSING
481
+ // ============================================================
482
+
483
+ /**
484
+ * Build reference field configuration for API calls
485
+ */
486
+ export function buildReferenceFieldConfig(field: ProcessedField): any {
487
+ if (field.type !== "reference" || !field.backendField.Values?.Reference) {
488
+ return null;
489
+ }
490
+
491
+ const ref = field.backendField.Values.Reference;
492
+
493
+ return {
494
+ businessObject: ref.BusinessObject,
495
+ fields: ref.Fields || ["_id"], // Default to ID field
496
+ filters: ref.Filters,
497
+ sort: ref.Sort,
498
+ };
499
+ }
500
+
501
+ /**
502
+ * Extract all reference field configurations from schema
503
+ */
504
+ export function extractReferenceFields(
505
+ processedSchema: ProcessedSchema
506
+ ): Record<string, any> {
507
+ const referenceFields: Record<string, any> = {};
508
+
509
+ for (const [fieldName, field] of Object.entries(processedSchema.fields)) {
510
+ if (field.type === "reference") {
511
+ const config = buildReferenceFieldConfig(field);
512
+ if (config) {
513
+ referenceFields[fieldName] = config;
514
+ }
515
+ }
516
+ }
517
+
518
+ return referenceFields;
519
+ }