@tanstack/form-core 0.20.1 → 0.20.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"FieldApi.js","sources":["../../src/FieldApi.ts"],"sourcesContent":["import { Store } from '@tanstack/store'\nimport { getAsyncValidatorArray, getBy, getSyncValidatorArray } from './utils'\nimport type { FieldInfo, FormApi } from './FormApi'\nimport type {\n ValidationCause,\n ValidationError,\n ValidationErrorMap,\n Validator,\n} from './types'\nimport type { AsyncValidator, SyncValidator, Updater } from './utils'\nimport type { DeepKeys, DeepValue, NoInfer } from './util-types'\n\nexport type FieldValidateFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = (props: {\n value: TData\n fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>\n}) => ValidationError\n\nexport type FieldValidateOrFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = TFieldValidator extends Validator<TData, infer TFN>\n ?\n | TFN\n | FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : TFormValidator extends Validator<TParentData, infer FFN>\n ?\n | FFN\n | FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n\nexport type FieldValidateAsyncFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = (options: {\n value: TData\n fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>\n signal: AbortSignal\n}) => ValidationError | Promise<ValidationError>\n\nexport type FieldAsyncValidateOrFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = TFieldValidator extends Validator<TData, infer TFN>\n ?\n | TFN\n | FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : TFormValidator extends Validator<TParentData, infer FFN>\n ?\n | FFN\n | FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n\nexport interface FieldValidators<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n onMount?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n onChange?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n onChangeAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n onChangeAsyncDebounceMs?: number\n onChangeListenTo?: DeepKeys<TParentData>[]\n onBlur?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n onBlurAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n onBlurAsyncDebounceMs?: number\n onBlurListenTo?: DeepKeys<TParentData>[]\n onSubmit?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n onSubmitAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n}\n\nexport interface FieldOptions<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n name: TName\n defaultValue?: NoInfer<TData>\n asyncDebounceMs?: number\n asyncAlways?: boolean\n preserveValue?: boolean\n validatorAdapter?: TFieldValidator\n validators?: FieldValidators<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n defaultMeta?: Partial<FieldMeta>\n}\n\nexport interface FieldApiOptions<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> extends FieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n > {\n form: FormApi<TParentData, TFormValidator>\n}\n\nexport type FieldMeta = {\n isTouched: boolean\n isPristine: boolean\n isDirty: boolean\n touchedErrors: ValidationError[]\n errors: ValidationError[]\n errorMap: ValidationErrorMap\n isValidating: boolean\n}\n\nexport type FieldState<TData> = {\n value: TData\n meta: FieldMeta\n}\n\nexport type ResolveName<TParentData> = unknown extends TParentData\n ? string\n : DeepKeys<TParentData>\n\nexport class FieldApi<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n form: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >['form']\n name!: DeepKeys<TParentData>\n options: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n > = {} as any\n store!: Store<FieldState<TData>>\n state!: FieldState<TData>\n prevState!: FieldState<TData>\n\n constructor(\n opts: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) {\n this.form = opts.form as never\n this.name = opts.name as never\n\n if (opts.defaultValue !== undefined) {\n this.form.setFieldValue(this.name, opts.defaultValue as never)\n }\n\n this.store = new Store<FieldState<TData>>(\n {\n value: this.getValue(),\n\n meta: this._getMeta() ?? {\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n ...opts.defaultMeta,\n },\n },\n {\n onUpdate: () => {\n const state = this.store.state\n\n state.meta.errors = Object.values(state.meta.errorMap).filter(\n (val: unknown) => val !== undefined,\n )\n\n state.meta.touchedErrors = state.meta.isTouched\n ? state.meta.errors\n : []\n\n state.meta.isPristine = !state.meta.isDirty\n\n this.prevState = state\n this.state = state\n },\n },\n )\n\n this.state = this.store.state\n this.prevState = this.state\n this.options = opts as never\n }\n\n runValidator<\n TValue extends { value: TData; fieldApi: FieldApi<any, any, any, any> },\n TType extends 'validate' | 'validateAsync',\n >(props: {\n validate: TType extends 'validate'\n ? FieldValidateOrFn<any, any, any, any>\n : FieldAsyncValidateOrFn<any, any, any, any>\n value: TValue\n type: TType\n }): ReturnType<ReturnType<Validator<any>>[TType]> {\n const adapters = [\n this.form.options.validatorAdapter,\n this.options.validatorAdapter,\n ] as const\n for (const adapter of adapters) {\n if (adapter && typeof props.validate !== 'function') {\n return adapter()[props.type](\n props.value as never,\n props.validate,\n ) as never\n }\n }\n\n return (props.validate as FieldValidateFn<any, any>)(props.value) as never\n }\n\n mount = () => {\n const info = this.getInfo()\n info.instance = this as never\n const unsubscribe = this.form.store.subscribe(() => {\n this.store.batch(() => {\n const nextValue = this.getValue()\n const nextMeta = this.getMeta()\n\n if (nextValue !== this.state.value) {\n this.store.setState((prev) => ({ ...prev, value: nextValue }))\n }\n\n if (nextMeta !== this.state.meta) {\n this.store.setState((prev) => ({ ...prev, meta: nextMeta }))\n }\n })\n })\n\n this.update(this.options as never)\n const { onMount } = this.options.validators || {}\n\n if (onMount) {\n const error = this.runValidator({\n validate: onMount,\n value: {\n value: this.state.value,\n fieldApi: this,\n },\n type: 'validate',\n })\n if (error) {\n this.setMeta((prev) => ({\n ...prev,\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n errorMap: { ...prev?.errorMap, onMount: error },\n }))\n }\n }\n\n return () => {\n const preserveValue = this.options.preserveValue\n unsubscribe()\n if (!preserveValue) {\n this.form.deleteField(this.name)\n }\n }\n }\n\n update = (\n opts: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) => {\n // Default Value\n\n if (this.state.value === undefined) {\n const formDefault = getBy(opts.form.options.defaultValues, opts.name)\n\n if (opts.defaultValue !== undefined) {\n this.setValue(opts.defaultValue as never)\n } else if (formDefault !== undefined) {\n this.setValue(formDefault as never)\n }\n }\n\n // Default Meta\n if (this._getMeta() === undefined) {\n this.setMeta(this.state.meta)\n }\n\n this.options = opts as never\n }\n\n getValue = (): TData => {\n return this.form.getFieldValue(this.name) as TData\n }\n\n setValue = (\n updater: Updater<TData>,\n options?: { touch?: boolean; notify?: boolean },\n ) => {\n this.form.setFieldValue(this.name, updater as never, options)\n this.validate('change')\n }\n\n _getMeta = () => this.form.getFieldMeta(this.name)\n getMeta = () =>\n this._getMeta() ??\n ({\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n ...this.options.defaultMeta,\n } as FieldMeta)\n\n setMeta = (updater: Updater<FieldMeta>) =>\n this.form.setFieldMeta(this.name, updater)\n\n getInfo = () => this.form.getFieldInfo(this.name)\n\n pushValue = (value: TData extends any[] ? TData[number] : never) =>\n this.form.pushFieldValue(this.name, value as any)\n\n insertValue = (\n index: number,\n value: TData extends any[] ? TData[number] : never,\n ) => this.form.insertFieldValue(this.name, index, value as any)\n\n removeValue = async (index: number, opts?: { touch: boolean }) => {\n await this.form.removeFieldValue(this.name, index, opts)\n }\n\n swapValues = (aIndex: number, bIndex: number) =>\n this.form.swapFieldValues(this.name, aIndex, bIndex)\n\n getLinkedFields = (cause: ValidationCause) => {\n const fields = Object.values(this.form.fieldInfo) as FieldInfo<\n any,\n TFormValidator\n >[]\n\n const linkedFields: FieldApi<any, any, any, any>[] = []\n for (const field of fields) {\n if (!field.instance) continue\n const { onChangeListenTo, onBlurListenTo } =\n field.instance.options.validators || {}\n if (\n cause === 'change' &&\n onChangeListenTo?.includes(this.name as string)\n ) {\n linkedFields.push(field.instance)\n }\n if (cause === 'blur' && onBlurListenTo?.includes(this.name as string)) {\n linkedFields.push(field.instance)\n }\n }\n\n return linkedFields\n }\n\n moveValue = (aIndex: number, bIndex: number) =>\n this.form.moveFieldValues(this.name, aIndex, bIndex)\n\n validateSync = (cause: ValidationCause) => {\n const validates = getSyncValidatorArray(cause, this.options)\n\n const linkedFields = this.getLinkedFields(cause)\n const linkedFieldValidates = linkedFields.reduce(\n (acc, field) => {\n const fieldValidates = getSyncValidatorArray(cause, field.options)\n fieldValidates.forEach((validate) => {\n ;(validate as any).field = field\n })\n return acc.concat(fieldValidates as never)\n },\n [] as Array<SyncValidator<any> & { field: FieldApi<any, any, any, any> }>,\n )\n\n // Needs type cast as eslint errantly believes this is always falsy\n let hasErrored = false as boolean\n\n this.form.store.batch(() => {\n const validateFieldFn = (\n field: FieldApi<any, any, any, any>,\n validateObj: SyncValidator<any>,\n ) => {\n const error = normalizeError(\n field.runValidator({\n validate: validateObj.validate,\n value: { value: field.getValue(), fieldApi: field },\n type: 'validate',\n }),\n )\n const errorMapKey = getErrorMapKey(validateObj.cause)\n if (field.state.meta.errorMap[errorMapKey] !== error) {\n field.setMeta((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [getErrorMapKey(validateObj.cause)]: error,\n },\n }))\n }\n if (error) {\n hasErrored = true\n }\n }\n\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n validateFieldFn(this, validateObj)\n }\n for (const fieldValitateObj of linkedFieldValidates) {\n if (!fieldValitateObj.validate) continue\n validateFieldFn(fieldValitateObj.field, fieldValitateObj)\n }\n })\n\n /**\n * when we have an error for onSubmit in the state, we want\n * to clear the error as soon as the user enters a valid value in the field\n */\n const submitErrKey = getErrorMapKey('submit')\n if (\n this.state.meta.errorMap[submitErrKey] &&\n cause !== 'submit' &&\n !hasErrored\n ) {\n this.setMeta((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [submitErrKey]: undefined,\n },\n }))\n }\n\n return { hasErrored }\n }\n\n validateAsync = async (cause: ValidationCause) => {\n const validates = getAsyncValidatorArray(cause, this.options)\n\n const linkedFields = this.getLinkedFields(cause)\n const linkedFieldValidates = linkedFields.reduce(\n (acc, field) => {\n const fieldValidates = getAsyncValidatorArray(cause, field.options)\n fieldValidates.forEach((validate) => {\n ;(validate as any).field = field\n })\n return acc.concat(fieldValidates as never)\n },\n [] as Array<\n AsyncValidator<any> & { field: FieldApi<any, any, any, any> }\n >,\n )\n\n if (!this.state.meta.isValidating) {\n this.setMeta((prev) => ({ ...prev, isValidating: true }))\n }\n\n for (const linkedField of linkedFields) {\n linkedField.setMeta((prev) => ({ ...prev, isValidating: true }))\n }\n\n /**\n * We have to use a for loop and generate our promises this way, otherwise it won't be sync\n * when there are no validators needed to be run\n */\n const validatesPromises: Promise<ValidationError | undefined>[] = []\n const linkedPromises: Promise<ValidationError | undefined>[] = []\n\n const validateFieldAsyncFn = (\n field: FieldApi<any, any, any, any>,\n validateObj: AsyncValidator<any>,\n promises: Promise<ValidationError | undefined>[],\n ) => {\n const key = getErrorMapKey(validateObj.cause)\n const fieldValidatorMeta = field.getInfo().validationMetaMap[key]\n\n fieldValidatorMeta?.lastAbortController.abort()\n const controller = new AbortController()\n\n this.getInfo().validationMetaMap[key] = {\n lastAbortController: controller,\n }\n\n promises.push(\n new Promise<ValidationError | undefined>(async (resolve) => {\n let rawError!: ValidationError | undefined\n try {\n rawError = await new Promise((rawResolve, rawReject) => {\n setTimeout(async () => {\n if (controller.signal.aborted) return rawResolve(undefined)\n try {\n rawResolve(\n await this.runValidator({\n validate: validateObj.validate,\n value: {\n value: field.getValue(),\n fieldApi: field,\n signal: controller.signal,\n },\n type: 'validateAsync',\n }),\n )\n } catch (e) {\n rawReject(e)\n }\n }, validateObj.debounceMs)\n })\n } catch (e: unknown) {\n rawError = e as ValidationError\n }\n const error = normalizeError(rawError)\n field.setMeta((prev) => {\n return {\n ...prev,\n errorMap: {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n ...prev?.errorMap,\n [getErrorMapKey(cause)]: error,\n },\n }\n })\n\n resolve(error)\n }),\n )\n }\n\n // TODO: Dedupe this logic to reduce bundle size\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n validateFieldAsyncFn(this, validateObj, validatesPromises)\n }\n for (const fieldValitateObj of linkedFieldValidates) {\n if (!fieldValitateObj.validate) continue\n validateFieldAsyncFn(\n fieldValitateObj.field,\n fieldValitateObj,\n linkedPromises,\n )\n }\n\n let results: ValidationError[] = []\n if (validatesPromises.length || linkedPromises.length) {\n results = await Promise.all(validatesPromises)\n await Promise.all(linkedPromises)\n }\n\n this.setMeta((prev) => ({ ...prev, isValidating: false }))\n\n for (const linkedField of linkedFields) {\n linkedField.setMeta((prev) => ({ ...prev, isValidating: false }))\n }\n\n return results.filter(Boolean)\n }\n\n validate = (\n cause: ValidationCause,\n ): ValidationError[] | Promise<ValidationError[]> => {\n // If the field is pristine and validatePristine is false, do not validate\n if (!this.state.meta.isTouched) return []\n\n try {\n this.form.validate(cause)\n } catch (_) {}\n\n // Attempt to sync validate first\n const { hasErrored } = this.validateSync(cause)\n\n if (hasErrored && !this.options.asyncAlways) {\n return this.state.meta.errors\n }\n // No error? Attempt async validation\n return this.validateAsync(cause)\n }\n\n handleChange = (updater: Updater<TData>) => {\n this.setValue(updater, { touch: true })\n }\n\n handleBlur = () => {\n const prevTouched = this.state.meta.isTouched\n if (!prevTouched) {\n this.setMeta((prev) => ({ ...prev, isTouched: true }))\n this.validate('change')\n }\n this.validate('blur')\n }\n}\n\nfunction normalizeError(rawError?: ValidationError) {\n if (rawError) {\n if (typeof rawError !== 'string') {\n return 'Invalid Form Values'\n }\n\n return rawError\n }\n\n return undefined\n}\n\nfunction getErrorMapKey(cause: ValidationCause) {\n switch (cause) {\n case 'submit':\n return 'onSubmit'\n case 'blur':\n return 'onBlur'\n case 'mount':\n return 'onMount'\n case 'server':\n return 'onServer'\n case 'change':\n default:\n return 'onChange'\n }\n}\n"],"names":["opts"],"mappings":"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"}
1
+ {"version":3,"file":"FieldApi.js","sources":["../../src/FieldApi.ts"],"sourcesContent":["import { Store } from '@tanstack/store'\nimport { getAsyncValidatorArray, getBy, getSyncValidatorArray } from './utils'\nimport type { FieldInfo, FormApi } from './FormApi'\nimport type {\n ValidationCause,\n ValidationError,\n ValidationErrorMap,\n Validator,\n} from './types'\nimport type { AsyncValidator, SyncValidator, Updater } from './utils'\nimport type { DeepKeys, DeepValue, NoInfer } from './util-types'\n\nexport type FieldValidateFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = (props: {\n value: TData\n fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>\n}) => ValidationError\n\nexport type FieldValidateOrFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = TFieldValidator extends Validator<TData, infer TFN>\n ?\n | TFN\n | FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : TFormValidator extends Validator<TParentData, infer FFN>\n ?\n | FFN\n | FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n\nexport type FieldValidateAsyncFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = (options: {\n value: TData\n fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>\n signal: AbortSignal\n}) => ValidationError | Promise<ValidationError>\n\nexport type FieldAsyncValidateOrFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = TFieldValidator extends Validator<TData, infer TFN>\n ?\n | TFN\n | FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : TFormValidator extends Validator<TParentData, infer FFN>\n ?\n | FFN\n | FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n\nexport interface FieldValidators<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n onMount?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n onChange?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n onChangeAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n onChangeAsyncDebounceMs?: number\n onChangeListenTo?: DeepKeys<TParentData>[]\n onBlur?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n onBlurAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n onBlurAsyncDebounceMs?: number\n onBlurListenTo?: DeepKeys<TParentData>[]\n onSubmit?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n onSubmitAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n}\n\nexport interface FieldOptions<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n name: TName\n defaultValue?: NoInfer<TData>\n asyncDebounceMs?: number\n asyncAlways?: boolean\n preserveValue?: boolean\n validatorAdapter?: TFieldValidator\n validators?: FieldValidators<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n defaultMeta?: Partial<FieldMeta>\n}\n\nexport interface FieldApiOptions<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> extends FieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n > {\n form: FormApi<TParentData, TFormValidator>\n}\n\nexport type FieldMeta = {\n isTouched: boolean\n isPristine: boolean\n isDirty: boolean\n touchedErrors: ValidationError[]\n errors: ValidationError[]\n errorMap: ValidationErrorMap\n isValidating: boolean\n}\n\nexport type FieldState<TData> = {\n value: TData\n meta: FieldMeta\n}\n\nexport type ResolveName<TParentData> = unknown extends TParentData\n ? string\n : DeepKeys<TParentData>\n\nexport class FieldApi<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n form: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >['form']\n name!: DeepKeys<TParentData>\n options: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n > = {} as any\n store!: Store<FieldState<TData>>\n state!: FieldState<TData>\n prevState!: FieldState<TData>\n\n constructor(\n opts: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) {\n this.form = opts.form as never\n this.name = opts.name as never\n\n if (opts.defaultValue !== undefined) {\n this.form.setFieldValue(this.name, opts.defaultValue as never)\n }\n\n this.store = new Store<FieldState<TData>>(\n {\n value: this.getValue(),\n\n meta: this._getMeta() ?? {\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n ...opts.defaultMeta,\n },\n },\n {\n onUpdate: () => {\n const state = this.store.state\n\n state.meta.errors = Object.values(state.meta.errorMap).filter(\n (val: unknown) => val !== undefined,\n )\n\n state.meta.touchedErrors = state.meta.isTouched\n ? state.meta.errors\n : []\n\n state.meta.isPristine = !state.meta.isDirty\n\n this.prevState = state\n this.state = state\n },\n },\n )\n\n this.state = this.store.state\n this.prevState = this.state\n this.options = opts as never\n }\n\n runValidator<\n TValue extends { value: TData; fieldApi: FieldApi<any, any, any, any> },\n TType extends 'validate' | 'validateAsync',\n >(props: {\n validate: TType extends 'validate'\n ? FieldValidateOrFn<any, any, any, any>\n : FieldAsyncValidateOrFn<any, any, any, any>\n value: TValue\n type: TType\n }): ReturnType<ReturnType<Validator<any>>[TType]> {\n const adapters = [\n this.form.options.validatorAdapter,\n this.options.validatorAdapter,\n ] as const\n for (const adapter of adapters) {\n if (adapter && typeof props.validate !== 'function') {\n return adapter()[props.type](\n props.value as never,\n props.validate,\n ) as never\n }\n }\n\n return (props.validate as FieldValidateFn<any, any>)(props.value) as never\n }\n\n mount = () => {\n const info = this.getInfo()\n info.instance = this as never\n const unsubscribe = this.form.store.subscribe(() => {\n this.store.batch(() => {\n const nextValue = this.getValue()\n const nextMeta = this.getMeta()\n\n if (nextValue !== this.state.value) {\n this.store.setState((prev) => ({ ...prev, value: nextValue }))\n }\n\n if (nextMeta !== this.state.meta) {\n this.store.setState((prev) => ({ ...prev, meta: nextMeta }))\n }\n })\n })\n\n this.update(this.options as never)\n const { onMount } = this.options.validators || {}\n\n if (onMount) {\n const error = this.runValidator({\n validate: onMount,\n value: {\n value: this.state.value,\n fieldApi: this,\n },\n type: 'validate',\n })\n if (error) {\n this.setMeta((prev) => ({\n ...prev,\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n errorMap: { ...prev?.errorMap, onMount: error },\n }))\n }\n }\n\n return () => {\n const preserveValue = this.options.preserveValue\n unsubscribe()\n if (!preserveValue) {\n this.form.deleteField(this.name)\n }\n }\n }\n\n update = (\n opts: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) => {\n // Default Value\n\n if (this.state.value === undefined) {\n const formDefault = getBy(opts.form.options.defaultValues, opts.name)\n\n if (opts.defaultValue !== undefined) {\n this.setValue(opts.defaultValue as never)\n } else if (formDefault !== undefined) {\n this.setValue(formDefault as never)\n }\n }\n\n // Default Meta\n if (this._getMeta() === undefined) {\n this.setMeta(this.state.meta)\n }\n\n this.options = opts as never\n }\n\n getValue = (): TData => {\n return this.form.getFieldValue(this.name) as TData\n }\n\n setValue = (\n updater: Updater<TData>,\n options?: { touch?: boolean; notify?: boolean },\n ) => {\n this.form.setFieldValue(this.name, updater as never, options)\n this.validate('change')\n }\n\n _getMeta = () => this.form.getFieldMeta(this.name)\n getMeta = () =>\n this._getMeta() ??\n ({\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n ...this.options.defaultMeta,\n } as FieldMeta)\n\n setMeta = (updater: Updater<FieldMeta>) =>\n this.form.setFieldMeta(this.name, updater)\n\n getInfo = () => this.form.getFieldInfo(this.name)\n\n pushValue = (value: TData extends any[] ? TData[number] : never) =>\n this.form.pushFieldValue(this.name, value as any)\n\n insertValue = (\n index: number,\n value: TData extends any[] ? TData[number] : never,\n ) => this.form.insertFieldValue(this.name, index, value as any)\n\n removeValue = (index: number, opts?: { touch: boolean }) =>\n this.form.removeFieldValue(this.name, index, opts)\n\n swapValues = (aIndex: number, bIndex: number) =>\n this.form.swapFieldValues(this.name, aIndex, bIndex)\n\n getLinkedFields = (cause: ValidationCause) => {\n const fields = Object.values(this.form.fieldInfo) as FieldInfo<\n any,\n TFormValidator\n >[]\n\n const linkedFields: FieldApi<any, any, any, any>[] = []\n for (const field of fields) {\n if (!field.instance) continue\n const { onChangeListenTo, onBlurListenTo } =\n field.instance.options.validators || {}\n if (\n cause === 'change' &&\n onChangeListenTo?.includes(this.name as string)\n ) {\n linkedFields.push(field.instance)\n }\n if (cause === 'blur' && onBlurListenTo?.includes(this.name as string)) {\n linkedFields.push(field.instance)\n }\n }\n\n return linkedFields\n }\n\n moveValue = (aIndex: number, bIndex: number) =>\n this.form.moveFieldValues(this.name, aIndex, bIndex)\n\n validateSync = (cause: ValidationCause) => {\n const validates = getSyncValidatorArray(cause, this.options)\n\n const linkedFields = this.getLinkedFields(cause)\n const linkedFieldValidates = linkedFields.reduce(\n (acc, field) => {\n const fieldValidates = getSyncValidatorArray(cause, field.options)\n fieldValidates.forEach((validate) => {\n ;(validate as any).field = field\n })\n return acc.concat(fieldValidates as never)\n },\n [] as Array<SyncValidator<any> & { field: FieldApi<any, any, any, any> }>,\n )\n\n // Needs type cast as eslint errantly believes this is always falsy\n let hasErrored = false as boolean\n\n this.form.store.batch(() => {\n const validateFieldFn = (\n field: FieldApi<any, any, any, any>,\n validateObj: SyncValidator<any>,\n ) => {\n const error = normalizeError(\n field.runValidator({\n validate: validateObj.validate,\n value: { value: field.getValue(), fieldApi: field },\n type: 'validate',\n }),\n )\n const errorMapKey = getErrorMapKey(validateObj.cause)\n if (field.state.meta.errorMap[errorMapKey] !== error) {\n field.setMeta((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [getErrorMapKey(validateObj.cause)]: error,\n },\n }))\n }\n if (error) {\n hasErrored = true\n }\n }\n\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n validateFieldFn(this, validateObj)\n }\n for (const fieldValitateObj of linkedFieldValidates) {\n if (!fieldValitateObj.validate) continue\n validateFieldFn(fieldValitateObj.field, fieldValitateObj)\n }\n })\n\n /**\n * when we have an error for onSubmit in the state, we want\n * to clear the error as soon as the user enters a valid value in the field\n */\n const submitErrKey = getErrorMapKey('submit')\n if (\n this.state.meta.errorMap[submitErrKey] &&\n cause !== 'submit' &&\n !hasErrored\n ) {\n this.setMeta((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [submitErrKey]: undefined,\n },\n }))\n }\n\n return { hasErrored }\n }\n\n validateAsync = async (cause: ValidationCause) => {\n const validates = getAsyncValidatorArray(cause, this.options)\n\n const linkedFields = this.getLinkedFields(cause)\n const linkedFieldValidates = linkedFields.reduce(\n (acc, field) => {\n const fieldValidates = getAsyncValidatorArray(cause, field.options)\n fieldValidates.forEach((validate) => {\n ;(validate as any).field = field\n })\n return acc.concat(fieldValidates as never)\n },\n [] as Array<\n AsyncValidator<any> & { field: FieldApi<any, any, any, any> }\n >,\n )\n\n if (!this.state.meta.isValidating) {\n this.setMeta((prev) => ({ ...prev, isValidating: true }))\n }\n\n for (const linkedField of linkedFields) {\n linkedField.setMeta((prev) => ({ ...prev, isValidating: true }))\n }\n\n /**\n * We have to use a for loop and generate our promises this way, otherwise it won't be sync\n * when there are no validators needed to be run\n */\n const validatesPromises: Promise<ValidationError | undefined>[] = []\n const linkedPromises: Promise<ValidationError | undefined>[] = []\n\n const validateFieldAsyncFn = (\n field: FieldApi<any, any, any, any>,\n validateObj: AsyncValidator<any>,\n promises: Promise<ValidationError | undefined>[],\n ) => {\n const key = getErrorMapKey(validateObj.cause)\n const fieldValidatorMeta = field.getInfo().validationMetaMap[key]\n\n fieldValidatorMeta?.lastAbortController.abort()\n const controller = new AbortController()\n\n this.getInfo().validationMetaMap[key] = {\n lastAbortController: controller,\n }\n\n promises.push(\n new Promise<ValidationError | undefined>(async (resolve) => {\n let rawError!: ValidationError | undefined\n try {\n rawError = await new Promise((rawResolve, rawReject) => {\n setTimeout(async () => {\n if (controller.signal.aborted) return rawResolve(undefined)\n try {\n rawResolve(\n await this.runValidator({\n validate: validateObj.validate,\n value: {\n value: field.getValue(),\n fieldApi: field,\n signal: controller.signal,\n },\n type: 'validateAsync',\n }),\n )\n } catch (e) {\n rawReject(e)\n }\n }, validateObj.debounceMs)\n })\n } catch (e: unknown) {\n rawError = e as ValidationError\n }\n const error = normalizeError(rawError)\n field.setMeta((prev) => {\n return {\n ...prev,\n errorMap: {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n ...prev?.errorMap,\n [getErrorMapKey(cause)]: error,\n },\n }\n })\n\n resolve(error)\n }),\n )\n }\n\n // TODO: Dedupe this logic to reduce bundle size\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n validateFieldAsyncFn(this, validateObj, validatesPromises)\n }\n for (const fieldValitateObj of linkedFieldValidates) {\n if (!fieldValitateObj.validate) continue\n validateFieldAsyncFn(\n fieldValitateObj.field,\n fieldValitateObj,\n linkedPromises,\n )\n }\n\n let results: ValidationError[] = []\n if (validatesPromises.length || linkedPromises.length) {\n results = await Promise.all(validatesPromises)\n await Promise.all(linkedPromises)\n }\n\n this.setMeta((prev) => ({ ...prev, isValidating: false }))\n\n for (const linkedField of linkedFields) {\n linkedField.setMeta((prev) => ({ ...prev, isValidating: false }))\n }\n\n return results.filter(Boolean)\n }\n\n validate = (\n cause: ValidationCause,\n ): ValidationError[] | Promise<ValidationError[]> => {\n // If the field is pristine and validatePristine is false, do not validate\n if (!this.state.meta.isTouched) return []\n\n try {\n this.form.validate(cause)\n } catch (_) {}\n\n // Attempt to sync validate first\n const { hasErrored } = this.validateSync(cause)\n\n if (hasErrored && !this.options.asyncAlways) {\n return this.state.meta.errors\n }\n // No error? Attempt async validation\n return this.validateAsync(cause)\n }\n\n handleChange = (updater: Updater<TData>) => {\n this.setValue(updater, { touch: true })\n }\n\n handleBlur = () => {\n const prevTouched = this.state.meta.isTouched\n if (!prevTouched) {\n this.setMeta((prev) => ({ ...prev, isTouched: true }))\n this.validate('change')\n }\n this.validate('blur')\n }\n}\n\nfunction normalizeError(rawError?: ValidationError) {\n if (rawError) {\n if (typeof rawError !== 'string') {\n return 'Invalid Form Values'\n }\n\n return rawError\n }\n\n return undefined\n}\n\nfunction getErrorMapKey(cause: ValidationCause) {\n switch (cause) {\n case 'submit':\n return 'onSubmit'\n case 'blur':\n return 'onBlur'\n case 'mount':\n return 'onMount'\n case 'server':\n return 'onServer'\n case 'change':\n default:\n return 'onChange'\n }\n}\n"],"names":["opts"],"mappings":"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"}
@@ -93,6 +93,8 @@ export declare class FormApi<TFormData, TFormValidator extends Validator<TFormDa
93
93
  update: (options?: FormOptions<TFormData, TFormValidator>) => void;
94
94
  reset: () => void;
95
95
  validateAllFields: (cause: ValidationCause) => Promise<ValidationError[]>;
96
+ validateArrayFieldsStartingFrom: <TField extends DeepKeys<TFormData>>(field: TField, index: number, cause: ValidationCause) => Promise<ValidationError[]>;
97
+ validateField: <TField extends DeepKeys<TFormData>>(field: TField, cause: ValidationCause) => ValidationError[] | Promise<ValidationError[]>;
96
98
  validateSync: (cause: ValidationCause) => {
97
99
  hasErrored: boolean;
98
100
  };
@@ -113,7 +115,7 @@ export declare class FormApi<TFormData, TFormValidator extends Validator<TFormDa
113
115
  }) => void;
114
116
  insertFieldValue: <TField extends DeepKeys<TFormData>>(field: TField, index: number, value: DeepValue<TFormData, TField> extends any[] ? DeepValue<TFormData, TField>[number] : never, opts?: {
115
117
  touch?: boolean;
116
- }) => void;
118
+ }) => Promise<void>;
117
119
  removeFieldValue: <TField extends DeepKeys<TFormData>>(field: TField, index: number, opts?: {
118
120
  touch?: boolean;
119
121
  }) => Promise<void>;
@@ -107,6 +107,37 @@ class FormApi {
107
107
  const fieldErrorMapMap = await Promise.all(fieldValidationPromises);
108
108
  return fieldErrorMapMap.flat();
109
109
  };
110
+ this.validateArrayFieldsStartingFrom = async (field, index, cause) => {
111
+ const currentValue = this.getFieldValue(field);
112
+ const lastIndex = Array.isArray(currentValue) ? Math.max(currentValue.length - 1, 0) : null;
113
+ const fieldKeysToValidate = [`${field}[${index}]`];
114
+ for (let i = index + 1; i <= (lastIndex ?? 0); i++) {
115
+ fieldKeysToValidate.push(`${field}[${i}]`);
116
+ }
117
+ const fieldsToValidate = Object.keys(this.fieldInfo).filter(
118
+ (fieldKey) => fieldKeysToValidate.some((key) => fieldKey.startsWith(key))
119
+ );
120
+ const fieldValidationPromises = [];
121
+ this.store.batch(() => {
122
+ fieldsToValidate.forEach((nestedField) => {
123
+ fieldValidationPromises.push(
124
+ Promise.resolve().then(() => this.validateField(nestedField, cause))
125
+ );
126
+ });
127
+ });
128
+ const fieldErrorMapMap = await Promise.all(fieldValidationPromises);
129
+ return fieldErrorMapMap.flat();
130
+ };
131
+ this.validateField = (field, cause) => {
132
+ var _a2;
133
+ const fieldInstance = (_a2 = this.fieldInfo[field]) == null ? void 0 : _a2.instance;
134
+ if (!fieldInstance)
135
+ return [];
136
+ if (!fieldInstance.state.meta.isTouched) {
137
+ fieldInstance.setMeta((prev) => ({ ...prev, isTouched: true }));
138
+ }
139
+ return fieldInstance.validate(cause);
140
+ };
110
141
  this.validateSync = (cause) => {
111
142
  const validates = getSyncValidatorArray(cause, this.options);
112
143
  let hasErrored = false;
@@ -342,13 +373,14 @@ class FormApi {
342
373
  delete this.fieldInfo[field];
343
374
  };
344
375
  this.pushFieldValue = (field, value, opts2) => {
345
- return this.setFieldValue(
376
+ this.setFieldValue(
346
377
  field,
347
378
  (prev) => [...Array.isArray(prev) ? prev : [], value],
348
379
  opts2
349
380
  );
381
+ this.validateField(field, "change");
350
382
  };
351
- this.insertFieldValue = (field, index, value, opts2) => {
383
+ this.insertFieldValue = async (field, index, value, opts2) => {
352
384
  this.setFieldValue(
353
385
  field,
354
386
  (prev) => {
@@ -358,6 +390,8 @@ class FormApi {
358
390
  },
359
391
  opts2
360
392
  );
393
+ await this.validateField(field, "change");
394
+ await this.validateArrayFieldsStartingFrom(field, index, "change");
361
395
  };
362
396
  this.removeFieldValue = async (field, index, opts2) => {
363
397
  const fieldValue = this.getFieldValue(field);
@@ -378,7 +412,8 @@ class FormApi {
378
412
  );
379
413
  fieldsToDelete.forEach((f) => this.deleteField(f));
380
414
  }
381
- await this.validateAllFields("change");
415
+ await this.validateField(field, "change");
416
+ await this.validateArrayFieldsStartingFrom(field, index, "change");
382
417
  };
383
418
  this.swapFieldValues = (field, index1, index2) => {
384
419
  this.setFieldValue(field, (prev) => {
@@ -386,12 +421,18 @@ class FormApi {
386
421
  const prev2 = prev[index2];
387
422
  return setBy(setBy(prev, `${index1}`, prev2), `${index2}`, prev1);
388
423
  });
424
+ this.validateField(field, "change");
425
+ this.validateField(`${field}[${index1}]`, "change");
426
+ this.validateField(`${field}[${index2}]`, "change");
389
427
  };
390
428
  this.moveFieldValues = (field, index1, index2) => {
391
429
  this.setFieldValue(field, (prev) => {
392
430
  prev.splice(index2, 0, prev.splice(index1, 1)[0]);
393
431
  return prev;
394
432
  });
433
+ this.validateField(field, "change");
434
+ this.validateField(`${field}[${index1}]`, "change");
435
+ this.validateField(`${field}[${index2}]`, "change");
395
436
  };
396
437
  this.store = new Store(
397
438
  getDefaultFormState({
@@ -1 +1 @@
1
- {"version":3,"file":"FormApi.js","sources":["../../src/FormApi.ts"],"sourcesContent":["import { Store } from '@tanstack/store'\nimport {\n deleteBy,\n functionalUpdate,\n getAsyncValidatorArray,\n getBy,\n getSyncValidatorArray,\n isNonEmptyArray,\n setBy,\n} from './utils'\nimport type { Updater } from './utils'\nimport type { DeepKeys, DeepValue } from './util-types'\nimport type { FieldApi, FieldMeta } from './FieldApi'\nimport type {\n ValidationCause,\n ValidationError,\n ValidationErrorMap,\n ValidationErrorMapKeys,\n Validator,\n} from './types'\n\nexport type FormValidateFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (props: {\n value: TFormData\n formApi: FormApi<TFormData, TFormValidator>\n}) => ValidationError\n\nexport type FormValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer TFN>\n ? TFN\n : FormValidateFn<TFormData, TFormValidator>\n\nexport type FormValidateAsyncFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (props: {\n value: TFormData\n formApi: FormApi<TFormData, TFormValidator>\n signal: AbortSignal\n}) => ValidationError | Promise<ValidationError>\n\nexport type FormAsyncValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer FFN>\n ? FFN | FormValidateAsyncFn<TFormData, TFormValidator>\n : FormValidateAsyncFn<TFormData, TFormValidator>\n\nexport interface FormValidators<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n onMount?: FormValidateOrFn<TFormData, TFormValidator>\n onChange?: FormValidateOrFn<TFormData, TFormValidator>\n onChangeAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\n onChangeAsyncDebounceMs?: number\n onBlur?: FormValidateOrFn<TFormData, TFormValidator>\n onBlurAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\n onBlurAsyncDebounceMs?: number\n onSubmit?: FormValidateOrFn<TFormData, TFormValidator>\n onSubmitAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\n}\n\nexport interface FormTransform<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n fn: (\n formBase: FormApi<TFormData, TFormValidator>,\n ) => FormApi<TFormData, TFormValidator>\n deps: unknown[]\n}\n\nexport interface FormOptions<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n defaultValues?: TFormData\n defaultState?: Partial<FormState<TFormData>>\n asyncAlways?: boolean\n asyncDebounceMs?: number\n validatorAdapter?: TFormValidator\n validators?: FormValidators<TFormData, TFormValidator>\n onSubmit?: (props: {\n value: TFormData\n formApi: FormApi<TFormData, TFormValidator>\n }) => any | Promise<any>\n onSubmitInvalid?: (props: {\n value: TFormData\n formApi: FormApi<TFormData, TFormValidator>\n }) => void\n transform?: FormTransform<TFormData, TFormValidator>\n}\n\nexport type ValidationMeta = {\n lastAbortController: AbortController\n}\n\nexport type FieldInfo<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = {\n instance: FieldApi<\n TFormData,\n any,\n Validator<unknown, unknown> | undefined,\n TFormValidator\n > | null\n validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>\n}\n\nexport type FormState<TFormData> = {\n values: TFormData\n // Form Validation\n isFormValidating: boolean\n isFormValid: boolean\n errors: ValidationError[]\n errorMap: ValidationErrorMap\n validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>\n // Fields\n fieldMeta: Record<DeepKeys<TFormData>, FieldMeta>\n isFieldsValidating: boolean\n isFieldsValid: boolean\n isSubmitting: boolean\n // General\n isTouched: boolean\n isDirty: boolean\n isPristine: boolean\n isSubmitted: boolean\n isValidating: boolean\n isValid: boolean\n canSubmit: boolean\n submissionAttempts: number\n}\n\nfunction getDefaultFormState<TFormData>(\n defaultState: Partial<FormState<TFormData>>,\n): FormState<TFormData> {\n return {\n values: defaultState.values ?? ({} as never),\n errors: defaultState.errors ?? [],\n errorMap: defaultState.errorMap ?? {},\n fieldMeta: defaultState.fieldMeta ?? ({} as never),\n canSubmit: defaultState.canSubmit ?? true,\n isFieldsValid: defaultState.isFieldsValid ?? false,\n isFieldsValidating: defaultState.isFieldsValidating ?? false,\n isFormValid: defaultState.isFormValid ?? false,\n isFormValidating: defaultState.isFormValidating ?? false,\n isSubmitted: defaultState.isSubmitted ?? false,\n isSubmitting: defaultState.isSubmitting ?? false,\n isTouched: defaultState.isTouched ?? false,\n isPristine: defaultState.isPristine ?? true,\n isDirty: defaultState.isDirty ?? false,\n isValid: defaultState.isValid ?? false,\n isValidating: defaultState.isValidating ?? false,\n submissionAttempts: defaultState.submissionAttempts ?? 0,\n validationMetaMap: defaultState.validationMetaMap ?? {\n onChange: undefined,\n onBlur: undefined,\n onSubmit: undefined,\n onMount: undefined,\n onServer: undefined,\n },\n }\n}\n\nexport class FormApi<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n options: FormOptions<TFormData, TFormValidator> = {}\n store!: Store<FormState<TFormData>>\n // Do not use __state directly, as it is not reactive.\n // Please use form.useStore() utility to subscribe to state\n state!: FormState<TFormData>\n // // This carries the context for nested fields\n fieldInfo: Record<DeepKeys<TFormData>, FieldInfo<TFormData, TFormValidator>> =\n {} as any\n\n prevTransformArray: unknown[] = []\n\n constructor(opts?: FormOptions<TFormData, TFormValidator>) {\n this.store = new Store<FormState<TFormData>>(\n getDefaultFormState({\n ...(opts?.defaultState as any),\n values: opts?.defaultValues ?? opts?.defaultState?.values,\n isFormValid: true,\n }),\n {\n onUpdate: () => {\n let { state } = this.store\n // Computed state\n const fieldMetaValues = Object.values(state.fieldMeta) as (\n | FieldMeta\n | undefined\n )[]\n\n const isFieldsValidating = fieldMetaValues.some(\n (field) => field?.isValidating,\n )\n\n const isFieldsValid = !fieldMetaValues.some(\n (field) =>\n field?.errorMap &&\n isNonEmptyArray(Object.values(field.errorMap).filter(Boolean)),\n )\n\n const isTouched = fieldMetaValues.some((field) => field?.isTouched)\n\n const isDirty = fieldMetaValues.some((field) => field?.isDirty)\n const isPristine = !isDirty\n\n const isValidating = isFieldsValidating || state.isFormValidating\n state.errors = Object.values(state.errorMap).filter(\n (val: unknown) => val !== undefined,\n )\n const isFormValid = state.errors.length === 0\n const isValid = isFieldsValid && isFormValid\n const canSubmit =\n (state.submissionAttempts === 0 && !isTouched) ||\n (!isValidating && !state.isSubmitting && isValid)\n\n state = {\n ...state,\n isFieldsValidating,\n isFieldsValid,\n isFormValid,\n isValid,\n canSubmit,\n isTouched,\n isPristine,\n isDirty,\n }\n\n this.state = state\n this.store.state = this.state\n\n // Only run transform if state has shallowly changed - IE how React.useEffect works\n const transformArray = this.options.transform?.deps ?? []\n const shouldTransform =\n transformArray.length !== this.prevTransformArray.length ||\n transformArray.some((val, i) => val !== this.prevTransformArray[i])\n\n if (shouldTransform) {\n // This mutates the state\n this.options.transform?.fn(this)\n this.store.state = this.state\n this.prevTransformArray = transformArray\n }\n },\n },\n )\n\n this.state = this.store.state\n\n this.update(opts || {})\n }\n\n runValidator<\n TValue extends { value: TFormData; formApi: FormApi<any, any> },\n TType extends 'validate' | 'validateAsync',\n >(props: {\n validate: TType extends 'validate'\n ? FormValidateOrFn<TFormData, TFormValidator>\n : FormAsyncValidateOrFn<TFormData, TFormValidator>\n value: TValue\n type: TType\n }): ReturnType<ReturnType<Validator<any>>[TType]> {\n const adapter = this.options.validatorAdapter\n if (adapter && typeof props.validate !== 'function') {\n return adapter()[props.type](props.value, props.validate) as never\n }\n\n return (props.validate as FormValidateFn<any, any>)(props.value) as never\n }\n\n mount = () => {\n const { onMount } = this.options.validators || {}\n if (!onMount) return\n const error = this.runValidator({\n validate: onMount,\n value: {\n value: this.state.values,\n formApi: this,\n },\n type: 'validate',\n })\n if (error) {\n this.store.setState((prev) => ({\n ...prev,\n errorMap: { ...prev.errorMap, onMount: error },\n }))\n }\n }\n\n update = (options?: FormOptions<TFormData, TFormValidator>) => {\n if (!options) return\n\n const oldOptions = this.options\n\n // Options need to be updated first so that when the store is updated, the state is correct for the derived state\n this.options = options\n\n this.store.batch(() => {\n const shouldUpdateValues =\n options.defaultValues &&\n options.defaultValues !== oldOptions.defaultValues &&\n !this.state.isTouched\n\n const shouldUpdateState =\n options.defaultState !== oldOptions.defaultState &&\n !this.state.isTouched\n\n this.store.setState(() =>\n getDefaultFormState(\n Object.assign(\n {},\n this.state as any,\n\n shouldUpdateState ? options.defaultState : {},\n\n shouldUpdateValues\n ? {\n values: options.defaultValues,\n }\n : {},\n ),\n ),\n )\n })\n }\n\n reset = () => {\n const { fieldMeta: currentFieldMeta } = this.state\n const fieldMeta = this.resetFieldMeta(currentFieldMeta)\n this.store.setState(() =>\n getDefaultFormState({\n ...(this.options.defaultState as any),\n values: this.options.defaultValues ?? this.options.defaultState?.values,\n fieldMeta,\n }),\n )\n }\n\n validateAllFields = async (cause: ValidationCause) => {\n const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any\n this.store.batch(() => {\n void (\n Object.values(this.fieldInfo) as FieldInfo<any, TFormValidator>[]\n ).forEach((field) => {\n if (!field.instance) return\n const fieldInstance = field.instance\n // Validate the field\n fieldValidationPromises.push(\n Promise.resolve().then(() => fieldInstance.validate(cause)),\n )\n // If any fields are not touched\n if (!field.instance.state.meta.isTouched) {\n // Mark them as touched\n field.instance.setMeta((prev) => ({ ...prev, isTouched: true }))\n }\n })\n })\n\n const fieldErrorMapMap = await Promise.all(fieldValidationPromises)\n return fieldErrorMapMap.flat()\n }\n\n // TODO: This code is copied from FieldApi, we should refactor to share\n validateSync = (cause: ValidationCause) => {\n const validates = getSyncValidatorArray(cause, this.options)\n let hasErrored = false as boolean\n\n this.store.batch(() => {\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n\n const error = normalizeError(\n this.runValidator({\n validate: validateObj.validate,\n value: {\n value: this.state.values,\n formApi: this,\n },\n type: 'validate',\n }),\n )\n const errorMapKey = getErrorMapKey(validateObj.cause)\n if (this.state.errorMap[errorMapKey] !== error) {\n this.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: error,\n },\n }))\n }\n if (error) {\n hasErrored = true\n }\n }\n })\n\n /**\n * when we have an error for onSubmit in the state, we want\n * to clear the error as soon as the user enters a valid value in the field\n */\n const submitErrKey = getErrorMapKey('submit')\n if (\n this.state.errorMap[submitErrKey] &&\n cause !== 'submit' &&\n !hasErrored\n ) {\n this.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [submitErrKey]: undefined,\n },\n }))\n }\n\n return { hasErrored }\n }\n\n validateAsync = async (\n cause: ValidationCause,\n ): Promise<ValidationError[]> => {\n const validates = getAsyncValidatorArray(cause, this.options)\n\n if (!this.state.isFormValidating) {\n this.store.setState((prev) => ({ ...prev, isFormValidating: true }))\n }\n\n /**\n * We have to use a for loop and generate our promises this way, otherwise it won't be sync\n * when there are no validators needed to be run\n */\n const promises: Promise<ValidationError | undefined>[] = []\n\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n const key = getErrorMapKey(validateObj.cause)\n const fieldValidatorMeta = this.state.validationMetaMap[key]\n\n fieldValidatorMeta?.lastAbortController.abort()\n const controller = new AbortController()\n\n this.state.validationMetaMap[key] = {\n lastAbortController: controller,\n }\n\n promises.push(\n new Promise<ValidationError | undefined>(async (resolve) => {\n let rawError!: ValidationError | undefined\n try {\n rawError = await new Promise((rawResolve, rawReject) => {\n setTimeout(async () => {\n if (controller.signal.aborted) return rawResolve(undefined)\n try {\n rawResolve(\n await this.runValidator({\n validate: validateObj.validate!,\n value: {\n value: this.state.values,\n formApi: this,\n signal: controller.signal,\n },\n type: 'validateAsync',\n }),\n )\n } catch (e) {\n rawReject(e)\n }\n }, validateObj.debounceMs)\n })\n } catch (e: unknown) {\n rawError = e as ValidationError\n }\n const error = normalizeError(rawError)\n this.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [getErrorMapKey(cause)]: error,\n },\n }))\n\n resolve(error)\n }),\n )\n }\n\n let results: ValidationError[] = []\n if (promises.length) {\n results = await Promise.all(promises)\n }\n\n this.store.setState((prev) => ({\n ...prev,\n isFormValidating: false,\n }))\n\n return results.filter(Boolean)\n }\n\n validate = (\n cause: ValidationCause,\n ): ValidationError[] | Promise<ValidationError[]> => {\n // Attempt to sync validate first\n const { hasErrored } = this.validateSync(cause)\n\n if (hasErrored && !this.options.asyncAlways) {\n return this.state.errors\n }\n\n // No error? Attempt async validation\n return this.validateAsync(cause)\n }\n\n handleSubmit = async () => {\n // Check to see that the form and all fields have been touched\n // If they have not, touch them all and run validation\n // Run form validation\n // Submit the form\n\n this.store.setState((old) => ({\n ...old,\n // Submission attempts mark the form as not submitted\n isSubmitted: false,\n // Count submission attempts\n submissionAttempts: old.submissionAttempts + 1,\n }))\n\n // Don't let invalid forms submit\n if (!this.state.canSubmit) return\n\n this.store.setState((d) => ({ ...d, isSubmitting: true }))\n\n const done = () => {\n this.store.setState((prev) => ({ ...prev, isSubmitting: false }))\n }\n\n // Validate all fields\n await this.validateAllFields('submit')\n\n // Fields are invalid, do not submit\n if (!this.state.isFieldsValid) {\n done()\n this.options.onSubmitInvalid?.({\n value: this.state.values,\n formApi: this,\n })\n return\n }\n\n // Run validation for the form\n await this.validate('submit')\n\n if (!this.state.isValid) {\n done()\n this.options.onSubmitInvalid?.({\n value: this.state.values,\n formApi: this,\n })\n return\n }\n\n try {\n // Run the submit code\n await this.options.onSubmit?.({ value: this.state.values, formApi: this })\n\n this.store.batch(() => {\n this.store.setState((prev) => ({ ...prev, isSubmitted: true }))\n done()\n })\n } catch (err) {\n done()\n throw err\n }\n }\n\n getFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): DeepValue<TFormData, TField> => getBy(this.state.values, field)\n\n getFieldMeta = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): FieldMeta | undefined => {\n return this.state.fieldMeta[field]\n }\n\n getFieldInfo = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): FieldInfo<TFormData, TFormValidator> => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return (this.fieldInfo[field] ||= {\n instance: null,\n validationMetaMap: {\n onChange: undefined,\n onBlur: undefined,\n onSubmit: undefined,\n onMount: undefined,\n onServer: undefined,\n },\n })\n }\n\n setFieldMeta = <TField extends DeepKeys<TFormData>>(\n field: TField,\n updater: Updater<FieldMeta>,\n ) => {\n this.store.setState((prev) => {\n return {\n ...prev,\n fieldMeta: {\n ...prev.fieldMeta,\n [field]: functionalUpdate(updater, prev.fieldMeta[field]),\n },\n }\n })\n }\n\n resetFieldMeta = <TField extends DeepKeys<TFormData>>(\n fieldMeta: Record<TField, FieldMeta>,\n ): Record<TField, FieldMeta> => {\n return Object.keys(fieldMeta).reduce(\n (acc: Record<TField, FieldMeta>, key) => {\n const fieldKey = key as TField\n acc[fieldKey] = {\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n }\n return acc\n },\n {} as Record<TField, FieldMeta>,\n )\n }\n\n setFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n updater: Updater<DeepValue<TFormData, TField>>,\n opts?: { touch?: boolean },\n ) => {\n const touch = opts?.touch\n\n this.store.batch(() => {\n if (touch) {\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n isTouched: true,\n isDirty: true,\n }))\n }\n\n this.store.setState((prev) => {\n return {\n ...prev,\n values: setBy(prev.values, field, updater),\n }\n })\n })\n }\n\n deleteField = <TField extends DeepKeys<TFormData>>(field: TField) => {\n this.store.setState((prev) => {\n const newState = { ...prev }\n newState.values = deleteBy(newState.values, field)\n delete newState.fieldMeta[field]\n\n return newState\n })\n delete this.fieldInfo[field]\n }\n\n pushFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: { touch?: boolean },\n ) => {\n return this.setFieldValue(\n field,\n (prev) => [...(Array.isArray(prev) ? prev : []), value] as any,\n opts,\n )\n }\n\n insertFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: { touch?: boolean },\n ) => {\n this.setFieldValue(\n field,\n (prev) => {\n return (prev as DeepValue<TFormData, TField>[]).map((d, i) =>\n i === index ? value : d,\n ) as any\n },\n opts,\n )\n }\n\n removeFieldValue = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n opts?: { touch?: boolean },\n ) => {\n const fieldValue = this.getFieldValue(field)\n\n const lastIndex = Array.isArray(fieldValue)\n ? Math.max(fieldValue.length - 1, 0)\n : null\n\n this.setFieldValue(\n field,\n (prev) => {\n return (prev as DeepValue<TFormData, TField>[]).filter(\n (_d, i) => i !== index,\n ) as any\n },\n opts,\n )\n\n if (lastIndex !== null) {\n const start = `${field}[${lastIndex}]`\n const fieldsToDelete = Object.keys(this.fieldInfo).filter((f) =>\n f.startsWith(start),\n )\n\n // Cleanup the last fields\n fieldsToDelete.forEach((f) => this.deleteField(f as TField))\n }\n\n await this.validateAllFields('change')\n }\n\n swapFieldValues = <TField extends DeepKeys<TFormData>>(\n field: TField,\n index1: number,\n index2: number,\n ) => {\n this.setFieldValue(field, (prev: any) => {\n const prev1 = prev[index1]!\n const prev2 = prev[index2]!\n return setBy(setBy(prev, `${index1}`, prev2), `${index2}`, prev1)\n })\n }\n\n moveFieldValues = <TField extends DeepKeys<TFormData>>(\n field: TField,\n index1: number,\n index2: number,\n ) => {\n this.setFieldValue(field, (prev: any) => {\n prev.splice(index2, 0, prev.splice(index1, 1)[0])\n return prev\n })\n }\n}\n\nfunction normalizeError(rawError?: ValidationError) {\n if (rawError) {\n if (typeof rawError !== 'string') {\n return 'Invalid Form Values'\n }\n\n return rawError\n }\n\n return undefined\n}\n\nfunction getErrorMapKey(cause: ValidationCause) {\n switch (cause) {\n case 'submit':\n return 'onSubmit'\n case 'blur':\n return 'onBlur'\n case 'mount':\n return 'onMount'\n case 'server':\n return 'onServer'\n case 'change':\n default:\n return 'onChange'\n }\n}\n"],"names":["_a","opts"],"mappings":"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"}
1
+ {"version":3,"file":"FormApi.js","sources":["../../src/FormApi.ts"],"sourcesContent":["import { Store } from '@tanstack/store'\nimport {\n deleteBy,\n functionalUpdate,\n getAsyncValidatorArray,\n getBy,\n getSyncValidatorArray,\n isNonEmptyArray,\n setBy,\n} from './utils'\nimport type { Updater } from './utils'\nimport type { DeepKeys, DeepValue } from './util-types'\nimport type { FieldApi, FieldMeta } from './FieldApi'\nimport type {\n ValidationCause,\n ValidationError,\n ValidationErrorMap,\n ValidationErrorMapKeys,\n Validator,\n} from './types'\n\nexport type FormValidateFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (props: {\n value: TFormData\n formApi: FormApi<TFormData, TFormValidator>\n}) => ValidationError\n\nexport type FormValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer TFN>\n ? TFN\n : FormValidateFn<TFormData, TFormValidator>\n\nexport type FormValidateAsyncFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (props: {\n value: TFormData\n formApi: FormApi<TFormData, TFormValidator>\n signal: AbortSignal\n}) => ValidationError | Promise<ValidationError>\n\nexport type FormAsyncValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer FFN>\n ? FFN | FormValidateAsyncFn<TFormData, TFormValidator>\n : FormValidateAsyncFn<TFormData, TFormValidator>\n\nexport interface FormValidators<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n onMount?: FormValidateOrFn<TFormData, TFormValidator>\n onChange?: FormValidateOrFn<TFormData, TFormValidator>\n onChangeAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\n onChangeAsyncDebounceMs?: number\n onBlur?: FormValidateOrFn<TFormData, TFormValidator>\n onBlurAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\n onBlurAsyncDebounceMs?: number\n onSubmit?: FormValidateOrFn<TFormData, TFormValidator>\n onSubmitAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\n}\n\nexport interface FormTransform<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n fn: (\n formBase: FormApi<TFormData, TFormValidator>,\n ) => FormApi<TFormData, TFormValidator>\n deps: unknown[]\n}\n\nexport interface FormOptions<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n defaultValues?: TFormData\n defaultState?: Partial<FormState<TFormData>>\n asyncAlways?: boolean\n asyncDebounceMs?: number\n validatorAdapter?: TFormValidator\n validators?: FormValidators<TFormData, TFormValidator>\n onSubmit?: (props: {\n value: TFormData\n formApi: FormApi<TFormData, TFormValidator>\n }) => any | Promise<any>\n onSubmitInvalid?: (props: {\n value: TFormData\n formApi: FormApi<TFormData, TFormValidator>\n }) => void\n transform?: FormTransform<TFormData, TFormValidator>\n}\n\nexport type ValidationMeta = {\n lastAbortController: AbortController\n}\n\nexport type FieldInfo<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = {\n instance: FieldApi<\n TFormData,\n any,\n Validator<unknown, unknown> | undefined,\n TFormValidator\n > | null\n validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>\n}\n\nexport type FormState<TFormData> = {\n values: TFormData\n // Form Validation\n isFormValidating: boolean\n isFormValid: boolean\n errors: ValidationError[]\n errorMap: ValidationErrorMap\n validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>\n // Fields\n fieldMeta: Record<DeepKeys<TFormData>, FieldMeta>\n isFieldsValidating: boolean\n isFieldsValid: boolean\n isSubmitting: boolean\n // General\n isTouched: boolean\n isDirty: boolean\n isPristine: boolean\n isSubmitted: boolean\n isValidating: boolean\n isValid: boolean\n canSubmit: boolean\n submissionAttempts: number\n}\n\nfunction getDefaultFormState<TFormData>(\n defaultState: Partial<FormState<TFormData>>,\n): FormState<TFormData> {\n return {\n values: defaultState.values ?? ({} as never),\n errors: defaultState.errors ?? [],\n errorMap: defaultState.errorMap ?? {},\n fieldMeta: defaultState.fieldMeta ?? ({} as never),\n canSubmit: defaultState.canSubmit ?? true,\n isFieldsValid: defaultState.isFieldsValid ?? false,\n isFieldsValidating: defaultState.isFieldsValidating ?? false,\n isFormValid: defaultState.isFormValid ?? false,\n isFormValidating: defaultState.isFormValidating ?? false,\n isSubmitted: defaultState.isSubmitted ?? false,\n isSubmitting: defaultState.isSubmitting ?? false,\n isTouched: defaultState.isTouched ?? false,\n isPristine: defaultState.isPristine ?? true,\n isDirty: defaultState.isDirty ?? false,\n isValid: defaultState.isValid ?? false,\n isValidating: defaultState.isValidating ?? false,\n submissionAttempts: defaultState.submissionAttempts ?? 0,\n validationMetaMap: defaultState.validationMetaMap ?? {\n onChange: undefined,\n onBlur: undefined,\n onSubmit: undefined,\n onMount: undefined,\n onServer: undefined,\n },\n }\n}\n\nexport class FormApi<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n options: FormOptions<TFormData, TFormValidator> = {}\n store!: Store<FormState<TFormData>>\n // Do not use __state directly, as it is not reactive.\n // Please use form.useStore() utility to subscribe to state\n state!: FormState<TFormData>\n // // This carries the context for nested fields\n fieldInfo: Record<DeepKeys<TFormData>, FieldInfo<TFormData, TFormValidator>> =\n {} as any\n\n prevTransformArray: unknown[] = []\n\n constructor(opts?: FormOptions<TFormData, TFormValidator>) {\n this.store = new Store<FormState<TFormData>>(\n getDefaultFormState({\n ...(opts?.defaultState as any),\n values: opts?.defaultValues ?? opts?.defaultState?.values,\n isFormValid: true,\n }),\n {\n onUpdate: () => {\n let { state } = this.store\n // Computed state\n const fieldMetaValues = Object.values(state.fieldMeta) as (\n | FieldMeta\n | undefined\n )[]\n\n const isFieldsValidating = fieldMetaValues.some(\n (field) => field?.isValidating,\n )\n\n const isFieldsValid = !fieldMetaValues.some(\n (field) =>\n field?.errorMap &&\n isNonEmptyArray(Object.values(field.errorMap).filter(Boolean)),\n )\n\n const isTouched = fieldMetaValues.some((field) => field?.isTouched)\n\n const isDirty = fieldMetaValues.some((field) => field?.isDirty)\n const isPristine = !isDirty\n\n const isValidating = isFieldsValidating || state.isFormValidating\n state.errors = Object.values(state.errorMap).filter(\n (val: unknown) => val !== undefined,\n )\n const isFormValid = state.errors.length === 0\n const isValid = isFieldsValid && isFormValid\n const canSubmit =\n (state.submissionAttempts === 0 && !isTouched) ||\n (!isValidating && !state.isSubmitting && isValid)\n\n state = {\n ...state,\n isFieldsValidating,\n isFieldsValid,\n isFormValid,\n isValid,\n canSubmit,\n isTouched,\n isPristine,\n isDirty,\n }\n\n this.state = state\n this.store.state = this.state\n\n // Only run transform if state has shallowly changed - IE how React.useEffect works\n const transformArray = this.options.transform?.deps ?? []\n const shouldTransform =\n transformArray.length !== this.prevTransformArray.length ||\n transformArray.some((val, i) => val !== this.prevTransformArray[i])\n\n if (shouldTransform) {\n // This mutates the state\n this.options.transform?.fn(this)\n this.store.state = this.state\n this.prevTransformArray = transformArray\n }\n },\n },\n )\n\n this.state = this.store.state\n\n this.update(opts || {})\n }\n\n runValidator<\n TValue extends { value: TFormData; formApi: FormApi<any, any> },\n TType extends 'validate' | 'validateAsync',\n >(props: {\n validate: TType extends 'validate'\n ? FormValidateOrFn<TFormData, TFormValidator>\n : FormAsyncValidateOrFn<TFormData, TFormValidator>\n value: TValue\n type: TType\n }): ReturnType<ReturnType<Validator<any>>[TType]> {\n const adapter = this.options.validatorAdapter\n if (adapter && typeof props.validate !== 'function') {\n return adapter()[props.type](props.value, props.validate) as never\n }\n\n return (props.validate as FormValidateFn<any, any>)(props.value) as never\n }\n\n mount = () => {\n const { onMount } = this.options.validators || {}\n if (!onMount) return\n const error = this.runValidator({\n validate: onMount,\n value: {\n value: this.state.values,\n formApi: this,\n },\n type: 'validate',\n })\n if (error) {\n this.store.setState((prev) => ({\n ...prev,\n errorMap: { ...prev.errorMap, onMount: error },\n }))\n }\n }\n\n update = (options?: FormOptions<TFormData, TFormValidator>) => {\n if (!options) return\n\n const oldOptions = this.options\n\n // Options need to be updated first so that when the store is updated, the state is correct for the derived state\n this.options = options\n\n this.store.batch(() => {\n const shouldUpdateValues =\n options.defaultValues &&\n options.defaultValues !== oldOptions.defaultValues &&\n !this.state.isTouched\n\n const shouldUpdateState =\n options.defaultState !== oldOptions.defaultState &&\n !this.state.isTouched\n\n this.store.setState(() =>\n getDefaultFormState(\n Object.assign(\n {},\n this.state as any,\n\n shouldUpdateState ? options.defaultState : {},\n\n shouldUpdateValues\n ? {\n values: options.defaultValues,\n }\n : {},\n ),\n ),\n )\n })\n }\n\n reset = () => {\n const { fieldMeta: currentFieldMeta } = this.state\n const fieldMeta = this.resetFieldMeta(currentFieldMeta)\n this.store.setState(() =>\n getDefaultFormState({\n ...(this.options.defaultState as any),\n values: this.options.defaultValues ?? this.options.defaultState?.values,\n fieldMeta,\n }),\n )\n }\n\n validateAllFields = async (cause: ValidationCause) => {\n const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any\n this.store.batch(() => {\n void (\n Object.values(this.fieldInfo) as FieldInfo<any, TFormValidator>[]\n ).forEach((field) => {\n if (!field.instance) return\n const fieldInstance = field.instance\n // Validate the field\n fieldValidationPromises.push(\n Promise.resolve().then(() => fieldInstance.validate(cause)),\n )\n // If any fields are not touched\n if (!field.instance.state.meta.isTouched) {\n // Mark them as touched\n field.instance.setMeta((prev) => ({ ...prev, isTouched: true }))\n }\n })\n })\n\n const fieldErrorMapMap = await Promise.all(fieldValidationPromises)\n return fieldErrorMapMap.flat()\n }\n\n validateArrayFieldsStartingFrom = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n cause: ValidationCause,\n ) => {\n const currentValue = this.getFieldValue(field)\n\n const lastIndex = Array.isArray(currentValue)\n ? Math.max(currentValue.length - 1, 0)\n : null\n\n // We have to validate all fields that have shifted (at least the current field)\n const fieldKeysToValidate = [`${field}[${index}]`]\n for (let i = index + 1; i <= (lastIndex ?? 0); i++) {\n fieldKeysToValidate.push(`${field}[${i}]`)\n }\n\n // We also have to include all fields that are nested in the shifted fields\n const fieldsToValidate = Object.keys(this.fieldInfo).filter((fieldKey) =>\n fieldKeysToValidate.some((key) => fieldKey.startsWith(key)),\n ) as DeepKeys<TFormData>[]\n\n // Validate the fields\n const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any\n this.store.batch(() => {\n fieldsToValidate.forEach((nestedField) => {\n fieldValidationPromises.push(\n Promise.resolve().then(() => this.validateField(nestedField, cause)),\n )\n })\n })\n\n const fieldErrorMapMap = await Promise.all(fieldValidationPromises)\n return fieldErrorMapMap.flat()\n }\n\n validateField = <TField extends DeepKeys<TFormData>>(\n field: TField,\n cause: ValidationCause,\n ) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const fieldInstance = this.fieldInfo[field]?.instance\n if (!fieldInstance) return []\n\n // If the field is not touched (same logic as in validateAllFields)\n if (!fieldInstance.state.meta.isTouched) {\n // Mark it as touched\n fieldInstance.setMeta((prev) => ({ ...prev, isTouched: true }))\n }\n\n return fieldInstance.validate(cause)\n }\n\n // TODO: This code is copied from FieldApi, we should refactor to share\n validateSync = (cause: ValidationCause) => {\n const validates = getSyncValidatorArray(cause, this.options)\n let hasErrored = false as boolean\n\n this.store.batch(() => {\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n\n const error = normalizeError(\n this.runValidator({\n validate: validateObj.validate,\n value: {\n value: this.state.values,\n formApi: this,\n },\n type: 'validate',\n }),\n )\n const errorMapKey = getErrorMapKey(validateObj.cause)\n if (this.state.errorMap[errorMapKey] !== error) {\n this.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: error,\n },\n }))\n }\n if (error) {\n hasErrored = true\n }\n }\n })\n\n /**\n * when we have an error for onSubmit in the state, we want\n * to clear the error as soon as the user enters a valid value in the field\n */\n const submitErrKey = getErrorMapKey('submit')\n if (\n this.state.errorMap[submitErrKey] &&\n cause !== 'submit' &&\n !hasErrored\n ) {\n this.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [submitErrKey]: undefined,\n },\n }))\n }\n\n return { hasErrored }\n }\n\n validateAsync = async (\n cause: ValidationCause,\n ): Promise<ValidationError[]> => {\n const validates = getAsyncValidatorArray(cause, this.options)\n\n if (!this.state.isFormValidating) {\n this.store.setState((prev) => ({ ...prev, isFormValidating: true }))\n }\n\n /**\n * We have to use a for loop and generate our promises this way, otherwise it won't be sync\n * when there are no validators needed to be run\n */\n const promises: Promise<ValidationError | undefined>[] = []\n\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n const key = getErrorMapKey(validateObj.cause)\n const fieldValidatorMeta = this.state.validationMetaMap[key]\n\n fieldValidatorMeta?.lastAbortController.abort()\n const controller = new AbortController()\n\n this.state.validationMetaMap[key] = {\n lastAbortController: controller,\n }\n\n promises.push(\n new Promise<ValidationError | undefined>(async (resolve) => {\n let rawError!: ValidationError | undefined\n try {\n rawError = await new Promise((rawResolve, rawReject) => {\n setTimeout(async () => {\n if (controller.signal.aborted) return rawResolve(undefined)\n try {\n rawResolve(\n await this.runValidator({\n validate: validateObj.validate!,\n value: {\n value: this.state.values,\n formApi: this,\n signal: controller.signal,\n },\n type: 'validateAsync',\n }),\n )\n } catch (e) {\n rawReject(e)\n }\n }, validateObj.debounceMs)\n })\n } catch (e: unknown) {\n rawError = e as ValidationError\n }\n const error = normalizeError(rawError)\n this.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [getErrorMapKey(cause)]: error,\n },\n }))\n\n resolve(error)\n }),\n )\n }\n\n let results: ValidationError[] = []\n if (promises.length) {\n results = await Promise.all(promises)\n }\n\n this.store.setState((prev) => ({\n ...prev,\n isFormValidating: false,\n }))\n\n return results.filter(Boolean)\n }\n\n validate = (\n cause: ValidationCause,\n ): ValidationError[] | Promise<ValidationError[]> => {\n // Attempt to sync validate first\n const { hasErrored } = this.validateSync(cause)\n\n if (hasErrored && !this.options.asyncAlways) {\n return this.state.errors\n }\n\n // No error? Attempt async validation\n return this.validateAsync(cause)\n }\n\n handleSubmit = async () => {\n // Check to see that the form and all fields have been touched\n // If they have not, touch them all and run validation\n // Run form validation\n // Submit the form\n\n this.store.setState((old) => ({\n ...old,\n // Submission attempts mark the form as not submitted\n isSubmitted: false,\n // Count submission attempts\n submissionAttempts: old.submissionAttempts + 1,\n }))\n\n // Don't let invalid forms submit\n if (!this.state.canSubmit) return\n\n this.store.setState((d) => ({ ...d, isSubmitting: true }))\n\n const done = () => {\n this.store.setState((prev) => ({ ...prev, isSubmitting: false }))\n }\n\n // Validate all fields\n await this.validateAllFields('submit')\n\n // Fields are invalid, do not submit\n if (!this.state.isFieldsValid) {\n done()\n this.options.onSubmitInvalid?.({\n value: this.state.values,\n formApi: this,\n })\n return\n }\n\n // Run validation for the form\n await this.validate('submit')\n\n if (!this.state.isValid) {\n done()\n this.options.onSubmitInvalid?.({\n value: this.state.values,\n formApi: this,\n })\n return\n }\n\n try {\n // Run the submit code\n await this.options.onSubmit?.({ value: this.state.values, formApi: this })\n\n this.store.batch(() => {\n this.store.setState((prev) => ({ ...prev, isSubmitted: true }))\n done()\n })\n } catch (err) {\n done()\n throw err\n }\n }\n\n getFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): DeepValue<TFormData, TField> => getBy(this.state.values, field)\n\n getFieldMeta = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): FieldMeta | undefined => {\n return this.state.fieldMeta[field]\n }\n\n getFieldInfo = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): FieldInfo<TFormData, TFormValidator> => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return (this.fieldInfo[field] ||= {\n instance: null,\n validationMetaMap: {\n onChange: undefined,\n onBlur: undefined,\n onSubmit: undefined,\n onMount: undefined,\n onServer: undefined,\n },\n })\n }\n\n setFieldMeta = <TField extends DeepKeys<TFormData>>(\n field: TField,\n updater: Updater<FieldMeta>,\n ) => {\n this.store.setState((prev) => {\n return {\n ...prev,\n fieldMeta: {\n ...prev.fieldMeta,\n [field]: functionalUpdate(updater, prev.fieldMeta[field]),\n },\n }\n })\n }\n\n resetFieldMeta = <TField extends DeepKeys<TFormData>>(\n fieldMeta: Record<TField, FieldMeta>,\n ): Record<TField, FieldMeta> => {\n return Object.keys(fieldMeta).reduce(\n (acc: Record<TField, FieldMeta>, key) => {\n const fieldKey = key as TField\n acc[fieldKey] = {\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n }\n return acc\n },\n {} as Record<TField, FieldMeta>,\n )\n }\n\n setFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n updater: Updater<DeepValue<TFormData, TField>>,\n opts?: { touch?: boolean },\n ) => {\n const touch = opts?.touch\n\n this.store.batch(() => {\n if (touch) {\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n isTouched: true,\n isDirty: true,\n }))\n }\n\n this.store.setState((prev) => {\n return {\n ...prev,\n values: setBy(prev.values, field, updater),\n }\n })\n })\n }\n\n deleteField = <TField extends DeepKeys<TFormData>>(field: TField) => {\n this.store.setState((prev) => {\n const newState = { ...prev }\n newState.values = deleteBy(newState.values, field)\n delete newState.fieldMeta[field]\n\n return newState\n })\n delete this.fieldInfo[field]\n }\n\n pushFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: { touch?: boolean },\n ) => {\n this.setFieldValue(\n field,\n (prev) => [...(Array.isArray(prev) ? prev : []), value] as any,\n opts,\n )\n this.validateField(field, 'change')\n }\n\n insertFieldValue = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: { touch?: boolean },\n ) => {\n this.setFieldValue(\n field,\n (prev) => {\n return (prev as DeepValue<TFormData, TField>[]).map((d, i) =>\n i === index ? value : d,\n ) as any\n },\n opts,\n )\n\n // Validate the whole array + all fields that have shifted\n await this.validateField(field, 'change')\n await this.validateArrayFieldsStartingFrom(field, index, 'change')\n }\n\n removeFieldValue = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n opts?: { touch?: boolean },\n ) => {\n const fieldValue = this.getFieldValue(field)\n\n const lastIndex = Array.isArray(fieldValue)\n ? Math.max(fieldValue.length - 1, 0)\n : null\n\n this.setFieldValue(\n field,\n (prev) => {\n return (prev as DeepValue<TFormData, TField>[]).filter(\n (_d, i) => i !== index,\n ) as any\n },\n opts,\n )\n\n if (lastIndex !== null) {\n const start = `${field}[${lastIndex}]`\n const fieldsToDelete = Object.keys(this.fieldInfo).filter((f) =>\n f.startsWith(start),\n )\n\n // Cleanup the last fields\n fieldsToDelete.forEach((f) => this.deleteField(f as TField))\n }\n\n // Validate the whole array + all fields that have shifted\n await this.validateField(field, 'change')\n await this.validateArrayFieldsStartingFrom(field, index, 'change')\n }\n\n swapFieldValues = <TField extends DeepKeys<TFormData>>(\n field: TField,\n index1: number,\n index2: number,\n ) => {\n this.setFieldValue(field, (prev: any) => {\n const prev1 = prev[index1]!\n const prev2 = prev[index2]!\n return setBy(setBy(prev, `${index1}`, prev2), `${index2}`, prev1)\n })\n\n // Validate the whole array\n this.validateField(field, 'change')\n // Validate the swapped fields\n this.validateField(`${field}[${index1}]` as DeepKeys<TFormData>, 'change')\n this.validateField(`${field}[${index2}]` as DeepKeys<TFormData>, 'change')\n }\n\n moveFieldValues = <TField extends DeepKeys<TFormData>>(\n field: TField,\n index1: number,\n index2: number,\n ) => {\n this.setFieldValue(field, (prev: any) => {\n prev.splice(index2, 0, prev.splice(index1, 1)[0])\n return prev\n })\n\n // Validate the whole array\n this.validateField(field, 'change')\n // Validate the moved fields\n this.validateField(`${field}[${index1}]` as DeepKeys<TFormData>, 'change')\n this.validateField(`${field}[${index2}]` as DeepKeys<TFormData>, 'change')\n }\n}\n\nfunction normalizeError(rawError?: ValidationError) {\n if (rawError) {\n if (typeof rawError !== 'string') {\n return 'Invalid Form Values'\n }\n\n return rawError\n }\n\n return undefined\n}\n\nfunction getErrorMapKey(cause: ValidationCause) {\n switch (cause) {\n case 'submit':\n return 'onSubmit'\n case 'blur':\n return 'onBlur'\n case 'mount':\n return 'onMount'\n case 'server':\n return 'onServer'\n case 'change':\n default:\n return 'onChange'\n }\n}\n"],"names":["_a","opts"],"mappings":"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"}
package/dist/esm/utils.js CHANGED
@@ -21,6 +21,9 @@ function setBy(obj, _path, updater) {
21
21
  const key = path.shift();
22
22
  if (typeof key === "string") {
23
23
  if (typeof parent === "object") {
24
+ if (parent === null) {
25
+ parent = {};
26
+ }
24
27
  return {
25
28
  ...parent,
26
29
  [key]: doSet(parent[key])
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["import type { ValidationCause } from './types'\nimport type { FormValidators } from './FormApi'\nimport type { FieldValidators } from './FieldApi'\n\nexport type UpdaterFn<TInput, TOutput = TInput> = (input: TInput) => TOutput\n\nexport type Updater<TInput, TOutput = TInput> =\n | TOutput\n | UpdaterFn<TInput, TOutput>\n\nexport function functionalUpdate<TInput, TOutput = TInput>(\n updater: Updater<TInput, TOutput>,\n input: TInput,\n): TOutput {\n return typeof updater === 'function'\n ? (updater as UpdaterFn<TInput, TOutput>)(input)\n : updater\n}\n\n/**\n * Get a value from an object using a path, including dot notation.\n */\nexport function getBy(obj: any, path: any) {\n const pathObj = makePathArray(path)\n return pathObj.reduce((current: any, pathPart: any) => {\n if (current === null) return null\n if (typeof current !== 'undefined') {\n return current[pathPart]\n }\n return undefined\n }, obj)\n}\n\n/**\n * Set a value on an object using a path, including dot notation.\n */\nexport function setBy(obj: any, _path: any, updater: Updater<any>) {\n const path = makePathArray(_path)\n\n function doSet(parent?: any): any {\n if (!path.length) {\n return functionalUpdate(updater, parent)\n }\n\n const key = path.shift()\n\n if (typeof key === 'string') {\n if (typeof parent === 'object') {\n return {\n ...parent,\n [key]: doSet(parent[key]),\n }\n }\n return {\n [key]: doSet(),\n }\n }\n\n if (Array.isArray(parent) && key !== undefined) {\n const prefix = parent.slice(0, key)\n return [\n ...(prefix.length ? prefix : new Array(key)),\n doSet(parent[key]),\n ...parent.slice(key + 1),\n ]\n }\n return [...new Array(key), doSet()]\n }\n\n return doSet(obj)\n}\n\n/**\n * Delete a field on an object using a path, including dot notation.\n */\nexport function deleteBy(obj: any, _path: any) {\n const path = makePathArray(_path)\n\n function doDelete(parent: any): any {\n if (!parent) return\n if (path.length === 1) {\n const finalPath = path[0]!\n if (Array.isArray(parent) && typeof finalPath === 'number') {\n return parent.filter((_, i) => i !== finalPath)\n }\n const { [finalPath]: remove, ...rest } = parent\n return rest\n }\n\n const key = path.shift()\n\n if (typeof key === 'string') {\n if (typeof parent === 'object') {\n return {\n ...parent,\n [key]: doDelete(parent[key]),\n }\n }\n }\n\n if (typeof key === 'number') {\n if (Array.isArray(parent)) {\n if (key >= parent.length) {\n return parent\n }\n const prefix = parent.slice(0, key)\n return [\n ...(prefix.length ? prefix : new Array(key)),\n doDelete(parent[key]),\n ...parent.slice(key + 1),\n ]\n }\n }\n\n throw new Error('It seems we have created an infinite loop in deleteBy. ')\n }\n\n return doDelete(obj)\n}\n\nconst reFindNumbers0 = /^(\\d*)$/gm\nconst reFindNumbers1 = /\\.(\\d*)\\./gm\nconst reFindNumbers2 = /^(\\d*)\\./gm\nconst reFindNumbers3 = /\\.(\\d*$)/gm\nconst reFindMultiplePeriods = /\\.{2,}/gm\n\nconst intPrefix = '__int__'\nconst intReplace = `${intPrefix}$1`\n\nexport function makePathArray(str: string) {\n if (typeof str !== 'string') {\n throw new Error('Path must be a string.')\n }\n\n return str\n .replaceAll('[', '.')\n .replaceAll(']', '')\n .replace(reFindNumbers0, intReplace)\n .replace(reFindNumbers1, `.${intReplace}.`)\n .replace(reFindNumbers2, `${intReplace}.`)\n .replace(reFindNumbers3, `.${intReplace}`)\n .replace(reFindMultiplePeriods, '.')\n .split('.')\n .map((d) => {\n if (d.indexOf(intPrefix) === 0) {\n return parseInt(d.substring(intPrefix.length), 10)\n }\n return d\n })\n}\n\nexport function isNonEmptyArray(obj: any) {\n return !(Array.isArray(obj) && obj.length === 0)\n}\n\ninterface AsyncValidatorArrayPartialOptions<T> {\n validators?: T\n asyncDebounceMs?: number\n}\n\nexport interface AsyncValidator<T> {\n cause: ValidationCause\n validate: T\n debounceMs: number\n}\n\nexport function getAsyncValidatorArray<T>(\n cause: ValidationCause,\n options: AsyncValidatorArrayPartialOptions<T>,\n): T extends FieldValidators<any, any>\n ? Array<\n AsyncValidator<T['onChangeAsync'] | T['onBlurAsync'] | T['onSubmitAsync']>\n >\n : T extends FormValidators<any, any>\n ? Array<\n AsyncValidator<\n T['onChangeAsync'] | T['onBlurAsync'] | T['onSubmitAsync']\n >\n >\n : never {\n const { asyncDebounceMs } = options\n const {\n onChangeAsync,\n onBlurAsync,\n onSubmitAsync,\n onBlurAsyncDebounceMs,\n onChangeAsyncDebounceMs,\n } = (options.validators || {}) as\n | FieldValidators<any, any>\n | FormValidators<any, any>\n\n const defaultDebounceMs = asyncDebounceMs ?? 0\n\n const changeValidator = {\n cause: 'change',\n validate: onChangeAsync,\n debounceMs: onChangeAsyncDebounceMs ?? defaultDebounceMs,\n } as const\n\n const blurValidator = {\n cause: 'blur',\n validate: onBlurAsync,\n debounceMs: onBlurAsyncDebounceMs ?? defaultDebounceMs,\n } as const\n\n const submitValidator = {\n cause: 'submit',\n validate: onSubmitAsync,\n debounceMs: 0,\n } as const\n\n const noopValidator = (\n validator:\n | typeof changeValidator\n | typeof blurValidator\n | typeof submitValidator,\n ) => ({ ...validator, debounceMs: 0 }) as const\n\n switch (cause) {\n case 'submit':\n return [\n noopValidator(changeValidator),\n noopValidator(blurValidator),\n submitValidator,\n ] as never\n case 'blur':\n return [blurValidator] as never\n case 'change':\n return [changeValidator] as never\n case 'server':\n default:\n return [] as never\n }\n}\n\ninterface SyncValidatorArrayPartialOptions<T> {\n validators?: T\n}\n\nexport interface SyncValidator<T> {\n cause: ValidationCause\n validate: T\n}\n\nexport function getSyncValidatorArray<T>(\n cause: ValidationCause,\n options: SyncValidatorArrayPartialOptions<T>,\n): T extends FieldValidators<any, any>\n ? Array<SyncValidator<T['onChange'] | T['onBlur'] | T['onSubmit']>>\n : T extends FormValidators<any, any>\n ? Array<SyncValidator<T['onChange'] | T['onBlur'] | T['onSubmit']>>\n : never {\n const { onChange, onBlur, onSubmit } = (options.validators || {}) as\n | FieldValidators<any, any>\n | FormValidators<any, any>\n\n const changeValidator = { cause: 'change', validate: onChange } as const\n const blurValidator = { cause: 'blur', validate: onBlur } as const\n const submitValidator = { cause: 'submit', validate: onSubmit } as const\n\n // Allows us to clear onServer errors\n const serverValidator = {\n cause: 'server',\n validate: () => undefined,\n } as const\n\n switch (cause) {\n case 'submit':\n return [\n changeValidator,\n blurValidator,\n submitValidator,\n serverValidator,\n ] as never\n case 'server':\n return [serverValidator] as never\n case 'blur':\n return [blurValidator, serverValidator] as never\n case 'change':\n default:\n return [changeValidator, serverValidator] as never\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["import type { ValidationCause } from './types'\nimport type { FormValidators } from './FormApi'\nimport type { FieldValidators } from './FieldApi'\n\nexport type UpdaterFn<TInput, TOutput = TInput> = (input: TInput) => TOutput\n\nexport type Updater<TInput, TOutput = TInput> =\n | TOutput\n | UpdaterFn<TInput, TOutput>\n\nexport function functionalUpdate<TInput, TOutput = TInput>(\n updater: Updater<TInput, TOutput>,\n input: TInput,\n): TOutput {\n return typeof updater === 'function'\n ? (updater as UpdaterFn<TInput, TOutput>)(input)\n : updater\n}\n\n/**\n * Get a value from an object using a path, including dot notation.\n */\nexport function getBy(obj: any, path: any) {\n const pathObj = makePathArray(path)\n return pathObj.reduce((current: any, pathPart: any) => {\n if (current === null) return null\n if (typeof current !== 'undefined') {\n return current[pathPart]\n }\n return undefined\n }, obj)\n}\n\n/**\n * Set a value on an object using a path, including dot notation.\n */\nexport function setBy(obj: any, _path: any, updater: Updater<any>) {\n const path = makePathArray(_path)\n\n function doSet(parent?: any): any {\n if (!path.length) {\n return functionalUpdate(updater, parent)\n }\n\n const key = path.shift()\n\n if (typeof key === 'string') {\n if (typeof parent === 'object') {\n if (parent === null) {\n parent = {}\n }\n return {\n ...parent,\n [key]: doSet(parent[key]),\n }\n }\n return {\n [key]: doSet(),\n }\n }\n\n if (Array.isArray(parent) && key !== undefined) {\n const prefix = parent.slice(0, key)\n return [\n ...(prefix.length ? prefix : new Array(key)),\n doSet(parent[key]),\n ...parent.slice(key + 1),\n ]\n }\n return [...new Array(key), doSet()]\n }\n\n return doSet(obj)\n}\n\n/**\n * Delete a field on an object using a path, including dot notation.\n */\nexport function deleteBy(obj: any, _path: any) {\n const path = makePathArray(_path)\n\n function doDelete(parent: any): any {\n if (!parent) return\n if (path.length === 1) {\n const finalPath = path[0]!\n if (Array.isArray(parent) && typeof finalPath === 'number') {\n return parent.filter((_, i) => i !== finalPath)\n }\n const { [finalPath]: remove, ...rest } = parent\n return rest\n }\n\n const key = path.shift()\n\n if (typeof key === 'string') {\n if (typeof parent === 'object') {\n return {\n ...parent,\n [key]: doDelete(parent[key]),\n }\n }\n }\n\n if (typeof key === 'number') {\n if (Array.isArray(parent)) {\n if (key >= parent.length) {\n return parent\n }\n const prefix = parent.slice(0, key)\n return [\n ...(prefix.length ? prefix : new Array(key)),\n doDelete(parent[key]),\n ...parent.slice(key + 1),\n ]\n }\n }\n\n throw new Error('It seems we have created an infinite loop in deleteBy. ')\n }\n\n return doDelete(obj)\n}\n\nconst reFindNumbers0 = /^(\\d*)$/gm\nconst reFindNumbers1 = /\\.(\\d*)\\./gm\nconst reFindNumbers2 = /^(\\d*)\\./gm\nconst reFindNumbers3 = /\\.(\\d*$)/gm\nconst reFindMultiplePeriods = /\\.{2,}/gm\n\nconst intPrefix = '__int__'\nconst intReplace = `${intPrefix}$1`\n\nexport function makePathArray(str: string) {\n if (typeof str !== 'string') {\n throw new Error('Path must be a string.')\n }\n\n return str\n .replaceAll('[', '.')\n .replaceAll(']', '')\n .replace(reFindNumbers0, intReplace)\n .replace(reFindNumbers1, `.${intReplace}.`)\n .replace(reFindNumbers2, `${intReplace}.`)\n .replace(reFindNumbers3, `.${intReplace}`)\n .replace(reFindMultiplePeriods, '.')\n .split('.')\n .map((d) => {\n if (d.indexOf(intPrefix) === 0) {\n return parseInt(d.substring(intPrefix.length), 10)\n }\n return d\n })\n}\n\nexport function isNonEmptyArray(obj: any) {\n return !(Array.isArray(obj) && obj.length === 0)\n}\n\ninterface AsyncValidatorArrayPartialOptions<T> {\n validators?: T\n asyncDebounceMs?: number\n}\n\nexport interface AsyncValidator<T> {\n cause: ValidationCause\n validate: T\n debounceMs: number\n}\n\nexport function getAsyncValidatorArray<T>(\n cause: ValidationCause,\n options: AsyncValidatorArrayPartialOptions<T>,\n): T extends FieldValidators<any, any>\n ? Array<\n AsyncValidator<T['onChangeAsync'] | T['onBlurAsync'] | T['onSubmitAsync']>\n >\n : T extends FormValidators<any, any>\n ? Array<\n AsyncValidator<\n T['onChangeAsync'] | T['onBlurAsync'] | T['onSubmitAsync']\n >\n >\n : never {\n const { asyncDebounceMs } = options\n const {\n onChangeAsync,\n onBlurAsync,\n onSubmitAsync,\n onBlurAsyncDebounceMs,\n onChangeAsyncDebounceMs,\n } = (options.validators || {}) as\n | FieldValidators<any, any>\n | FormValidators<any, any>\n\n const defaultDebounceMs = asyncDebounceMs ?? 0\n\n const changeValidator = {\n cause: 'change',\n validate: onChangeAsync,\n debounceMs: onChangeAsyncDebounceMs ?? defaultDebounceMs,\n } as const\n\n const blurValidator = {\n cause: 'blur',\n validate: onBlurAsync,\n debounceMs: onBlurAsyncDebounceMs ?? defaultDebounceMs,\n } as const\n\n const submitValidator = {\n cause: 'submit',\n validate: onSubmitAsync,\n debounceMs: 0,\n } as const\n\n const noopValidator = (\n validator:\n | typeof changeValidator\n | typeof blurValidator\n | typeof submitValidator,\n ) => ({ ...validator, debounceMs: 0 }) as const\n\n switch (cause) {\n case 'submit':\n return [\n noopValidator(changeValidator),\n noopValidator(blurValidator),\n submitValidator,\n ] as never\n case 'blur':\n return [blurValidator] as never\n case 'change':\n return [changeValidator] as never\n case 'server':\n default:\n return [] as never\n }\n}\n\ninterface SyncValidatorArrayPartialOptions<T> {\n validators?: T\n}\n\nexport interface SyncValidator<T> {\n cause: ValidationCause\n validate: T\n}\n\nexport function getSyncValidatorArray<T>(\n cause: ValidationCause,\n options: SyncValidatorArrayPartialOptions<T>,\n): T extends FieldValidators<any, any>\n ? Array<SyncValidator<T['onChange'] | T['onBlur'] | T['onSubmit']>>\n : T extends FormValidators<any, any>\n ? Array<SyncValidator<T['onChange'] | T['onBlur'] | T['onSubmit']>>\n : never {\n const { onChange, onBlur, onSubmit } = (options.validators || {}) as\n | FieldValidators<any, any>\n | FormValidators<any, any>\n\n const changeValidator = { cause: 'change', validate: onChange } as const\n const blurValidator = { cause: 'blur', validate: onBlur } as const\n const submitValidator = { cause: 'submit', validate: onSubmit } as const\n\n // Allows us to clear onServer errors\n const serverValidator = {\n cause: 'server',\n validate: () => undefined,\n } as const\n\n switch (cause) {\n case 'submit':\n return [\n changeValidator,\n blurValidator,\n submitValidator,\n serverValidator,\n ] as never\n case 'server':\n return [serverValidator] as never\n case 'blur':\n return [blurValidator, serverValidator] as never\n case 'change':\n default:\n return [changeValidator, serverValidator] as never\n }\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/form-core",
3
- "version": "0.20.1",
3
+ "version": "0.20.3",
4
4
  "description": "Powerful, type-safe, framework agnostic forms.",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
package/src/FieldApi.ts CHANGED
@@ -477,9 +477,8 @@ export class FieldApi<
477
477
  value: TData extends any[] ? TData[number] : never,
478
478
  ) => this.form.insertFieldValue(this.name, index, value as any)
479
479
 
480
- removeValue = async (index: number, opts?: { touch: boolean }) => {
481
- await this.form.removeFieldValue(this.name, index, opts)
482
- }
480
+ removeValue = (index: number, opts?: { touch: boolean }) =>
481
+ this.form.removeFieldValue(this.name, index, opts)
483
482
 
484
483
  swapValues = (aIndex: number, bIndex: number) =>
485
484
  this.form.swapFieldValues(this.name, aIndex, bIndex)