@ram_28/kf-ai-sdk 1.0.8 → 1.0.10

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 (29) hide show
  1. package/dist/components/hooks/index.d.ts +2 -1
  2. package/dist/components/hooks/index.d.ts.map +1 -1
  3. package/dist/components/hooks/useForm/apiClient.d.ts +4 -4
  4. package/dist/components/hooks/useForm/apiClient.d.ts.map +1 -1
  5. package/dist/components/hooks/useForm/expressionValidator.utils.d.ts +3 -3
  6. package/dist/components/hooks/useForm/expressionValidator.utils.d.ts.map +1 -1
  7. package/dist/components/hooks/useForm/index.d.ts +7 -4
  8. package/dist/components/hooks/useForm/index.d.ts.map +1 -1
  9. package/dist/components/hooks/useForm/optimizedExpressionValidator.utils.d.ts +5 -5
  10. package/dist/components/hooks/useForm/optimizedExpressionValidator.utils.d.ts.map +1 -1
  11. package/dist/components/hooks/useForm/ruleClassifier.utils.d.ts +7 -6
  12. package/dist/components/hooks/useForm/ruleClassifier.utils.d.ts.map +1 -1
  13. package/dist/components/hooks/useForm/schemaParser.utils.d.ts +8 -8
  14. package/dist/components/hooks/useForm/schemaParser.utils.d.ts.map +1 -1
  15. package/dist/components/hooks/useForm/types.d.ts +130 -112
  16. package/dist/components/hooks/useForm/types.d.ts.map +1 -1
  17. package/dist/components/hooks/useForm/useForm.d.ts.map +1 -1
  18. package/dist/index.cjs +13 -13
  19. package/dist/index.mjs +2082 -2067
  20. package/package.json +1 -1
  21. package/sdk/components/hooks/index.ts +24 -4
  22. package/sdk/components/hooks/useForm/apiClient.ts +5 -5
  23. package/sdk/components/hooks/useForm/expressionValidator.utils.ts +11 -11
  24. package/sdk/components/hooks/useForm/index.ts +41 -45
  25. package/sdk/components/hooks/useForm/optimizedExpressionValidator.utils.ts +7 -7
  26. package/sdk/components/hooks/useForm/ruleClassifier.utils.ts +21 -20
  27. package/sdk/components/hooks/useForm/schemaParser.utils.ts +36 -41
  28. package/sdk/components/hooks/useForm/types.ts +156 -141
  29. package/sdk/components/hooks/useForm/useForm.ts +155 -142
@@ -11,9 +11,9 @@ import type { Path } from "react-hook-form";
11
11
  import type {
12
12
  UseFormOptions,
13
13
  UseFormReturn,
14
- BackendSchema,
15
- ProcessedSchema,
16
- ProcessedField,
14
+ BDOSchema,
15
+ FormSchemaConfig,
16
+ FormFieldConfig,
17
17
  } from "./types";
18
18
 
19
19
  import { processSchema, extractReferenceFields } from "./schemaParser.utils";
@@ -49,10 +49,7 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
49
49
  mode = "onBlur", // Validation mode - controls when errors are shown (see types.ts for details)
50
50
  enabled = true,
51
51
  userRole,
52
- onSuccess,
53
- onError,
54
52
  onSchemaError,
55
- onSubmitError,
56
53
  skipSchemaFetch = false,
57
54
  schema: manualSchema,
58
55
  draftOnEveryChange = false,
@@ -62,10 +59,9 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
62
59
  // STATE MANAGEMENT
63
60
  // ============================================================
64
61
 
65
- const [processedSchema, setProcessedSchema] =
66
- useState<ProcessedSchema | null>(null);
62
+ const [schemaConfig, setSchemaConfig] =
63
+ useState<FormSchemaConfig | null>(null);
67
64
  const [referenceData, setReferenceData] = useState<Record<string, any[]>>({});
68
- const [submitError, setSubmitError] = useState<Error | null>(null);
69
65
  const [isSubmitting, setIsSubmitting] = useState(false);
70
66
  const [lastFormValues] = useState<Partial<T>>({});
71
67
 
@@ -77,25 +73,10 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
77
73
  // This allows us to detect changes since the last draft, not since form init
78
74
  const lastSyncedValuesRef = useRef<Partial<T> | null>(null);
79
75
 
80
- // Stable callback refs to prevent dependency loops
81
- const onSuccessRef = useRef(onSuccess);
82
- const onErrorRef = useRef(onError);
83
- const onSubmitErrorRef = useRef(onSubmitError);
76
+ // Stable callback ref to prevent dependency loops
84
77
  const onSchemaErrorRef = useRef(onSchemaError);
85
78
 
86
- // Update refs when callbacks change
87
- useEffect(() => {
88
- onSuccessRef.current = onSuccess;
89
- }, [onSuccess]);
90
-
91
- useEffect(() => {
92
- onErrorRef.current = onError;
93
- }, [onError]);
94
-
95
- useEffect(() => {
96
- onSubmitErrorRef.current = onSubmitError;
97
- }, [onSubmitError]);
98
-
79
+ // Update ref when callback changes
99
80
  useEffect(() => {
100
81
  onSchemaErrorRef.current = onSchemaError;
101
82
  }, [onSchemaError]);
@@ -153,8 +134,8 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
153
134
  }
154
135
 
155
136
  // Apply default values from schema
156
- if (processedSchema) {
157
- for (const [fieldName, field] of Object.entries(processedSchema.fields)) {
137
+ if (schemaConfig) {
138
+ for (const [fieldName, field] of Object.entries(schemaConfig.fields)) {
158
139
  if (field.defaultValue !== undefined && !(fieldName in values)) {
159
140
  (values as any)[fieldName] = field.defaultValue;
160
141
  }
@@ -162,7 +143,7 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
162
143
  }
163
144
 
164
145
  return values;
165
- }, [defaultValues, recordData, operation, processedSchema]);
146
+ }, [defaultValues, recordData, operation, schemaConfig]);
166
147
 
167
148
  const rhfForm = useReactHookForm<T>({
168
149
  mode,
@@ -185,7 +166,7 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
185
166
  {}, // Pass empty object - validation functions get live values from react-hook-form
186
167
  userRole
187
168
  );
188
- setProcessedSchema(processed);
169
+ setSchemaConfig(processed);
189
170
 
190
171
  // Fetch reference data for reference fields
191
172
  const refFields = extractReferenceFields(processed);
@@ -201,40 +182,34 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
201
182
  }
202
183
  }, [schema, userRole]); // Removed onSchemaError - using ref instead
203
184
 
204
- // Handle schema and record errors
185
+ // Handle schema error
205
186
  useEffect(() => {
206
187
  if (schemaError) {
207
188
  onSchemaErrorRef.current?.(schemaError);
208
189
  }
209
190
  }, [schemaError]);
210
191
 
211
- useEffect(() => {
212
- if (recordError) {
213
- onErrorRef.current?.(recordError);
214
- }
215
- }, [recordError]);
216
-
217
192
  // ============================================================
218
193
  // COMPUTED FIELD DEPENDENCY TRACKING AND OPTIMIZATION
219
194
  // ============================================================
220
195
 
221
196
  // Extract computed field dependencies using optimized analyzer
222
197
  const computedFieldDependencies = useMemo(() => {
223
- if (!processedSchema) return [];
198
+ if (!schemaConfig) return [];
224
199
 
225
200
  const dependencies = new Set<string>();
226
- const computedFieldNames = new Set(processedSchema.computedFields);
201
+ const computedFieldNames = new Set(schemaConfig.computedFields);
227
202
 
228
203
  // Analyze dependencies from computation rules
229
- Object.entries(processedSchema.fieldRules).forEach(([fieldName, rules]) => {
204
+ Object.entries(schemaConfig.fieldRules).forEach(([fieldName, rules]) => {
230
205
  rules.computation.forEach((ruleId) => {
231
- const rule = processedSchema.rules.computation[ruleId];
206
+ const rule = schemaConfig.rules.computation[ruleId];
232
207
  if (rule?.ExpressionTree) {
233
208
  const ruleDeps = getFieldDependencies(rule.ExpressionTree);
234
209
  ruleDeps.forEach((dep) => {
235
210
  // Only add non-computed fields as dependencies
236
211
  if (
237
- processedSchema.fields[dep] &&
212
+ schemaConfig.fields[dep] &&
238
213
  dep !== fieldName &&
239
214
  !computedFieldNames.has(dep)
240
215
  ) {
@@ -246,16 +221,16 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
246
221
  });
247
222
 
248
223
  // Also check formulas (legacy support)
249
- processedSchema.computedFields.forEach((fieldName: string) => {
250
- const field = processedSchema.fields[fieldName];
251
- if (field.backendField.Formula) {
224
+ schemaConfig.computedFields.forEach((fieldName: string) => {
225
+ const field = schemaConfig.fields[fieldName];
226
+ if (field._bdoField.Formula) {
252
227
  const fieldDeps = getFieldDependencies(
253
- field.backendField.Formula.ExpressionTree
228
+ field._bdoField.Formula.ExpressionTree
254
229
  );
255
230
  fieldDeps.forEach((dep) => {
256
231
  // Only add non-computed fields as dependencies
257
232
  if (
258
- processedSchema.fields[dep] &&
233
+ schemaConfig.fields[dep] &&
259
234
  dep !== fieldName &&
260
235
  !computedFieldNames.has(dep)
261
236
  ) {
@@ -266,7 +241,7 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
266
241
  });
267
242
 
268
243
  return Array.from(dependencies) as Array<Path<T>>;
269
- }, [processedSchema]);
244
+ }, [schemaConfig]);
270
245
 
271
246
  // Watch dependencies are tracked but not used for automatic computation
272
247
  // Computation is triggered manually on blur after validation passes
@@ -278,7 +253,7 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
278
253
  // Manual computation trigger - called on blur after validation passes
279
254
  const triggerComputationAfterValidation = useCallback(
280
255
  async (fieldName: string) => {
281
- if (!processedSchema || computedFieldDependencies.length === 0) {
256
+ if (!schemaConfig || computedFieldDependencies.length === 0) {
282
257
  return;
283
258
  }
284
259
 
@@ -305,7 +280,7 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
305
280
 
306
281
  computeTimeoutRef.current = setTimeout(() => {
307
282
  // Additional safety check
308
- if (!processedSchema) return;
283
+ if (!schemaConfig) return;
309
284
 
310
285
  // Prevent concurrent API calls
311
286
  if (isComputingRef.current) {
@@ -338,7 +313,7 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
338
313
 
339
314
  // Get computed field names to exclude from payload
340
315
  const computedFieldNames = new Set(
341
- processedSchema.computedFields || []
316
+ schemaConfig.computedFields || []
342
317
  );
343
318
 
344
319
  // Find fields that changed from baseline (excluding computed fields)
@@ -430,7 +405,7 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
430
405
  }, 300); // 300ms debounce
431
406
  },
432
407
  [
433
- processedSchema,
408
+ schemaConfig,
434
409
  operation,
435
410
  recordId,
436
411
  recordData,
@@ -446,7 +421,7 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
446
421
  // ============================================================
447
422
 
448
423
  const validateForm = useCallback(async (): Promise<boolean> => {
449
- if (!processedSchema) {
424
+ if (!schemaConfig) {
450
425
  return false;
451
426
  }
452
427
 
@@ -460,7 +435,7 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
460
435
 
461
436
  // Cross-field validation
462
437
  // Transform ValidationRule[] to the format expected by validateCrossField
463
- const transformedRules = processedSchema.crossFieldValidation.map(
438
+ const transformedRules = schemaConfig.crossFieldValidation.map(
464
439
  (rule) => ({
465
440
  Id: rule.Id,
466
441
  Condition: { ExpressionTree: rule.ExpressionTree },
@@ -487,7 +462,7 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
487
462
 
488
463
  return true;
489
464
  }, [
490
- processedSchema,
465
+ schemaConfig,
491
466
  rhfForm.getValues,
492
467
  rhfForm.trigger,
493
468
  rhfForm.setError,
@@ -495,122 +470,163 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
495
470
  ]);
496
471
 
497
472
  // ============================================================
498
- // FORM SUBMISSION
473
+ // HANDLE SUBMIT - RHF-style API with internal submission
499
474
  // ============================================================
500
475
 
501
- const submit = useCallback(async (): Promise<void> => {
502
- if (!processedSchema) {
503
- throw new Error("Schema not loaded");
504
- }
505
-
506
- setIsSubmitting(true);
507
- setSubmitError(null);
476
+ /**
477
+ * handleSubmit follows React Hook Form's signature pattern:
478
+ *
479
+ * handleSubmit(onSuccess?, onError?) => (e?) => Promise<void>
480
+ *
481
+ * Internal flow:
482
+ * 1. RHF validation + Cross-field validation → FAILS → onError(fieldErrors)
483
+ * 2. Clean data & call API → FAILS → onError(apiError)
484
+ * 3. SUCCESS → onSuccess(responseData)
485
+ */
486
+ const handleSubmit = useCallback(
487
+ (
488
+ onSuccess?: (data: T, e?: React.BaseSyntheticEvent) => void | Promise<void>,
489
+ onError?: (
490
+ error: import("react-hook-form").FieldErrors<T> | Error,
491
+ e?: React.BaseSyntheticEvent
492
+ ) => void | Promise<void>
493
+ ) => {
494
+ return rhfForm.handleSubmit(
495
+ // RHF onValid handler - validation passed, now do cross-field + API
496
+ async (data, event) => {
497
+ if (!schemaConfig) {
498
+ const error = new Error("Schema not loaded");
499
+ onError?.(error, event);
500
+ return;
501
+ }
508
502
 
509
- try {
510
- // Validate form including cross-field validation
511
- const isValid = await validateForm();
512
- if (!isValid) {
513
- throw new Error("Form validation failed");
514
- }
503
+ setIsSubmitting(true);
515
504
 
516
- const formValues = rhfForm.getValues();
505
+ try {
506
+ // Cross-field validation
507
+ const transformedRules = schemaConfig.crossFieldValidation.map(
508
+ (rule) => ({
509
+ Id: rule.Id,
510
+ Condition: { ExpressionTree: rule.ExpressionTree },
511
+ Message: rule.Message || `Validation failed for ${rule.Name}`,
512
+ })
513
+ );
517
514
 
518
- // Clean data for submission
519
- // - For create: includes all non-computed fields
520
- // - For update: includes only fields that changed from recordData
521
- const cleanedData = cleanFormData(
522
- formValues as any,
523
- processedSchema.computedFields,
524
- operation,
525
- recordData as Partial<T> | undefined
526
- );
515
+ const crossFieldErrors = validateCrossField(
516
+ transformedRules,
517
+ data as any,
518
+ referenceData
519
+ );
527
520
 
528
- // Submit data
529
- const result = await submitFormData<T>(
530
- source,
531
- operation,
532
- cleanedData,
533
- recordId
534
- );
521
+ if (crossFieldErrors.length > 0) {
522
+ // Set cross-field errors in form state
523
+ crossFieldErrors.forEach((error, index) => {
524
+ rhfForm.setError(`root.crossField${index}` as any, {
525
+ type: "validate",
526
+ message: error.message,
527
+ });
528
+ });
529
+ // Call onError with current form errors
530
+ onError?.(rhfForm.formState.errors, event);
531
+ return;
532
+ }
535
533
 
536
- if (!result.success) {
537
- throw result.error || new Error("Submission failed");
538
- }
534
+ // Clean data for submission
535
+ const cleanedData = cleanFormData(
536
+ data as any,
537
+ schemaConfig.computedFields,
538
+ operation,
539
+ recordData as Partial<T> | undefined
540
+ );
539
541
 
540
- // Success callback
541
- onSuccessRef.current?.(result.data || formValues);
542
+ // Submit data to API
543
+ const result = await submitFormData<T>(
544
+ source,
545
+ operation,
546
+ cleanedData,
547
+ recordId
548
+ );
542
549
 
543
- // Reset form for create operations
544
- if (operation === "create") {
545
- rhfForm.reset();
546
- }
547
- } catch (error) {
548
- const submitError = error as Error;
549
- setSubmitError(submitError);
550
- onSubmitErrorRef.current?.(submitError);
551
- onErrorRef.current?.(submitError);
552
- throw error;
553
- } finally {
554
- setIsSubmitting(false);
555
- }
556
- }, [processedSchema, validateForm, rhfForm, source, operation, recordId, recordData]);
550
+ if (!result.success) {
551
+ throw result.error || new Error("Submission failed");
552
+ }
557
553
 
558
- // ============================================================
559
- // HANDLE SUBMIT - Simplified API
560
- // ============================================================
554
+ // Reset form for create operations
555
+ if (operation === "create") {
556
+ rhfForm.reset();
557
+ }
561
558
 
562
- // Simplified handleSubmit that always uses SDK's submit function
563
- const handleSubmit = useCallback(() => {
564
- return rhfForm.handleSubmit(async () => {
565
- await submit();
566
- });
567
- }, [rhfForm, submit]);
559
+ // Success callback with response data
560
+ await onSuccess?.(result.data || data, event);
561
+ } catch (error) {
562
+ // API error - call onError with Error object
563
+ onError?.(error as Error, event);
564
+ } finally {
565
+ setIsSubmitting(false);
566
+ }
567
+ },
568
+ // RHF onInvalid handler - validation failed
569
+ (errors, event) => {
570
+ onError?.(errors, event);
571
+ }
572
+ );
573
+ },
574
+ [
575
+ rhfForm,
576
+ schemaConfig,
577
+ referenceData,
578
+ source,
579
+ operation,
580
+ recordId,
581
+ recordData,
582
+ ]
583
+ );
568
584
 
569
585
  // ============================================================
570
586
  // FIELD HELPERS
571
587
  // ============================================================
572
588
 
573
589
  const getField = useCallback(
574
- <K extends keyof T>(fieldName: K): ProcessedField | null => {
575
- return processedSchema?.fields[fieldName as string] || null;
590
+ <K extends keyof T>(fieldName: K): FormFieldConfig | null => {
591
+ return schemaConfig?.fields[fieldName as string] || null;
576
592
  },
577
- [processedSchema]
593
+ [schemaConfig]
578
594
  );
579
595
 
580
- const getFields = useCallback((): Record<keyof T, ProcessedField> => {
581
- if (!processedSchema) return {} as Record<keyof T, ProcessedField>;
596
+ const getFields = useCallback((): Record<keyof T, FormFieldConfig> => {
597
+ if (!schemaConfig) return {} as Record<keyof T, FormFieldConfig>;
582
598
 
583
- const typedFields: Record<keyof T, ProcessedField> = {} as any;
584
- Object.entries(processedSchema.fields).forEach(([key, field]) => {
599
+ const typedFields: Record<keyof T, FormFieldConfig> = {} as any;
600
+ Object.entries(schemaConfig.fields).forEach(([key, field]) => {
585
601
  (typedFields as any)[key] = field;
586
602
  });
587
603
 
588
604
  return typedFields;
589
- }, [processedSchema]);
605
+ }, [schemaConfig]);
590
606
 
591
607
  const hasField = useCallback(
592
608
  <K extends keyof T>(fieldName: K): boolean => {
593
- return !!processedSchema?.fields[fieldName as string];
609
+ return !!schemaConfig?.fields[fieldName as string];
594
610
  },
595
- [processedSchema]
611
+ [schemaConfig]
596
612
  );
597
613
 
598
614
  const isFieldRequired = useCallback(
599
615
  <K extends keyof T>(fieldName: K): boolean => {
600
616
  return (
601
- processedSchema?.requiredFields.includes(fieldName as string) || false
617
+ schemaConfig?.requiredFields.includes(fieldName as string) || false
602
618
  );
603
619
  },
604
- [processedSchema]
620
+ [schemaConfig]
605
621
  );
606
622
 
607
623
  const isFieldComputed = useCallback(
608
624
  <K extends keyof T>(fieldName: K): boolean => {
609
625
  return (
610
- processedSchema?.computedFields.includes(fieldName as string) || false
626
+ schemaConfig?.computedFields.includes(fieldName as string) || false
611
627
  );
612
628
  },
613
- [processedSchema]
629
+ [schemaConfig]
614
630
  );
615
631
 
616
632
  // ============================================================
@@ -623,7 +639,6 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
623
639
 
624
640
  const clearErrors = useCallback((): void => {
625
641
  rhfForm.clearErrors();
626
- setSubmitError(null);
627
642
  }, [rhfForm]);
628
643
 
629
644
  // ============================================================
@@ -634,16 +649,16 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
634
649
  isLoadingSchema || (operation === "update" && isLoadingRecord);
635
650
  const isLoading = isLoadingInitialData || isSubmitting;
636
651
  const loadError = schemaError || recordError;
637
- const hasError = !!(loadError || submitError);
652
+ const hasError = !!loadError;
638
653
 
639
654
  const computedFields = useMemo<Array<keyof T>>(
640
- () => (processedSchema?.computedFields as Array<keyof T>) || [],
641
- [processedSchema]
655
+ () => (schemaConfig?.computedFields as Array<keyof T>) || [],
656
+ [schemaConfig]
642
657
  );
643
658
 
644
659
  const requiredFields = useMemo<Array<keyof T>>(
645
- () => (processedSchema?.requiredFields as Array<keyof T>) || [],
646
- [processedSchema]
660
+ () => (schemaConfig?.requiredFields as Array<keyof T>) || [],
661
+ [schemaConfig]
647
662
  );
648
663
 
649
664
  // ============================================================
@@ -652,11 +667,11 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
652
667
 
653
668
  // Create validation rules from processed schema (client-side only)
654
669
  const validationRules = useMemo(() => {
655
- if (!processedSchema) return {};
670
+ if (!schemaConfig) return {};
656
671
 
657
672
  const rules: Record<string, any> = {};
658
673
 
659
- Object.entries(processedSchema.fields).forEach(([fieldName, field]) => {
674
+ Object.entries(schemaConfig.fields).forEach(([fieldName, field]) => {
660
675
  const fieldRules: any = {};
661
676
 
662
677
  // Required validation
@@ -689,7 +704,7 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
689
704
 
690
705
  // Execute client-side validation rules with optimization
691
706
  for (const ruleId of validationRuleIds) {
692
- const rule = processedSchema.rules.validation[ruleId];
707
+ const rule = schemaConfig.rules.validation[ruleId];
693
708
  if (rule) {
694
709
  const result = validateFieldOptimized<T>(
695
710
  fieldName,
@@ -712,7 +727,7 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
712
727
  });
713
728
 
714
729
  return rules;
715
- }, [processedSchema, rhfForm, referenceData]);
730
+ }, [schemaConfig, rhfForm, referenceData]);
716
731
 
717
732
  /**
718
733
  * Enhanced register function that wraps react-hook-form's register
@@ -796,12 +811,11 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
796
811
 
797
812
  // Error handling
798
813
  loadError: loadError as Error | null,
799
- submitError,
800
814
  hasError,
801
815
 
802
816
  // Schema information
803
- schema: schema as BackendSchema | null,
804
- processedSchema,
817
+ schema: schema as BDOSchema | null,
818
+ schemaConfig,
805
819
  computedFields,
806
820
  requiredFields,
807
821
 
@@ -813,7 +827,6 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
813
827
  isFieldComputed,
814
828
 
815
829
  // Operations
816
- submit,
817
830
  refreshSchema,
818
831
  validateForm,
819
832
  clearErrors,