@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.
- package/LICENSE +21 -0
- package/README.md +62 -0
- package/package.json +46 -0
- package/src/FormProvider.tsrx +76 -0
- package/src/FormProvider.tsrx.d.ts +10 -0
- package/src/constants.ts +31 -0
- package/src/controller.tsrx +8 -0
- package/src/controller.tsrx.d.ts +52 -0
- package/src/form.tsrx +119 -0
- package/src/form.tsrx.d.ts +6 -0
- package/src/formStateSubscribe.tsrx +10 -0
- package/src/formStateSubscribe.tsrx.d.ts +16 -0
- package/src/index.ts +19 -0
- package/src/logic/appendErrors.ts +19 -0
- package/src/logic/createFormControl.ts +1841 -0
- package/src/logic/generateId.ts +14 -0
- package/src/logic/generateWatchOutput.ts +27 -0
- package/src/logic/getCheckboxValue.ts +36 -0
- package/src/logic/getDirtyFields.ts +120 -0
- package/src/logic/getEventValue.ts +12 -0
- package/src/logic/getFieldValue.ts +33 -0
- package/src/logic/getFieldValueAs.ts +22 -0
- package/src/logic/getFocusFieldName.ts +13 -0
- package/src/logic/getNodeParentName.ts +4 -0
- package/src/logic/getProxyFormState.ts +33 -0
- package/src/logic/getRadioValue.ts +24 -0
- package/src/logic/getResolverOptions.ts +33 -0
- package/src/logic/getRuleValue.ts +16 -0
- package/src/logic/getValidateError.ts +22 -0
- package/src/logic/getValidationModes.ts +11 -0
- package/src/logic/getValueAndMessage.ts +12 -0
- package/src/logic/hasPromiseValidation.ts +27 -0
- package/src/logic/hasValidation.ts +12 -0
- package/src/logic/index.ts +3 -0
- package/src/logic/isNameInFieldArray.ts +7 -0
- package/src/logic/isWatched.ts +11 -0
- package/src/logic/iterateFieldsByAction.ts +37 -0
- package/src/logic/schemaErrorLookup.ts +54 -0
- package/src/logic/shouldRenderFormState.ts +25 -0
- package/src/logic/shouldSubscribeByName.ts +18 -0
- package/src/logic/skipValidation.ts +21 -0
- package/src/logic/unsetEmptyArray.ts +6 -0
- package/src/logic/updateFieldArrayRootError.ts +17 -0
- package/src/logic/validateField.ts +273 -0
- package/src/types/controller.ts +98 -0
- package/src/types/errors.ts +56 -0
- package/src/types/events.ts +26 -0
- package/src/types/fieldArray.ts +288 -0
- package/src/types/fields.ts +46 -0
- package/src/types/form.ts +961 -0
- package/src/types/index.ts +12 -0
- package/src/types/path/common.ts +391 -0
- package/src/types/path/eager.ts +224 -0
- package/src/types/path/index.ts +16 -0
- package/src/types/resolvers.ts +38 -0
- package/src/types/utils.ts +125 -0
- package/src/types/validator.ts +94 -0
- package/src/types/watch.ts +66 -0
- package/src/useController.ts +268 -0
- package/src/useFieldArray.ts +490 -0
- package/src/useForm.ts +182 -0
- package/src/useFormContext.ts +47 -0
- package/src/useFormControlContext.ts +25 -0
- package/src/useFormState.ts +86 -0
- package/src/useIsomorphicLayoutEffect.ts +6 -0
- package/src/useWatch.ts +356 -0
- package/src/utils/append.ts +4 -0
- package/src/utils/cloneObject.ts +32 -0
- package/src/utils/compact.ts +2 -0
- package/src/utils/convertToArrayPayload.ts +2 -0
- package/src/utils/createSubject.ts +48 -0
- package/src/utils/deepEqual.ts +81 -0
- package/src/utils/deepMerge.ts +27 -0
- package/src/utils/extractFormValues.ts +28 -0
- package/src/utils/fillEmptyArray.ts +3 -0
- package/src/utils/flatten.ts +23 -0
- package/src/utils/get.ts +29 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/insert.ts +8 -0
- package/src/utils/isBoolean.ts +2 -0
- package/src/utils/isCheckBoxInput.ts +4 -0
- package/src/utils/isDateObject.ts +2 -0
- package/src/utils/isEmptyObject.ts +7 -0
- package/src/utils/isFileInput.ts +4 -0
- package/src/utils/isFunction.ts +2 -0
- package/src/utils/isHTMLElement.ts +13 -0
- package/src/utils/isKey.ts +4 -0
- package/src/utils/isMultipleSelect.ts +5 -0
- package/src/utils/isNullOrUndefined.ts +2 -0
- package/src/utils/isObject.ts +8 -0
- package/src/utils/isPlainObject.ts +8 -0
- package/src/utils/isPrimitive.ts +8 -0
- package/src/utils/isRadioInput.ts +4 -0
- package/src/utils/isRadioOrCheckbox.ts +8 -0
- package/src/utils/isRegex.ts +2 -0
- package/src/utils/isString.ts +2 -0
- package/src/utils/isUndefined.ts +2 -0
- package/src/utils/isWeb.ts +4 -0
- package/src/utils/live.ts +6 -0
- package/src/utils/move.ts +15 -0
- package/src/utils/noop.ts +2 -0
- package/src/utils/objectHasFunction.ts +11 -0
- package/src/utils/prepend.ts +7 -0
- package/src/utils/remove.ts +24 -0
- package/src/utils/set.ts +36 -0
- package/src/utils/sleep.ts +2 -0
- package/src/utils/stringToPath.ts +4 -0
- package/src/utils/swap.ts +4 -0
- package/src/utils/unset.ts +65 -0
- package/src/utils/update.ts +5 -0
- package/src/watch.tsrx +7 -0
- 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,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,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
|
+
);
|