@octanejs/hook-form 0.1.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 (112) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -0
  3. package/package.json +46 -0
  4. package/src/FormProvider.tsrx +76 -0
  5. package/src/FormProvider.tsrx.d.ts +10 -0
  6. package/src/constants.ts +31 -0
  7. package/src/controller.tsrx +8 -0
  8. package/src/controller.tsrx.d.ts +52 -0
  9. package/src/form.tsrx +119 -0
  10. package/src/form.tsrx.d.ts +6 -0
  11. package/src/formStateSubscribe.tsrx +10 -0
  12. package/src/formStateSubscribe.tsrx.d.ts +16 -0
  13. package/src/index.ts +19 -0
  14. package/src/logic/appendErrors.ts +19 -0
  15. package/src/logic/createFormControl.ts +1841 -0
  16. package/src/logic/generateId.ts +14 -0
  17. package/src/logic/generateWatchOutput.ts +27 -0
  18. package/src/logic/getCheckboxValue.ts +36 -0
  19. package/src/logic/getDirtyFields.ts +120 -0
  20. package/src/logic/getEventValue.ts +12 -0
  21. package/src/logic/getFieldValue.ts +33 -0
  22. package/src/logic/getFieldValueAs.ts +22 -0
  23. package/src/logic/getFocusFieldName.ts +13 -0
  24. package/src/logic/getNodeParentName.ts +4 -0
  25. package/src/logic/getProxyFormState.ts +33 -0
  26. package/src/logic/getRadioValue.ts +24 -0
  27. package/src/logic/getResolverOptions.ts +33 -0
  28. package/src/logic/getRuleValue.ts +16 -0
  29. package/src/logic/getValidateError.ts +22 -0
  30. package/src/logic/getValidationModes.ts +11 -0
  31. package/src/logic/getValueAndMessage.ts +12 -0
  32. package/src/logic/hasPromiseValidation.ts +27 -0
  33. package/src/logic/hasValidation.ts +12 -0
  34. package/src/logic/index.ts +3 -0
  35. package/src/logic/isNameInFieldArray.ts +7 -0
  36. package/src/logic/isWatched.ts +11 -0
  37. package/src/logic/iterateFieldsByAction.ts +37 -0
  38. package/src/logic/schemaErrorLookup.ts +54 -0
  39. package/src/logic/shouldRenderFormState.ts +25 -0
  40. package/src/logic/shouldSubscribeByName.ts +18 -0
  41. package/src/logic/skipValidation.ts +21 -0
  42. package/src/logic/unsetEmptyArray.ts +6 -0
  43. package/src/logic/updateFieldArrayRootError.ts +17 -0
  44. package/src/logic/validateField.ts +273 -0
  45. package/src/types/controller.ts +98 -0
  46. package/src/types/errors.ts +56 -0
  47. package/src/types/events.ts +26 -0
  48. package/src/types/fieldArray.ts +288 -0
  49. package/src/types/fields.ts +46 -0
  50. package/src/types/form.ts +961 -0
  51. package/src/types/index.ts +12 -0
  52. package/src/types/path/common.ts +391 -0
  53. package/src/types/path/eager.ts +224 -0
  54. package/src/types/path/index.ts +16 -0
  55. package/src/types/resolvers.ts +38 -0
  56. package/src/types/utils.ts +125 -0
  57. package/src/types/validator.ts +94 -0
  58. package/src/types/watch.ts +66 -0
  59. package/src/useController.ts +268 -0
  60. package/src/useFieldArray.ts +490 -0
  61. package/src/useForm.ts +182 -0
  62. package/src/useFormContext.ts +47 -0
  63. package/src/useFormControlContext.ts +25 -0
  64. package/src/useFormState.ts +86 -0
  65. package/src/useIsomorphicLayoutEffect.ts +6 -0
  66. package/src/useWatch.ts +356 -0
  67. package/src/utils/append.ts +4 -0
  68. package/src/utils/cloneObject.ts +32 -0
  69. package/src/utils/compact.ts +2 -0
  70. package/src/utils/convertToArrayPayload.ts +2 -0
  71. package/src/utils/createSubject.ts +48 -0
  72. package/src/utils/deepEqual.ts +81 -0
  73. package/src/utils/deepMerge.ts +27 -0
  74. package/src/utils/extractFormValues.ts +28 -0
  75. package/src/utils/fillEmptyArray.ts +3 -0
  76. package/src/utils/flatten.ts +23 -0
  77. package/src/utils/get.ts +29 -0
  78. package/src/utils/index.ts +3 -0
  79. package/src/utils/insert.ts +8 -0
  80. package/src/utils/isBoolean.ts +2 -0
  81. package/src/utils/isCheckBoxInput.ts +4 -0
  82. package/src/utils/isDateObject.ts +2 -0
  83. package/src/utils/isEmptyObject.ts +7 -0
  84. package/src/utils/isFileInput.ts +4 -0
  85. package/src/utils/isFunction.ts +2 -0
  86. package/src/utils/isHTMLElement.ts +13 -0
  87. package/src/utils/isKey.ts +4 -0
  88. package/src/utils/isMultipleSelect.ts +5 -0
  89. package/src/utils/isNullOrUndefined.ts +2 -0
  90. package/src/utils/isObject.ts +8 -0
  91. package/src/utils/isPlainObject.ts +8 -0
  92. package/src/utils/isPrimitive.ts +8 -0
  93. package/src/utils/isRadioInput.ts +4 -0
  94. package/src/utils/isRadioOrCheckbox.ts +8 -0
  95. package/src/utils/isRegex.ts +2 -0
  96. package/src/utils/isString.ts +2 -0
  97. package/src/utils/isUndefined.ts +2 -0
  98. package/src/utils/isWeb.ts +4 -0
  99. package/src/utils/live.ts +6 -0
  100. package/src/utils/move.ts +15 -0
  101. package/src/utils/noop.ts +2 -0
  102. package/src/utils/objectHasFunction.ts +11 -0
  103. package/src/utils/prepend.ts +7 -0
  104. package/src/utils/remove.ts +24 -0
  105. package/src/utils/set.ts +36 -0
  106. package/src/utils/sleep.ts +2 -0
  107. package/src/utils/stringToPath.ts +4 -0
  108. package/src/utils/swap.ts +4 -0
  109. package/src/utils/unset.ts +65 -0
  110. package/src/utils/update.ts +5 -0
  111. package/src/watch.tsrx +7 -0
  112. package/src/watch.tsrx.d.ts +42 -0
@@ -0,0 +1,14 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/generateId.ts (octane port).
2
+ export default () => {
3
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
4
+ return crypto.randomUUID();
5
+ }
6
+
7
+ const d = typeof performance === 'undefined' ? Date.now() : performance.now() * 1000;
8
+
9
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
10
+ const r = ((Math.random() * 16 + d) % 16) | 0;
11
+
12
+ return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16);
13
+ });
14
+ };
@@ -0,0 +1,27 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/generateWatchOutput.ts (octane port).
2
+ import type { DeepPartial, FieldValues, Names } from '../types';
3
+ import get from '../utils/get';
4
+ import isString from '../utils/isString';
5
+
6
+ export default <T>(
7
+ names: string | string[] | undefined,
8
+ _names: Names,
9
+ formValues?: FieldValues,
10
+ isGlobal?: boolean,
11
+ defaultValue?: DeepPartial<T> | unknown,
12
+ ) => {
13
+ if (isString(names)) {
14
+ isGlobal && _names.watch.add(names);
15
+ return get(formValues, names, defaultValue);
16
+ }
17
+
18
+ if (Array.isArray(names)) {
19
+ return names.map(
20
+ (fieldName) => (isGlobal && _names.watch.add(fieldName), get(formValues, fieldName)),
21
+ );
22
+ }
23
+
24
+ isGlobal && (_names.watchAll = true);
25
+
26
+ return formValues;
27
+ };
@@ -0,0 +1,36 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/getCheckboxValue.ts (octane port).
2
+ import isUndefined from '../utils/isUndefined';
3
+
4
+ type CheckboxFieldResult = {
5
+ isValid: boolean;
6
+ value: string | string[] | boolean | undefined;
7
+ };
8
+
9
+ const defaultResult: CheckboxFieldResult = {
10
+ value: false,
11
+ isValid: false,
12
+ };
13
+
14
+ const validResult = { value: true, isValid: true };
15
+
16
+ export default (options?: HTMLInputElement[]): CheckboxFieldResult => {
17
+ if (Array.isArray(options)) {
18
+ if (options.length > 1) {
19
+ const values = options
20
+ .filter((option) => option && option.checked && !option.disabled)
21
+ .map((option) => option.value);
22
+ return { value: values, isValid: !!values.length };
23
+ }
24
+
25
+ return options[0].checked && !options[0].disabled
26
+ ? // @ts-expect-error expected to work in the browser
27
+ options[0].attributes && !isUndefined(options[0].attributes.value)
28
+ ? isUndefined(options[0].value) || options[0].value === ''
29
+ ? validResult
30
+ : { value: options[0].value, isValid: true }
31
+ : validResult
32
+ : defaultResult;
33
+ }
34
+
35
+ return defaultResult;
36
+ };
@@ -0,0 +1,120 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/getDirtyFields.ts (octane port).
2
+ import type { FieldRefs } from '../types';
3
+ import deepEqual from '../utils/deepEqual';
4
+ import get from '../utils/get';
5
+ import isNullOrUndefined from '../utils/isNullOrUndefined';
6
+ import isObject from '../utils/isObject';
7
+ import isPrimitive from '../utils/isPrimitive';
8
+ import isUndefined from '../utils/isUndefined';
9
+ import objectHasFunction from '../utils/objectHasFunction';
10
+
11
+ function isTraversable<T>(value: T): boolean {
12
+ return Array.isArray(value) || (isObject(value) && !objectHasFunction(value));
13
+ }
14
+
15
+ function isRegisteredLeaf(fields: FieldRefs | undefined, path: string): boolean {
16
+ const field = fields && get(fields, path);
17
+ return !!(field && '_f' in field);
18
+ }
19
+
20
+ function markFieldsDirty<T>(
21
+ data: T,
22
+ fields: Record<string, any> = {},
23
+ fieldRefs?: FieldRefs,
24
+ path = '',
25
+ ) {
26
+ for (const key in data) {
27
+ const value = data[key];
28
+ const currentPath = path ? `${path}.${key}` : key;
29
+
30
+ if (
31
+ isTraversable(value) &&
32
+ (!Array.isArray(value) || !isRegisteredLeaf(fieldRefs, currentPath))
33
+ ) {
34
+ fields[key] = Array.isArray(value) ? [] : {};
35
+ markFieldsDirty(value, fields[key], fieldRefs, currentPath);
36
+ } else if (!isUndefined(value)) {
37
+ fields[key] = true;
38
+ }
39
+ }
40
+
41
+ return fields;
42
+ }
43
+
44
+ function pruneDirtyFields<T>(value: T): T {
45
+ if (value === false) {
46
+ return undefined as T;
47
+ }
48
+
49
+ if (value === true) {
50
+ return true as T;
51
+ }
52
+
53
+ if (Array.isArray(value)) {
54
+ const result = value.map((value) => pruneDirtyFields(value));
55
+ return (result.some((value) => value !== undefined) ? result : undefined) as T;
56
+ }
57
+
58
+ if (isObject(value)) {
59
+ const result: Record<string, unknown> = {};
60
+
61
+ for (const key in value) {
62
+ const pruned = pruneDirtyFields(value[key]);
63
+
64
+ if (!isUndefined(pruned)) {
65
+ result[key] = pruned;
66
+ }
67
+ }
68
+
69
+ return (Object.keys(result).length ? result : undefined) as T;
70
+ }
71
+
72
+ return undefined as T;
73
+ }
74
+
75
+ export default function getDirtyFields<T>(
76
+ data: T,
77
+ formValues: T,
78
+ dirtyFieldsFromValues?: Record<
79
+ Extract<keyof T, string>,
80
+ ReturnType<typeof markFieldsDirty> | boolean
81
+ >,
82
+ fieldRefs?: FieldRefs,
83
+ path = '',
84
+ ) {
85
+ if (!dirtyFieldsFromValues) {
86
+ dirtyFieldsFromValues = markFieldsDirty(formValues, {}, fieldRefs);
87
+ }
88
+
89
+ for (const key in data) {
90
+ const value = data[key];
91
+ const currentPath = path ? `${path}.${key}` : key;
92
+
93
+ if (
94
+ isTraversable(value) &&
95
+ (!Array.isArray(value) || !isRegisteredLeaf(fieldRefs, currentPath))
96
+ ) {
97
+ if (isUndefined(formValues) || isPrimitive(dirtyFieldsFromValues[key])) {
98
+ dirtyFieldsFromValues[key] = markFieldsDirty(
99
+ value,
100
+ Array.isArray(value) ? [] : {},
101
+ fieldRefs,
102
+ currentPath,
103
+ );
104
+ } else {
105
+ getDirtyFields(
106
+ value,
107
+ isNullOrUndefined(formValues) ? {} : formValues[key],
108
+ dirtyFieldsFromValues[key],
109
+ fieldRefs,
110
+ currentPath,
111
+ );
112
+ }
113
+ } else {
114
+ const formValue = formValues[key];
115
+ dirtyFieldsFromValues[key] = !deepEqual(value, formValue);
116
+ }
117
+ }
118
+
119
+ return pruneDirtyFields(dirtyFieldsFromValues) || {};
120
+ }
@@ -0,0 +1,12 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/getEventValue.ts (octane port).
2
+ import isCheckBoxInput from '../utils/isCheckBoxInput';
3
+ import isObject from '../utils/isObject';
4
+
5
+ type Event = { target: any };
6
+
7
+ export default (event: unknown) =>
8
+ isObject(event) && (event as Event).target
9
+ ? isCheckBoxInput((event as Event).target)
10
+ ? (event as Event).target.checked
11
+ : (event as Event).target.value
12
+ : event;
@@ -0,0 +1,33 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/getFieldValue.ts (octane port).
2
+ import type { Field } from '../types';
3
+ import isCheckBox from '../utils/isCheckBoxInput';
4
+ import isFileInput from '../utils/isFileInput';
5
+ import isMultipleSelect from '../utils/isMultipleSelect';
6
+ import isRadioInput from '../utils/isRadioInput';
7
+ import isUndefined from '../utils/isUndefined';
8
+
9
+ import getCheckboxValue from './getCheckboxValue';
10
+ import getFieldValueAs from './getFieldValueAs';
11
+ import getRadioValue from './getRadioValue';
12
+
13
+ export default function getFieldValue(_f: Field['_f']) {
14
+ const ref = _f.ref;
15
+
16
+ if (isFileInput(ref)) {
17
+ return ref.files;
18
+ }
19
+
20
+ if (isRadioInput(ref)) {
21
+ return getRadioValue(_f.refs).value;
22
+ }
23
+
24
+ if (isMultipleSelect(ref)) {
25
+ return [...ref.selectedOptions].map(({ value }) => value);
26
+ }
27
+
28
+ if (isCheckBox(ref)) {
29
+ return getCheckboxValue(_f.refs).value;
30
+ }
31
+
32
+ return getFieldValueAs(isUndefined(ref.value) ? _f.ref.value : ref.value, _f);
33
+ }
@@ -0,0 +1,22 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/getFieldValueAs.ts (octane port).
2
+ import type { Field, NativeFieldValue } from '../types';
3
+ import isString from '../utils/isString';
4
+ import isUndefined from '../utils/isUndefined';
5
+
6
+ export default <T extends NativeFieldValue>(
7
+ value: T,
8
+ { valueAsNumber, valueAsDate, setValueAs }: Field['_f'],
9
+ ) =>
10
+ isUndefined(value)
11
+ ? value
12
+ : valueAsNumber
13
+ ? value === ''
14
+ ? NaN
15
+ : value
16
+ ? +value
17
+ : value
18
+ : valueAsDate && isString(value)
19
+ ? new Date(value)
20
+ : setValueAs
21
+ ? setValueAs(value)
22
+ : value;
@@ -0,0 +1,13 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/getFocusFieldName.ts (octane port).
2
+ import type { FieldArrayMethodProps, InternalFieldName } from '../types';
3
+ import isUndefined from '../utils/isUndefined';
4
+
5
+ export default (
6
+ name: InternalFieldName,
7
+ index: number,
8
+ options: FieldArrayMethodProps = {},
9
+ ): string =>
10
+ options.shouldFocus || isUndefined(options.shouldFocus)
11
+ ? options.focusName ||
12
+ `${name}.${isUndefined(options.focusIndex) ? index : options.focusIndex}.`
13
+ : '';
@@ -0,0 +1,4 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/getNodeParentName.ts (octane port).
2
+ const ARRAY_INDEX_RE = /\.\d+(\.|$)/;
3
+
4
+ export default (name: string) => name.substring(0, name.search(ARRAY_INDEX_RE)) || name;
@@ -0,0 +1,33 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/getProxyFormState.ts (octane port).
2
+ import { VALIDATION_MODE } from '../constants';
3
+ import type { Control, FieldValues, FormState, ReadFormState } from '../types';
4
+
5
+ export default <
6
+ TFieldValues extends FieldValues,
7
+ TContext = any,
8
+ TTransformedValues = TFieldValues,
9
+ >(
10
+ formState: FormState<TFieldValues>,
11
+ control: Control<TFieldValues, TContext, TTransformedValues>,
12
+ localProxyFormState?: ReadFormState,
13
+ isRoot = true,
14
+ ) => {
15
+ const result = {} as typeof formState;
16
+
17
+ for (const key in formState) {
18
+ Object.defineProperty(result, key, {
19
+ get: () => {
20
+ const _key = key as keyof FormState<TFieldValues> & keyof ReadFormState;
21
+
22
+ if (control._proxyFormState[_key] !== VALIDATION_MODE.all) {
23
+ control._proxyFormState[_key] = !isRoot || VALIDATION_MODE.all;
24
+ }
25
+
26
+ localProxyFormState && (localProxyFormState[_key] = true);
27
+ return formState[_key];
28
+ },
29
+ });
30
+ }
31
+
32
+ return result;
33
+ };
@@ -0,0 +1,24 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/getRadioValue.ts (octane port).
2
+ type RadioFieldResult = {
3
+ isValid: boolean;
4
+ value: number | string | null;
5
+ };
6
+
7
+ const defaultReturn: RadioFieldResult = {
8
+ isValid: false,
9
+ value: null,
10
+ };
11
+
12
+ export default (options?: HTMLInputElement[]): RadioFieldResult =>
13
+ Array.isArray(options)
14
+ ? options.reduce(
15
+ (previous, option): RadioFieldResult =>
16
+ option && option.checked && !option.disabled
17
+ ? {
18
+ isValid: true,
19
+ value: option.value,
20
+ }
21
+ : previous,
22
+ defaultReturn,
23
+ )
24
+ : defaultReturn;
@@ -0,0 +1,33 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/getResolverOptions.ts (octane port).
2
+ import type {
3
+ CriteriaMode,
4
+ Field,
5
+ FieldName,
6
+ FieldRefs,
7
+ FieldValues,
8
+ InternalFieldName,
9
+ } from '../types';
10
+ import { get } from '../utils';
11
+ import set from '../utils/set';
12
+
13
+ export default <TFieldValues extends FieldValues>(
14
+ fieldsNames: Set<InternalFieldName> | InternalFieldName[],
15
+ _fields: FieldRefs,
16
+ criteriaMode?: CriteriaMode,
17
+ shouldUseNativeValidation?: boolean | undefined,
18
+ ) => {
19
+ const fields: Record<InternalFieldName, Field['_f']> = {};
20
+
21
+ for (const name of fieldsNames) {
22
+ const field: Field = get(_fields, name);
23
+
24
+ field && set(fields, name, field._f);
25
+ }
26
+
27
+ return {
28
+ criteriaMode,
29
+ names: [...fieldsNames] as FieldName<TFieldValues>[],
30
+ fields,
31
+ shouldUseNativeValidation,
32
+ };
33
+ };
@@ -0,0 +1,16 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/getRuleValue.ts (octane port).
2
+ import type { ValidationRule, ValidationValue, ValidationValueMessage } from '../types';
3
+ import isObject from '../utils/isObject';
4
+ import isRegex from '../utils/isRegex';
5
+ import isUndefined from '../utils/isUndefined';
6
+
7
+ export default <T extends ValidationValue>(rule?: ValidationRule<T> | ValidationValueMessage<T>) =>
8
+ isUndefined(rule)
9
+ ? rule
10
+ : isRegex(rule)
11
+ ? rule.source
12
+ : isObject(rule)
13
+ ? isRegex(rule.value)
14
+ ? rule.value.source
15
+ : rule.value
16
+ : rule;
@@ -0,0 +1,22 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/getValidateError.ts (octane port).
2
+ import type { FieldError, Ref, ValidateResult } from '../types';
3
+ import isBoolean from '../utils/isBoolean';
4
+ import isString from '../utils/isString';
5
+
6
+ export default function getValidateError(
7
+ result: ValidateResult,
8
+ ref: Ref,
9
+ type = 'validate',
10
+ ): FieldError | void {
11
+ if (
12
+ isString(result) ||
13
+ (Array.isArray(result) && result.every(isString)) ||
14
+ (isBoolean(result) && !result)
15
+ ) {
16
+ return {
17
+ type,
18
+ message: isString(result) ? result : '',
19
+ ref,
20
+ };
21
+ }
22
+ }
@@ -0,0 +1,11 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/getValidationModes.ts (octane port).
2
+ import { VALIDATION_MODE } from '../constants';
3
+ import type { Mode, ValidationModeFlags } from '../types';
4
+
5
+ export default (mode?: Mode): ValidationModeFlags => ({
6
+ isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
7
+ isOnBlur: mode === VALIDATION_MODE.onBlur,
8
+ isOnChange: mode === VALIDATION_MODE.onChange,
9
+ isOnAll: mode === VALIDATION_MODE.all,
10
+ isOnTouch: mode === VALIDATION_MODE.onTouched,
11
+ });
@@ -0,0 +1,12 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/getValueAndMessage.ts (octane port).
2
+ import type { ValidationRule } from '../types';
3
+ import isObject from '../utils/isObject';
4
+ import isRegex from '../utils/isRegex';
5
+
6
+ export default (validationData?: ValidationRule) =>
7
+ isObject(validationData) && !isRegex(validationData)
8
+ ? validationData
9
+ : {
10
+ value: validationData,
11
+ message: '',
12
+ };
@@ -0,0 +1,27 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/hasPromiseValidation.ts (octane port).
2
+ import type { Field, Validate } from '../types';
3
+ import isFunction from '../utils/isFunction';
4
+ import isObject from '../utils/isObject';
5
+
6
+ const ASYNC_FUNCTION = 'AsyncFunction';
7
+
8
+ export default (fieldReference: Field['_f']) => {
9
+ if (!fieldReference || !fieldReference.validate) return false;
10
+
11
+ if (isFunction(fieldReference.validate)) {
12
+ return fieldReference.validate.constructor.name === ASYNC_FUNCTION;
13
+ }
14
+
15
+ if (isObject(fieldReference.validate)) {
16
+ for (const key in fieldReference.validate) {
17
+ if (
18
+ (fieldReference.validate[key] as Validate<unknown, unknown>).constructor.name ===
19
+ ASYNC_FUNCTION
20
+ ) {
21
+ return true;
22
+ }
23
+ }
24
+ }
25
+
26
+ return false;
27
+ };
@@ -0,0 +1,12 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/hasValidation.ts (octane port).
2
+ import type { Field } from '../types';
3
+
4
+ export default (options: Field['_f']) =>
5
+ options.mount &&
6
+ (options.required ||
7
+ options.min ||
8
+ options.max ||
9
+ options.maxLength ||
10
+ options.minLength ||
11
+ options.pattern ||
12
+ options.validate);
@@ -0,0 +1,3 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/index.ts (octane port).
2
+ export { default as appendErrors } from './appendErrors';
3
+ export { createFormControl } from './createFormControl';
@@ -0,0 +1,7 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/isNameInFieldArray.ts (octane port).
2
+ import type { InternalFieldName } from '../types';
3
+
4
+ export default (names: Set<InternalFieldName>, name: InternalFieldName) =>
5
+ name
6
+ .split('.')
7
+ .some((part, index, arr) => !isNaN(Number(part)) && names.has(arr.slice(0, index).join('.')));
@@ -0,0 +1,11 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/isWatched.ts (octane port).
2
+ import type { InternalFieldName, Names } from '../types';
3
+
4
+ export default (name: InternalFieldName, _names: Names, isBlurEvent?: boolean) => {
5
+ if (isBlurEvent) return false;
6
+ if (_names.watchAll || _names.watch.has(name)) return true;
7
+ for (const watchName of _names.watch) {
8
+ if (name.startsWith(watchName) && name.charAt(watchName.length) === '.') return true;
9
+ }
10
+ return false;
11
+ };
@@ -0,0 +1,37 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/iterateFieldsByAction.ts (octane port).
2
+ import type { FieldRefs, InternalFieldName, Ref } from '../types';
3
+ import { get } from '../utils';
4
+ import isObject from '../utils/isObject';
5
+
6
+ const iterateFieldsByAction = (
7
+ fields: FieldRefs,
8
+ action: (ref: Ref, name: string) => 1 | undefined | void,
9
+ fieldsNames?: Set<InternalFieldName> | InternalFieldName[] | 0,
10
+ abortEarly?: boolean,
11
+ ) => {
12
+ for (const key of fieldsNames || Object.keys(fields)) {
13
+ const field = get(fields, key);
14
+
15
+ if (field) {
16
+ const { _f, ...currentField } = field;
17
+
18
+ if (_f) {
19
+ if (_f.refs && _f.refs[0] && action(_f.refs[0], key) && !abortEarly) {
20
+ return true;
21
+ } else if (_f.ref && action(_f.ref, _f.name) && !abortEarly) {
22
+ return true;
23
+ } else {
24
+ if (iterateFieldsByAction(currentField, action)) {
25
+ break;
26
+ }
27
+ }
28
+ } else if (isObject(currentField)) {
29
+ if (iterateFieldsByAction(currentField as FieldRefs, action)) {
30
+ break;
31
+ }
32
+ }
33
+ }
34
+ }
35
+ return;
36
+ };
37
+ export default iterateFieldsByAction;
@@ -0,0 +1,54 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/schemaErrorLookup.ts (octane port).
2
+ import type { FieldError, FieldErrors, FieldValues } from '../types';
3
+ import get from '../utils/get';
4
+ import isKey from '../utils/isKey';
5
+
6
+ export default function schemaErrorLookup<T extends FieldValues = FieldValues>(
7
+ errors: FieldErrors<T>,
8
+ _fields: FieldValues,
9
+ name: string,
10
+ ): {
11
+ error?: FieldError;
12
+ name: string;
13
+ } {
14
+ const error = get(errors, name);
15
+
16
+ if (error || isKey(name)) {
17
+ return {
18
+ error,
19
+ name,
20
+ };
21
+ }
22
+
23
+ const names = name.split('.');
24
+
25
+ while (names.length) {
26
+ const fieldName = names.join('.');
27
+ const field = get(_fields, fieldName);
28
+ const foundError = get(errors, fieldName);
29
+
30
+ if (field && !Array.isArray(field) && name !== fieldName) {
31
+ return { name };
32
+ }
33
+
34
+ if (foundError && foundError.type) {
35
+ return {
36
+ name: fieldName,
37
+ error: foundError,
38
+ };
39
+ }
40
+
41
+ if (foundError && foundError.root && foundError.root.type) {
42
+ return {
43
+ name: `${fieldName}.root`,
44
+ error: foundError.root,
45
+ };
46
+ }
47
+
48
+ names.pop();
49
+ }
50
+
51
+ return {
52
+ name,
53
+ };
54
+ }
@@ -0,0 +1,25 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/shouldRenderFormState.ts (octane port).
2
+ import { VALIDATION_MODE } from '../constants';
3
+ import type { FieldValues, FormState, InternalFieldName, ReadFormState } from '../types';
4
+
5
+ export default <T extends FieldValues, K extends ReadFormState>(
6
+ formStateData: Partial<FormState<T>> & {
7
+ name?: InternalFieldName;
8
+ values?: T;
9
+ },
10
+ _proxyFormState: K,
11
+ updateFormState: (formState: Partial<FormState<T>>) => void,
12
+ isRoot?: boolean,
13
+ ) => {
14
+ updateFormState(formStateData);
15
+ const { name, ...formState } = formStateData;
16
+ const keys = Object.keys(formState);
17
+
18
+ return (
19
+ !keys.length ||
20
+ (isRoot && keys.length >= Object.keys(_proxyFormState).length) ||
21
+ keys.find(
22
+ (key) => _proxyFormState[key as keyof ReadFormState] === (!isRoot || VALIDATION_MODE.all),
23
+ )
24
+ );
25
+ };
@@ -0,0 +1,18 @@
1
+ // Vendored from react-hook-form@7.81.0 src/logic/shouldSubscribeByName.ts (octane port).
2
+ import convertToArrayPayload from '../utils/convertToArrayPayload';
3
+
4
+ export default <T extends string | readonly string[] | undefined>(
5
+ name?: T,
6
+ signalName?: string,
7
+ exact?: boolean,
8
+ ) =>
9
+ !name ||
10
+ !signalName ||
11
+ name === signalName ||
12
+ convertToArrayPayload(name).some(
13
+ (currentName) =>
14
+ currentName &&
15
+ (exact
16
+ ? currentName === signalName || currentName.startsWith(signalName + '.')
17
+ : currentName.startsWith(signalName) || signalName.startsWith(currentName)),
18
+ );