@tanstack/form-core
Advanced tools
Comparing version 0.32.0 to 0.33.0
import { Store } from '@tanstack/store'; | ||
import { FieldInfo, FieldsErrorMapFromValidator, FormApi } from './FormApi.js'; | ||
import { UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap, Validator } from './types.js'; | ||
import { UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap, ValidationSource, Validator } from './types.js'; | ||
import { Updater } from './utils.js'; | ||
@@ -226,2 +226,3 @@ import { DeepKeys, DeepValue, NoInfer } from './util-types.js'; | ||
fieldApi: FieldApi<any, any, any, any>; | ||
validationSource: ValidationSource; | ||
}, TType extends 'validate' | 'validateAsync'>(props: { | ||
@@ -231,3 +232,3 @@ validate: TType extends 'validate' ? FieldValidateOrFn<any, any, any, any> : FieldAsyncValidateOrFn<any, any, any, any>; | ||
type: TType; | ||
}): ReturnType<ReturnType<Validator<any>>[TType]>; | ||
}): TType extends 'validate' ? ValidationError : Promise<ValidationError>; | ||
/** | ||
@@ -234,0 +235,0 @@ * Mounts the field instance to the form. |
@@ -31,3 +31,4 @@ import { Store } from "@tanstack/store"; | ||
value: this.state.value, | ||
fieldApi: this | ||
fieldApi: this, | ||
validationSource: "field" | ||
}, | ||
@@ -134,3 +135,7 @@ type: "validate" | ||
validate: validateObj.validate, | ||
value: { value: field.getValue(), fieldApi: field }, | ||
value: { | ||
value: field.getValue(), | ||
validationSource: "field", | ||
fieldApi: field | ||
}, | ||
type: "validate" | ||
@@ -221,3 +226,4 @@ }) | ||
fieldApi: field, | ||
signal: controller.signal | ||
signal: controller.signal, | ||
validationSource: "field" | ||
}, | ||
@@ -224,0 +230,0 @@ type: "validateAsync" |
@@ -5,3 +5,3 @@ import { Store } from '@tanstack/store'; | ||
import { FieldApi, FieldMeta } from './FieldApi.js'; | ||
import { FormValidationError, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap, ValidationErrorMapKeys, Validator } from './types.js'; | ||
import { FormValidationError, FormValidationErrorMap, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap, ValidationErrorMapKeys, ValidationSource, Validator } from './types.js'; | ||
export type FieldsErrorMapFromValidator<TFormData> = Partial<Record<DeepKeys<TFormData>, ValidationErrorMap>>; | ||
@@ -164,3 +164,3 @@ export type FormValidateFn<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = (props: { | ||
*/ | ||
errorMap: ValidationErrorMap; | ||
errorMap: FormValidationErrorMap; | ||
/** | ||
@@ -265,2 +265,3 @@ * An internal mechanism used for keeping track of validation logic in a form. | ||
formApi: FormApi<any, any>; | ||
validationSource: ValidationSource; | ||
}, TType extends 'validate' | 'validateAsync'>(props: { | ||
@@ -267,0 +268,0 @@ validate: TType extends 'validate' ? FormValidateOrFn<TFormData, TFormValidator> : FormAsyncValidateOrFn<TFormData, TFormValidator>; |
@@ -32,2 +32,5 @@ import { Store } from "@tanstack/store"; | ||
} | ||
const isFormValidationError = (error) => { | ||
return typeof error === "object"; | ||
}; | ||
class FormApi { | ||
@@ -49,3 +52,4 @@ /** | ||
value: this.state.values, | ||
formApi: this | ||
formApi: this, | ||
validationSource: "form" | ||
}, | ||
@@ -160,3 +164,4 @@ type: "validate" | ||
value: this.state.values, | ||
formApi: this | ||
formApi: this, | ||
validationSource: "form" | ||
}, | ||
@@ -243,2 +248,3 @@ type: "validate" | ||
formApi: this, | ||
validationSource: "form", | ||
signal: controller.signal | ||
@@ -543,5 +549,13 @@ }, | ||
const isValidating = isFieldsValidating || state.isFormValidating; | ||
state.errors = Object.values(state.errorMap).filter( | ||
(val) => val !== void 0 | ||
); | ||
state.errors = Object.values(state.errorMap).reduce((prev, curr) => { | ||
if (curr === void 0) return prev; | ||
if (typeof curr === "string") { | ||
prev.push(curr); | ||
return prev; | ||
} else if (curr && isFormValidationError(curr)) { | ||
prev.push(curr.form); | ||
return prev; | ||
} | ||
return prev; | ||
}, []); | ||
const isFormValid = state.errors.length === 0; | ||
@@ -548,0 +562,0 @@ const isValid = isFieldsValid && isFormValid; |
import { DeepKeys } from './util-types.js'; | ||
export type ValidationError = undefined | false | null | string; | ||
export type ValidationSource = 'form' | 'field'; | ||
/** | ||
@@ -10,6 +11,8 @@ * If/when TypeScript supports higher-kinded types, this should not be `unknown` anymore | ||
value: Type; | ||
}, fn: Fn): ValidationError; | ||
validationSource: ValidationSource; | ||
}, fn: Fn): ValidationError | FormValidationError<unknown>; | ||
validateAsync(options: { | ||
value: Type; | ||
}, fn: Fn): Promise<ValidationError>; | ||
validationSource: ValidationSource; | ||
}, fn: Fn): Promise<ValidationError | FormValidationError<unknown>>; | ||
}; | ||
@@ -40,2 +43,8 @@ /** | ||
* @private | ||
*/ | ||
export type FormValidationErrorMap = { | ||
[K in ValidationErrorMapKeys]?: ValidationError | FormValidationError<unknown>; | ||
}; | ||
/** | ||
* @private | ||
* | ||
@@ -42,0 +51,0 @@ * @example |
@@ -28,3 +28,3 @@ import { ValidationCause } from './types.js'; | ||
*/ | ||
export declare function makePathArray(str: string): (string | number)[]; | ||
export declare function makePathArray(str: string | Array<string | number>): (string | number)[]; | ||
/** | ||
@@ -31,0 +31,0 @@ * @private |
@@ -93,2 +93,5 @@ function functionalUpdate(updater, input) { | ||
function makePathArray(str) { | ||
if (Array.isArray(str)) { | ||
return [...str]; | ||
} | ||
if (typeof str !== "string") { | ||
@@ -95,0 +98,0 @@ throw new Error("Path must be a string."); |
{ | ||
"name": "@tanstack/form-core", | ||
"version": "0.32.0", | ||
"version": "0.33.0", | ||
"description": "Powerful, type-safe, framework agnostic forms.", | ||
@@ -5,0 +5,0 @@ "author": "tannerlinsley", |
@@ -9,2 +9,3 @@ import { Store } from '@tanstack/store' | ||
ValidationErrorMap, | ||
ValidationSource, | ||
Validator, | ||
@@ -497,3 +498,7 @@ } from './types' | ||
runValidator< | ||
TValue extends { value: TData; fieldApi: FieldApi<any, any, any, any> }, | ||
TValue extends { | ||
value: TData | ||
fieldApi: FieldApi<any, any, any, any> | ||
validationSource: ValidationSource | ||
}, | ||
TType extends 'validate' | 'validateAsync', | ||
@@ -506,3 +511,4 @@ >(props: { | ||
type: TType | ||
}): ReturnType<ReturnType<Validator<any>>[TType]> { | ||
// When `api` is 'field', the return type cannot be `FormValidationError` | ||
}): TType extends 'validate' ? ValidationError : Promise<ValidationError> { | ||
const adapters = [ | ||
@@ -554,2 +560,3 @@ this.form.options.validatorAdapter, | ||
fieldApi: this, | ||
validationSource: 'field', | ||
}, | ||
@@ -770,3 +777,7 @@ type: 'validate', | ||
validate: validateObj.validate, | ||
value: { value: field.getValue(), fieldApi: field }, | ||
value: { | ||
value: field.getValue(), | ||
validationSource: 'field', | ||
fieldApi: field, | ||
}, | ||
type: 'validate', | ||
@@ -898,2 +909,3 @@ }), | ||
signal: controller.signal, | ||
validationSource: 'field', | ||
}, | ||
@@ -900,0 +912,0 @@ type: 'validateAsync', |
@@ -16,2 +16,3 @@ import { Store } from '@tanstack/store' | ||
FormValidationError, | ||
FormValidationErrorMap, | ||
UpdateMetaOptions, | ||
@@ -22,2 +23,3 @@ ValidationCause, | ||
ValidationErrorMapKeys, | ||
ValidationSource, | ||
Validator, | ||
@@ -239,3 +241,3 @@ } from './types' | ||
*/ | ||
errorMap: ValidationErrorMap | ||
errorMap: FormValidationErrorMap | ||
/** | ||
@@ -331,2 +333,8 @@ * An internal mechanism used for keeping track of validation logic in a form. | ||
const isFormValidationError = ( | ||
error: unknown, | ||
): error is FormValidationError<unknown> => { | ||
return typeof error === 'object' | ||
} | ||
/** | ||
@@ -406,5 +414,14 @@ * A class representing the Form API. It handles the logic and interactions with the form state. | ||
const isValidating = isFieldsValidating || state.isFormValidating | ||
state.errors = Object.values(state.errorMap).filter( | ||
(val: unknown) => val !== undefined, | ||
) | ||
state.errors = Object.values(state.errorMap).reduce((prev, curr) => { | ||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
if (curr === undefined) return prev | ||
if (typeof curr === 'string') { | ||
prev.push(curr) | ||
return prev | ||
} else if (curr && isFormValidationError(curr)) { | ||
prev.push(curr.form) | ||
return prev | ||
} | ||
return prev | ||
}, [] as ValidationError[]) | ||
const isFormValid = state.errors.length === 0 | ||
@@ -457,3 +474,7 @@ const isValid = isFieldsValid && isFormValid | ||
runValidator< | ||
TValue extends { value: TFormData; formApi: FormApi<any, any> }, | ||
TValue extends { | ||
value: TFormData | ||
formApi: FormApi<any, any> | ||
validationSource: ValidationSource | ||
}, | ||
TType extends 'validate' | 'validateAsync', | ||
@@ -483,2 +504,3 @@ >(props: { | ||
formApi: this, | ||
validationSource: 'form', | ||
}, | ||
@@ -672,2 +694,3 @@ type: 'validate', | ||
formApi: this, | ||
validationSource: 'form', | ||
}, | ||
@@ -778,3 +801,6 @@ type: 'validate', | ||
new Promise<ValidationPromiseResult<TFormData>>(async (resolve) => { | ||
let rawError!: ValidationError | undefined | ||
let rawError!: | ||
| ValidationError | ||
| FormValidationError<unknown> | ||
| undefined | ||
try { | ||
@@ -791,2 +817,3 @@ rawError = await new Promise((rawResolve, rawReject) => { | ||
formApi: this, | ||
validationSource: 'form', | ||
signal: controller.signal, | ||
@@ -1241,3 +1268,3 @@ }, | ||
function normalizeError<TFormData>(rawError?: FormValidationError<TFormData>): { | ||
function normalizeError<TFormData>(rawError?: FormValidationError<unknown>): { | ||
formError: ValidationError | ||
@@ -1250,3 +1277,3 @@ fieldErrors?: Partial<Record<DeepKeys<TFormData>, ValidationError>> | ||
const fieldErrors = rawError.fields | ||
return { formError, fieldErrors } | ||
return { formError, fieldErrors } as never | ||
} | ||
@@ -1253,0 +1280,0 @@ |
@@ -5,2 +5,4 @@ import type { DeepKeys } from './util-types' | ||
export type ValidationSource = 'form' | 'field' | ||
/** | ||
@@ -11,4 +13,10 @@ * If/when TypeScript supports higher-kinded types, this should not be `unknown` anymore | ||
export type Validator<Type, Fn = unknown> = () => { | ||
validate(options: { value: Type }, fn: Fn): ValidationError | ||
validateAsync(options: { value: Type }, fn: Fn): Promise<ValidationError> | ||
validate( | ||
options: { value: Type; validationSource: ValidationSource }, | ||
fn: Fn, | ||
): ValidationError | FormValidationError<unknown> | ||
validateAsync( | ||
options: { value: Type; validationSource: ValidationSource }, | ||
fn: Fn, | ||
): Promise<ValidationError | FormValidationError<unknown>> | ||
} | ||
@@ -44,2 +52,9 @@ | ||
* @private | ||
*/ | ||
export type FormValidationErrorMap = { | ||
[K in ValidationErrorMapKeys]?: ValidationError | FormValidationError<unknown> | ||
} | ||
/** | ||
* @private | ||
* | ||
@@ -46,0 +61,0 @@ * @example |
@@ -142,3 +142,7 @@ import type { ValidationCause } from './types' | ||
*/ | ||
export function makePathArray(str: string) { | ||
export function makePathArray(str: string | Array<string | number>) { | ||
if (Array.isArray(str)) { | ||
return [...str] | ||
} | ||
if (typeof str !== 'string') { | ||
@@ -145,0 +149,0 @@ throw new Error('Path must be a string.') |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
464519
6191