@tanstack/form-core 1.16.0 → 1.17.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/dist/cjs/FieldApi.cjs +48 -40
- package/dist/cjs/FieldApi.cjs.map +1 -1
- package/dist/cjs/FieldApi.d.cts +33 -30
- package/dist/cjs/FieldGroupApi.cjs.map +1 -1
- package/dist/cjs/FieldGroupApi.d.cts +6 -6
- package/dist/cjs/FormApi.cjs +79 -69
- package/dist/cjs/FormApi.cjs.map +1 -1
- package/dist/cjs/FormApi.d.cts +40 -35
- package/dist/cjs/ValidationLogic.cjs +106 -0
- package/dist/cjs/ValidationLogic.cjs.map +1 -0
- package/dist/cjs/ValidationLogic.d.cts +47 -0
- package/dist/cjs/formOptions.cjs.map +1 -1
- package/dist/cjs/formOptions.d.cts +1 -1
- package/dist/cjs/index.cjs +3 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -0
- package/dist/cjs/mergeForm.cjs.map +1 -1
- package/dist/cjs/mergeForm.d.cts +1 -1
- package/dist/cjs/metaHelper.cjs.map +1 -1
- package/dist/cjs/metaHelper.d.cts +1 -1
- package/dist/cjs/standardSchemaValidator.cjs.map +1 -1
- package/dist/cjs/types.d.cts +6 -3
- package/dist/cjs/utils.cjs +51 -63
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +11 -5
- package/dist/esm/FieldApi.d.ts +33 -30
- package/dist/esm/FieldApi.js +48 -40
- package/dist/esm/FieldApi.js.map +1 -1
- package/dist/esm/FieldGroupApi.d.ts +6 -6
- package/dist/esm/FieldGroupApi.js.map +1 -1
- package/dist/esm/FormApi.d.ts +40 -35
- package/dist/esm/FormApi.js +79 -69
- package/dist/esm/FormApi.js.map +1 -1
- package/dist/esm/ValidationLogic.d.ts +47 -0
- package/dist/esm/ValidationLogic.js +106 -0
- package/dist/esm/ValidationLogic.js.map +1 -0
- package/dist/esm/formOptions.d.ts +1 -1
- package/dist/esm/formOptions.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/mergeForm.d.ts +1 -1
- package/dist/esm/mergeForm.js.map +1 -1
- package/dist/esm/metaHelper.d.ts +1 -1
- package/dist/esm/metaHelper.js.map +1 -1
- package/dist/esm/standardSchemaValidator.js.map +1 -1
- package/dist/esm/types.d.ts +6 -3
- package/dist/esm/utils.d.ts +11 -5
- package/dist/esm/utils.js +51 -63
- package/dist/esm/utils.js.map +1 -1
- package/package.json +16 -3
- package/src/FieldApi.ts +185 -14
- package/src/FieldGroupApi.ts +14 -0
- package/src/FormApi.ts +131 -3
- package/src/ValidationLogic.ts +200 -0
- package/src/formOptions.ts +1 -1
- package/src/index.ts +1 -0
- package/src/mergeForm.ts +16 -1
- package/src/metaHelper.ts +4 -0
- package/src/types.ts +17 -1
- package/src/utils.ts +159 -109
package/dist/cjs/FormApi.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Derived, Store } from '@tanstack/store';
|
|
2
|
+
import { ValidationLogicFn } from './ValidationLogic.cjs';
|
|
2
3
|
import { StandardSchemaV1, StandardSchemaV1Issue, TStandardSchemaValidatorValue } from './standardSchemaValidator.cjs';
|
|
3
4
|
import { AnyFieldApi, AnyFieldMeta, AnyFieldMetaBase, FieldApi } from './FieldApi.cjs';
|
|
4
5
|
import { ExtractGlobalFormError, FieldManipulator, FormValidationError, FormValidationErrorMap, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap, ValidationErrorMapKeys } from './types.cjs';
|
|
@@ -10,7 +11,7 @@ import { Updater } from './utils.cjs';
|
|
|
10
11
|
type FormErrorMapFromValidator<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>> = Partial<Record<DeepKeys<TFormData>, ValidationErrorMap<TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>>>;
|
|
11
12
|
export type FormValidateFn<TFormData> = (props: {
|
|
12
13
|
value: TFormData;
|
|
13
|
-
formApi: FormApi<TFormData, any, any, any, any, any, any, any, any, any>;
|
|
14
|
+
formApi: FormApi<TFormData, any, any, any, any, any, any, any, any, any, any, any>;
|
|
14
15
|
}) => unknown;
|
|
15
16
|
/**
|
|
16
17
|
* @private
|
|
@@ -22,7 +23,7 @@ export type UnwrapFormValidateOrFn<TValidateOrFn extends undefined | FormValidat
|
|
|
22
23
|
*/
|
|
23
24
|
export type FormValidateAsyncFn<TFormData> = (props: {
|
|
24
25
|
value: TFormData;
|
|
25
|
-
formApi: FormApi<TFormData, any, any, any, any, any, any, any, any, any>;
|
|
26
|
+
formApi: FormApi<TFormData, any, any, any, any, any, any, any, any, any, any, any>;
|
|
26
27
|
signal: AbortSignal;
|
|
27
28
|
}) => unknown | Promise<unknown>;
|
|
28
29
|
export type FormValidator<TFormData, TType, TFn = unknown> = {
|
|
@@ -38,7 +39,7 @@ export type FormValidator<TFormData, TType, TFn = unknown> = {
|
|
|
38
39
|
*/
|
|
39
40
|
export type FormAsyncValidateOrFn<TFormData> = FormValidateAsyncFn<TFormData> | StandardSchemaV1<TFormData, unknown>;
|
|
40
41
|
export type UnwrapFormAsyncValidateOrFn<TValidateOrFn extends undefined | FormAsyncValidateOrFn<any>> = [TValidateOrFn] extends [FormValidateAsyncFn<any>] ? ExtractGlobalFormError<Awaited<ReturnType<TValidateOrFn>>> : [TValidateOrFn] extends [StandardSchemaV1<any, any>] ? Record<string, StandardSchemaV1Issue[]> : undefined;
|
|
41
|
-
export interface FormValidators<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>> {
|
|
42
|
+
export interface FormValidators<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnDynamic extends undefined | FormValidateOrFn<TFormData>, TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>> {
|
|
42
43
|
/**
|
|
43
44
|
* Optional function that fires as soon as the component mounts.
|
|
44
45
|
*/
|
|
@@ -69,30 +70,33 @@ export interface FormValidators<TFormData, TOnMount extends undefined | FormVali
|
|
|
69
70
|
onBlurAsyncDebounceMs?: number;
|
|
70
71
|
onSubmit?: TOnSubmit;
|
|
71
72
|
onSubmitAsync?: TOnSubmitAsync;
|
|
73
|
+
onDynamic?: TOnDynamic;
|
|
74
|
+
onDynamicAsync?: TOnDynamicAsync;
|
|
75
|
+
onDynamicAsyncDebounceMs?: number;
|
|
72
76
|
}
|
|
73
77
|
/**
|
|
74
78
|
* @private
|
|
75
79
|
*/
|
|
76
|
-
export interface FormTransform<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, TSubmitMeta = never> {
|
|
77
|
-
fn: (formBase: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>) => FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>;
|
|
80
|
+
export interface FormTransform<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnDynamic extends undefined | FormValidateOrFn<TFormData>, TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, TSubmitMeta = never> {
|
|
81
|
+
fn: (formBase: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>) => FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
|
|
78
82
|
deps: unknown[];
|
|
79
83
|
}
|
|
80
|
-
export interface FormListeners<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, TSubmitMeta = never> {
|
|
84
|
+
export interface FormListeners<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnDynamic extends undefined | FormValidateOrFn<TFormData>, TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, TSubmitMeta = never> {
|
|
81
85
|
onChange?: (props: {
|
|
82
|
-
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>;
|
|
86
|
+
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
|
|
83
87
|
fieldApi: AnyFieldApi;
|
|
84
88
|
}) => void;
|
|
85
89
|
onChangeDebounceMs?: number;
|
|
86
90
|
onBlur?: (props: {
|
|
87
|
-
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>;
|
|
91
|
+
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
|
|
88
92
|
fieldApi: AnyFieldApi;
|
|
89
93
|
}) => void;
|
|
90
94
|
onBlurDebounceMs?: number;
|
|
91
95
|
onMount?: (props: {
|
|
92
|
-
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>;
|
|
96
|
+
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
|
|
93
97
|
}) => void;
|
|
94
98
|
onSubmit?: (props: {
|
|
95
|
-
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>;
|
|
99
|
+
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
|
|
96
100
|
meta: TSubmitMeta;
|
|
97
101
|
}) => void;
|
|
98
102
|
}
|
|
@@ -112,11 +116,11 @@ export interface BaseFormOptions<in out TFormData, in out TSubmitMeta = never> {
|
|
|
112
116
|
/**
|
|
113
117
|
* An object representing the options for a form.
|
|
114
118
|
*/
|
|
115
|
-
export interface FormOptions<in out TFormData, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, in out TSubmitMeta = never> extends BaseFormOptions<TFormData, TSubmitMeta> {
|
|
119
|
+
export interface FormOptions<in out TFormData, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>, in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, in out TSubmitMeta = never> extends BaseFormOptions<TFormData, TSubmitMeta> {
|
|
116
120
|
/**
|
|
117
121
|
* The default state for the form.
|
|
118
122
|
*/
|
|
119
|
-
defaultState?: Partial<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>>;
|
|
123
|
+
defaultState?: Partial<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>>;
|
|
120
124
|
/**
|
|
121
125
|
* If true, always run async validation, even when sync validation has produced an error. Defaults to undefined.
|
|
122
126
|
*/
|
|
@@ -132,17 +136,18 @@ export interface FormOptions<in out TFormData, in out TOnMount extends undefined
|
|
|
132
136
|
/**
|
|
133
137
|
* A list of validators to pass to the form
|
|
134
138
|
*/
|
|
135
|
-
validators?: FormValidators<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>;
|
|
139
|
+
validators?: FormValidators<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>;
|
|
140
|
+
validationLogic?: ValidationLogicFn;
|
|
136
141
|
/**
|
|
137
142
|
* form level listeners
|
|
138
143
|
*/
|
|
139
|
-
listeners?: FormListeners<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>;
|
|
144
|
+
listeners?: FormListeners<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
|
|
140
145
|
/**
|
|
141
146
|
* A function to be called when the form is submitted, what should happen once the user submits a valid form returns `any` or a promise `Promise<any>`
|
|
142
147
|
*/
|
|
143
148
|
onSubmit?: (props: {
|
|
144
149
|
value: TFormData;
|
|
145
|
-
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>;
|
|
150
|
+
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
|
|
146
151
|
meta: TSubmitMeta;
|
|
147
152
|
}) => any | Promise<any>;
|
|
148
153
|
/**
|
|
@@ -150,10 +155,10 @@ export interface FormOptions<in out TFormData, in out TOnMount extends undefined
|
|
|
150
155
|
*/
|
|
151
156
|
onSubmitInvalid?: (props: {
|
|
152
157
|
value: TFormData;
|
|
153
|
-
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>;
|
|
158
|
+
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
|
|
154
159
|
meta: TSubmitMeta;
|
|
155
160
|
}) => void;
|
|
156
|
-
transform?: FormTransform<NoInfer<TFormData>, NoInfer<TOnMount>, NoInfer<TOnChange>, NoInfer<TOnChangeAsync>, NoInfer<TOnBlur>, NoInfer<TOnBlurAsync>, NoInfer<TOnSubmit>, NoInfer<TOnSubmitAsync>, NoInfer<TOnServer>, NoInfer<TSubmitMeta>>;
|
|
161
|
+
transform?: FormTransform<NoInfer<TFormData>, NoInfer<TOnMount>, NoInfer<TOnChange>, NoInfer<TOnChangeAsync>, NoInfer<TOnBlur>, NoInfer<TOnBlurAsync>, NoInfer<TOnSubmit>, NoInfer<TOnSubmitAsync>, NoInfer<TOnDynamic>, NoInfer<TOnDynamicAsync>, NoInfer<TOnServer>, NoInfer<TSubmitMeta>>;
|
|
157
162
|
}
|
|
158
163
|
/**
|
|
159
164
|
* An object representing the validation metadata for a field. Not intended for public usage.
|
|
@@ -171,7 +176,7 @@ export type FieldInfo<TFormData> = {
|
|
|
171
176
|
/**
|
|
172
177
|
* An instance of the FieldAPI.
|
|
173
178
|
*/
|
|
174
|
-
instance: FieldApi<TFormData, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any> | null;
|
|
179
|
+
instance: FieldApi<TFormData, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any> | null;
|
|
175
180
|
/**
|
|
176
181
|
* A record of field validation internal handling.
|
|
177
182
|
*/
|
|
@@ -180,7 +185,7 @@ export type FieldInfo<TFormData> = {
|
|
|
180
185
|
/**
|
|
181
186
|
* An object representing the current state of the form.
|
|
182
187
|
*/
|
|
183
|
-
export type BaseFormState<in out TFormData, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>> = {
|
|
188
|
+
export type BaseFormState<in out TFormData, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>, in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>> = {
|
|
184
189
|
/**
|
|
185
190
|
* The current values of the form fields.
|
|
186
191
|
*/
|
|
@@ -188,7 +193,7 @@ export type BaseFormState<in out TFormData, in out TOnMount extends undefined |
|
|
|
188
193
|
/**
|
|
189
194
|
* The error map for the form itself.
|
|
190
195
|
*/
|
|
191
|
-
errorMap: ValidationErrorMap<UnwrapFormValidateOrFn<TOnMount>, UnwrapFormValidateOrFn<TOnChange>, UnwrapFormAsyncValidateOrFn<TOnChangeAsync>, UnwrapFormValidateOrFn<TOnBlur>, UnwrapFormAsyncValidateOrFn<TOnBlurAsync>, UnwrapFormValidateOrFn<TOnSubmit>, UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>, UnwrapFormAsyncValidateOrFn<TOnServer>>;
|
|
196
|
+
errorMap: ValidationErrorMap<UnwrapFormValidateOrFn<TOnMount>, UnwrapFormValidateOrFn<TOnChange>, UnwrapFormAsyncValidateOrFn<TOnChangeAsync>, UnwrapFormValidateOrFn<TOnBlur>, UnwrapFormAsyncValidateOrFn<TOnBlurAsync>, UnwrapFormValidateOrFn<TOnSubmit>, UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>, UnwrapFormValidateOrFn<TOnDynamic>, UnwrapFormAsyncValidateOrFn<TOnDynamicAsync>, UnwrapFormAsyncValidateOrFn<TOnServer>>;
|
|
192
197
|
/**
|
|
193
198
|
* An internal mechanism used for keeping track of validation logic in a form.
|
|
194
199
|
*/
|
|
@@ -235,7 +240,7 @@ export type BaseFormState<in out TFormData, in out TOnMount extends undefined |
|
|
|
235
240
|
*/
|
|
236
241
|
_force_re_eval?: boolean;
|
|
237
242
|
};
|
|
238
|
-
export type DerivedFormState<in out TFormData, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>> = {
|
|
243
|
+
export type DerivedFormState<in out TFormData, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>, in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>> = {
|
|
239
244
|
/**
|
|
240
245
|
* A boolean indicating if the form is currently validating.
|
|
241
246
|
*/
|
|
@@ -247,7 +252,7 @@ export type DerivedFormState<in out TFormData, in out TOnMount extends undefined
|
|
|
247
252
|
/**
|
|
248
253
|
* The error array for the form itself.
|
|
249
254
|
*/
|
|
250
|
-
errors: Array<UnwrapFormValidateOrFn<TOnMount> | UnwrapFormValidateOrFn<TOnChange> | UnwrapFormAsyncValidateOrFn<TOnChangeAsync> | UnwrapFormValidateOrFn<TOnBlur> | UnwrapFormAsyncValidateOrFn<TOnBlurAsync> | UnwrapFormValidateOrFn<TOnSubmit> | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync> | UnwrapFormAsyncValidateOrFn<TOnServer>>;
|
|
255
|
+
errors: Array<UnwrapFormValidateOrFn<TOnMount> | UnwrapFormValidateOrFn<TOnChange> | UnwrapFormAsyncValidateOrFn<TOnChangeAsync> | UnwrapFormValidateOrFn<TOnBlur> | UnwrapFormAsyncValidateOrFn<TOnBlurAsync> | UnwrapFormValidateOrFn<TOnSubmit> | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync> | UnwrapFormValidateOrFn<TOnDynamic> | UnwrapFormAsyncValidateOrFn<TOnDynamicAsync> | UnwrapFormAsyncValidateOrFn<TOnServer>>;
|
|
251
256
|
/**
|
|
252
257
|
* A boolean indicating if any of the form fields are currently validating.
|
|
253
258
|
*/
|
|
@@ -289,15 +294,15 @@ export type DerivedFormState<in out TFormData, in out TOnMount extends undefined
|
|
|
289
294
|
*/
|
|
290
295
|
fieldMeta: Record<DeepKeys<TFormData>, AnyFieldMeta>;
|
|
291
296
|
};
|
|
292
|
-
export interface FormState<in out TFormData, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>> extends BaseFormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>, DerivedFormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer> {
|
|
297
|
+
export interface FormState<in out TFormData, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>, in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>> extends BaseFormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>, DerivedFormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer> {
|
|
293
298
|
}
|
|
294
|
-
export type AnyFormState = FormState<any, any, any, any, any, any, any, any, any>;
|
|
299
|
+
export type AnyFormState = FormState<any, any, any, any, any, any, any, any, any, any, any>;
|
|
295
300
|
/**
|
|
296
301
|
* @public
|
|
297
302
|
*
|
|
298
303
|
* A type representing the Form API with all generics set to `any` for convenience.
|
|
299
304
|
*/
|
|
300
|
-
export type AnyFormApi = FormApi<any, any, any, any, any, any, any, any, any, any>;
|
|
305
|
+
export type AnyFormApi = FormApi<any, any, any, any, any, any, any, any, any, any, any, any>;
|
|
301
306
|
/**
|
|
302
307
|
* A class representing the Form API. It handles the logic and interactions with the form state.
|
|
303
308
|
*
|
|
@@ -305,19 +310,19 @@ export type AnyFormApi = FormApi<any, any, any, any, any, any, any, any, any, an
|
|
|
305
310
|
* hook/function like `useForm` or `createForm` to create a new instance for you that uses your framework's reactivity model.
|
|
306
311
|
* However, if you need to create a new instance manually, you can do so by calling the `new FormApi` constructor.
|
|
307
312
|
*/
|
|
308
|
-
export declare class FormApi<in out TFormData, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, in out TSubmitMeta = never> implements FieldManipulator<TFormData, TSubmitMeta> {
|
|
313
|
+
export declare class FormApi<in out TFormData, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>, in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, in out TSubmitMeta = never> implements FieldManipulator<TFormData, TSubmitMeta> {
|
|
309
314
|
/**
|
|
310
315
|
* The options for the form.
|
|
311
316
|
*/
|
|
312
|
-
options: FormOptions<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>;
|
|
313
|
-
baseStore: Store<BaseFormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>>;
|
|
317
|
+
options: FormOptions<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
|
|
318
|
+
baseStore: Store<BaseFormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>>;
|
|
314
319
|
fieldMetaDerived: Derived<Record<DeepKeys<TFormData>, AnyFieldMeta>>;
|
|
315
|
-
store: Derived<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>>;
|
|
320
|
+
store: Derived<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>>;
|
|
316
321
|
/**
|
|
317
322
|
* A record of field information for each field in the form.
|
|
318
323
|
*/
|
|
319
324
|
fieldInfo: Record<DeepKeys<TFormData>, FieldInfo<TFormData>>;
|
|
320
|
-
get state(): FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>;
|
|
325
|
+
get state(): FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>;
|
|
321
326
|
/**
|
|
322
327
|
* @private
|
|
323
328
|
*/
|
|
@@ -325,7 +330,7 @@ export declare class FormApi<in out TFormData, in out TOnMount extends undefined
|
|
|
325
330
|
/**
|
|
326
331
|
* Constructs a new `FormApi` instance with the given form options.
|
|
327
332
|
*/
|
|
328
|
-
constructor(opts?: FormOptions<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>);
|
|
333
|
+
constructor(opts?: FormOptions<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>);
|
|
329
334
|
/**
|
|
330
335
|
* @private
|
|
331
336
|
*/
|
|
@@ -340,7 +345,7 @@ export declare class FormApi<in out TFormData, in out TOnMount extends undefined
|
|
|
340
345
|
/**
|
|
341
346
|
* Updates the form options and form state.
|
|
342
347
|
*/
|
|
343
|
-
update: (options?: FormOptions<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>) => void;
|
|
348
|
+
update: (options?: FormOptions<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>) => void;
|
|
344
349
|
/**
|
|
345
350
|
* Resets the form state to the default values.
|
|
346
351
|
* If values are provided, the form will be reset to those values instead and the default values will be updated.
|
|
@@ -441,14 +446,14 @@ export declare class FormApi<in out TFormData, in out TOnMount extends undefined
|
|
|
441
446
|
/**
|
|
442
447
|
* Updates the form's errorMap
|
|
443
448
|
*/
|
|
444
|
-
setErrorMap(errorMap: FormValidationErrorMap<TFormData, UnwrapFormValidateOrFn<TOnMount>, UnwrapFormValidateOrFn<TOnChange>, UnwrapFormAsyncValidateOrFn<TOnChangeAsync>, UnwrapFormValidateOrFn<TOnBlur>, UnwrapFormAsyncValidateOrFn<TOnBlurAsync>, UnwrapFormValidateOrFn<TOnSubmit>, UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>, UnwrapFormAsyncValidateOrFn<TOnServer>>): void;
|
|
449
|
+
setErrorMap(errorMap: FormValidationErrorMap<TFormData, UnwrapFormValidateOrFn<TOnMount>, UnwrapFormValidateOrFn<TOnChange>, UnwrapFormAsyncValidateOrFn<TOnChangeAsync>, UnwrapFormValidateOrFn<TOnBlur>, UnwrapFormAsyncValidateOrFn<TOnBlurAsync>, UnwrapFormValidateOrFn<TOnSubmit>, UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>, UnwrapFormValidateOrFn<TOnDynamic>, UnwrapFormAsyncValidateOrFn<TOnDynamicAsync>, UnwrapFormAsyncValidateOrFn<TOnServer>>): void;
|
|
445
450
|
/**
|
|
446
451
|
* Returns form and field level errors
|
|
447
452
|
*/
|
|
448
453
|
getAllErrors: () => {
|
|
449
454
|
form: {
|
|
450
|
-
errors: Array<UnwrapFormValidateOrFn<TOnMount> | UnwrapFormValidateOrFn<TOnChange> | UnwrapFormAsyncValidateOrFn<TOnChangeAsync> | UnwrapFormValidateOrFn<TOnBlur> | UnwrapFormAsyncValidateOrFn<TOnBlurAsync> | UnwrapFormValidateOrFn<TOnSubmit> | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync> | UnwrapFormAsyncValidateOrFn<TOnServer>>;
|
|
451
|
-
errorMap: ValidationErrorMap<UnwrapFormValidateOrFn<TOnMount>, UnwrapFormValidateOrFn<TOnChange>, UnwrapFormAsyncValidateOrFn<TOnChangeAsync>, UnwrapFormValidateOrFn<TOnBlur>, UnwrapFormAsyncValidateOrFn<TOnBlurAsync>, UnwrapFormValidateOrFn<TOnSubmit>, UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>, UnwrapFormAsyncValidateOrFn<TOnServer>>;
|
|
455
|
+
errors: Array<UnwrapFormValidateOrFn<TOnMount> | UnwrapFormValidateOrFn<TOnChange> | UnwrapFormAsyncValidateOrFn<TOnChangeAsync> | UnwrapFormValidateOrFn<TOnBlur> | UnwrapFormAsyncValidateOrFn<TOnBlurAsync> | UnwrapFormValidateOrFn<TOnSubmit> | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync> | UnwrapFormValidateOrFn<TOnDynamic> | UnwrapFormAsyncValidateOrFn<TOnDynamicAsync> | UnwrapFormAsyncValidateOrFn<TOnServer>>;
|
|
456
|
+
errorMap: ValidationErrorMap<UnwrapFormValidateOrFn<TOnMount>, UnwrapFormValidateOrFn<TOnChange>, UnwrapFormAsyncValidateOrFn<TOnChangeAsync>, UnwrapFormValidateOrFn<TOnBlur>, UnwrapFormAsyncValidateOrFn<TOnBlurAsync>, UnwrapFormValidateOrFn<TOnSubmit>, UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>, UnwrapFormValidateOrFn<TOnDynamic>, UnwrapFormAsyncValidateOrFn<TOnDynamicAsync>, UnwrapFormAsyncValidateOrFn<TOnServer>>;
|
|
452
457
|
};
|
|
453
458
|
fields: Record<DeepKeys<TFormData>, {
|
|
454
459
|
errors: ValidationError[];
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const revalidateLogic = ({
|
|
4
|
+
mode = "submit",
|
|
5
|
+
modeAfterSubmission = "change"
|
|
6
|
+
} = {}) => (props) => {
|
|
7
|
+
const validatorNames = Object.keys(props.validators ?? {});
|
|
8
|
+
if (validatorNames.length === 0) {
|
|
9
|
+
return props.runValidation({
|
|
10
|
+
validators: [],
|
|
11
|
+
form: props.form
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
const dynamicValidator = {
|
|
15
|
+
fn: props.event.async ? props.validators["onDynamicAsync"] : props.validators["onDynamic"],
|
|
16
|
+
cause: "dynamic"
|
|
17
|
+
};
|
|
18
|
+
const validatorsToAdd = [];
|
|
19
|
+
const modeToWatch = props.form.state.submissionAttempts === 0 ? mode : modeAfterSubmission;
|
|
20
|
+
if ([modeToWatch, "submit"].includes(props.event.type)) {
|
|
21
|
+
validatorsToAdd.push(dynamicValidator);
|
|
22
|
+
}
|
|
23
|
+
let defaultValidators = [];
|
|
24
|
+
defaultValidationLogic({
|
|
25
|
+
...props,
|
|
26
|
+
runValidation: (vProps) => {
|
|
27
|
+
defaultValidators = vProps.validators;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
if (validatorsToAdd.length === 0) {
|
|
31
|
+
return props.runValidation({
|
|
32
|
+
validators: defaultValidators,
|
|
33
|
+
form: props.form
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return props.runValidation({
|
|
37
|
+
validators: [...defaultValidators, ...validatorsToAdd],
|
|
38
|
+
form: props.form
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
const defaultValidationLogic = (props) => {
|
|
42
|
+
if (!props.validators) {
|
|
43
|
+
return props.runValidation({
|
|
44
|
+
validators: [],
|
|
45
|
+
form: props.form
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
const isAsync = props.event.async;
|
|
49
|
+
const onMountValidator = isAsync ? void 0 : { fn: props.validators.onMount, cause: "mount" };
|
|
50
|
+
const onChangeValidator = {
|
|
51
|
+
fn: isAsync ? props.validators.onChangeAsync : props.validators.onChange,
|
|
52
|
+
cause: "change"
|
|
53
|
+
};
|
|
54
|
+
const onBlurValidator = {
|
|
55
|
+
fn: isAsync ? props.validators.onBlurAsync : props.validators.onBlur,
|
|
56
|
+
cause: "blur"
|
|
57
|
+
};
|
|
58
|
+
const onSubmitValidator = {
|
|
59
|
+
fn: isAsync ? props.validators.onSubmitAsync : props.validators.onSubmit,
|
|
60
|
+
cause: "submit"
|
|
61
|
+
};
|
|
62
|
+
const onServerValidator = isAsync ? void 0 : { fn: () => void 0, cause: "server" };
|
|
63
|
+
switch (props.event.type) {
|
|
64
|
+
case "mount": {
|
|
65
|
+
return props.runValidation({
|
|
66
|
+
validators: [onMountValidator],
|
|
67
|
+
form: props.form
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
case "submit": {
|
|
71
|
+
return props.runValidation({
|
|
72
|
+
validators: [
|
|
73
|
+
onChangeValidator,
|
|
74
|
+
onBlurValidator,
|
|
75
|
+
onSubmitValidator,
|
|
76
|
+
onServerValidator
|
|
77
|
+
],
|
|
78
|
+
form: props.form
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
case "server": {
|
|
82
|
+
return props.runValidation({
|
|
83
|
+
validators: [],
|
|
84
|
+
form: props.form
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
case "blur": {
|
|
88
|
+
return props.runValidation({
|
|
89
|
+
validators: [onBlurValidator, onServerValidator],
|
|
90
|
+
form: props.form
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
case "change": {
|
|
94
|
+
return props.runValidation({
|
|
95
|
+
validators: [onChangeValidator, onServerValidator],
|
|
96
|
+
form: props.form
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
default: {
|
|
100
|
+
throw new Error(`Unknown validation event type: ${props.event.type}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
exports.defaultValidationLogic = defaultValidationLogic;
|
|
105
|
+
exports.revalidateLogic = revalidateLogic;
|
|
106
|
+
//# sourceMappingURL=ValidationLogic.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ValidationLogic.cjs","sources":["../../src/ValidationLogic.ts"],"sourcesContent":["import type { AnyFormApi, FormValidators } from './FormApi'\n\ninterface ValidationLogicValidatorsFn {\n // TODO: Type this properly\n fn: FormValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >[keyof FormValidators<any, any, any, any, any, any, any, any, any, any>]\n cause: 'change' | 'blur' | 'submit' | 'mount' | 'server' | 'dynamic'\n}\n\nexport interface ValidationLogicProps {\n // TODO: Type this properly\n form: AnyFormApi\n // TODO: Type this properly\n validators:\n | FormValidators<any, any, any, any, any, any, any, any, any, any>\n | undefined\n | null\n event: {\n type: 'blur' | 'change' | 'submit' | 'mount' | 'server'\n fieldName?: string\n async: boolean\n }\n runValidation: (props: {\n validators: Array<ValidationLogicValidatorsFn | undefined>\n form: AnyFormApi\n }) => void\n}\n\ninterface RevalidateLogicProps {\n /**\n * @default 'submit'\n *\n * This is the mode that will be used before the form has been submitted.\n * It will run the validation logic on `submit` by default, but can be set to `change` or `blur`.\n */\n mode?: 'change' | 'blur' | 'submit'\n /**\n * @default 'change'\n *\n * This is the mode that will be used after the form has been submitted.\n * It will run the validation logic on `change` by default, but can be set to `blur` or `submit`.\n */\n modeAfterSubmission?: 'change' | 'blur' | 'submit'\n}\n\nexport type ValidationLogicFn = (props: ValidationLogicProps) => void\n\n/**\n * This forces a form's validation logic to be ran as if it were a React Hook Form validation logic.\n *\n * This means that it will only run the `onDynamic` validator, and it will not run any other validators and changes the validation\n * type based on the state of the form itself.\n *\n * When the form is not yet submitted, it will not run the validation logic.\n * When the form is submitted, it will run the validation logic on `change`\n */\nexport const revalidateLogic =\n ({\n mode = 'submit',\n modeAfterSubmission = 'change',\n }: RevalidateLogicProps = {}): ValidationLogicFn =>\n (props) => {\n const validatorNames = Object.keys(props.validators ?? {})\n if (validatorNames.length === 0) {\n // No validators is a valid case, just return\n return props.runValidation({\n validators: [],\n form: props.form,\n })\n }\n\n const dynamicValidator = {\n fn: props.event.async\n ? props.validators!['onDynamicAsync']\n : props.validators!['onDynamic'],\n cause: 'dynamic',\n } as const\n\n const validatorsToAdd = [] as ValidationLogicValidatorsFn[]\n\n const modeToWatch =\n props.form.state.submissionAttempts === 0 ? mode : modeAfterSubmission\n\n if ([modeToWatch, 'submit'].includes(props.event.type)) {\n validatorsToAdd.push(dynamicValidator)\n }\n\n let defaultValidators = [] as ValidationLogicValidatorsFn[]\n\n defaultValidationLogic({\n ...props,\n runValidation: (vProps) => {\n defaultValidators = vProps.validators as ValidationLogicValidatorsFn[]\n },\n })\n\n if (validatorsToAdd.length === 0) {\n return props.runValidation({\n validators: defaultValidators,\n form: props.form,\n })\n }\n\n return props.runValidation({\n validators: [...defaultValidators, ...validatorsToAdd],\n form: props.form,\n })\n }\n\nexport const defaultValidationLogic: ValidationLogicFn = (props) => {\n // Handle case where no validators are provided\n if (!props.validators) {\n return props.runValidation({\n validators: [],\n form: props.form,\n })\n }\n\n const isAsync = props.event.async\n\n const onMountValidator = isAsync\n ? undefined\n : ({ fn: props.validators.onMount, cause: 'mount' } as const)\n\n const onChangeValidator = {\n fn: isAsync ? props.validators.onChangeAsync : props.validators.onChange,\n cause: 'change',\n } as const\n\n const onBlurValidator = {\n fn: isAsync ? props.validators.onBlurAsync : props.validators.onBlur,\n cause: 'blur',\n } as const\n\n const onSubmitValidator = {\n fn: isAsync ? props.validators.onSubmitAsync : props.validators.onSubmit,\n cause: 'submit',\n } as const\n\n // Allows us to clear onServer errors\n const onServerValidator = isAsync\n ? undefined\n : ({ fn: () => undefined, cause: 'server' } as const)\n\n switch (props.event.type) {\n case 'mount': {\n // Run mount validation\n return props.runValidation({\n validators: [onMountValidator],\n form: props.form,\n })\n }\n case 'submit': {\n // Run change, blur, submit, server validation\n return props.runValidation({\n validators: [\n onChangeValidator,\n onBlurValidator,\n onSubmitValidator,\n onServerValidator,\n ],\n form: props.form,\n })\n }\n case 'server': {\n // Run server validation\n return props.runValidation({\n validators: [],\n form: props.form,\n })\n }\n case 'blur': {\n // Run blur, server validation\n return props.runValidation({\n validators: [onBlurValidator, onServerValidator],\n form: props.form,\n })\n }\n case 'change': {\n // Run change, server validation\n return props.runValidation({\n validators: [onChangeValidator, onServerValidator],\n form: props.form,\n })\n }\n default: {\n throw new Error(`Unknown validation event type: ${props.event.type}`)\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { AnyFormApi, FormValidators } from './FormApi.cjs';
|
|
2
|
+
interface ValidationLogicValidatorsFn {
|
|
3
|
+
fn: FormValidators<any, any, any, any, any, any, any, any, any, any>[keyof FormValidators<any, any, any, any, any, any, any, any, any, any>];
|
|
4
|
+
cause: 'change' | 'blur' | 'submit' | 'mount' | 'server' | 'dynamic';
|
|
5
|
+
}
|
|
6
|
+
export interface ValidationLogicProps {
|
|
7
|
+
form: AnyFormApi;
|
|
8
|
+
validators: FormValidators<any, any, any, any, any, any, any, any, any, any> | undefined | null;
|
|
9
|
+
event: {
|
|
10
|
+
type: 'blur' | 'change' | 'submit' | 'mount' | 'server';
|
|
11
|
+
fieldName?: string;
|
|
12
|
+
async: boolean;
|
|
13
|
+
};
|
|
14
|
+
runValidation: (props: {
|
|
15
|
+
validators: Array<ValidationLogicValidatorsFn | undefined>;
|
|
16
|
+
form: AnyFormApi;
|
|
17
|
+
}) => void;
|
|
18
|
+
}
|
|
19
|
+
interface RevalidateLogicProps {
|
|
20
|
+
/**
|
|
21
|
+
* @default 'submit'
|
|
22
|
+
*
|
|
23
|
+
* This is the mode that will be used before the form has been submitted.
|
|
24
|
+
* It will run the validation logic on `submit` by default, but can be set to `change` or `blur`.
|
|
25
|
+
*/
|
|
26
|
+
mode?: 'change' | 'blur' | 'submit';
|
|
27
|
+
/**
|
|
28
|
+
* @default 'change'
|
|
29
|
+
*
|
|
30
|
+
* This is the mode that will be used after the form has been submitted.
|
|
31
|
+
* It will run the validation logic on `change` by default, but can be set to `blur` or `submit`.
|
|
32
|
+
*/
|
|
33
|
+
modeAfterSubmission?: 'change' | 'blur' | 'submit';
|
|
34
|
+
}
|
|
35
|
+
export type ValidationLogicFn = (props: ValidationLogicProps) => void;
|
|
36
|
+
/**
|
|
37
|
+
* This forces a form's validation logic to be ran as if it were a React Hook Form validation logic.
|
|
38
|
+
*
|
|
39
|
+
* This means that it will only run the `onDynamic` validator, and it will not run any other validators and changes the validation
|
|
40
|
+
* type based on the state of the form itself.
|
|
41
|
+
*
|
|
42
|
+
* When the form is not yet submitted, it will not run the validation logic.
|
|
43
|
+
* When the form is submitted, it will run the validation logic on `change`
|
|
44
|
+
*/
|
|
45
|
+
export declare const revalidateLogic: ({ mode, modeAfterSubmission, }?: RevalidateLogicProps) => ValidationLogicFn;
|
|
46
|
+
export declare const defaultValidationLogic: ValidationLogicFn;
|
|
47
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formOptions.cjs","sources":["../../src/formOptions.ts"],"sourcesContent":["import type { FormOptions } from './FormApi'\n\nexport function formOptions<\n T extends Partial<\n FormOptions<any, any, any, any, any, any, any, any, any, any>\n >,\n>(defaultOpts: T) {\n return defaultOpts\n}\n"],"names":[],"mappings":";;AAEO,SAAS,YAId,aAAgB;
|
|
1
|
+
{"version":3,"file":"formOptions.cjs","sources":["../../src/formOptions.ts"],"sourcesContent":["import type { FormOptions } from './FormApi'\n\nexport function formOptions<\n T extends Partial<\n FormOptions<any, any, any, any, any, any, any, any, any, any, any, any>\n >,\n>(defaultOpts: T) {\n return defaultOpts\n}\n"],"names":[],"mappings":";;AAEO,SAAS,YAId,aAAgB;AAChB,SAAO;AACT;;"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { FormOptions } from './FormApi.cjs';
|
|
2
|
-
export declare function formOptions<T extends Partial<FormOptions<any, any, any, any, any, any, any, any, any, any>>>(defaultOpts: T): T;
|
|
2
|
+
export declare function formOptions<T extends Partial<FormOptions<any, any, any, any, any, any, any, any, any, any, any, any>>>(defaultOpts: T): T;
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -7,6 +7,7 @@ const mergeForm = require("./mergeForm.cjs");
|
|
|
7
7
|
const formOptions = require("./formOptions.cjs");
|
|
8
8
|
const standardSchemaValidator = require("./standardSchemaValidator.cjs");
|
|
9
9
|
const FieldGroupApi = require("./FieldGroupApi.cjs");
|
|
10
|
+
const ValidationLogic = require("./ValidationLogic.cjs");
|
|
10
11
|
exports.FormApi = FormApi.FormApi;
|
|
11
12
|
exports.FieldApi = FieldApi.FieldApi;
|
|
12
13
|
exports.concatenatePaths = utils.concatenatePaths;
|
|
@@ -29,4 +30,6 @@ exports.formOptions = formOptions.formOptions;
|
|
|
29
30
|
exports.isStandardSchemaValidator = standardSchemaValidator.isStandardSchemaValidator;
|
|
30
31
|
exports.standardSchemaValidators = standardSchemaValidator.standardSchemaValidators;
|
|
31
32
|
exports.FieldGroupApi = FieldGroupApi.FieldGroupApi;
|
|
33
|
+
exports.defaultValidationLogic = ValidationLogic.defaultValidationLogic;
|
|
34
|
+
exports.revalidateLogic = ValidationLogic.revalidateLogic;
|
|
32
35
|
//# sourceMappingURL=index.cjs.map
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/cjs/index.d.cts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mergeForm.cjs","sources":["../../src/mergeForm.ts"],"sourcesContent":["import type { FormApi } from './FormApi'\n\nfunction isValidKey(key: string | number | symbol): boolean {\n const dangerousProps = ['__proto__', 'constructor', 'prototype']\n return !dangerousProps.includes(String(key))\n}\n\n/**\n * @private\n */\nexport function mutateMergeDeep(\n target: object | null | undefined,\n source: object | null | undefined,\n): object {\n // Early return if either is not an object\n if (target === null || target === undefined || typeof target !== 'object')\n return {} as object\n if (source === null || source === undefined || typeof source !== 'object')\n return target\n\n const targetKeys = Object.keys(target)\n const sourceKeys = Object.keys(source)\n const keySet = new Set([...targetKeys, ...sourceKeys])\n\n for (const key of keySet) {\n if (!isValidKey(key)) continue\n\n const targetKey = key as keyof typeof target\n const sourceKey = key as keyof typeof source\n\n if (!Object.hasOwn(source, sourceKey)) continue\n\n const sourceValue = source[sourceKey] as unknown\n const targetValue = target[targetKey] as unknown\n\n // Handle arrays\n if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {\n Object.defineProperty(target, key, {\n value: [...sourceValue],\n enumerable: true,\n writable: true,\n configurable: true,\n })\n continue\n }\n\n // Handle nested objects (type assertion to satisfy ESLint)\n const isTargetObj = typeof targetValue === 'object' && targetValue !== null\n const isSourceObj = typeof sourceValue === 'object' && sourceValue !== null\n const areObjects =\n isTargetObj &&\n isSourceObj &&\n !Array.isArray(targetValue) &&\n !Array.isArray(sourceValue)\n\n if (areObjects) {\n mutateMergeDeep(targetValue as object, sourceValue as object)\n continue\n }\n\n // Handle all other cases\n Object.defineProperty(target, key, {\n value: sourceValue,\n enumerable: true,\n writable: true,\n configurable: true,\n })\n }\n\n return target\n}\n\nexport function mergeForm<TFormData>(\n baseForm: FormApi<\n NoInfer<TFormData>,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n state: Partial<\n FormApi
|
|
1
|
+
{"version":3,"file":"mergeForm.cjs","sources":["../../src/mergeForm.ts"],"sourcesContent":["import type { FormApi } from './FormApi'\n\nfunction isValidKey(key: string | number | symbol): boolean {\n const dangerousProps = ['__proto__', 'constructor', 'prototype']\n return !dangerousProps.includes(String(key))\n}\n\n/**\n * @private\n */\nexport function mutateMergeDeep(\n target: object | null | undefined,\n source: object | null | undefined,\n): object {\n // Early return if either is not an object\n if (target === null || target === undefined || typeof target !== 'object')\n return {} as object\n if (source === null || source === undefined || typeof source !== 'object')\n return target\n\n const targetKeys = Object.keys(target)\n const sourceKeys = Object.keys(source)\n const keySet = new Set([...targetKeys, ...sourceKeys])\n\n for (const key of keySet) {\n if (!isValidKey(key)) continue\n\n const targetKey = key as keyof typeof target\n const sourceKey = key as keyof typeof source\n\n if (!Object.hasOwn(source, sourceKey)) continue\n\n const sourceValue = source[sourceKey] as unknown\n const targetValue = target[targetKey] as unknown\n\n // Handle arrays\n if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {\n Object.defineProperty(target, key, {\n value: [...sourceValue],\n enumerable: true,\n writable: true,\n configurable: true,\n })\n continue\n }\n\n // Handle nested objects (type assertion to satisfy ESLint)\n const isTargetObj = typeof targetValue === 'object' && targetValue !== null\n const isSourceObj = typeof sourceValue === 'object' && sourceValue !== null\n const areObjects =\n isTargetObj &&\n isSourceObj &&\n !Array.isArray(targetValue) &&\n !Array.isArray(sourceValue)\n\n if (areObjects) {\n mutateMergeDeep(targetValue as object, sourceValue as object)\n continue\n }\n\n // Handle all other cases\n Object.defineProperty(target, key, {\n value: sourceValue,\n enumerable: true,\n writable: true,\n configurable: true,\n })\n }\n\n return target\n}\n\nexport function mergeForm<TFormData>(\n baseForm: FormApi<\n NoInfer<TFormData>,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n state: Partial<\n FormApi<\n TFormData,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >['state']\n >,\n) {\n mutateMergeDeep(baseForm.state, state)\n return baseForm\n}\n"],"names":[],"mappings":";;AAEA,SAAS,WAAW,KAAwC;AAC1D,QAAM,iBAAiB,CAAC,aAAa,eAAe,WAAW;AAC/D,SAAO,CAAC,eAAe,SAAS,OAAO,GAAG,CAAC;AAC7C;AAKO,SAAS,gBACd,QACA,QACQ;AAER,MAAI,WAAW,QAAQ,WAAW,UAAa,OAAO,WAAW;AAC/D,WAAO,CAAA;AACT,MAAI,WAAW,QAAQ,WAAW,UAAa,OAAO,WAAW;AAC/D,WAAO;AAET,QAAM,aAAa,OAAO,KAAK,MAAM;AACrC,QAAM,aAAa,OAAO,KAAK,MAAM;AACrC,QAAM,6BAAa,IAAI,CAAC,GAAG,YAAY,GAAG,UAAU,CAAC;AAErD,aAAW,OAAO,QAAQ;AACxB,QAAI,CAAC,WAAW,GAAG,EAAG;AAEtB,UAAM,YAAY;AAClB,UAAM,YAAY;AAElB,QAAI,CAAC,OAAO,OAAO,QAAQ,SAAS,EAAG;AAEvC,UAAM,cAAc,OAAO,SAAS;AACpC,UAAM,cAAc,OAAO,SAAS;AAGpC,QAAI,MAAM,QAAQ,WAAW,KAAK,MAAM,QAAQ,WAAW,GAAG;AAC5D,aAAO,eAAe,QAAQ,KAAK;AAAA,QACjC,OAAO,CAAC,GAAG,WAAW;AAAA,QACtB,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,cAAc;AAAA,MAAA,CACf;AACD;AAAA,IACF;AAGA,UAAM,cAAc,OAAO,gBAAgB,YAAY,gBAAgB;AACvE,UAAM,cAAc,OAAO,gBAAgB,YAAY,gBAAgB;AACvE,UAAM,aACJ,eACA,eACA,CAAC,MAAM,QAAQ,WAAW,KAC1B,CAAC,MAAM,QAAQ,WAAW;AAE5B,QAAI,YAAY;AACd,sBAAgB,aAAuB,WAAqB;AAC5D;AAAA,IACF;AAGA,WAAO,eAAe,QAAQ,KAAK;AAAA,MACjC,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,cAAc;AAAA,IAAA,CACf;AAAA,EACH;AAEA,SAAO;AACT;AAEO,SAAS,UACd,UAcA,OAgBA;AACA,kBAAgB,SAAS,OAAO,KAAK;AACrC,SAAO;AACT;;;"}
|
package/dist/cjs/mergeForm.d.cts
CHANGED
|
@@ -3,4 +3,4 @@ import { FormApi } from './FormApi.cjs';
|
|
|
3
3
|
* @private
|
|
4
4
|
*/
|
|
5
5
|
export declare function mutateMergeDeep(target: object | null | undefined, source: object | null | undefined): object;
|
|
6
|
-
export declare function mergeForm<TFormData>(baseForm: FormApi<NoInfer<TFormData>, any, any, any, any, any, any, any, any, any>, state: Partial<FormApi<TFormData, any, any, any, any, any, any, any, any, any>['state']>): FormApi<NoInfer<TFormData>, any, any, any, any, any, any, any, any, any>;
|
|
6
|
+
export declare function mergeForm<TFormData>(baseForm: FormApi<NoInfer<TFormData>, any, any, any, any, any, any, any, any, any, any, any>, state: Partial<FormApi<TFormData, any, any, any, any, any, any, any, any, any, any, any>['state']>): FormApi<NoInfer<TFormData>, any, any, any, any, any, any, any, any, any, any, any>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metaHelper.cjs","sources":["../../src/metaHelper.ts"],"sourcesContent":["import type {\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\nimport type { AnyFieldMeta } from './FieldApi'\nimport type { DeepKeys } from './util-types'\n\ntype ArrayFieldMode = 'insert' | 'remove' | 'swap' | 'move'\n\nexport const defaultFieldMeta: AnyFieldMeta = {\n isValidating: false,\n isTouched: false,\n isBlurred: false,\n isDirty: false,\n isPristine: true,\n isValid: true,\n isDefaultValue: true,\n errors: [],\n errorMap: {},\n errorSourceMap: {},\n}\n\nexport function metaHelper<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta,\n>(\n formApi: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >,\n) {\n function handleArrayFieldMetaShift(\n field: DeepKeys<TFormData>,\n index: number,\n mode: ArrayFieldMode,\n secondIndex?: number,\n ) {\n const affectedFields = getAffectedFields(field, index, mode, secondIndex)\n\n const handlers = {\n insert: () => handleInsertMode(affectedFields, field, index),\n remove: () => handleRemoveMode(affectedFields),\n swap: () =>\n secondIndex !== undefined &&\n handleSwapMode(affectedFields, field, index, secondIndex),\n move: () =>\n secondIndex !== undefined &&\n handleMoveMode(affectedFields, field, index, secondIndex),\n }\n\n handlers[mode]()\n }\n\n function getFieldPath(field: DeepKeys<TFormData>, index: number): string {\n return `${field}[${index}]`\n }\n\n function getAffectedFields(\n field: DeepKeys<TFormData>,\n index: number,\n mode: ArrayFieldMode,\n secondIndex?: number,\n ): DeepKeys<TFormData>[] {\n const affectedFieldKeys = [getFieldPath(field, index)]\n\n if (mode === 'swap') {\n affectedFieldKeys.push(getFieldPath(field, secondIndex!))\n } else if (mode === 'move') {\n const [startIndex, endIndex] = [\n Math.min(index, secondIndex!),\n Math.max(index, secondIndex!),\n ]\n for (let i = startIndex; i <= endIndex; i++) {\n affectedFieldKeys.push(getFieldPath(field, i))\n }\n } else {\n const currentValue = formApi.getFieldValue(field)\n const fieldItems = Array.isArray(currentValue)\n ? (currentValue as Array<unknown>).length\n : 0\n for (let i = index + 1; i < fieldItems; i++) {\n affectedFieldKeys.push(getFieldPath(field, i))\n }\n }\n\n return Object.keys(formApi.fieldInfo).filter((fieldKey) =>\n affectedFieldKeys.some((key) => fieldKey.startsWith(key)),\n ) as DeepKeys<TFormData>[]\n }\n\n function updateIndex(\n fieldKey: string,\n direction: 'up' | 'down',\n ): DeepKeys<TFormData> {\n return fieldKey.replace(/\\[(\\d+)\\]/, (_, num) => {\n const currIndex = parseInt(num, 10)\n const newIndex =\n direction === 'up' ? currIndex + 1 : Math.max(0, currIndex - 1)\n return `[${newIndex}]`\n }) as DeepKeys<TFormData>\n }\n\n function shiftMeta(fields: DeepKeys<TFormData>[], direction: 'up' | 'down') {\n const sortedFields = direction === 'up' ? fields : [...fields].reverse()\n\n sortedFields.forEach((fieldKey) => {\n const nextFieldKey = updateIndex(fieldKey.toString(), direction)\n const nextFieldMeta = formApi.getFieldMeta(nextFieldKey)\n if (nextFieldMeta) {\n formApi.setFieldMeta(fieldKey, nextFieldMeta)\n } else {\n formApi.setFieldMeta(fieldKey, getEmptyFieldMeta())\n }\n })\n }\n\n const getEmptyFieldMeta = (): AnyFieldMeta => defaultFieldMeta\n\n const handleInsertMode = (\n fields: DeepKeys<TFormData>[],\n field: DeepKeys<TFormData>,\n insertIndex: number,\n ) => {\n shiftMeta(fields, 'down')\n\n fields.forEach((fieldKey) => {\n if (fieldKey.toString().startsWith(getFieldPath(field, insertIndex))) {\n formApi.setFieldMeta(fieldKey, getEmptyFieldMeta())\n }\n })\n }\n\n const handleRemoveMode = (fields: DeepKeys<TFormData>[]) => {\n shiftMeta(fields, 'up')\n }\n\n const handleMoveMode = (\n fields: DeepKeys<TFormData>[],\n field: DeepKeys<TFormData>,\n fromIndex: number,\n toIndex: number,\n ) => {\n // Store the original field meta that will be reapplied at the destination index\n const fromFields = new Map(\n Object.keys(formApi.fieldInfo)\n .filter((fieldKey) =>\n fieldKey.startsWith(getFieldPath(field, fromIndex)),\n )\n .map((fieldKey) => [\n fieldKey as DeepKeys<TFormData>,\n formApi.getFieldMeta(fieldKey as DeepKeys<TFormData>),\n ]),\n )\n\n shiftMeta(fields, fromIndex < toIndex ? 'up' : 'down')\n\n // Reapply the stored field meta at the destination index\n Object.keys(formApi.fieldInfo)\n .filter((fieldKey) => fieldKey.startsWith(getFieldPath(field, toIndex)))\n .forEach((fieldKey) => {\n const fromKey = fieldKey.replace(\n getFieldPath(field, toIndex),\n getFieldPath(field, fromIndex),\n ) as DeepKeys<TFormData>\n\n const fromMeta = fromFields.get(fromKey)\n if (fromMeta) {\n formApi.setFieldMeta(fieldKey as DeepKeys<TFormData>, fromMeta)\n }\n })\n }\n\n const handleSwapMode = (\n fields: DeepKeys<TFormData>[],\n field: DeepKeys<TFormData>,\n index: number,\n secondIndex: number,\n ) => {\n fields.forEach((fieldKey) => {\n if (!fieldKey.toString().startsWith(getFieldPath(field, index))) return\n\n const swappedKey = fieldKey\n .toString()\n .replace(\n getFieldPath(field, index),\n getFieldPath(field, secondIndex),\n ) as DeepKeys<TFormData>\n\n const [meta1, meta2] = [\n formApi.getFieldMeta(fieldKey),\n formApi.getFieldMeta(swappedKey),\n ]\n\n if (meta1) formApi.setFieldMeta(swappedKey, meta1)\n if (meta2) formApi.setFieldMeta(fieldKey, meta2)\n })\n }\n\n return { handleArrayFieldMetaShift }\n}\n"],"names":[],"mappings":";;AAUO,MAAM,mBAAiC;AAAA,EAC5C,cAAc;AAAA,EACd,WAAW;AAAA,EACX,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,QAAQ,
|
|
1
|
+
{"version":3,"file":"metaHelper.cjs","sources":["../../src/metaHelper.ts"],"sourcesContent":["import type {\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\nimport type { AnyFieldMeta } from './FieldApi'\nimport type { DeepKeys } from './util-types'\n\ntype ArrayFieldMode = 'insert' | 'remove' | 'swap' | 'move'\n\nexport const defaultFieldMeta: AnyFieldMeta = {\n isValidating: false,\n isTouched: false,\n isBlurred: false,\n isDirty: false,\n isPristine: true,\n isValid: true,\n isDefaultValue: true,\n errors: [],\n errorMap: {},\n errorSourceMap: {},\n}\n\nexport function metaHelper<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta,\n>(\n formApi: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n) {\n function handleArrayFieldMetaShift(\n field: DeepKeys<TFormData>,\n index: number,\n mode: ArrayFieldMode,\n secondIndex?: number,\n ) {\n const affectedFields = getAffectedFields(field, index, mode, secondIndex)\n\n const handlers = {\n insert: () => handleInsertMode(affectedFields, field, index),\n remove: () => handleRemoveMode(affectedFields),\n swap: () =>\n secondIndex !== undefined &&\n handleSwapMode(affectedFields, field, index, secondIndex),\n move: () =>\n secondIndex !== undefined &&\n handleMoveMode(affectedFields, field, index, secondIndex),\n }\n\n handlers[mode]()\n }\n\n function getFieldPath(field: DeepKeys<TFormData>, index: number): string {\n return `${field}[${index}]`\n }\n\n function getAffectedFields(\n field: DeepKeys<TFormData>,\n index: number,\n mode: ArrayFieldMode,\n secondIndex?: number,\n ): DeepKeys<TFormData>[] {\n const affectedFieldKeys = [getFieldPath(field, index)]\n\n if (mode === 'swap') {\n affectedFieldKeys.push(getFieldPath(field, secondIndex!))\n } else if (mode === 'move') {\n const [startIndex, endIndex] = [\n Math.min(index, secondIndex!),\n Math.max(index, secondIndex!),\n ]\n for (let i = startIndex; i <= endIndex; i++) {\n affectedFieldKeys.push(getFieldPath(field, i))\n }\n } else {\n const currentValue = formApi.getFieldValue(field)\n const fieldItems = Array.isArray(currentValue)\n ? (currentValue as Array<unknown>).length\n : 0\n for (let i = index + 1; i < fieldItems; i++) {\n affectedFieldKeys.push(getFieldPath(field, i))\n }\n }\n\n return Object.keys(formApi.fieldInfo).filter((fieldKey) =>\n affectedFieldKeys.some((key) => fieldKey.startsWith(key)),\n ) as DeepKeys<TFormData>[]\n }\n\n function updateIndex(\n fieldKey: string,\n direction: 'up' | 'down',\n ): DeepKeys<TFormData> {\n return fieldKey.replace(/\\[(\\d+)\\]/, (_, num) => {\n const currIndex = parseInt(num, 10)\n const newIndex =\n direction === 'up' ? currIndex + 1 : Math.max(0, currIndex - 1)\n return `[${newIndex}]`\n }) as DeepKeys<TFormData>\n }\n\n function shiftMeta(fields: DeepKeys<TFormData>[], direction: 'up' | 'down') {\n const sortedFields = direction === 'up' ? fields : [...fields].reverse()\n\n sortedFields.forEach((fieldKey) => {\n const nextFieldKey = updateIndex(fieldKey.toString(), direction)\n const nextFieldMeta = formApi.getFieldMeta(nextFieldKey)\n if (nextFieldMeta) {\n formApi.setFieldMeta(fieldKey, nextFieldMeta)\n } else {\n formApi.setFieldMeta(fieldKey, getEmptyFieldMeta())\n }\n })\n }\n\n const getEmptyFieldMeta = (): AnyFieldMeta => defaultFieldMeta\n\n const handleInsertMode = (\n fields: DeepKeys<TFormData>[],\n field: DeepKeys<TFormData>,\n insertIndex: number,\n ) => {\n shiftMeta(fields, 'down')\n\n fields.forEach((fieldKey) => {\n if (fieldKey.toString().startsWith(getFieldPath(field, insertIndex))) {\n formApi.setFieldMeta(fieldKey, getEmptyFieldMeta())\n }\n })\n }\n\n const handleRemoveMode = (fields: DeepKeys<TFormData>[]) => {\n shiftMeta(fields, 'up')\n }\n\n const handleMoveMode = (\n fields: DeepKeys<TFormData>[],\n field: DeepKeys<TFormData>,\n fromIndex: number,\n toIndex: number,\n ) => {\n // Store the original field meta that will be reapplied at the destination index\n const fromFields = new Map(\n Object.keys(formApi.fieldInfo)\n .filter((fieldKey) =>\n fieldKey.startsWith(getFieldPath(field, fromIndex)),\n )\n .map((fieldKey) => [\n fieldKey as DeepKeys<TFormData>,\n formApi.getFieldMeta(fieldKey as DeepKeys<TFormData>),\n ]),\n )\n\n shiftMeta(fields, fromIndex < toIndex ? 'up' : 'down')\n\n // Reapply the stored field meta at the destination index\n Object.keys(formApi.fieldInfo)\n .filter((fieldKey) => fieldKey.startsWith(getFieldPath(field, toIndex)))\n .forEach((fieldKey) => {\n const fromKey = fieldKey.replace(\n getFieldPath(field, toIndex),\n getFieldPath(field, fromIndex),\n ) as DeepKeys<TFormData>\n\n const fromMeta = fromFields.get(fromKey)\n if (fromMeta) {\n formApi.setFieldMeta(fieldKey as DeepKeys<TFormData>, fromMeta)\n }\n })\n }\n\n const handleSwapMode = (\n fields: DeepKeys<TFormData>[],\n field: DeepKeys<TFormData>,\n index: number,\n secondIndex: number,\n ) => {\n fields.forEach((fieldKey) => {\n if (!fieldKey.toString().startsWith(getFieldPath(field, index))) return\n\n const swappedKey = fieldKey\n .toString()\n .replace(\n getFieldPath(field, index),\n getFieldPath(field, secondIndex),\n ) as DeepKeys<TFormData>\n\n const [meta1, meta2] = [\n formApi.getFieldMeta(fieldKey),\n formApi.getFieldMeta(swappedKey),\n ]\n\n if (meta1) formApi.setFieldMeta(swappedKey, meta1)\n if (meta2) formApi.setFieldMeta(fieldKey, meta2)\n })\n }\n\n return { handleArrayFieldMetaShift }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import { AnyFieldMeta } from './FieldApi.cjs';
|
|
|
3
3
|
import { DeepKeys } from './util-types.cjs';
|
|
4
4
|
type ArrayFieldMode = 'insert' | 'remove' | 'swap' | 'move';
|
|
5
5
|
export declare const defaultFieldMeta: AnyFieldMeta;
|
|
6
|
-
export declare function metaHelper<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, TSubmitMeta>(formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>): {
|
|
6
|
+
export declare function metaHelper<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnDynamic extends undefined | FormValidateOrFn<TFormData>, TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, TSubmitMeta>(formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>): {
|
|
7
7
|
handleArrayFieldMetaShift: (field: DeepKeys<TFormData>, index: number, mode: ArrayFieldMode, secondIndex?: number) => void;
|
|
8
8
|
};
|
|
9
9
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standardSchemaValidator.cjs","sources":["../../src/standardSchemaValidator.ts"],"sourcesContent":["import type { ValidationSource } from './types'\n\nexport type TStandardSchemaValidatorValue<\n TData,\n TSource extends ValidationSource = ValidationSource,\n> = {\n value: TData\n validationSource: TSource\n}\n\nexport type TStandardSchemaValidatorIssue<\n TSource extends ValidationSource = ValidationSource,\n> = TSource extends 'form'\n ? {\n form: Record<string, StandardSchemaV1Issue[]>\n fields: Record<string, StandardSchemaV1Issue[]>\n }\n : TSource extends 'field'\n ? StandardSchemaV1Issue[]\n : never\n\nfunction prefixSchemaToErrors(issues: readonly StandardSchemaV1Issue[]) {\n const schema = new Map<string, StandardSchemaV1Issue[]>()\n\n for (const issue of issues) {\n const path = [...(issue.path ?? [])]\n .map((segment) => {\n const normalizedSegment =\n typeof segment === 'object' ? segment.key : segment\n return typeof normalizedSegment === 'number'\n ? `[${normalizedSegment}]`\n : normalizedSegment\n })\n .join('.')\n .replace(/\\.\\[/g, '[')\n\n schema.set(path, (schema.get(path) ?? []).concat(issue))\n }\n\n return Object.fromEntries(schema)\n}\n\nconst transformFormIssues = <TSource extends ValidationSource>(\n issues: readonly StandardSchemaV1Issue[],\n): TStandardSchemaValidatorIssue<TSource> => {\n const schemaErrors = prefixSchemaToErrors(issues)\n return {\n form: schemaErrors,\n fields: schemaErrors,\n } as TStandardSchemaValidatorIssue<TSource>\n}\n\nexport const standardSchemaValidators = {\n validate<TSource extends ValidationSource = ValidationSource>(\n {\n value,\n validationSource,\n }: TStandardSchemaValidatorValue<unknown, TSource>,\n schema: StandardSchemaV1,\n ): TStandardSchemaValidatorIssue<TSource> | undefined {\n const result = schema['~standard'].validate(value)\n\n if (result instanceof Promise) {\n throw new Error('async function passed to sync validator')\n }\n\n if (!result.issues) return\n\n if (validationSource === 'field')\n return result.issues as TStandardSchemaValidatorIssue<TSource>\n return transformFormIssues<TSource>(result.issues)\n },\n async validateAsync<TSource extends ValidationSource>(\n {\n value,\n validationSource,\n }: TStandardSchemaValidatorValue<unknown, TSource>,\n schema: StandardSchemaV1,\n ): Promise<TStandardSchemaValidatorIssue<TSource> | undefined> {\n const result = await schema['~standard'].validate(value)\n\n if (!result.issues) return\n\n if (validationSource === 'field')\n return result.issues as TStandardSchemaValidatorIssue<TSource>\n return transformFormIssues<TSource>(result.issues)\n },\n}\n\nexport const isStandardSchemaValidator = (\n validator: unknown,\n): validator is StandardSchemaV1 =>\n !!validator && '~standard' in (validator as object)\n\n/**\n * The Standard Schema interface.\n */\nexport type StandardSchemaV1<Input = unknown, Output = Input> = {\n /**\n * The Standard Schema properties.\n */\n readonly '~standard': StandardSchemaV1Props<Input, Output>\n}\n\n/**\n * The Standard Schema properties interface.\n */\ninterface StandardSchemaV1Props<Input = unknown, Output = Input> {\n /**\n * The version number of the standard.\n */\n readonly version: 1\n /**\n * The vendor name of the schema library.\n */\n readonly vendor: string\n /**\n * Validates unknown input values.\n */\n readonly validate: (\n value: unknown,\n ) => StandardSchemaV1Result<Output> | Promise<StandardSchemaV1Result<Output>>\n /**\n * Inferred types associated with the schema.\n */\n readonly types?: StandardSchemaV1Types<Input, Output> | undefined\n}\n/**\n * The result interface of the validate function.\n */\ntype StandardSchemaV1Result<Output> =\n | StandardSchemaV1SuccessResult<Output>\n | StandardSchemaV1FailureResult\n/**\n * The result interface if validation succeeds.\n */\ninterface StandardSchemaV1SuccessResult<Output> {\n /**\n * The typed output value.\n */\n readonly value: Output\n /**\n * The non-existent issues.\n */\n readonly issues?: undefined\n}\n/**\n * The result interface if validation fails.\n */\ninterface StandardSchemaV1FailureResult {\n /**\n * The issues of failed validation.\n */\n readonly issues: ReadonlyArray<StandardSchemaV1Issue>\n}\n/**\n * The issue interface of the failure output.\n */\nexport interface StandardSchemaV1Issue {\n /**\n * The error message of the issue.\n */\n readonly message: string\n /**\n * The path of the issue, if any.\n */\n readonly path?:\n | ReadonlyArray<PropertyKey | StandardSchemaV1PathSegment>\n | undefined\n}\n/**\n * The path segment interface of the issue.\n */\ninterface StandardSchemaV1PathSegment {\n /**\n * The key representing a path segment.\n */\n readonly key: PropertyKey\n}\n/**\n * The Standard Schema types interface.\n */\ninterface StandardSchemaV1Types<Input = unknown, Output = Input> {\n /**\n * The input type of the schema.\n */\n readonly input: Input\n /**\n * The output type of the schema.\n */\n readonly output: Output\n}\n"],"names":[],"mappings":";;AAqBA,SAAS,qBAAqB,QAA0C;
|
|
1
|
+
{"version":3,"file":"standardSchemaValidator.cjs","sources":["../../src/standardSchemaValidator.ts"],"sourcesContent":["import type { ValidationSource } from './types'\n\nexport type TStandardSchemaValidatorValue<\n TData,\n TSource extends ValidationSource = ValidationSource,\n> = {\n value: TData\n validationSource: TSource\n}\n\nexport type TStandardSchemaValidatorIssue<\n TSource extends ValidationSource = ValidationSource,\n> = TSource extends 'form'\n ? {\n form: Record<string, StandardSchemaV1Issue[]>\n fields: Record<string, StandardSchemaV1Issue[]>\n }\n : TSource extends 'field'\n ? StandardSchemaV1Issue[]\n : never\n\nfunction prefixSchemaToErrors(issues: readonly StandardSchemaV1Issue[]) {\n const schema = new Map<string, StandardSchemaV1Issue[]>()\n\n for (const issue of issues) {\n const path = [...(issue.path ?? [])]\n .map((segment) => {\n const normalizedSegment =\n typeof segment === 'object' ? segment.key : segment\n return typeof normalizedSegment === 'number'\n ? `[${normalizedSegment}]`\n : normalizedSegment\n })\n .join('.')\n .replace(/\\.\\[/g, '[')\n\n schema.set(path, (schema.get(path) ?? []).concat(issue))\n }\n\n return Object.fromEntries(schema)\n}\n\nconst transformFormIssues = <TSource extends ValidationSource>(\n issues: readonly StandardSchemaV1Issue[],\n): TStandardSchemaValidatorIssue<TSource> => {\n const schemaErrors = prefixSchemaToErrors(issues)\n return {\n form: schemaErrors,\n fields: schemaErrors,\n } as TStandardSchemaValidatorIssue<TSource>\n}\n\nexport const standardSchemaValidators = {\n validate<TSource extends ValidationSource = ValidationSource>(\n {\n value,\n validationSource,\n }: TStandardSchemaValidatorValue<unknown, TSource>,\n schema: StandardSchemaV1,\n ): TStandardSchemaValidatorIssue<TSource> | undefined {\n const result = schema['~standard'].validate(value)\n\n if (result instanceof Promise) {\n throw new Error('async function passed to sync validator')\n }\n\n if (!result.issues) return\n\n if (validationSource === 'field')\n return result.issues as TStandardSchemaValidatorIssue<TSource>\n return transformFormIssues<TSource>(result.issues)\n },\n async validateAsync<TSource extends ValidationSource>(\n {\n value,\n validationSource,\n }: TStandardSchemaValidatorValue<unknown, TSource>,\n schema: StandardSchemaV1,\n ): Promise<TStandardSchemaValidatorIssue<TSource> | undefined> {\n const result = await schema['~standard'].validate(value)\n\n if (!result.issues) return\n\n if (validationSource === 'field')\n return result.issues as TStandardSchemaValidatorIssue<TSource>\n return transformFormIssues<TSource>(result.issues)\n },\n}\n\nexport const isStandardSchemaValidator = (\n validator: unknown,\n): validator is StandardSchemaV1 =>\n !!validator && '~standard' in (validator as object)\n\n/**\n * The Standard Schema interface.\n */\nexport type StandardSchemaV1<Input = unknown, Output = Input> = {\n /**\n * The Standard Schema properties.\n */\n readonly '~standard': StandardSchemaV1Props<Input, Output>\n}\n\n/**\n * The Standard Schema properties interface.\n */\ninterface StandardSchemaV1Props<Input = unknown, Output = Input> {\n /**\n * The version number of the standard.\n */\n readonly version: 1\n /**\n * The vendor name of the schema library.\n */\n readonly vendor: string\n /**\n * Validates unknown input values.\n */\n readonly validate: (\n value: unknown,\n ) => StandardSchemaV1Result<Output> | Promise<StandardSchemaV1Result<Output>>\n /**\n * Inferred types associated with the schema.\n */\n readonly types?: StandardSchemaV1Types<Input, Output> | undefined\n}\n/**\n * The result interface of the validate function.\n */\ntype StandardSchemaV1Result<Output> =\n | StandardSchemaV1SuccessResult<Output>\n | StandardSchemaV1FailureResult\n/**\n * The result interface if validation succeeds.\n */\ninterface StandardSchemaV1SuccessResult<Output> {\n /**\n * The typed output value.\n */\n readonly value: Output\n /**\n * The non-existent issues.\n */\n readonly issues?: undefined\n}\n/**\n * The result interface if validation fails.\n */\ninterface StandardSchemaV1FailureResult {\n /**\n * The issues of failed validation.\n */\n readonly issues: ReadonlyArray<StandardSchemaV1Issue>\n}\n/**\n * The issue interface of the failure output.\n */\nexport interface StandardSchemaV1Issue {\n /**\n * The error message of the issue.\n */\n readonly message: string\n /**\n * The path of the issue, if any.\n */\n readonly path?:\n | ReadonlyArray<PropertyKey | StandardSchemaV1PathSegment>\n | undefined\n}\n/**\n * The path segment interface of the issue.\n */\ninterface StandardSchemaV1PathSegment {\n /**\n * The key representing a path segment.\n */\n readonly key: PropertyKey\n}\n/**\n * The Standard Schema types interface.\n */\ninterface StandardSchemaV1Types<Input = unknown, Output = Input> {\n /**\n * The input type of the schema.\n */\n readonly input: Input\n /**\n * The output type of the schema.\n */\n readonly output: Output\n}\n"],"names":[],"mappings":";;AAqBA,SAAS,qBAAqB,QAA0C;AACtE,QAAM,6BAAa,IAAA;AAEnB,aAAW,SAAS,QAAQ;AAC1B,UAAM,OAAO,CAAC,GAAI,MAAM,QAAQ,CAAA,CAAG,EAChC,IAAI,CAAC,YAAY;AAChB,YAAM,oBACJ,OAAO,YAAY,WAAW,QAAQ,MAAM;AAC9C,aAAO,OAAO,sBAAsB,WAChC,IAAI,iBAAiB,MACrB;AAAA,IACN,CAAC,EACA,KAAK,GAAG,EACR,QAAQ,SAAS,GAAG;AAEvB,WAAO,IAAI,OAAO,OAAO,IAAI,IAAI,KAAK,CAAA,GAAI,OAAO,KAAK,CAAC;AAAA,EACzD;AAEA,SAAO,OAAO,YAAY,MAAM;AAClC;AAEA,MAAM,sBAAsB,CAC1B,WAC2C;AAC3C,QAAM,eAAe,qBAAqB,MAAM;AAChD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,EAAA;AAEZ;AAEO,MAAM,2BAA2B;AAAA,EACtC,SACE;AAAA,IACE;AAAA,IACA;AAAA,EAAA,GAEF,QACoD;AACpD,UAAM,SAAS,OAAO,WAAW,EAAE,SAAS,KAAK;AAEjD,QAAI,kBAAkB,SAAS;AAC7B,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAEA,QAAI,CAAC,OAAO,OAAQ;AAEpB,QAAI,qBAAqB;AACvB,aAAO,OAAO;AAChB,WAAO,oBAA6B,OAAO,MAAM;AAAA,EACnD;AAAA,EACA,MAAM,cACJ;AAAA,IACE;AAAA,IACA;AAAA,EAAA,GAEF,QAC6D;AAC7D,UAAM,SAAS,MAAM,OAAO,WAAW,EAAE,SAAS,KAAK;AAEvD,QAAI,CAAC,OAAO,OAAQ;AAEpB,QAAI,qBAAqB;AACvB,aAAO,OAAO;AAChB,WAAO,oBAA6B,OAAO,MAAM;AAAA,EACnD;AACF;AAEO,MAAM,4BAA4B,CACvC,cAEA,CAAC,CAAC,aAAa,eAAgB;;;"}
|