Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@tanstack/form-core

Package Overview
Dependencies
Maintainers
5
Versions
217
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tanstack/form-core - npm Package Compare versions

Comparing version
1.32.1
to
1.33.0
+832
dist/cjs/FormGroupApi.cjs
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const store = require("@tanstack/store");
const utils = require("./utils.cjs");
const ValidationLogic = require("./ValidationLogic.cjs");
const standardSchemaValidator = require("./standardSchemaValidator.cjs");
const metaHelper = require("./metaHelper.cjs");
const FieldApi = require("./FieldApi.cjs");
function getDefaultFormGroupState(defaultState) {
return {
isSubmitted: defaultState.isSubmitted ?? false,
isSubmitting: defaultState.isSubmitting ?? false,
isValidating: defaultState.isValidating ?? false,
submissionAttempts: defaultState.submissionAttempts ?? 0,
isSubmitSuccessful: defaultState.isSubmitSuccessful ?? false
};
}
function getDefaultFormGroupMeta(defaultMeta) {
return {
...metaHelper.defaultFieldMeta,
...defaultMeta,
errors: [],
isPristine: true,
isValid: true,
isDefaultValue: true,
isFieldsValidating: false,
isFieldsValid: true,
isGroupValid: true,
canSubmit: true,
isSubmitting: false,
isSubmitted: false,
isValidating: false,
submissionAttempts: 0,
isSubmitSuccessful: false
};
}
class FormGroupApi {
constructor(opts) {
this.options = {};
this.setFormGroupState = (updater) => {
this.form.baseStore.setState((prev) => {
const prevGroupState = prev.formGroupStateBase[this.name] ?? getDefaultFormGroupState({});
return {
...prev,
formGroupStateBase: {
...prev.formGroupStateBase,
[this.name]: updater(prevGroupState)
}
};
});
};
this._lastDistributedFieldNames = {};
this.update = (opts2) => {
this.options = opts2;
this.name = opts2.name;
if (!this.state.meta.isTouched && this.options.defaultValue !== void 0) {
const formField = this.form.getFieldValue(this.name);
if (!utils.evaluate(formField, opts2.defaultValue)) {
this.form.setFieldValue(this.name, opts2.defaultValue, {
dontUpdateMeta: true,
dontValidate: true,
dontRunListeners: true
});
}
}
if (!this.form.getFieldMeta(this.name)) {
this.form.setFieldMeta(this.name, {
...metaHelper.defaultFieldMeta,
...this.options.defaultMeta
});
}
};
this.mount = () => {
this.update(this.options);
this.form.formGroupApis.add(this);
this.fieldInfo.instance = this;
this.form.baseStore.setState((prev) => ({
...prev,
formGroupStateBase: {
...prev.formGroupStateBase,
[this.name]: prev.formGroupStateBase[this.name] ?? getDefaultFormGroupState({
...this.options.defaultState
})
}
}));
const { onMount } = this.options.validators || {};
if (onMount) {
const rawError = this.runValidator({
validate: onMount,
value: {
value: this.state.value,
groupApi: this,
validationSource: "form"
},
type: "validate"
});
let groupOwnRawError = rawError;
let groupFieldErrors = void 0;
if (isGlobalGroupValidationError(rawError)) {
groupOwnRawError = rawError.group;
groupFieldErrors = rawError.fields;
}
const error = normalizeError(groupOwnRawError);
if (error) {
this.setMeta(
(prev) => ({
...prev,
errorMap: {
...prev.errorMap,
onMount: error
},
errorSourceMap: {
...prev.errorSourceMap,
onMount: "field"
}
})
);
}
this.distributeFieldErrors("onMount", groupFieldErrors);
}
this.options.listeners?.onMount?.({
value: this.state.value,
groupApi: this
});
return () => {
for (const [key, timeout] of Object.entries(
this.timeoutIds.validations
)) {
if (timeout) {
clearTimeout(timeout);
this.timeoutIds.validations[key] = null;
}
}
for (const [key, timeout] of Object.entries(this.timeoutIds.listeners)) {
if (timeout) {
clearTimeout(timeout);
this.timeoutIds.listeners[key] = null;
}
}
for (const [key, timeout] of Object.entries(
this.timeoutIds.formListeners
)) {
if (timeout) {
clearTimeout(timeout);
this.timeoutIds.formListeners[key] = null;
}
}
if (this.fieldInfo.instance !== this) return;
for (const [key, validationMeta] of Object.entries(
this.fieldInfo.validationMetaMap
)) {
validationMeta?.lastAbortController.abort();
this.fieldInfo.validationMetaMap[key] = void 0;
}
this.form.formGroupApis.delete(this);
this.form.baseStore.setState((prev) => ({
...prev,
formGroupStateBase: {
...prev.formGroupStateBase,
[this.name]: getDefaultFormGroupState({})
}
}));
this.fieldInfo.instance = null;
this.options.listeners?.onUnmount?.({
value: this.state.value,
groupApi: this
});
};
};
this.setValue = (updater, options) => {
this.form.setFieldValue(
this.name,
updater,
utils.mergeOpts(options, { dontRunListeners: true, dontValidate: true })
);
if (!options?.dontRunListeners) {
this.triggerOnChangeListener();
}
if (!options?.dontValidate) {
this.validate("change");
}
};
this.getMeta = () => this.store.state.meta;
this.setMeta = (updater) => this.form.setFieldMeta(this.name, updater);
this.getInfo = () => this.fieldInfo;
this.getRelatedFields = () => {
const fields = Object.values(this.form.fieldInfo);
const relatedFields = [];
for (const field of fields) {
if (!field.instance) continue;
if (!(field.instance instanceof FieldApi.FieldApi)) continue;
if (field.instance.name.startsWith(this.name)) {
relatedFields.push(field.instance);
}
}
return relatedFields;
};
this.getRelatedFieldMetasDerived = () => {
const fields = Object.entries(this.form.fieldMetaDerived.state);
const relatedFieldMetas = [];
for (const [fieldName, fieldMeta] of fields) {
if (fieldName === this.name) continue;
if (utils.isFieldInGroup(this.name, fieldName)) {
relatedFieldMetas.push({ ...fieldMeta, name: fieldName });
}
}
return relatedFieldMetas;
};
this.buildChildFieldName = (relativeName) => {
if (relativeName === "") return this.name;
if (relativeName.startsWith("[")) return `${this.name}${relativeName}`;
return `${this.name}.${relativeName}`;
};
this.distributeFieldErrors = (errorMapKey, fieldErrors) => {
const previousNames = this._lastDistributedFieldNames[errorMapKey] ?? /* @__PURE__ */ new Set();
const currentNames = /* @__PURE__ */ new Set();
if (fieldErrors) {
for (const [relativeName, err] of Object.entries(fieldErrors)) {
if (err === void 0 || err === null || err === false) continue;
currentNames.add(this.buildChildFieldName(relativeName));
}
}
const allNames = /* @__PURE__ */ new Set([...previousNames, ...currentNames]);
let hasErrored = false;
for (const fullName of allNames) {
const relativeName = fullName.startsWith(this.name + "[") ? fullName.slice(this.name.length) : fullName.slice(this.name.length + 1);
const newFormValidatorError = fieldErrors?.[relativeName];
const fieldMeta = this.form.getFieldMeta(fullName);
if (!fieldMeta && !newFormValidatorError) continue;
const previousErrorValue = fieldMeta?.errorMap[errorMapKey];
const isPreviousErrorFromFormValidator = fieldMeta?.errorSourceMap[errorMapKey] === "form";
const { newErrorValue, newSource } = utils.determineFormLevelErrorSourceAndValue({
newFormValidatorError,
isPreviousErrorFromFormValidator,
previousErrorValue
});
if (newErrorValue) hasErrored = true;
if (previousErrorValue === newErrorValue && fieldMeta?.errorSourceMap[errorMapKey] === newSource) {
continue;
}
this.form.setFieldMeta(fullName, (prev) => ({
...prev,
errorMap: {
...prev.errorMap,
[errorMapKey]: newErrorValue
},
errorSourceMap: {
...prev.errorSourceMap,
[errorMapKey]: newSource
}
}));
}
this._lastDistributedFieldNames[errorMapKey] = currentNames;
return hasErrored;
};
this.validateSync = (cause, errorFromForm, opts2 = {}) => {
const validates = utils.getSyncValidatorArray(cause, {
...this.options,
form: this.form,
group: this,
validationLogic: this.options.validationLogic || this.form.options.validationLogic || ValidationLogic.defaultValidationLogic
});
const relatedFields = opts2.skipRelatedFieldValidation ? [] : this.getRelatedFields();
const relatedFieldValidates = relatedFields.reduce(
(acc, field) => {
const fieldValidates = utils.getSyncValidatorArray(cause, {
...field.options,
form: field.form,
validationLogic: field.form.options.validationLogic || ValidationLogic.defaultValidationLogic
});
fieldValidates.forEach((validate) => {
validate.field = field;
});
return acc.concat(fieldValidates);
},
[]
);
let hasErrored = false;
store.batch(() => {
const validateFieldOrGroupFn = (fieldOrGroup, validateObj) => {
const errorMapKey = getErrorMapKey(validateObj.cause);
const isGroup = fieldOrGroup === this;
let rawError = void 0;
if (validateObj.validate) {
rawError = fieldOrGroup.runValidator({
validate: validateObj.validate,
value: {
value: fieldOrGroup.store.state.value,
// For the group's own validators we want standard schemas to
// produce a `{ form, fields }` shape (with relative keys) so
// we can fan errors out to children. Field-level validators on
// related fields keep the regular field source.
validationSource: isGroup ? "form" : "field",
...fieldOrGroup instanceof FormGroupApi ? {
groupApi: fieldOrGroup
} : { fieldApi: fieldOrGroup }
},
type: "validate"
});
}
let groupOwnRawError = rawError;
let groupFieldErrors = void 0;
if (isGroup && isGlobalGroupValidationError(rawError)) {
groupOwnRawError = rawError.group;
groupFieldErrors = rawError.fields;
}
const fieldLevelError = normalizeError(
groupOwnRawError
);
const formLevelError = errorFromForm[errorMapKey];
const { newErrorValue, newSource } = utils.determineFieldLevelErrorSourceAndValue({
formLevelError,
fieldLevelError
});
if (fieldOrGroup.state.meta.errorMap?.[errorMapKey] !== newErrorValue) {
fieldOrGroup.setMeta((prev) => ({
...prev,
errorMap: {
...prev.errorMap,
[errorMapKey]: newErrorValue
},
errorSourceMap: {
...prev.errorSourceMap,
[errorMapKey]: newSource
}
}));
}
if (newErrorValue) {
hasErrored = true;
}
if (isGroup) {
const distributedHasErrored = this.distributeFieldErrors(
errorMapKey,
groupFieldErrors
);
if (distributedHasErrored) {
hasErrored = true;
}
}
};
for (const validateObj of validates) {
validateFieldOrGroupFn(this, validateObj);
}
for (const fieldValidateObj of relatedFieldValidates) {
if (!fieldValidateObj.validate) continue;
validateFieldOrGroupFn(fieldValidateObj.field, fieldValidateObj);
}
});
const submitErrKey = getErrorMapKey("submit");
if (
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
this.state.meta.errorMap?.[submitErrKey] && cause !== "submit" && !hasErrored
) {
this.setMeta((prev) => ({
...prev,
errorMap: {
...prev.errorMap,
[submitErrKey]: void 0
},
errorSourceMap: {
...prev.errorSourceMap,
[submitErrKey]: void 0
}
}));
}
return { hasErrored };
};
this.validateAsync = async (cause, formValidationResultPromise, opts2 = {}) => {
const validates = utils.getAsyncValidatorArray(cause, {
...this.options,
form: this.form,
group: this,
validationLogic: this.options.validationLogic || this.form.options.validationLogic || ValidationLogic.defaultValidationLogic
});
const asyncFormValidationResults = await formValidationResultPromise;
const relatedFields = opts2.skipRelatedFieldValidation ? [] : this.getRelatedFields();
const relatedFieldValidates = relatedFields.reduce(
(acc, field) => {
const fieldValidates = utils.getAsyncValidatorArray(cause, {
...field.options,
form: field.form,
validationLogic: field.form.options.validationLogic || ValidationLogic.defaultValidationLogic
});
fieldValidates.forEach((validate) => {
validate.field = field;
});
return acc.concat(fieldValidates);
},
[]
);
const validatesPromises = [];
const linkedPromises = [];
const hasAsyncValidators = validates.some((v) => v.validate) || relatedFieldValidates.some((v) => v.validate);
if (hasAsyncValidators) {
if (!this.state.meta.isValidating) {
this.setMeta((prev) => ({ ...prev, isValidating: true }));
}
for (const linkedField of relatedFields) {
linkedField.setMeta((prev) => ({ ...prev, isValidating: true }));
}
}
const validateFieldOrGroupAsyncFn = (fieldOrGroup, validateObj, promises) => {
const errorMapKey = getErrorMapKey(validateObj.cause);
const fieldInfo = fieldOrGroup.getInfo();
const fieldValidatorMeta = fieldInfo.validationMetaMap[errorMapKey];
fieldValidatorMeta?.lastAbortController.abort();
const controller = new AbortController();
fieldInfo.validationMetaMap[errorMapKey] = {
lastAbortController: controller
};
const isGroup = fieldOrGroup === this;
promises.push(
new Promise(async (resolve) => {
let rawError;
try {
rawError = await new Promise((rawResolve, rawReject) => {
if (fieldOrGroup.timeoutIds.validations[validateObj.cause]) {
clearTimeout(
fieldOrGroup.timeoutIds.validations[validateObj.cause]
);
}
fieldOrGroup.timeoutIds.validations[validateObj.cause] = setTimeout(async () => {
if (controller.signal.aborted) return rawResolve(void 0);
try {
rawResolve(
await this.runValidator({
validate: validateObj.validate,
value: {
value: fieldOrGroup.store.state.value,
signal: controller.signal,
// See sync counterpart: produce `{ form, fields }`
// from standard schemas attached to the group so we
// can fan errors out to children.
validationSource: isGroup ? "form" : "field",
...fieldOrGroup instanceof FormGroupApi ? {
groupApi: fieldOrGroup
} : { fieldApi: fieldOrGroup }
},
type: "validateAsync"
})
);
} catch (e) {
rawReject(e);
}
}, validateObj.debounceMs);
});
} catch (e) {
rawError = e;
}
if (controller.signal.aborted) return resolve(void 0);
let groupOwnRawError = rawError;
let groupFieldErrors = void 0;
if (isGroup && isGlobalGroupValidationError(rawError)) {
groupOwnRawError = rawError.group;
groupFieldErrors = rawError.fields;
}
const fieldLevelError = normalizeError(groupOwnRawError);
const formLevelError = asyncFormValidationResults[fieldOrGroup.name]?.[errorMapKey];
const { newErrorValue, newSource } = utils.determineFieldLevelErrorSourceAndValue({
formLevelError,
fieldLevelError
});
if (fieldOrGroup.getInfo().instance !== fieldOrGroup) {
return resolve(void 0);
}
fieldOrGroup.setMeta((prev) => {
return {
...prev,
errorMap: {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
...prev?.errorMap,
[errorMapKey]: newErrorValue
},
errorSourceMap: {
...prev.errorSourceMap,
[errorMapKey]: newSource
}
};
});
if (isGroup) {
this.distributeFieldErrors(errorMapKey, groupFieldErrors);
}
resolve(newErrorValue);
})
);
};
for (const validateObj of validates) {
if (!validateObj.validate) continue;
validateFieldOrGroupAsyncFn(this, validateObj, validatesPromises);
}
for (const fieldValitateObj of relatedFieldValidates) {
if (!fieldValitateObj.validate) continue;
validateFieldOrGroupAsyncFn(
fieldValitateObj.field,
fieldValitateObj,
linkedPromises
);
}
let results = [];
if (validatesPromises.length || linkedPromises.length) {
results = await Promise.all(validatesPromises);
await Promise.all(linkedPromises);
}
if (hasAsyncValidators) {
this.setMeta((prev) => ({ ...prev, isValidating: false }));
for (const linkedField of relatedFields) {
linkedField.setMeta((prev) => ({ ...prev, isValidating: false }));
}
}
return results.filter(Boolean);
};
this.validateAllFields = async (cause) => {
const fieldValidationPromises = [];
store.batch(() => {
void Object.values(this.getRelatedFields()).forEach((fieldInstance) => {
fieldValidationPromises.push(
// Remember, `validate` is either a sync operation or a promise
Promise.resolve().then(
() => fieldInstance.validate(cause, {
skipFormValidation: true,
skipGroupValidation: true
})
)
);
if (!fieldInstance.store.state.meta.isTouched) {
fieldInstance.setMeta((prev) => ({ ...prev, isTouched: true }));
}
});
});
const fieldErrorMapMap = await Promise.all(fieldValidationPromises);
return fieldErrorMapMap.flat();
};
this.validateArrayFieldsStartingFrom = (field, index, cause) => {
return this.form.validateArrayFieldsStartingFrom(field, index, cause);
};
this.validateField = (field, cause) => {
return this.form.validateField(field, cause);
};
this.getFieldValue = (field) => {
return this.form.getFieldValue(field);
};
this.getFieldMeta = (field) => {
return this.form.getFieldMeta(field);
};
this.setFieldMeta = (field, updater) => {
return this.form.setFieldMeta(field, updater);
};
this.setFieldValue = (field, value) => {
return this.form.setFieldValue(field, value);
};
this.deleteField = (field) => {
return this.form.deleteField(field);
};
this.pushFieldValue = (field, value) => {
return this.form.pushFieldValue(field, value);
};
this.insertFieldValue = (field, index, value) => {
return this.form.insertFieldValue(field, index, value);
};
this.replaceFieldValue = (field, index, value) => {
return this.form.replaceFieldValue(field, index, value);
};
this.swapFieldValues = (field, index1, index2) => {
return this.form.swapFieldValues(field, index1, index2);
};
this.moveFieldValues = (field, fromIndex, toIndex) => {
return this.form.moveFieldValues(field, fromIndex, toIndex);
};
this.clearFieldValues = (field) => {
return this.form.clearFieldValues(field);
};
this.resetField = (field) => {
return this.form.resetField(field);
};
this.removeFieldValue = (field, index) => {
return this.form.removeFieldValue(field, index);
};
this.areRelatedFieldsValid = () => {
return Object.values(this.getRelatedFields()).every(
(field) => field.state.meta.isValid
);
};
this.validate = (cause, opts2) => {
const { fieldsErrorMap } = opts2?.skipFormValidation ? { fieldsErrorMap: {} } : this.form.validateSync(cause, {
dontUpdateFormErrorMap: true,
filterFieldNames: (fieldName) => utils.isFieldInGroup(this.name, fieldName)
});
const { hasErrored } = this.validateSync(
cause,
fieldsErrorMap[this.name] ?? {},
{ skipRelatedFieldValidation: opts2?.skipRelatedFieldValidation }
);
if (hasErrored && !this.options.asyncAlways) {
this.getInfo().validationMetaMap[getErrorMapKey(cause)]?.lastAbortController.abort();
return this.state.meta.errors;
}
const formValidationResultPromise = opts2?.skipFormValidation ? Promise.resolve({}) : this.form.validateAsync(cause, {
dontUpdateFormErrorMap: true,
filterFieldNames: (fieldName) => utils.isFieldInGroup(this.name, fieldName)
});
return this.validateAsync(cause, formValidationResultPromise, {
skipRelatedFieldValidation: opts2?.skipRelatedFieldValidation
});
};
this.triggerOnChangeListener = () => {
const formDebounceMs = this.form.options.listeners?.onChangeGroupDebounceMs;
if (formDebounceMs && formDebounceMs > 0) {
if (this.timeoutIds.formListeners.change) {
clearTimeout(this.timeoutIds.formListeners.change);
}
this.timeoutIds.formListeners.change = setTimeout(() => {
this.form.options.listeners?.onChangeGroup?.({
formApi: this.form,
groupApi: this
});
}, formDebounceMs);
} else {
this.form.options.listeners?.onChangeGroup?.({
formApi: this.form,
groupApi: this
});
}
const fieldDebounceMs = this.options.listeners?.onChangeDebounceMs;
if (fieldDebounceMs && fieldDebounceMs > 0) {
if (this.timeoutIds.listeners.change) {
clearTimeout(this.timeoutIds.listeners.change);
}
this.timeoutIds.listeners.change = setTimeout(() => {
this.options.listeners?.onChange?.({
value: this.state.value,
groupApi: this
});
}, fieldDebounceMs);
} else {
this.options.listeners?.onChange?.({
value: this.state.value,
groupApi: this
});
}
};
this.triggerOnSubmitListener = () => {
this.options.listeners?.onSubmit?.({
value: this.state.value,
groupApi: this
});
};
this._handleSubmit = async (submitMeta) => {
this.setFormGroupState((old) => ({
...old,
// Submission attempts mark the form as not submitted
isSubmitted: false,
// Count submission attempts
submissionAttempts: old.submissionAttempts + 1,
isSubmitSuccessful: false
// Reset isSubmitSuccessful at the start of submission
}));
store.batch(() => {
void Object.values(this.getRelatedFields()).forEach((field) => {
if (!field.state.meta.isTouched) {
field.setMeta((prev) => ({ ...prev, isTouched: true }));
}
});
});
const submitMetaArg = submitMeta ?? this.options.onSubmitMeta;
this.setFormGroupState((d) => ({ ...d, isSubmitting: true }));
const done = () => {
this.setFormGroupState((prev) => ({ ...prev, isSubmitting: false }));
};
await this.validateAllFields("submit");
if (!this.areRelatedFieldsValid()) {
done();
this.options.onGroupSubmitInvalid?.({
value: this.state.value,
groupApi: this,
meta: submitMetaArg
});
return;
}
await this.validate("submit", {
// This has already happened in the previous step
skipRelatedFieldValidation: true
});
if (!this.areRelatedFieldsValid() || !this.state.meta.isValid) {
done();
this.options.onGroupSubmitInvalid?.({
value: this.state.value,
groupApi: this,
meta: submitMetaArg
});
return;
}
store.batch(() => {
void Object.values(this.getRelatedFields()).forEach((field) => {
field.options.listeners?.onGroupSubmit?.({
value: field.state.value,
fieldApi: field
});
});
});
this.options.listeners?.onSubmit?.({
groupApi: this,
value: this.state.value
});
try {
await this.options.onGroupSubmit?.({
value: this.state.value,
groupApi: this,
meta: submitMetaArg
});
store.batch(() => {
this.setFormGroupState((prev) => ({
...prev,
isSubmitted: true,
isSubmitSuccessful: true
// Set isSubmitSuccessful to true on successful submission
}));
done();
});
} catch (err) {
this.setFormGroupState((prev) => ({
...prev,
isSubmitSuccessful: false
// Ensure isSubmitSuccessful is false if an error occurs
}));
done();
throw err;
}
};
this.form = opts.form;
this.name = opts.name;
this.options = opts;
this.timeoutIds = {
validations: {},
listeners: {},
formListeners: {}
};
this.fieldInfo = {
instance: null,
validationMetaMap: {
onChange: void 0,
onBlur: void 0,
onSubmit: void 0,
onMount: void 0,
onServer: void 0,
onDynamic: void 0
}
};
this.store = store.createStore(
(prevVal) => {
this.form.formGroupMetaDerived.get();
this.form.baseStore.get();
const meta = this.form.getFormGroupMeta(this.name) ?? getDefaultFormGroupMeta(opts.defaultMeta);
let value = this.form.getFieldValue(this.name);
if (!meta.isTouched && value === void 0 && this.options.defaultValue !== void 0 && !utils.evaluate(value, this.options.defaultValue)) {
value = this.options.defaultValue;
}
if (prevVal && prevVal.value === value && prevVal.meta === meta) {
return prevVal;
}
return {
value,
meta
};
}
);
this.handleSubmit = this.handleSubmit.bind(this);
}
/**
* The current field state.
*/
get state() {
return this.store.state;
}
/**
* @private
*/
runValidator(props) {
if (standardSchemaValidator.isStandardSchemaValidator(props.validate)) {
const result = standardSchemaValidator.standardSchemaValidators[props.type](
props.value,
props.validate
);
if (props.type === "validate") {
return remapStandardSchemaResultForGroup(result);
}
return result.then(
remapStandardSchemaResultForGroup
);
}
return props.validate(
props.value
);
}
handleSubmit(submitMeta) {
return this._handleSubmit(submitMeta);
}
}
function normalizeError(rawError) {
if (rawError) {
return rawError;
}
return void 0;
}
function isGlobalGroupValidationError(error) {
return !!error && typeof error === "object" && "fields" in error;
}
function remapStandardSchemaResultForGroup(result) {
if (!result || typeof result !== "object") return result;
if (!("form" in result) && !("fields" in result)) return result;
const { form, fields, ...rest } = result;
return { ...rest, group: form, fields };
}
function getErrorMapKey(cause) {
switch (cause) {
case "submit":
return "onSubmit";
case "blur":
return "onBlur";
case "mount":
return "onMount";
case "server":
return "onServer";
case "dynamic":
return "onDynamic";
case "change":
default:
return "onChange";
}
}
exports.FormGroupApi = FormGroupApi;
exports.getDefaultFormGroupMeta = getDefaultFormGroupMeta;
//# sourceMappingURL=FormGroupApi.cjs.map

Sorry, the diff of this file is too big to display

import { ValidationLogicFn } from './ValidationLogic.cjs';
import { AnyFieldLikeMeta, AnyFieldLikeMetaBase, FieldErrorMapFromValidator, FieldInfo, FieldLikeAPI, FieldLikeMeta, FieldLikeMetaBase, FieldLikeOptions, FormLikeAPI, ListenerCause, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap } from './types.cjs';
import { FormApi, FormAsyncValidateOrFn, FormValidateOrFn } from './FormApi.cjs';
import { AnyFieldApi } from './FieldApi.cjs';
import { StandardSchemaV1, TStandardSchemaValidatorValue } from './standardSchemaValidator.cjs';
import { Updater } from './utils.cjs';
import { ReadonlyStore } from '@tanstack/store';
import { DeepKeys, DeepKeysOfType, DeepValue } from './util-types.cjs';
/**
* @private
*/
export type FormGroupValidateFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = (props: {
value: TData;
groupApi: FormGroupApi<TParentData, TName, TData, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
}) => unknown;
/**
* @private
*/
export type FormGroupValidateOrFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FormGroupValidateFn<TParentData, TName, TData> | StandardSchemaV1<TData, unknown>;
/**
* @private
*/
export type FormGroupValidateAsyncFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = (options: {
value: TData;
groupApi: FormGroupApi<TParentData, TName, TData, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
signal: AbortSignal;
}) => unknown | Promise<unknown>;
/**
* @private
*/
export type FormGroupAsyncValidateOrFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FormGroupValidateAsyncFn<TParentData, TName, TData> | StandardSchemaV1<TData, unknown>;
/**
* @private
*/
export type FormGroupListenerFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = (props: {
value: TData;
groupApi: FormGroupApi<TParentData, TName, TData, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
}) => void;
export interface FormGroupValidators<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>> {
/**
* An optional function, that runs on the mount event of input.
*/
onMount?: TOnMount;
/**
* An optional function, that runs on the change event of input.
*
* @example z.string().min(1)
*/
onChange?: TOnChange;
/**
* An optional property similar to `onChange` but async validation
*
* @example z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })
*/
onChangeAsync?: TOnChangeAsync;
/**
* An optional number to represent how long the `onChangeAsync` should wait before running
*
* If set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds
*/
onChangeAsyncDebounceMs?: number;
/**
* An optional list of field names that should trigger this field's `onChange` and `onChangeAsync` events when its value changes
*/
/**
* An optional function, that runs on the blur event of input.
*
* @example z.string().min(1)
*/
onBlur?: TOnBlur;
/**
* An optional property similar to `onBlur` but async validation.
*
* @example z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })
*/
onBlurAsync?: TOnBlurAsync;
/**
* An optional number to represent how long the `onBlurAsync` should wait before running
*
* If set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds
*/
onBlurAsyncDebounceMs?: number;
/**
* An optional list of field names that should trigger this field's `onBlur` and `onBlurAsync` events when its value changes
*/
/**
* An optional function, that runs on the submit event of form.
*
* @example z.string().min(1)
*/
onSubmit?: TOnSubmit;
/**
* An optional property similar to `onSubmit` but async validation.
*
* @example z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })
*/
onSubmitAsync?: TOnSubmitAsync;
onDynamic?: TOnDynamic;
onDynamicAsync?: TOnDynamicAsync;
onDynamicAsyncDebounceMs?: number;
}
export interface FormGroupListeners<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> {
onChange?: FormGroupListenerFn<TParentData, TName, TData>;
onChangeDebounceMs?: number;
onBlur?: FormGroupListenerFn<TParentData, TName, TData>;
onBlurDebounceMs?: number;
onMount?: FormGroupListenerFn<TParentData, TName, TData>;
onUnmount?: FormGroupListenerFn<TParentData, TName, TData>;
onSubmit?: FormGroupListenerFn<TParentData, TName, TData>;
onGroupSubmit?: FormGroupListenerFn<TParentData, TName, TData>;
}
interface FormGroupExtraOptions<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TSubmitMeta, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> {
/**
* A list of validators to pass to the field
*/
validators?: FormGroupValidators<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>;
/**
* If true, allows the form to be submitted in an invalid state i.e. canSubmit will remain true regardless of validation errors. Defaults to undefined.
*/
canSubmitWhenInvalid?: boolean;
/**
* A list of listeners which attach to the corresponding events
*/
listeners?: FormGroupListeners<TParentData, TName, TData>;
defaultState?: FormGroupState;
/**
* Optional validation logic strategy to use for this group's own
* validators (e.g. `revalidateLogic()`). When omitted, the parent form's
* `validationLogic` (or the default) is used.
*/
validationLogic?: ValidationLogicFn;
/**
* onSubmitMeta, the data passed from the handleSubmit handler, to the onSubmit function props
*/
onSubmitMeta?: TSubmitMeta;
/**
* A function to be called when the form is submitted, what should happen once the user submits a valid form returns `any` or a promise `Promise<any>`
*/
onGroupSubmit?: (props: {
value: TData;
groupApi: FormGroupApi<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>;
meta: TSubmitMeta;
}) => any | Promise<any>;
/**
* Specify an action for scenarios where the user tries to submit an invalid form.
*/
onGroupSubmitInvalid?: (props: {
value: TData;
groupApi: FormGroupApi<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>;
meta: TSubmitMeta;
}) => void;
}
export interface FormGroupOptions<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TSubmitMeta, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> extends FieldLikeOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>, FormGroupExtraOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta> {
}
export interface FormGroupApiOptions<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TSubmitMeta, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> extends FormGroupOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta> {
form: FormApi<TParentData, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>;
}
export interface FormGroupState {
/**
* A boolean indicating if the form is currently in the process of being submitted after `handleSubmit` is called.
*
* Goes back to `false` when submission completes for one of the following reasons:
* - the validation step returned errors.
* - the `onSubmit` function has completed.
*
* Note: if you're running async operations in your `onSubmit` function make sure to await them to ensure `isSubmitting` is set to `false` only when the async operation completes.
*
* This is useful for displaying loading indicators or disabling form inputs during submission.
*
*/
isSubmitting: boolean;
/**
* A boolean indicating if the `onSubmit` function has completed successfully.
*
* Goes back to `false` at each new submission attempt.
*
* Note: you can use isSubmitting to check if the form is currently submitting.
*/
isSubmitted: boolean;
/**
* A boolean indicating if the form or any of its fields are currently validating.
*/
isValidating: boolean;
/**
* A counter for tracking the number of submission attempts.
*/
submissionAttempts: number;
/**
* A boolean indicating if the last submission was successful.
*/
isSubmitSuccessful: boolean;
}
/**
* @public
*
* A type representing the FormGroup API with all generics set to `any` for convenience.
*/
export type AnyFormGroupApi = FormGroupApi<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
/**
* @public
*
* The `meta` shape exposed on `FormGroupApi.state.meta`. Mirrors
* `FieldApi.state.meta` (since `FormGroupMeta extends FieldLikeMeta`) but
* additionally surfaces the group's submission lifecycle and aggregated
* validity flags. All derivation lives on the parent `FormApi` (in
* `formGroupMetaDerived`), keeping per-instance `FormGroupApi.store` as
* minimal as `FieldApi.store`.
*
* Aggregated booleans (`isTouched`, `isBlurred`, `isDirty`, `isPristine`,
* `isDefaultValue`) are computed across the group's descendant fields
* rather than the group's own field-meta entry.
*/
export interface FormGroupMeta<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> extends FieldLikeMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>, FormGroupState {
isFieldsValidating: boolean;
isFieldsValid: boolean;
isGroupValid: boolean;
isValid: boolean;
canSubmit: boolean;
}
/**
* @public
*
* `FormGroupMeta` with all generics widened to `any`.
*/
export type AnyFormGroupMeta = FormGroupMeta<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
export interface FormGroupStoreState<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> {
/**
* The current value of the form group.
*/
value: TData;
/**
* The current metadata of the form group, including aggregated validity,
* group-level errors, and submission lifecycle.
*/
meta: FormGroupMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
}
/**
* @private
*
* Builds a default `FormGroupMeta` value, used as a fallback when the
* parent form's `formGroupMetaDerived` store has no entry for this group
* yet (e.g. between `new FormGroupApi(...)` and `mount()`).
*/
export declare function getDefaultFormGroupMeta(defaultMeta?: Partial<AnyFieldLikeMetaBase>): AnyFormGroupMeta;
export declare class FormGroupApi<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TSubmitMeta, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> implements FormLikeAPI<TParentData, TSubmitMeta>, FieldLikeAPI<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta, FormGroupExtraOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>> {
/**
* A reference to the form API instance.
*/
form: FormGroupApiOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>['form'];
/**
* The field name.
*/
name: TName;
/**
* The field options.
*/
options: FormGroupApiOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>;
/**
* The field state store.
*/
store: ReadonlyStore<FormGroupStoreState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>;
/**
* The current field state.
*/
get state(): FormGroupStoreState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
/**
* @private
*
* Updates this group's submission lifecycle state on the parent form's
* `baseStore` (where group state is now persisted), preserving entries
* for any other mounted groups. After writing, the form's
* `formGroupMetaDerived` re-derives so this group's `state.meta` picks
* up the new lifecycle values automatically.
*/
private setFormGroupState;
timeoutIds: {
validations: Record<ValidationCause, ReturnType<typeof setTimeout> | null>;
listeners: Record<ListenerCause, ReturnType<typeof setTimeout> | null>;
formListeners: Record<ListenerCause, ReturnType<typeof setTimeout> | null>;
};
/**
* @private
*
* Tracks the set of fully-qualified child field names that this group's
* validators last set form-source errors on, keyed by `errorMap` key.
* Used to clear stale group-level field errors on subsequent runs without
* trampling errors set by the parent form's validators.
*/
private _lastDistributedFieldNames;
private fieldInfo;
constructor(opts: FormGroupApiOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>);
/**
* Updates the field instance with new options.
*/
update: (opts: FormGroupApiOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>) => void;
/**
* @private
*/
runValidator<TValue extends TStandardSchemaValidatorValue<TData> & {
groupApi: AnyFormGroupApi;
}, TType extends 'validate' | 'validateAsync'>(props: {
validate: TType extends 'validate' ? FormGroupValidateOrFn<any, any, any> : FormGroupAsyncValidateOrFn<any, any, any>;
value: TValue;
type: TType;
}): unknown;
mount: () => () => void;
/**
* Sets the field value and run the `change` validator.
*/
setValue: (updater: Updater<TData>, options?: UpdateMetaOptions) => void;
getMeta: () => FormGroupMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
/**
* Sets the field metadata.
*/
setMeta: (updater: Updater<FieldLikeMetaBase<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>) => void;
/**
* Gets the field information object.
*/
getInfo: () => FieldInfo<TParentData>;
/**
* @private
*/
getRelatedFields: () => AnyFieldApi[];
/**
* @private
*/
getRelatedFieldMetasDerived: () => (FieldLikeMetaBase<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any> & import('./types.cjs').FieldLikeMetaDerived<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any> & {
name: string;
})[];
/**
* @private
*
* Builds a fully-qualified field name from a path that is relative to this
* group, supporting both dot (`name`, `nested.value`) and bracket
* (`[0].name`) notation.
*/
private buildChildFieldName;
/**
* @private
*
* Distributes a `{ fields: { ... } }` payload returned by one of this
* group's own validators onto the corresponding child fields. Tracks
* which fields have been touched so subsequent runs can clear stale
* errors without trampling errors set by the parent form's validators.
*/
private distributeFieldErrors;
/**
* @private
*/
validateSync: (cause: ValidationCause, errorFromForm: ValidationErrorMap, opts?: {
skipRelatedFieldValidation?: boolean;
}) => {
hasErrored: boolean;
};
/**
* @private
*/
validateAsync: (cause: ValidationCause, formValidationResultPromise: Promise<FieldErrorMapFromValidator<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>>, opts?: {
skipRelatedFieldValidation?: boolean;
}) => Promise<unknown[]>;
/**
* Validates all fields according to the FIELD level validators.
* This will ignore FORM level validators, use form.validate({ValidationCause}) for a complete validation
*/
validateAllFields: (cause: ValidationCause) => Promise<unknown[]>;
validateArrayFieldsStartingFrom: <TField extends DeepKeysOfType<TParentData, any[]>>(field: TField, index: number, cause: ValidationCause) => Promise<unknown[]>;
validateField: <TField extends DeepKeysOfType<TParentData, any>>(field: TField, cause: ValidationCause) => any[] | Promise<any[]>;
getFieldValue: <TField extends DeepKeysOfType<TParentData, any>>(field: TField) => DeepValue<TParentData, TField>;
getFieldMeta: <TField extends DeepKeysOfType<TParentData, any>>(field: TField) => AnyFieldLikeMeta | undefined;
setFieldMeta: <TField extends DeepKeysOfType<TParentData, any>>(field: TField, updater: Updater<AnyFieldLikeMetaBase>) => void;
setFieldValue: <TField extends DeepKeysOfType<TParentData, any>>(field: TField, value: any) => void;
deleteField: <TField extends DeepKeysOfType<TParentData, any>>(field: TField) => void;
pushFieldValue: <TField extends DeepKeysOfType<TParentData, any[]>>(field: TField, value: any) => void;
insertFieldValue: <TField extends DeepKeysOfType<TParentData, any[]>>(field: TField, index: number, value: any) => Promise<void>;
replaceFieldValue: <TField extends DeepKeysOfType<TParentData, any[]>>(field: TField, index: number, value: any) => Promise<void>;
swapFieldValues: <TField extends DeepKeysOfType<TParentData, any[]>>(field: TField, index1: number, index2: number) => void;
moveFieldValues: <TField extends DeepKeysOfType<TParentData, any[]>>(field: TField, fromIndex: number, toIndex: number) => void;
clearFieldValues: <TField extends DeepKeysOfType<TParentData, any[]>>(field: TField) => void;
resetField: <TField extends DeepKeysOfType<TParentData, any>>(field: TField) => void;
removeFieldValue: <TField extends DeepKeysOfType<TParentData, any[]>>(field: TField, index: number) => Promise<void>;
areRelatedFieldsValid: () => boolean;
/**
* Validates the form group and all related children.
*/
validate: (cause: ValidationCause, opts?: {
skipFormValidation?: boolean;
skipRelatedFieldValidation?: boolean;
}) => ValidationError[] | Promise<ValidationError[]>;
/**
* @private
*/
triggerOnChangeListener: () => void;
/**
* @private
*/
triggerOnSubmitListener: () => void;
handleSubmit(): Promise<void>;
handleSubmit(submitMeta: TSubmitMeta): Promise<void>;
/**
* Handles the form submission, performs validation, and calls the appropriate onSubmit or onSubmitInvalid callbacks.
*/
_handleSubmit: (submitMeta?: TSubmitMeta) => Promise<void>;
}
export {};
import { ValidationLogicFn } from './ValidationLogic.js';
import { AnyFieldLikeMeta, AnyFieldLikeMetaBase, FieldErrorMapFromValidator, FieldInfo, FieldLikeAPI, FieldLikeMeta, FieldLikeMetaBase, FieldLikeOptions, FormLikeAPI, ListenerCause, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap } from './types.js';
import { FormApi, FormAsyncValidateOrFn, FormValidateOrFn } from './FormApi.js';
import { AnyFieldApi } from './FieldApi.js';
import { StandardSchemaV1, TStandardSchemaValidatorValue } from './standardSchemaValidator.js';
import { Updater } from './utils.js';
import { ReadonlyStore } from '@tanstack/store';
import { DeepKeys, DeepKeysOfType, DeepValue } from './util-types.js';
/**
* @private
*/
export type FormGroupValidateFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = (props: {
value: TData;
groupApi: FormGroupApi<TParentData, TName, TData, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
}) => unknown;
/**
* @private
*/
export type FormGroupValidateOrFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FormGroupValidateFn<TParentData, TName, TData> | StandardSchemaV1<TData, unknown>;
/**
* @private
*/
export type FormGroupValidateAsyncFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = (options: {
value: TData;
groupApi: FormGroupApi<TParentData, TName, TData, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
signal: AbortSignal;
}) => unknown | Promise<unknown>;
/**
* @private
*/
export type FormGroupAsyncValidateOrFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FormGroupValidateAsyncFn<TParentData, TName, TData> | StandardSchemaV1<TData, unknown>;
/**
* @private
*/
export type FormGroupListenerFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = (props: {
value: TData;
groupApi: FormGroupApi<TParentData, TName, TData, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
}) => void;
export interface FormGroupValidators<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>> {
/**
* An optional function, that runs on the mount event of input.
*/
onMount?: TOnMount;
/**
* An optional function, that runs on the change event of input.
*
* @example z.string().min(1)
*/
onChange?: TOnChange;
/**
* An optional property similar to `onChange` but async validation
*
* @example z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })
*/
onChangeAsync?: TOnChangeAsync;
/**
* An optional number to represent how long the `onChangeAsync` should wait before running
*
* If set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds
*/
onChangeAsyncDebounceMs?: number;
/**
* An optional list of field names that should trigger this field's `onChange` and `onChangeAsync` events when its value changes
*/
/**
* An optional function, that runs on the blur event of input.
*
* @example z.string().min(1)
*/
onBlur?: TOnBlur;
/**
* An optional property similar to `onBlur` but async validation.
*
* @example z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })
*/
onBlurAsync?: TOnBlurAsync;
/**
* An optional number to represent how long the `onBlurAsync` should wait before running
*
* If set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds
*/
onBlurAsyncDebounceMs?: number;
/**
* An optional list of field names that should trigger this field's `onBlur` and `onBlurAsync` events when its value changes
*/
/**
* An optional function, that runs on the submit event of form.
*
* @example z.string().min(1)
*/
onSubmit?: TOnSubmit;
/**
* An optional property similar to `onSubmit` but async validation.
*
* @example z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })
*/
onSubmitAsync?: TOnSubmitAsync;
onDynamic?: TOnDynamic;
onDynamicAsync?: TOnDynamicAsync;
onDynamicAsyncDebounceMs?: number;
}
export interface FormGroupListeners<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> {
onChange?: FormGroupListenerFn<TParentData, TName, TData>;
onChangeDebounceMs?: number;
onBlur?: FormGroupListenerFn<TParentData, TName, TData>;
onBlurDebounceMs?: number;
onMount?: FormGroupListenerFn<TParentData, TName, TData>;
onUnmount?: FormGroupListenerFn<TParentData, TName, TData>;
onSubmit?: FormGroupListenerFn<TParentData, TName, TData>;
onGroupSubmit?: FormGroupListenerFn<TParentData, TName, TData>;
}
interface FormGroupExtraOptions<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TSubmitMeta, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> {
/**
* A list of validators to pass to the field
*/
validators?: FormGroupValidators<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>;
/**
* If true, allows the form to be submitted in an invalid state i.e. canSubmit will remain true regardless of validation errors. Defaults to undefined.
*/
canSubmitWhenInvalid?: boolean;
/**
* A list of listeners which attach to the corresponding events
*/
listeners?: FormGroupListeners<TParentData, TName, TData>;
defaultState?: FormGroupState;
/**
* Optional validation logic strategy to use for this group's own
* validators (e.g. `revalidateLogic()`). When omitted, the parent form's
* `validationLogic` (or the default) is used.
*/
validationLogic?: ValidationLogicFn;
/**
* onSubmitMeta, the data passed from the handleSubmit handler, to the onSubmit function props
*/
onSubmitMeta?: TSubmitMeta;
/**
* A function to be called when the form is submitted, what should happen once the user submits a valid form returns `any` or a promise `Promise<any>`
*/
onGroupSubmit?: (props: {
value: TData;
groupApi: FormGroupApi<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>;
meta: TSubmitMeta;
}) => any | Promise<any>;
/**
* Specify an action for scenarios where the user tries to submit an invalid form.
*/
onGroupSubmitInvalid?: (props: {
value: TData;
groupApi: FormGroupApi<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>;
meta: TSubmitMeta;
}) => void;
}
export interface FormGroupOptions<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TSubmitMeta, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> extends FieldLikeOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>, FormGroupExtraOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta> {
}
export interface FormGroupApiOptions<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TSubmitMeta, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> extends FormGroupOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta> {
form: FormApi<TParentData, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>;
}
export interface FormGroupState {
/**
* A boolean indicating if the form is currently in the process of being submitted after `handleSubmit` is called.
*
* Goes back to `false` when submission completes for one of the following reasons:
* - the validation step returned errors.
* - the `onSubmit` function has completed.
*
* Note: if you're running async operations in your `onSubmit` function make sure to await them to ensure `isSubmitting` is set to `false` only when the async operation completes.
*
* This is useful for displaying loading indicators or disabling form inputs during submission.
*
*/
isSubmitting: boolean;
/**
* A boolean indicating if the `onSubmit` function has completed successfully.
*
* Goes back to `false` at each new submission attempt.
*
* Note: you can use isSubmitting to check if the form is currently submitting.
*/
isSubmitted: boolean;
/**
* A boolean indicating if the form or any of its fields are currently validating.
*/
isValidating: boolean;
/**
* A counter for tracking the number of submission attempts.
*/
submissionAttempts: number;
/**
* A boolean indicating if the last submission was successful.
*/
isSubmitSuccessful: boolean;
}
/**
* @public
*
* A type representing the FormGroup API with all generics set to `any` for convenience.
*/
export type AnyFormGroupApi = FormGroupApi<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
/**
* @public
*
* The `meta` shape exposed on `FormGroupApi.state.meta`. Mirrors
* `FieldApi.state.meta` (since `FormGroupMeta extends FieldLikeMeta`) but
* additionally surfaces the group's submission lifecycle and aggregated
* validity flags. All derivation lives on the parent `FormApi` (in
* `formGroupMetaDerived`), keeping per-instance `FormGroupApi.store` as
* minimal as `FieldApi.store`.
*
* Aggregated booleans (`isTouched`, `isBlurred`, `isDirty`, `isPristine`,
* `isDefaultValue`) are computed across the group's descendant fields
* rather than the group's own field-meta entry.
*/
export interface FormGroupMeta<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> extends FieldLikeMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>, FormGroupState {
isFieldsValidating: boolean;
isFieldsValid: boolean;
isGroupValid: boolean;
isValid: boolean;
canSubmit: boolean;
}
/**
* @public
*
* `FormGroupMeta` with all generics widened to `any`.
*/
export type AnyFormGroupMeta = FormGroupMeta<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
export interface FormGroupStoreState<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> {
/**
* The current value of the form group.
*/
value: TData;
/**
* The current metadata of the form group, including aggregated validity,
* group-level errors, and submission lifecycle.
*/
meta: FormGroupMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
}
/**
* @private
*
* Builds a default `FormGroupMeta` value, used as a fallback when the
* parent form's `formGroupMetaDerived` store has no entry for this group
* yet (e.g. between `new FormGroupApi(...)` and `mount()`).
*/
export declare function getDefaultFormGroupMeta(defaultMeta?: Partial<AnyFieldLikeMetaBase>): AnyFormGroupMeta;
export declare class FormGroupApi<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TSubmitMeta, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> implements FormLikeAPI<TParentData, TSubmitMeta>, FieldLikeAPI<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta, FormGroupExtraOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>> {
/**
* A reference to the form API instance.
*/
form: FormGroupApiOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>['form'];
/**
* The field name.
*/
name: TName;
/**
* The field options.
*/
options: FormGroupApiOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>;
/**
* The field state store.
*/
store: ReadonlyStore<FormGroupStoreState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>;
/**
* The current field state.
*/
get state(): FormGroupStoreState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
/**
* @private
*
* Updates this group's submission lifecycle state on the parent form's
* `baseStore` (where group state is now persisted), preserving entries
* for any other mounted groups. After writing, the form's
* `formGroupMetaDerived` re-derives so this group's `state.meta` picks
* up the new lifecycle values automatically.
*/
private setFormGroupState;
timeoutIds: {
validations: Record<ValidationCause, ReturnType<typeof setTimeout> | null>;
listeners: Record<ListenerCause, ReturnType<typeof setTimeout> | null>;
formListeners: Record<ListenerCause, ReturnType<typeof setTimeout> | null>;
};
/**
* @private
*
* Tracks the set of fully-qualified child field names that this group's
* validators last set form-source errors on, keyed by `errorMap` key.
* Used to clear stale group-level field errors on subsequent runs without
* trampling errors set by the parent form's validators.
*/
private _lastDistributedFieldNames;
private fieldInfo;
constructor(opts: FormGroupApiOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>);
/**
* Updates the field instance with new options.
*/
update: (opts: FormGroupApiOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TSubmitMeta, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>) => void;
/**
* @private
*/
runValidator<TValue extends TStandardSchemaValidatorValue<TData> & {
groupApi: AnyFormGroupApi;
}, TType extends 'validate' | 'validateAsync'>(props: {
validate: TType extends 'validate' ? FormGroupValidateOrFn<any, any, any> : FormGroupAsyncValidateOrFn<any, any, any>;
value: TValue;
type: TType;
}): unknown;
mount: () => () => void;
/**
* Sets the field value and run the `change` validator.
*/
setValue: (updater: Updater<TData>, options?: UpdateMetaOptions) => void;
getMeta: () => FormGroupMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
/**
* Sets the field metadata.
*/
setMeta: (updater: Updater<FieldLikeMetaBase<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>) => void;
/**
* Gets the field information object.
*/
getInfo: () => FieldInfo<TParentData>;
/**
* @private
*/
getRelatedFields: () => AnyFieldApi[];
/**
* @private
*/
getRelatedFieldMetasDerived: () => (FieldLikeMetaBase<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any> & import('./types.js').FieldLikeMetaDerived<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any> & {
name: string;
})[];
/**
* @private
*
* Builds a fully-qualified field name from a path that is relative to this
* group, supporting both dot (`name`, `nested.value`) and bracket
* (`[0].name`) notation.
*/
private buildChildFieldName;
/**
* @private
*
* Distributes a `{ fields: { ... } }` payload returned by one of this
* group's own validators onto the corresponding child fields. Tracks
* which fields have been touched so subsequent runs can clear stale
* errors without trampling errors set by the parent form's validators.
*/
private distributeFieldErrors;
/**
* @private
*/
validateSync: (cause: ValidationCause, errorFromForm: ValidationErrorMap, opts?: {
skipRelatedFieldValidation?: boolean;
}) => {
hasErrored: boolean;
};
/**
* @private
*/
validateAsync: (cause: ValidationCause, formValidationResultPromise: Promise<FieldErrorMapFromValidator<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>>, opts?: {
skipRelatedFieldValidation?: boolean;
}) => Promise<unknown[]>;
/**
* Validates all fields according to the FIELD level validators.
* This will ignore FORM level validators, use form.validate({ValidationCause}) for a complete validation
*/
validateAllFields: (cause: ValidationCause) => Promise<unknown[]>;
validateArrayFieldsStartingFrom: <TField extends DeepKeysOfType<TParentData, any[]>>(field: TField, index: number, cause: ValidationCause) => Promise<unknown[]>;
validateField: <TField extends DeepKeysOfType<TParentData, any>>(field: TField, cause: ValidationCause) => any[] | Promise<any[]>;
getFieldValue: <TField extends DeepKeysOfType<TParentData, any>>(field: TField) => DeepValue<TParentData, TField>;
getFieldMeta: <TField extends DeepKeysOfType<TParentData, any>>(field: TField) => AnyFieldLikeMeta | undefined;
setFieldMeta: <TField extends DeepKeysOfType<TParentData, any>>(field: TField, updater: Updater<AnyFieldLikeMetaBase>) => void;
setFieldValue: <TField extends DeepKeysOfType<TParentData, any>>(field: TField, value: any) => void;
deleteField: <TField extends DeepKeysOfType<TParentData, any>>(field: TField) => void;
pushFieldValue: <TField extends DeepKeysOfType<TParentData, any[]>>(field: TField, value: any) => void;
insertFieldValue: <TField extends DeepKeysOfType<TParentData, any[]>>(field: TField, index: number, value: any) => Promise<void>;
replaceFieldValue: <TField extends DeepKeysOfType<TParentData, any[]>>(field: TField, index: number, value: any) => Promise<void>;
swapFieldValues: <TField extends DeepKeysOfType<TParentData, any[]>>(field: TField, index1: number, index2: number) => void;
moveFieldValues: <TField extends DeepKeysOfType<TParentData, any[]>>(field: TField, fromIndex: number, toIndex: number) => void;
clearFieldValues: <TField extends DeepKeysOfType<TParentData, any[]>>(field: TField) => void;
resetField: <TField extends DeepKeysOfType<TParentData, any>>(field: TField) => void;
removeFieldValue: <TField extends DeepKeysOfType<TParentData, any[]>>(field: TField, index: number) => Promise<void>;
areRelatedFieldsValid: () => boolean;
/**
* Validates the form group and all related children.
*/
validate: (cause: ValidationCause, opts?: {
skipFormValidation?: boolean;
skipRelatedFieldValidation?: boolean;
}) => ValidationError[] | Promise<ValidationError[]>;
/**
* @private
*/
triggerOnChangeListener: () => void;
/**
* @private
*/
triggerOnSubmitListener: () => void;
handleSubmit(): Promise<void>;
handleSubmit(submitMeta: TSubmitMeta): Promise<void>;
/**
* Handles the form submission, performs validation, and calls the appropriate onSubmit or onSubmitInvalid callbacks.
*/
_handleSubmit: (submitMeta?: TSubmitMeta) => Promise<void>;
}
export {};
import { batch, createStore } from "@tanstack/store";
import { evaluate, mergeOpts, isFieldInGroup, determineFormLevelErrorSourceAndValue, getSyncValidatorArray, getAsyncValidatorArray, determineFieldLevelErrorSourceAndValue } from "./utils.js";
import { defaultValidationLogic } from "./ValidationLogic.js";
import { isStandardSchemaValidator, standardSchemaValidators } from "./standardSchemaValidator.js";
import { defaultFieldMeta } from "./metaHelper.js";
import { FieldApi } from "./FieldApi.js";
function getDefaultFormGroupState(defaultState) {
return {
isSubmitted: defaultState.isSubmitted ?? false,
isSubmitting: defaultState.isSubmitting ?? false,
isValidating: defaultState.isValidating ?? false,
submissionAttempts: defaultState.submissionAttempts ?? 0,
isSubmitSuccessful: defaultState.isSubmitSuccessful ?? false
};
}
function getDefaultFormGroupMeta(defaultMeta) {
return {
...defaultFieldMeta,
...defaultMeta,
errors: [],
isPristine: true,
isValid: true,
isDefaultValue: true,
isFieldsValidating: false,
isFieldsValid: true,
isGroupValid: true,
canSubmit: true,
isSubmitting: false,
isSubmitted: false,
isValidating: false,
submissionAttempts: 0,
isSubmitSuccessful: false
};
}
class FormGroupApi {
constructor(opts) {
this.options = {};
this.setFormGroupState = (updater) => {
this.form.baseStore.setState((prev) => {
const prevGroupState = prev.formGroupStateBase[this.name] ?? getDefaultFormGroupState({});
return {
...prev,
formGroupStateBase: {
...prev.formGroupStateBase,
[this.name]: updater(prevGroupState)
}
};
});
};
this._lastDistributedFieldNames = {};
this.update = (opts2) => {
this.options = opts2;
this.name = opts2.name;
if (!this.state.meta.isTouched && this.options.defaultValue !== void 0) {
const formField = this.form.getFieldValue(this.name);
if (!evaluate(formField, opts2.defaultValue)) {
this.form.setFieldValue(this.name, opts2.defaultValue, {
dontUpdateMeta: true,
dontValidate: true,
dontRunListeners: true
});
}
}
if (!this.form.getFieldMeta(this.name)) {
this.form.setFieldMeta(this.name, {
...defaultFieldMeta,
...this.options.defaultMeta
});
}
};
this.mount = () => {
this.update(this.options);
this.form.formGroupApis.add(this);
this.fieldInfo.instance = this;
this.form.baseStore.setState((prev) => ({
...prev,
formGroupStateBase: {
...prev.formGroupStateBase,
[this.name]: prev.formGroupStateBase[this.name] ?? getDefaultFormGroupState({
...this.options.defaultState
})
}
}));
const { onMount } = this.options.validators || {};
if (onMount) {
const rawError = this.runValidator({
validate: onMount,
value: {
value: this.state.value,
groupApi: this,
validationSource: "form"
},
type: "validate"
});
let groupOwnRawError = rawError;
let groupFieldErrors = void 0;
if (isGlobalGroupValidationError(rawError)) {
groupOwnRawError = rawError.group;
groupFieldErrors = rawError.fields;
}
const error = normalizeError(groupOwnRawError);
if (error) {
this.setMeta(
(prev) => ({
...prev,
errorMap: {
...prev.errorMap,
onMount: error
},
errorSourceMap: {
...prev.errorSourceMap,
onMount: "field"
}
})
);
}
this.distributeFieldErrors("onMount", groupFieldErrors);
}
this.options.listeners?.onMount?.({
value: this.state.value,
groupApi: this
});
return () => {
for (const [key, timeout] of Object.entries(
this.timeoutIds.validations
)) {
if (timeout) {
clearTimeout(timeout);
this.timeoutIds.validations[key] = null;
}
}
for (const [key, timeout] of Object.entries(this.timeoutIds.listeners)) {
if (timeout) {
clearTimeout(timeout);
this.timeoutIds.listeners[key] = null;
}
}
for (const [key, timeout] of Object.entries(
this.timeoutIds.formListeners
)) {
if (timeout) {
clearTimeout(timeout);
this.timeoutIds.formListeners[key] = null;
}
}
if (this.fieldInfo.instance !== this) return;
for (const [key, validationMeta] of Object.entries(
this.fieldInfo.validationMetaMap
)) {
validationMeta?.lastAbortController.abort();
this.fieldInfo.validationMetaMap[key] = void 0;
}
this.form.formGroupApis.delete(this);
this.form.baseStore.setState((prev) => ({
...prev,
formGroupStateBase: {
...prev.formGroupStateBase,
[this.name]: getDefaultFormGroupState({})
}
}));
this.fieldInfo.instance = null;
this.options.listeners?.onUnmount?.({
value: this.state.value,
groupApi: this
});
};
};
this.setValue = (updater, options) => {
this.form.setFieldValue(
this.name,
updater,
mergeOpts(options, { dontRunListeners: true, dontValidate: true })
);
if (!options?.dontRunListeners) {
this.triggerOnChangeListener();
}
if (!options?.dontValidate) {
this.validate("change");
}
};
this.getMeta = () => this.store.state.meta;
this.setMeta = (updater) => this.form.setFieldMeta(this.name, updater);
this.getInfo = () => this.fieldInfo;
this.getRelatedFields = () => {
const fields = Object.values(this.form.fieldInfo);
const relatedFields = [];
for (const field of fields) {
if (!field.instance) continue;
if (!(field.instance instanceof FieldApi)) continue;
if (field.instance.name.startsWith(this.name)) {
relatedFields.push(field.instance);
}
}
return relatedFields;
};
this.getRelatedFieldMetasDerived = () => {
const fields = Object.entries(this.form.fieldMetaDerived.state);
const relatedFieldMetas = [];
for (const [fieldName, fieldMeta] of fields) {
if (fieldName === this.name) continue;
if (isFieldInGroup(this.name, fieldName)) {
relatedFieldMetas.push({ ...fieldMeta, name: fieldName });
}
}
return relatedFieldMetas;
};
this.buildChildFieldName = (relativeName) => {
if (relativeName === "") return this.name;
if (relativeName.startsWith("[")) return `${this.name}${relativeName}`;
return `${this.name}.${relativeName}`;
};
this.distributeFieldErrors = (errorMapKey, fieldErrors) => {
const previousNames = this._lastDistributedFieldNames[errorMapKey] ?? /* @__PURE__ */ new Set();
const currentNames = /* @__PURE__ */ new Set();
if (fieldErrors) {
for (const [relativeName, err] of Object.entries(fieldErrors)) {
if (err === void 0 || err === null || err === false) continue;
currentNames.add(this.buildChildFieldName(relativeName));
}
}
const allNames = /* @__PURE__ */ new Set([...previousNames, ...currentNames]);
let hasErrored = false;
for (const fullName of allNames) {
const relativeName = fullName.startsWith(this.name + "[") ? fullName.slice(this.name.length) : fullName.slice(this.name.length + 1);
const newFormValidatorError = fieldErrors?.[relativeName];
const fieldMeta = this.form.getFieldMeta(fullName);
if (!fieldMeta && !newFormValidatorError) continue;
const previousErrorValue = fieldMeta?.errorMap[errorMapKey];
const isPreviousErrorFromFormValidator = fieldMeta?.errorSourceMap[errorMapKey] === "form";
const { newErrorValue, newSource } = determineFormLevelErrorSourceAndValue({
newFormValidatorError,
isPreviousErrorFromFormValidator,
previousErrorValue
});
if (newErrorValue) hasErrored = true;
if (previousErrorValue === newErrorValue && fieldMeta?.errorSourceMap[errorMapKey] === newSource) {
continue;
}
this.form.setFieldMeta(fullName, (prev) => ({
...prev,
errorMap: {
...prev.errorMap,
[errorMapKey]: newErrorValue
},
errorSourceMap: {
...prev.errorSourceMap,
[errorMapKey]: newSource
}
}));
}
this._lastDistributedFieldNames[errorMapKey] = currentNames;
return hasErrored;
};
this.validateSync = (cause, errorFromForm, opts2 = {}) => {
const validates = getSyncValidatorArray(cause, {
...this.options,
form: this.form,
group: this,
validationLogic: this.options.validationLogic || this.form.options.validationLogic || defaultValidationLogic
});
const relatedFields = opts2.skipRelatedFieldValidation ? [] : this.getRelatedFields();
const relatedFieldValidates = relatedFields.reduce(
(acc, field) => {
const fieldValidates = getSyncValidatorArray(cause, {
...field.options,
form: field.form,
validationLogic: field.form.options.validationLogic || defaultValidationLogic
});
fieldValidates.forEach((validate) => {
validate.field = field;
});
return acc.concat(fieldValidates);
},
[]
);
let hasErrored = false;
batch(() => {
const validateFieldOrGroupFn = (fieldOrGroup, validateObj) => {
const errorMapKey = getErrorMapKey(validateObj.cause);
const isGroup = fieldOrGroup === this;
let rawError = void 0;
if (validateObj.validate) {
rawError = fieldOrGroup.runValidator({
validate: validateObj.validate,
value: {
value: fieldOrGroup.store.state.value,
// For the group's own validators we want standard schemas to
// produce a `{ form, fields }` shape (with relative keys) so
// we can fan errors out to children. Field-level validators on
// related fields keep the regular field source.
validationSource: isGroup ? "form" : "field",
...fieldOrGroup instanceof FormGroupApi ? {
groupApi: fieldOrGroup
} : { fieldApi: fieldOrGroup }
},
type: "validate"
});
}
let groupOwnRawError = rawError;
let groupFieldErrors = void 0;
if (isGroup && isGlobalGroupValidationError(rawError)) {
groupOwnRawError = rawError.group;
groupFieldErrors = rawError.fields;
}
const fieldLevelError = normalizeError(
groupOwnRawError
);
const formLevelError = errorFromForm[errorMapKey];
const { newErrorValue, newSource } = determineFieldLevelErrorSourceAndValue({
formLevelError,
fieldLevelError
});
if (fieldOrGroup.state.meta.errorMap?.[errorMapKey] !== newErrorValue) {
fieldOrGroup.setMeta((prev) => ({
...prev,
errorMap: {
...prev.errorMap,
[errorMapKey]: newErrorValue
},
errorSourceMap: {
...prev.errorSourceMap,
[errorMapKey]: newSource
}
}));
}
if (newErrorValue) {
hasErrored = true;
}
if (isGroup) {
const distributedHasErrored = this.distributeFieldErrors(
errorMapKey,
groupFieldErrors
);
if (distributedHasErrored) {
hasErrored = true;
}
}
};
for (const validateObj of validates) {
validateFieldOrGroupFn(this, validateObj);
}
for (const fieldValidateObj of relatedFieldValidates) {
if (!fieldValidateObj.validate) continue;
validateFieldOrGroupFn(fieldValidateObj.field, fieldValidateObj);
}
});
const submitErrKey = getErrorMapKey("submit");
if (
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
this.state.meta.errorMap?.[submitErrKey] && cause !== "submit" && !hasErrored
) {
this.setMeta((prev) => ({
...prev,
errorMap: {
...prev.errorMap,
[submitErrKey]: void 0
},
errorSourceMap: {
...prev.errorSourceMap,
[submitErrKey]: void 0
}
}));
}
return { hasErrored };
};
this.validateAsync = async (cause, formValidationResultPromise, opts2 = {}) => {
const validates = getAsyncValidatorArray(cause, {
...this.options,
form: this.form,
group: this,
validationLogic: this.options.validationLogic || this.form.options.validationLogic || defaultValidationLogic
});
const asyncFormValidationResults = await formValidationResultPromise;
const relatedFields = opts2.skipRelatedFieldValidation ? [] : this.getRelatedFields();
const relatedFieldValidates = relatedFields.reduce(
(acc, field) => {
const fieldValidates = getAsyncValidatorArray(cause, {
...field.options,
form: field.form,
validationLogic: field.form.options.validationLogic || defaultValidationLogic
});
fieldValidates.forEach((validate) => {
validate.field = field;
});
return acc.concat(fieldValidates);
},
[]
);
const validatesPromises = [];
const linkedPromises = [];
const hasAsyncValidators = validates.some((v) => v.validate) || relatedFieldValidates.some((v) => v.validate);
if (hasAsyncValidators) {
if (!this.state.meta.isValidating) {
this.setMeta((prev) => ({ ...prev, isValidating: true }));
}
for (const linkedField of relatedFields) {
linkedField.setMeta((prev) => ({ ...prev, isValidating: true }));
}
}
const validateFieldOrGroupAsyncFn = (fieldOrGroup, validateObj, promises) => {
const errorMapKey = getErrorMapKey(validateObj.cause);
const fieldInfo = fieldOrGroup.getInfo();
const fieldValidatorMeta = fieldInfo.validationMetaMap[errorMapKey];
fieldValidatorMeta?.lastAbortController.abort();
const controller = new AbortController();
fieldInfo.validationMetaMap[errorMapKey] = {
lastAbortController: controller
};
const isGroup = fieldOrGroup === this;
promises.push(
new Promise(async (resolve) => {
let rawError;
try {
rawError = await new Promise((rawResolve, rawReject) => {
if (fieldOrGroup.timeoutIds.validations[validateObj.cause]) {
clearTimeout(
fieldOrGroup.timeoutIds.validations[validateObj.cause]
);
}
fieldOrGroup.timeoutIds.validations[validateObj.cause] = setTimeout(async () => {
if (controller.signal.aborted) return rawResolve(void 0);
try {
rawResolve(
await this.runValidator({
validate: validateObj.validate,
value: {
value: fieldOrGroup.store.state.value,
signal: controller.signal,
// See sync counterpart: produce `{ form, fields }`
// from standard schemas attached to the group so we
// can fan errors out to children.
validationSource: isGroup ? "form" : "field",
...fieldOrGroup instanceof FormGroupApi ? {
groupApi: fieldOrGroup
} : { fieldApi: fieldOrGroup }
},
type: "validateAsync"
})
);
} catch (e) {
rawReject(e);
}
}, validateObj.debounceMs);
});
} catch (e) {
rawError = e;
}
if (controller.signal.aborted) return resolve(void 0);
let groupOwnRawError = rawError;
let groupFieldErrors = void 0;
if (isGroup && isGlobalGroupValidationError(rawError)) {
groupOwnRawError = rawError.group;
groupFieldErrors = rawError.fields;
}
const fieldLevelError = normalizeError(groupOwnRawError);
const formLevelError = asyncFormValidationResults[fieldOrGroup.name]?.[errorMapKey];
const { newErrorValue, newSource } = determineFieldLevelErrorSourceAndValue({
formLevelError,
fieldLevelError
});
if (fieldOrGroup.getInfo().instance !== fieldOrGroup) {
return resolve(void 0);
}
fieldOrGroup.setMeta((prev) => {
return {
...prev,
errorMap: {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
...prev?.errorMap,
[errorMapKey]: newErrorValue
},
errorSourceMap: {
...prev.errorSourceMap,
[errorMapKey]: newSource
}
};
});
if (isGroup) {
this.distributeFieldErrors(errorMapKey, groupFieldErrors);
}
resolve(newErrorValue);
})
);
};
for (const validateObj of validates) {
if (!validateObj.validate) continue;
validateFieldOrGroupAsyncFn(this, validateObj, validatesPromises);
}
for (const fieldValitateObj of relatedFieldValidates) {
if (!fieldValitateObj.validate) continue;
validateFieldOrGroupAsyncFn(
fieldValitateObj.field,
fieldValitateObj,
linkedPromises
);
}
let results = [];
if (validatesPromises.length || linkedPromises.length) {
results = await Promise.all(validatesPromises);
await Promise.all(linkedPromises);
}
if (hasAsyncValidators) {
this.setMeta((prev) => ({ ...prev, isValidating: false }));
for (const linkedField of relatedFields) {
linkedField.setMeta((prev) => ({ ...prev, isValidating: false }));
}
}
return results.filter(Boolean);
};
this.validateAllFields = async (cause) => {
const fieldValidationPromises = [];
batch(() => {
void Object.values(this.getRelatedFields()).forEach((fieldInstance) => {
fieldValidationPromises.push(
// Remember, `validate` is either a sync operation or a promise
Promise.resolve().then(
() => fieldInstance.validate(cause, {
skipFormValidation: true,
skipGroupValidation: true
})
)
);
if (!fieldInstance.store.state.meta.isTouched) {
fieldInstance.setMeta((prev) => ({ ...prev, isTouched: true }));
}
});
});
const fieldErrorMapMap = await Promise.all(fieldValidationPromises);
return fieldErrorMapMap.flat();
};
this.validateArrayFieldsStartingFrom = (field, index, cause) => {
return this.form.validateArrayFieldsStartingFrom(field, index, cause);
};
this.validateField = (field, cause) => {
return this.form.validateField(field, cause);
};
this.getFieldValue = (field) => {
return this.form.getFieldValue(field);
};
this.getFieldMeta = (field) => {
return this.form.getFieldMeta(field);
};
this.setFieldMeta = (field, updater) => {
return this.form.setFieldMeta(field, updater);
};
this.setFieldValue = (field, value) => {
return this.form.setFieldValue(field, value);
};
this.deleteField = (field) => {
return this.form.deleteField(field);
};
this.pushFieldValue = (field, value) => {
return this.form.pushFieldValue(field, value);
};
this.insertFieldValue = (field, index, value) => {
return this.form.insertFieldValue(field, index, value);
};
this.replaceFieldValue = (field, index, value) => {
return this.form.replaceFieldValue(field, index, value);
};
this.swapFieldValues = (field, index1, index2) => {
return this.form.swapFieldValues(field, index1, index2);
};
this.moveFieldValues = (field, fromIndex, toIndex) => {
return this.form.moveFieldValues(field, fromIndex, toIndex);
};
this.clearFieldValues = (field) => {
return this.form.clearFieldValues(field);
};
this.resetField = (field) => {
return this.form.resetField(field);
};
this.removeFieldValue = (field, index) => {
return this.form.removeFieldValue(field, index);
};
this.areRelatedFieldsValid = () => {
return Object.values(this.getRelatedFields()).every(
(field) => field.state.meta.isValid
);
};
this.validate = (cause, opts2) => {
const { fieldsErrorMap } = opts2?.skipFormValidation ? { fieldsErrorMap: {} } : this.form.validateSync(cause, {
dontUpdateFormErrorMap: true,
filterFieldNames: (fieldName) => isFieldInGroup(this.name, fieldName)
});
const { hasErrored } = this.validateSync(
cause,
fieldsErrorMap[this.name] ?? {},
{ skipRelatedFieldValidation: opts2?.skipRelatedFieldValidation }
);
if (hasErrored && !this.options.asyncAlways) {
this.getInfo().validationMetaMap[getErrorMapKey(cause)]?.lastAbortController.abort();
return this.state.meta.errors;
}
const formValidationResultPromise = opts2?.skipFormValidation ? Promise.resolve({}) : this.form.validateAsync(cause, {
dontUpdateFormErrorMap: true,
filterFieldNames: (fieldName) => isFieldInGroup(this.name, fieldName)
});
return this.validateAsync(cause, formValidationResultPromise, {
skipRelatedFieldValidation: opts2?.skipRelatedFieldValidation
});
};
this.triggerOnChangeListener = () => {
const formDebounceMs = this.form.options.listeners?.onChangeGroupDebounceMs;
if (formDebounceMs && formDebounceMs > 0) {
if (this.timeoutIds.formListeners.change) {
clearTimeout(this.timeoutIds.formListeners.change);
}
this.timeoutIds.formListeners.change = setTimeout(() => {
this.form.options.listeners?.onChangeGroup?.({
formApi: this.form,
groupApi: this
});
}, formDebounceMs);
} else {
this.form.options.listeners?.onChangeGroup?.({
formApi: this.form,
groupApi: this
});
}
const fieldDebounceMs = this.options.listeners?.onChangeDebounceMs;
if (fieldDebounceMs && fieldDebounceMs > 0) {
if (this.timeoutIds.listeners.change) {
clearTimeout(this.timeoutIds.listeners.change);
}
this.timeoutIds.listeners.change = setTimeout(() => {
this.options.listeners?.onChange?.({
value: this.state.value,
groupApi: this
});
}, fieldDebounceMs);
} else {
this.options.listeners?.onChange?.({
value: this.state.value,
groupApi: this
});
}
};
this.triggerOnSubmitListener = () => {
this.options.listeners?.onSubmit?.({
value: this.state.value,
groupApi: this
});
};
this._handleSubmit = async (submitMeta) => {
this.setFormGroupState((old) => ({
...old,
// Submission attempts mark the form as not submitted
isSubmitted: false,
// Count submission attempts
submissionAttempts: old.submissionAttempts + 1,
isSubmitSuccessful: false
// Reset isSubmitSuccessful at the start of submission
}));
batch(() => {
void Object.values(this.getRelatedFields()).forEach((field) => {
if (!field.state.meta.isTouched) {
field.setMeta((prev) => ({ ...prev, isTouched: true }));
}
});
});
const submitMetaArg = submitMeta ?? this.options.onSubmitMeta;
this.setFormGroupState((d) => ({ ...d, isSubmitting: true }));
const done = () => {
this.setFormGroupState((prev) => ({ ...prev, isSubmitting: false }));
};
await this.validateAllFields("submit");
if (!this.areRelatedFieldsValid()) {
done();
this.options.onGroupSubmitInvalid?.({
value: this.state.value,
groupApi: this,
meta: submitMetaArg
});
return;
}
await this.validate("submit", {
// This has already happened in the previous step
skipRelatedFieldValidation: true
});
if (!this.areRelatedFieldsValid() || !this.state.meta.isValid) {
done();
this.options.onGroupSubmitInvalid?.({
value: this.state.value,
groupApi: this,
meta: submitMetaArg
});
return;
}
batch(() => {
void Object.values(this.getRelatedFields()).forEach((field) => {
field.options.listeners?.onGroupSubmit?.({
value: field.state.value,
fieldApi: field
});
});
});
this.options.listeners?.onSubmit?.({
groupApi: this,
value: this.state.value
});
try {
await this.options.onGroupSubmit?.({
value: this.state.value,
groupApi: this,
meta: submitMetaArg
});
batch(() => {
this.setFormGroupState((prev) => ({
...prev,
isSubmitted: true,
isSubmitSuccessful: true
// Set isSubmitSuccessful to true on successful submission
}));
done();
});
} catch (err) {
this.setFormGroupState((prev) => ({
...prev,
isSubmitSuccessful: false
// Ensure isSubmitSuccessful is false if an error occurs
}));
done();
throw err;
}
};
this.form = opts.form;
this.name = opts.name;
this.options = opts;
this.timeoutIds = {
validations: {},
listeners: {},
formListeners: {}
};
this.fieldInfo = {
instance: null,
validationMetaMap: {
onChange: void 0,
onBlur: void 0,
onSubmit: void 0,
onMount: void 0,
onServer: void 0,
onDynamic: void 0
}
};
this.store = createStore(
(prevVal) => {
this.form.formGroupMetaDerived.get();
this.form.baseStore.get();
const meta = this.form.getFormGroupMeta(this.name) ?? getDefaultFormGroupMeta(opts.defaultMeta);
let value = this.form.getFieldValue(this.name);
if (!meta.isTouched && value === void 0 && this.options.defaultValue !== void 0 && !evaluate(value, this.options.defaultValue)) {
value = this.options.defaultValue;
}
if (prevVal && prevVal.value === value && prevVal.meta === meta) {
return prevVal;
}
return {
value,
meta
};
}
);
this.handleSubmit = this.handleSubmit.bind(this);
}
/**
* The current field state.
*/
get state() {
return this.store.state;
}
/**
* @private
*/
runValidator(props) {
if (isStandardSchemaValidator(props.validate)) {
const result = standardSchemaValidators[props.type](
props.value,
props.validate
);
if (props.type === "validate") {
return remapStandardSchemaResultForGroup(result);
}
return result.then(
remapStandardSchemaResultForGroup
);
}
return props.validate(
props.value
);
}
handleSubmit(submitMeta) {
return this._handleSubmit(submitMeta);
}
}
function normalizeError(rawError) {
if (rawError) {
return rawError;
}
return void 0;
}
function isGlobalGroupValidationError(error) {
return !!error && typeof error === "object" && "fields" in error;
}
function remapStandardSchemaResultForGroup(result) {
if (!result || typeof result !== "object") return result;
if (!("form" in result) && !("fields" in result)) return result;
const { form, fields, ...rest } = result;
return { ...rest, group: form, fields };
}
function getErrorMapKey(cause) {
switch (cause) {
case "submit":
return "onSubmit";
case "blur":
return "onBlur";
case "mount":
return "onMount";
case "server":
return "onServer";
case "dynamic":
return "onDynamic";
case "change":
default:
return "onChange";
}
}
export {
FormGroupApi,
getDefaultFormGroupMeta
};
//# sourceMappingURL=FormGroupApi.js.map

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

+108
-42

@@ -224,2 +224,5 @@ "use strict";

if (!field.instance) continue;
if (!(field.instance instanceof FieldApi)) {
continue;
}
const { onChangeListenTo, onBlurListenTo } = field.instance.options.validators || {};

@@ -455,13 +458,65 @@ if (cause === "change" && onChangeListenTo?.includes(this.name)) {

if (!this.state.meta.isTouched) return [];
const { fieldsErrorMap } = opts2?.skipFormValidation ? { fieldsErrorMap: {} } : this.form.validateSync(cause);
const { hasErrored } = this.validateSync(
cause,
fieldsErrorMap[this.name] ?? {}
const encompassingGroups = opts2?.skipGroupValidation ? [] : Array.from(this.form.formGroupApis).filter(
(group) => this.name.startsWith(group.name)
);
const formSyncResult = opts2?.skipFormValidation ? { fieldsErrorMap: {} } : this.form.validateSync(cause);
let fieldsErrorMap = formSyncResult.fieldsErrorMap[this.name] ?? {};
if (!opts2?.skipFormValidation) {
for (const group of encompassingGroups) {
if (group.state.meta.submissionAttempts === 0) continue;
const { fieldsErrorMap: groupFormErrors } = this.form.validateSync(
cause,
{
group,
dontUpdateFormErrorMap: true,
filterFieldNames: (fieldName) => utils.isFieldInGroup(group.name, fieldName)
}
);
fieldsErrorMap = {
...fieldsErrorMap,
...groupFormErrors[this.name] ?? {}
};
}
}
const { hasErrored } = this.validateSync(cause, fieldsErrorMap);
const groupHasErroredWeakMap = /* @__PURE__ */ new WeakMap();
for (const group of encompassingGroups) {
const { hasErrored: groupHasErrored } = group.validateSync(
cause,
{},
{ skipRelatedFieldValidation: true }
);
groupHasErroredWeakMap.set(group, groupHasErrored);
}
if (hasErrored && !this.options.asyncAlways) {
this.getInfo().validationMetaMap[getErrorMapKey(cause)]?.lastAbortController.abort();
return this.state.meta.errors;
const groupErrors = [];
for (const group of encompassingGroups) {
group.getInfo().validationMetaMap[getErrorMapKey(cause)]?.lastAbortController.abort();
groupErrors.push(group.state.meta.errors);
}
return [...this.state.meta.errors, ...groupErrors.flat()];
}
const formValidationResultPromise = opts2?.skipFormValidation ? Promise.resolve({}) : this.form.validateAsync(cause);
return this.validateAsync(cause, formValidationResultPromise);
const fieldAsyncResults = this.validateAsync(
cause,
formValidationResultPromise
);
const groupAsyncResults = [];
for (const group of encompassingGroups) {
if (groupHasErroredWeakMap.get(group) && !group.options.asyncAlways) {
continue;
}
groupAsyncResults.push(
group.validateAsync(cause, formValidationResultPromise, {
skipRelatedFieldValidation: true
})
);
}
if (groupAsyncResults.length === 0) {
return fieldAsyncResults;
}
return Promise.all([fieldAsyncResults, ...groupAsyncResults]).then(
(results) => results.flat()
);
};

@@ -503,2 +558,38 @@ this.handleChange = (updater) => {

};
this.triggerOnBlurListener = () => {
const formDebounceMs = this.form.options.listeners?.onBlurDebounceMs;
if (formDebounceMs && formDebounceMs > 0) {
if (this.timeoutIds.formListeners.blur) {
clearTimeout(this.timeoutIds.formListeners.blur);
}
this.timeoutIds.formListeners.blur = setTimeout(() => {
this.form.options.listeners?.onBlur?.({
formApi: this.form,
fieldApi: this
});
}, formDebounceMs);
} else {
this.form.options.listeners?.onBlur?.({
formApi: this.form,
fieldApi: this
});
}
const fieldDebounceMs = this.options.listeners?.onBlurDebounceMs;
if (fieldDebounceMs && fieldDebounceMs > 0) {
if (this.timeoutIds.listeners.blur) {
clearTimeout(this.timeoutIds.listeners.blur);
}
this.timeoutIds.listeners.blur = setTimeout(() => {
this.options.listeners?.onBlur?.({
value: this.state.value,
fieldApi: this
});
}, fieldDebounceMs);
} else {
this.options.listeners?.onBlur?.({
value: this.state.value,
fieldApi: this
});
}
};
this.triggerOnChangeListener = () => {

@@ -539,3 +630,14 @@ const formDebounceMs = this.form.options.listeners?.onChangeDebounceMs;

}
for (const group of this.form.formGroupApis) {
if (utils.isFieldInGroup(group.name, this.name)) {
group.triggerOnChangeListener();
}
}
};
this.triggerOnSubmitListener = () => {
this.options.listeners?.onSubmit?.({
value: this.state.value,
fieldApi: this
});
};
this.form = opts.form;

@@ -588,38 +690,2 @@ this.name = opts.name;

}
triggerOnBlurListener() {
const formDebounceMs = this.form.options.listeners?.onBlurDebounceMs;
if (formDebounceMs && formDebounceMs > 0) {
if (this.timeoutIds.formListeners.blur) {
clearTimeout(this.timeoutIds.formListeners.blur);
}
this.timeoutIds.formListeners.blur = setTimeout(() => {
this.form.options.listeners?.onBlur?.({
formApi: this.form,
fieldApi: this
});
}, formDebounceMs);
} else {
this.form.options.listeners?.onBlur?.({
formApi: this.form,
fieldApi: this
});
}
const fieldDebounceMs = this.options.listeners?.onBlurDebounceMs;
if (fieldDebounceMs && fieldDebounceMs > 0) {
if (this.timeoutIds.listeners.blur) {
clearTimeout(this.timeoutIds.listeners.blur);
}
this.timeoutIds.listeners.blur = setTimeout(() => {
this.options.listeners?.onBlur?.({
value: this.state.value,
fieldApi: this
});
}, fieldDebounceMs);
} else {
this.options.listeners?.onBlur?.({
value: this.state.value,
fieldApi: this
});
}
}
}

@@ -626,0 +692,0 @@ function normalizeError(rawError) {

@@ -0,6 +1,6 @@

import { FieldErrorMapFromValidator, FieldInfo, FieldLikeAPI, FieldLikeApiOptions, FieldLikeMetaBase, FieldLikeOptions, FieldLikeState, ListenerCause, UnwrapFieldAsyncValidateOrFn, UnwrapFieldValidateOrFn, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap } from './types.cjs';
import { ReadonlyStore } from '@tanstack/store';
import { DeepKeys, DeepValue, RejectPromiseValidator, UnwrapOneLevelOfArray } from './util-types.cjs';
import { StandardSchemaV1, StandardSchemaV1Issue, TStandardSchemaValidatorValue } from './standardSchemaValidator.cjs';
import { FieldInfo, FormApi, FormAsyncValidateOrFn, FormValidateAsyncFn, FormValidateFn, FormValidateOrFn } from './FormApi.cjs';
import { ListenerCause, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap, ValidationErrorMapSource } from './types.cjs';
import { DeepKeys, DeepValue, RejectPromiseValidator } from './util-types.cjs';
import { StandardSchemaV1, TStandardSchemaValidatorValue } from './standardSchemaValidator.cjs';
import { FormAsyncValidateOrFn, FormValidateOrFn } from './FormApi.cjs';
import { Updater } from './utils.cjs';

@@ -10,6 +10,2 @@ /**

*/
type FieldErrorMapFromValidator<TFormData, TName extends DeepKeys<TFormData>, TData extends DeepValue<TFormData, TName>, TOnMount extends undefined | FieldValidateOrFn<TFormData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TFormData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TFormData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TFormData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TFormData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TFormData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TFormData, TName, TData>> = Partial<Record<DeepKeys<TFormData>, ValidationErrorMap<TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>>>;
/**
* @private
*/
export type FieldValidateFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = (props: {

@@ -22,15 +18,2 @@ value: TData;

*/
export type FieldValidateOrFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FieldValidateFn<TParentData, TName, TData> | StandardSchemaV1<TData, unknown>;
type StandardBrandedSchemaV1<T> = T & {
__standardSchemaV1: true;
};
type UnwrapFormValidateOrFnForInner<TValidateOrFn extends undefined | FormValidateOrFn<any>> = [TValidateOrFn] extends [FormValidateFn<any>] ? ReturnType<TValidateOrFn> : [TValidateOrFn] extends [StandardSchemaV1<infer TOut, any>] ? StandardBrandedSchemaV1<TOut> : undefined;
export type UnwrapFieldValidateOrFn<TName extends string, TValidateOrFn extends undefined | FieldValidateOrFn<any, any, any>, TFormValidateOrFn extends undefined | FormValidateOrFn<any>> = ([TFormValidateOrFn] extends [StandardSchemaV1<any, infer TStandardOut>] ? TName extends keyof TStandardOut ? StandardSchemaV1Issue[] : undefined : undefined) | (UnwrapFormValidateOrFnForInner<TFormValidateOrFn> extends infer TFormValidateVal ? TFormValidateVal extends {
__standardSchemaV1: true;
} ? [DeepValue<TFormValidateVal, TName>] extends [never] ? undefined : StandardSchemaV1Issue[] : TFormValidateVal extends {
fields: any;
} ? TName extends keyof TFormValidateVal['fields'] ? TFormValidateVal['fields'][TName] : undefined : undefined : never) | ([TValidateOrFn] extends [FieldValidateFn<any, any, any>] ? ReturnType<TValidateOrFn> : [TValidateOrFn] extends [StandardSchemaV1<any, any>] ? StandardSchemaV1Issue[] : undefined);
/**
* @private
*/
export type FieldValidateAsyncFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = (options: {

@@ -44,12 +27,2 @@ value: TData;

*/
export type FieldAsyncValidateOrFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FieldValidateAsyncFn<TParentData, TName, TData> | StandardSchemaV1<TData, unknown>;
type UnwrapFormAsyncValidateOrFnForInner<TValidateOrFn extends undefined | FormAsyncValidateOrFn<any>> = [TValidateOrFn] extends [FormValidateAsyncFn<any>] ? Awaited<ReturnType<TValidateOrFn>> : [TValidateOrFn] extends [StandardSchemaV1<infer TOut, any>] ? StandardBrandedSchemaV1<TOut> : undefined;
export type UnwrapFieldAsyncValidateOrFn<TName extends string, TValidateOrFn extends undefined | FieldAsyncValidateOrFn<any, any, any>, TFormValidateOrFn extends undefined | FormAsyncValidateOrFn<any>> = ([TFormValidateOrFn] extends [StandardSchemaV1<any, infer TStandardOut>] ? TName extends keyof TStandardOut ? StandardSchemaV1Issue[] : undefined : undefined) | (UnwrapFormAsyncValidateOrFnForInner<TFormValidateOrFn> extends infer TFormValidateVal ? TFormValidateVal extends {
__standardSchemaV1: true;
} ? [DeepValue<TFormValidateVal, TName>] extends [never] ? undefined : StandardSchemaV1Issue[] : TFormValidateVal extends {
fields: any;
} ? TName extends keyof TFormValidateVal['fields'] ? TFormValidateVal['fields'][TName] : undefined : undefined : never) | ([TValidateOrFn] extends [FieldValidateAsyncFn<any, any, any>] ? Awaited<ReturnType<TValidateOrFn>> : [TValidateOrFn] extends [StandardSchemaV1<any, any>] ? StandardSchemaV1Issue[] : undefined);
/**
* @private
*/
export type FieldListenerFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = (props: {

@@ -59,2 +32,10 @@ value: TData;

}) => void;
/**
* @private
*/
export type FieldValidateOrFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FieldValidateFn<TParentData, TName, TData> | StandardSchemaV1<TData, unknown>;
/**
* @private
*/
export type FieldAsyncValidateOrFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FieldValidateAsyncFn<TParentData, TName, TData> | StandardSchemaV1<TData, unknown>;
export interface FieldValidators<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>> {

@@ -133,24 +114,6 @@ /**

onSubmit?: FieldListenerFn<TParentData, TName, TData>;
onGroupSubmit?: FieldListenerFn<TParentData, TName, TData>;
}
/**
* An object type representing the options for a field in a form.
*/
export interface FieldOptions<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>> {
interface FieldExtraOptions<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>> {
/**
* The field name. The type will be `DeepKeys<TParentData>` to ensure your name is a deep key of the parent dataset.
*/
name: TName;
/**
* An optional default value for the field.
*/
defaultValue?: NoInfer<TData>;
/**
* The default time to debounce async validation if there is not a more specific debounce time passed.
*/
asyncDebounceMs?: number;
/**
* If `true`, always run async validation, even if there are errors emitted during synchronous validation.
*/
asyncAlways?: boolean;
/**
* A list of validators to pass to the field

@@ -160,93 +123,14 @@ */

/**
* An optional object with default metadata for the field.
*/
defaultMeta?: Partial<FieldMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, any, any, any, any, any, any, any, any, any>>;
/**
* A list of listeners which attach to the corresponding events
*/
listeners?: FieldListeners<TParentData, TName, TData>;
/**
* Disable the `flat(1)` operation on `field.errors`. This is useful if you want to keep the error structure as is. Not suggested for most use-cases.
*/
disableErrorFlat?: boolean;
}
/**
* An object type representing the required options for the FieldApi class.
* An object type representing the options for a field in a form.
*/
export interface FieldApiOptions<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> extends FieldOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync> {
form: FormApi<TParentData, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>;
export interface FieldOptions<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>> extends FieldExtraOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>, FieldLikeOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync> {
}
export type FieldMetaBase<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TFormOnMount extends undefined | FormValidateOrFn<TParentData>, TFormOnChange extends undefined | FormValidateOrFn<TParentData>, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> = {
/**
* A flag indicating whether the field has been touched.
*/
isTouched: boolean;
/**
* A flag indicating whether the field has been blurred.
*/
isBlurred: boolean;
/**
* A flag that is `true` if the field's value has been modified by the user. Opposite of `isPristine`.
*/
isDirty: boolean;
/**
* A map of errors related to the field value.
*/
errorMap: ValidationErrorMap<UnwrapFieldValidateOrFn<TName, TOnMount, TFormOnMount>, UnwrapFieldValidateOrFn<TName, TOnChange, TFormOnChange>, UnwrapFieldAsyncValidateOrFn<TName, TOnChangeAsync, TFormOnChangeAsync>, UnwrapFieldValidateOrFn<TName, TOnBlur, TFormOnBlur>, UnwrapFieldAsyncValidateOrFn<TName, TOnBlurAsync, TFormOnBlurAsync>, UnwrapFieldValidateOrFn<TName, TOnSubmit, TFormOnSubmit>, UnwrapFieldAsyncValidateOrFn<TName, TOnSubmitAsync, TFormOnSubmitAsync>, UnwrapFieldValidateOrFn<TName, TOnDynamic, TFormOnDynamic>, UnwrapFieldAsyncValidateOrFn<TName, TOnDynamicAsync, TFormOnDynamicAsync>>;
/**
* @private allows tracking the source of the errors in the error map
*/
errorSourceMap: ValidationErrorMapSource;
/**
* A flag indicating whether the field is currently being validated.
*/
isValidating: boolean;
/**
* @private a counter that is incremented every time a structural array
* operation (push, insert, remove, swap, move, replace, clear) modifies
* the value of an array field. Adapters can subscribe to this to trigger
* re-renders for `mode="array"` fields without having to subscribe to the
* full field value.
*/
_arrayVersion: number;
};
export type AnyFieldMetaBase = FieldMetaBase<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
export type FieldMetaDerived<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TFormOnMount extends undefined | FormValidateOrFn<TParentData>, TFormOnChange extends undefined | FormValidateOrFn<TParentData>, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> = {
/**
* An array of errors related to the field value.
*/
errors: Array<UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnMount, TFormOnMount>> | UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnChange, TFormOnChange>> | UnwrapOneLevelOfArray<UnwrapFieldAsyncValidateOrFn<TName, TOnChangeAsync, TFormOnChangeAsync>> | UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnBlur, TFormOnBlur>> | UnwrapOneLevelOfArray<UnwrapFieldAsyncValidateOrFn<TName, TOnBlurAsync, TFormOnBlurAsync>> | UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnSubmit, TFormOnSubmit>> | UnwrapOneLevelOfArray<UnwrapFieldAsyncValidateOrFn<TName, TOnSubmitAsync, TFormOnSubmitAsync>> | UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnDynamic, TFormOnDynamic>> | UnwrapOneLevelOfArray<UnwrapFieldAsyncValidateOrFn<TName, TOnDynamicAsync, TFormOnDynamicAsync>>>;
/**
* A flag that is `true` if the field's value has not been modified by the user. Opposite of `isDirty`.
*/
isPristine: boolean;
/**
* A boolean indicating if the field is valid. Evaluates `true` if there are no field errors.
*/
isValid: boolean;
/**
* A flag indicating whether the field's current value is the default value
*/
isDefaultValue: boolean;
};
export type AnyFieldMetaDerived = FieldMetaDerived<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
export interface FieldApiOptions<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> extends FieldLikeApiOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>, FieldExtraOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync> {
}
/**
* An object type representing the metadata of a field in a form.
*/
export type FieldMeta<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TFormOnMount extends undefined | FormValidateOrFn<TParentData>, TFormOnChange extends undefined | FormValidateOrFn<TParentData>, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> = FieldMetaBase<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync> & FieldMetaDerived<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
export type AnyFieldMeta = FieldMeta<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
/**
* An object type representing the state of a field.
*/
export type FieldState<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TFormOnMount extends undefined | FormValidateOrFn<TParentData>, TFormOnChange extends undefined | FormValidateOrFn<TParentData>, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> = {
/**
* The current value of the field.
*/
value: TData;
/**
* The current metadata of the field.
*/
meta: FieldMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
};
/**
* @public

@@ -270,3 +154,3 @@ *

*/
export declare class FieldApi<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> {
export declare class FieldApi<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> implements FieldLikeAPI<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta, FieldExtraOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>> {
/**

@@ -287,7 +171,7 @@ * A reference to the form API instance.

*/
store: ReadonlyStore<FieldState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>;
store: ReadonlyStore<FieldLikeState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>;
/**
* The current field state.
*/
get state(): FieldState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
get state(): FieldLikeState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
timeoutIds: {

@@ -330,7 +214,7 @@ validations: Record<ValidationCause, ReturnType<typeof setTimeout> | null>;

setValue: (updater: Updater<TData>, options?: UpdateMetaOptions) => void;
getMeta: () => FieldMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
getMeta: () => import('./types.cjs').FieldLikeMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
/**
* Sets the field metadata.
*/
setMeta: (updater: Updater<FieldMetaBase<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>) => void;
setMeta: (updater: Updater<FieldLikeMetaBase<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>) => void;
/**

@@ -387,2 +271,3 @@ * Gets the field information object.

skipFormValidation?: boolean;
skipGroupValidation?: boolean;
}) => ValidationError[] | Promise<ValidationError[]>;

@@ -406,3 +291,3 @@ /**

*/
parseValueWithSchema: (schema: StandardSchemaV1<TData, unknown>) => StandardSchemaV1Issue[] | undefined;
parseValueWithSchema: (schema: StandardSchemaV1<TData, unknown>) => import('./standardSchemaValidator.cjs').StandardSchemaV1Issue[] | undefined;
/**

@@ -413,3 +298,3 @@ * Parses the field's value with the given schema and returns

*/
parseValueWithSchemaAsync: (schema: StandardSchemaV1<TData, unknown>) => Promise<StandardSchemaV1Issue[] | undefined>;
parseValueWithSchemaAsync: (schema: StandardSchemaV1<TData, unknown>) => Promise<import('./standardSchemaValidator.cjs').StandardSchemaV1Issue[] | undefined>;
private triggerOnBlurListener;

@@ -420,3 +305,7 @@ /**

triggerOnChangeListener: () => void;
/**
* @private
*/
triggerOnSubmitListener: () => void;
}
export {};

@@ -1,1 +0,1 @@

{"version":3,"file":"FieldGroupApi.cjs","sources":["../../src/FieldGroupApi.ts"],"sourcesContent":["import { createStore } from '@tanstack/store'\nimport { concatenatePaths, getBy, makePathArray } from './utils'\nimport type { ReadonlyStore } from '@tanstack/store'\nimport type { Updater } from './utils'\nimport type {\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\nimport type { AnyFieldMetaBase, FieldOptions } from './FieldApi'\nimport type {\n DeepKeys,\n DeepKeysOfType,\n DeepValue,\n FieldsMap,\n} from './util-types'\nimport type {\n FieldManipulator,\n UpdateMetaOptions,\n ValidationCause,\n} from './types'\n\nexport type AnyFieldGroupApi = FieldGroupApi<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\nexport interface FieldGroupState<in out TFieldGroupData> {\n /**\n * The current values of the field group\n */\n values: TFieldGroupData\n}\n\n/**\n * An object representing the options for a field group.\n */\nexport interface FieldGroupOptions<\n in out TFormData,\n in out TFieldGroupData,\n in out TFields extends\n | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n | FieldsMap<TFormData, TFieldGroupData>,\n in out TOnMount extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChange extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TSubmitMeta = never,\n> {\n form:\n | FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >\n | FieldGroupApi<\n any,\n TFormData,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n TSubmitMeta\n >\n /**\n * The path to the field group data.\n */\n fields: TFields\n /**\n * The expected subsetValues that the form must provide.\n */\n defaultValues?: TFieldGroupData\n /**\n * onSubmitMeta, the data passed from the handleSubmit handler, to the onSubmit function props\n */\n onSubmitMeta?: TSubmitMeta\n}\n\nexport class FieldGroupApi<\n in out TFormData,\n in out TFieldGroupData,\n in out TFields extends\n | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n | FieldsMap<TFormData, TFieldGroupData>,\n in out TOnMount extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChange extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TSubmitMeta = never,\n> implements FieldManipulator<TFieldGroupData, TSubmitMeta> {\n /**\n * The form that called this field group.\n */\n readonly form: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >\n\n readonly fieldsMap: TFields\n\n /**\n * Get the true name of the field. Not required within `Field` or `AppField`.\n * @private\n */\n getFormFieldName = <TField extends DeepKeys<TFieldGroupData>>(\n subfield: TField,\n ): DeepKeys<TFormData> => {\n if (typeof this.fieldsMap === 'string') {\n return concatenatePaths(this.fieldsMap, subfield)\n }\n\n const firstAccessor = makePathArray(subfield)[0]\n if (typeof firstAccessor !== 'string') {\n // top-level arrays cannot be mapped\n return ''\n }\n\n const restOfPath = subfield.slice(firstAccessor.length)\n const formMappedPath =\n // TFields is either a string or this. See guard above.\n (this.fieldsMap as FieldsMap<TFormData, TFieldGroupData>)[\n firstAccessor as keyof TFieldGroupData\n ]\n\n return concatenatePaths(formMappedPath, restOfPath)\n }\n\n /**\n * Get the field options with the true form DeepKeys for validators\n * @private\n */\n getFormFieldOptions = <\n TOptions extends FieldOptions<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n >(\n props: TOptions,\n ): TOptions => {\n const newProps = { ...props }\n const validators = newProps.validators\n\n newProps.name = this.getFormFieldName(props.name)\n\n if (\n validators &&\n (validators.onChangeListenTo || validators.onBlurListenTo)\n ) {\n const newValidators = { ...validators }\n\n const remapListenTo = (listenTo: DeepKeys<any>[] | undefined) => {\n if (!listenTo) return undefined\n return listenTo.map((localFieldName) =>\n this.getFormFieldName(localFieldName),\n )\n }\n\n newValidators.onChangeListenTo = remapListenTo(\n validators.onChangeListenTo,\n )\n newValidators.onBlurListenTo = remapListenTo(validators.onBlurListenTo)\n\n newProps.validators = newValidators\n }\n\n return newProps\n }\n\n store: ReadonlyStore<FieldGroupState<TFieldGroupData>>\n\n get state() {\n return this.store.state\n }\n\n /**\n * Constructs a new `FieldGroupApi` instance with the given form options.\n */\n constructor(\n opts: FieldGroupOptions<\n TFormData,\n TFieldGroupData,\n TFields,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) {\n if (opts.form instanceof FieldGroupApi) {\n const group = opts.form\n this.form = group.form as never\n\n // the DeepKey is already namespaced, so we need to ensure that we reference\n // the form and not the group\n if (typeof opts.fields === 'string') {\n this.fieldsMap = group.getFormFieldName(opts.fields) as TFields\n } else {\n // TypeScript has a tough time with generics being a union for some reason\n const fields = {\n ...(opts.fields as FieldsMap<TFormData, TFieldGroupData>),\n }\n for (const key in fields) {\n fields[key] = group.getFormFieldName(fields[key]) as never\n }\n this.fieldsMap = fields as never\n }\n } else {\n this.form = opts.form\n this.fieldsMap = opts.fields\n }\n\n this.store = createStore(() => {\n const currFormStore = this.form.store.get()\n let values: TFieldGroupData\n if (typeof this.fieldsMap === 'string') {\n // all values live at that name, so we can directly fetch it\n values = getBy(currFormStore.values, this.fieldsMap)\n } else {\n // we need to fetch the values from all places where they were mapped from\n values = {} as never\n const fields: Record<keyof TFieldGroupData, string> = this\n .fieldsMap as never\n for (const key in fields) {\n values[key] = getBy(currFormStore.values, fields[key])\n }\n }\n\n return {\n values,\n }\n })\n }\n\n /**\n * Mounts the field group instance to listen to value changes.\n *\n * TODO: Remove\n */\n mount = () => {\n return () => {}\n }\n\n /**\n * Validates the children of a specified array in the form starting from a given index until the end using the correct handlers for a given validation type.\n */\n validateArrayFieldsStartingFrom = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n cause: ValidationCause,\n ) => {\n return this.form.validateArrayFieldsStartingFrom(\n this.getFormFieldName(field),\n index,\n cause,\n )\n }\n\n /**\n * Validates a specified field in the form using the correct handlers for a given validation type.\n */\n validateField = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n cause: ValidationCause,\n ) => {\n return this.form.validateField(this.getFormFieldName(field), cause)\n }\n\n /**\n * Handles the form submission, performs validation, and calls the appropriate onSubmit or onSubmitInvalid callbacks.\n */\n handleSubmit(): Promise<void>\n handleSubmit(submitMeta: TSubmitMeta): Promise<void>\n async handleSubmit(submitMeta?: TSubmitMeta): Promise<void> {\n // cast is required since the implementation isn't one of the two overloads\n return this.form.handleSubmit(submitMeta as any)\n }\n\n /**\n * Gets the value of the specified field.\n */\n getFieldValue = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n ): DeepValue<TFieldGroupData, TField> => {\n return this.form.getFieldValue(this.getFormFieldName(field)) as DeepValue<\n TFieldGroupData,\n TField\n >\n }\n\n /**\n * Gets the metadata of the specified field.\n */\n getFieldMeta = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.getFieldMeta(this.getFormFieldName(field))\n }\n\n /**\n * Updates the metadata of the specified field.\n */\n setFieldMeta = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n updater: Updater<AnyFieldMetaBase>,\n ) => {\n return this.form.setFieldMeta(this.getFormFieldName(field), updater)\n }\n\n /**\n * Sets the value of the specified field and optionally updates the touched state.\n */\n setFieldValue = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n updater: Updater<DeepValue<TFieldGroupData, TField>>,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.setFieldValue(\n this.getFormFieldName(field) as never,\n updater as never,\n opts,\n )\n }\n\n /**\n * Delete a field and its subfields.\n */\n deleteField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.deleteField(this.getFormFieldName(field))\n }\n\n /**\n * Pushes a value into an array field.\n */\n pushFieldValue = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.pushFieldValue(\n this.getFormFieldName(field),\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Insert a value into an array field at the specified index.\n */\n insertFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.insertFieldValue(\n this.getFormFieldName(field),\n index,\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Replaces a value into an array field at the specified index.\n */\n replaceFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.replaceFieldValue(\n this.getFormFieldName(field),\n index,\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Removes a value from an array field at the specified index.\n */\n removeFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.removeFieldValue(this.getFormFieldName(field), index, opts)\n }\n\n /**\n * Swaps the values at the specified indices within an array field.\n */\n swapFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.swapFieldValues(\n this.getFormFieldName(field),\n index1,\n index2,\n opts,\n )\n }\n\n /**\n * Moves the value at the first specified index to the second specified index within an array field.\n */\n moveFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.moveFieldValues(\n this.getFormFieldName(field),\n index1,\n index2,\n opts,\n )\n }\n\n clearFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.clearFieldValues(this.getFormFieldName(field), opts)\n }\n\n /**\n * Resets the field value and meta to default state\n */\n resetField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.resetField(this.getFormFieldName(field))\n }\n\n validateAllFields = (cause: ValidationCause) =>\n this.form.validateAllFields(cause)\n}\n"],"names":["concatenatePaths","makePathArray","opts","createStore","getBy"],"mappings":"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"}
{"version":3,"file":"FieldGroupApi.cjs","sources":["../../src/FieldGroupApi.ts"],"sourcesContent":["import { createStore } from '@tanstack/store'\nimport { concatenatePaths, getBy, makePathArray } from './utils'\nimport type {\n AnyFieldLikeMetaBase,\n FormLikeAPI,\n UpdateMetaOptions,\n ValidationCause,\n} from './types'\nimport type { ReadonlyStore } from '@tanstack/store'\nimport type { Updater } from './utils'\nimport type {\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\nimport type { FieldOptions } from './FieldApi'\nimport type {\n DeepKeys,\n DeepKeysOfType,\n DeepValue,\n FieldsMap,\n} from './util-types'\n\nexport type AnyFieldGroupApi = FieldGroupApi<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\nexport interface FieldGroupState<in out TFieldGroupData> {\n /**\n * The current values of the field group\n */\n values: TFieldGroupData\n}\n\n/**\n * An object representing the options for a field group.\n */\nexport interface FieldGroupOptions<\n in out TFormData,\n in out TFieldGroupData,\n in out TFields extends\n | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n | FieldsMap<TFormData, TFieldGroupData>,\n in out TOnMount extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChange extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TSubmitMeta = never,\n> {\n form:\n | FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >\n | FieldGroupApi<\n any,\n TFormData,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n TSubmitMeta\n >\n /**\n * The path to the field group data.\n */\n fields: TFields\n /**\n * The expected subsetValues that the form must provide.\n */\n defaultValues?: TFieldGroupData\n /**\n * onSubmitMeta, the data passed from the handleSubmit handler, to the onSubmit function props\n */\n onSubmitMeta?: TSubmitMeta\n}\n\nexport class FieldGroupApi<\n in out TFormData,\n in out TFieldGroupData,\n in out TFields extends\n | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n | FieldsMap<TFormData, TFieldGroupData>,\n in out TOnMount extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChange extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TSubmitMeta = never,\n> implements FormLikeAPI<TFieldGroupData, TSubmitMeta> {\n /**\n * The form that called this field group.\n */\n readonly form: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >\n\n readonly fieldsMap: TFields\n\n /**\n * Get the true name of the field. Not required within `Field` or `AppField`.\n * @private\n */\n getFormFieldName = <TField extends DeepKeys<TFieldGroupData>>(\n subfield: TField,\n ): DeepKeys<TFormData> => {\n if (typeof this.fieldsMap === 'string') {\n return concatenatePaths(this.fieldsMap, subfield)\n }\n\n const firstAccessor = makePathArray(subfield)[0]\n if (typeof firstAccessor !== 'string') {\n // top-level arrays cannot be mapped\n return ''\n }\n\n const restOfPath = subfield.slice(firstAccessor.length)\n const formMappedPath =\n // TFields is either a string or this. See guard above.\n (this.fieldsMap as FieldsMap<TFormData, TFieldGroupData>)[\n firstAccessor as keyof TFieldGroupData\n ]\n\n return concatenatePaths(formMappedPath, restOfPath)\n }\n\n /**\n * Get the field options with the true form DeepKeys for validators\n * @private\n */\n getFormFieldOptions = <\n TOptions extends FieldOptions<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n >(\n props: TOptions,\n ): TOptions => {\n const newProps = { ...props }\n const validators = newProps.validators\n\n newProps.name = this.getFormFieldName(props.name)\n\n if (\n validators &&\n (validators.onChangeListenTo || validators.onBlurListenTo)\n ) {\n const newValidators = { ...validators }\n\n const remapListenTo = (listenTo: DeepKeys<any>[] | undefined) => {\n if (!listenTo) return undefined\n return listenTo.map((localFieldName) =>\n this.getFormFieldName(localFieldName),\n )\n }\n\n newValidators.onChangeListenTo = remapListenTo(\n validators.onChangeListenTo,\n )\n newValidators.onBlurListenTo = remapListenTo(validators.onBlurListenTo)\n\n newProps.validators = newValidators\n }\n\n return newProps\n }\n\n store: ReadonlyStore<FieldGroupState<TFieldGroupData>>\n\n get state() {\n return this.store.state\n }\n\n /**\n * Constructs a new `FieldGroupApi` instance with the given form options.\n */\n constructor(\n opts: FieldGroupOptions<\n TFormData,\n TFieldGroupData,\n TFields,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) {\n if (opts.form instanceof FieldGroupApi) {\n const group = opts.form\n this.form = group.form as never\n\n // the DeepKey is already namespaced, so we need to ensure that we reference\n // the form and not the group\n if (typeof opts.fields === 'string') {\n this.fieldsMap = group.getFormFieldName(opts.fields) as TFields\n } else {\n // TypeScript has a tough time with generics being a union for some reason\n const fields = {\n ...(opts.fields as FieldsMap<TFormData, TFieldGroupData>),\n }\n for (const key in fields) {\n fields[key] = group.getFormFieldName(fields[key]) as never\n }\n this.fieldsMap = fields as never\n }\n } else {\n this.form = opts.form\n this.fieldsMap = opts.fields\n }\n\n this.store = createStore(() => {\n const currFormStore = this.form.store.get()\n let values: TFieldGroupData\n if (typeof this.fieldsMap === 'string') {\n // all values live at that name, so we can directly fetch it\n values = getBy(currFormStore.values, this.fieldsMap)\n } else {\n // we need to fetch the values from all places where they were mapped from\n values = {} as never\n const fields: Record<keyof TFieldGroupData, string> = this\n .fieldsMap as never\n for (const key in fields) {\n values[key] = getBy(currFormStore.values, fields[key])\n }\n }\n\n return {\n values,\n }\n })\n }\n\n /**\n * Mounts the field group instance to listen to value changes.\n *\n * TODO: Remove\n */\n mount = () => {\n return () => {}\n }\n\n /**\n * Validates the children of a specified array in the form starting from a given index until the end using the correct handlers for a given validation type.\n */\n validateArrayFieldsStartingFrom = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n cause: ValidationCause,\n ) => {\n return this.form.validateArrayFieldsStartingFrom(\n this.getFormFieldName(field),\n index,\n cause,\n )\n }\n\n /**\n * Validates a specified field in the form using the correct handlers for a given validation type.\n */\n validateField = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n cause: ValidationCause,\n ) => {\n return this.form.validateField(this.getFormFieldName(field), cause)\n }\n\n /**\n * Handles the form submission, performs validation, and calls the appropriate onSubmit or onSubmitInvalid callbacks.\n */\n handleSubmit(): Promise<void>\n handleSubmit(submitMeta: TSubmitMeta): Promise<void>\n async handleSubmit(submitMeta?: TSubmitMeta): Promise<void> {\n // cast is required since the implementation isn't one of the two overloads\n return this.form.handleSubmit(submitMeta as any)\n }\n\n /**\n * Gets the value of the specified field.\n */\n getFieldValue = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n ): DeepValue<TFieldGroupData, TField> => {\n return this.form.getFieldValue(this.getFormFieldName(field)) as DeepValue<\n TFieldGroupData,\n TField\n >\n }\n\n /**\n * Gets the metadata of the specified field.\n */\n getFieldMeta = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.getFieldMeta(this.getFormFieldName(field))\n }\n\n /**\n * Updates the metadata of the specified field.\n */\n setFieldMeta = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n updater: Updater<AnyFieldLikeMetaBase>,\n ) => {\n return this.form.setFieldMeta(this.getFormFieldName(field), updater)\n }\n\n /**\n * Sets the value of the specified field and optionally updates the touched state.\n */\n setFieldValue = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n updater: Updater<DeepValue<TFieldGroupData, TField>>,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.setFieldValue(\n this.getFormFieldName(field) as never,\n updater as never,\n opts,\n )\n }\n\n /**\n * Delete a field and its subfields.\n */\n deleteField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.deleteField(this.getFormFieldName(field))\n }\n\n /**\n * Pushes a value into an array field.\n */\n pushFieldValue = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.pushFieldValue(\n this.getFormFieldName(field),\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Insert a value into an array field at the specified index.\n */\n insertFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.insertFieldValue(\n this.getFormFieldName(field),\n index,\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Replaces a value into an array field at the specified index.\n */\n replaceFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.replaceFieldValue(\n this.getFormFieldName(field),\n index,\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Removes a value from an array field at the specified index.\n */\n removeFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.removeFieldValue(this.getFormFieldName(field), index, opts)\n }\n\n /**\n * Swaps the values at the specified indices within an array field.\n */\n swapFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.swapFieldValues(\n this.getFormFieldName(field),\n index1,\n index2,\n opts,\n )\n }\n\n /**\n * Moves the value at the first specified index to the second specified index within an array field.\n */\n moveFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.moveFieldValues(\n this.getFormFieldName(field),\n index1,\n index2,\n opts,\n )\n }\n\n clearFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.clearFieldValues(this.getFormFieldName(field), opts)\n }\n\n /**\n * Resets the field value and meta to default state\n */\n resetField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.resetField(this.getFormFieldName(field))\n }\n\n validateAllFields = (cause: ValidationCause) =>\n this.form.validateAllFields(cause)\n}\n"],"names":["concatenatePaths","makePathArray","opts","createStore","getBy"],"mappings":"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"}

@@ -0,7 +1,7 @@

import { AnyFieldLikeMetaBase, FormLikeAPI, UpdateMetaOptions, ValidationCause } from './types.cjs';
import { ReadonlyStore } from '@tanstack/store';
import { Updater } from './utils.cjs';
import { FormApi, FormAsyncValidateOrFn, FormValidateOrFn } from './FormApi.cjs';
import { AnyFieldMetaBase, FieldOptions } from './FieldApi.cjs';
import { FieldOptions } from './FieldApi.cjs';
import { DeepKeys, DeepKeysOfType, DeepValue, FieldsMap } from './util-types.cjs';
import { FieldManipulator, UpdateMetaOptions, ValidationCause } from './types.cjs';
export type AnyFieldGroupApi = FieldGroupApi<any, any, any, any, any, any, any, any, any, any, any, any, any, any>;

@@ -32,3 +32,3 @@ export interface FieldGroupState<in out TFieldGroupData> {

}
export declare class FieldGroupApi<in out TFormData, in out TFieldGroupData, in out TFields extends DeepKeysOfType<TFormData, TFieldGroupData | null | undefined> | FieldsMap<TFormData, TFieldGroupData>, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>, in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, in out TSubmitMeta = never> implements FieldManipulator<TFieldGroupData, TSubmitMeta> {
export declare class FieldGroupApi<in out TFormData, in out TFieldGroupData, in out TFields extends DeepKeysOfType<TFormData, TFieldGroupData | null | undefined> | FieldsMap<TFormData, TFieldGroupData>, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>, in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, in out TSubmitMeta = never> implements FormLikeAPI<TFieldGroupData, TSubmitMeta> {
/**

@@ -81,7 +81,7 @@ * The form that called this field group.

*/
getFieldMeta: <TField extends DeepKeys<TFieldGroupData>>(field: TField) => import('./FieldApi.cjs').AnyFieldMeta | undefined;
getFieldMeta: <TField extends DeepKeys<TFieldGroupData>>(field: TField) => import('./types.cjs').AnyFieldLikeMeta | undefined;
/**
* Updates the metadata of the specified field.
*/
setFieldMeta: <TField extends DeepKeys<TFieldGroupData>>(field: TField, updater: Updater<AnyFieldMetaBase>) => void;
setFieldMeta: <TField extends DeepKeys<TFieldGroupData>>(field: TField, updater: Updater<AnyFieldLikeMetaBase>) => void;
/**

@@ -88,0 +88,0 @@ * Sets the value of the specified field and optionally updates the touched state.

@@ -14,2 +14,3 @@ "use strict";

fieldMetaBase: defaultState.fieldMetaBase ?? {},
formGroupStateBase: defaultState.formGroupStateBase ?? {},
isSubmitted: defaultState.isSubmitted ?? false,

@@ -37,2 +38,3 @@ isSubmitting: defaultState.isSubmitting ?? false,

this.fieldInfo = {};
this.formGroupApis = /* @__PURE__ */ new Set();
this.mount = () => {

@@ -170,6 +172,9 @@ const cleanupDevtoolBroadcast = this.store.subscribe(() => {

Promise.resolve().then(
() => fieldInstance.validate(cause, { skipFormValidation: true })
() => fieldInstance.validate(cause, {
skipFormValidation: true,
skipGroupValidation: true
})
)
);
if (!field.instance.state.meta.isTouched) {
if (!field.instance.store.state.meta.isTouched) {
field.instance.setMeta((prev) => ({ ...prev, isTouched: true }));

@@ -215,3 +220,3 @@ }

}
if (!fieldInstance.state.meta.isTouched) {
if (!fieldInstance.store.state.meta.isTouched) {
fieldInstance.setMeta((prev) => ({ ...prev, isTouched: true }));

@@ -221,6 +226,7 @@ }

};
this.validateSync = (cause) => {
this.validateSync = (cause, validateOpts) => {
const validates = utils.getSyncValidatorArray(cause, {
...this.options,
form: this,
group: validateOpts?.group,
validationLogic: this.options.validationLogic || ValidationLogic.defaultValidationLogic

@@ -244,6 +250,11 @@ });

const errorMapKey = getErrorMapKey(validateObj.cause);
const allFieldsToProcess = /* @__PURE__ */ new Set([
let allFieldsToProcess = /* @__PURE__ */ new Set([
...Object.keys(this.state.fieldMeta),
...Object.keys(fieldErrors || {})
]);
if (validateOpts?.filterFieldNames) {
allFieldsToProcess = new Set(
[...allFieldsToProcess].filter(validateOpts.filterFieldNames)
);
}
for (const field of allFieldsToProcess) {

@@ -289,10 +300,12 @@ if (this.baseStore.state.fieldMetaBase[field] === void 0 && !fieldErrors?.[field]) {

}
if (this.state.errorMap?.[errorMapKey] !== formError) {
this.baseStore.setState((prev) => ({
...prev,
errorMap: {
...prev.errorMap,
[errorMapKey]: formError
}
}));
if (!validateOpts?.dontUpdateFormErrorMap) {
if (this.state.errorMap?.[errorMapKey] !== formError) {
this.baseStore.setState((prev) => ({
...prev,
errorMap: {
...prev.errorMap,
[errorMapKey]: formError
}
}));
}
}

@@ -303,2 +316,5 @@ if (formError || fieldErrors) {

}
if (validateOpts?.dontUpdateFormErrorMap) {
return;
}
const submitErrKey = getErrorMapKey("submit");

@@ -333,6 +349,7 @@ if (

};
this.validateAsync = async (cause) => {
this.validateAsync = async (cause, validateOpts) => {
const validates = utils.getAsyncValidatorArray(cause, {
...this.options,
form: this,
group: validateOpts?.group,
validationLogic: this.options.validationLogic || ValidationLogic.defaultValidationLogic

@@ -390,5 +407,7 @@ });

const errorMapKey = getErrorMapKey(validateObj.cause);
for (const field of Object.keys(
this.state.fieldMeta
)) {
let fields = Object.keys(this.state.fieldMeta);
if (validateOpts?.filterFieldNames) {
fields = fields.filter(validateOpts.filterFieldNames);
}
for (const field of fields) {
if (this.baseStore.state.fieldMetaBase[field] === void 0) {

@@ -413,6 +432,3 @@ continue;

});
if (
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
currentErrorMap?.[errorMapKey] !== newErrorValue
) {
if (currentErrorMap?.[errorMapKey] !== newErrorValue) {
this.setFieldMeta(field, (prev) => ({

@@ -431,9 +447,11 @@ ...prev,

}
this.baseStore.setState((prev) => ({
...prev,
errorMap: {
...prev.errorMap,
[errorMapKey]: formError
}
}));
if (!validateOpts?.dontUpdateFormErrorMap) {
this.baseStore.setState((prev) => ({
...prev,
errorMap: {
...prev.errorMap,
[errorMapKey]: formError
}
}));
}
resolve(

@@ -471,8 +489,11 @@ fieldErrorsFromFormValidators ? { fieldErrors: fieldErrorsFromFormValidators, errorMapKey } : void 0

};
this.validate = (cause) => {
const { hasErrored, fieldsErrorMap } = this.validateSync(cause);
this.validate = (cause, validateOpts) => {
const { hasErrored, fieldsErrorMap } = this.validateSync(
cause,
validateOpts
);
if (hasErrored && !this.options.asyncAlways) {
return fieldsErrorMap;
}
return this.validateAsync(cause);
return this.validateAsync(cause, validateOpts);
};

@@ -493,3 +514,3 @@ this._handleSubmit = async (submitMeta) => {

if (!field.instance) return;
if (!field.instance.state.meta.isTouched) {
if (!field.instance.store.state.meta.isTouched) {
field.instance.setMeta((prev) => ({ ...prev, isTouched: true }));

@@ -550,6 +571,3 @@ }

(field) => {
field.instance?.options.listeners?.onSubmit?.({
value: field.instance.state.value,
fieldApi: field.instance
});
field.instance?.triggerOnSubmitListener();
}

@@ -600,2 +618,5 @@ );

};
this.getFormGroupMeta = (name) => {
return this.formGroupMetaDerived.state[name];
};
this.getFieldInfo = (field) => {

@@ -994,2 +1015,103 @@ return this.fieldInfo[field] ||= {

);
this.formGroupMetaDerived = store.createStore(
(prevVal) => {
const currBaseStore = this.baseStore.get();
const currFieldMeta = this.fieldMetaDerived.get();
const result = {};
for (const group of this.formGroupApis) {
const groupName = group.name;
const lifecycle = currBaseStore.formGroupStateBase[groupName] ?? {
isSubmitted: false,
isSubmitting: false,
isValidating: false,
submissionAttempts: 0,
isSubmitSuccessful: false
};
const ownFieldMeta = currFieldMeta[groupName];
let isFieldsValidating = false;
let isFieldsValid = true;
let aggIsTouched = false;
let aggIsBlurred = false;
let aggIsDefaultValue = true;
let aggIsDirty = false;
for (const fieldName in currFieldMeta) {
if (fieldName === groupName) continue;
if (!utils.isFieldInGroup(groupName, fieldName)) continue;
const m = currFieldMeta[fieldName];
if (!m) continue;
if (m.isValidating) isFieldsValidating = true;
if (!m.isValid) isFieldsValid = false;
if (m.isTouched) aggIsTouched = true;
if (m.isBlurred) aggIsBlurred = true;
if (!m.isDefaultValue) aggIsDefaultValue = false;
if (m.isDirty) aggIsDirty = true;
}
const isPristine = !aggIsDirty;
const isValidating = !!isFieldsValidating || lifecycle.isValidating;
const errorMap = ownFieldMeta?.errorMap ?? {};
const errorSourceMap = ownFieldMeta?.errorSourceMap ?? {};
const hasOnMountError = Boolean(
errorMap.onMount || Object.entries(currFieldMeta).some(
([fieldName, field]) => field && fieldName !== groupName && utils.isFieldInGroup(groupName, fieldName) && field.errorMap.onMount
)
);
const prevGroupMeta = prevVal?.[groupName];
let errors = prevGroupMeta?.errors ?? [];
if (!prevGroupMeta || prevGroupMeta.__srcErrorMap !== errorMap) {
errors = Object.values(errorMap).reduce((acc, curr) => {
if (curr === void 0) return acc;
if (curr && typeof curr === "object" && "fields" in curr) {
const groupErr = curr.group;
if (groupErr !== void 0) acc.push(groupErr);
return acc;
}
acc.push(curr);
return acc;
}, []);
}
const isGroupValid = errors.length === 0;
const isValid = isFieldsValid && isGroupValid;
const submitInvalid = group.options.canSubmitWhenInvalid ?? false;
const canSubmit = lifecycle.submissionAttempts === 0 && !aggIsTouched && !hasOnMountError || !isValidating && !lifecycle.isSubmitting && isValid || submitInvalid;
if (prevGroupMeta && prevGroupMeta.errorMap === errorMap && prevGroupMeta.errorSourceMap === errorSourceMap && prevGroupMeta.errors === errors && prevGroupMeta.isFieldsValidating === isFieldsValidating && prevGroupMeta.isFieldsValid === isFieldsValid && prevGroupMeta.isGroupValid === isGroupValid && prevGroupMeta.isValid === isValid && prevGroupMeta.canSubmit === canSubmit && prevGroupMeta.isTouched === aggIsTouched && prevGroupMeta.isBlurred === aggIsBlurred && prevGroupMeta.isPristine === isPristine && prevGroupMeta.isDefaultValue === aggIsDefaultValue && prevGroupMeta.isDirty === aggIsDirty && prevGroupMeta.isValidating === isValidating && prevGroupMeta.isSubmitting === lifecycle.isSubmitting && prevGroupMeta.isSubmitted === lifecycle.isSubmitted && prevGroupMeta.submissionAttempts === lifecycle.submissionAttempts && prevGroupMeta.isSubmitSuccessful === lifecycle.isSubmitSuccessful) {
result[groupName] = prevGroupMeta;
continue;
}
const meta = {
// Submission lifecycle (spread first; `isValidating` below
// intentionally overrides `lifecycle.isValidating` with the
// OR of group-level + descendant-field validating).
...lifecycle,
// Field-meta-base fields (so `setMeta` updates can roundtrip
// through `state.meta`).
errorMap,
errorSourceMap,
_arrayVersion: ownFieldMeta?._arrayVersion ?? 0,
// Aggregated descendant booleans (override field-level meaning
// for groups — a group's "field" itself never receives input).
isTouched: aggIsTouched,
isBlurred: aggIsBlurred,
isDirty: aggIsDirty,
isPristine,
isDefaultValue: aggIsDefaultValue,
// Aggregated validity
isValid,
errors,
isValidating,
// Group-only flags
isFieldsValidating,
isFieldsValid,
isGroupValid,
canSubmit
};
Object.defineProperty(meta, "__srcErrorMap", {
value: errorMap,
enumerable: false,
configurable: true
});
result[groupName] = meta;
}
return result;
}
);
let prevBaseStoreForStore = void 0;

@@ -996,0 +1118,0 @@ this.store = store.createStore((prevVal) => {

@@ -0,6 +1,7 @@

import { AnyFieldLikeMeta, AnyFieldLikeMetaBase, ExtractGlobalFormError, FieldInfo, FormLikeAPI, FormValidationError, FormValidationErrorMap, ListenerCause, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap, ValidationErrorMapKeys } from './types.cjs';
import { ReadonlyStore, Store } from '@tanstack/store';
import { ValidationLogicFn } from './ValidationLogic.cjs';
import { StandardSchemaV1, StandardSchemaV1Issue, TStandardSchemaValidatorValue } from './standardSchemaValidator.cjs';
import { AnyFieldApi, AnyFieldMeta, AnyFieldMetaBase, FieldApi } from './FieldApi.cjs';
import { ExtractGlobalFormError, FieldManipulator, FormValidationError, FormValidationErrorMap, ListenerCause, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap, ValidationErrorMapKeys } from './types.cjs';
import { AnyFieldApi } from './FieldApi.cjs';
import { AnyFormGroupApi, AnyFormGroupMeta, FormGroupState } from './FormGroupApi.cjs';
import { DeepKeys, DeepKeysOfType, DeepValue, RejectPromiseValidator } from './util-types.cjs';

@@ -77,8 +78,15 @@ import { Updater } from './utils.cjs';

}
interface FormListenersPropsGroup<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnDynamic extends undefined | FormValidateOrFn<TFormData>, TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, TSubmitMeta = never> {
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
groupApi: AnyFormGroupApi;
}
interface FormListenersPropsField<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnDynamic extends undefined | FormValidateOrFn<TFormData>, TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, TSubmitMeta = never> {
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
fieldApi: AnyFieldApi;
}
export interface FormListeners<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnDynamic extends undefined | FormValidateOrFn<TFormData>, TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, TSubmitMeta = never> {
onChange?: (props: {
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
fieldApi: AnyFieldApi;
}) => void;
onChange?: (props: FormListenersPropsField<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>) => void;
onChangeDebounceMs?: number;
onChangeGroup?: (props: FormListenersPropsGroup<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>) => void;
onChangeGroupDebounceMs?: number;
onBlur?: (props: {

@@ -96,6 +104,4 @@ formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;

}) => void;
onFieldUnmount?: (props: {
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
fieldApi: AnyFieldApi;
}) => void;
onFieldUnmount?: (props: FormListenersPropsField<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>) => void;
onGroupUnmount?: (props: FormListenersPropsGroup<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>) => void;
}

@@ -177,15 +183,2 @@ /**

/**
* An object representing the field information for a specific field within the form.
*/
export type FieldInfo<TFormData> = {
/**
* An instance of the FieldAPI.
*/
instance: FieldApi<TFormData, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any> | null;
/**
* A record of field validation internal handling.
*/
validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>;
};
/**
* An object representing the current state of the form.

@@ -209,4 +202,11 @@ */

*/
fieldMetaBase: Partial<Record<DeepKeys<TFormData>, AnyFieldMetaBase>>;
fieldMetaBase: Partial<Record<DeepKeys<TFormData>, AnyFieldLikeMetaBase>>;
/**
* A record of submission lifecycle state for each mounted `FormGroupApi`,
* keyed by the group's fully-qualified field name. Stored on the form so
* group-level state can be read from `FormApi` without having to walk the
* mounted group instances.
*/
formGroupStateBase: Partial<Record<string, FormGroupState>>;
/**
* A boolean indicating if the form is currently in the process of being submitted after `handleSubmit` is called.

@@ -302,3 +302,3 @@ *

*/
fieldMeta: Partial<Record<DeepKeys<TFormData>, AnyFieldMeta>>;
fieldMeta: Partial<Record<DeepKeys<TFormData>, AnyFieldLikeMeta>>;
};

@@ -314,2 +314,7 @@ export interface FormState<in out TFormData, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>, in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>> extends BaseFormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>, DerivedFormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer> {

export type AnyFormApi = FormApi<any, any, any, any, any, any, any, any, any, any, any, any>;
interface ValidateOpts<TFormData> {
dontUpdateFormErrorMap?: boolean;
filterFieldNames?: (fieldName: DeepKeys<TFormData>) => boolean;
group?: AnyFormGroupApi;
}
/**

@@ -326,3 +331,3 @@ * We cannot use methods and must use arrow functions. Otherwise, our React adapters

*/
export declare class FormApi<in out TFormData, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>, in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, in out TSubmitMeta = never> implements FieldManipulator<TFormData, TSubmitMeta> {
export declare class FormApi<in out TFormData, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>, in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, in out TSubmitMeta = never> implements FormLikeAPI<TFormData, TSubmitMeta> {
/**

@@ -334,2 +339,10 @@ * The options for the form.

fieldMetaDerived: Store<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>['fieldMeta']>;
/**
* A derived store of every mounted `FormGroupApi`'s `meta`, keyed by
* group name. Mirrors `fieldMetaDerived` for fields: per-group `meta`
* is computed once on the form (from `baseStore.formGroupStateBase`,
* `fieldMetaDerived`, and the registered `formGroupApis`) so reads
* from a `FormGroupApi.store` instance stay minimal.
*/
formGroupMetaDerived: ReadonlyStore<Record<string, AnyFormGroupMeta>>;
store: ReadonlyStore<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>>;

@@ -340,2 +353,8 @@ /**

fieldInfo: Partial<Record<DeepKeys<TFormData>, FieldInfo<TFormData>>>;
/**
* The set of currently-mounted `FormGroupApi` instances belonging to
* this form. Used by `FieldApi.validate` to cascade field-level changes
* into the validators of any group that encompasses the field.
*/
formGroupApis: Set<AnyFormGroupApi>;
get state(): FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>;

@@ -405,3 +424,3 @@ /**

*/
validateSync: (cause: ValidationCause) => {
validateSync: (cause: ValidationCause, validateOpts?: ValidateOpts<TFormData>) => {
hasErrored: boolean;

@@ -413,7 +432,7 @@ fieldsErrorMap: FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>;

*/
validateAsync: (cause: ValidationCause) => Promise<FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>>;
validateAsync: (cause: ValidationCause, validateOpts?: ValidateOpts<TFormData>) => Promise<FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>>;
/**
* @private
*/
validate: (cause: ValidationCause) => FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync> | Promise<FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>>;
validate: (cause: ValidationCause, validateOpts?: ValidateOpts<TFormData>) => FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync> | Promise<FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>>;
handleSubmit(): Promise<void>;

@@ -432,4 +451,10 @@ handleSubmit(submitMeta: TSubmitMeta): Promise<void>;

*/
getFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField) => AnyFieldMeta | undefined;
getFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField) => AnyFieldLikeMeta | undefined;
/**
* Gets the derived `meta` of the form group registered at the given
* name. Mirrors `getFieldMeta` for fields. Returns `undefined` if no
* `FormGroupApi` with that name is currently mounted.
*/
getFormGroupMeta: (name: string) => AnyFormGroupMeta | undefined;
/**
* Gets the field info of the specified field.

@@ -441,7 +466,7 @@ */

*/
setFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField, updater: Updater<AnyFieldMetaBase>) => void;
setFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField, updater: Updater<AnyFieldLikeMetaBase>) => void;
/**
* resets every field's meta
*/
resetFieldMeta: <TField extends DeepKeys<TFormData>>(fieldMeta: Partial<Record<TField, AnyFieldMeta>>) => Partial<Record<TField, AnyFieldMeta>>;
resetFieldMeta: <TField extends DeepKeys<TFormData>>(fieldMeta: Partial<Record<TField, AnyFieldLikeMeta>>) => Partial<Record<TField, AnyFieldLikeMeta>>;
/**

@@ -448,0 +473,0 @@ * Sets the value of the specified field and optionally updates the touched state.

@@ -5,2 +5,3 @@ "use strict";

const FieldApi = require("./FieldApi.cjs");
const FormGroupApi = require("./FormGroupApi.cjs");
const utils = require("./utils.cjs");

@@ -16,2 +17,4 @@ const mergeForm = require("./mergeForm.cjs");

exports.FieldApi = FieldApi.FieldApi;
exports.FormGroupApi = FormGroupApi.FormGroupApi;
exports.getDefaultFormGroupMeta = FormGroupApi.getDefaultFormGroupMeta;
exports.concatenatePaths = utils.concatenatePaths;

@@ -28,2 +31,3 @@ exports.createFieldMap = utils.createFieldMap;

exports.getSyncValidatorArray = utils.getSyncValidatorArray;
exports.isFieldInGroup = utils.isFieldInGroup;
exports.isGlobalFormValidationError = utils.isGlobalFormValidationError;

@@ -30,0 +34,0 @@ exports.isNonEmptyArray = utils.isNonEmptyArray;

@@ -1,1 +0,1 @@

{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
export * from './FormApi.cjs';
export * from './FieldApi.cjs';
export * from './FormGroupApi.cjs';
export * from './utils.cjs';

@@ -4,0 +5,0 @@ export * from './util-types.cjs';

@@ -1,1 +0,1 @@

{"version":3,"file":"metaHelper.cjs","sources":["../../src/metaHelper.ts"],"sourcesContent":["import type {\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\nimport type { AnyFieldMeta } from './FieldApi'\nimport type { DeepKeys } from './util-types'\n\ntype ValueFieldMode = 'insert' | 'remove' | 'swap' | 'move'\n\nexport const defaultFieldMeta: AnyFieldMeta = {\n isValidating: false,\n isTouched: false,\n isBlurred: false,\n isDirty: false,\n isPristine: true,\n isValid: true,\n isDefaultValue: true,\n errors: [],\n errorMap: {},\n errorSourceMap: {},\n _arrayVersion: 0,\n}\n\nexport function metaHelper<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n>(\n formApi: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n) {\n /**\n * Bump the `_arrayVersion` counter on the array field's meta. This\n * provides a cheap, structural signal that adapters can subscribe to in\n * order to trigger re-renders when the array is mutated in ways that\n * `length` alone cannot detect (e.g. swaps and moves).\n */\n function bumpArrayVersion(field: DeepKeys<TFormData>) {\n const currentMeta = formApi.getFieldMeta(field) ?? defaultFieldMeta\n formApi.setFieldMeta(field, {\n ...currentMeta,\n _arrayVersion: (currentMeta._arrayVersion || 0) + 1,\n })\n }\n\n /**\n * Handle the meta shift caused from moving a field from one index to another.\n */\n function handleArrayMove(\n field: DeepKeys<TFormData>,\n fromIndex: number,\n toIndex: number,\n ) {\n bumpArrayVersion(field)\n const affectedFields = getAffectedFields(field, fromIndex, 'move', toIndex)\n\n const startIndex = Math.min(fromIndex, toIndex)\n const endIndex = Math.max(fromIndex, toIndex)\n for (let i = startIndex; i <= endIndex; i++) {\n affectedFields.push(getFieldPath(field, i))\n }\n\n // Store the original field meta that will be reapplied at the destination index\n const fromFields = Object.keys(formApi.fieldInfo).reduce(\n (fieldMap, fieldKey) => {\n if (fieldKey.startsWith(getFieldPath(field, fromIndex))) {\n fieldMap.set(\n fieldKey as DeepKeys<TFormData>,\n formApi.getFieldMeta(fieldKey as DeepKeys<TFormData>),\n )\n }\n return fieldMap\n },\n new Map<DeepKeys<TFormData>, AnyFieldMeta | undefined>(),\n )\n\n shiftMeta(affectedFields, fromIndex < toIndex ? 'up' : 'down')\n\n // Reapply the stored field meta at the destination index\n Object.keys(formApi.fieldInfo)\n .filter((fieldKey) => fieldKey.startsWith(getFieldPath(field, toIndex)))\n .forEach((fieldKey) => {\n const fromKey = fieldKey.replace(\n getFieldPath(field, toIndex),\n getFieldPath(field, fromIndex),\n ) as DeepKeys<TFormData>\n\n const fromMeta = fromFields.get(fromKey)\n if (fromMeta) {\n formApi.setFieldMeta(fieldKey as DeepKeys<TFormData>, fromMeta)\n }\n })\n }\n\n /**\n * Handle the meta shift from removing a field at the specified index.\n */\n function handleArrayRemove(field: DeepKeys<TFormData>, index: number) {\n bumpArrayVersion(field)\n const affectedFields = getAffectedFields(field, index, 'remove')\n\n shiftMeta(affectedFields, 'up')\n }\n\n /**\n * Handle the meta shift from swapping two fields at the specified indeces.\n */\n function handleArraySwap(\n field: DeepKeys<TFormData>,\n index: number,\n secondIndex: number,\n ) {\n bumpArrayVersion(field)\n const affectedFields = getAffectedFields(field, index, 'swap', secondIndex)\n\n affectedFields.forEach((fieldKey) => {\n if (!fieldKey.toString().startsWith(getFieldPath(field, index))) {\n return\n }\n\n const swappedKey = fieldKey\n .toString()\n .replace(\n getFieldPath(field, index),\n getFieldPath(field, secondIndex),\n ) as DeepKeys<TFormData>\n\n const [meta1, meta2] = [\n formApi.getFieldMeta(fieldKey),\n formApi.getFieldMeta(swappedKey),\n ]\n\n if (meta1) formApi.setFieldMeta(swappedKey, meta1)\n if (meta2) formApi.setFieldMeta(fieldKey, meta2)\n })\n }\n\n /**\n * Handle the meta shift from inserting a field at the specified index.\n */\n function handleArrayInsert(field: DeepKeys<TFormData>, insertIndex: number) {\n bumpArrayVersion(field)\n const affectedFields = getAffectedFields(field, insertIndex, 'insert')\n\n shiftMeta(affectedFields, 'down')\n\n affectedFields.forEach((fieldKey) => {\n if (fieldKey.toString().startsWith(getFieldPath(field, insertIndex))) {\n formApi.setFieldMeta(fieldKey, getEmptyFieldMeta())\n }\n })\n }\n\n function getFieldPath(\n field: DeepKeys<TFormData>,\n index: number,\n ): DeepKeys<TFormData> {\n return `${field}[${index}]` as DeepKeys<TFormData>\n }\n\n function getAffectedFields(\n field: DeepKeys<TFormData>,\n index: number,\n mode: ValueFieldMode,\n secondIndex?: number,\n ): DeepKeys<TFormData>[] {\n const affectedFieldKeys = [getFieldPath(field, index)]\n\n switch (mode) {\n case 'swap':\n affectedFieldKeys.push(getFieldPath(field, secondIndex!))\n break\n case 'move': {\n const [startIndex, endIndex] = [\n Math.min(index, secondIndex!),\n Math.max(index, secondIndex!),\n ]\n for (let i = startIndex; i <= endIndex; i++) {\n affectedFieldKeys.push(getFieldPath(field, i))\n }\n break\n }\n default: {\n const currentValue = formApi.getFieldValue(field)\n const fieldItems = Array.isArray(currentValue)\n ? (currentValue as Array<unknown>).length\n : 0\n for (let i = index + 1; i < fieldItems; i++) {\n affectedFieldKeys.push(getFieldPath(field, i))\n }\n break\n }\n }\n\n return Object.keys(formApi.fieldInfo).filter((fieldKey) =>\n affectedFieldKeys.some((key) => fieldKey.startsWith(key)),\n ) as DeepKeys<TFormData>[]\n }\n\n function updateIndex(\n fieldKey: string,\n direction: 'up' | 'down',\n ): DeepKeys<TFormData> {\n return fieldKey.replace(/\\[(\\d+)\\]/, (_, num) => {\n const currIndex = parseInt(num, 10)\n const newIndex =\n direction === 'up' ? currIndex + 1 : Math.max(0, currIndex - 1)\n return `[${newIndex}]`\n }) as DeepKeys<TFormData>\n }\n\n function shiftMeta(fields: DeepKeys<TFormData>[], direction: 'up' | 'down') {\n const sortedFields = direction === 'up' ? fields : [...fields].reverse()\n\n sortedFields.forEach((fieldKey) => {\n const nextFieldKey = updateIndex(fieldKey.toString(), direction)\n const nextFieldMeta = formApi.getFieldMeta(nextFieldKey)\n if (nextFieldMeta) {\n formApi.setFieldMeta(fieldKey, nextFieldMeta)\n } else {\n formApi.setFieldMeta(fieldKey, getEmptyFieldMeta())\n }\n })\n }\n\n const getEmptyFieldMeta = (): AnyFieldMeta => defaultFieldMeta\n\n return {\n bumpArrayVersion,\n handleArrayMove,\n handleArrayRemove,\n handleArraySwap,\n handleArrayInsert,\n }\n}\n"],"names":[],"mappings":"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"}
{"version":3,"file":"metaHelper.cjs","sources":["../../src/metaHelper.ts"],"sourcesContent":["import type {\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\nimport type { DeepKeys } from './util-types'\nimport type { AnyFieldLikeMeta } from './types'\n\ntype ValueFieldMode = 'insert' | 'remove' | 'swap' | 'move'\n\nexport const defaultFieldMeta: AnyFieldLikeMeta = {\n isValidating: false,\n isTouched: false,\n isBlurred: false,\n isDirty: false,\n isPristine: true,\n isValid: true,\n isDefaultValue: true,\n errors: [],\n errorMap: {},\n errorSourceMap: {},\n _arrayVersion: 0,\n}\n\nexport function metaHelper<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n>(\n formApi: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n) {\n /**\n * Bump the `_arrayVersion` counter on the array field's meta. This\n * provides a cheap, structural signal that adapters can subscribe to in\n * order to trigger re-renders when the array is mutated in ways that\n * `length` alone cannot detect (e.g. swaps and moves).\n */\n function bumpArrayVersion(field: DeepKeys<TFormData>) {\n const currentMeta = formApi.getFieldMeta(field) ?? defaultFieldMeta\n formApi.setFieldMeta(field, {\n ...currentMeta,\n _arrayVersion: (currentMeta._arrayVersion || 0) + 1,\n })\n }\n\n /**\n * Handle the meta shift caused from moving a field from one index to another.\n */\n function handleArrayMove(\n field: DeepKeys<TFormData>,\n fromIndex: number,\n toIndex: number,\n ) {\n bumpArrayVersion(field)\n const affectedFields = getAffectedFields(field, fromIndex, 'move', toIndex)\n\n const startIndex = Math.min(fromIndex, toIndex)\n const endIndex = Math.max(fromIndex, toIndex)\n for (let i = startIndex; i <= endIndex; i++) {\n affectedFields.push(getFieldPath(field, i))\n }\n\n // Store the original field meta that will be reapplied at the destination index\n const fromFields = Object.keys(formApi.fieldInfo).reduce(\n (fieldMap, fieldKey) => {\n if (fieldKey.startsWith(getFieldPath(field, fromIndex))) {\n fieldMap.set(\n fieldKey as DeepKeys<TFormData>,\n formApi.getFieldMeta(fieldKey as DeepKeys<TFormData>),\n )\n }\n return fieldMap\n },\n new Map<DeepKeys<TFormData>, AnyFieldLikeMeta | undefined>(),\n )\n\n shiftMeta(affectedFields, fromIndex < toIndex ? 'up' : 'down')\n\n // Reapply the stored field meta at the destination index\n Object.keys(formApi.fieldInfo)\n .filter((fieldKey) => fieldKey.startsWith(getFieldPath(field, toIndex)))\n .forEach((fieldKey) => {\n const fromKey = fieldKey.replace(\n getFieldPath(field, toIndex),\n getFieldPath(field, fromIndex),\n ) as DeepKeys<TFormData>\n\n const fromMeta = fromFields.get(fromKey)\n if (fromMeta) {\n formApi.setFieldMeta(fieldKey as DeepKeys<TFormData>, fromMeta)\n }\n })\n }\n\n /**\n * Handle the meta shift from removing a field at the specified index.\n */\n function handleArrayRemove(field: DeepKeys<TFormData>, index: number) {\n bumpArrayVersion(field)\n const affectedFields = getAffectedFields(field, index, 'remove')\n\n shiftMeta(affectedFields, 'up')\n }\n\n /**\n * Handle the meta shift from swapping two fields at the specified indeces.\n */\n function handleArraySwap(\n field: DeepKeys<TFormData>,\n index: number,\n secondIndex: number,\n ) {\n bumpArrayVersion(field)\n const affectedFields = getAffectedFields(field, index, 'swap', secondIndex)\n\n affectedFields.forEach((fieldKey) => {\n if (!fieldKey.toString().startsWith(getFieldPath(field, index))) {\n return\n }\n\n const swappedKey = fieldKey\n .toString()\n .replace(\n getFieldPath(field, index),\n getFieldPath(field, secondIndex),\n ) as DeepKeys<TFormData>\n\n const [meta1, meta2] = [\n formApi.getFieldMeta(fieldKey),\n formApi.getFieldMeta(swappedKey),\n ]\n\n if (meta1) formApi.setFieldMeta(swappedKey, meta1)\n if (meta2) formApi.setFieldMeta(fieldKey, meta2)\n })\n }\n\n /**\n * Handle the meta shift from inserting a field at the specified index.\n */\n function handleArrayInsert(field: DeepKeys<TFormData>, insertIndex: number) {\n bumpArrayVersion(field)\n const affectedFields = getAffectedFields(field, insertIndex, 'insert')\n\n shiftMeta(affectedFields, 'down')\n\n affectedFields.forEach((fieldKey) => {\n if (fieldKey.toString().startsWith(getFieldPath(field, insertIndex))) {\n formApi.setFieldMeta(fieldKey, getEmptyFieldMeta())\n }\n })\n }\n\n function getFieldPath(\n field: DeepKeys<TFormData>,\n index: number,\n ): DeepKeys<TFormData> {\n return `${field}[${index}]` as DeepKeys<TFormData>\n }\n\n function getAffectedFields(\n field: DeepKeys<TFormData>,\n index: number,\n mode: ValueFieldMode,\n secondIndex?: number,\n ): DeepKeys<TFormData>[] {\n const affectedFieldKeys = [getFieldPath(field, index)]\n\n switch (mode) {\n case 'swap':\n affectedFieldKeys.push(getFieldPath(field, secondIndex!))\n break\n case 'move': {\n const [startIndex, endIndex] = [\n Math.min(index, secondIndex!),\n Math.max(index, secondIndex!),\n ]\n for (let i = startIndex; i <= endIndex; i++) {\n affectedFieldKeys.push(getFieldPath(field, i))\n }\n break\n }\n default: {\n const currentValue = formApi.getFieldValue(field)\n const fieldItems = Array.isArray(currentValue)\n ? (currentValue as Array<unknown>).length\n : 0\n for (let i = index + 1; i < fieldItems; i++) {\n affectedFieldKeys.push(getFieldPath(field, i))\n }\n break\n }\n }\n\n return Object.keys(formApi.fieldInfo).filter((fieldKey) =>\n affectedFieldKeys.some((key) => fieldKey.startsWith(key)),\n ) as DeepKeys<TFormData>[]\n }\n\n function updateIndex(\n fieldKey: string,\n direction: 'up' | 'down',\n ): DeepKeys<TFormData> {\n return fieldKey.replace(/\\[(\\d+)\\]/, (_, num) => {\n const currIndex = parseInt(num, 10)\n const newIndex =\n direction === 'up' ? currIndex + 1 : Math.max(0, currIndex - 1)\n return `[${newIndex}]`\n }) as DeepKeys<TFormData>\n }\n\n function shiftMeta(fields: DeepKeys<TFormData>[], direction: 'up' | 'down') {\n const sortedFields = direction === 'up' ? fields : [...fields].reverse()\n\n sortedFields.forEach((fieldKey) => {\n const nextFieldKey = updateIndex(fieldKey.toString(), direction)\n const nextFieldMeta = formApi.getFieldMeta(nextFieldKey)\n if (nextFieldMeta) {\n formApi.setFieldMeta(fieldKey, nextFieldMeta)\n } else {\n formApi.setFieldMeta(fieldKey, getEmptyFieldMeta())\n }\n })\n }\n\n const getEmptyFieldMeta = (): AnyFieldLikeMeta => defaultFieldMeta\n\n return {\n bumpArrayVersion,\n handleArrayMove,\n handleArrayRemove,\n handleArraySwap,\n handleArrayInsert,\n }\n}\n"],"names":[],"mappings":"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"}
import { FormApi, FormAsyncValidateOrFn, FormValidateOrFn } from './FormApi.cjs';
import { AnyFieldMeta } from './FieldApi.cjs';
import { DeepKeys } from './util-types.cjs';
export declare const defaultFieldMeta: AnyFieldMeta;
import { AnyFieldLikeMeta } from './types.cjs';
export declare const defaultFieldMeta: AnyFieldLikeMeta;
export declare function metaHelper<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnDynamic extends undefined | FormValidateOrFn<TFormData>, TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, TSubmitMeta = never>(formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>): {

@@ -6,0 +6,0 @@ bumpArrayVersion: (field: DeepKeys<TFormData>) => void;

@@ -46,4 +46,5 @@ "use strict";

if (!result.issues) return;
if (validationSource === "field")
if (validationSource === "field") {
return result.issues;
}
return transformFormIssues(result.issues, value);

@@ -57,4 +58,5 @@ },

if (!result.issues) return;
if (validationSource === "field")
if (validationSource === "field") {
return result.issues;
}
return transformFormIssues(result.issues, value);

@@ -61,0 +63,0 @@ }

@@ -1,1 +0,1 @@

{"version":3,"file":"standardSchemaValidator.cjs","sources":["../../src/standardSchemaValidator.ts"],"sourcesContent":["import type { ValidationSource } from './types'\n\nexport type TStandardSchemaValidatorValue<\n TData,\n TSource extends ValidationSource = ValidationSource,\n> = {\n value: TData\n validationSource: TSource\n}\n\nexport type TStandardSchemaValidatorIssue<\n TSource extends ValidationSource = ValidationSource,\n> = TSource extends 'form'\n ? {\n form: Record<string, StandardSchemaV1Issue[]>\n fields: Record<string, StandardSchemaV1Issue[]>\n }\n : TSource extends 'field'\n ? StandardSchemaV1Issue[]\n : never\n\nfunction prefixSchemaToErrors(\n issues: readonly StandardSchemaV1Issue[],\n formValue: unknown,\n) {\n const schema = new Map<string, StandardSchemaV1Issue[]>()\n\n for (const issue of issues) {\n const issuePath = issue.path ?? []\n\n let currentFormValue = formValue\n let path = ''\n\n for (let i = 0; i < issuePath.length; i++) {\n const pathSegment = issuePath[i]\n if (pathSegment === undefined) continue\n\n const segment =\n typeof pathSegment === 'object' ? pathSegment.key : pathSegment\n\n // Standard Schema doesn't specify if paths should use numbers or stringified numbers for array access.\n // However, if we follow the path it provides and encounter an array, then we can assume it's intended for array access.\n const segmentAsNumber = Number(segment)\n if (Array.isArray(currentFormValue) && !Number.isNaN(segmentAsNumber)) {\n path += `[${segmentAsNumber}]`\n } else {\n path += (i > 0 ? '.' : '') + String(segment)\n }\n\n if (typeof currentFormValue === 'object' && currentFormValue !== null) {\n currentFormValue = currentFormValue[segment as never]\n } else {\n currentFormValue = undefined\n }\n }\n schema.set(path, (schema.get(path) ?? []).concat(issue))\n }\n\n return Object.fromEntries(schema)\n}\n\nconst transformFormIssues = <TSource extends ValidationSource>(\n issues: readonly StandardSchemaV1Issue[],\n formValue: unknown,\n): TStandardSchemaValidatorIssue<TSource> => {\n const schemaErrors = prefixSchemaToErrors(issues, formValue)\n return {\n form: schemaErrors,\n fields: schemaErrors,\n } as TStandardSchemaValidatorIssue<TSource>\n}\n\nexport const standardSchemaValidators = {\n validate<TSource extends ValidationSource = ValidationSource>(\n {\n value,\n validationSource,\n }: TStandardSchemaValidatorValue<unknown, TSource>,\n schema: StandardSchemaV1,\n ): TStandardSchemaValidatorIssue<TSource> | undefined {\n const result = schema['~standard'].validate(value)\n\n if (result instanceof Promise) {\n throw new Error('async function passed to sync validator')\n }\n\n if (!result.issues) return\n\n if (validationSource === 'field')\n return result.issues as TStandardSchemaValidatorIssue<TSource>\n return transformFormIssues<TSource>(result.issues, value)\n },\n async validateAsync<TSource extends ValidationSource>(\n {\n value,\n validationSource,\n }: TStandardSchemaValidatorValue<unknown, TSource>,\n schema: StandardSchemaV1,\n ): Promise<TStandardSchemaValidatorIssue<TSource> | undefined> {\n const result = await schema['~standard'].validate(value)\n\n if (!result.issues) return\n\n if (validationSource === 'field')\n return result.issues as TStandardSchemaValidatorIssue<TSource>\n return transformFormIssues<TSource>(result.issues, value)\n },\n}\n\nexport const isStandardSchemaValidator = (\n validator: unknown,\n): validator is StandardSchemaV1 =>\n !!validator && '~standard' in (validator as object)\n\n/**\n * The Standard Schema interface.\n */\nexport type StandardSchemaV1<Input = unknown, Output = Input> = {\n /**\n * The Standard Schema properties.\n */\n readonly '~standard': StandardSchemaV1Props<Input, Output>\n}\n\n/**\n * The Standard Schema properties interface.\n */\ninterface StandardSchemaV1Props<Input = unknown, Output = Input> {\n /**\n * The version number of the standard.\n */\n readonly version: 1\n /**\n * The vendor name of the schema library.\n */\n readonly vendor: string\n /**\n * Validates unknown input values.\n */\n readonly validate: (\n value: unknown,\n ) => StandardSchemaV1Result<Output> | Promise<StandardSchemaV1Result<Output>>\n /**\n * Inferred types associated with the schema.\n */\n readonly types?: StandardSchemaV1Types<Input, Output> | undefined\n}\n/**\n * The result interface of the validate function.\n */\ntype StandardSchemaV1Result<Output> =\n | StandardSchemaV1SuccessResult<Output>\n | StandardSchemaV1FailureResult\n/**\n * The result interface if validation succeeds.\n */\ninterface StandardSchemaV1SuccessResult<Output> {\n /**\n * The typed output value.\n */\n readonly value: Output\n /**\n * The non-existent issues.\n */\n readonly issues?: undefined\n}\n/**\n * The result interface if validation fails.\n */\ninterface StandardSchemaV1FailureResult {\n /**\n * The issues of failed validation.\n */\n readonly issues: ReadonlyArray<StandardSchemaV1Issue>\n}\n/**\n * The issue interface of the failure output.\n */\nexport interface StandardSchemaV1Issue {\n /**\n * The error message of the issue.\n */\n readonly message: string\n /**\n * The path of the issue, if any.\n */\n readonly path?:\n | ReadonlyArray<PropertyKey | StandardSchemaV1PathSegment>\n | undefined\n}\n/**\n * The path segment interface of the issue.\n */\ninterface StandardSchemaV1PathSegment {\n /**\n * The key representing a path segment.\n */\n readonly key: PropertyKey\n}\n/**\n * The Standard Schema types interface.\n */\ninterface StandardSchemaV1Types<Input = unknown, Output = Input> {\n /**\n * The input type of the schema.\n */\n readonly input: Input\n /**\n * The output type of the schema.\n */\n readonly output: Output\n}\n"],"names":[],"mappings":";;AAqBA,SAAS,qBACP,QACA,WACA;AACA,QAAM,6BAAa,IAAA;AAEnB,aAAW,SAAS,QAAQ;AAC1B,UAAM,YAAY,MAAM,QAAQ,CAAA;AAEhC,QAAI,mBAAmB;AACvB,QAAI,OAAO;AAEX,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,YAAM,cAAc,UAAU,CAAC;AAC/B,UAAI,gBAAgB,OAAW;AAE/B,YAAM,UACJ,OAAO,gBAAgB,WAAW,YAAY,MAAM;AAItD,YAAM,kBAAkB,OAAO,OAAO;AACtC,UAAI,MAAM,QAAQ,gBAAgB,KAAK,CAAC,OAAO,MAAM,eAAe,GAAG;AACrE,gBAAQ,IAAI,eAAe;AAAA,MAC7B,OAAO;AACL,iBAAS,IAAI,IAAI,MAAM,MAAM,OAAO,OAAO;AAAA,MAC7C;AAEA,UAAI,OAAO,qBAAqB,YAAY,qBAAqB,MAAM;AACrE,2BAAmB,iBAAiB,OAAgB;AAAA,MACtD,OAAO;AACL,2BAAmB;AAAA,MACrB;AAAA,IACF;AACA,WAAO,IAAI,OAAO,OAAO,IAAI,IAAI,KAAK,CAAA,GAAI,OAAO,KAAK,CAAC;AAAA,EACzD;AAEA,SAAO,OAAO,YAAY,MAAM;AAClC;AAEA,MAAM,sBAAsB,CAC1B,QACA,cAC2C;AAC3C,QAAM,eAAe,qBAAqB,QAAQ,SAAS;AAC3D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,EAAA;AAEZ;AAEO,MAAM,2BAA2B;AAAA,EACtC,SACE;AAAA,IACE;AAAA,IACA;AAAA,EAAA,GAEF,QACoD;AACpD,UAAM,SAAS,OAAO,WAAW,EAAE,SAAS,KAAK;AAEjD,QAAI,kBAAkB,SAAS;AAC7B,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAEA,QAAI,CAAC,OAAO,OAAQ;AAEpB,QAAI,qBAAqB;AACvB,aAAO,OAAO;AAChB,WAAO,oBAA6B,OAAO,QAAQ,KAAK;AAAA,EAC1D;AAAA,EACA,MAAM,cACJ;AAAA,IACE;AAAA,IACA;AAAA,EAAA,GAEF,QAC6D;AAC7D,UAAM,SAAS,MAAM,OAAO,WAAW,EAAE,SAAS,KAAK;AAEvD,QAAI,CAAC,OAAO,OAAQ;AAEpB,QAAI,qBAAqB;AACvB,aAAO,OAAO;AAChB,WAAO,oBAA6B,OAAO,QAAQ,KAAK;AAAA,EAC1D;AACF;AAEO,MAAM,4BAA4B,CACvC,cAEA,CAAC,CAAC,aAAa,eAAgB;;;"}
{"version":3,"file":"standardSchemaValidator.cjs","sources":["../../src/standardSchemaValidator.ts"],"sourcesContent":["import type { ValidationSource } from './types'\n\nexport type TStandardSchemaValidatorValue<\n TData,\n TSource extends ValidationSource = ValidationSource,\n> = {\n value: TData\n validationSource: TSource\n}\n\nexport type TStandardSchemaValidatorIssue<\n TSource extends ValidationSource = ValidationSource,\n> = TSource extends 'form'\n ? {\n form: Record<string, StandardSchemaV1Issue[]>\n fields: Record<string, StandardSchemaV1Issue[]>\n }\n : TSource extends 'field'\n ? StandardSchemaV1Issue[]\n : never\n\nfunction prefixSchemaToErrors(\n issues: readonly StandardSchemaV1Issue[],\n formValue: unknown,\n) {\n const schema = new Map<string, StandardSchemaV1Issue[]>()\n\n for (const issue of issues) {\n const issuePath = issue.path ?? []\n\n let currentFormValue = formValue\n let path = ''\n\n for (let i = 0; i < issuePath.length; i++) {\n const pathSegment = issuePath[i]\n if (pathSegment === undefined) continue\n\n const segment =\n typeof pathSegment === 'object' ? pathSegment.key : pathSegment\n\n // Standard Schema doesn't specify if paths should use numbers or stringified numbers for array access.\n // However, if we follow the path it provides and encounter an array, then we can assume it's intended for array access.\n const segmentAsNumber = Number(segment)\n if (Array.isArray(currentFormValue) && !Number.isNaN(segmentAsNumber)) {\n path += `[${segmentAsNumber}]`\n } else {\n path += (i > 0 ? '.' : '') + String(segment)\n }\n\n if (typeof currentFormValue === 'object' && currentFormValue !== null) {\n currentFormValue = currentFormValue[segment as never]\n } else {\n currentFormValue = undefined\n }\n }\n schema.set(path, (schema.get(path) ?? []).concat(issue))\n }\n\n return Object.fromEntries(schema)\n}\n\nconst transformFormIssues = <TSource extends ValidationSource>(\n issues: readonly StandardSchemaV1Issue[],\n formValue: unknown,\n): TStandardSchemaValidatorIssue<TSource> => {\n const schemaErrors = prefixSchemaToErrors(issues, formValue)\n return {\n form: schemaErrors,\n fields: schemaErrors,\n } as TStandardSchemaValidatorIssue<TSource>\n}\n\nexport const standardSchemaValidators = {\n validate<TSource extends ValidationSource = ValidationSource>(\n {\n value,\n validationSource,\n }: TStandardSchemaValidatorValue<unknown, TSource>,\n schema: StandardSchemaV1,\n ): TStandardSchemaValidatorIssue<TSource> | undefined {\n const result = schema['~standard'].validate(value)\n\n if (result instanceof Promise) {\n throw new Error('async function passed to sync validator')\n }\n\n if (!result.issues) return\n\n if (validationSource === 'field') {\n return result.issues as TStandardSchemaValidatorIssue<TSource>\n }\n return transformFormIssues<TSource>(result.issues, value)\n },\n async validateAsync<TSource extends ValidationSource>(\n {\n value,\n validationSource,\n }: TStandardSchemaValidatorValue<unknown, TSource>,\n schema: StandardSchemaV1,\n ): Promise<TStandardSchemaValidatorIssue<TSource> | undefined> {\n const result = await schema['~standard'].validate(value)\n\n if (!result.issues) return\n\n if (validationSource === 'field') {\n return result.issues as TStandardSchemaValidatorIssue<TSource>\n }\n return transformFormIssues<TSource>(result.issues, value)\n },\n}\n\nexport const isStandardSchemaValidator = (\n validator: unknown,\n): validator is StandardSchemaV1 =>\n !!validator && '~standard' in (validator as object)\n\n/**\n * The Standard Schema interface.\n */\nexport type StandardSchemaV1<Input = unknown, Output = Input> = {\n /**\n * The Standard Schema properties.\n */\n readonly '~standard': StandardSchemaV1Props<Input, Output>\n}\n\n/**\n * The Standard Schema properties interface.\n */\ninterface StandardSchemaV1Props<Input = unknown, Output = Input> {\n /**\n * The version number of the standard.\n */\n readonly version: 1\n /**\n * The vendor name of the schema library.\n */\n readonly vendor: string\n /**\n * Validates unknown input values.\n */\n readonly validate: (\n value: unknown,\n ) => StandardSchemaV1Result<Output> | Promise<StandardSchemaV1Result<Output>>\n /**\n * Inferred types associated with the schema.\n */\n readonly types?: StandardSchemaV1Types<Input, Output> | undefined\n}\n/**\n * The result interface of the validate function.\n */\ntype StandardSchemaV1Result<Output> =\n | StandardSchemaV1SuccessResult<Output>\n | StandardSchemaV1FailureResult\n/**\n * The result interface if validation succeeds.\n */\ninterface StandardSchemaV1SuccessResult<Output> {\n /**\n * The typed output value.\n */\n readonly value: Output\n /**\n * The non-existent issues.\n */\n readonly issues?: undefined\n}\n/**\n * The result interface if validation fails.\n */\ninterface StandardSchemaV1FailureResult {\n /**\n * The issues of failed validation.\n */\n readonly issues: ReadonlyArray<StandardSchemaV1Issue>\n}\n/**\n * The issue interface of the failure output.\n */\nexport interface StandardSchemaV1Issue {\n /**\n * The error message of the issue.\n */\n readonly message: string\n /**\n * The path of the issue, if any.\n */\n readonly path?:\n | ReadonlyArray<PropertyKey | StandardSchemaV1PathSegment>\n | undefined\n}\n/**\n * The path segment interface of the issue.\n */\ninterface StandardSchemaV1PathSegment {\n /**\n * The key representing a path segment.\n */\n readonly key: PropertyKey\n}\n/**\n * The Standard Schema types interface.\n */\ninterface StandardSchemaV1Types<Input = unknown, Output = Input> {\n /**\n * The input type of the schema.\n */\n readonly input: Input\n /**\n * The output type of the schema.\n */\n readonly output: Output\n}\n"],"names":[],"mappings":";;AAqBA,SAAS,qBACP,QACA,WACA;AACA,QAAM,6BAAa,IAAA;AAEnB,aAAW,SAAS,QAAQ;AAC1B,UAAM,YAAY,MAAM,QAAQ,CAAA;AAEhC,QAAI,mBAAmB;AACvB,QAAI,OAAO;AAEX,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,YAAM,cAAc,UAAU,CAAC;AAC/B,UAAI,gBAAgB,OAAW;AAE/B,YAAM,UACJ,OAAO,gBAAgB,WAAW,YAAY,MAAM;AAItD,YAAM,kBAAkB,OAAO,OAAO;AACtC,UAAI,MAAM,QAAQ,gBAAgB,KAAK,CAAC,OAAO,MAAM,eAAe,GAAG;AACrE,gBAAQ,IAAI,eAAe;AAAA,MAC7B,OAAO;AACL,iBAAS,IAAI,IAAI,MAAM,MAAM,OAAO,OAAO;AAAA,MAC7C;AAEA,UAAI,OAAO,qBAAqB,YAAY,qBAAqB,MAAM;AACrE,2BAAmB,iBAAiB,OAAgB;AAAA,MACtD,OAAO;AACL,2BAAmB;AAAA,MACrB;AAAA,IACF;AACA,WAAO,IAAI,OAAO,OAAO,IAAI,IAAI,KAAK,CAAA,GAAI,OAAO,KAAK,CAAC;AAAA,EACzD;AAEA,SAAO,OAAO,YAAY,MAAM;AAClC;AAEA,MAAM,sBAAsB,CAC1B,QACA,cAC2C;AAC3C,QAAM,eAAe,qBAAqB,QAAQ,SAAS;AAC3D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,EAAA;AAEZ;AAEO,MAAM,2BAA2B;AAAA,EACtC,SACE;AAAA,IACE;AAAA,IACA;AAAA,EAAA,GAEF,QACoD;AACpD,UAAM,SAAS,OAAO,WAAW,EAAE,SAAS,KAAK;AAEjD,QAAI,kBAAkB,SAAS;AAC7B,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAEA,QAAI,CAAC,OAAO,OAAQ;AAEpB,QAAI,qBAAqB,SAAS;AAChC,aAAO,OAAO;AAAA,IAChB;AACA,WAAO,oBAA6B,OAAO,QAAQ,KAAK;AAAA,EAC1D;AAAA,EACA,MAAM,cACJ;AAAA,IACE;AAAA,IACA;AAAA,EAAA,GAEF,QAC6D;AAC7D,UAAM,SAAS,MAAM,OAAO,WAAW,EAAE,SAAS,KAAK;AAEvD,QAAI,CAAC,OAAO,OAAQ;AAEpB,QAAI,qBAAqB,SAAS;AAChC,aAAO,OAAO;AAAA,IAChB;AACA,WAAO,oBAA6B,OAAO,QAAQ,KAAK;AAAA,EAC1D;AACF;AAEO,MAAM,4BAA4B,CACvC,cAEA,CAAC,CAAC,aAAa,eAAgB;;;"}

@@ -21,2 +21,3 @@ "use strict";

fieldMetaBase: null,
formGroupStateBase: null,
isSubmitting: null,

@@ -23,0 +24,0 @@ isSubmitted: null,

@@ -1,1 +0,1 @@

{"version":3,"file":"transform.cjs","sources":["../../src/transform.ts"],"sourcesContent":["import { batch } from '@tanstack/store'\nimport { deepCopy } from './utils'\nimport type {\n AnyBaseFormState,\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\n\n/**\n * @private\n */\nexport type FormTransform<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n> = (\n formBase: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n) => FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n>\n\n/**\n * @private\n */\nexport function mergeAndUpdate<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n>(\n form: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n fn?: FormTransform<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n) {\n // Run the `transform` function on `form.state`, diff it, and update the relevant parts with what needs updating\n if (!fn) return\n\n const newObj = Object.assign({}, form, {\n state: deepCopy(form.state),\n })\n\n fn(newObj)\n\n if (newObj.fieldInfo !== form.fieldInfo) {\n form.fieldInfo = newObj.fieldInfo\n }\n\n if (newObj.options !== form.options) {\n form.options = newObj.options\n }\n\n const baseFormKeys = Object.keys({\n values: null,\n validationMetaMap: null,\n fieldMetaBase: null,\n isSubmitting: null,\n isSubmitted: null,\n isValidating: null,\n submissionAttempts: null,\n isSubmitSuccessful: null,\n _force_re_eval: null,\n // Do not remove this, it ensures that we have all the keys in `BaseFormState`\n } satisfies Record<\n // Exclude errorMap since we need to handle that uniquely\n Exclude<keyof AnyBaseFormState, 'errorMap'>,\n null\n >) as Array<keyof AnyBaseFormState>\n\n const diffedObject = baseFormKeys.reduce((prev, key) => {\n if (form.state[key] !== newObj.state[key]) {\n prev[key] = newObj.state[key]\n }\n return prev\n }, {} as Partial<AnyBaseFormState>)\n\n batch(() => {\n if (Object.keys(diffedObject).length) {\n form.baseStore.setState((prev) => ({ ...prev, ...diffedObject }))\n }\n\n if (newObj.state.errorMap !== form.state.errorMap) {\n // Check if we need to update `fieldMetaBase` with `errorMaps` set by\n form.setErrorMap(newObj.state.errorMap)\n }\n })\n\n return newObj\n}\n"],"names":["deepCopy","batch"],"mappings":";;;;AA0DO,SAAS,eAcd,MAcA,IAcA;AAEA,MAAI,CAAC,GAAI;AAET,QAAM,SAAS,OAAO,OAAO,CAAA,GAAI,MAAM;AAAA,IACrC,OAAOA,MAAAA,SAAS,KAAK,KAAK;AAAA,EAAA,CAC3B;AAED,KAAG,MAAM;AAET,MAAI,OAAO,cAAc,KAAK,WAAW;AACvC,SAAK,YAAY,OAAO;AAAA,EAC1B;AAEA,MAAI,OAAO,YAAY,KAAK,SAAS;AACnC,SAAK,UAAU,OAAO;AAAA,EACxB;AAEA,QAAM,eAAe,OAAO,KAAK;AAAA,IAC/B,QAAQ;AAAA,IACR,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,cAAc;AAAA,IACd,aAAa;AAAA,IACb,cAAc;AAAA,IACd,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,gBAAgB;AAAA;AAAA,EAAA,CAMjB;AAED,QAAM,eAAe,aAAa,OAAO,CAAC,MAAM,QAAQ;AACtD,QAAI,KAAK,MAAM,GAAG,MAAM,OAAO,MAAM,GAAG,GAAG;AACzC,WAAK,GAAG,IAAI,OAAO,MAAM,GAAG;AAAA,IAC9B;AACA,WAAO;AAAA,EACT,GAAG,CAAA,CAA+B;AAElCC,QAAAA,MAAM,MAAM;AACV,QAAI,OAAO,KAAK,YAAY,EAAE,QAAQ;AACpC,WAAK,UAAU,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,GAAG,aAAA,EAAe;AAAA,IAClE;AAEA,QAAI,OAAO,MAAM,aAAa,KAAK,MAAM,UAAU;AAEjD,WAAK,YAAY,OAAO,MAAM,QAAQ;AAAA,IACxC;AAAA,EACF,CAAC;AAED,SAAO;AACT;;"}
{"version":3,"file":"transform.cjs","sources":["../../src/transform.ts"],"sourcesContent":["import { batch } from '@tanstack/store'\nimport { deepCopy } from './utils'\nimport type {\n AnyBaseFormState,\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\n\n/**\n * @private\n */\nexport type FormTransform<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n> = (\n formBase: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n) => FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n>\n\n/**\n * @private\n */\nexport function mergeAndUpdate<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n>(\n form: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n fn?: FormTransform<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n) {\n // Run the `transform` function on `form.state`, diff it, and update the relevant parts with what needs updating\n if (!fn) return\n\n const newObj = Object.assign({}, form, {\n state: deepCopy(form.state),\n })\n\n fn(newObj)\n\n if (newObj.fieldInfo !== form.fieldInfo) {\n form.fieldInfo = newObj.fieldInfo\n }\n\n if (newObj.options !== form.options) {\n form.options = newObj.options\n }\n\n const baseFormKeys = Object.keys({\n values: null,\n validationMetaMap: null,\n fieldMetaBase: null,\n formGroupStateBase: null,\n isSubmitting: null,\n isSubmitted: null,\n isValidating: null,\n submissionAttempts: null,\n isSubmitSuccessful: null,\n _force_re_eval: null,\n // Do not remove this, it ensures that we have all the keys in `BaseFormState`\n } satisfies Record<\n // Exclude errorMap since we need to handle that uniquely\n Exclude<keyof AnyBaseFormState, 'errorMap'>,\n null\n >) as Array<keyof AnyBaseFormState>\n\n const diffedObject = baseFormKeys.reduce((prev, key) => {\n if (form.state[key] !== newObj.state[key]) {\n prev[key] = newObj.state[key]\n }\n return prev\n }, {} as Partial<AnyBaseFormState>)\n\n batch(() => {\n if (Object.keys(diffedObject).length) {\n form.baseStore.setState((prev) => ({ ...prev, ...diffedObject }))\n }\n\n if (newObj.state.errorMap !== form.state.errorMap) {\n // Check if we need to update `fieldMetaBase` with `errorMaps` set by\n form.setErrorMap(newObj.state.errorMap)\n }\n })\n\n return newObj\n}\n"],"names":["deepCopy","batch"],"mappings":";;;;AA0DO,SAAS,eAcd,MAcA,IAcA;AAEA,MAAI,CAAC,GAAI;AAET,QAAM,SAAS,OAAO,OAAO,CAAA,GAAI,MAAM;AAAA,IACrC,OAAOA,MAAAA,SAAS,KAAK,KAAK;AAAA,EAAA,CAC3B;AAED,KAAG,MAAM;AAET,MAAI,OAAO,cAAc,KAAK,WAAW;AACvC,SAAK,YAAY,OAAO;AAAA,EAC1B;AAEA,MAAI,OAAO,YAAY,KAAK,SAAS;AACnC,SAAK,UAAU,OAAO;AAAA,EACxB;AAEA,QAAM,eAAe,OAAO,KAAK;AAAA,IAC/B,QAAQ;AAAA,IACR,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,oBAAoB;AAAA,IACpB,cAAc;AAAA,IACd,aAAa;AAAA,IACb,cAAc;AAAA,IACd,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,gBAAgB;AAAA;AAAA,EAAA,CAMjB;AAED,QAAM,eAAe,aAAa,OAAO,CAAC,MAAM,QAAQ;AACtD,QAAI,KAAK,MAAM,GAAG,MAAM,OAAO,MAAM,GAAG,GAAG;AACzC,WAAK,GAAG,IAAI,OAAO,MAAM,GAAG;AAAA,IAC9B;AACA,WAAO;AAAA,EACT,GAAG,CAAA,CAA+B;AAElCC,QAAAA,MAAM,MAAM;AACV,QAAI,OAAO,KAAK,YAAY,EAAE,QAAQ;AACpC,WAAK,UAAU,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,GAAG,aAAA,EAAe;AAAA,IAClE;AAEA,QAAI,OAAO,MAAM,aAAa,KAAK,MAAM,UAAU;AAEjD,WAAK,YAAY,OAAO,MAAM,QAAQ;AAAA,IACxC;AAAA,EACF,CAAC;AAED,SAAO;AACT;;"}

@@ -1,4 +0,8 @@

import { AnyFieldMeta, AnyFieldMetaBase } from './FieldApi.cjs';
import { DeepKeys, DeepKeysOfType, DeepValue } from './util-types.cjs';
import { FieldAsyncValidateOrFn, FieldValidateAsyncFn, FieldValidateFn, FieldValidateOrFn } from './FieldApi.cjs';
import { DeepKeys, DeepKeysOfType, DeepValue, UnwrapOneLevelOfArray } from './util-types.cjs';
import { Updater } from './utils.cjs';
import { AnyFormApi, FormApi, FormAsyncValidateOrFn, FormValidateAsyncFn, FormValidateFn, FormValidateOrFn, ValidationMeta } from './FormApi.cjs';
import { ReadonlyStore } from '@tanstack/store';
import { FormGroupAsyncValidateOrFn, FormGroupValidateAsyncFn, FormGroupValidateFn, FormGroupValidateOrFn } from './FormGroupApi.cjs';
import { StandardSchemaV1, StandardSchemaV1Issue } from './standardSchemaValidator.cjs';
export type ValidationError = unknown;

@@ -90,5 +94,4 @@ export type ValidationSource = 'form' | 'field';

* @private
* A list of field manipulation methods that a form-like API must implement.
*/
export interface FieldManipulator<TFormData, TSubmitMeta> {
export interface FormLikeAPI<TFormData, TSubmitMeta> {
/**

@@ -118,7 +121,7 @@ * Validates all fields using the correct handlers for a given validation cause.

*/
getFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField) => AnyFieldMeta | undefined;
getFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField) => AnyFieldLikeMeta | undefined;
/**
* Updates the metadata of the specified field.
*/
setFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField, updater: Updater<AnyFieldMetaBase>) => void;
setFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField, updater: Updater<AnyFieldLikeMetaBase>) => void;
/**

@@ -165,1 +168,180 @@ * Sets the value of the specified field and optionally updates the touched state.

}
type UnwrapFormAsyncValidateOrFnForInner<TValidateOrFn extends undefined | FormAsyncValidateOrFn<any>> = [TValidateOrFn] extends [FormValidateAsyncFn<any>] ? Awaited<ReturnType<TValidateOrFn>> : [TValidateOrFn] extends [StandardSchemaV1<infer TOut, any>] ? StandardBrandedSchemaV1<TOut> : undefined;
export type UnwrapFieldAsyncValidateOrFn<TName extends string, TValidateOrFn extends undefined | FieldAsyncValidateOrFn<any, any, any> | FormGroupAsyncValidateOrFn<any, any>, TFormValidateOrFn extends undefined | FormAsyncValidateOrFn<any>> = ([TFormValidateOrFn] extends [StandardSchemaV1<any, infer TStandardOut>] ? TName extends keyof TStandardOut ? StandardSchemaV1Issue[] : undefined : undefined) | (UnwrapFormAsyncValidateOrFnForInner<TFormValidateOrFn> extends infer TFormValidateVal ? TFormValidateVal extends {
__standardSchemaV1: true;
} ? [DeepValue<TFormValidateVal, TName>] extends [never] ? undefined : StandardSchemaV1Issue[] : TFormValidateVal extends {
fields: any;
} ? TName extends keyof TFormValidateVal['fields'] ? TFormValidateVal['fields'][TName] : undefined : undefined : never) | ([TValidateOrFn] extends [FieldValidateAsyncFn<any, any, any>] ? Awaited<ReturnType<TValidateOrFn>> : [TValidateOrFn] extends [StandardSchemaV1<any, any>] ? StandardSchemaV1Issue[] : undefined) | ([TValidateOrFn] extends [FormGroupValidateAsyncFn<any, any, any>] ? Awaited<ReturnType<TValidateOrFn>> : [TValidateOrFn] extends [StandardSchemaV1<any, any>] ? StandardSchemaV1Issue[] : undefined);
/**
* @private
*/
export type FieldErrorMapFromValidator<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>> = Partial<Record<DeepKeys<TParentData>, ValidationErrorMap<TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>>>;
type StandardBrandedSchemaV1<T> = T & {
__standardSchemaV1: true;
};
type UnwrapFormValidateOrFnForInner<TValidateOrFn extends undefined | FormValidateOrFn<any>> = [TValidateOrFn] extends [FormValidateFn<any>] ? ReturnType<TValidateOrFn> : [TValidateOrFn] extends [StandardSchemaV1<infer TOut, any>] ? StandardBrandedSchemaV1<TOut> : undefined;
export type UnwrapFieldValidateOrFn<TName extends string, TValidateOrFn extends undefined | FieldValidateOrFn<any, any, any> | FormGroupValidateOrFn<any, any, any>, TFormValidateOrFn extends undefined | FormValidateOrFn<any>> = ([TFormValidateOrFn] extends [StandardSchemaV1<any, infer TStandardOut>] ? TName extends keyof TStandardOut ? StandardSchemaV1Issue[] : undefined : undefined) | (UnwrapFormValidateOrFnForInner<TFormValidateOrFn> extends infer TFormValidateVal ? TFormValidateVal extends {
__standardSchemaV1: true;
} ? [DeepValue<TFormValidateVal, TName>] extends [never] ? undefined : StandardSchemaV1Issue[] : TFormValidateVal extends {
fields: any;
} ? TName extends keyof TFormValidateVal['fields'] ? TFormValidateVal['fields'][TName] : undefined : undefined : never) | ([TValidateOrFn] extends [FieldValidateFn<any, any, any>] ? ReturnType<TValidateOrFn> : [TValidateOrFn] extends [StandardSchemaV1<any, any>] ? StandardSchemaV1Issue[] : undefined) | ([TValidateOrFn] extends [FormGroupValidateFn<any, any, any>] ? ReturnType<TValidateOrFn> : [TValidateOrFn] extends [StandardSchemaV1<any, any>] ? StandardSchemaV1Issue[] : undefined);
/**
* @private
*/
export type FieldLikeMetaBase<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TFormOnMount extends undefined | FormValidateOrFn<TParentData>, TFormOnChange extends undefined | FormValidateOrFn<TParentData>, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> = {
/**
* A flag indicating whether the field has been touched.
*/
isTouched: boolean;
/**
* A flag indicating whether the field has been blurred.
*/
isBlurred: boolean;
/**
* A flag that is `true` if the field's value has been modified by the user. Opposite of `isPristine`.
*/
isDirty: boolean;
/**
* A map of errors related to the field value.
*/
errorMap: ValidationErrorMap<UnwrapFieldValidateOrFn<TName, TOnMount, TFormOnMount>, UnwrapFieldValidateOrFn<TName, TOnChange, TFormOnChange>, UnwrapFieldAsyncValidateOrFn<TName, TOnChangeAsync, TFormOnChangeAsync>, UnwrapFieldValidateOrFn<TName, TOnBlur, TFormOnBlur>, UnwrapFieldAsyncValidateOrFn<TName, TOnBlurAsync, TFormOnBlurAsync>, UnwrapFieldValidateOrFn<TName, TOnSubmit, TFormOnSubmit>, UnwrapFieldAsyncValidateOrFn<TName, TOnSubmitAsync, TFormOnSubmitAsync>, UnwrapFieldValidateOrFn<TName, TOnDynamic, TFormOnDynamic>, UnwrapFieldAsyncValidateOrFn<TName, TOnDynamicAsync, TFormOnDynamicAsync>>;
/**
* @private allows tracking the source of the errors in the error map
*/
errorSourceMap: ValidationErrorMapSource;
/**
* A flag indicating whether the field is currently being validated.
*/
isValidating: boolean;
/**
* @private a counter that is incremented every time a structural array
* operation (push, insert, remove, swap, move, replace, clear) modifies
* the value of an array field. Adapters can subscribe to this to trigger
* re-renders for `mode="array"` fields without having to subscribe to the
* full field value.
*/
_arrayVersion: number;
};
/**
* @private
*/
export type AnyFieldLikeMetaBase = FieldLikeMetaBase<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
/**
* @private
*/
export type FieldLikeMetaDerived<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TFormOnMount extends undefined | FormValidateOrFn<TParentData>, TFormOnChange extends undefined | FormValidateOrFn<TParentData>, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> = {
/**
* An array of errors related to the field value.
*/
errors: Array<UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnMount, TFormOnMount>> | UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnChange, TFormOnChange>> | UnwrapOneLevelOfArray<UnwrapFieldAsyncValidateOrFn<TName, TOnChangeAsync, TFormOnChangeAsync>> | UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnBlur, TFormOnBlur>> | UnwrapOneLevelOfArray<UnwrapFieldAsyncValidateOrFn<TName, TOnBlurAsync, TFormOnBlurAsync>> | UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnSubmit, TFormOnSubmit>> | UnwrapOneLevelOfArray<UnwrapFieldAsyncValidateOrFn<TName, TOnSubmitAsync, TFormOnSubmitAsync>> | UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnDynamic, TFormOnDynamic>> | UnwrapOneLevelOfArray<UnwrapFieldAsyncValidateOrFn<TName, TOnDynamicAsync, TFormOnDynamicAsync>>>;
/**
* A flag that is `true` if the field's value has not been modified by the user. Opposite of `isDirty`.
*/
isPristine: boolean;
/**
* A boolean indicating if the field is valid. Evaluates `true` if there are no field errors.
*/
isValid: boolean;
/**
* A flag indicating whether the field's current value is the default value
*/
isDefaultValue: boolean;
};
/**
* @private
* An object type representing the metadata of a field in a form.
*/
export type FieldLikeMeta<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TFormOnMount extends undefined | FormValidateOrFn<TParentData>, TFormOnChange extends undefined | FormValidateOrFn<TParentData>, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> = FieldLikeMetaBase<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync> & FieldLikeMetaDerived<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
/**
* @private
*/
export type AnyFieldLikeMeta = FieldLikeMeta<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
export type AnyFieldMeta = AnyFieldLikeMeta;
/**
* @private
* An object type representing the state of a field.
*/
export type FieldLikeState<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TFormOnMount extends undefined | FormValidateOrFn<TParentData>, TFormOnChange extends undefined | FormValidateOrFn<TParentData>, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> = {
/**
* The current value of the field.
*/
value: TData;
/**
* The current metadata of the field.
*/
meta: FieldLikeMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
};
/**
* @private
* An object type representing the options for a field in a form.
*/
export interface FieldLikeOptions<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>> {
/**
* The field name. The type will be `DeepKeys<TParentData>` to ensure your name is a deep key of the parent dataset.
*/
name: TName;
/**
* An optional default value for the field.
*/
defaultValue?: NoInfer<TData>;
/**
* The default time to debounce async validation if there is not a more specific debounce time passed.
*/
asyncDebounceMs?: number;
/**
* If `true`, always run async validation, even if there are errors emitted during synchronous validation.
*/
asyncAlways?: boolean;
/**
* An optional object with default metadata for the field.
*/
defaultMeta?: Partial<FieldLikeMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, any, any, any, any, any, any, any, any, any>>;
/**
* Disable the `flat(1)` operation on `field.errors`. This is useful if you want to keep the error structure as is. Not suggested for most use-cases.
*/
disableErrorFlat?: boolean;
}
/**
* @private
* An object type representing the required options for the FieldApi class.
*/
export interface FieldLikeApiOptions<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> extends FieldLikeOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync> {
form: FormApi<TParentData, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>;
}
/**
* @private
*/
export interface FieldLikeAPI<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta, TExtraOptions = {}> {
form: AnyFormApi;
options: FieldLikeApiOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta> & TExtraOptions;
store: ReadonlyStore<FieldLikeState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>;
/**
* The field name.
*/
name: TName;
mount: () => () => void;
setValue: (updater: Updater<TData>, options?: UpdateMetaOptions) => void;
getMeta: () => AnyFieldLikeMeta;
setMeta: (updater: Updater<AnyFieldLikeMetaBase>) => void;
getInfo: () => FieldInfo<TParentData>;
validate: (cause: ValidationCause, opts?: {
skipFormValidation?: boolean;
skipGroupValidation?: boolean;
}) => ValidationError[] | Promise<ValidationError[]>;
/**
* @private
*/
triggerOnChangeListener: () => void;
/**
* @private
*/
triggerOnSubmitListener: () => void;
}
/**
* @private
*/
export interface FieldInfo<TParentData> {
instance: FieldLikeAPI<TParentData, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any> | null;
validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>;
}
export {};

@@ -176,2 +176,3 @@ "use strict";

form: options.form,
group: options.group,
validators: options.validators,

@@ -220,2 +221,3 @@ event: { type: cause, fieldName: options.fieldName, async: false },

form: options.form,
group: options.group,
validators: options.validators,

@@ -383,2 +385,5 @@ event: { type: cause, fieldName: options.fieldName, async: true },

}
function isFieldInGroup(groupName, fieldName) {
return fieldName === groupName || fieldName.startsWith(`${groupName}.`) || fieldName.startsWith(`${groupName}[`);
}
exports.concatenatePaths = concatenatePaths;

@@ -395,2 +400,3 @@ exports.createFieldMap = createFieldMap;

exports.getSyncValidatorArray = getSyncValidatorArray;
exports.isFieldInGroup = isFieldInGroup;
exports.isGlobalFormValidationError = isGlobalFormValidationError;

@@ -397,0 +403,0 @@ exports.isNonEmptyArray = isNonEmptyArray;

@@ -1,1 +0,1 @@

{"version":3,"file":"utils.cjs","sources":["../../src/utils.ts"],"sourcesContent":["import { liteThrottle } from '@tanstack/pacer-lite'\nimport { formEventClient } from './EventClient'\nimport type { ValidationLogicProps } from './ValidationLogic'\nimport type { FieldValidators } from './FieldApi'\nimport type { AnyFormApi, FormValidators } from './FormApi'\nimport type {\n GlobalFormValidationError,\n ValidationCause,\n ValidationError,\n ValidationSource,\n} from './types'\n\nexport type UpdaterFn<TInput, TOutput = TInput> = (input: TInput) => TOutput\n\nexport type Updater<TInput, TOutput = TInput> =\n | TOutput\n | UpdaterFn<TInput, TOutput>\n\n/**\n * @private\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 * @private\n */\nexport function getBy(obj: unknown, path: string | (string | number)[]): any {\n const pathObj = makePathArray(path)\n return pathObj.reduce((current: any, pathPart) => {\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 * @private\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 (\n typeof key === 'string' ||\n (typeof key === 'number' && !Array.isArray(parent))\n ) {\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) && typeof key === 'number') {\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 * @private\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 (\n typeof key === 'string' ||\n (typeof key === 'number' && !Array.isArray(parent))\n ) {\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\n// Char codes used by the parser below.\nconst CC_DOT = 0x2e // '.'\nconst CC_OPEN = 0x5b // '['\nconst CC_CLOSE = 0x5d // ']'\nconst CC_ZERO = 0x30 // '0'\nconst CC_NINE = 0x39 // '9'\n\n/**\n * @private\n */\nexport function makePathArray(str: string | Array<string | number>) {\n if (Array.isArray(str)) {\n return [...str]\n }\n\n if (typeof str !== 'string') {\n throw new Error('Path must be a string.')\n }\n\n const len = str.length\n const result: Array<string | number> = []\n // Location of the first character of the in-progress segment in `str`.\n // The segment ends at the current `i` when we hit a separator.\n //\n // We strip an optional leading '[' so '[0]' parses as [0], not ['', 0].\n // Doing this up front keeps the loop's backwards compatibility handling simpler.\n let segStart = len > 0 && str.charCodeAt(0) === CC_OPEN ? 1 : 0\n // Whether the in-progress segment has been all ASCII digits so far.\n // Used together with the leading-zero check to decide if it should be\n // pushed as a number instead of a string.\n let allDigits = true\n // Tracks the previous character. Only necessary to preserve the\n // old behavior for malformed input.\n let prev = -1\n // Walk once. `i === len` is treated as a virtual final separator so the\n // flush block handles both mid-string segments and the last one.\n for (let i = segStart; i <= len; i++) {\n const char = i < len ? str.charCodeAt(i) : -1\n\n // Handle separators (including the virtual one at the end). Flush the in-progress segment.\n if (i === len || char === CC_DOT || char === CC_OPEN || char === CC_CLOSE) {\n const segLen = i - segStart\n if (segLen > 0) {\n // To treat the segment as a number...\n const treatAsNumber =\n // ...it must contain only digits...\n allDigits &&\n // ...and either be a single '0' or not start with '0'.\n (segLen === 1 || str.charCodeAt(segStart) !== CC_ZERO)\n\n const seg = str.slice(segStart, i)\n if (treatAsNumber) {\n const num = parseInt(seg, 10)\n // Up to 15 digits, parseInt is always lossless (the max\n // 15-digit decimal is below Number.MAX_SAFE_INTEGER). Beyond\n // that, verify by round-trip: if parseInt lost precision\n // (e.g., a 20-digit literal), fall back to the string so we\n // don't silently change the value.\n if (segLen <= 15 || String(num) === seg) {\n result.push(num)\n } else {\n result.push(seg)\n }\n } else {\n result.push(seg)\n }\n } else if (\n // This branch, which handles empty segments, only exists to preserve\n // the old behavior for malformed input.\n\n // Push the empty segment unless this is a \"phantom boundary\" the\n // old regex impl would have absorbed:\n // 1. `]` was always stripped — `prev === ']'` means the real\n // boundary already happened on the previous iteration.\n // 2. A leading `]` was stripped too (the leading `[` strip\n // above handles its counterpart for `[`).\n // 3. `..` and `[[` collapse to a single boundary.\n prev !== CC_CLOSE &&\n !(prev === -1 && char === CC_CLOSE) &&\n !(prev === char && (char === CC_DOT || char === CC_OPEN))\n ) {\n result.push('')\n }\n\n // Start a new segment.\n segStart = i + 1\n allDigits = true\n } else if (char < CC_ZERO || char > CC_NINE) {\n allDigits = false\n }\n\n prev = char\n }\n\n // If the input was effectively all phantom chars (e.g. ']', '[]',\n // '[]]'), the loop produces no segments. The old impl returned ['']\n // for these because.\n if (!result.length) result.push('')\n\n return result\n}\n\n/**\n * @private\n */\nexport function concatenatePaths(path1: string, path2: string): string {\n if (path1.length === 0) return path2\n if (path2.length === 0) return path1\n\n if (path2.startsWith('[')) {\n return path1 + path2\n }\n\n // In cases where parent and child withFieldGroup forms are both nested\n if (path2.startsWith('.')) {\n return path1 + path2\n }\n\n return `${path1}.${path2}`\n}\n\n/**\n * @private\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\n/**\n * @private\n */\nexport interface AsyncValidator<T> {\n cause: ValidationCause\n validate: T\n debounceMs: number\n}\n\ninterface SyncValidatorArrayPartialOptions<T> {\n validators?: T\n}\n\n/**\n * @private\n */\nexport interface SyncValidator<T> {\n cause: ValidationCause\n validate: T\n}\n\n/**\n * @private\n */\nexport function getSyncValidatorArray<T>(\n cause: ValidationCause,\n options: SyncValidatorArrayPartialOptions<T> & {\n validationLogic?: any\n form?: any\n fieldName?: string\n },\n): T extends FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n ? Array<\n SyncValidator<\n | T['onChange']\n | T['onBlur']\n | T['onSubmit']\n | T['onMount']\n | T['onDynamic']\n >\n >\n : T extends FormValidators<any, any, any, any, any, any, any, any, any, any>\n ? Array<\n SyncValidator<\n | T['onChange']\n | T['onBlur']\n | T['onSubmit']\n | T['onMount']\n | T['onDynamic']\n >\n >\n : never {\n const runValidation = (\n props: Parameters<ValidationLogicProps['runValidation']>[0],\n ) => {\n return props.validators.filter(Boolean).map((validator) => {\n return {\n cause: validator!.cause,\n validate: validator!.fn,\n }\n })\n }\n\n return options.validationLogic({\n form: options.form,\n validators: options.validators,\n event: { type: cause, fieldName: options.fieldName, async: false },\n runValidation,\n })\n}\n\n/**\n * @private\n */\nexport function getAsyncValidatorArray<T>(\n cause: ValidationCause,\n options: AsyncValidatorArrayPartialOptions<T> & {\n validationLogic?: any\n form?: any\n fieldName?: string\n },\n): T extends FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n ? Array<\n AsyncValidator<\n | T['onChangeAsync']\n | T['onBlurAsync']\n | T['onSubmitAsync']\n | T['onDynamicAsync']\n >\n >\n : T extends FormValidators<any, any, any, any, any, any, any, any, any, any>\n ? Array<\n AsyncValidator<\n | T['onChangeAsync']\n | T['onBlurAsync']\n | T['onSubmitAsync']\n | T['onDynamicAsync']\n >\n >\n : never {\n const { asyncDebounceMs } = options\n const {\n onBlurAsyncDebounceMs,\n onChangeAsyncDebounceMs,\n onDynamicAsyncDebounceMs,\n } = (options.validators || {}) as\n | FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n | FormValidators<any, any, any, any, any, any, any, any, any, any>\n\n const defaultDebounceMs = asyncDebounceMs ?? 0\n\n const runValidation = (\n props: Parameters<ValidationLogicProps['runValidation']>[0],\n ) => {\n return props.validators.filter(Boolean).map((validator) => {\n const validatorCause = validator?.cause || cause\n\n let debounceMs = defaultDebounceMs\n\n switch (validatorCause) {\n case 'change':\n debounceMs = onChangeAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'blur':\n debounceMs = onBlurAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'dynamic':\n debounceMs = onDynamicAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'submit':\n debounceMs = 0 // submit validators are always run immediately\n break\n default:\n break\n }\n\n if (cause === 'submit') {\n debounceMs = 0\n }\n\n return {\n cause: validatorCause,\n validate: validator!.fn,\n debounceMs: debounceMs,\n }\n })\n }\n\n return options.validationLogic({\n form: options.form,\n validators: options.validators,\n event: { type: cause, fieldName: options.fieldName, async: true },\n runValidation,\n })\n}\n\nexport const isGlobalFormValidationError = (\n error: unknown,\n): error is GlobalFormValidationError<unknown> => {\n return !!error && typeof error === 'object' && 'fields' in error\n}\n\nexport function evaluate<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n if (objA instanceof Date && objB instanceof Date) {\n return objA.getTime() === objB.getTime()\n }\n\n if (objA instanceof Map && objB instanceof Map) {\n if (objA.size !== objB.size) return false\n for (const [k, v] of objA) {\n if (!objB.has(k) || !Object.is(v, objB.get(k))) return false\n }\n return true\n }\n\n if (objA instanceof Set && objB instanceof Set) {\n if (objA.size !== objB.size) return false\n for (const v of objA) {\n if (!objB.has(v)) return false\n }\n return true\n }\n\n const keysA = Object.keys(objA)\n const keysB = Object.keys(objB)\n\n if (keysA.length !== keysB.length) {\n return false\n }\n\n // Two distinct non-plain, non-array objects with no own enumerable keys cannot\n // be compared by key iteration — the loop below would vacuously succeed and\n // treat them as equal regardless of their internal state. This covers Temporal\n // types, RegExp, and any class that exposes values only through getters.\n if (\n keysA.length === 0 &&\n !Array.isArray(objA) &&\n !Array.isArray(objB) &&\n (Object.getPrototypeOf(objA) !== Object.prototype ||\n Object.getPrototypeOf(objB) !== Object.prototype)\n ) {\n return false\n }\n\n for (const key of keysA) {\n // performs recursive search down the object tree\n\n if (\n !keysB.includes(key) ||\n !evaluate(objA[key as keyof T], objB[key as keyof T])\n ) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Determines the logic for determining the error source and value to set on the field meta within the form level sync/async validation.\n * @private\n */\nexport const determineFormLevelErrorSourceAndValue = ({\n newFormValidatorError,\n isPreviousErrorFromFormValidator,\n previousErrorValue,\n}: {\n newFormValidatorError: ValidationError\n isPreviousErrorFromFormValidator: boolean\n previousErrorValue: ValidationError\n}): {\n newErrorValue: ValidationError\n newSource: ValidationSource | undefined\n} => {\n // All falsy values are not considered errors\n if (newFormValidatorError) {\n return { newErrorValue: newFormValidatorError, newSource: 'form' }\n }\n\n // Clears form level error since it's now stale\n if (isPreviousErrorFromFormValidator) {\n return { newErrorValue: undefined, newSource: undefined }\n }\n\n // At this point, we have a preivous error which must have been set by the field validator, keep as is\n if (previousErrorValue) {\n return { newErrorValue: previousErrorValue, newSource: 'field' }\n }\n\n // No new or previous error, clear the error\n return { newErrorValue: undefined, newSource: undefined }\n}\n\n/**\n * Determines the logic for determining the error source and value to set on the field meta within the field level sync/async validation.\n * @private\n */\nexport const determineFieldLevelErrorSourceAndValue = ({\n formLevelError,\n fieldLevelError,\n}: {\n formLevelError: ValidationError\n fieldLevelError: ValidationError\n}): {\n newErrorValue: ValidationError\n newSource: ValidationSource | undefined\n} => {\n // At field level, we prioritize the field level error\n if (fieldLevelError) {\n return { newErrorValue: fieldLevelError, newSource: 'field' }\n }\n\n // If there is no field level error, and there is a form level error, we set the form level error\n if (formLevelError) {\n return { newErrorValue: formLevelError, newSource: 'form' }\n }\n\n return { newErrorValue: undefined, newSource: undefined }\n}\n\nexport function createFieldMap<T>(values: Readonly<T>): { [K in keyof T]: K } {\n const output: { [K in keyof T]: K } = {} as any\n\n for (const key in values) {\n output[key] = key\n }\n\n return output\n}\n\n/**\n * Merge the first parameter with the given overrides.\n * @private\n */\nexport function mergeOpts<T>(\n originalOpts: T | undefined | null,\n overrides: T,\n): T {\n if (originalOpts === undefined || originalOpts === null) {\n return overrides\n }\n\n return { ...originalOpts, ...overrides }\n}\n\n/*\n/ credit is due to https://github.com/lukeed/uuid for this code, with current npm\n/ attacks we didn't feel comfortable installing directly from npm. But big appreciation\n/ from the TanStack Form team <3.\n*/\n\nlet IDX = 256\nconst HEX: string[] = []\nlet BUFFER: number[] | undefined\n\nwhile (IDX--) {\n HEX[IDX] = (IDX + 256).toString(16).substring(1)\n}\n\nexport function uuid(): string {\n let i = 0\n let num: number\n let out = ''\n\n if (!BUFFER || IDX + 16 > 256) {\n BUFFER = new Array<number>(256)\n i = 256\n while (i--) {\n BUFFER[i] = (256 * Math.random()) | 0\n }\n i = 0\n IDX = 0\n }\n\n for (; i < 16; i++) {\n num = BUFFER[IDX + i] as number\n if (i === 6) out += HEX[(num & 15) | 64]\n else if (i === 8) out += HEX[(num & 63) | 128]\n else out += HEX[num]\n\n if (i & 1 && i > 1 && i < 11) out += '-'\n }\n\n IDX++\n return out\n}\n\nexport const throttleFormState = liteThrottle(\n (form: AnyFormApi) =>\n formEventClient.emit('form-state', {\n id: form.formId,\n state: form.store.state,\n }),\n {\n wait: 300,\n },\n)\n\n// Do not use a serialize and deserialize method like JSON.stringify/parse\n// as that will drop functions, dates, undefined, Infinity, NaN, etc.\nexport function deepCopy<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as any\n }\n\n if (Array.isArray(obj)) {\n const arrCopy = [] as any[]\n for (let i = 0; i < obj.length; i++) {\n arrCopy[i] = deepCopy(obj[i])\n }\n return arrCopy as any\n }\n\n if (obj instanceof Map) {\n const mapCopy = new Map()\n obj.forEach((value, key) => {\n mapCopy.set(key, deepCopy(value))\n })\n return mapCopy as any\n }\n\n if (obj instanceof Set) {\n const setCopy = new Set()\n obj.forEach((value) => {\n setCopy.add(deepCopy(value))\n })\n return setCopy as any\n }\n\n const copy: { [key: string]: any } = {}\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n copy[key] = deepCopy((obj as any)[key])\n }\n }\n return copy as T\n}\n"],"names":["liteThrottle","formEventClient"],"mappings":"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"}
{"version":3,"file":"utils.cjs","sources":["../../src/utils.ts"],"sourcesContent":["import { liteThrottle } from '@tanstack/pacer-lite'\nimport { formEventClient } from './EventClient'\nimport { AnyFormGroupApi } from './FormGroupApi'\nimport type { ValidationLogicProps } from './ValidationLogic'\nimport type { FieldValidators } from './FieldApi'\nimport type { AnyFormApi, FormValidators } from './FormApi'\nimport type {\n GlobalFormValidationError,\n ValidationCause,\n ValidationError,\n ValidationSource,\n} from './types'\n\nexport type UpdaterFn<TInput, TOutput = TInput> = (input: TInput) => TOutput\n\nexport type Updater<TInput, TOutput = TInput> =\n | TOutput\n | UpdaterFn<TInput, TOutput>\n\n/**\n * @private\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 * @private\n */\nexport function getBy(obj: unknown, path: string | (string | number)[]): any {\n const pathObj = makePathArray(path)\n return pathObj.reduce((current: any, pathPart) => {\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 * @private\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 (\n typeof key === 'string' ||\n (typeof key === 'number' && !Array.isArray(parent))\n ) {\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) && typeof key === 'number') {\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 * @private\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 (\n typeof key === 'string' ||\n (typeof key === 'number' && !Array.isArray(parent))\n ) {\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\n// Char codes used by the parser below.\nconst CC_DOT = 0x2e // '.'\nconst CC_OPEN = 0x5b // '['\nconst CC_CLOSE = 0x5d // ']'\nconst CC_ZERO = 0x30 // '0'\nconst CC_NINE = 0x39 // '9'\n\n/**\n * @private\n */\nexport function makePathArray(str: string | Array<string | number>) {\n if (Array.isArray(str)) {\n return [...str]\n }\n\n if (typeof str !== 'string') {\n throw new Error('Path must be a string.')\n }\n\n const len = str.length\n const result: Array<string | number> = []\n // Location of the first character of the in-progress segment in `str`.\n // The segment ends at the current `i` when we hit a separator.\n //\n // We strip an optional leading '[' so '[0]' parses as [0], not ['', 0].\n // Doing this up front keeps the loop's backwards compatibility handling simpler.\n let segStart = len > 0 && str.charCodeAt(0) === CC_OPEN ? 1 : 0\n // Whether the in-progress segment has been all ASCII digits so far.\n // Used together with the leading-zero check to decide if it should be\n // pushed as a number instead of a string.\n let allDigits = true\n // Tracks the previous character. Only necessary to preserve the\n // old behavior for malformed input.\n let prev = -1\n // Walk once. `i === len` is treated as a virtual final separator so the\n // flush block handles both mid-string segments and the last one.\n for (let i = segStart; i <= len; i++) {\n const char = i < len ? str.charCodeAt(i) : -1\n\n // Handle separators (including the virtual one at the end). Flush the in-progress segment.\n if (i === len || char === CC_DOT || char === CC_OPEN || char === CC_CLOSE) {\n const segLen = i - segStart\n if (segLen > 0) {\n // To treat the segment as a number...\n const treatAsNumber =\n // ...it must contain only digits...\n allDigits &&\n // ...and either be a single '0' or not start with '0'.\n (segLen === 1 || str.charCodeAt(segStart) !== CC_ZERO)\n\n const seg = str.slice(segStart, i)\n if (treatAsNumber) {\n const num = parseInt(seg, 10)\n // Up to 15 digits, parseInt is always lossless (the max\n // 15-digit decimal is below Number.MAX_SAFE_INTEGER). Beyond\n // that, verify by round-trip: if parseInt lost precision\n // (e.g., a 20-digit literal), fall back to the string so we\n // don't silently change the value.\n if (segLen <= 15 || String(num) === seg) {\n result.push(num)\n } else {\n result.push(seg)\n }\n } else {\n result.push(seg)\n }\n } else if (\n // This branch, which handles empty segments, only exists to preserve\n // the old behavior for malformed input.\n\n // Push the empty segment unless this is a \"phantom boundary\" the\n // old regex impl would have absorbed:\n // 1. `]` was always stripped — `prev === ']'` means the real\n // boundary already happened on the previous iteration.\n // 2. A leading `]` was stripped too (the leading `[` strip\n // above handles its counterpart for `[`).\n // 3. `..` and `[[` collapse to a single boundary.\n prev !== CC_CLOSE &&\n !(prev === -1 && char === CC_CLOSE) &&\n !(prev === char && (char === CC_DOT || char === CC_OPEN))\n ) {\n result.push('')\n }\n\n // Start a new segment.\n segStart = i + 1\n allDigits = true\n } else if (char < CC_ZERO || char > CC_NINE) {\n allDigits = false\n }\n\n prev = char\n }\n\n // If the input was effectively all phantom chars (e.g. ']', '[]',\n // '[]]'), the loop produces no segments. The old impl returned ['']\n // for these because.\n if (!result.length) result.push('')\n\n return result\n}\n\n/**\n * @private\n */\nexport function concatenatePaths(path1: string, path2: string): string {\n if (path1.length === 0) return path2\n if (path2.length === 0) return path1\n\n if (path2.startsWith('[')) {\n return path1 + path2\n }\n\n // In cases where parent and child withFieldGroup forms are both nested\n if (path2.startsWith('.')) {\n return path1 + path2\n }\n\n return `${path1}.${path2}`\n}\n\n/**\n * @private\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\n/**\n * @private\n */\nexport interface AsyncValidator<T> {\n cause: ValidationCause\n validate: T\n debounceMs: number\n}\n\ninterface SyncValidatorArrayPartialOptions<T> {\n validators?: T\n}\n\n/**\n * @private\n */\nexport interface SyncValidator<T> {\n cause: ValidationCause\n validate: T\n}\n\n/**\n * @private\n */\nexport function getSyncValidatorArray<T>(\n cause: ValidationCause,\n options: SyncValidatorArrayPartialOptions<T> & {\n validationLogic?: any\n form?: any\n group?: any\n fieldName?: string\n },\n): T extends FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n ? Array<\n SyncValidator<\n | T['onChange']\n | T['onBlur']\n | T['onSubmit']\n | T['onMount']\n | T['onDynamic']\n >\n >\n : T extends FormValidators<any, any, any, any, any, any, any, any, any, any>\n ? Array<\n SyncValidator<\n | T['onChange']\n | T['onBlur']\n | T['onSubmit']\n | T['onMount']\n | T['onDynamic']\n >\n >\n : never {\n const runValidation = (\n props: Parameters<ValidationLogicProps['runValidation']>[0],\n ) => {\n return props.validators.filter(Boolean).map((validator) => {\n return {\n cause: validator!.cause,\n validate: validator!.fn,\n }\n })\n }\n\n return options.validationLogic({\n form: options.form,\n group: options.group,\n validators: options.validators,\n event: { type: cause, fieldName: options.fieldName, async: false },\n runValidation,\n })\n}\n\n/**\n * @private\n */\nexport function getAsyncValidatorArray<T>(\n cause: ValidationCause,\n options: AsyncValidatorArrayPartialOptions<T> & {\n validationLogic?: any\n form?: any\n group?: any\n fieldName?: string\n },\n): T extends FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n ? Array<\n AsyncValidator<\n | T['onChangeAsync']\n | T['onBlurAsync']\n | T['onSubmitAsync']\n | T['onDynamicAsync']\n >\n >\n : T extends FormValidators<any, any, any, any, any, any, any, any, any, any>\n ? Array<\n AsyncValidator<\n | T['onChangeAsync']\n | T['onBlurAsync']\n | T['onSubmitAsync']\n | T['onDynamicAsync']\n >\n >\n : never {\n const { asyncDebounceMs } = options\n const {\n onBlurAsyncDebounceMs,\n onChangeAsyncDebounceMs,\n onDynamicAsyncDebounceMs,\n } = (options.validators || {}) as\n | FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n | FormValidators<any, any, any, any, any, any, any, any, any, any>\n\n const defaultDebounceMs = asyncDebounceMs ?? 0\n\n const runValidation = (\n props: Parameters<ValidationLogicProps['runValidation']>[0],\n ) => {\n return props.validators.filter(Boolean).map((validator) => {\n const validatorCause = validator?.cause || cause\n\n let debounceMs = defaultDebounceMs\n\n switch (validatorCause) {\n case 'change':\n debounceMs = onChangeAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'blur':\n debounceMs = onBlurAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'dynamic':\n debounceMs = onDynamicAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'submit':\n debounceMs = 0 // submit validators are always run immediately\n break\n default:\n break\n }\n\n if (cause === 'submit') {\n debounceMs = 0\n }\n\n return {\n cause: validatorCause,\n validate: validator!.fn,\n debounceMs: debounceMs,\n }\n })\n }\n\n return options.validationLogic({\n form: options.form,\n group: options.group,\n validators: options.validators,\n event: { type: cause, fieldName: options.fieldName, async: true },\n runValidation,\n })\n}\n\nexport const isGlobalFormValidationError = (\n error: unknown,\n): error is GlobalFormValidationError<unknown> => {\n return !!error && typeof error === 'object' && 'fields' in error\n}\n\nexport function evaluate<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n if (objA instanceof Date && objB instanceof Date) {\n return objA.getTime() === objB.getTime()\n }\n\n if (objA instanceof Map && objB instanceof Map) {\n if (objA.size !== objB.size) return false\n for (const [k, v] of objA) {\n if (!objB.has(k) || !Object.is(v, objB.get(k))) return false\n }\n return true\n }\n\n if (objA instanceof Set && objB instanceof Set) {\n if (objA.size !== objB.size) return false\n for (const v of objA) {\n if (!objB.has(v)) return false\n }\n return true\n }\n\n const keysA = Object.keys(objA)\n const keysB = Object.keys(objB)\n\n if (keysA.length !== keysB.length) {\n return false\n }\n\n // Two distinct non-plain, non-array objects with no own enumerable keys cannot\n // be compared by key iteration — the loop below would vacuously succeed and\n // treat them as equal regardless of their internal state. This covers Temporal\n // types, RegExp, and any class that exposes values only through getters.\n if (\n keysA.length === 0 &&\n !Array.isArray(objA) &&\n !Array.isArray(objB) &&\n (Object.getPrototypeOf(objA) !== Object.prototype ||\n Object.getPrototypeOf(objB) !== Object.prototype)\n ) {\n return false\n }\n\n for (const key of keysA) {\n // performs recursive search down the object tree\n\n if (\n !keysB.includes(key) ||\n !evaluate(objA[key as keyof T], objB[key as keyof T])\n ) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Determines the logic for determining the error source and value to set on the field meta within the form level sync/async validation.\n * @private\n */\nexport const determineFormLevelErrorSourceAndValue = ({\n newFormValidatorError,\n isPreviousErrorFromFormValidator,\n previousErrorValue,\n}: {\n newFormValidatorError: ValidationError\n isPreviousErrorFromFormValidator: boolean\n previousErrorValue: ValidationError\n}): {\n newErrorValue: ValidationError\n newSource: ValidationSource | undefined\n} => {\n // All falsy values are not considered errors\n if (newFormValidatorError) {\n return { newErrorValue: newFormValidatorError, newSource: 'form' }\n }\n\n // Clears form level error since it's now stale\n if (isPreviousErrorFromFormValidator) {\n return { newErrorValue: undefined, newSource: undefined }\n }\n\n // At this point, we have a preivous error which must have been set by the field validator, keep as is\n if (previousErrorValue) {\n return { newErrorValue: previousErrorValue, newSource: 'field' }\n }\n\n // No new or previous error, clear the error\n return { newErrorValue: undefined, newSource: undefined }\n}\n\n/**\n * Determines the logic for determining the error source and value to set on the field meta within the field level sync/async validation.\n * @private\n */\nexport const determineFieldLevelErrorSourceAndValue = ({\n formLevelError,\n fieldLevelError,\n}: {\n formLevelError: ValidationError\n fieldLevelError: ValidationError\n}): {\n newErrorValue: ValidationError\n newSource: ValidationSource | undefined\n} => {\n // At field level, we prioritize the field level error\n if (fieldLevelError) {\n return { newErrorValue: fieldLevelError, newSource: 'field' }\n }\n\n // If there is no field level error, and there is a form level error, we set the form level error\n if (formLevelError) {\n return { newErrorValue: formLevelError, newSource: 'form' }\n }\n\n return { newErrorValue: undefined, newSource: undefined }\n}\n\nexport function createFieldMap<T>(values: Readonly<T>): { [K in keyof T]: K } {\n const output: { [K in keyof T]: K } = {} as any\n\n for (const key in values) {\n output[key] = key\n }\n\n return output\n}\n\n/**\n * Merge the first parameter with the given overrides.\n * @private\n */\nexport function mergeOpts<T>(\n originalOpts: T | undefined | null,\n overrides: T,\n): T {\n if (originalOpts === undefined || originalOpts === null) {\n return overrides\n }\n\n return { ...originalOpts, ...overrides }\n}\n\n/*\n/ credit is due to https://github.com/lukeed/uuid for this code, with current npm\n/ attacks we didn't feel comfortable installing directly from npm. But big appreciation\n/ from the TanStack Form team <3.\n*/\n\nlet IDX = 256\nconst HEX: string[] = []\nlet BUFFER: number[] | undefined\n\nwhile (IDX--) {\n HEX[IDX] = (IDX + 256).toString(16).substring(1)\n}\n\nexport function uuid(): string {\n let i = 0\n let num: number\n let out = ''\n\n if (!BUFFER || IDX + 16 > 256) {\n BUFFER = new Array<number>(256)\n i = 256\n while (i--) {\n BUFFER[i] = (256 * Math.random()) | 0\n }\n i = 0\n IDX = 0\n }\n\n for (; i < 16; i++) {\n num = BUFFER[IDX + i] as number\n if (i === 6) out += HEX[(num & 15) | 64]\n else if (i === 8) out += HEX[(num & 63) | 128]\n else out += HEX[num]\n\n if (i & 1 && i > 1 && i < 11) out += '-'\n }\n\n IDX++\n return out\n}\n\nexport const throttleFormState = liteThrottle(\n (form: AnyFormApi) =>\n formEventClient.emit('form-state', {\n id: form.formId,\n state: form.store.state,\n }),\n {\n wait: 300,\n },\n)\n\n// Do not use a serialize and deserialize method like JSON.stringify/parse\n// as that will drop functions, dates, undefined, Infinity, NaN, etc.\nexport function deepCopy<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as any\n }\n\n if (Array.isArray(obj)) {\n const arrCopy = [] as any[]\n for (let i = 0; i < obj.length; i++) {\n arrCopy[i] = deepCopy(obj[i])\n }\n return arrCopy as any\n }\n\n if (obj instanceof Map) {\n const mapCopy = new Map()\n obj.forEach((value, key) => {\n mapCopy.set(key, deepCopy(value))\n })\n return mapCopy as any\n }\n\n if (obj instanceof Set) {\n const setCopy = new Set()\n obj.forEach((value) => {\n setCopy.add(deepCopy(value))\n })\n return setCopy as any\n }\n\n const copy: { [key: string]: any } = {}\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n copy[key] = deepCopy((obj as any)[key])\n }\n }\n return copy as T\n}\n\n/**\n * @private\n */\nexport function isFieldInGroup(groupName: string, fieldName: string) {\n return (\n fieldName === groupName ||\n fieldName.startsWith(`${groupName}.`) ||\n fieldName.startsWith(`${groupName}[`)\n )\n}\n"],"names":["liteThrottle","formEventClient"],"mappings":"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"}

@@ -65,2 +65,3 @@ import { FieldValidators } from './FieldApi.cjs';

form?: any;
group?: any;
fieldName?: string;

@@ -74,2 +75,3 @@ }): T extends FieldValidators<any, any, any, any, any, any, any, any, any, any, any, any> ? Array<SyncValidator<T['onChange'] | T['onBlur'] | T['onSubmit'] | T['onMount'] | T['onDynamic']>> : T extends FormValidators<any, any, any, any, any, any, any, any, any, any> ? Array<SyncValidator<T['onChange'] | T['onBlur'] | T['onSubmit'] | T['onMount'] | T['onDynamic']>> : never;

form?: any;
group?: any;
fieldName?: string;

@@ -113,2 +115,6 @@ }): T extends FieldValidators<any, any, any, any, any, any, any, any, any, any, any, any> ? Array<AsyncValidator<T['onChangeAsync'] | T['onBlurAsync'] | T['onSubmitAsync'] | T['onDynamicAsync']>> : T extends FormValidators<any, any, any, any, any, any, any, any, any, any> ? Array<AsyncValidator<T['onChangeAsync'] | T['onBlurAsync'] | T['onSubmitAsync'] | T['onDynamicAsync']>> : never;

export declare function deepCopy<T>(obj: T): T;
/**
* @private
*/
export declare function isFieldInGroup(groupName: string, fieldName: string): boolean;
export {};

@@ -19,3 +19,4 @@ "use strict";

const validatorsToAdd = [];
const modeToWatch = props.form.state.submissionAttempts === 0 ? mode : modeAfterSubmission;
const submissionAttempts = props.group ? props.group.state.meta.submissionAttempts : props.form.state.submissionAttempts;
const modeToWatch = submissionAttempts === 0 ? mode : modeAfterSubmission;
if ([modeToWatch, "submit"].includes(props.event.type)) {

@@ -22,0 +23,0 @@ validatorsToAdd.push(dynamicValidator);

@@ -1,1 +0,1 @@

{"version":3,"file":"ValidationLogic.cjs","sources":["../../src/ValidationLogic.ts"],"sourcesContent":["import type { AnyFormApi, FormValidators } from './FormApi'\n\nexport interface ValidationLogicValidatorsFn {\n // TODO: Type this properly\n fn: FormValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >[keyof FormValidators<any, any, any, any, any, any, any, any, any, any>]\n cause: 'change' | 'blur' | 'submit' | 'mount' | 'server' | 'dynamic'\n}\n\nexport interface ValidationLogicProps {\n // TODO: Type this properly\n form: AnyFormApi\n // TODO: Type this properly\n validators:\n | FormValidators<any, any, any, any, any, any, any, any, any, any>\n | undefined\n | null\n event: {\n type: 'blur' | 'change' | 'submit' | 'mount' | 'server'\n fieldName?: string\n async: boolean\n }\n runValidation: (props: {\n validators: Array<ValidationLogicValidatorsFn | undefined>\n form: AnyFormApi\n }) => void\n}\n\ninterface RevalidateLogicProps {\n /**\n * @default 'submit'\n *\n * This is the mode that will be used before the form has been submitted.\n * It will run the validation logic on `submit` by default, but can be set to `change` or `blur`.\n */\n mode?: 'change' | 'blur' | 'submit'\n /**\n * @default 'change'\n *\n * This is the mode that will be used after the form has been submitted.\n * It will run the validation logic on `change` by default, but can be set to `blur` or `submit`.\n */\n modeAfterSubmission?: 'change' | 'blur' | 'submit'\n}\n\nexport type ValidationLogicFn = (props: ValidationLogicProps) => void\n\n/**\n * This forces a form's validation logic to be ran as if it were a React Hook Form validation logic.\n *\n * This means that it will only run the `onDynamic` validator, and it will not run any other validators and changes the validation\n * type based on the state of the form itself.\n *\n * When the form is not yet submitted, it will not run the validation logic.\n * When the form is submitted, it will run the validation logic on `change`\n */\nexport const revalidateLogic =\n ({\n mode = 'submit',\n modeAfterSubmission = 'change',\n }: RevalidateLogicProps = {}): ValidationLogicFn =>\n (props) => {\n const validatorNames = Object.keys(props.validators ?? {})\n if (validatorNames.length === 0) {\n // No validators is a valid case, just return\n return props.runValidation({\n validators: [],\n form: props.form,\n })\n }\n\n const dynamicValidator = {\n fn: props.event.async\n ? props.validators!['onDynamicAsync']\n : props.validators!['onDynamic'],\n cause: 'dynamic',\n } as const\n\n const validatorsToAdd = [] as ValidationLogicValidatorsFn[]\n\n const modeToWatch =\n props.form.state.submissionAttempts === 0 ? mode : modeAfterSubmission\n\n if ([modeToWatch, 'submit'].includes(props.event.type)) {\n validatorsToAdd.push(dynamicValidator)\n }\n\n let defaultValidators = [] as ValidationLogicValidatorsFn[]\n\n defaultValidationLogic({\n ...props,\n runValidation: (vProps) => {\n defaultValidators = vProps.validators as ValidationLogicValidatorsFn[]\n },\n })\n\n if (validatorsToAdd.length === 0) {\n return props.runValidation({\n validators: defaultValidators,\n form: props.form,\n })\n }\n\n return props.runValidation({\n validators: [...defaultValidators, ...validatorsToAdd],\n form: props.form,\n })\n }\n\nexport const defaultValidationLogic: ValidationLogicFn = (props) => {\n // Handle case where no validators are provided\n if (!props.validators) {\n return props.runValidation({\n validators: [],\n form: props.form,\n })\n }\n\n const isAsync = props.event.async\n\n const onMountValidator = isAsync\n ? undefined\n : ({ fn: props.validators.onMount, cause: 'mount' } as const)\n\n const onChangeValidator = {\n fn: isAsync ? props.validators.onChangeAsync : props.validators.onChange,\n cause: 'change',\n } as const\n\n const onBlurValidator = {\n fn: isAsync ? props.validators.onBlurAsync : props.validators.onBlur,\n cause: 'blur',\n } as const\n\n const onSubmitValidator = {\n fn: isAsync ? props.validators.onSubmitAsync : props.validators.onSubmit,\n cause: 'submit',\n } as const\n\n // Allows us to clear onServer errors\n const onServerValidator = isAsync\n ? undefined\n : ({ fn: () => undefined, cause: 'server' } as const)\n\n switch (props.event.type) {\n case 'mount': {\n // Run mount validation\n return props.runValidation({\n validators: [onMountValidator],\n form: props.form,\n })\n }\n case 'submit': {\n // Run change, blur, submit, server validation\n return props.runValidation({\n validators: [\n onChangeValidator,\n onBlurValidator,\n onSubmitValidator,\n onServerValidator,\n ],\n form: props.form,\n })\n }\n case 'server': {\n // Run server validation\n return props.runValidation({\n validators: [],\n form: props.form,\n })\n }\n case 'blur': {\n // Run blur, server validation\n return props.runValidation({\n validators: [onBlurValidator, onServerValidator],\n form: props.form,\n })\n }\n case 'change': {\n // Run change, server validation\n return props.runValidation({\n validators: [onChangeValidator, onServerValidator],\n form: props.form,\n })\n }\n default: {\n throw new Error(`Unknown validation event type: ${props.event.type}`)\n }\n }\n}\n"],"names":[],"mappings":";;AAkEO,MAAM,kBACX,CAAC;AAAA,EACC,OAAO;AAAA,EACP,sBAAsB;AACxB,IAA0B,CAAA,MAC1B,CAAC,UAAU;AACT,QAAM,iBAAiB,OAAO,KAAK,MAAM,cAAc,CAAA,CAAE;AACzD,MAAI,eAAe,WAAW,GAAG;AAE/B,WAAO,MAAM,cAAc;AAAA,MACzB,YAAY,CAAA;AAAA,MACZ,MAAM,MAAM;AAAA,IAAA,CACb;AAAA,EACH;AAEA,QAAM,mBAAmB;AAAA,IACvB,IAAI,MAAM,MAAM,QACZ,MAAM,WAAY,gBAAgB,IAClC,MAAM,WAAY,WAAW;AAAA,IACjC,OAAO;AAAA,EAAA;AAGT,QAAM,kBAAkB,CAAA;AAExB,QAAM,cACJ,MAAM,KAAK,MAAM,uBAAuB,IAAI,OAAO;AAErD,MAAI,CAAC,aAAa,QAAQ,EAAE,SAAS,MAAM,MAAM,IAAI,GAAG;AACtD,oBAAgB,KAAK,gBAAgB;AAAA,EACvC;AAEA,MAAI,oBAAoB,CAAA;AAExB,yBAAuB;AAAA,IACrB,GAAG;AAAA,IACH,eAAe,CAAC,WAAW;AACzB,0BAAoB,OAAO;AAAA,IAC7B;AAAA,EAAA,CACD;AAED,MAAI,gBAAgB,WAAW,GAAG;AAChC,WAAO,MAAM,cAAc;AAAA,MACzB,YAAY;AAAA,MACZ,MAAM,MAAM;AAAA,IAAA,CACb;AAAA,EACH;AAEA,SAAO,MAAM,cAAc;AAAA,IACzB,YAAY,CAAC,GAAG,mBAAmB,GAAG,eAAe;AAAA,IACrD,MAAM,MAAM;AAAA,EAAA,CACb;AACH;AAEK,MAAM,yBAA4C,CAAC,UAAU;AAElE,MAAI,CAAC,MAAM,YAAY;AACrB,WAAO,MAAM,cAAc;AAAA,MACzB,YAAY,CAAA;AAAA,MACZ,MAAM,MAAM;AAAA,IAAA,CACb;AAAA,EACH;AAEA,QAAM,UAAU,MAAM,MAAM;AAE5B,QAAM,mBAAmB,UACrB,SACC,EAAE,IAAI,MAAM,WAAW,SAAS,OAAO,QAAA;AAE5C,QAAM,oBAAoB;AAAA,IACxB,IAAI,UAAU,MAAM,WAAW,gBAAgB,MAAM,WAAW;AAAA,IAChE,OAAO;AAAA,EAAA;AAGT,QAAM,kBAAkB;AAAA,IACtB,IAAI,UAAU,MAAM,WAAW,cAAc,MAAM,WAAW;AAAA,IAC9D,OAAO;AAAA,EAAA;AAGT,QAAM,oBAAoB;AAAA,IACxB,IAAI,UAAU,MAAM,WAAW,gBAAgB,MAAM,WAAW;AAAA,IAChE,OAAO;AAAA,EAAA;AAIT,QAAM,oBAAoB,UACtB,SACC,EAAE,IAAI,MAAM,QAAW,OAAO,SAAA;AAEnC,UAAQ,MAAM,MAAM,MAAA;AAAA,IAClB,KAAK,SAAS;AAEZ,aAAO,MAAM,cAAc;AAAA,QACzB,YAAY,CAAC,gBAAgB;AAAA,QAC7B,MAAM,MAAM;AAAA,MAAA,CACb;AAAA,IACH;AAAA,IACA,KAAK,UAAU;AAEb,aAAO,MAAM,cAAc;AAAA,QACzB,YAAY;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,MAAM,MAAM;AAAA,MAAA,CACb;AAAA,IACH;AAAA,IACA,KAAK,UAAU;AAEb,aAAO,MAAM,cAAc;AAAA,QACzB,YAAY,CAAA;AAAA,QACZ,MAAM,MAAM;AAAA,MAAA,CACb;AAAA,IACH;AAAA,IACA,KAAK,QAAQ;AAEX,aAAO,MAAM,cAAc;AAAA,QACzB,YAAY,CAAC,iBAAiB,iBAAiB;AAAA,QAC/C,MAAM,MAAM;AAAA,MAAA,CACb;AAAA,IACH;AAAA,IACA,KAAK,UAAU;AAEb,aAAO,MAAM,cAAc;AAAA,QACzB,YAAY,CAAC,mBAAmB,iBAAiB;AAAA,QACjD,MAAM,MAAM;AAAA,MAAA,CACb;AAAA,IACH;AAAA,IACA,SAAS;AACP,YAAM,IAAI,MAAM,kCAAkC,MAAM,MAAM,IAAI,EAAE;AAAA,IACtE;AAAA,EAAA;AAEJ;;;"}
{"version":3,"file":"ValidationLogic.cjs","sources":["../../src/ValidationLogic.ts"],"sourcesContent":["import type { AnyFormApi, FormValidators } from './FormApi'\nimport type { AnyFormGroupApi } from './FormGroupApi'\n\nexport interface ValidationLogicValidatorsFn {\n // TODO: Type this properly\n fn: FormValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >[keyof FormValidators<any, any, any, any, any, any, any, any, any, any>]\n cause: 'change' | 'blur' | 'submit' | 'mount' | 'server' | 'dynamic'\n}\n\nexport interface ValidationLogicProps {\n // TODO: Type this properly\n form: AnyFormApi\n /**\n * Set when the validators being processed belong to a `FormGroupApi`.\n * Allows validation strategies (e.g. `revalidateLogic`) to gate their\n * behavior on the group's own state instead of the parent form's.\n */\n group?: AnyFormGroupApi\n // TODO: Type this properly\n validators:\n | FormValidators<any, any, any, any, any, any, any, any, any, any>\n | undefined\n | null\n event: {\n type: 'blur' | 'change' | 'submit' | 'mount' | 'server'\n fieldName?: string\n async: boolean\n }\n runValidation: (props: {\n validators: Array<ValidationLogicValidatorsFn | undefined>\n form: AnyFormApi\n }) => void\n}\n\ninterface RevalidateLogicProps {\n /**\n * @default 'submit'\n *\n * This is the mode that will be used before the form has been submitted.\n * It will run the validation logic on `submit` by default, but can be set to `change` or `blur`.\n */\n mode?: 'change' | 'blur' | 'submit'\n /**\n * @default 'change'\n *\n * This is the mode that will be used after the form has been submitted.\n * It will run the validation logic on `change` by default, but can be set to `blur` or `submit`.\n */\n modeAfterSubmission?: 'change' | 'blur' | 'submit'\n}\n\nexport type ValidationLogicFn = (props: ValidationLogicProps) => void\n\n/**\n * This forces a form's validation logic to be ran as if it were a React Hook Form validation logic.\n *\n * This means that it will only run the `onDynamic` validator, and it will not run any other validators and changes the validation\n * type based on the state of the form itself.\n *\n * When the form is not yet submitted, it will not run the validation logic.\n * When the form is submitted, it will run the validation logic on `change`\n */\nexport const revalidateLogic =\n ({\n mode = 'submit',\n modeAfterSubmission = 'change',\n }: RevalidateLogicProps = {}): ValidationLogicFn =>\n (props) => {\n const validatorNames = Object.keys(props.validators ?? {})\n if (validatorNames.length === 0) {\n // No validators is a valid case, just return\n return props.runValidation({\n validators: [],\n form: props.form,\n })\n }\n\n const dynamicValidator = {\n fn: props.event.async\n ? props.validators!['onDynamicAsync']\n : props.validators!['onDynamic'],\n cause: 'dynamic',\n } as const\n\n const validatorsToAdd = [] as ValidationLogicValidatorsFn[]\n\n // When validating a `FormGroupApi`'s own validators, gate on the group's\n // submission attempts so a group's `onDynamic` validator only flips into\n // `modeAfterSubmission` after that group itself has been submitted.\n // Otherwise (form-level validators), gate on the parent form.\n const submissionAttempts = props.group\n ? props.group.state.meta.submissionAttempts\n : props.form.state.submissionAttempts\n\n const modeToWatch = submissionAttempts === 0 ? mode : modeAfterSubmission\n\n if ([modeToWatch, 'submit'].includes(props.event.type)) {\n validatorsToAdd.push(dynamicValidator)\n }\n\n let defaultValidators = [] as ValidationLogicValidatorsFn[]\n\n defaultValidationLogic({\n ...props,\n runValidation: (vProps) => {\n defaultValidators = vProps.validators as ValidationLogicValidatorsFn[]\n },\n })\n\n if (validatorsToAdd.length === 0) {\n return props.runValidation({\n validators: defaultValidators,\n form: props.form,\n })\n }\n\n return props.runValidation({\n validators: [...defaultValidators, ...validatorsToAdd],\n form: props.form,\n })\n }\n\nexport const defaultValidationLogic: ValidationLogicFn = (props) => {\n // Handle case where no validators are provided\n if (!props.validators) {\n return props.runValidation({\n validators: [],\n form: props.form,\n })\n }\n\n const isAsync = props.event.async\n\n const onMountValidator = isAsync\n ? undefined\n : ({ fn: props.validators.onMount, cause: 'mount' } as const)\n\n const onChangeValidator = {\n fn: isAsync ? props.validators.onChangeAsync : props.validators.onChange,\n cause: 'change',\n } as const\n\n const onBlurValidator = {\n fn: isAsync ? props.validators.onBlurAsync : props.validators.onBlur,\n cause: 'blur',\n } as const\n\n const onSubmitValidator = {\n fn: isAsync ? props.validators.onSubmitAsync : props.validators.onSubmit,\n cause: 'submit',\n } as const\n\n // Allows us to clear onServer errors\n const onServerValidator = isAsync\n ? undefined\n : ({ fn: () => undefined, cause: 'server' } as const)\n\n switch (props.event.type) {\n case 'mount': {\n // Run mount validation\n return props.runValidation({\n validators: [onMountValidator],\n form: props.form,\n })\n }\n case 'submit': {\n // Run change, blur, submit, server validation\n return props.runValidation({\n validators: [\n onChangeValidator,\n onBlurValidator,\n onSubmitValidator,\n onServerValidator,\n ],\n form: props.form,\n })\n }\n case 'server': {\n // Run server validation\n return props.runValidation({\n validators: [],\n form: props.form,\n })\n }\n case 'blur': {\n // Run blur, server validation\n return props.runValidation({\n validators: [onBlurValidator, onServerValidator],\n form: props.form,\n })\n }\n case 'change': {\n // Run change, server validation\n return props.runValidation({\n validators: [onChangeValidator, onServerValidator],\n form: props.form,\n })\n }\n default: {\n throw new Error(`Unknown validation event type: ${props.event.type}`)\n }\n }\n}\n"],"names":[],"mappings":"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"}
import { AnyFormApi, FormValidators } from './FormApi.cjs';
import { AnyFormGroupApi } from './FormGroupApi.cjs';
export interface ValidationLogicValidatorsFn {

@@ -8,2 +9,8 @@ fn: FormValidators<any, any, any, any, any, any, any, any, any, any>[keyof FormValidators<any, any, any, any, any, any, any, any, any, any>];

form: AnyFormApi;
/**
* Set when the validators being processed belong to a `FormGroupApi`.
* Allows validation strategies (e.g. `revalidateLogic`) to gate their
* behavior on the group's own state instead of the parent form's.
*/
group?: AnyFormGroupApi;
validators: FormValidators<any, any, any, any, any, any, any, any, any, any> | undefined | null;

@@ -10,0 +17,0 @@ event: {

@@ -0,6 +1,6 @@

import { FieldErrorMapFromValidator, FieldInfo, FieldLikeAPI, FieldLikeApiOptions, FieldLikeMetaBase, FieldLikeOptions, FieldLikeState, ListenerCause, UnwrapFieldAsyncValidateOrFn, UnwrapFieldValidateOrFn, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap } from './types.js';
import { ReadonlyStore } from '@tanstack/store';
import { DeepKeys, DeepValue, RejectPromiseValidator, UnwrapOneLevelOfArray } from './util-types.js';
import { StandardSchemaV1, StandardSchemaV1Issue, TStandardSchemaValidatorValue } from './standardSchemaValidator.js';
import { FieldInfo, FormApi, FormAsyncValidateOrFn, FormValidateAsyncFn, FormValidateFn, FormValidateOrFn } from './FormApi.js';
import { ListenerCause, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap, ValidationErrorMapSource } from './types.js';
import { DeepKeys, DeepValue, RejectPromiseValidator } from './util-types.js';
import { StandardSchemaV1, TStandardSchemaValidatorValue } from './standardSchemaValidator.js';
import { FormAsyncValidateOrFn, FormValidateOrFn } from './FormApi.js';
import { Updater } from './utils.js';

@@ -10,6 +10,2 @@ /**

*/
type FieldErrorMapFromValidator<TFormData, TName extends DeepKeys<TFormData>, TData extends DeepValue<TFormData, TName>, TOnMount extends undefined | FieldValidateOrFn<TFormData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TFormData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TFormData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TFormData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TFormData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TFormData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TFormData, TName, TData>> = Partial<Record<DeepKeys<TFormData>, ValidationErrorMap<TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>>>;
/**
* @private
*/
export type FieldValidateFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = (props: {

@@ -22,15 +18,2 @@ value: TData;

*/
export type FieldValidateOrFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FieldValidateFn<TParentData, TName, TData> | StandardSchemaV1<TData, unknown>;
type StandardBrandedSchemaV1<T> = T & {
__standardSchemaV1: true;
};
type UnwrapFormValidateOrFnForInner<TValidateOrFn extends undefined | FormValidateOrFn<any>> = [TValidateOrFn] extends [FormValidateFn<any>] ? ReturnType<TValidateOrFn> : [TValidateOrFn] extends [StandardSchemaV1<infer TOut, any>] ? StandardBrandedSchemaV1<TOut> : undefined;
export type UnwrapFieldValidateOrFn<TName extends string, TValidateOrFn extends undefined | FieldValidateOrFn<any, any, any>, TFormValidateOrFn extends undefined | FormValidateOrFn<any>> = ([TFormValidateOrFn] extends [StandardSchemaV1<any, infer TStandardOut>] ? TName extends keyof TStandardOut ? StandardSchemaV1Issue[] : undefined : undefined) | (UnwrapFormValidateOrFnForInner<TFormValidateOrFn> extends infer TFormValidateVal ? TFormValidateVal extends {
__standardSchemaV1: true;
} ? [DeepValue<TFormValidateVal, TName>] extends [never] ? undefined : StandardSchemaV1Issue[] : TFormValidateVal extends {
fields: any;
} ? TName extends keyof TFormValidateVal['fields'] ? TFormValidateVal['fields'][TName] : undefined : undefined : never) | ([TValidateOrFn] extends [FieldValidateFn<any, any, any>] ? ReturnType<TValidateOrFn> : [TValidateOrFn] extends [StandardSchemaV1<any, any>] ? StandardSchemaV1Issue[] : undefined);
/**
* @private
*/
export type FieldValidateAsyncFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = (options: {

@@ -44,12 +27,2 @@ value: TData;

*/
export type FieldAsyncValidateOrFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FieldValidateAsyncFn<TParentData, TName, TData> | StandardSchemaV1<TData, unknown>;
type UnwrapFormAsyncValidateOrFnForInner<TValidateOrFn extends undefined | FormAsyncValidateOrFn<any>> = [TValidateOrFn] extends [FormValidateAsyncFn<any>] ? Awaited<ReturnType<TValidateOrFn>> : [TValidateOrFn] extends [StandardSchemaV1<infer TOut, any>] ? StandardBrandedSchemaV1<TOut> : undefined;
export type UnwrapFieldAsyncValidateOrFn<TName extends string, TValidateOrFn extends undefined | FieldAsyncValidateOrFn<any, any, any>, TFormValidateOrFn extends undefined | FormAsyncValidateOrFn<any>> = ([TFormValidateOrFn] extends [StandardSchemaV1<any, infer TStandardOut>] ? TName extends keyof TStandardOut ? StandardSchemaV1Issue[] : undefined : undefined) | (UnwrapFormAsyncValidateOrFnForInner<TFormValidateOrFn> extends infer TFormValidateVal ? TFormValidateVal extends {
__standardSchemaV1: true;
} ? [DeepValue<TFormValidateVal, TName>] extends [never] ? undefined : StandardSchemaV1Issue[] : TFormValidateVal extends {
fields: any;
} ? TName extends keyof TFormValidateVal['fields'] ? TFormValidateVal['fields'][TName] : undefined : undefined : never) | ([TValidateOrFn] extends [FieldValidateAsyncFn<any, any, any>] ? Awaited<ReturnType<TValidateOrFn>> : [TValidateOrFn] extends [StandardSchemaV1<any, any>] ? StandardSchemaV1Issue[] : undefined);
/**
* @private
*/
export type FieldListenerFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = (props: {

@@ -59,2 +32,10 @@ value: TData;

}) => void;
/**
* @private
*/
export type FieldValidateOrFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FieldValidateFn<TParentData, TName, TData> | StandardSchemaV1<TData, unknown>;
/**
* @private
*/
export type FieldAsyncValidateOrFn<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FieldValidateAsyncFn<TParentData, TName, TData> | StandardSchemaV1<TData, unknown>;
export interface FieldValidators<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>> {

@@ -133,24 +114,6 @@ /**

onSubmit?: FieldListenerFn<TParentData, TName, TData>;
onGroupSubmit?: FieldListenerFn<TParentData, TName, TData>;
}
/**
* An object type representing the options for a field in a form.
*/
export interface FieldOptions<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>> {
interface FieldExtraOptions<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>> {
/**
* The field name. The type will be `DeepKeys<TParentData>` to ensure your name is a deep key of the parent dataset.
*/
name: TName;
/**
* An optional default value for the field.
*/
defaultValue?: NoInfer<TData>;
/**
* The default time to debounce async validation if there is not a more specific debounce time passed.
*/
asyncDebounceMs?: number;
/**
* If `true`, always run async validation, even if there are errors emitted during synchronous validation.
*/
asyncAlways?: boolean;
/**
* A list of validators to pass to the field

@@ -160,93 +123,14 @@ */

/**
* An optional object with default metadata for the field.
*/
defaultMeta?: Partial<FieldMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, any, any, any, any, any, any, any, any, any>>;
/**
* A list of listeners which attach to the corresponding events
*/
listeners?: FieldListeners<TParentData, TName, TData>;
/**
* Disable the `flat(1)` operation on `field.errors`. This is useful if you want to keep the error structure as is. Not suggested for most use-cases.
*/
disableErrorFlat?: boolean;
}
/**
* An object type representing the required options for the FieldApi class.
* An object type representing the options for a field in a form.
*/
export interface FieldApiOptions<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> extends FieldOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync> {
form: FormApi<TParentData, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>;
export interface FieldOptions<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>> extends FieldExtraOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>, FieldLikeOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync> {
}
export type FieldMetaBase<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TFormOnMount extends undefined | FormValidateOrFn<TParentData>, TFormOnChange extends undefined | FormValidateOrFn<TParentData>, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> = {
/**
* A flag indicating whether the field has been touched.
*/
isTouched: boolean;
/**
* A flag indicating whether the field has been blurred.
*/
isBlurred: boolean;
/**
* A flag that is `true` if the field's value has been modified by the user. Opposite of `isPristine`.
*/
isDirty: boolean;
/**
* A map of errors related to the field value.
*/
errorMap: ValidationErrorMap<UnwrapFieldValidateOrFn<TName, TOnMount, TFormOnMount>, UnwrapFieldValidateOrFn<TName, TOnChange, TFormOnChange>, UnwrapFieldAsyncValidateOrFn<TName, TOnChangeAsync, TFormOnChangeAsync>, UnwrapFieldValidateOrFn<TName, TOnBlur, TFormOnBlur>, UnwrapFieldAsyncValidateOrFn<TName, TOnBlurAsync, TFormOnBlurAsync>, UnwrapFieldValidateOrFn<TName, TOnSubmit, TFormOnSubmit>, UnwrapFieldAsyncValidateOrFn<TName, TOnSubmitAsync, TFormOnSubmitAsync>, UnwrapFieldValidateOrFn<TName, TOnDynamic, TFormOnDynamic>, UnwrapFieldAsyncValidateOrFn<TName, TOnDynamicAsync, TFormOnDynamicAsync>>;
/**
* @private allows tracking the source of the errors in the error map
*/
errorSourceMap: ValidationErrorMapSource;
/**
* A flag indicating whether the field is currently being validated.
*/
isValidating: boolean;
/**
* @private a counter that is incremented every time a structural array
* operation (push, insert, remove, swap, move, replace, clear) modifies
* the value of an array field. Adapters can subscribe to this to trigger
* re-renders for `mode="array"` fields without having to subscribe to the
* full field value.
*/
_arrayVersion: number;
};
export type AnyFieldMetaBase = FieldMetaBase<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
export type FieldMetaDerived<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TFormOnMount extends undefined | FormValidateOrFn<TParentData>, TFormOnChange extends undefined | FormValidateOrFn<TParentData>, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> = {
/**
* An array of errors related to the field value.
*/
errors: Array<UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnMount, TFormOnMount>> | UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnChange, TFormOnChange>> | UnwrapOneLevelOfArray<UnwrapFieldAsyncValidateOrFn<TName, TOnChangeAsync, TFormOnChangeAsync>> | UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnBlur, TFormOnBlur>> | UnwrapOneLevelOfArray<UnwrapFieldAsyncValidateOrFn<TName, TOnBlurAsync, TFormOnBlurAsync>> | UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnSubmit, TFormOnSubmit>> | UnwrapOneLevelOfArray<UnwrapFieldAsyncValidateOrFn<TName, TOnSubmitAsync, TFormOnSubmitAsync>> | UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnDynamic, TFormOnDynamic>> | UnwrapOneLevelOfArray<UnwrapFieldAsyncValidateOrFn<TName, TOnDynamicAsync, TFormOnDynamicAsync>>>;
/**
* A flag that is `true` if the field's value has not been modified by the user. Opposite of `isDirty`.
*/
isPristine: boolean;
/**
* A boolean indicating if the field is valid. Evaluates `true` if there are no field errors.
*/
isValid: boolean;
/**
* A flag indicating whether the field's current value is the default value
*/
isDefaultValue: boolean;
};
export type AnyFieldMetaDerived = FieldMetaDerived<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
export interface FieldApiOptions<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> extends FieldLikeApiOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>, FieldExtraOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync> {
}
/**
* An object type representing the metadata of a field in a form.
*/
export type FieldMeta<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TFormOnMount extends undefined | FormValidateOrFn<TParentData>, TFormOnChange extends undefined | FormValidateOrFn<TParentData>, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> = FieldMetaBase<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync> & FieldMetaDerived<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
export type AnyFieldMeta = FieldMeta<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
/**
* An object type representing the state of a field.
*/
export type FieldState<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, TFormOnMount extends undefined | FormValidateOrFn<TParentData>, TFormOnChange extends undefined | FormValidateOrFn<TParentData>, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> = {
/**
* The current value of the field.
*/
value: TData;
/**
* The current metadata of the field.
*/
meta: FieldMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
};
/**
* @public

@@ -270,3 +154,3 @@ *

*/
export declare class FieldApi<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> {
export declare class FieldApi<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData>, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> implements FieldLikeAPI<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta, FieldExtraOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>> {
/**

@@ -287,7 +171,7 @@ * A reference to the form API instance.

*/
store: ReadonlyStore<FieldState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>;
store: ReadonlyStore<FieldLikeState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>;
/**
* The current field state.
*/
get state(): FieldState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
get state(): FieldLikeState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
timeoutIds: {

@@ -330,7 +214,7 @@ validations: Record<ValidationCause, ReturnType<typeof setTimeout> | null>;

setValue: (updater: Updater<TData>, options?: UpdateMetaOptions) => void;
getMeta: () => FieldMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
getMeta: () => import('./types.js').FieldLikeMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
/**
* Sets the field metadata.
*/
setMeta: (updater: Updater<FieldMetaBase<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>) => void;
setMeta: (updater: Updater<FieldLikeMetaBase<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>) => void;
/**

@@ -387,2 +271,3 @@ * Gets the field information object.

skipFormValidation?: boolean;
skipGroupValidation?: boolean;
}) => ValidationError[] | Promise<ValidationError[]>;

@@ -406,3 +291,3 @@ /**

*/
parseValueWithSchema: (schema: StandardSchemaV1<TData, unknown>) => StandardSchemaV1Issue[] | undefined;
parseValueWithSchema: (schema: StandardSchemaV1<TData, unknown>) => import('./standardSchemaValidator.js').StandardSchemaV1Issue[] | undefined;
/**

@@ -413,3 +298,3 @@ * Parses the field's value with the given schema and returns

*/
parseValueWithSchemaAsync: (schema: StandardSchemaV1<TData, unknown>) => Promise<StandardSchemaV1Issue[] | undefined>;
parseValueWithSchemaAsync: (schema: StandardSchemaV1<TData, unknown>) => Promise<import('./standardSchemaValidator.js').StandardSchemaV1Issue[] | undefined>;
private triggerOnBlurListener;

@@ -420,3 +305,7 @@ /**

triggerOnChangeListener: () => void;
/**
* @private
*/
triggerOnSubmitListener: () => void;
}
export {};
import { batch, createStore } from "@tanstack/store";
import { standardSchemaValidators, isStandardSchemaValidator } from "./standardSchemaValidator.js";
import { defaultFieldMeta } from "./metaHelper.js";
import { evaluate, mergeOpts, getSyncValidatorArray, getAsyncValidatorArray, determineFieldLevelErrorSourceAndValue } from "./utils.js";
import { evaluate, mergeOpts, getSyncValidatorArray, getAsyncValidatorArray, isFieldInGroup, determineFieldLevelErrorSourceAndValue } from "./utils.js";
import { defaultValidationLogic } from "./ValidationLogic.js";

@@ -222,2 +222,5 @@ class FieldApi {

if (!field.instance) continue;
if (!(field.instance instanceof FieldApi)) {
continue;
}
const { onChangeListenTo, onBlurListenTo } = field.instance.options.validators || {};

@@ -453,13 +456,65 @@ if (cause === "change" && onChangeListenTo?.includes(this.name)) {

if (!this.state.meta.isTouched) return [];
const { fieldsErrorMap } = opts2?.skipFormValidation ? { fieldsErrorMap: {} } : this.form.validateSync(cause);
const { hasErrored } = this.validateSync(
cause,
fieldsErrorMap[this.name] ?? {}
const encompassingGroups = opts2?.skipGroupValidation ? [] : Array.from(this.form.formGroupApis).filter(
(group) => this.name.startsWith(group.name)
);
const formSyncResult = opts2?.skipFormValidation ? { fieldsErrorMap: {} } : this.form.validateSync(cause);
let fieldsErrorMap = formSyncResult.fieldsErrorMap[this.name] ?? {};
if (!opts2?.skipFormValidation) {
for (const group of encompassingGroups) {
if (group.state.meta.submissionAttempts === 0) continue;
const { fieldsErrorMap: groupFormErrors } = this.form.validateSync(
cause,
{
group,
dontUpdateFormErrorMap: true,
filterFieldNames: (fieldName) => isFieldInGroup(group.name, fieldName)
}
);
fieldsErrorMap = {
...fieldsErrorMap,
...groupFormErrors[this.name] ?? {}
};
}
}
const { hasErrored } = this.validateSync(cause, fieldsErrorMap);
const groupHasErroredWeakMap = /* @__PURE__ */ new WeakMap();
for (const group of encompassingGroups) {
const { hasErrored: groupHasErrored } = group.validateSync(
cause,
{},
{ skipRelatedFieldValidation: true }
);
groupHasErroredWeakMap.set(group, groupHasErrored);
}
if (hasErrored && !this.options.asyncAlways) {
this.getInfo().validationMetaMap[getErrorMapKey(cause)]?.lastAbortController.abort();
return this.state.meta.errors;
const groupErrors = [];
for (const group of encompassingGroups) {
group.getInfo().validationMetaMap[getErrorMapKey(cause)]?.lastAbortController.abort();
groupErrors.push(group.state.meta.errors);
}
return [...this.state.meta.errors, ...groupErrors.flat()];
}
const formValidationResultPromise = opts2?.skipFormValidation ? Promise.resolve({}) : this.form.validateAsync(cause);
return this.validateAsync(cause, formValidationResultPromise);
const fieldAsyncResults = this.validateAsync(
cause,
formValidationResultPromise
);
const groupAsyncResults = [];
for (const group of encompassingGroups) {
if (groupHasErroredWeakMap.get(group) && !group.options.asyncAlways) {
continue;
}
groupAsyncResults.push(
group.validateAsync(cause, formValidationResultPromise, {
skipRelatedFieldValidation: true
})
);
}
if (groupAsyncResults.length === 0) {
return fieldAsyncResults;
}
return Promise.all([fieldAsyncResults, ...groupAsyncResults]).then(
(results) => results.flat()
);
};

@@ -501,2 +556,38 @@ this.handleChange = (updater) => {

};
this.triggerOnBlurListener = () => {
const formDebounceMs = this.form.options.listeners?.onBlurDebounceMs;
if (formDebounceMs && formDebounceMs > 0) {
if (this.timeoutIds.formListeners.blur) {
clearTimeout(this.timeoutIds.formListeners.blur);
}
this.timeoutIds.formListeners.blur = setTimeout(() => {
this.form.options.listeners?.onBlur?.({
formApi: this.form,
fieldApi: this
});
}, formDebounceMs);
} else {
this.form.options.listeners?.onBlur?.({
formApi: this.form,
fieldApi: this
});
}
const fieldDebounceMs = this.options.listeners?.onBlurDebounceMs;
if (fieldDebounceMs && fieldDebounceMs > 0) {
if (this.timeoutIds.listeners.blur) {
clearTimeout(this.timeoutIds.listeners.blur);
}
this.timeoutIds.listeners.blur = setTimeout(() => {
this.options.listeners?.onBlur?.({
value: this.state.value,
fieldApi: this
});
}, fieldDebounceMs);
} else {
this.options.listeners?.onBlur?.({
value: this.state.value,
fieldApi: this
});
}
};
this.triggerOnChangeListener = () => {

@@ -537,3 +628,14 @@ const formDebounceMs = this.form.options.listeners?.onChangeDebounceMs;

}
for (const group of this.form.formGroupApis) {
if (isFieldInGroup(group.name, this.name)) {
group.triggerOnChangeListener();
}
}
};
this.triggerOnSubmitListener = () => {
this.options.listeners?.onSubmit?.({
value: this.state.value,
fieldApi: this
});
};
this.form = opts.form;

@@ -586,38 +688,2 @@ this.name = opts.name;

}
triggerOnBlurListener() {
const formDebounceMs = this.form.options.listeners?.onBlurDebounceMs;
if (formDebounceMs && formDebounceMs > 0) {
if (this.timeoutIds.formListeners.blur) {
clearTimeout(this.timeoutIds.formListeners.blur);
}
this.timeoutIds.formListeners.blur = setTimeout(() => {
this.form.options.listeners?.onBlur?.({
formApi: this.form,
fieldApi: this
});
}, formDebounceMs);
} else {
this.form.options.listeners?.onBlur?.({
formApi: this.form,
fieldApi: this
});
}
const fieldDebounceMs = this.options.listeners?.onBlurDebounceMs;
if (fieldDebounceMs && fieldDebounceMs > 0) {
if (this.timeoutIds.listeners.blur) {
clearTimeout(this.timeoutIds.listeners.blur);
}
this.timeoutIds.listeners.blur = setTimeout(() => {
this.options.listeners?.onBlur?.({
value: this.state.value,
fieldApi: this
});
}, fieldDebounceMs);
} else {
this.options.listeners?.onBlur?.({
value: this.state.value,
fieldApi: this
});
}
}
}

@@ -624,0 +690,0 @@ function normalizeError(rawError) {

@@ -0,7 +1,7 @@

import { AnyFieldLikeMetaBase, FormLikeAPI, UpdateMetaOptions, ValidationCause } from './types.js';
import { ReadonlyStore } from '@tanstack/store';
import { Updater } from './utils.js';
import { FormApi, FormAsyncValidateOrFn, FormValidateOrFn } from './FormApi.js';
import { AnyFieldMetaBase, FieldOptions } from './FieldApi.js';
import { FieldOptions } from './FieldApi.js';
import { DeepKeys, DeepKeysOfType, DeepValue, FieldsMap } from './util-types.js';
import { FieldManipulator, UpdateMetaOptions, ValidationCause } from './types.js';
export type AnyFieldGroupApi = FieldGroupApi<any, any, any, any, any, any, any, any, any, any, any, any, any, any>;

@@ -32,3 +32,3 @@ export interface FieldGroupState<in out TFieldGroupData> {

}
export declare class FieldGroupApi<in out TFormData, in out TFieldGroupData, in out TFields extends DeepKeysOfType<TFormData, TFieldGroupData | null | undefined> | FieldsMap<TFormData, TFieldGroupData>, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>, in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, in out TSubmitMeta = never> implements FieldManipulator<TFieldGroupData, TSubmitMeta> {
export declare class FieldGroupApi<in out TFormData, in out TFieldGroupData, in out TFields extends DeepKeysOfType<TFormData, TFieldGroupData | null | undefined> | FieldsMap<TFormData, TFieldGroupData>, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>, in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, in out TSubmitMeta = never> implements FormLikeAPI<TFieldGroupData, TSubmitMeta> {
/**

@@ -81,7 +81,7 @@ * The form that called this field group.

*/
getFieldMeta: <TField extends DeepKeys<TFieldGroupData>>(field: TField) => import('./FieldApi.js').AnyFieldMeta | undefined;
getFieldMeta: <TField extends DeepKeys<TFieldGroupData>>(field: TField) => import('./types.js').AnyFieldLikeMeta | undefined;
/**
* Updates the metadata of the specified field.
*/
setFieldMeta: <TField extends DeepKeys<TFieldGroupData>>(field: TField, updater: Updater<AnyFieldMetaBase>) => void;
setFieldMeta: <TField extends DeepKeys<TFieldGroupData>>(field: TField, updater: Updater<AnyFieldLikeMetaBase>) => void;
/**

@@ -88,0 +88,0 @@ * Sets the value of the specified field and optionally updates the touched state.

@@ -1,1 +0,1 @@

{"version":3,"file":"FieldGroupApi.js","sources":["../../src/FieldGroupApi.ts"],"sourcesContent":["import { createStore } from '@tanstack/store'\nimport { concatenatePaths, getBy, makePathArray } from './utils'\nimport type { ReadonlyStore } from '@tanstack/store'\nimport type { Updater } from './utils'\nimport type {\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\nimport type { AnyFieldMetaBase, FieldOptions } from './FieldApi'\nimport type {\n DeepKeys,\n DeepKeysOfType,\n DeepValue,\n FieldsMap,\n} from './util-types'\nimport type {\n FieldManipulator,\n UpdateMetaOptions,\n ValidationCause,\n} from './types'\n\nexport type AnyFieldGroupApi = FieldGroupApi<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\nexport interface FieldGroupState<in out TFieldGroupData> {\n /**\n * The current values of the field group\n */\n values: TFieldGroupData\n}\n\n/**\n * An object representing the options for a field group.\n */\nexport interface FieldGroupOptions<\n in out TFormData,\n in out TFieldGroupData,\n in out TFields extends\n | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n | FieldsMap<TFormData, TFieldGroupData>,\n in out TOnMount extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChange extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TSubmitMeta = never,\n> {\n form:\n | FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >\n | FieldGroupApi<\n any,\n TFormData,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n TSubmitMeta\n >\n /**\n * The path to the field group data.\n */\n fields: TFields\n /**\n * The expected subsetValues that the form must provide.\n */\n defaultValues?: TFieldGroupData\n /**\n * onSubmitMeta, the data passed from the handleSubmit handler, to the onSubmit function props\n */\n onSubmitMeta?: TSubmitMeta\n}\n\nexport class FieldGroupApi<\n in out TFormData,\n in out TFieldGroupData,\n in out TFields extends\n | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n | FieldsMap<TFormData, TFieldGroupData>,\n in out TOnMount extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChange extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TSubmitMeta = never,\n> implements FieldManipulator<TFieldGroupData, TSubmitMeta> {\n /**\n * The form that called this field group.\n */\n readonly form: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >\n\n readonly fieldsMap: TFields\n\n /**\n * Get the true name of the field. Not required within `Field` or `AppField`.\n * @private\n */\n getFormFieldName = <TField extends DeepKeys<TFieldGroupData>>(\n subfield: TField,\n ): DeepKeys<TFormData> => {\n if (typeof this.fieldsMap === 'string') {\n return concatenatePaths(this.fieldsMap, subfield)\n }\n\n const firstAccessor = makePathArray(subfield)[0]\n if (typeof firstAccessor !== 'string') {\n // top-level arrays cannot be mapped\n return ''\n }\n\n const restOfPath = subfield.slice(firstAccessor.length)\n const formMappedPath =\n // TFields is either a string or this. See guard above.\n (this.fieldsMap as FieldsMap<TFormData, TFieldGroupData>)[\n firstAccessor as keyof TFieldGroupData\n ]\n\n return concatenatePaths(formMappedPath, restOfPath)\n }\n\n /**\n * Get the field options with the true form DeepKeys for validators\n * @private\n */\n getFormFieldOptions = <\n TOptions extends FieldOptions<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n >(\n props: TOptions,\n ): TOptions => {\n const newProps = { ...props }\n const validators = newProps.validators\n\n newProps.name = this.getFormFieldName(props.name)\n\n if (\n validators &&\n (validators.onChangeListenTo || validators.onBlurListenTo)\n ) {\n const newValidators = { ...validators }\n\n const remapListenTo = (listenTo: DeepKeys<any>[] | undefined) => {\n if (!listenTo) return undefined\n return listenTo.map((localFieldName) =>\n this.getFormFieldName(localFieldName),\n )\n }\n\n newValidators.onChangeListenTo = remapListenTo(\n validators.onChangeListenTo,\n )\n newValidators.onBlurListenTo = remapListenTo(validators.onBlurListenTo)\n\n newProps.validators = newValidators\n }\n\n return newProps\n }\n\n store: ReadonlyStore<FieldGroupState<TFieldGroupData>>\n\n get state() {\n return this.store.state\n }\n\n /**\n * Constructs a new `FieldGroupApi` instance with the given form options.\n */\n constructor(\n opts: FieldGroupOptions<\n TFormData,\n TFieldGroupData,\n TFields,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) {\n if (opts.form instanceof FieldGroupApi) {\n const group = opts.form\n this.form = group.form as never\n\n // the DeepKey is already namespaced, so we need to ensure that we reference\n // the form and not the group\n if (typeof opts.fields === 'string') {\n this.fieldsMap = group.getFormFieldName(opts.fields) as TFields\n } else {\n // TypeScript has a tough time with generics being a union for some reason\n const fields = {\n ...(opts.fields as FieldsMap<TFormData, TFieldGroupData>),\n }\n for (const key in fields) {\n fields[key] = group.getFormFieldName(fields[key]) as never\n }\n this.fieldsMap = fields as never\n }\n } else {\n this.form = opts.form\n this.fieldsMap = opts.fields\n }\n\n this.store = createStore(() => {\n const currFormStore = this.form.store.get()\n let values: TFieldGroupData\n if (typeof this.fieldsMap === 'string') {\n // all values live at that name, so we can directly fetch it\n values = getBy(currFormStore.values, this.fieldsMap)\n } else {\n // we need to fetch the values from all places where they were mapped from\n values = {} as never\n const fields: Record<keyof TFieldGroupData, string> = this\n .fieldsMap as never\n for (const key in fields) {\n values[key] = getBy(currFormStore.values, fields[key])\n }\n }\n\n return {\n values,\n }\n })\n }\n\n /**\n * Mounts the field group instance to listen to value changes.\n *\n * TODO: Remove\n */\n mount = () => {\n return () => {}\n }\n\n /**\n * Validates the children of a specified array in the form starting from a given index until the end using the correct handlers for a given validation type.\n */\n validateArrayFieldsStartingFrom = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n cause: ValidationCause,\n ) => {\n return this.form.validateArrayFieldsStartingFrom(\n this.getFormFieldName(field),\n index,\n cause,\n )\n }\n\n /**\n * Validates a specified field in the form using the correct handlers for a given validation type.\n */\n validateField = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n cause: ValidationCause,\n ) => {\n return this.form.validateField(this.getFormFieldName(field), cause)\n }\n\n /**\n * Handles the form submission, performs validation, and calls the appropriate onSubmit or onSubmitInvalid callbacks.\n */\n handleSubmit(): Promise<void>\n handleSubmit(submitMeta: TSubmitMeta): Promise<void>\n async handleSubmit(submitMeta?: TSubmitMeta): Promise<void> {\n // cast is required since the implementation isn't one of the two overloads\n return this.form.handleSubmit(submitMeta as any)\n }\n\n /**\n * Gets the value of the specified field.\n */\n getFieldValue = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n ): DeepValue<TFieldGroupData, TField> => {\n return this.form.getFieldValue(this.getFormFieldName(field)) as DeepValue<\n TFieldGroupData,\n TField\n >\n }\n\n /**\n * Gets the metadata of the specified field.\n */\n getFieldMeta = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.getFieldMeta(this.getFormFieldName(field))\n }\n\n /**\n * Updates the metadata of the specified field.\n */\n setFieldMeta = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n updater: Updater<AnyFieldMetaBase>,\n ) => {\n return this.form.setFieldMeta(this.getFormFieldName(field), updater)\n }\n\n /**\n * Sets the value of the specified field and optionally updates the touched state.\n */\n setFieldValue = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n updater: Updater<DeepValue<TFieldGroupData, TField>>,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.setFieldValue(\n this.getFormFieldName(field) as never,\n updater as never,\n opts,\n )\n }\n\n /**\n * Delete a field and its subfields.\n */\n deleteField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.deleteField(this.getFormFieldName(field))\n }\n\n /**\n * Pushes a value into an array field.\n */\n pushFieldValue = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.pushFieldValue(\n this.getFormFieldName(field),\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Insert a value into an array field at the specified index.\n */\n insertFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.insertFieldValue(\n this.getFormFieldName(field),\n index,\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Replaces a value into an array field at the specified index.\n */\n replaceFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.replaceFieldValue(\n this.getFormFieldName(field),\n index,\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Removes a value from an array field at the specified index.\n */\n removeFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.removeFieldValue(this.getFormFieldName(field), index, opts)\n }\n\n /**\n * Swaps the values at the specified indices within an array field.\n */\n swapFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.swapFieldValues(\n this.getFormFieldName(field),\n index1,\n index2,\n opts,\n )\n }\n\n /**\n * Moves the value at the first specified index to the second specified index within an array field.\n */\n moveFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.moveFieldValues(\n this.getFormFieldName(field),\n index1,\n index2,\n opts,\n )\n }\n\n clearFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.clearFieldValues(this.getFormFieldName(field), opts)\n }\n\n /**\n * Resets the field value and meta to default state\n */\n resetField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.resetField(this.getFormFieldName(field))\n }\n\n validateAllFields = (cause: ValidationCause) =>\n this.form.validateAllFields(cause)\n}\n"],"names":["opts"],"mappings":";;AAgHO,MAAM,cAiB+C;AAAA;AAAA;AAAA;AAAA,EA4G1D,YACE,MAgBA;AApGF,SAAA,mBAAmB,CACjB,aACwB;AACxB,UAAI,OAAO,KAAK,cAAc,UAAU;AACtC,eAAO,iBAAiB,KAAK,WAAW,QAAQ;AAAA,MAClD;AAEA,YAAM,gBAAgB,cAAc,QAAQ,EAAE,CAAC;AAC/C,UAAI,OAAO,kBAAkB,UAAU;AAErC,eAAO;AAAA,MACT;AAEA,YAAM,aAAa,SAAS,MAAM,cAAc,MAAM;AACtD,YAAM;AAAA;AAAA,QAEH,KAAK,UACJ,aACF;AAAA;AAEF,aAAO,iBAAiB,gBAAgB,UAAU;AAAA,IACpD;AAMA,SAAA,sBAAsB,CAgBpB,UACa;AACb,YAAM,WAAW,EAAE,GAAG,MAAA;AACtB,YAAM,aAAa,SAAS;AAE5B,eAAS,OAAO,KAAK,iBAAiB,MAAM,IAAI;AAEhD,UACE,eACC,WAAW,oBAAoB,WAAW,iBAC3C;AACA,cAAM,gBAAgB,EAAE,GAAG,WAAA;AAE3B,cAAM,gBAAgB,CAAC,aAA0C;AAC/D,cAAI,CAAC,SAAU,QAAO;AACtB,iBAAO,SAAS;AAAA,YAAI,CAAC,mBACnB,KAAK,iBAAiB,cAAc;AAAA,UAAA;AAAA,QAExC;AAEA,sBAAc,mBAAmB;AAAA,UAC/B,WAAW;AAAA,QAAA;AAEb,sBAAc,iBAAiB,cAAc,WAAW,cAAc;AAEtE,iBAAS,aAAa;AAAA,MACxB;AAEA,aAAO;AAAA,IACT;AA+EA,SAAA,QAAQ,MAAM;AACZ,aAAO,MAAM;AAAA,MAAC;AAAA,IAChB;AAKA,SAAA,kCAAkC,OAGhC,OACA,OACA,UACG;AACH,aAAO,KAAK,KAAK;AAAA,QACf,KAAK,iBAAiB,KAAK;AAAA,QAC3B;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ;AAKA,SAAA,gBAAgB,CACd,OACA,UACG;AACH,aAAO,KAAK,KAAK,cAAc,KAAK,iBAAiB,KAAK,GAAG,KAAK;AAAA,IACpE;AAeA,SAAA,gBAAgB,CACd,UACuC;AACvC,aAAO,KAAK,KAAK,cAAc,KAAK,iBAAiB,KAAK,CAAC;AAAA,IAI7D;AAKA,SAAA,eAAe,CAA2C,UAAkB;AAC1E,aAAO,KAAK,KAAK,aAAa,KAAK,iBAAiB,KAAK,CAAC;AAAA,IAC5D;AAKA,SAAA,eAAe,CACb,OACA,YACG;AACH,aAAO,KAAK,KAAK,aAAa,KAAK,iBAAiB,KAAK,GAAG,OAAO;AAAA,IACrE;AAKA,SAAA,gBAAgB,CACd,OACA,SACAA,UACG;AACH,aAAO,KAAK,KAAK;AAAA,QACf,KAAK,iBAAiB,KAAK;AAAA,QAC3B;AAAA,QACAA;AAAA,MAAA;AAAA,IAEJ;AAKA,SAAA,cAAc,CAA2C,UAAkB;AACzE,aAAO,KAAK,KAAK,YAAY,KAAK,iBAAiB,KAAK,CAAC;AAAA,IAC3D;AAKA,SAAA,iBAAiB,CACf,OACA,OAGAA,UACG;AACH,aAAO,KAAK,KAAK;AAAA,QACf,KAAK,iBAAiB,KAAK;AAAA;AAAA,QAE3B;AAAA,QACAA;AAAA,MAAA;AAAA,IAEJ;AAKA,SAAA,mBAAmB,OAGjB,OACA,OACA,OAGAA,UACG;AACH,aAAO,KAAK,KAAK;AAAA,QACf,KAAK,iBAAiB,KAAK;AAAA,QAC3B;AAAA;AAAA,QAEA;AAAA,QACAA;AAAA,MAAA;AAAA,IAEJ;AAKA,SAAA,oBAAoB,OAGlB,OACA,OACA,OAGAA,UACG;AACH,aAAO,KAAK,KAAK;AAAA,QACf,KAAK,iBAAiB,KAAK;AAAA,QAC3B;AAAA;AAAA,QAEA;AAAA,QACAA;AAAA,MAAA;AAAA,IAEJ;AAKA,SAAA,mBAAmB,OAGjB,OACA,OACAA,UACG;AACH,aAAO,KAAK,KAAK,iBAAiB,KAAK,iBAAiB,KAAK,GAAG,OAAOA,KAAI;AAAA,IAC7E;AAKA,SAAA,kBAAkB,CAChB,OACA,QACA,QACAA,UACG;AACH,aAAO,KAAK,KAAK;AAAA,QACf,KAAK,iBAAiB,KAAK;AAAA,QAC3B;AAAA,QACA;AAAA,QACAA;AAAA,MAAA;AAAA,IAEJ;AAKA,SAAA,kBAAkB,CAChB,OACA,QACA,QACAA,UACG;AACH,aAAO,KAAK,KAAK;AAAA,QACf,KAAK,iBAAiB,KAAK;AAAA,QAC3B;AAAA,QACA;AAAA,QACAA;AAAA,MAAA;AAAA,IAEJ;AAEA,SAAA,mBAAmB,CACjB,OACAA,UACG;AACH,aAAO,KAAK,KAAK,iBAAiB,KAAK,iBAAiB,KAAK,GAAGA,KAAI;AAAA,IACtE;AAKA,SAAA,aAAa,CAA2C,UAAkB;AACxE,aAAO,KAAK,KAAK,WAAW,KAAK,iBAAiB,KAAK,CAAC;AAAA,IAC1D;AAEA,SAAA,oBAAoB,CAAC,UACnB,KAAK,KAAK,kBAAkB,KAAK;AA1QjC,QAAI,KAAK,gBAAgB,eAAe;AACtC,YAAM,QAAQ,KAAK;AACnB,WAAK,OAAO,MAAM;AAIlB,UAAI,OAAO,KAAK,WAAW,UAAU;AACnC,aAAK,YAAY,MAAM,iBAAiB,KAAK,MAAM;AAAA,MACrD,OAAO;AAEL,cAAM,SAAS;AAAA,UACb,GAAI,KAAK;AAAA,QAAA;AAEX,mBAAW,OAAO,QAAQ;AACxB,iBAAO,GAAG,IAAI,MAAM,iBAAiB,OAAO,GAAG,CAAC;AAAA,QAClD;AACA,aAAK,YAAY;AAAA,MACnB;AAAA,IACF,OAAO;AACL,WAAK,OAAO,KAAK;AACjB,WAAK,YAAY,KAAK;AAAA,IACxB;AAEA,SAAK,QAAQ,YAAY,MAAM;AAC7B,YAAM,gBAAgB,KAAK,KAAK,MAAM,IAAA;AACtC,UAAI;AACJ,UAAI,OAAO,KAAK,cAAc,UAAU;AAEtC,iBAAS,MAAM,cAAc,QAAQ,KAAK,SAAS;AAAA,MACrD,OAAO;AAEL,iBAAS,CAAA;AACT,cAAM,SAAgD,KACnD;AACH,mBAAW,OAAO,QAAQ;AACxB,iBAAO,GAAG,IAAI,MAAM,cAAc,QAAQ,OAAO,GAAG,CAAC;AAAA,QACvD;AAAA,MACF;AAEA,aAAO;AAAA,QACL;AAAA,MAAA;AAAA,IAEJ,CAAC;AAAA,EACH;AAAA,EApEA,IAAI,QAAQ;AACV,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EA6GA,MAAM,aAAa,YAAyC;AAE1D,WAAO,KAAK,KAAK,aAAa,UAAiB;AAAA,EACjD;AAkLF;"}
{"version":3,"file":"FieldGroupApi.js","sources":["../../src/FieldGroupApi.ts"],"sourcesContent":["import { createStore } from '@tanstack/store'\nimport { concatenatePaths, getBy, makePathArray } from './utils'\nimport type {\n AnyFieldLikeMetaBase,\n FormLikeAPI,\n UpdateMetaOptions,\n ValidationCause,\n} from './types'\nimport type { ReadonlyStore } from '@tanstack/store'\nimport type { Updater } from './utils'\nimport type {\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\nimport type { FieldOptions } from './FieldApi'\nimport type {\n DeepKeys,\n DeepKeysOfType,\n DeepValue,\n FieldsMap,\n} from './util-types'\n\nexport type AnyFieldGroupApi = FieldGroupApi<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\nexport interface FieldGroupState<in out TFieldGroupData> {\n /**\n * The current values of the field group\n */\n values: TFieldGroupData\n}\n\n/**\n * An object representing the options for a field group.\n */\nexport interface FieldGroupOptions<\n in out TFormData,\n in out TFieldGroupData,\n in out TFields extends\n | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n | FieldsMap<TFormData, TFieldGroupData>,\n in out TOnMount extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChange extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TSubmitMeta = never,\n> {\n form:\n | FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >\n | FieldGroupApi<\n any,\n TFormData,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n TSubmitMeta\n >\n /**\n * The path to the field group data.\n */\n fields: TFields\n /**\n * The expected subsetValues that the form must provide.\n */\n defaultValues?: TFieldGroupData\n /**\n * onSubmitMeta, the data passed from the handleSubmit handler, to the onSubmit function props\n */\n onSubmitMeta?: TSubmitMeta\n}\n\nexport class FieldGroupApi<\n in out TFormData,\n in out TFieldGroupData,\n in out TFields extends\n | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n | FieldsMap<TFormData, TFieldGroupData>,\n in out TOnMount extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChange extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TSubmitMeta = never,\n> implements FormLikeAPI<TFieldGroupData, TSubmitMeta> {\n /**\n * The form that called this field group.\n */\n readonly form: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >\n\n readonly fieldsMap: TFields\n\n /**\n * Get the true name of the field. Not required within `Field` or `AppField`.\n * @private\n */\n getFormFieldName = <TField extends DeepKeys<TFieldGroupData>>(\n subfield: TField,\n ): DeepKeys<TFormData> => {\n if (typeof this.fieldsMap === 'string') {\n return concatenatePaths(this.fieldsMap, subfield)\n }\n\n const firstAccessor = makePathArray(subfield)[0]\n if (typeof firstAccessor !== 'string') {\n // top-level arrays cannot be mapped\n return ''\n }\n\n const restOfPath = subfield.slice(firstAccessor.length)\n const formMappedPath =\n // TFields is either a string or this. See guard above.\n (this.fieldsMap as FieldsMap<TFormData, TFieldGroupData>)[\n firstAccessor as keyof TFieldGroupData\n ]\n\n return concatenatePaths(formMappedPath, restOfPath)\n }\n\n /**\n * Get the field options with the true form DeepKeys for validators\n * @private\n */\n getFormFieldOptions = <\n TOptions extends FieldOptions<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n >(\n props: TOptions,\n ): TOptions => {\n const newProps = { ...props }\n const validators = newProps.validators\n\n newProps.name = this.getFormFieldName(props.name)\n\n if (\n validators &&\n (validators.onChangeListenTo || validators.onBlurListenTo)\n ) {\n const newValidators = { ...validators }\n\n const remapListenTo = (listenTo: DeepKeys<any>[] | undefined) => {\n if (!listenTo) return undefined\n return listenTo.map((localFieldName) =>\n this.getFormFieldName(localFieldName),\n )\n }\n\n newValidators.onChangeListenTo = remapListenTo(\n validators.onChangeListenTo,\n )\n newValidators.onBlurListenTo = remapListenTo(validators.onBlurListenTo)\n\n newProps.validators = newValidators\n }\n\n return newProps\n }\n\n store: ReadonlyStore<FieldGroupState<TFieldGroupData>>\n\n get state() {\n return this.store.state\n }\n\n /**\n * Constructs a new `FieldGroupApi` instance with the given form options.\n */\n constructor(\n opts: FieldGroupOptions<\n TFormData,\n TFieldGroupData,\n TFields,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) {\n if (opts.form instanceof FieldGroupApi) {\n const group = opts.form\n this.form = group.form as never\n\n // the DeepKey is already namespaced, so we need to ensure that we reference\n // the form and not the group\n if (typeof opts.fields === 'string') {\n this.fieldsMap = group.getFormFieldName(opts.fields) as TFields\n } else {\n // TypeScript has a tough time with generics being a union for some reason\n const fields = {\n ...(opts.fields as FieldsMap<TFormData, TFieldGroupData>),\n }\n for (const key in fields) {\n fields[key] = group.getFormFieldName(fields[key]) as never\n }\n this.fieldsMap = fields as never\n }\n } else {\n this.form = opts.form\n this.fieldsMap = opts.fields\n }\n\n this.store = createStore(() => {\n const currFormStore = this.form.store.get()\n let values: TFieldGroupData\n if (typeof this.fieldsMap === 'string') {\n // all values live at that name, so we can directly fetch it\n values = getBy(currFormStore.values, this.fieldsMap)\n } else {\n // we need to fetch the values from all places where they were mapped from\n values = {} as never\n const fields: Record<keyof TFieldGroupData, string> = this\n .fieldsMap as never\n for (const key in fields) {\n values[key] = getBy(currFormStore.values, fields[key])\n }\n }\n\n return {\n values,\n }\n })\n }\n\n /**\n * Mounts the field group instance to listen to value changes.\n *\n * TODO: Remove\n */\n mount = () => {\n return () => {}\n }\n\n /**\n * Validates the children of a specified array in the form starting from a given index until the end using the correct handlers for a given validation type.\n */\n validateArrayFieldsStartingFrom = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n cause: ValidationCause,\n ) => {\n return this.form.validateArrayFieldsStartingFrom(\n this.getFormFieldName(field),\n index,\n cause,\n )\n }\n\n /**\n * Validates a specified field in the form using the correct handlers for a given validation type.\n */\n validateField = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n cause: ValidationCause,\n ) => {\n return this.form.validateField(this.getFormFieldName(field), cause)\n }\n\n /**\n * Handles the form submission, performs validation, and calls the appropriate onSubmit or onSubmitInvalid callbacks.\n */\n handleSubmit(): Promise<void>\n handleSubmit(submitMeta: TSubmitMeta): Promise<void>\n async handleSubmit(submitMeta?: TSubmitMeta): Promise<void> {\n // cast is required since the implementation isn't one of the two overloads\n return this.form.handleSubmit(submitMeta as any)\n }\n\n /**\n * Gets the value of the specified field.\n */\n getFieldValue = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n ): DeepValue<TFieldGroupData, TField> => {\n return this.form.getFieldValue(this.getFormFieldName(field)) as DeepValue<\n TFieldGroupData,\n TField\n >\n }\n\n /**\n * Gets the metadata of the specified field.\n */\n getFieldMeta = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.getFieldMeta(this.getFormFieldName(field))\n }\n\n /**\n * Updates the metadata of the specified field.\n */\n setFieldMeta = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n updater: Updater<AnyFieldLikeMetaBase>,\n ) => {\n return this.form.setFieldMeta(this.getFormFieldName(field), updater)\n }\n\n /**\n * Sets the value of the specified field and optionally updates the touched state.\n */\n setFieldValue = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n updater: Updater<DeepValue<TFieldGroupData, TField>>,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.setFieldValue(\n this.getFormFieldName(field) as never,\n updater as never,\n opts,\n )\n }\n\n /**\n * Delete a field and its subfields.\n */\n deleteField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.deleteField(this.getFormFieldName(field))\n }\n\n /**\n * Pushes a value into an array field.\n */\n pushFieldValue = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.pushFieldValue(\n this.getFormFieldName(field),\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Insert a value into an array field at the specified index.\n */\n insertFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.insertFieldValue(\n this.getFormFieldName(field),\n index,\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Replaces a value into an array field at the specified index.\n */\n replaceFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.replaceFieldValue(\n this.getFormFieldName(field),\n index,\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Removes a value from an array field at the specified index.\n */\n removeFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.removeFieldValue(this.getFormFieldName(field), index, opts)\n }\n\n /**\n * Swaps the values at the specified indices within an array field.\n */\n swapFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.swapFieldValues(\n this.getFormFieldName(field),\n index1,\n index2,\n opts,\n )\n }\n\n /**\n * Moves the value at the first specified index to the second specified index within an array field.\n */\n moveFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.moveFieldValues(\n this.getFormFieldName(field),\n index1,\n index2,\n opts,\n )\n }\n\n clearFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.clearFieldValues(this.getFormFieldName(field), opts)\n }\n\n /**\n * Resets the field value and meta to default state\n */\n resetField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.resetField(this.getFormFieldName(field))\n }\n\n validateAllFields = (cause: ValidationCause) =>\n this.form.validateAllFields(cause)\n}\n"],"names":["opts"],"mappings":"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"}

@@ -0,6 +1,7 @@

import { AnyFieldLikeMeta, AnyFieldLikeMetaBase, ExtractGlobalFormError, FieldInfo, FormLikeAPI, FormValidationError, FormValidationErrorMap, ListenerCause, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap, ValidationErrorMapKeys } from './types.js';
import { ReadonlyStore, Store } from '@tanstack/store';
import { ValidationLogicFn } from './ValidationLogic.js';
import { StandardSchemaV1, StandardSchemaV1Issue, TStandardSchemaValidatorValue } from './standardSchemaValidator.js';
import { AnyFieldApi, AnyFieldMeta, AnyFieldMetaBase, FieldApi } from './FieldApi.js';
import { ExtractGlobalFormError, FieldManipulator, FormValidationError, FormValidationErrorMap, ListenerCause, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap, ValidationErrorMapKeys } from './types.js';
import { AnyFieldApi } from './FieldApi.js';
import { AnyFormGroupApi, AnyFormGroupMeta, FormGroupState } from './FormGroupApi.js';
import { DeepKeys, DeepKeysOfType, DeepValue, RejectPromiseValidator } from './util-types.js';

@@ -77,8 +78,15 @@ import { Updater } from './utils.js';

}
interface FormListenersPropsGroup<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnDynamic extends undefined | FormValidateOrFn<TFormData>, TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, TSubmitMeta = never> {
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
groupApi: AnyFormGroupApi;
}
interface FormListenersPropsField<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnDynamic extends undefined | FormValidateOrFn<TFormData>, TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, TSubmitMeta = never> {
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
fieldApi: AnyFieldApi;
}
export interface FormListeners<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnDynamic extends undefined | FormValidateOrFn<TFormData>, TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, TSubmitMeta = never> {
onChange?: (props: {
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
fieldApi: AnyFieldApi;
}) => void;
onChange?: (props: FormListenersPropsField<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>) => void;
onChangeDebounceMs?: number;
onChangeGroup?: (props: FormListenersPropsGroup<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>) => void;
onChangeGroupDebounceMs?: number;
onBlur?: (props: {

@@ -96,6 +104,4 @@ formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;

}) => void;
onFieldUnmount?: (props: {
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>;
fieldApi: AnyFieldApi;
}) => void;
onFieldUnmount?: (props: FormListenersPropsField<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>) => void;
onGroupUnmount?: (props: FormListenersPropsGroup<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>) => void;
}

@@ -177,15 +183,2 @@ /**

/**
* An object representing the field information for a specific field within the form.
*/
export type FieldInfo<TFormData> = {
/**
* An instance of the FieldAPI.
*/
instance: FieldApi<TFormData, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any> | null;
/**
* A record of field validation internal handling.
*/
validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>;
};
/**
* An object representing the current state of the form.

@@ -209,4 +202,11 @@ */

*/
fieldMetaBase: Partial<Record<DeepKeys<TFormData>, AnyFieldMetaBase>>;
fieldMetaBase: Partial<Record<DeepKeys<TFormData>, AnyFieldLikeMetaBase>>;
/**
* A record of submission lifecycle state for each mounted `FormGroupApi`,
* keyed by the group's fully-qualified field name. Stored on the form so
* group-level state can be read from `FormApi` without having to walk the
* mounted group instances.
*/
formGroupStateBase: Partial<Record<string, FormGroupState>>;
/**
* A boolean indicating if the form is currently in the process of being submitted after `handleSubmit` is called.

@@ -302,3 +302,3 @@ *

*/
fieldMeta: Partial<Record<DeepKeys<TFormData>, AnyFieldMeta>>;
fieldMeta: Partial<Record<DeepKeys<TFormData>, AnyFieldLikeMeta>>;
};

@@ -314,2 +314,7 @@ export interface FormState<in out TFormData, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>, in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>> extends BaseFormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>, DerivedFormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer> {

export type AnyFormApi = FormApi<any, any, any, any, any, any, any, any, any, any, any, any>;
interface ValidateOpts<TFormData> {
dontUpdateFormErrorMap?: boolean;
filterFieldNames?: (fieldName: DeepKeys<TFormData>) => boolean;
group?: AnyFormGroupApi;
}
/**

@@ -326,3 +331,3 @@ * We cannot use methods and must use arrow functions. Otherwise, our React adapters

*/
export declare class FormApi<in out TFormData, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>, in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, in out TSubmitMeta = never> implements FieldManipulator<TFormData, TSubmitMeta> {
export declare class FormApi<in out TFormData, in out TOnMount extends undefined | FormValidateOrFn<TFormData>, in out TOnChange extends undefined | FormValidateOrFn<TFormData>, in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnBlur extends undefined | FormValidateOrFn<TFormData>, in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>, in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>, in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, in out TSubmitMeta = never> implements FormLikeAPI<TFormData, TSubmitMeta> {
/**

@@ -334,2 +339,10 @@ * The options for the form.

fieldMetaDerived: Store<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>['fieldMeta']>;
/**
* A derived store of every mounted `FormGroupApi`'s `meta`, keyed by
* group name. Mirrors `fieldMetaDerived` for fields: per-group `meta`
* is computed once on the form (from `baseStore.formGroupStateBase`,
* `fieldMetaDerived`, and the registered `formGroupApis`) so reads
* from a `FormGroupApi.store` instance stay minimal.
*/
formGroupMetaDerived: ReadonlyStore<Record<string, AnyFormGroupMeta>>;
store: ReadonlyStore<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>>;

@@ -340,2 +353,8 @@ /**

fieldInfo: Partial<Record<DeepKeys<TFormData>, FieldInfo<TFormData>>>;
/**
* The set of currently-mounted `FormGroupApi` instances belonging to
* this form. Used by `FieldApi.validate` to cascade field-level changes
* into the validators of any group that encompasses the field.
*/
formGroupApis: Set<AnyFormGroupApi>;
get state(): FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>;

@@ -405,3 +424,3 @@ /**

*/
validateSync: (cause: ValidationCause) => {
validateSync: (cause: ValidationCause, validateOpts?: ValidateOpts<TFormData>) => {
hasErrored: boolean;

@@ -413,7 +432,7 @@ fieldsErrorMap: FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>;

*/
validateAsync: (cause: ValidationCause) => Promise<FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>>;
validateAsync: (cause: ValidationCause, validateOpts?: ValidateOpts<TFormData>) => Promise<FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>>;
/**
* @private
*/
validate: (cause: ValidationCause) => FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync> | Promise<FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>>;
validate: (cause: ValidationCause, validateOpts?: ValidateOpts<TFormData>) => FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync> | Promise<FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync>>;
handleSubmit(): Promise<void>;

@@ -432,4 +451,10 @@ handleSubmit(submitMeta: TSubmitMeta): Promise<void>;

*/
getFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField) => AnyFieldMeta | undefined;
getFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField) => AnyFieldLikeMeta | undefined;
/**
* Gets the derived `meta` of the form group registered at the given
* name. Mirrors `getFieldMeta` for fields. Returns `undefined` if no
* `FormGroupApi` with that name is currently mounted.
*/
getFormGroupMeta: (name: string) => AnyFormGroupMeta | undefined;
/**
* Gets the field info of the specified field.

@@ -441,7 +466,7 @@ */

*/
setFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField, updater: Updater<AnyFieldMetaBase>) => void;
setFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField, updater: Updater<AnyFieldLikeMetaBase>) => void;
/**
* resets every field's meta
*/
resetFieldMeta: <TField extends DeepKeys<TFormData>>(fieldMeta: Partial<Record<TField, AnyFieldMeta>>) => Partial<Record<TField, AnyFieldMeta>>;
resetFieldMeta: <TField extends DeepKeys<TFormData>>(fieldMeta: Partial<Record<TField, AnyFieldLikeMeta>>) => Partial<Record<TField, AnyFieldLikeMeta>>;
/**

@@ -448,0 +473,0 @@ * Sets the value of the specified field and optionally updates the touched state.

import { batch, createStore } from "@tanstack/store";
import { throttleFormState, evaluate, setBy, getSyncValidatorArray, determineFormLevelErrorSourceAndValue, getAsyncValidatorArray, getBy, functionalUpdate, deleteBy, mergeOpts, isGlobalFormValidationError, uuid, isNonEmptyArray } from "./utils.js";
import { throttleFormState, evaluate, setBy, getSyncValidatorArray, determineFormLevelErrorSourceAndValue, getAsyncValidatorArray, getBy, functionalUpdate, deleteBy, mergeOpts, isGlobalFormValidationError, uuid, isNonEmptyArray, isFieldInGroup } from "./utils.js";
import { defaultValidationLogic } from "./ValidationLogic.js";

@@ -12,2 +12,3 @@ import { standardSchemaValidators, isStandardSchemaValidator } from "./standardSchemaValidator.js";

fieldMetaBase: defaultState.fieldMetaBase ?? {},
formGroupStateBase: defaultState.formGroupStateBase ?? {},
isSubmitted: defaultState.isSubmitted ?? false,

@@ -35,2 +36,3 @@ isSubmitting: defaultState.isSubmitting ?? false,

this.fieldInfo = {};
this.formGroupApis = /* @__PURE__ */ new Set();
this.mount = () => {

@@ -168,6 +170,9 @@ const cleanupDevtoolBroadcast = this.store.subscribe(() => {

Promise.resolve().then(
() => fieldInstance.validate(cause, { skipFormValidation: true })
() => fieldInstance.validate(cause, {
skipFormValidation: true,
skipGroupValidation: true
})
)
);
if (!field.instance.state.meta.isTouched) {
if (!field.instance.store.state.meta.isTouched) {
field.instance.setMeta((prev) => ({ ...prev, isTouched: true }));

@@ -213,3 +218,3 @@ }

}
if (!fieldInstance.state.meta.isTouched) {
if (!fieldInstance.store.state.meta.isTouched) {
fieldInstance.setMeta((prev) => ({ ...prev, isTouched: true }));

@@ -219,6 +224,7 @@ }

};
this.validateSync = (cause) => {
this.validateSync = (cause, validateOpts) => {
const validates = getSyncValidatorArray(cause, {
...this.options,
form: this,
group: validateOpts?.group,
validationLogic: this.options.validationLogic || defaultValidationLogic

@@ -242,6 +248,11 @@ });

const errorMapKey = getErrorMapKey(validateObj.cause);
const allFieldsToProcess = /* @__PURE__ */ new Set([
let allFieldsToProcess = /* @__PURE__ */ new Set([
...Object.keys(this.state.fieldMeta),
...Object.keys(fieldErrors || {})
]);
if (validateOpts?.filterFieldNames) {
allFieldsToProcess = new Set(
[...allFieldsToProcess].filter(validateOpts.filterFieldNames)
);
}
for (const field of allFieldsToProcess) {

@@ -287,10 +298,12 @@ if (this.baseStore.state.fieldMetaBase[field] === void 0 && !fieldErrors?.[field]) {

}
if (this.state.errorMap?.[errorMapKey] !== formError) {
this.baseStore.setState((prev) => ({
...prev,
errorMap: {
...prev.errorMap,
[errorMapKey]: formError
}
}));
if (!validateOpts?.dontUpdateFormErrorMap) {
if (this.state.errorMap?.[errorMapKey] !== formError) {
this.baseStore.setState((prev) => ({
...prev,
errorMap: {
...prev.errorMap,
[errorMapKey]: formError
}
}));
}
}

@@ -301,2 +314,5 @@ if (formError || fieldErrors) {

}
if (validateOpts?.dontUpdateFormErrorMap) {
return;
}
const submitErrKey = getErrorMapKey("submit");

@@ -331,6 +347,7 @@ if (

};
this.validateAsync = async (cause) => {
this.validateAsync = async (cause, validateOpts) => {
const validates = getAsyncValidatorArray(cause, {
...this.options,
form: this,
group: validateOpts?.group,
validationLogic: this.options.validationLogic || defaultValidationLogic

@@ -388,5 +405,7 @@ });

const errorMapKey = getErrorMapKey(validateObj.cause);
for (const field of Object.keys(
this.state.fieldMeta
)) {
let fields = Object.keys(this.state.fieldMeta);
if (validateOpts?.filterFieldNames) {
fields = fields.filter(validateOpts.filterFieldNames);
}
for (const field of fields) {
if (this.baseStore.state.fieldMetaBase[field] === void 0) {

@@ -411,6 +430,3 @@ continue;

});
if (
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
currentErrorMap?.[errorMapKey] !== newErrorValue
) {
if (currentErrorMap?.[errorMapKey] !== newErrorValue) {
this.setFieldMeta(field, (prev) => ({

@@ -429,9 +445,11 @@ ...prev,

}
this.baseStore.setState((prev) => ({
...prev,
errorMap: {
...prev.errorMap,
[errorMapKey]: formError
}
}));
if (!validateOpts?.dontUpdateFormErrorMap) {
this.baseStore.setState((prev) => ({
...prev,
errorMap: {
...prev.errorMap,
[errorMapKey]: formError
}
}));
}
resolve(

@@ -469,8 +487,11 @@ fieldErrorsFromFormValidators ? { fieldErrors: fieldErrorsFromFormValidators, errorMapKey } : void 0

};
this.validate = (cause) => {
const { hasErrored, fieldsErrorMap } = this.validateSync(cause);
this.validate = (cause, validateOpts) => {
const { hasErrored, fieldsErrorMap } = this.validateSync(
cause,
validateOpts
);
if (hasErrored && !this.options.asyncAlways) {
return fieldsErrorMap;
}
return this.validateAsync(cause);
return this.validateAsync(cause, validateOpts);
};

@@ -491,3 +512,3 @@ this._handleSubmit = async (submitMeta) => {

if (!field.instance) return;
if (!field.instance.state.meta.isTouched) {
if (!field.instance.store.state.meta.isTouched) {
field.instance.setMeta((prev) => ({ ...prev, isTouched: true }));

@@ -548,6 +569,3 @@ }

(field) => {
field.instance?.options.listeners?.onSubmit?.({
value: field.instance.state.value,
fieldApi: field.instance
});
field.instance?.triggerOnSubmitListener();
}

@@ -598,2 +616,5 @@ );

};
this.getFormGroupMeta = (name) => {
return this.formGroupMetaDerived.state[name];
};
this.getFieldInfo = (field) => {

@@ -992,2 +1013,103 @@ return this.fieldInfo[field] ||= {

);
this.formGroupMetaDerived = createStore(
(prevVal) => {
const currBaseStore = this.baseStore.get();
const currFieldMeta = this.fieldMetaDerived.get();
const result = {};
for (const group of this.formGroupApis) {
const groupName = group.name;
const lifecycle = currBaseStore.formGroupStateBase[groupName] ?? {
isSubmitted: false,
isSubmitting: false,
isValidating: false,
submissionAttempts: 0,
isSubmitSuccessful: false
};
const ownFieldMeta = currFieldMeta[groupName];
let isFieldsValidating = false;
let isFieldsValid = true;
let aggIsTouched = false;
let aggIsBlurred = false;
let aggIsDefaultValue = true;
let aggIsDirty = false;
for (const fieldName in currFieldMeta) {
if (fieldName === groupName) continue;
if (!isFieldInGroup(groupName, fieldName)) continue;
const m = currFieldMeta[fieldName];
if (!m) continue;
if (m.isValidating) isFieldsValidating = true;
if (!m.isValid) isFieldsValid = false;
if (m.isTouched) aggIsTouched = true;
if (m.isBlurred) aggIsBlurred = true;
if (!m.isDefaultValue) aggIsDefaultValue = false;
if (m.isDirty) aggIsDirty = true;
}
const isPristine = !aggIsDirty;
const isValidating = !!isFieldsValidating || lifecycle.isValidating;
const errorMap = ownFieldMeta?.errorMap ?? {};
const errorSourceMap = ownFieldMeta?.errorSourceMap ?? {};
const hasOnMountError = Boolean(
errorMap.onMount || Object.entries(currFieldMeta).some(
([fieldName, field]) => field && fieldName !== groupName && isFieldInGroup(groupName, fieldName) && field.errorMap.onMount
)
);
const prevGroupMeta = prevVal?.[groupName];
let errors = prevGroupMeta?.errors ?? [];
if (!prevGroupMeta || prevGroupMeta.__srcErrorMap !== errorMap) {
errors = Object.values(errorMap).reduce((acc, curr) => {
if (curr === void 0) return acc;
if (curr && typeof curr === "object" && "fields" in curr) {
const groupErr = curr.group;
if (groupErr !== void 0) acc.push(groupErr);
return acc;
}
acc.push(curr);
return acc;
}, []);
}
const isGroupValid = errors.length === 0;
const isValid = isFieldsValid && isGroupValid;
const submitInvalid = group.options.canSubmitWhenInvalid ?? false;
const canSubmit = lifecycle.submissionAttempts === 0 && !aggIsTouched && !hasOnMountError || !isValidating && !lifecycle.isSubmitting && isValid || submitInvalid;
if (prevGroupMeta && prevGroupMeta.errorMap === errorMap && prevGroupMeta.errorSourceMap === errorSourceMap && prevGroupMeta.errors === errors && prevGroupMeta.isFieldsValidating === isFieldsValidating && prevGroupMeta.isFieldsValid === isFieldsValid && prevGroupMeta.isGroupValid === isGroupValid && prevGroupMeta.isValid === isValid && prevGroupMeta.canSubmit === canSubmit && prevGroupMeta.isTouched === aggIsTouched && prevGroupMeta.isBlurred === aggIsBlurred && prevGroupMeta.isPristine === isPristine && prevGroupMeta.isDefaultValue === aggIsDefaultValue && prevGroupMeta.isDirty === aggIsDirty && prevGroupMeta.isValidating === isValidating && prevGroupMeta.isSubmitting === lifecycle.isSubmitting && prevGroupMeta.isSubmitted === lifecycle.isSubmitted && prevGroupMeta.submissionAttempts === lifecycle.submissionAttempts && prevGroupMeta.isSubmitSuccessful === lifecycle.isSubmitSuccessful) {
result[groupName] = prevGroupMeta;
continue;
}
const meta = {
// Submission lifecycle (spread first; `isValidating` below
// intentionally overrides `lifecycle.isValidating` with the
// OR of group-level + descendant-field validating).
...lifecycle,
// Field-meta-base fields (so `setMeta` updates can roundtrip
// through `state.meta`).
errorMap,
errorSourceMap,
_arrayVersion: ownFieldMeta?._arrayVersion ?? 0,
// Aggregated descendant booleans (override field-level meaning
// for groups — a group's "field" itself never receives input).
isTouched: aggIsTouched,
isBlurred: aggIsBlurred,
isDirty: aggIsDirty,
isPristine,
isDefaultValue: aggIsDefaultValue,
// Aggregated validity
isValid,
errors,
isValidating,
// Group-only flags
isFieldsValidating,
isFieldsValid,
isGroupValid,
canSubmit
};
Object.defineProperty(meta, "__srcErrorMap", {
value: errorMap,
enumerable: false,
configurable: true
});
result[groupName] = meta;
}
return result;
}
);
let prevBaseStoreForStore = void 0;

@@ -994,0 +1116,0 @@ this.store = createStore((prevVal) => {

export * from './FormApi.js';
export * from './FieldApi.js';
export * from './FormGroupApi.js';
export * from './utils.js';

@@ -4,0 +5,0 @@ export * from './util-types.js';

import { FormApi } from "./FormApi.js";
import { FieldApi } from "./FieldApi.js";
import { concatenatePaths, createFieldMap, deepCopy, deleteBy, determineFieldLevelErrorSourceAndValue, determineFormLevelErrorSourceAndValue, evaluate, functionalUpdate, getAsyncValidatorArray, getBy, getSyncValidatorArray, isGlobalFormValidationError, isNonEmptyArray, makePathArray, mergeOpts, setBy, throttleFormState, uuid } from "./utils.js";
import { FormGroupApi, getDefaultFormGroupMeta } from "./FormGroupApi.js";
import { concatenatePaths, createFieldMap, deepCopy, deleteBy, determineFieldLevelErrorSourceAndValue, determineFormLevelErrorSourceAndValue, evaluate, functionalUpdate, getAsyncValidatorArray, getBy, getSyncValidatorArray, isFieldInGroup, isGlobalFormValidationError, isNonEmptyArray, makePathArray, mergeOpts, setBy, throttleFormState, uuid } from "./utils.js";
import { mergeForm, mutateMergeDeep } from "./mergeForm.js";

@@ -15,2 +16,3 @@ import { formOptions } from "./formOptions.js";

FormApi,
FormGroupApi,
concatenatePaths,

@@ -29,3 +31,5 @@ createFieldMap,

getBy,
getDefaultFormGroupMeta,
getSyncValidatorArray,
isFieldInGroup,
isGlobalFormValidationError,

@@ -32,0 +36,0 @@ isNonEmptyArray,

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
import { FormApi, FormAsyncValidateOrFn, FormValidateOrFn } from './FormApi.js';
import { AnyFieldMeta } from './FieldApi.js';
import { DeepKeys } from './util-types.js';
export declare const defaultFieldMeta: AnyFieldMeta;
import { AnyFieldLikeMeta } from './types.js';
export declare const defaultFieldMeta: AnyFieldLikeMeta;
export declare function metaHelper<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnDynamic extends undefined | FormValidateOrFn<TFormData>, TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, TSubmitMeta = never>(formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>): {

@@ -6,0 +6,0 @@ bumpArrayVersion: (field: DeepKeys<TFormData>) => void;

@@ -1,1 +0,1 @@

{"version":3,"file":"metaHelper.js","sources":["../../src/metaHelper.ts"],"sourcesContent":["import type {\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\nimport type { AnyFieldMeta } from './FieldApi'\nimport type { DeepKeys } from './util-types'\n\ntype ValueFieldMode = 'insert' | 'remove' | 'swap' | 'move'\n\nexport const defaultFieldMeta: AnyFieldMeta = {\n isValidating: false,\n isTouched: false,\n isBlurred: false,\n isDirty: false,\n isPristine: true,\n isValid: true,\n isDefaultValue: true,\n errors: [],\n errorMap: {},\n errorSourceMap: {},\n _arrayVersion: 0,\n}\n\nexport function metaHelper<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n>(\n formApi: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n) {\n /**\n * Bump the `_arrayVersion` counter on the array field's meta. This\n * provides a cheap, structural signal that adapters can subscribe to in\n * order to trigger re-renders when the array is mutated in ways that\n * `length` alone cannot detect (e.g. swaps and moves).\n */\n function bumpArrayVersion(field: DeepKeys<TFormData>) {\n const currentMeta = formApi.getFieldMeta(field) ?? defaultFieldMeta\n formApi.setFieldMeta(field, {\n ...currentMeta,\n _arrayVersion: (currentMeta._arrayVersion || 0) + 1,\n })\n }\n\n /**\n * Handle the meta shift caused from moving a field from one index to another.\n */\n function handleArrayMove(\n field: DeepKeys<TFormData>,\n fromIndex: number,\n toIndex: number,\n ) {\n bumpArrayVersion(field)\n const affectedFields = getAffectedFields(field, fromIndex, 'move', toIndex)\n\n const startIndex = Math.min(fromIndex, toIndex)\n const endIndex = Math.max(fromIndex, toIndex)\n for (let i = startIndex; i <= endIndex; i++) {\n affectedFields.push(getFieldPath(field, i))\n }\n\n // Store the original field meta that will be reapplied at the destination index\n const fromFields = Object.keys(formApi.fieldInfo).reduce(\n (fieldMap, fieldKey) => {\n if (fieldKey.startsWith(getFieldPath(field, fromIndex))) {\n fieldMap.set(\n fieldKey as DeepKeys<TFormData>,\n formApi.getFieldMeta(fieldKey as DeepKeys<TFormData>),\n )\n }\n return fieldMap\n },\n new Map<DeepKeys<TFormData>, AnyFieldMeta | undefined>(),\n )\n\n shiftMeta(affectedFields, fromIndex < toIndex ? 'up' : 'down')\n\n // Reapply the stored field meta at the destination index\n Object.keys(formApi.fieldInfo)\n .filter((fieldKey) => fieldKey.startsWith(getFieldPath(field, toIndex)))\n .forEach((fieldKey) => {\n const fromKey = fieldKey.replace(\n getFieldPath(field, toIndex),\n getFieldPath(field, fromIndex),\n ) as DeepKeys<TFormData>\n\n const fromMeta = fromFields.get(fromKey)\n if (fromMeta) {\n formApi.setFieldMeta(fieldKey as DeepKeys<TFormData>, fromMeta)\n }\n })\n }\n\n /**\n * Handle the meta shift from removing a field at the specified index.\n */\n function handleArrayRemove(field: DeepKeys<TFormData>, index: number) {\n bumpArrayVersion(field)\n const affectedFields = getAffectedFields(field, index, 'remove')\n\n shiftMeta(affectedFields, 'up')\n }\n\n /**\n * Handle the meta shift from swapping two fields at the specified indeces.\n */\n function handleArraySwap(\n field: DeepKeys<TFormData>,\n index: number,\n secondIndex: number,\n ) {\n bumpArrayVersion(field)\n const affectedFields = getAffectedFields(field, index, 'swap', secondIndex)\n\n affectedFields.forEach((fieldKey) => {\n if (!fieldKey.toString().startsWith(getFieldPath(field, index))) {\n return\n }\n\n const swappedKey = fieldKey\n .toString()\n .replace(\n getFieldPath(field, index),\n getFieldPath(field, secondIndex),\n ) as DeepKeys<TFormData>\n\n const [meta1, meta2] = [\n formApi.getFieldMeta(fieldKey),\n formApi.getFieldMeta(swappedKey),\n ]\n\n if (meta1) formApi.setFieldMeta(swappedKey, meta1)\n if (meta2) formApi.setFieldMeta(fieldKey, meta2)\n })\n }\n\n /**\n * Handle the meta shift from inserting a field at the specified index.\n */\n function handleArrayInsert(field: DeepKeys<TFormData>, insertIndex: number) {\n bumpArrayVersion(field)\n const affectedFields = getAffectedFields(field, insertIndex, 'insert')\n\n shiftMeta(affectedFields, 'down')\n\n affectedFields.forEach((fieldKey) => {\n if (fieldKey.toString().startsWith(getFieldPath(field, insertIndex))) {\n formApi.setFieldMeta(fieldKey, getEmptyFieldMeta())\n }\n })\n }\n\n function getFieldPath(\n field: DeepKeys<TFormData>,\n index: number,\n ): DeepKeys<TFormData> {\n return `${field}[${index}]` as DeepKeys<TFormData>\n }\n\n function getAffectedFields(\n field: DeepKeys<TFormData>,\n index: number,\n mode: ValueFieldMode,\n secondIndex?: number,\n ): DeepKeys<TFormData>[] {\n const affectedFieldKeys = [getFieldPath(field, index)]\n\n switch (mode) {\n case 'swap':\n affectedFieldKeys.push(getFieldPath(field, secondIndex!))\n break\n case 'move': {\n const [startIndex, endIndex] = [\n Math.min(index, secondIndex!),\n Math.max(index, secondIndex!),\n ]\n for (let i = startIndex; i <= endIndex; i++) {\n affectedFieldKeys.push(getFieldPath(field, i))\n }\n break\n }\n default: {\n const currentValue = formApi.getFieldValue(field)\n const fieldItems = Array.isArray(currentValue)\n ? (currentValue as Array<unknown>).length\n : 0\n for (let i = index + 1; i < fieldItems; i++) {\n affectedFieldKeys.push(getFieldPath(field, i))\n }\n break\n }\n }\n\n return Object.keys(formApi.fieldInfo).filter((fieldKey) =>\n affectedFieldKeys.some((key) => fieldKey.startsWith(key)),\n ) as DeepKeys<TFormData>[]\n }\n\n function updateIndex(\n fieldKey: string,\n direction: 'up' | 'down',\n ): DeepKeys<TFormData> {\n return fieldKey.replace(/\\[(\\d+)\\]/, (_, num) => {\n const currIndex = parseInt(num, 10)\n const newIndex =\n direction === 'up' ? currIndex + 1 : Math.max(0, currIndex - 1)\n return `[${newIndex}]`\n }) as DeepKeys<TFormData>\n }\n\n function shiftMeta(fields: DeepKeys<TFormData>[], direction: 'up' | 'down') {\n const sortedFields = direction === 'up' ? fields : [...fields].reverse()\n\n sortedFields.forEach((fieldKey) => {\n const nextFieldKey = updateIndex(fieldKey.toString(), direction)\n const nextFieldMeta = formApi.getFieldMeta(nextFieldKey)\n if (nextFieldMeta) {\n formApi.setFieldMeta(fieldKey, nextFieldMeta)\n } else {\n formApi.setFieldMeta(fieldKey, getEmptyFieldMeta())\n }\n })\n }\n\n const getEmptyFieldMeta = (): AnyFieldMeta => defaultFieldMeta\n\n return {\n bumpArrayVersion,\n handleArrayMove,\n handleArrayRemove,\n handleArraySwap,\n handleArrayInsert,\n }\n}\n"],"names":[],"mappings":"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"}
{"version":3,"file":"metaHelper.js","sources":["../../src/metaHelper.ts"],"sourcesContent":["import type {\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\nimport type { DeepKeys } from './util-types'\nimport type { AnyFieldLikeMeta } from './types'\n\ntype ValueFieldMode = 'insert' | 'remove' | 'swap' | 'move'\n\nexport const defaultFieldMeta: AnyFieldLikeMeta = {\n isValidating: false,\n isTouched: false,\n isBlurred: false,\n isDirty: false,\n isPristine: true,\n isValid: true,\n isDefaultValue: true,\n errors: [],\n errorMap: {},\n errorSourceMap: {},\n _arrayVersion: 0,\n}\n\nexport function metaHelper<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n>(\n formApi: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n) {\n /**\n * Bump the `_arrayVersion` counter on the array field's meta. This\n * provides a cheap, structural signal that adapters can subscribe to in\n * order to trigger re-renders when the array is mutated in ways that\n * `length` alone cannot detect (e.g. swaps and moves).\n */\n function bumpArrayVersion(field: DeepKeys<TFormData>) {\n const currentMeta = formApi.getFieldMeta(field) ?? defaultFieldMeta\n formApi.setFieldMeta(field, {\n ...currentMeta,\n _arrayVersion: (currentMeta._arrayVersion || 0) + 1,\n })\n }\n\n /**\n * Handle the meta shift caused from moving a field from one index to another.\n */\n function handleArrayMove(\n field: DeepKeys<TFormData>,\n fromIndex: number,\n toIndex: number,\n ) {\n bumpArrayVersion(field)\n const affectedFields = getAffectedFields(field, fromIndex, 'move', toIndex)\n\n const startIndex = Math.min(fromIndex, toIndex)\n const endIndex = Math.max(fromIndex, toIndex)\n for (let i = startIndex; i <= endIndex; i++) {\n affectedFields.push(getFieldPath(field, i))\n }\n\n // Store the original field meta that will be reapplied at the destination index\n const fromFields = Object.keys(formApi.fieldInfo).reduce(\n (fieldMap, fieldKey) => {\n if (fieldKey.startsWith(getFieldPath(field, fromIndex))) {\n fieldMap.set(\n fieldKey as DeepKeys<TFormData>,\n formApi.getFieldMeta(fieldKey as DeepKeys<TFormData>),\n )\n }\n return fieldMap\n },\n new Map<DeepKeys<TFormData>, AnyFieldLikeMeta | undefined>(),\n )\n\n shiftMeta(affectedFields, fromIndex < toIndex ? 'up' : 'down')\n\n // Reapply the stored field meta at the destination index\n Object.keys(formApi.fieldInfo)\n .filter((fieldKey) => fieldKey.startsWith(getFieldPath(field, toIndex)))\n .forEach((fieldKey) => {\n const fromKey = fieldKey.replace(\n getFieldPath(field, toIndex),\n getFieldPath(field, fromIndex),\n ) as DeepKeys<TFormData>\n\n const fromMeta = fromFields.get(fromKey)\n if (fromMeta) {\n formApi.setFieldMeta(fieldKey as DeepKeys<TFormData>, fromMeta)\n }\n })\n }\n\n /**\n * Handle the meta shift from removing a field at the specified index.\n */\n function handleArrayRemove(field: DeepKeys<TFormData>, index: number) {\n bumpArrayVersion(field)\n const affectedFields = getAffectedFields(field, index, 'remove')\n\n shiftMeta(affectedFields, 'up')\n }\n\n /**\n * Handle the meta shift from swapping two fields at the specified indeces.\n */\n function handleArraySwap(\n field: DeepKeys<TFormData>,\n index: number,\n secondIndex: number,\n ) {\n bumpArrayVersion(field)\n const affectedFields = getAffectedFields(field, index, 'swap', secondIndex)\n\n affectedFields.forEach((fieldKey) => {\n if (!fieldKey.toString().startsWith(getFieldPath(field, index))) {\n return\n }\n\n const swappedKey = fieldKey\n .toString()\n .replace(\n getFieldPath(field, index),\n getFieldPath(field, secondIndex),\n ) as DeepKeys<TFormData>\n\n const [meta1, meta2] = [\n formApi.getFieldMeta(fieldKey),\n formApi.getFieldMeta(swappedKey),\n ]\n\n if (meta1) formApi.setFieldMeta(swappedKey, meta1)\n if (meta2) formApi.setFieldMeta(fieldKey, meta2)\n })\n }\n\n /**\n * Handle the meta shift from inserting a field at the specified index.\n */\n function handleArrayInsert(field: DeepKeys<TFormData>, insertIndex: number) {\n bumpArrayVersion(field)\n const affectedFields = getAffectedFields(field, insertIndex, 'insert')\n\n shiftMeta(affectedFields, 'down')\n\n affectedFields.forEach((fieldKey) => {\n if (fieldKey.toString().startsWith(getFieldPath(field, insertIndex))) {\n formApi.setFieldMeta(fieldKey, getEmptyFieldMeta())\n }\n })\n }\n\n function getFieldPath(\n field: DeepKeys<TFormData>,\n index: number,\n ): DeepKeys<TFormData> {\n return `${field}[${index}]` as DeepKeys<TFormData>\n }\n\n function getAffectedFields(\n field: DeepKeys<TFormData>,\n index: number,\n mode: ValueFieldMode,\n secondIndex?: number,\n ): DeepKeys<TFormData>[] {\n const affectedFieldKeys = [getFieldPath(field, index)]\n\n switch (mode) {\n case 'swap':\n affectedFieldKeys.push(getFieldPath(field, secondIndex!))\n break\n case 'move': {\n const [startIndex, endIndex] = [\n Math.min(index, secondIndex!),\n Math.max(index, secondIndex!),\n ]\n for (let i = startIndex; i <= endIndex; i++) {\n affectedFieldKeys.push(getFieldPath(field, i))\n }\n break\n }\n default: {\n const currentValue = formApi.getFieldValue(field)\n const fieldItems = Array.isArray(currentValue)\n ? (currentValue as Array<unknown>).length\n : 0\n for (let i = index + 1; i < fieldItems; i++) {\n affectedFieldKeys.push(getFieldPath(field, i))\n }\n break\n }\n }\n\n return Object.keys(formApi.fieldInfo).filter((fieldKey) =>\n affectedFieldKeys.some((key) => fieldKey.startsWith(key)),\n ) as DeepKeys<TFormData>[]\n }\n\n function updateIndex(\n fieldKey: string,\n direction: 'up' | 'down',\n ): DeepKeys<TFormData> {\n return fieldKey.replace(/\\[(\\d+)\\]/, (_, num) => {\n const currIndex = parseInt(num, 10)\n const newIndex =\n direction === 'up' ? currIndex + 1 : Math.max(0, currIndex - 1)\n return `[${newIndex}]`\n }) as DeepKeys<TFormData>\n }\n\n function shiftMeta(fields: DeepKeys<TFormData>[], direction: 'up' | 'down') {\n const sortedFields = direction === 'up' ? fields : [...fields].reverse()\n\n sortedFields.forEach((fieldKey) => {\n const nextFieldKey = updateIndex(fieldKey.toString(), direction)\n const nextFieldMeta = formApi.getFieldMeta(nextFieldKey)\n if (nextFieldMeta) {\n formApi.setFieldMeta(fieldKey, nextFieldMeta)\n } else {\n formApi.setFieldMeta(fieldKey, getEmptyFieldMeta())\n }\n })\n }\n\n const getEmptyFieldMeta = (): AnyFieldLikeMeta => defaultFieldMeta\n\n return {\n bumpArrayVersion,\n handleArrayMove,\n handleArrayRemove,\n handleArraySwap,\n handleArrayInsert,\n }\n}\n"],"names":[],"mappings":"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"}

@@ -44,4 +44,5 @@ function prefixSchemaToErrors(issues, formValue) {

if (!result.issues) return;
if (validationSource === "field")
if (validationSource === "field") {
return result.issues;
}
return transformFormIssues(result.issues, value);

@@ -55,4 +56,5 @@ },

if (!result.issues) return;
if (validationSource === "field")
if (validationSource === "field") {
return result.issues;
}
return transformFormIssues(result.issues, value);

@@ -59,0 +61,0 @@ }

@@ -1,1 +0,1 @@

{"version":3,"file":"standardSchemaValidator.js","sources":["../../src/standardSchemaValidator.ts"],"sourcesContent":["import type { ValidationSource } from './types'\n\nexport type TStandardSchemaValidatorValue<\n TData,\n TSource extends ValidationSource = ValidationSource,\n> = {\n value: TData\n validationSource: TSource\n}\n\nexport type TStandardSchemaValidatorIssue<\n TSource extends ValidationSource = ValidationSource,\n> = TSource extends 'form'\n ? {\n form: Record<string, StandardSchemaV1Issue[]>\n fields: Record<string, StandardSchemaV1Issue[]>\n }\n : TSource extends 'field'\n ? StandardSchemaV1Issue[]\n : never\n\nfunction prefixSchemaToErrors(\n issues: readonly StandardSchemaV1Issue[],\n formValue: unknown,\n) {\n const schema = new Map<string, StandardSchemaV1Issue[]>()\n\n for (const issue of issues) {\n const issuePath = issue.path ?? []\n\n let currentFormValue = formValue\n let path = ''\n\n for (let i = 0; i < issuePath.length; i++) {\n const pathSegment = issuePath[i]\n if (pathSegment === undefined) continue\n\n const segment =\n typeof pathSegment === 'object' ? pathSegment.key : pathSegment\n\n // Standard Schema doesn't specify if paths should use numbers or stringified numbers for array access.\n // However, if we follow the path it provides and encounter an array, then we can assume it's intended for array access.\n const segmentAsNumber = Number(segment)\n if (Array.isArray(currentFormValue) && !Number.isNaN(segmentAsNumber)) {\n path += `[${segmentAsNumber}]`\n } else {\n path += (i > 0 ? '.' : '') + String(segment)\n }\n\n if (typeof currentFormValue === 'object' && currentFormValue !== null) {\n currentFormValue = currentFormValue[segment as never]\n } else {\n currentFormValue = undefined\n }\n }\n schema.set(path, (schema.get(path) ?? []).concat(issue))\n }\n\n return Object.fromEntries(schema)\n}\n\nconst transformFormIssues = <TSource extends ValidationSource>(\n issues: readonly StandardSchemaV1Issue[],\n formValue: unknown,\n): TStandardSchemaValidatorIssue<TSource> => {\n const schemaErrors = prefixSchemaToErrors(issues, formValue)\n return {\n form: schemaErrors,\n fields: schemaErrors,\n } as TStandardSchemaValidatorIssue<TSource>\n}\n\nexport const standardSchemaValidators = {\n validate<TSource extends ValidationSource = ValidationSource>(\n {\n value,\n validationSource,\n }: TStandardSchemaValidatorValue<unknown, TSource>,\n schema: StandardSchemaV1,\n ): TStandardSchemaValidatorIssue<TSource> | undefined {\n const result = schema['~standard'].validate(value)\n\n if (result instanceof Promise) {\n throw new Error('async function passed to sync validator')\n }\n\n if (!result.issues) return\n\n if (validationSource === 'field')\n return result.issues as TStandardSchemaValidatorIssue<TSource>\n return transformFormIssues<TSource>(result.issues, value)\n },\n async validateAsync<TSource extends ValidationSource>(\n {\n value,\n validationSource,\n }: TStandardSchemaValidatorValue<unknown, TSource>,\n schema: StandardSchemaV1,\n ): Promise<TStandardSchemaValidatorIssue<TSource> | undefined> {\n const result = await schema['~standard'].validate(value)\n\n if (!result.issues) return\n\n if (validationSource === 'field')\n return result.issues as TStandardSchemaValidatorIssue<TSource>\n return transformFormIssues<TSource>(result.issues, value)\n },\n}\n\nexport const isStandardSchemaValidator = (\n validator: unknown,\n): validator is StandardSchemaV1 =>\n !!validator && '~standard' in (validator as object)\n\n/**\n * The Standard Schema interface.\n */\nexport type StandardSchemaV1<Input = unknown, Output = Input> = {\n /**\n * The Standard Schema properties.\n */\n readonly '~standard': StandardSchemaV1Props<Input, Output>\n}\n\n/**\n * The Standard Schema properties interface.\n */\ninterface StandardSchemaV1Props<Input = unknown, Output = Input> {\n /**\n * The version number of the standard.\n */\n readonly version: 1\n /**\n * The vendor name of the schema library.\n */\n readonly vendor: string\n /**\n * Validates unknown input values.\n */\n readonly validate: (\n value: unknown,\n ) => StandardSchemaV1Result<Output> | Promise<StandardSchemaV1Result<Output>>\n /**\n * Inferred types associated with the schema.\n */\n readonly types?: StandardSchemaV1Types<Input, Output> | undefined\n}\n/**\n * The result interface of the validate function.\n */\ntype StandardSchemaV1Result<Output> =\n | StandardSchemaV1SuccessResult<Output>\n | StandardSchemaV1FailureResult\n/**\n * The result interface if validation succeeds.\n */\ninterface StandardSchemaV1SuccessResult<Output> {\n /**\n * The typed output value.\n */\n readonly value: Output\n /**\n * The non-existent issues.\n */\n readonly issues?: undefined\n}\n/**\n * The result interface if validation fails.\n */\ninterface StandardSchemaV1FailureResult {\n /**\n * The issues of failed validation.\n */\n readonly issues: ReadonlyArray<StandardSchemaV1Issue>\n}\n/**\n * The issue interface of the failure output.\n */\nexport interface StandardSchemaV1Issue {\n /**\n * The error message of the issue.\n */\n readonly message: string\n /**\n * The path of the issue, if any.\n */\n readonly path?:\n | ReadonlyArray<PropertyKey | StandardSchemaV1PathSegment>\n | undefined\n}\n/**\n * The path segment interface of the issue.\n */\ninterface StandardSchemaV1PathSegment {\n /**\n * The key representing a path segment.\n */\n readonly key: PropertyKey\n}\n/**\n * The Standard Schema types interface.\n */\ninterface StandardSchemaV1Types<Input = unknown, Output = Input> {\n /**\n * The input type of the schema.\n */\n readonly input: Input\n /**\n * The output type of the schema.\n */\n readonly output: Output\n}\n"],"names":[],"mappings":"AAqBA,SAAS,qBACP,QACA,WACA;AACA,QAAM,6BAAa,IAAA;AAEnB,aAAW,SAAS,QAAQ;AAC1B,UAAM,YAAY,MAAM,QAAQ,CAAA;AAEhC,QAAI,mBAAmB;AACvB,QAAI,OAAO;AAEX,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,YAAM,cAAc,UAAU,CAAC;AAC/B,UAAI,gBAAgB,OAAW;AAE/B,YAAM,UACJ,OAAO,gBAAgB,WAAW,YAAY,MAAM;AAItD,YAAM,kBAAkB,OAAO,OAAO;AACtC,UAAI,MAAM,QAAQ,gBAAgB,KAAK,CAAC,OAAO,MAAM,eAAe,GAAG;AACrE,gBAAQ,IAAI,eAAe;AAAA,MAC7B,OAAO;AACL,iBAAS,IAAI,IAAI,MAAM,MAAM,OAAO,OAAO;AAAA,MAC7C;AAEA,UAAI,OAAO,qBAAqB,YAAY,qBAAqB,MAAM;AACrE,2BAAmB,iBAAiB,OAAgB;AAAA,MACtD,OAAO;AACL,2BAAmB;AAAA,MACrB;AAAA,IACF;AACA,WAAO,IAAI,OAAO,OAAO,IAAI,IAAI,KAAK,CAAA,GAAI,OAAO,KAAK,CAAC;AAAA,EACzD;AAEA,SAAO,OAAO,YAAY,MAAM;AAClC;AAEA,MAAM,sBAAsB,CAC1B,QACA,cAC2C;AAC3C,QAAM,eAAe,qBAAqB,QAAQ,SAAS;AAC3D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,EAAA;AAEZ;AAEO,MAAM,2BAA2B;AAAA,EACtC,SACE;AAAA,IACE;AAAA,IACA;AAAA,EAAA,GAEF,QACoD;AACpD,UAAM,SAAS,OAAO,WAAW,EAAE,SAAS,KAAK;AAEjD,QAAI,kBAAkB,SAAS;AAC7B,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAEA,QAAI,CAAC,OAAO,OAAQ;AAEpB,QAAI,qBAAqB;AACvB,aAAO,OAAO;AAChB,WAAO,oBAA6B,OAAO,QAAQ,KAAK;AAAA,EAC1D;AAAA,EACA,MAAM,cACJ;AAAA,IACE;AAAA,IACA;AAAA,EAAA,GAEF,QAC6D;AAC7D,UAAM,SAAS,MAAM,OAAO,WAAW,EAAE,SAAS,KAAK;AAEvD,QAAI,CAAC,OAAO,OAAQ;AAEpB,QAAI,qBAAqB;AACvB,aAAO,OAAO;AAChB,WAAO,oBAA6B,OAAO,QAAQ,KAAK;AAAA,EAC1D;AACF;AAEO,MAAM,4BAA4B,CACvC,cAEA,CAAC,CAAC,aAAa,eAAgB;"}
{"version":3,"file":"standardSchemaValidator.js","sources":["../../src/standardSchemaValidator.ts"],"sourcesContent":["import type { ValidationSource } from './types'\n\nexport type TStandardSchemaValidatorValue<\n TData,\n TSource extends ValidationSource = ValidationSource,\n> = {\n value: TData\n validationSource: TSource\n}\n\nexport type TStandardSchemaValidatorIssue<\n TSource extends ValidationSource = ValidationSource,\n> = TSource extends 'form'\n ? {\n form: Record<string, StandardSchemaV1Issue[]>\n fields: Record<string, StandardSchemaV1Issue[]>\n }\n : TSource extends 'field'\n ? StandardSchemaV1Issue[]\n : never\n\nfunction prefixSchemaToErrors(\n issues: readonly StandardSchemaV1Issue[],\n formValue: unknown,\n) {\n const schema = new Map<string, StandardSchemaV1Issue[]>()\n\n for (const issue of issues) {\n const issuePath = issue.path ?? []\n\n let currentFormValue = formValue\n let path = ''\n\n for (let i = 0; i < issuePath.length; i++) {\n const pathSegment = issuePath[i]\n if (pathSegment === undefined) continue\n\n const segment =\n typeof pathSegment === 'object' ? pathSegment.key : pathSegment\n\n // Standard Schema doesn't specify if paths should use numbers or stringified numbers for array access.\n // However, if we follow the path it provides and encounter an array, then we can assume it's intended for array access.\n const segmentAsNumber = Number(segment)\n if (Array.isArray(currentFormValue) && !Number.isNaN(segmentAsNumber)) {\n path += `[${segmentAsNumber}]`\n } else {\n path += (i > 0 ? '.' : '') + String(segment)\n }\n\n if (typeof currentFormValue === 'object' && currentFormValue !== null) {\n currentFormValue = currentFormValue[segment as never]\n } else {\n currentFormValue = undefined\n }\n }\n schema.set(path, (schema.get(path) ?? []).concat(issue))\n }\n\n return Object.fromEntries(schema)\n}\n\nconst transformFormIssues = <TSource extends ValidationSource>(\n issues: readonly StandardSchemaV1Issue[],\n formValue: unknown,\n): TStandardSchemaValidatorIssue<TSource> => {\n const schemaErrors = prefixSchemaToErrors(issues, formValue)\n return {\n form: schemaErrors,\n fields: schemaErrors,\n } as TStandardSchemaValidatorIssue<TSource>\n}\n\nexport const standardSchemaValidators = {\n validate<TSource extends ValidationSource = ValidationSource>(\n {\n value,\n validationSource,\n }: TStandardSchemaValidatorValue<unknown, TSource>,\n schema: StandardSchemaV1,\n ): TStandardSchemaValidatorIssue<TSource> | undefined {\n const result = schema['~standard'].validate(value)\n\n if (result instanceof Promise) {\n throw new Error('async function passed to sync validator')\n }\n\n if (!result.issues) return\n\n if (validationSource === 'field') {\n return result.issues as TStandardSchemaValidatorIssue<TSource>\n }\n return transformFormIssues<TSource>(result.issues, value)\n },\n async validateAsync<TSource extends ValidationSource>(\n {\n value,\n validationSource,\n }: TStandardSchemaValidatorValue<unknown, TSource>,\n schema: StandardSchemaV1,\n ): Promise<TStandardSchemaValidatorIssue<TSource> | undefined> {\n const result = await schema['~standard'].validate(value)\n\n if (!result.issues) return\n\n if (validationSource === 'field') {\n return result.issues as TStandardSchemaValidatorIssue<TSource>\n }\n return transformFormIssues<TSource>(result.issues, value)\n },\n}\n\nexport const isStandardSchemaValidator = (\n validator: unknown,\n): validator is StandardSchemaV1 =>\n !!validator && '~standard' in (validator as object)\n\n/**\n * The Standard Schema interface.\n */\nexport type StandardSchemaV1<Input = unknown, Output = Input> = {\n /**\n * The Standard Schema properties.\n */\n readonly '~standard': StandardSchemaV1Props<Input, Output>\n}\n\n/**\n * The Standard Schema properties interface.\n */\ninterface StandardSchemaV1Props<Input = unknown, Output = Input> {\n /**\n * The version number of the standard.\n */\n readonly version: 1\n /**\n * The vendor name of the schema library.\n */\n readonly vendor: string\n /**\n * Validates unknown input values.\n */\n readonly validate: (\n value: unknown,\n ) => StandardSchemaV1Result<Output> | Promise<StandardSchemaV1Result<Output>>\n /**\n * Inferred types associated with the schema.\n */\n readonly types?: StandardSchemaV1Types<Input, Output> | undefined\n}\n/**\n * The result interface of the validate function.\n */\ntype StandardSchemaV1Result<Output> =\n | StandardSchemaV1SuccessResult<Output>\n | StandardSchemaV1FailureResult\n/**\n * The result interface if validation succeeds.\n */\ninterface StandardSchemaV1SuccessResult<Output> {\n /**\n * The typed output value.\n */\n readonly value: Output\n /**\n * The non-existent issues.\n */\n readonly issues?: undefined\n}\n/**\n * The result interface if validation fails.\n */\ninterface StandardSchemaV1FailureResult {\n /**\n * The issues of failed validation.\n */\n readonly issues: ReadonlyArray<StandardSchemaV1Issue>\n}\n/**\n * The issue interface of the failure output.\n */\nexport interface StandardSchemaV1Issue {\n /**\n * The error message of the issue.\n */\n readonly message: string\n /**\n * The path of the issue, if any.\n */\n readonly path?:\n | ReadonlyArray<PropertyKey | StandardSchemaV1PathSegment>\n | undefined\n}\n/**\n * The path segment interface of the issue.\n */\ninterface StandardSchemaV1PathSegment {\n /**\n * The key representing a path segment.\n */\n readonly key: PropertyKey\n}\n/**\n * The Standard Schema types interface.\n */\ninterface StandardSchemaV1Types<Input = unknown, Output = Input> {\n /**\n * The input type of the schema.\n */\n readonly input: Input\n /**\n * The output type of the schema.\n */\n readonly output: Output\n}\n"],"names":[],"mappings":"AAqBA,SAAS,qBACP,QACA,WACA;AACA,QAAM,6BAAa,IAAA;AAEnB,aAAW,SAAS,QAAQ;AAC1B,UAAM,YAAY,MAAM,QAAQ,CAAA;AAEhC,QAAI,mBAAmB;AACvB,QAAI,OAAO;AAEX,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,YAAM,cAAc,UAAU,CAAC;AAC/B,UAAI,gBAAgB,OAAW;AAE/B,YAAM,UACJ,OAAO,gBAAgB,WAAW,YAAY,MAAM;AAItD,YAAM,kBAAkB,OAAO,OAAO;AACtC,UAAI,MAAM,QAAQ,gBAAgB,KAAK,CAAC,OAAO,MAAM,eAAe,GAAG;AACrE,gBAAQ,IAAI,eAAe;AAAA,MAC7B,OAAO;AACL,iBAAS,IAAI,IAAI,MAAM,MAAM,OAAO,OAAO;AAAA,MAC7C;AAEA,UAAI,OAAO,qBAAqB,YAAY,qBAAqB,MAAM;AACrE,2BAAmB,iBAAiB,OAAgB;AAAA,MACtD,OAAO;AACL,2BAAmB;AAAA,MACrB;AAAA,IACF;AACA,WAAO,IAAI,OAAO,OAAO,IAAI,IAAI,KAAK,CAAA,GAAI,OAAO,KAAK,CAAC;AAAA,EACzD;AAEA,SAAO,OAAO,YAAY,MAAM;AAClC;AAEA,MAAM,sBAAsB,CAC1B,QACA,cAC2C;AAC3C,QAAM,eAAe,qBAAqB,QAAQ,SAAS;AAC3D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,EAAA;AAEZ;AAEO,MAAM,2BAA2B;AAAA,EACtC,SACE;AAAA,IACE;AAAA,IACA;AAAA,EAAA,GAEF,QACoD;AACpD,UAAM,SAAS,OAAO,WAAW,EAAE,SAAS,KAAK;AAEjD,QAAI,kBAAkB,SAAS;AAC7B,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAEA,QAAI,CAAC,OAAO,OAAQ;AAEpB,QAAI,qBAAqB,SAAS;AAChC,aAAO,OAAO;AAAA,IAChB;AACA,WAAO,oBAA6B,OAAO,QAAQ,KAAK;AAAA,EAC1D;AAAA,EACA,MAAM,cACJ;AAAA,IACE;AAAA,IACA;AAAA,EAAA,GAEF,QAC6D;AAC7D,UAAM,SAAS,MAAM,OAAO,WAAW,EAAE,SAAS,KAAK;AAEvD,QAAI,CAAC,OAAO,OAAQ;AAEpB,QAAI,qBAAqB,SAAS;AAChC,aAAO,OAAO;AAAA,IAChB;AACA,WAAO,oBAA6B,OAAO,QAAQ,KAAK;AAAA,EAC1D;AACF;AAEO,MAAM,4BAA4B,CACvC,cAEA,CAAC,CAAC,aAAa,eAAgB;"}

@@ -19,2 +19,3 @@ import { batch } from "@tanstack/store";

fieldMetaBase: null,
formGroupStateBase: null,
isSubmitting: null,

@@ -21,0 +22,0 @@ isSubmitted: null,

@@ -1,1 +0,1 @@

{"version":3,"file":"transform.js","sources":["../../src/transform.ts"],"sourcesContent":["import { batch } from '@tanstack/store'\nimport { deepCopy } from './utils'\nimport type {\n AnyBaseFormState,\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\n\n/**\n * @private\n */\nexport type FormTransform<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n> = (\n formBase: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n) => FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n>\n\n/**\n * @private\n */\nexport function mergeAndUpdate<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n>(\n form: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n fn?: FormTransform<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n) {\n // Run the `transform` function on `form.state`, diff it, and update the relevant parts with what needs updating\n if (!fn) return\n\n const newObj = Object.assign({}, form, {\n state: deepCopy(form.state),\n })\n\n fn(newObj)\n\n if (newObj.fieldInfo !== form.fieldInfo) {\n form.fieldInfo = newObj.fieldInfo\n }\n\n if (newObj.options !== form.options) {\n form.options = newObj.options\n }\n\n const baseFormKeys = Object.keys({\n values: null,\n validationMetaMap: null,\n fieldMetaBase: null,\n isSubmitting: null,\n isSubmitted: null,\n isValidating: null,\n submissionAttempts: null,\n isSubmitSuccessful: null,\n _force_re_eval: null,\n // Do not remove this, it ensures that we have all the keys in `BaseFormState`\n } satisfies Record<\n // Exclude errorMap since we need to handle that uniquely\n Exclude<keyof AnyBaseFormState, 'errorMap'>,\n null\n >) as Array<keyof AnyBaseFormState>\n\n const diffedObject = baseFormKeys.reduce((prev, key) => {\n if (form.state[key] !== newObj.state[key]) {\n prev[key] = newObj.state[key]\n }\n return prev\n }, {} as Partial<AnyBaseFormState>)\n\n batch(() => {\n if (Object.keys(diffedObject).length) {\n form.baseStore.setState((prev) => ({ ...prev, ...diffedObject }))\n }\n\n if (newObj.state.errorMap !== form.state.errorMap) {\n // Check if we need to update `fieldMetaBase` with `errorMaps` set by\n form.setErrorMap(newObj.state.errorMap)\n }\n })\n\n return newObj\n}\n"],"names":[],"mappings":";;AA0DO,SAAS,eAcd,MAcA,IAcA;AAEA,MAAI,CAAC,GAAI;AAET,QAAM,SAAS,OAAO,OAAO,CAAA,GAAI,MAAM;AAAA,IACrC,OAAO,SAAS,KAAK,KAAK;AAAA,EAAA,CAC3B;AAED,KAAG,MAAM;AAET,MAAI,OAAO,cAAc,KAAK,WAAW;AACvC,SAAK,YAAY,OAAO;AAAA,EAC1B;AAEA,MAAI,OAAO,YAAY,KAAK,SAAS;AACnC,SAAK,UAAU,OAAO;AAAA,EACxB;AAEA,QAAM,eAAe,OAAO,KAAK;AAAA,IAC/B,QAAQ;AAAA,IACR,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,cAAc;AAAA,IACd,aAAa;AAAA,IACb,cAAc;AAAA,IACd,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,gBAAgB;AAAA;AAAA,EAAA,CAMjB;AAED,QAAM,eAAe,aAAa,OAAO,CAAC,MAAM,QAAQ;AACtD,QAAI,KAAK,MAAM,GAAG,MAAM,OAAO,MAAM,GAAG,GAAG;AACzC,WAAK,GAAG,IAAI,OAAO,MAAM,GAAG;AAAA,IAC9B;AACA,WAAO;AAAA,EACT,GAAG,CAAA,CAA+B;AAElC,QAAM,MAAM;AACV,QAAI,OAAO,KAAK,YAAY,EAAE,QAAQ;AACpC,WAAK,UAAU,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,GAAG,aAAA,EAAe;AAAA,IAClE;AAEA,QAAI,OAAO,MAAM,aAAa,KAAK,MAAM,UAAU;AAEjD,WAAK,YAAY,OAAO,MAAM,QAAQ;AAAA,IACxC;AAAA,EACF,CAAC;AAED,SAAO;AACT;"}
{"version":3,"file":"transform.js","sources":["../../src/transform.ts"],"sourcesContent":["import { batch } from '@tanstack/store'\nimport { deepCopy } from './utils'\nimport type {\n AnyBaseFormState,\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\n\n/**\n * @private\n */\nexport type FormTransform<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n> = (\n formBase: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n) => FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n>\n\n/**\n * @private\n */\nexport function mergeAndUpdate<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n>(\n form: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n fn?: FormTransform<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n) {\n // Run the `transform` function on `form.state`, diff it, and update the relevant parts with what needs updating\n if (!fn) return\n\n const newObj = Object.assign({}, form, {\n state: deepCopy(form.state),\n })\n\n fn(newObj)\n\n if (newObj.fieldInfo !== form.fieldInfo) {\n form.fieldInfo = newObj.fieldInfo\n }\n\n if (newObj.options !== form.options) {\n form.options = newObj.options\n }\n\n const baseFormKeys = Object.keys({\n values: null,\n validationMetaMap: null,\n fieldMetaBase: null,\n formGroupStateBase: null,\n isSubmitting: null,\n isSubmitted: null,\n isValidating: null,\n submissionAttempts: null,\n isSubmitSuccessful: null,\n _force_re_eval: null,\n // Do not remove this, it ensures that we have all the keys in `BaseFormState`\n } satisfies Record<\n // Exclude errorMap since we need to handle that uniquely\n Exclude<keyof AnyBaseFormState, 'errorMap'>,\n null\n >) as Array<keyof AnyBaseFormState>\n\n const diffedObject = baseFormKeys.reduce((prev, key) => {\n if (form.state[key] !== newObj.state[key]) {\n prev[key] = newObj.state[key]\n }\n return prev\n }, {} as Partial<AnyBaseFormState>)\n\n batch(() => {\n if (Object.keys(diffedObject).length) {\n form.baseStore.setState((prev) => ({ ...prev, ...diffedObject }))\n }\n\n if (newObj.state.errorMap !== form.state.errorMap) {\n // Check if we need to update `fieldMetaBase` with `errorMaps` set by\n form.setErrorMap(newObj.state.errorMap)\n }\n })\n\n return newObj\n}\n"],"names":[],"mappings":";;AA0DO,SAAS,eAcd,MAcA,IAcA;AAEA,MAAI,CAAC,GAAI;AAET,QAAM,SAAS,OAAO,OAAO,CAAA,GAAI,MAAM;AAAA,IACrC,OAAO,SAAS,KAAK,KAAK;AAAA,EAAA,CAC3B;AAED,KAAG,MAAM;AAET,MAAI,OAAO,cAAc,KAAK,WAAW;AACvC,SAAK,YAAY,OAAO;AAAA,EAC1B;AAEA,MAAI,OAAO,YAAY,KAAK,SAAS;AACnC,SAAK,UAAU,OAAO;AAAA,EACxB;AAEA,QAAM,eAAe,OAAO,KAAK;AAAA,IAC/B,QAAQ;AAAA,IACR,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,oBAAoB;AAAA,IACpB,cAAc;AAAA,IACd,aAAa;AAAA,IACb,cAAc;AAAA,IACd,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,gBAAgB;AAAA;AAAA,EAAA,CAMjB;AAED,QAAM,eAAe,aAAa,OAAO,CAAC,MAAM,QAAQ;AACtD,QAAI,KAAK,MAAM,GAAG,MAAM,OAAO,MAAM,GAAG,GAAG;AACzC,WAAK,GAAG,IAAI,OAAO,MAAM,GAAG;AAAA,IAC9B;AACA,WAAO;AAAA,EACT,GAAG,CAAA,CAA+B;AAElC,QAAM,MAAM;AACV,QAAI,OAAO,KAAK,YAAY,EAAE,QAAQ;AACpC,WAAK,UAAU,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,GAAG,aAAA,EAAe;AAAA,IAClE;AAEA,QAAI,OAAO,MAAM,aAAa,KAAK,MAAM,UAAU;AAEjD,WAAK,YAAY,OAAO,MAAM,QAAQ;AAAA,IACxC;AAAA,EACF,CAAC;AAED,SAAO;AACT;"}

@@ -1,4 +0,8 @@

import { AnyFieldMeta, AnyFieldMetaBase } from './FieldApi.js';
import { DeepKeys, DeepKeysOfType, DeepValue } from './util-types.js';
import { FieldAsyncValidateOrFn, FieldValidateAsyncFn, FieldValidateFn, FieldValidateOrFn } from './FieldApi.js';
import { DeepKeys, DeepKeysOfType, DeepValue, UnwrapOneLevelOfArray } from './util-types.js';
import { Updater } from './utils.js';
import { AnyFormApi, FormApi, FormAsyncValidateOrFn, FormValidateAsyncFn, FormValidateFn, FormValidateOrFn, ValidationMeta } from './FormApi.js';
import { ReadonlyStore } from '@tanstack/store';
import { FormGroupAsyncValidateOrFn, FormGroupValidateAsyncFn, FormGroupValidateFn, FormGroupValidateOrFn } from './FormGroupApi.js';
import { StandardSchemaV1, StandardSchemaV1Issue } from './standardSchemaValidator.js';
export type ValidationError = unknown;

@@ -90,5 +94,4 @@ export type ValidationSource = 'form' | 'field';

* @private
* A list of field manipulation methods that a form-like API must implement.
*/
export interface FieldManipulator<TFormData, TSubmitMeta> {
export interface FormLikeAPI<TFormData, TSubmitMeta> {
/**

@@ -118,7 +121,7 @@ * Validates all fields using the correct handlers for a given validation cause.

*/
getFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField) => AnyFieldMeta | undefined;
getFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField) => AnyFieldLikeMeta | undefined;
/**
* Updates the metadata of the specified field.
*/
setFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField, updater: Updater<AnyFieldMetaBase>) => void;
setFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField, updater: Updater<AnyFieldLikeMetaBase>) => void;
/**

@@ -165,1 +168,180 @@ * Sets the value of the specified field and optionally updates the touched state.

}
type UnwrapFormAsyncValidateOrFnForInner<TValidateOrFn extends undefined | FormAsyncValidateOrFn<any>> = [TValidateOrFn] extends [FormValidateAsyncFn<any>] ? Awaited<ReturnType<TValidateOrFn>> : [TValidateOrFn] extends [StandardSchemaV1<infer TOut, any>] ? StandardBrandedSchemaV1<TOut> : undefined;
export type UnwrapFieldAsyncValidateOrFn<TName extends string, TValidateOrFn extends undefined | FieldAsyncValidateOrFn<any, any, any> | FormGroupAsyncValidateOrFn<any, any>, TFormValidateOrFn extends undefined | FormAsyncValidateOrFn<any>> = ([TFormValidateOrFn] extends [StandardSchemaV1<any, infer TStandardOut>] ? TName extends keyof TStandardOut ? StandardSchemaV1Issue[] : undefined : undefined) | (UnwrapFormAsyncValidateOrFnForInner<TFormValidateOrFn> extends infer TFormValidateVal ? TFormValidateVal extends {
__standardSchemaV1: true;
} ? [DeepValue<TFormValidateVal, TName>] extends [never] ? undefined : StandardSchemaV1Issue[] : TFormValidateVal extends {
fields: any;
} ? TName extends keyof TFormValidateVal['fields'] ? TFormValidateVal['fields'][TName] : undefined : undefined : never) | ([TValidateOrFn] extends [FieldValidateAsyncFn<any, any, any>] ? Awaited<ReturnType<TValidateOrFn>> : [TValidateOrFn] extends [StandardSchemaV1<any, any>] ? StandardSchemaV1Issue[] : undefined) | ([TValidateOrFn] extends [FormGroupValidateAsyncFn<any, any, any>] ? Awaited<ReturnType<TValidateOrFn>> : [TValidateOrFn] extends [StandardSchemaV1<any, any>] ? StandardSchemaV1Issue[] : undefined);
/**
* @private
*/
export type FieldErrorMapFromValidator<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>> = Partial<Record<DeepKeys<TParentData>, ValidationErrorMap<TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>>>;
type StandardBrandedSchemaV1<T> = T & {
__standardSchemaV1: true;
};
type UnwrapFormValidateOrFnForInner<TValidateOrFn extends undefined | FormValidateOrFn<any>> = [TValidateOrFn] extends [FormValidateFn<any>] ? ReturnType<TValidateOrFn> : [TValidateOrFn] extends [StandardSchemaV1<infer TOut, any>] ? StandardBrandedSchemaV1<TOut> : undefined;
export type UnwrapFieldValidateOrFn<TName extends string, TValidateOrFn extends undefined | FieldValidateOrFn<any, any, any> | FormGroupValidateOrFn<any, any, any>, TFormValidateOrFn extends undefined | FormValidateOrFn<any>> = ([TFormValidateOrFn] extends [StandardSchemaV1<any, infer TStandardOut>] ? TName extends keyof TStandardOut ? StandardSchemaV1Issue[] : undefined : undefined) | (UnwrapFormValidateOrFnForInner<TFormValidateOrFn> extends infer TFormValidateVal ? TFormValidateVal extends {
__standardSchemaV1: true;
} ? [DeepValue<TFormValidateVal, TName>] extends [never] ? undefined : StandardSchemaV1Issue[] : TFormValidateVal extends {
fields: any;
} ? TName extends keyof TFormValidateVal['fields'] ? TFormValidateVal['fields'][TName] : undefined : undefined : never) | ([TValidateOrFn] extends [FieldValidateFn<any, any, any>] ? ReturnType<TValidateOrFn> : [TValidateOrFn] extends [StandardSchemaV1<any, any>] ? StandardSchemaV1Issue[] : undefined) | ([TValidateOrFn] extends [FormGroupValidateFn<any, any, any>] ? ReturnType<TValidateOrFn> : [TValidateOrFn] extends [StandardSchemaV1<any, any>] ? StandardSchemaV1Issue[] : undefined);
/**
* @private
*/
export type FieldLikeMetaBase<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TFormOnMount extends undefined | FormValidateOrFn<TParentData>, TFormOnChange extends undefined | FormValidateOrFn<TParentData>, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> = {
/**
* A flag indicating whether the field has been touched.
*/
isTouched: boolean;
/**
* A flag indicating whether the field has been blurred.
*/
isBlurred: boolean;
/**
* A flag that is `true` if the field's value has been modified by the user. Opposite of `isPristine`.
*/
isDirty: boolean;
/**
* A map of errors related to the field value.
*/
errorMap: ValidationErrorMap<UnwrapFieldValidateOrFn<TName, TOnMount, TFormOnMount>, UnwrapFieldValidateOrFn<TName, TOnChange, TFormOnChange>, UnwrapFieldAsyncValidateOrFn<TName, TOnChangeAsync, TFormOnChangeAsync>, UnwrapFieldValidateOrFn<TName, TOnBlur, TFormOnBlur>, UnwrapFieldAsyncValidateOrFn<TName, TOnBlurAsync, TFormOnBlurAsync>, UnwrapFieldValidateOrFn<TName, TOnSubmit, TFormOnSubmit>, UnwrapFieldAsyncValidateOrFn<TName, TOnSubmitAsync, TFormOnSubmitAsync>, UnwrapFieldValidateOrFn<TName, TOnDynamic, TFormOnDynamic>, UnwrapFieldAsyncValidateOrFn<TName, TOnDynamicAsync, TFormOnDynamicAsync>>;
/**
* @private allows tracking the source of the errors in the error map
*/
errorSourceMap: ValidationErrorMapSource;
/**
* A flag indicating whether the field is currently being validated.
*/
isValidating: boolean;
/**
* @private a counter that is incremented every time a structural array
* operation (push, insert, remove, swap, move, replace, clear) modifies
* the value of an array field. Adapters can subscribe to this to trigger
* re-renders for `mode="array"` fields without having to subscribe to the
* full field value.
*/
_arrayVersion: number;
};
/**
* @private
*/
export type AnyFieldLikeMetaBase = FieldLikeMetaBase<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
/**
* @private
*/
export type FieldLikeMetaDerived<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TFormOnMount extends undefined | FormValidateOrFn<TParentData>, TFormOnChange extends undefined | FormValidateOrFn<TParentData>, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> = {
/**
* An array of errors related to the field value.
*/
errors: Array<UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnMount, TFormOnMount>> | UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnChange, TFormOnChange>> | UnwrapOneLevelOfArray<UnwrapFieldAsyncValidateOrFn<TName, TOnChangeAsync, TFormOnChangeAsync>> | UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnBlur, TFormOnBlur>> | UnwrapOneLevelOfArray<UnwrapFieldAsyncValidateOrFn<TName, TOnBlurAsync, TFormOnBlurAsync>> | UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnSubmit, TFormOnSubmit>> | UnwrapOneLevelOfArray<UnwrapFieldAsyncValidateOrFn<TName, TOnSubmitAsync, TFormOnSubmitAsync>> | UnwrapOneLevelOfArray<UnwrapFieldValidateOrFn<TName, TOnDynamic, TFormOnDynamic>> | UnwrapOneLevelOfArray<UnwrapFieldAsyncValidateOrFn<TName, TOnDynamicAsync, TFormOnDynamicAsync>>>;
/**
* A flag that is `true` if the field's value has not been modified by the user. Opposite of `isDirty`.
*/
isPristine: boolean;
/**
* A boolean indicating if the field is valid. Evaluates `true` if there are no field errors.
*/
isValid: boolean;
/**
* A flag indicating whether the field's current value is the default value
*/
isDefaultValue: boolean;
};
/**
* @private
* An object type representing the metadata of a field in a form.
*/
export type FieldLikeMeta<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TFormOnMount extends undefined | FormValidateOrFn<TParentData>, TFormOnChange extends undefined | FormValidateOrFn<TParentData>, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> = FieldLikeMetaBase<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync> & FieldLikeMetaDerived<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
/**
* @private
*/
export type AnyFieldLikeMeta = FieldLikeMeta<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>;
export type AnyFieldMeta = AnyFieldLikeMeta;
/**
* @private
* An object type representing the state of a field.
*/
export type FieldLikeState<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, TFormOnMount extends undefined | FormValidateOrFn<TParentData>, TFormOnChange extends undefined | FormValidateOrFn<TParentData>, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>> = {
/**
* The current value of the field.
*/
value: TData;
/**
* The current metadata of the field.
*/
meta: FieldLikeMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>;
};
/**
* @private
* An object type representing the options for a field in a form.
*/
export interface FieldLikeOptions<TParentData, TName extends DeepKeys<TParentData>, TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>> {
/**
* The field name. The type will be `DeepKeys<TParentData>` to ensure your name is a deep key of the parent dataset.
*/
name: TName;
/**
* An optional default value for the field.
*/
defaultValue?: NoInfer<TData>;
/**
* The default time to debounce async validation if there is not a more specific debounce time passed.
*/
asyncDebounceMs?: number;
/**
* If `true`, always run async validation, even if there are errors emitted during synchronous validation.
*/
asyncAlways?: boolean;
/**
* An optional object with default metadata for the field.
*/
defaultMeta?: Partial<FieldLikeMeta<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, any, any, any, any, any, any, any, any, any>>;
/**
* Disable the `flat(1)` operation on `field.errors`. This is useful if you want to keep the error structure as is. Not suggested for most use-cases.
*/
disableErrorFlat?: boolean;
}
/**
* @private
* An object type representing the required options for the FieldApi class.
*/
export interface FieldLikeApiOptions<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta> extends FieldLikeOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync> {
form: FormApi<TParentData, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta>;
}
/**
* @private
*/
export interface FieldLikeAPI<in out TParentData, in out TName extends DeepKeys<TParentData>, in out TData extends DeepValue<TParentData, TName>, in out TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnChangeAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnBlurAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData> | FormGroupValidateOrFn<TParentData, TName, TData>, in out TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn<TParentData, TName, TData> | FormGroupAsyncValidateOrFn<TParentData, TName, TData>, in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>, in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>, in out TParentSubmitMeta, TExtraOptions = {}> {
form: AnyFormApi;
options: FieldLikeApiOptions<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TParentSubmitMeta> & TExtraOptions;
store: ReadonlyStore<FieldLikeState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>;
/**
* The field name.
*/
name: TName;
mount: () => () => void;
setValue: (updater: Updater<TData>, options?: UpdateMetaOptions) => void;
getMeta: () => AnyFieldLikeMeta;
setMeta: (updater: Updater<AnyFieldLikeMetaBase>) => void;
getInfo: () => FieldInfo<TParentData>;
validate: (cause: ValidationCause, opts?: {
skipFormValidation?: boolean;
skipGroupValidation?: boolean;
}) => ValidationError[] | Promise<ValidationError[]>;
/**
* @private
*/
triggerOnChangeListener: () => void;
/**
* @private
*/
triggerOnSubmitListener: () => void;
}
/**
* @private
*/
export interface FieldInfo<TParentData> {
instance: FieldLikeAPI<TParentData, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any> | null;
validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>;
}
export {};

@@ -65,2 +65,3 @@ import { FieldValidators } from './FieldApi.js';

form?: any;
group?: any;
fieldName?: string;

@@ -74,2 +75,3 @@ }): T extends FieldValidators<any, any, any, any, any, any, any, any, any, any, any, any> ? Array<SyncValidator<T['onChange'] | T['onBlur'] | T['onSubmit'] | T['onMount'] | T['onDynamic']>> : T extends FormValidators<any, any, any, any, any, any, any, any, any, any> ? Array<SyncValidator<T['onChange'] | T['onBlur'] | T['onSubmit'] | T['onMount'] | T['onDynamic']>> : never;

form?: any;
group?: any;
fieldName?: string;

@@ -113,2 +115,6 @@ }): T extends FieldValidators<any, any, any, any, any, any, any, any, any, any, any, any> ? Array<AsyncValidator<T['onChangeAsync'] | T['onBlurAsync'] | T['onSubmitAsync'] | T['onDynamicAsync']>> : T extends FormValidators<any, any, any, any, any, any, any, any, any, any> ? Array<AsyncValidator<T['onChangeAsync'] | T['onBlurAsync'] | T['onSubmitAsync'] | T['onDynamicAsync']>> : never;

export declare function deepCopy<T>(obj: T): T;
/**
* @private
*/
export declare function isFieldInGroup(groupName: string, fieldName: string): boolean;
export {};

@@ -174,2 +174,3 @@ import { liteThrottle } from "@tanstack/pacer-lite";

form: options.form,
group: options.group,
validators: options.validators,

@@ -218,2 +219,3 @@ event: { type: cause, fieldName: options.fieldName, async: false },

form: options.form,
group: options.group,
validators: options.validators,

@@ -381,2 +383,5 @@ event: { type: cause, fieldName: options.fieldName, async: true },

}
function isFieldInGroup(groupName, fieldName) {
return fieldName === groupName || fieldName.startsWith(`${groupName}.`) || fieldName.startsWith(`${groupName}[`);
}
export {

@@ -394,2 +399,3 @@ concatenatePaths,

getSyncValidatorArray,
isFieldInGroup,
isGlobalFormValidationError,

@@ -396,0 +402,0 @@ isNonEmptyArray,

@@ -1,1 +0,1 @@

{"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["import { liteThrottle } from '@tanstack/pacer-lite'\nimport { formEventClient } from './EventClient'\nimport type { ValidationLogicProps } from './ValidationLogic'\nimport type { FieldValidators } from './FieldApi'\nimport type { AnyFormApi, FormValidators } from './FormApi'\nimport type {\n GlobalFormValidationError,\n ValidationCause,\n ValidationError,\n ValidationSource,\n} from './types'\n\nexport type UpdaterFn<TInput, TOutput = TInput> = (input: TInput) => TOutput\n\nexport type Updater<TInput, TOutput = TInput> =\n | TOutput\n | UpdaterFn<TInput, TOutput>\n\n/**\n * @private\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 * @private\n */\nexport function getBy(obj: unknown, path: string | (string | number)[]): any {\n const pathObj = makePathArray(path)\n return pathObj.reduce((current: any, pathPart) => {\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 * @private\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 (\n typeof key === 'string' ||\n (typeof key === 'number' && !Array.isArray(parent))\n ) {\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) && typeof key === 'number') {\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 * @private\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 (\n typeof key === 'string' ||\n (typeof key === 'number' && !Array.isArray(parent))\n ) {\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\n// Char codes used by the parser below.\nconst CC_DOT = 0x2e // '.'\nconst CC_OPEN = 0x5b // '['\nconst CC_CLOSE = 0x5d // ']'\nconst CC_ZERO = 0x30 // '0'\nconst CC_NINE = 0x39 // '9'\n\n/**\n * @private\n */\nexport function makePathArray(str: string | Array<string | number>) {\n if (Array.isArray(str)) {\n return [...str]\n }\n\n if (typeof str !== 'string') {\n throw new Error('Path must be a string.')\n }\n\n const len = str.length\n const result: Array<string | number> = []\n // Location of the first character of the in-progress segment in `str`.\n // The segment ends at the current `i` when we hit a separator.\n //\n // We strip an optional leading '[' so '[0]' parses as [0], not ['', 0].\n // Doing this up front keeps the loop's backwards compatibility handling simpler.\n let segStart = len > 0 && str.charCodeAt(0) === CC_OPEN ? 1 : 0\n // Whether the in-progress segment has been all ASCII digits so far.\n // Used together with the leading-zero check to decide if it should be\n // pushed as a number instead of a string.\n let allDigits = true\n // Tracks the previous character. Only necessary to preserve the\n // old behavior for malformed input.\n let prev = -1\n // Walk once. `i === len` is treated as a virtual final separator so the\n // flush block handles both mid-string segments and the last one.\n for (let i = segStart; i <= len; i++) {\n const char = i < len ? str.charCodeAt(i) : -1\n\n // Handle separators (including the virtual one at the end). Flush the in-progress segment.\n if (i === len || char === CC_DOT || char === CC_OPEN || char === CC_CLOSE) {\n const segLen = i - segStart\n if (segLen > 0) {\n // To treat the segment as a number...\n const treatAsNumber =\n // ...it must contain only digits...\n allDigits &&\n // ...and either be a single '0' or not start with '0'.\n (segLen === 1 || str.charCodeAt(segStart) !== CC_ZERO)\n\n const seg = str.slice(segStart, i)\n if (treatAsNumber) {\n const num = parseInt(seg, 10)\n // Up to 15 digits, parseInt is always lossless (the max\n // 15-digit decimal is below Number.MAX_SAFE_INTEGER). Beyond\n // that, verify by round-trip: if parseInt lost precision\n // (e.g., a 20-digit literal), fall back to the string so we\n // don't silently change the value.\n if (segLen <= 15 || String(num) === seg) {\n result.push(num)\n } else {\n result.push(seg)\n }\n } else {\n result.push(seg)\n }\n } else if (\n // This branch, which handles empty segments, only exists to preserve\n // the old behavior for malformed input.\n\n // Push the empty segment unless this is a \"phantom boundary\" the\n // old regex impl would have absorbed:\n // 1. `]` was always stripped — `prev === ']'` means the real\n // boundary already happened on the previous iteration.\n // 2. A leading `]` was stripped too (the leading `[` strip\n // above handles its counterpart for `[`).\n // 3. `..` and `[[` collapse to a single boundary.\n prev !== CC_CLOSE &&\n !(prev === -1 && char === CC_CLOSE) &&\n !(prev === char && (char === CC_DOT || char === CC_OPEN))\n ) {\n result.push('')\n }\n\n // Start a new segment.\n segStart = i + 1\n allDigits = true\n } else if (char < CC_ZERO || char > CC_NINE) {\n allDigits = false\n }\n\n prev = char\n }\n\n // If the input was effectively all phantom chars (e.g. ']', '[]',\n // '[]]'), the loop produces no segments. The old impl returned ['']\n // for these because.\n if (!result.length) result.push('')\n\n return result\n}\n\n/**\n * @private\n */\nexport function concatenatePaths(path1: string, path2: string): string {\n if (path1.length === 0) return path2\n if (path2.length === 0) return path1\n\n if (path2.startsWith('[')) {\n return path1 + path2\n }\n\n // In cases where parent and child withFieldGroup forms are both nested\n if (path2.startsWith('.')) {\n return path1 + path2\n }\n\n return `${path1}.${path2}`\n}\n\n/**\n * @private\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\n/**\n * @private\n */\nexport interface AsyncValidator<T> {\n cause: ValidationCause\n validate: T\n debounceMs: number\n}\n\ninterface SyncValidatorArrayPartialOptions<T> {\n validators?: T\n}\n\n/**\n * @private\n */\nexport interface SyncValidator<T> {\n cause: ValidationCause\n validate: T\n}\n\n/**\n * @private\n */\nexport function getSyncValidatorArray<T>(\n cause: ValidationCause,\n options: SyncValidatorArrayPartialOptions<T> & {\n validationLogic?: any\n form?: any\n fieldName?: string\n },\n): T extends FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n ? Array<\n SyncValidator<\n | T['onChange']\n | T['onBlur']\n | T['onSubmit']\n | T['onMount']\n | T['onDynamic']\n >\n >\n : T extends FormValidators<any, any, any, any, any, any, any, any, any, any>\n ? Array<\n SyncValidator<\n | T['onChange']\n | T['onBlur']\n | T['onSubmit']\n | T['onMount']\n | T['onDynamic']\n >\n >\n : never {\n const runValidation = (\n props: Parameters<ValidationLogicProps['runValidation']>[0],\n ) => {\n return props.validators.filter(Boolean).map((validator) => {\n return {\n cause: validator!.cause,\n validate: validator!.fn,\n }\n })\n }\n\n return options.validationLogic({\n form: options.form,\n validators: options.validators,\n event: { type: cause, fieldName: options.fieldName, async: false },\n runValidation,\n })\n}\n\n/**\n * @private\n */\nexport function getAsyncValidatorArray<T>(\n cause: ValidationCause,\n options: AsyncValidatorArrayPartialOptions<T> & {\n validationLogic?: any\n form?: any\n fieldName?: string\n },\n): T extends FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n ? Array<\n AsyncValidator<\n | T['onChangeAsync']\n | T['onBlurAsync']\n | T['onSubmitAsync']\n | T['onDynamicAsync']\n >\n >\n : T extends FormValidators<any, any, any, any, any, any, any, any, any, any>\n ? Array<\n AsyncValidator<\n | T['onChangeAsync']\n | T['onBlurAsync']\n | T['onSubmitAsync']\n | T['onDynamicAsync']\n >\n >\n : never {\n const { asyncDebounceMs } = options\n const {\n onBlurAsyncDebounceMs,\n onChangeAsyncDebounceMs,\n onDynamicAsyncDebounceMs,\n } = (options.validators || {}) as\n | FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n | FormValidators<any, any, any, any, any, any, any, any, any, any>\n\n const defaultDebounceMs = asyncDebounceMs ?? 0\n\n const runValidation = (\n props: Parameters<ValidationLogicProps['runValidation']>[0],\n ) => {\n return props.validators.filter(Boolean).map((validator) => {\n const validatorCause = validator?.cause || cause\n\n let debounceMs = defaultDebounceMs\n\n switch (validatorCause) {\n case 'change':\n debounceMs = onChangeAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'blur':\n debounceMs = onBlurAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'dynamic':\n debounceMs = onDynamicAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'submit':\n debounceMs = 0 // submit validators are always run immediately\n break\n default:\n break\n }\n\n if (cause === 'submit') {\n debounceMs = 0\n }\n\n return {\n cause: validatorCause,\n validate: validator!.fn,\n debounceMs: debounceMs,\n }\n })\n }\n\n return options.validationLogic({\n form: options.form,\n validators: options.validators,\n event: { type: cause, fieldName: options.fieldName, async: true },\n runValidation,\n })\n}\n\nexport const isGlobalFormValidationError = (\n error: unknown,\n): error is GlobalFormValidationError<unknown> => {\n return !!error && typeof error === 'object' && 'fields' in error\n}\n\nexport function evaluate<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n if (objA instanceof Date && objB instanceof Date) {\n return objA.getTime() === objB.getTime()\n }\n\n if (objA instanceof Map && objB instanceof Map) {\n if (objA.size !== objB.size) return false\n for (const [k, v] of objA) {\n if (!objB.has(k) || !Object.is(v, objB.get(k))) return false\n }\n return true\n }\n\n if (objA instanceof Set && objB instanceof Set) {\n if (objA.size !== objB.size) return false\n for (const v of objA) {\n if (!objB.has(v)) return false\n }\n return true\n }\n\n const keysA = Object.keys(objA)\n const keysB = Object.keys(objB)\n\n if (keysA.length !== keysB.length) {\n return false\n }\n\n // Two distinct non-plain, non-array objects with no own enumerable keys cannot\n // be compared by key iteration — the loop below would vacuously succeed and\n // treat them as equal regardless of their internal state. This covers Temporal\n // types, RegExp, and any class that exposes values only through getters.\n if (\n keysA.length === 0 &&\n !Array.isArray(objA) &&\n !Array.isArray(objB) &&\n (Object.getPrototypeOf(objA) !== Object.prototype ||\n Object.getPrototypeOf(objB) !== Object.prototype)\n ) {\n return false\n }\n\n for (const key of keysA) {\n // performs recursive search down the object tree\n\n if (\n !keysB.includes(key) ||\n !evaluate(objA[key as keyof T], objB[key as keyof T])\n ) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Determines the logic for determining the error source and value to set on the field meta within the form level sync/async validation.\n * @private\n */\nexport const determineFormLevelErrorSourceAndValue = ({\n newFormValidatorError,\n isPreviousErrorFromFormValidator,\n previousErrorValue,\n}: {\n newFormValidatorError: ValidationError\n isPreviousErrorFromFormValidator: boolean\n previousErrorValue: ValidationError\n}): {\n newErrorValue: ValidationError\n newSource: ValidationSource | undefined\n} => {\n // All falsy values are not considered errors\n if (newFormValidatorError) {\n return { newErrorValue: newFormValidatorError, newSource: 'form' }\n }\n\n // Clears form level error since it's now stale\n if (isPreviousErrorFromFormValidator) {\n return { newErrorValue: undefined, newSource: undefined }\n }\n\n // At this point, we have a preivous error which must have been set by the field validator, keep as is\n if (previousErrorValue) {\n return { newErrorValue: previousErrorValue, newSource: 'field' }\n }\n\n // No new or previous error, clear the error\n return { newErrorValue: undefined, newSource: undefined }\n}\n\n/**\n * Determines the logic for determining the error source and value to set on the field meta within the field level sync/async validation.\n * @private\n */\nexport const determineFieldLevelErrorSourceAndValue = ({\n formLevelError,\n fieldLevelError,\n}: {\n formLevelError: ValidationError\n fieldLevelError: ValidationError\n}): {\n newErrorValue: ValidationError\n newSource: ValidationSource | undefined\n} => {\n // At field level, we prioritize the field level error\n if (fieldLevelError) {\n return { newErrorValue: fieldLevelError, newSource: 'field' }\n }\n\n // If there is no field level error, and there is a form level error, we set the form level error\n if (formLevelError) {\n return { newErrorValue: formLevelError, newSource: 'form' }\n }\n\n return { newErrorValue: undefined, newSource: undefined }\n}\n\nexport function createFieldMap<T>(values: Readonly<T>): { [K in keyof T]: K } {\n const output: { [K in keyof T]: K } = {} as any\n\n for (const key in values) {\n output[key] = key\n }\n\n return output\n}\n\n/**\n * Merge the first parameter with the given overrides.\n * @private\n */\nexport function mergeOpts<T>(\n originalOpts: T | undefined | null,\n overrides: T,\n): T {\n if (originalOpts === undefined || originalOpts === null) {\n return overrides\n }\n\n return { ...originalOpts, ...overrides }\n}\n\n/*\n/ credit is due to https://github.com/lukeed/uuid for this code, with current npm\n/ attacks we didn't feel comfortable installing directly from npm. But big appreciation\n/ from the TanStack Form team <3.\n*/\n\nlet IDX = 256\nconst HEX: string[] = []\nlet BUFFER: number[] | undefined\n\nwhile (IDX--) {\n HEX[IDX] = (IDX + 256).toString(16).substring(1)\n}\n\nexport function uuid(): string {\n let i = 0\n let num: number\n let out = ''\n\n if (!BUFFER || IDX + 16 > 256) {\n BUFFER = new Array<number>(256)\n i = 256\n while (i--) {\n BUFFER[i] = (256 * Math.random()) | 0\n }\n i = 0\n IDX = 0\n }\n\n for (; i < 16; i++) {\n num = BUFFER[IDX + i] as number\n if (i === 6) out += HEX[(num & 15) | 64]\n else if (i === 8) out += HEX[(num & 63) | 128]\n else out += HEX[num]\n\n if (i & 1 && i > 1 && i < 11) out += '-'\n }\n\n IDX++\n return out\n}\n\nexport const throttleFormState = liteThrottle(\n (form: AnyFormApi) =>\n formEventClient.emit('form-state', {\n id: form.formId,\n state: form.store.state,\n }),\n {\n wait: 300,\n },\n)\n\n// Do not use a serialize and deserialize method like JSON.stringify/parse\n// as that will drop functions, dates, undefined, Infinity, NaN, etc.\nexport function deepCopy<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as any\n }\n\n if (Array.isArray(obj)) {\n const arrCopy = [] as any[]\n for (let i = 0; i < obj.length; i++) {\n arrCopy[i] = deepCopy(obj[i])\n }\n return arrCopy as any\n }\n\n if (obj instanceof Map) {\n const mapCopy = new Map()\n obj.forEach((value, key) => {\n mapCopy.set(key, deepCopy(value))\n })\n return mapCopy as any\n }\n\n if (obj instanceof Set) {\n const setCopy = new Set()\n obj.forEach((value) => {\n setCopy.add(deepCopy(value))\n })\n return setCopy as any\n }\n\n const copy: { [key: string]: any } = {}\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n copy[key] = deepCopy((obj as any)[key])\n }\n }\n return copy as T\n}\n"],"names":[],"mappings":";;AAqBO,SAAS,iBACd,SACA,OACS;AACT,SAAO,OAAO,YAAY,aACrB,QAAuC,KAAK,IAC7C;AACN;AAMO,SAAS,MAAM,KAAc,MAAyC;AAC3E,QAAM,UAAU,cAAc,IAAI;AAClC,SAAO,QAAQ,OAAO,CAAC,SAAc,aAAa;AAChD,QAAI,YAAY,KAAM,QAAO;AAC7B,QAAI,OAAO,YAAY,aAAa;AAClC,aAAO,QAAQ,QAAQ;AAAA,IACzB;AACA,WAAO;AAAA,EACT,GAAG,GAAG;AACR;AAMO,SAAS,MAAM,KAAU,OAAY,SAAuB;AACjE,QAAM,OAAO,cAAc,KAAK;AAEhC,WAAS,MAAM,QAAmB;AAChC,QAAI,CAAC,KAAK,QAAQ;AAChB,aAAO,iBAAiB,SAAS,MAAM;AAAA,IACzC;AAEA,UAAM,MAAM,KAAK,MAAA;AAEjB,QACE,OAAO,QAAQ,YACd,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,MAAM,GACjD;AACA,UAAI,OAAO,WAAW,UAAU;AAC9B,YAAI,WAAW,MAAM;AACnB,mBAAS,CAAA;AAAA,QACX;AACA,eAAO;AAAA,UACL,GAAG;AAAA,UACH,CAAC,GAAG,GAAG,MAAM,OAAO,GAAG,CAAC;AAAA,QAAA;AAAA,MAE5B;AACA,aAAO;AAAA,QACL,CAAC,GAAG,GAAG,MAAA;AAAA,MAAM;AAAA,IAEjB;AAEA,QAAI,MAAM,QAAQ,MAAM,KAAK,OAAO,QAAQ,UAAU;AACpD,YAAM,SAAS,OAAO,MAAM,GAAG,GAAG;AAClC,aAAO;AAAA,QACL,GAAI,OAAO,SAAS,SAAS,IAAI,MAAM,GAAG;AAAA,QAC1C,MAAM,OAAO,GAAG,CAAC;AAAA,QACjB,GAAG,OAAO,MAAM,MAAM,CAAC;AAAA,MAAA;AAAA,IAE3B;AACA,WAAO,CAAC,GAAG,IAAI,MAAM,GAAG,GAAG,OAAO;AAAA,EACpC;AAEA,SAAO,MAAM,GAAG;AAClB;AAMO,SAAS,SAAS,KAAU,OAAY;AAC7C,QAAM,OAAO,cAAc,KAAK;AAEhC,WAAS,SAAS,QAAkB;AAClC,QAAI,CAAC,OAAQ;AACb,QAAI,KAAK,WAAW,GAAG;AACrB,YAAM,YAAY,KAAK,CAAC;AACxB,UAAI,MAAM,QAAQ,MAAM,KAAK,OAAO,cAAc,UAAU;AAC1D,eAAO,OAAO,OAAO,CAAC,GAAG,MAAM,MAAM,SAAS;AAAA,MAChD;AACA,YAAM,EAAE,CAAC,SAAS,GAAG,QAAQ,GAAG,SAAS;AACzC,aAAO;AAAA,IACT;AAEA,UAAM,MAAM,KAAK,MAAA;AAEjB,QACE,OAAO,QAAQ,YACd,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,MAAM,GACjD;AACA,UAAI,OAAO,WAAW,UAAU;AAC9B,eAAO;AAAA,UACL,GAAG;AAAA,UACH,CAAC,GAAG,GAAG,SAAS,OAAO,GAAG,CAAC;AAAA,QAAA;AAAA,MAE/B;AAAA,IACF;AAEA,QAAI,OAAO,QAAQ,UAAU;AAC3B,UAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,YAAI,OAAO,OAAO,QAAQ;AACxB,iBAAO;AAAA,QACT;AACA,cAAM,SAAS,OAAO,MAAM,GAAG,GAAG;AAClC,eAAO;AAAA,UACL,GAAI,OAAO,SAAS,SAAS,IAAI,MAAM,GAAG;AAAA,UAC1C,SAAS,OAAO,GAAG,CAAC;AAAA,UACpB,GAAG,OAAO,MAAM,MAAM,CAAC;AAAA,QAAA;AAAA,MAE3B;AAAA,IACF;AAEA,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AAEA,SAAO,SAAS,GAAG;AACrB;AAGA,MAAM,SAAS;AACf,MAAM,UAAU;AAChB,MAAM,WAAW;AACjB,MAAM,UAAU;AAChB,MAAM,UAAU;AAKT,SAAS,cAAc,KAAsC;AAClE,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,WAAO,CAAC,GAAG,GAAG;AAAA,EAChB;AAEA,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C;AAEA,QAAM,MAAM,IAAI;AAChB,QAAM,SAAiC,CAAA;AAMvC,MAAI,WAAW,MAAM,KAAK,IAAI,WAAW,CAAC,MAAM,UAAU,IAAI;AAI9D,MAAI,YAAY;AAGhB,MAAI,OAAO;AAGX,WAAS,IAAI,UAAU,KAAK,KAAK,KAAK;AACpC,UAAM,OAAO,IAAI,MAAM,IAAI,WAAW,CAAC,IAAI;AAG3C,QAAI,MAAM,OAAO,SAAS,UAAU,SAAS,WAAW,SAAS,UAAU;AACzE,YAAM,SAAS,IAAI;AACnB,UAAI,SAAS,GAAG;AAEd,cAAM;AAAA;AAAA,UAEJ;AAAA,WAEC,WAAW,KAAK,IAAI,WAAW,QAAQ,MAAM;AAAA;AAEhD,cAAM,MAAM,IAAI,MAAM,UAAU,CAAC;AACjC,YAAI,eAAe;AACjB,gBAAM,MAAM,SAAS,KAAK,EAAE;AAM5B,cAAI,UAAU,MAAM,OAAO,GAAG,MAAM,KAAK;AACvC,mBAAO,KAAK,GAAG;AAAA,UACjB,OAAO;AACL,mBAAO,KAAK,GAAG;AAAA,UACjB;AAAA,QACF,OAAO;AACL,iBAAO,KAAK,GAAG;AAAA,QACjB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAWE,SAAS,YACT,EAAE,SAAS,MAAM,SAAS,aAC1B,EAAE,SAAS,SAAS,SAAS,UAAU,SAAS;AAAA,QAChD;AACA,eAAO,KAAK,EAAE;AAAA,MAChB;AAGA,iBAAW,IAAI;AACf,kBAAY;AAAA,IACd,WAAW,OAAO,WAAW,OAAO,SAAS;AAC3C,kBAAY;AAAA,IACd;AAEA,WAAO;AAAA,EACT;AAKA,MAAI,CAAC,OAAO,OAAQ,QAAO,KAAK,EAAE;AAElC,SAAO;AACT;AAKO,SAAS,iBAAiB,OAAe,OAAuB;AACrE,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,MAAI,MAAM,WAAW,GAAG,GAAG;AACzB,WAAO,QAAQ;AAAA,EACjB;AAGA,MAAI,MAAM,WAAW,GAAG,GAAG;AACzB,WAAO,QAAQ;AAAA,EACjB;AAEA,SAAO,GAAG,KAAK,IAAI,KAAK;AAC1B;AAKO,SAAS,gBAAgB,KAAU;AACxC,SAAO,EAAE,MAAM,QAAQ,GAAG,KAAK,IAAI,WAAW;AAChD;AA+BO,SAAS,sBACd,OACA,SAsCU;AACV,QAAM,gBAAgB,CACpB,UACG;AACH,WAAO,MAAM,WAAW,OAAO,OAAO,EAAE,IAAI,CAAC,cAAc;AACzD,aAAO;AAAA,QACL,OAAO,UAAW;AAAA,QAClB,UAAU,UAAW;AAAA,MAAA;AAAA,IAEzB,CAAC;AAAA,EACH;AAEA,SAAO,QAAQ,gBAAgB;AAAA,IAC7B,MAAM,QAAQ;AAAA,IACd,YAAY,QAAQ;AAAA,IACpB,OAAO,EAAE,MAAM,OAAO,WAAW,QAAQ,WAAW,OAAO,MAAA;AAAA,IAC3D;AAAA,EAAA,CACD;AACH;AAKO,SAAS,uBACd,OACA,SAoCU;AACV,QAAM,EAAE,oBAAoB;AAC5B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACG,QAAQ,cAAc,CAAA;AAiB3B,QAAM,oBAAoB,mBAAmB;AAE7C,QAAM,gBAAgB,CACpB,UACG;AACH,WAAO,MAAM,WAAW,OAAO,OAAO,EAAE,IAAI,CAAC,cAAc;AACzD,YAAM,iBAAiB,WAAW,SAAS;AAE3C,UAAI,aAAa;AAEjB,cAAQ,gBAAA;AAAA,QACN,KAAK;AACH,uBAAa,2BAA2B;AACxC;AAAA,QACF,KAAK;AACH,uBAAa,yBAAyB;AACtC;AAAA,QACF,KAAK;AACH,uBAAa,4BAA4B;AACzC;AAAA,QACF,KAAK;AACH,uBAAa;AACb;AAAA,MAEA;AAGJ,UAAI,UAAU,UAAU;AACtB,qBAAa;AAAA,MACf;AAEA,aAAO;AAAA,QACL,OAAO;AAAA,QACP,UAAU,UAAW;AAAA,QACrB;AAAA,MAAA;AAAA,IAEJ,CAAC;AAAA,EACH;AAEA,SAAO,QAAQ,gBAAgB;AAAA,IAC7B,MAAM,QAAQ;AAAA,IACd,YAAY,QAAQ;AAAA,IACpB,OAAO,EAAE,MAAM,OAAO,WAAW,QAAQ,WAAW,OAAO,KAAA;AAAA,IAC3D;AAAA,EAAA,CACD;AACH;AAEO,MAAM,8BAA8B,CACzC,UACgD;AAChD,SAAO,CAAC,CAAC,SAAS,OAAO,UAAU,YAAY,YAAY;AAC7D;AAEO,SAAS,SAAY,MAAS,MAAS;AAC5C,MAAI,OAAO,GAAG,MAAM,IAAI,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,MACE,OAAO,SAAS,YAChB,SAAS,QACT,OAAO,SAAS,YAChB,SAAS,MACT;AACA,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB,QAAQ,gBAAgB,MAAM;AAChD,WAAO,KAAK,cAAc,KAAK,QAAA;AAAA,EACjC;AAEA,MAAI,gBAAgB,OAAO,gBAAgB,KAAK;AAC9C,QAAI,KAAK,SAAS,KAAK,KAAM,QAAO;AACpC,eAAW,CAAC,GAAG,CAAC,KAAK,MAAM;AACzB,UAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,EAAG,QAAO;AAAA,IACzD;AACA,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB,OAAO,gBAAgB,KAAK;AAC9C,QAAI,KAAK,SAAS,KAAK,KAAM,QAAO;AACpC,eAAW,KAAK,MAAM;AACpB,UAAI,CAAC,KAAK,IAAI,CAAC,EAAG,QAAO;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,OAAO,KAAK,IAAI;AAC9B,QAAM,QAAQ,OAAO,KAAK,IAAI;AAE9B,MAAI,MAAM,WAAW,MAAM,QAAQ;AACjC,WAAO;AAAA,EACT;AAMA,MACE,MAAM,WAAW,KACjB,CAAC,MAAM,QAAQ,IAAI,KACnB,CAAC,MAAM,QAAQ,IAAI,MAClB,OAAO,eAAe,IAAI,MAAM,OAAO,aACtC,OAAO,eAAe,IAAI,MAAM,OAAO,YACzC;AACA,WAAO;AAAA,EACT;AAEA,aAAW,OAAO,OAAO;AAGvB,QACE,CAAC,MAAM,SAAS,GAAG,KACnB,CAAC,SAAS,KAAK,GAAc,GAAG,KAAK,GAAc,CAAC,GACpD;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAMO,MAAM,wCAAwC,CAAC;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AACF,MAOK;AAEH,MAAI,uBAAuB;AACzB,WAAO,EAAE,eAAe,uBAAuB,WAAW,OAAA;AAAA,EAC5D;AAGA,MAAI,kCAAkC;AACpC,WAAO,EAAE,eAAe,QAAW,WAAW,OAAA;AAAA,EAChD;AAGA,MAAI,oBAAoB;AACtB,WAAO,EAAE,eAAe,oBAAoB,WAAW,QAAA;AAAA,EACzD;AAGA,SAAO,EAAE,eAAe,QAAW,WAAW,OAAA;AAChD;AAMO,MAAM,yCAAyC,CAAC;AAAA,EACrD;AAAA,EACA;AACF,MAMK;AAEH,MAAI,iBAAiB;AACnB,WAAO,EAAE,eAAe,iBAAiB,WAAW,QAAA;AAAA,EACtD;AAGA,MAAI,gBAAgB;AAClB,WAAO,EAAE,eAAe,gBAAgB,WAAW,OAAA;AAAA,EACrD;AAEA,SAAO,EAAE,eAAe,QAAW,WAAW,OAAA;AAChD;AAEO,SAAS,eAAkB,QAA4C;AAC5E,QAAM,SAAgC,CAAA;AAEtC,aAAW,OAAO,QAAQ;AACxB,WAAO,GAAG,IAAI;AAAA,EAChB;AAEA,SAAO;AACT;AAMO,SAAS,UACd,cACA,WACG;AACH,MAAI,iBAAiB,UAAa,iBAAiB,MAAM;AACvD,WAAO;AAAA,EACT;AAEA,SAAO,EAAE,GAAG,cAAc,GAAG,UAAA;AAC/B;AAQA,IAAI,MAAM;AACV,MAAM,MAAgB,CAAA;AACtB,IAAI;AAEJ,OAAO,OAAO;AACZ,MAAI,GAAG,KAAK,MAAM,KAAK,SAAS,EAAE,EAAE,UAAU,CAAC;AACjD;AAEO,SAAS,OAAe;AAC7B,MAAI,IAAI;AACR,MAAI;AACJ,MAAI,MAAM;AAEV,MAAI,CAAC,UAAU,MAAM,KAAK,KAAK;AAC7B,aAAS,IAAI,MAAc,GAAG;AAC9B,QAAI;AACJ,WAAO,KAAK;AACV,aAAO,CAAC,IAAK,MAAM,KAAK,WAAY;AAAA,IACtC;AACA,QAAI;AACJ,UAAM;AAAA,EACR;AAEA,SAAO,IAAI,IAAI,KAAK;AAClB,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,MAAM,EAAG,QAAO,IAAK,MAAM,KAAM,EAAE;AAAA,aAC9B,MAAM,EAAG,QAAO,IAAK,MAAM,KAAM,GAAG;AAAA,QACxC,QAAO,IAAI,GAAG;AAEnB,QAAI,IAAI,KAAK,IAAI,KAAK,IAAI,GAAI,QAAO;AAAA,EACvC;AAEA;AACA,SAAO;AACT;AAEO,MAAM,oBAAoB;AAAA,EAC/B,CAAC,SACC,gBAAgB,KAAK,cAAc;AAAA,IACjC,IAAI,KAAK;AAAA,IACT,OAAO,KAAK,MAAM;AAAA,EAAA,CACnB;AAAA,EACH;AAAA,IACE,MAAM;AAAA,EAAA;AAEV;AAIO,SAAS,SAAY,KAAW;AACrC,MAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;AAC3C,WAAO;AAAA,EACT;AAEA,MAAI,eAAe,MAAM;AACvB,WAAO,IAAI,KAAK,IAAI,SAAS;AAAA,EAC/B;AAEA,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,UAAM,UAAU,CAAA;AAChB,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,cAAQ,CAAC,IAAI,SAAS,IAAI,CAAC,CAAC;AAAA,IAC9B;AACA,WAAO;AAAA,EACT;AAEA,MAAI,eAAe,KAAK;AACtB,UAAM,8BAAc,IAAA;AACpB,QAAI,QAAQ,CAAC,OAAO,QAAQ;AAC1B,cAAQ,IAAI,KAAK,SAAS,KAAK,CAAC;AAAA,IAClC,CAAC;AACD,WAAO;AAAA,EACT;AAEA,MAAI,eAAe,KAAK;AACtB,UAAM,8BAAc,IAAA;AACpB,QAAI,QAAQ,CAAC,UAAU;AACrB,cAAQ,IAAI,SAAS,KAAK,CAAC;AAAA,IAC7B,CAAC;AACD,WAAO;AAAA,EACT;AAEA,QAAM,OAA+B,CAAA;AACrC,aAAW,OAAO,KAAK;AACrB,QAAI,OAAO,UAAU,eAAe,KAAK,KAAK,GAAG,GAAG;AAClD,WAAK,GAAG,IAAI,SAAU,IAAY,GAAG,CAAC;AAAA,IACxC;AAAA,EACF;AACA,SAAO;AACT;"}
{"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["import { liteThrottle } from '@tanstack/pacer-lite'\nimport { formEventClient } from './EventClient'\nimport { AnyFormGroupApi } from './FormGroupApi'\nimport type { ValidationLogicProps } from './ValidationLogic'\nimport type { FieldValidators } from './FieldApi'\nimport type { AnyFormApi, FormValidators } from './FormApi'\nimport type {\n GlobalFormValidationError,\n ValidationCause,\n ValidationError,\n ValidationSource,\n} from './types'\n\nexport type UpdaterFn<TInput, TOutput = TInput> = (input: TInput) => TOutput\n\nexport type Updater<TInput, TOutput = TInput> =\n | TOutput\n | UpdaterFn<TInput, TOutput>\n\n/**\n * @private\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 * @private\n */\nexport function getBy(obj: unknown, path: string | (string | number)[]): any {\n const pathObj = makePathArray(path)\n return pathObj.reduce((current: any, pathPart) => {\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 * @private\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 (\n typeof key === 'string' ||\n (typeof key === 'number' && !Array.isArray(parent))\n ) {\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) && typeof key === 'number') {\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 * @private\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 (\n typeof key === 'string' ||\n (typeof key === 'number' && !Array.isArray(parent))\n ) {\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\n// Char codes used by the parser below.\nconst CC_DOT = 0x2e // '.'\nconst CC_OPEN = 0x5b // '['\nconst CC_CLOSE = 0x5d // ']'\nconst CC_ZERO = 0x30 // '0'\nconst CC_NINE = 0x39 // '9'\n\n/**\n * @private\n */\nexport function makePathArray(str: string | Array<string | number>) {\n if (Array.isArray(str)) {\n return [...str]\n }\n\n if (typeof str !== 'string') {\n throw new Error('Path must be a string.')\n }\n\n const len = str.length\n const result: Array<string | number> = []\n // Location of the first character of the in-progress segment in `str`.\n // The segment ends at the current `i` when we hit a separator.\n //\n // We strip an optional leading '[' so '[0]' parses as [0], not ['', 0].\n // Doing this up front keeps the loop's backwards compatibility handling simpler.\n let segStart = len > 0 && str.charCodeAt(0) === CC_OPEN ? 1 : 0\n // Whether the in-progress segment has been all ASCII digits so far.\n // Used together with the leading-zero check to decide if it should be\n // pushed as a number instead of a string.\n let allDigits = true\n // Tracks the previous character. Only necessary to preserve the\n // old behavior for malformed input.\n let prev = -1\n // Walk once. `i === len` is treated as a virtual final separator so the\n // flush block handles both mid-string segments and the last one.\n for (let i = segStart; i <= len; i++) {\n const char = i < len ? str.charCodeAt(i) : -1\n\n // Handle separators (including the virtual one at the end). Flush the in-progress segment.\n if (i === len || char === CC_DOT || char === CC_OPEN || char === CC_CLOSE) {\n const segLen = i - segStart\n if (segLen > 0) {\n // To treat the segment as a number...\n const treatAsNumber =\n // ...it must contain only digits...\n allDigits &&\n // ...and either be a single '0' or not start with '0'.\n (segLen === 1 || str.charCodeAt(segStart) !== CC_ZERO)\n\n const seg = str.slice(segStart, i)\n if (treatAsNumber) {\n const num = parseInt(seg, 10)\n // Up to 15 digits, parseInt is always lossless (the max\n // 15-digit decimal is below Number.MAX_SAFE_INTEGER). Beyond\n // that, verify by round-trip: if parseInt lost precision\n // (e.g., a 20-digit literal), fall back to the string so we\n // don't silently change the value.\n if (segLen <= 15 || String(num) === seg) {\n result.push(num)\n } else {\n result.push(seg)\n }\n } else {\n result.push(seg)\n }\n } else if (\n // This branch, which handles empty segments, only exists to preserve\n // the old behavior for malformed input.\n\n // Push the empty segment unless this is a \"phantom boundary\" the\n // old regex impl would have absorbed:\n // 1. `]` was always stripped — `prev === ']'` means the real\n // boundary already happened on the previous iteration.\n // 2. A leading `]` was stripped too (the leading `[` strip\n // above handles its counterpart for `[`).\n // 3. `..` and `[[` collapse to a single boundary.\n prev !== CC_CLOSE &&\n !(prev === -1 && char === CC_CLOSE) &&\n !(prev === char && (char === CC_DOT || char === CC_OPEN))\n ) {\n result.push('')\n }\n\n // Start a new segment.\n segStart = i + 1\n allDigits = true\n } else if (char < CC_ZERO || char > CC_NINE) {\n allDigits = false\n }\n\n prev = char\n }\n\n // If the input was effectively all phantom chars (e.g. ']', '[]',\n // '[]]'), the loop produces no segments. The old impl returned ['']\n // for these because.\n if (!result.length) result.push('')\n\n return result\n}\n\n/**\n * @private\n */\nexport function concatenatePaths(path1: string, path2: string): string {\n if (path1.length === 0) return path2\n if (path2.length === 0) return path1\n\n if (path2.startsWith('[')) {\n return path1 + path2\n }\n\n // In cases where parent and child withFieldGroup forms are both nested\n if (path2.startsWith('.')) {\n return path1 + path2\n }\n\n return `${path1}.${path2}`\n}\n\n/**\n * @private\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\n/**\n * @private\n */\nexport interface AsyncValidator<T> {\n cause: ValidationCause\n validate: T\n debounceMs: number\n}\n\ninterface SyncValidatorArrayPartialOptions<T> {\n validators?: T\n}\n\n/**\n * @private\n */\nexport interface SyncValidator<T> {\n cause: ValidationCause\n validate: T\n}\n\n/**\n * @private\n */\nexport function getSyncValidatorArray<T>(\n cause: ValidationCause,\n options: SyncValidatorArrayPartialOptions<T> & {\n validationLogic?: any\n form?: any\n group?: any\n fieldName?: string\n },\n): T extends FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n ? Array<\n SyncValidator<\n | T['onChange']\n | T['onBlur']\n | T['onSubmit']\n | T['onMount']\n | T['onDynamic']\n >\n >\n : T extends FormValidators<any, any, any, any, any, any, any, any, any, any>\n ? Array<\n SyncValidator<\n | T['onChange']\n | T['onBlur']\n | T['onSubmit']\n | T['onMount']\n | T['onDynamic']\n >\n >\n : never {\n const runValidation = (\n props: Parameters<ValidationLogicProps['runValidation']>[0],\n ) => {\n return props.validators.filter(Boolean).map((validator) => {\n return {\n cause: validator!.cause,\n validate: validator!.fn,\n }\n })\n }\n\n return options.validationLogic({\n form: options.form,\n group: options.group,\n validators: options.validators,\n event: { type: cause, fieldName: options.fieldName, async: false },\n runValidation,\n })\n}\n\n/**\n * @private\n */\nexport function getAsyncValidatorArray<T>(\n cause: ValidationCause,\n options: AsyncValidatorArrayPartialOptions<T> & {\n validationLogic?: any\n form?: any\n group?: any\n fieldName?: string\n },\n): T extends FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n ? Array<\n AsyncValidator<\n | T['onChangeAsync']\n | T['onBlurAsync']\n | T['onSubmitAsync']\n | T['onDynamicAsync']\n >\n >\n : T extends FormValidators<any, any, any, any, any, any, any, any, any, any>\n ? Array<\n AsyncValidator<\n | T['onChangeAsync']\n | T['onBlurAsync']\n | T['onSubmitAsync']\n | T['onDynamicAsync']\n >\n >\n : never {\n const { asyncDebounceMs } = options\n const {\n onBlurAsyncDebounceMs,\n onChangeAsyncDebounceMs,\n onDynamicAsyncDebounceMs,\n } = (options.validators || {}) as\n | FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n | FormValidators<any, any, any, any, any, any, any, any, any, any>\n\n const defaultDebounceMs = asyncDebounceMs ?? 0\n\n const runValidation = (\n props: Parameters<ValidationLogicProps['runValidation']>[0],\n ) => {\n return props.validators.filter(Boolean).map((validator) => {\n const validatorCause = validator?.cause || cause\n\n let debounceMs = defaultDebounceMs\n\n switch (validatorCause) {\n case 'change':\n debounceMs = onChangeAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'blur':\n debounceMs = onBlurAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'dynamic':\n debounceMs = onDynamicAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'submit':\n debounceMs = 0 // submit validators are always run immediately\n break\n default:\n break\n }\n\n if (cause === 'submit') {\n debounceMs = 0\n }\n\n return {\n cause: validatorCause,\n validate: validator!.fn,\n debounceMs: debounceMs,\n }\n })\n }\n\n return options.validationLogic({\n form: options.form,\n group: options.group,\n validators: options.validators,\n event: { type: cause, fieldName: options.fieldName, async: true },\n runValidation,\n })\n}\n\nexport const isGlobalFormValidationError = (\n error: unknown,\n): error is GlobalFormValidationError<unknown> => {\n return !!error && typeof error === 'object' && 'fields' in error\n}\n\nexport function evaluate<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n if (objA instanceof Date && objB instanceof Date) {\n return objA.getTime() === objB.getTime()\n }\n\n if (objA instanceof Map && objB instanceof Map) {\n if (objA.size !== objB.size) return false\n for (const [k, v] of objA) {\n if (!objB.has(k) || !Object.is(v, objB.get(k))) return false\n }\n return true\n }\n\n if (objA instanceof Set && objB instanceof Set) {\n if (objA.size !== objB.size) return false\n for (const v of objA) {\n if (!objB.has(v)) return false\n }\n return true\n }\n\n const keysA = Object.keys(objA)\n const keysB = Object.keys(objB)\n\n if (keysA.length !== keysB.length) {\n return false\n }\n\n // Two distinct non-plain, non-array objects with no own enumerable keys cannot\n // be compared by key iteration — the loop below would vacuously succeed and\n // treat them as equal regardless of their internal state. This covers Temporal\n // types, RegExp, and any class that exposes values only through getters.\n if (\n keysA.length === 0 &&\n !Array.isArray(objA) &&\n !Array.isArray(objB) &&\n (Object.getPrototypeOf(objA) !== Object.prototype ||\n Object.getPrototypeOf(objB) !== Object.prototype)\n ) {\n return false\n }\n\n for (const key of keysA) {\n // performs recursive search down the object tree\n\n if (\n !keysB.includes(key) ||\n !evaluate(objA[key as keyof T], objB[key as keyof T])\n ) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Determines the logic for determining the error source and value to set on the field meta within the form level sync/async validation.\n * @private\n */\nexport const determineFormLevelErrorSourceAndValue = ({\n newFormValidatorError,\n isPreviousErrorFromFormValidator,\n previousErrorValue,\n}: {\n newFormValidatorError: ValidationError\n isPreviousErrorFromFormValidator: boolean\n previousErrorValue: ValidationError\n}): {\n newErrorValue: ValidationError\n newSource: ValidationSource | undefined\n} => {\n // All falsy values are not considered errors\n if (newFormValidatorError) {\n return { newErrorValue: newFormValidatorError, newSource: 'form' }\n }\n\n // Clears form level error since it's now stale\n if (isPreviousErrorFromFormValidator) {\n return { newErrorValue: undefined, newSource: undefined }\n }\n\n // At this point, we have a preivous error which must have been set by the field validator, keep as is\n if (previousErrorValue) {\n return { newErrorValue: previousErrorValue, newSource: 'field' }\n }\n\n // No new or previous error, clear the error\n return { newErrorValue: undefined, newSource: undefined }\n}\n\n/**\n * Determines the logic for determining the error source and value to set on the field meta within the field level sync/async validation.\n * @private\n */\nexport const determineFieldLevelErrorSourceAndValue = ({\n formLevelError,\n fieldLevelError,\n}: {\n formLevelError: ValidationError\n fieldLevelError: ValidationError\n}): {\n newErrorValue: ValidationError\n newSource: ValidationSource | undefined\n} => {\n // At field level, we prioritize the field level error\n if (fieldLevelError) {\n return { newErrorValue: fieldLevelError, newSource: 'field' }\n }\n\n // If there is no field level error, and there is a form level error, we set the form level error\n if (formLevelError) {\n return { newErrorValue: formLevelError, newSource: 'form' }\n }\n\n return { newErrorValue: undefined, newSource: undefined }\n}\n\nexport function createFieldMap<T>(values: Readonly<T>): { [K in keyof T]: K } {\n const output: { [K in keyof T]: K } = {} as any\n\n for (const key in values) {\n output[key] = key\n }\n\n return output\n}\n\n/**\n * Merge the first parameter with the given overrides.\n * @private\n */\nexport function mergeOpts<T>(\n originalOpts: T | undefined | null,\n overrides: T,\n): T {\n if (originalOpts === undefined || originalOpts === null) {\n return overrides\n }\n\n return { ...originalOpts, ...overrides }\n}\n\n/*\n/ credit is due to https://github.com/lukeed/uuid for this code, with current npm\n/ attacks we didn't feel comfortable installing directly from npm. But big appreciation\n/ from the TanStack Form team <3.\n*/\n\nlet IDX = 256\nconst HEX: string[] = []\nlet BUFFER: number[] | undefined\n\nwhile (IDX--) {\n HEX[IDX] = (IDX + 256).toString(16).substring(1)\n}\n\nexport function uuid(): string {\n let i = 0\n let num: number\n let out = ''\n\n if (!BUFFER || IDX + 16 > 256) {\n BUFFER = new Array<number>(256)\n i = 256\n while (i--) {\n BUFFER[i] = (256 * Math.random()) | 0\n }\n i = 0\n IDX = 0\n }\n\n for (; i < 16; i++) {\n num = BUFFER[IDX + i] as number\n if (i === 6) out += HEX[(num & 15) | 64]\n else if (i === 8) out += HEX[(num & 63) | 128]\n else out += HEX[num]\n\n if (i & 1 && i > 1 && i < 11) out += '-'\n }\n\n IDX++\n return out\n}\n\nexport const throttleFormState = liteThrottle(\n (form: AnyFormApi) =>\n formEventClient.emit('form-state', {\n id: form.formId,\n state: form.store.state,\n }),\n {\n wait: 300,\n },\n)\n\n// Do not use a serialize and deserialize method like JSON.stringify/parse\n// as that will drop functions, dates, undefined, Infinity, NaN, etc.\nexport function deepCopy<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as any\n }\n\n if (Array.isArray(obj)) {\n const arrCopy = [] as any[]\n for (let i = 0; i < obj.length; i++) {\n arrCopy[i] = deepCopy(obj[i])\n }\n return arrCopy as any\n }\n\n if (obj instanceof Map) {\n const mapCopy = new Map()\n obj.forEach((value, key) => {\n mapCopy.set(key, deepCopy(value))\n })\n return mapCopy as any\n }\n\n if (obj instanceof Set) {\n const setCopy = new Set()\n obj.forEach((value) => {\n setCopy.add(deepCopy(value))\n })\n return setCopy as any\n }\n\n const copy: { [key: string]: any } = {}\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n copy[key] = deepCopy((obj as any)[key])\n }\n }\n return copy as T\n}\n\n/**\n * @private\n */\nexport function isFieldInGroup(groupName: string, fieldName: string) {\n return (\n fieldName === groupName ||\n fieldName.startsWith(`${groupName}.`) ||\n fieldName.startsWith(`${groupName}[`)\n )\n}\n"],"names":[],"mappings":"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"}
import { AnyFormApi, FormValidators } from './FormApi.js';
import { AnyFormGroupApi } from './FormGroupApi.js';
export interface ValidationLogicValidatorsFn {

@@ -8,2 +9,8 @@ fn: FormValidators<any, any, any, any, any, any, any, any, any, any>[keyof FormValidators<any, any, any, any, any, any, any, any, any, any>];

form: AnyFormApi;
/**
* Set when the validators being processed belong to a `FormGroupApi`.
* Allows validation strategies (e.g. `revalidateLogic`) to gate their
* behavior on the group's own state instead of the parent form's.
*/
group?: AnyFormGroupApi;
validators: FormValidators<any, any, any, any, any, any, any, any, any, any> | undefined | null;

@@ -10,0 +17,0 @@ event: {

@@ -17,3 +17,4 @@ const revalidateLogic = ({

const validatorsToAdd = [];
const modeToWatch = props.form.state.submissionAttempts === 0 ? mode : modeAfterSubmission;
const submissionAttempts = props.group ? props.group.state.meta.submissionAttempts : props.form.state.submissionAttempts;
const modeToWatch = submissionAttempts === 0 ? mode : modeAfterSubmission;
if ([modeToWatch, "submit"].includes(props.event.type)) {

@@ -20,0 +21,0 @@ validatorsToAdd.push(dynamicValidator);

@@ -1,1 +0,1 @@

{"version":3,"file":"ValidationLogic.js","sources":["../../src/ValidationLogic.ts"],"sourcesContent":["import type { AnyFormApi, FormValidators } from './FormApi'\n\nexport interface ValidationLogicValidatorsFn {\n // TODO: Type this properly\n fn: FormValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >[keyof FormValidators<any, any, any, any, any, any, any, any, any, any>]\n cause: 'change' | 'blur' | 'submit' | 'mount' | 'server' | 'dynamic'\n}\n\nexport interface ValidationLogicProps {\n // TODO: Type this properly\n form: AnyFormApi\n // TODO: Type this properly\n validators:\n | FormValidators<any, any, any, any, any, any, any, any, any, any>\n | undefined\n | null\n event: {\n type: 'blur' | 'change' | 'submit' | 'mount' | 'server'\n fieldName?: string\n async: boolean\n }\n runValidation: (props: {\n validators: Array<ValidationLogicValidatorsFn | undefined>\n form: AnyFormApi\n }) => void\n}\n\ninterface RevalidateLogicProps {\n /**\n * @default 'submit'\n *\n * This is the mode that will be used before the form has been submitted.\n * It will run the validation logic on `submit` by default, but can be set to `change` or `blur`.\n */\n mode?: 'change' | 'blur' | 'submit'\n /**\n * @default 'change'\n *\n * This is the mode that will be used after the form has been submitted.\n * It will run the validation logic on `change` by default, but can be set to `blur` or `submit`.\n */\n modeAfterSubmission?: 'change' | 'blur' | 'submit'\n}\n\nexport type ValidationLogicFn = (props: ValidationLogicProps) => void\n\n/**\n * This forces a form's validation logic to be ran as if it were a React Hook Form validation logic.\n *\n * This means that it will only run the `onDynamic` validator, and it will not run any other validators and changes the validation\n * type based on the state of the form itself.\n *\n * When the form is not yet submitted, it will not run the validation logic.\n * When the form is submitted, it will run the validation logic on `change`\n */\nexport const revalidateLogic =\n ({\n mode = 'submit',\n modeAfterSubmission = 'change',\n }: RevalidateLogicProps = {}): ValidationLogicFn =>\n (props) => {\n const validatorNames = Object.keys(props.validators ?? {})\n if (validatorNames.length === 0) {\n // No validators is a valid case, just return\n return props.runValidation({\n validators: [],\n form: props.form,\n })\n }\n\n const dynamicValidator = {\n fn: props.event.async\n ? props.validators!['onDynamicAsync']\n : props.validators!['onDynamic'],\n cause: 'dynamic',\n } as const\n\n const validatorsToAdd = [] as ValidationLogicValidatorsFn[]\n\n const modeToWatch =\n props.form.state.submissionAttempts === 0 ? mode : modeAfterSubmission\n\n if ([modeToWatch, 'submit'].includes(props.event.type)) {\n validatorsToAdd.push(dynamicValidator)\n }\n\n let defaultValidators = [] as ValidationLogicValidatorsFn[]\n\n defaultValidationLogic({\n ...props,\n runValidation: (vProps) => {\n defaultValidators = vProps.validators as ValidationLogicValidatorsFn[]\n },\n })\n\n if (validatorsToAdd.length === 0) {\n return props.runValidation({\n validators: defaultValidators,\n form: props.form,\n })\n }\n\n return props.runValidation({\n validators: [...defaultValidators, ...validatorsToAdd],\n form: props.form,\n })\n }\n\nexport const defaultValidationLogic: ValidationLogicFn = (props) => {\n // Handle case where no validators are provided\n if (!props.validators) {\n return props.runValidation({\n validators: [],\n form: props.form,\n })\n }\n\n const isAsync = props.event.async\n\n const onMountValidator = isAsync\n ? undefined\n : ({ fn: props.validators.onMount, cause: 'mount' } as const)\n\n const onChangeValidator = {\n fn: isAsync ? props.validators.onChangeAsync : props.validators.onChange,\n cause: 'change',\n } as const\n\n const onBlurValidator = {\n fn: isAsync ? props.validators.onBlurAsync : props.validators.onBlur,\n cause: 'blur',\n } as const\n\n const onSubmitValidator = {\n fn: isAsync ? props.validators.onSubmitAsync : props.validators.onSubmit,\n cause: 'submit',\n } as const\n\n // Allows us to clear onServer errors\n const onServerValidator = isAsync\n ? undefined\n : ({ fn: () => undefined, cause: 'server' } as const)\n\n switch (props.event.type) {\n case 'mount': {\n // Run mount validation\n return props.runValidation({\n validators: [onMountValidator],\n form: props.form,\n })\n }\n case 'submit': {\n // Run change, blur, submit, server validation\n return props.runValidation({\n validators: [\n onChangeValidator,\n onBlurValidator,\n onSubmitValidator,\n onServerValidator,\n ],\n form: props.form,\n })\n }\n case 'server': {\n // Run server validation\n return props.runValidation({\n validators: [],\n form: props.form,\n })\n }\n case 'blur': {\n // Run blur, server validation\n return props.runValidation({\n validators: [onBlurValidator, onServerValidator],\n form: props.form,\n })\n }\n case 'change': {\n // Run change, server validation\n return props.runValidation({\n validators: [onChangeValidator, onServerValidator],\n form: props.form,\n })\n }\n default: {\n throw new Error(`Unknown validation event type: ${props.event.type}`)\n }\n }\n}\n"],"names":[],"mappings":"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"}
{"version":3,"file":"ValidationLogic.js","sources":["../../src/ValidationLogic.ts"],"sourcesContent":["import type { AnyFormApi, FormValidators } from './FormApi'\nimport type { AnyFormGroupApi } from './FormGroupApi'\n\nexport interface ValidationLogicValidatorsFn {\n // TODO: Type this properly\n fn: FormValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >[keyof FormValidators<any, any, any, any, any, any, any, any, any, any>]\n cause: 'change' | 'blur' | 'submit' | 'mount' | 'server' | 'dynamic'\n}\n\nexport interface ValidationLogicProps {\n // TODO: Type this properly\n form: AnyFormApi\n /**\n * Set when the validators being processed belong to a `FormGroupApi`.\n * Allows validation strategies (e.g. `revalidateLogic`) to gate their\n * behavior on the group's own state instead of the parent form's.\n */\n group?: AnyFormGroupApi\n // TODO: Type this properly\n validators:\n | FormValidators<any, any, any, any, any, any, any, any, any, any>\n | undefined\n | null\n event: {\n type: 'blur' | 'change' | 'submit' | 'mount' | 'server'\n fieldName?: string\n async: boolean\n }\n runValidation: (props: {\n validators: Array<ValidationLogicValidatorsFn | undefined>\n form: AnyFormApi\n }) => void\n}\n\ninterface RevalidateLogicProps {\n /**\n * @default 'submit'\n *\n * This is the mode that will be used before the form has been submitted.\n * It will run the validation logic on `submit` by default, but can be set to `change` or `blur`.\n */\n mode?: 'change' | 'blur' | 'submit'\n /**\n * @default 'change'\n *\n * This is the mode that will be used after the form has been submitted.\n * It will run the validation logic on `change` by default, but can be set to `blur` or `submit`.\n */\n modeAfterSubmission?: 'change' | 'blur' | 'submit'\n}\n\nexport type ValidationLogicFn = (props: ValidationLogicProps) => void\n\n/**\n * This forces a form's validation logic to be ran as if it were a React Hook Form validation logic.\n *\n * This means that it will only run the `onDynamic` validator, and it will not run any other validators and changes the validation\n * type based on the state of the form itself.\n *\n * When the form is not yet submitted, it will not run the validation logic.\n * When the form is submitted, it will run the validation logic on `change`\n */\nexport const revalidateLogic =\n ({\n mode = 'submit',\n modeAfterSubmission = 'change',\n }: RevalidateLogicProps = {}): ValidationLogicFn =>\n (props) => {\n const validatorNames = Object.keys(props.validators ?? {})\n if (validatorNames.length === 0) {\n // No validators is a valid case, just return\n return props.runValidation({\n validators: [],\n form: props.form,\n })\n }\n\n const dynamicValidator = {\n fn: props.event.async\n ? props.validators!['onDynamicAsync']\n : props.validators!['onDynamic'],\n cause: 'dynamic',\n } as const\n\n const validatorsToAdd = [] as ValidationLogicValidatorsFn[]\n\n // When validating a `FormGroupApi`'s own validators, gate on the group's\n // submission attempts so a group's `onDynamic` validator only flips into\n // `modeAfterSubmission` after that group itself has been submitted.\n // Otherwise (form-level validators), gate on the parent form.\n const submissionAttempts = props.group\n ? props.group.state.meta.submissionAttempts\n : props.form.state.submissionAttempts\n\n const modeToWatch = submissionAttempts === 0 ? mode : modeAfterSubmission\n\n if ([modeToWatch, 'submit'].includes(props.event.type)) {\n validatorsToAdd.push(dynamicValidator)\n }\n\n let defaultValidators = [] as ValidationLogicValidatorsFn[]\n\n defaultValidationLogic({\n ...props,\n runValidation: (vProps) => {\n defaultValidators = vProps.validators as ValidationLogicValidatorsFn[]\n },\n })\n\n if (validatorsToAdd.length === 0) {\n return props.runValidation({\n validators: defaultValidators,\n form: props.form,\n })\n }\n\n return props.runValidation({\n validators: [...defaultValidators, ...validatorsToAdd],\n form: props.form,\n })\n }\n\nexport const defaultValidationLogic: ValidationLogicFn = (props) => {\n // Handle case where no validators are provided\n if (!props.validators) {\n return props.runValidation({\n validators: [],\n form: props.form,\n })\n }\n\n const isAsync = props.event.async\n\n const onMountValidator = isAsync\n ? undefined\n : ({ fn: props.validators.onMount, cause: 'mount' } as const)\n\n const onChangeValidator = {\n fn: isAsync ? props.validators.onChangeAsync : props.validators.onChange,\n cause: 'change',\n } as const\n\n const onBlurValidator = {\n fn: isAsync ? props.validators.onBlurAsync : props.validators.onBlur,\n cause: 'blur',\n } as const\n\n const onSubmitValidator = {\n fn: isAsync ? props.validators.onSubmitAsync : props.validators.onSubmit,\n cause: 'submit',\n } as const\n\n // Allows us to clear onServer errors\n const onServerValidator = isAsync\n ? undefined\n : ({ fn: () => undefined, cause: 'server' } as const)\n\n switch (props.event.type) {\n case 'mount': {\n // Run mount validation\n return props.runValidation({\n validators: [onMountValidator],\n form: props.form,\n })\n }\n case 'submit': {\n // Run change, blur, submit, server validation\n return props.runValidation({\n validators: [\n onChangeValidator,\n onBlurValidator,\n onSubmitValidator,\n onServerValidator,\n ],\n form: props.form,\n })\n }\n case 'server': {\n // Run server validation\n return props.runValidation({\n validators: [],\n form: props.form,\n })\n }\n case 'blur': {\n // Run blur, server validation\n return props.runValidation({\n validators: [onBlurValidator, onServerValidator],\n form: props.form,\n })\n }\n case 'change': {\n // Run change, server validation\n return props.runValidation({\n validators: [onChangeValidator, onServerValidator],\n form: props.form,\n })\n }\n default: {\n throw new Error(`Unknown validation event type: ${props.event.type}`)\n }\n }\n}\n"],"names":[],"mappings":"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"}
{
"name": "@tanstack/form-core",
"version": "1.32.1",
"version": "1.33.0",
"description": "Powerful, type-safe, framework agnostic forms.",

@@ -42,3 +42,3 @@ "author": "tannerlinsley",

"@tanstack/pacer-lite": "^0.1.1",
"@tanstack/store": "^0.9.1"
"@tanstack/store": "^0.11.0"
},

@@ -45,0 +45,0 @@ "devDependencies": {

@@ -12,27 +12,18 @@ import { batch, createStore } from '@tanstack/store'

getSyncValidatorArray,
isFieldInGroup,
mergeOpts,
} from './utils'
import { defaultValidationLogic } from './ValidationLogic'
import type { ReadonlyStore } from '@tanstack/store'
import type { AnyFormGroupApi } from './FormGroupApi'
import type {
DeepKeys,
DeepValue,
RejectPromiseValidator,
UnwrapOneLevelOfArray,
} from './util-types'
import type {
StandardSchemaV1,
StandardSchemaV1Issue,
TStandardSchemaValidatorValue,
} from './standardSchemaValidator'
import type {
FieldErrorMapFromValidator,
FieldInfo,
FormApi,
FormAsyncValidateOrFn,
FormValidateAsyncFn,
FormValidateFn,
FormValidateOrFn,
} from './FormApi'
import type {
FieldLikeAPI,
FieldLikeApiOptions,
FieldLikeMetaBase,
FieldLikeOptions,
FieldLikeState,
ListenerCause,
UnwrapFieldAsyncValidateOrFn,
UnwrapFieldValidateOrFn,
UpdateMetaOptions,

@@ -42,4 +33,10 @@ ValidationCause,

ValidationErrorMap,
ValidationErrorMapSource,
} from './types'
import type { ReadonlyStore } from '@tanstack/store'
import type { DeepKeys, DeepValue, RejectPromiseValidator } from './util-types'
import type {
StandardSchemaV1,
TStandardSchemaValidatorValue,
} from './standardSchemaValidator'
import type { FormAsyncValidateOrFn, FormValidateOrFn } from './FormApi'
import type { AsyncValidator, SyncValidator, Updater } from './utils'

@@ -50,38 +47,2 @@

*/
// TODO: Add the `Unwrap` type to the errors
type FieldErrorMapFromValidator<
TFormData,
TName extends DeepKeys<TFormData>,
TData extends DeepValue<TFormData, TName>,
TOnMount extends undefined | FieldValidateOrFn<TFormData, TName, TData>,
TOnChange extends undefined | FieldValidateOrFn<TFormData, TName, TData>,
TOnChangeAsync extends
| undefined
| FieldAsyncValidateOrFn<TFormData, TName, TData>,
TOnBlur extends undefined | FieldValidateOrFn<TFormData, TName, TData>,
TOnBlurAsync extends
| undefined
| FieldAsyncValidateOrFn<TFormData, TName, TData>,
TOnSubmit extends undefined | FieldValidateOrFn<TFormData, TName, TData>,
TOnSubmitAsync extends
| undefined
| FieldAsyncValidateOrFn<TFormData, TName, TData>,
> = Partial<
Record<
DeepKeys<TFormData>,
ValidationErrorMap<
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync
>
>
>
/**
* @private
*/
export type FieldValidateFn<

@@ -125,51 +86,2 @@ TParentData,

*/
export type FieldValidateOrFn<
TParentData,
TName extends DeepKeys<TParentData>,
TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
> =
| FieldValidateFn<TParentData, TName, TData>
| StandardSchemaV1<TData, unknown>
type StandardBrandedSchemaV1<T> = T & { __standardSchemaV1: true }
type UnwrapFormValidateOrFnForInner<
TValidateOrFn extends undefined | FormValidateOrFn<any>,
> = [TValidateOrFn] extends [FormValidateFn<any>]
? ReturnType<TValidateOrFn>
: [TValidateOrFn] extends [StandardSchemaV1<infer TOut, any>]
? StandardBrandedSchemaV1<TOut>
: undefined
export type UnwrapFieldValidateOrFn<
TName extends string,
TValidateOrFn extends undefined | FieldValidateOrFn<any, any, any>,
TFormValidateOrFn extends undefined | FormValidateOrFn<any>,
> =
| ([TFormValidateOrFn] extends [StandardSchemaV1<any, infer TStandardOut>]
? TName extends keyof TStandardOut
? StandardSchemaV1Issue[]
: undefined
: undefined)
| (UnwrapFormValidateOrFnForInner<TFormValidateOrFn> extends infer TFormValidateVal
? TFormValidateVal extends { __standardSchemaV1: true }
? [DeepValue<TFormValidateVal, TName>] extends [never]
? undefined
: StandardSchemaV1Issue[]
: TFormValidateVal extends { fields: any }
? TName extends keyof TFormValidateVal['fields']
? TFormValidateVal['fields'][TName]
: undefined
: undefined
: never)
| ([TValidateOrFn] extends [FieldValidateFn<any, any, any>]
? ReturnType<TValidateOrFn>
: [TValidateOrFn] extends [StandardSchemaV1<any, any>]
? // TODO: Check if `disableErrorFlat` is enabled, if so, return StandardSchemaV1Issue[][]
StandardSchemaV1Issue[]
: undefined)
/**
* @private
*/
export type FieldValidateAsyncFn<

@@ -214,49 +126,2 @@ TParentData,

*/
export type FieldAsyncValidateOrFn<
TParentData,
TName extends DeepKeys<TParentData>,
TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
> =
| FieldValidateAsyncFn<TParentData, TName, TData>
| StandardSchemaV1<TData, unknown>
type UnwrapFormAsyncValidateOrFnForInner<
TValidateOrFn extends undefined | FormAsyncValidateOrFn<any>,
> = [TValidateOrFn] extends [FormValidateAsyncFn<any>]
? Awaited<ReturnType<TValidateOrFn>>
: [TValidateOrFn] extends [StandardSchemaV1<infer TOut, any>]
? StandardBrandedSchemaV1<TOut>
: undefined
export type UnwrapFieldAsyncValidateOrFn<
TName extends string,
TValidateOrFn extends undefined | FieldAsyncValidateOrFn<any, any, any>,
TFormValidateOrFn extends undefined | FormAsyncValidateOrFn<any>,
> =
| ([TFormValidateOrFn] extends [StandardSchemaV1<any, infer TStandardOut>]
? TName extends keyof TStandardOut
? StandardSchemaV1Issue[]
: undefined
: undefined)
| (UnwrapFormAsyncValidateOrFnForInner<TFormValidateOrFn> extends infer TFormValidateVal
? TFormValidateVal extends { __standardSchemaV1: true }
? [DeepValue<TFormValidateVal, TName>] extends [never]
? undefined
: StandardSchemaV1Issue[]
: TFormValidateVal extends { fields: any }
? TName extends keyof TFormValidateVal['fields']
? TFormValidateVal['fields'][TName]
: undefined
: undefined
: never)
| ([TValidateOrFn] extends [FieldValidateAsyncFn<any, any, any>]
? Awaited<ReturnType<TValidateOrFn>>
: [TValidateOrFn] extends [StandardSchemaV1<any, any>]
? // TODO: Check if `disableErrorFlat` is enabled, if so, return StandardSchemaV1Issue[][]
StandardSchemaV1Issue[]
: undefined)
/**
* @private
*/
export type FieldListenerFn<

@@ -297,2 +162,24 @@ TParentData,

/**
* @private
*/
export type FieldValidateOrFn<
TParentData,
TName extends DeepKeys<TParentData>,
TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
> =
| FieldValidateFn<TParentData, TName, TData>
| StandardSchemaV1<TData, unknown>
/**
* @private
*/
export type FieldAsyncValidateOrFn<
TParentData,
TName extends DeepKeys<TParentData>,
TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
> =
| FieldValidateAsyncFn<TParentData, TName, TData>
| StandardSchemaV1<TData, unknown>
export interface FieldValidators<

@@ -398,8 +285,6 @@ TParentData,

onSubmit?: FieldListenerFn<TParentData, TName, TData>
onGroupSubmit?: FieldListenerFn<TParentData, TName, TData>
}
/**
* An object type representing the options for a field in a form.
*/
export interface FieldOptions<
interface FieldExtraOptions<
TParentData,

@@ -427,18 +312,2 @@ TName extends DeepKeys<TParentData>,

/**
* The field name. The type will be `DeepKeys<TParentData>` to ensure your name is a deep key of the parent dataset.
*/
name: TName
/**
* An optional default value for the field.
*/
defaultValue?: NoInfer<TData>
/**
* The default time to debounce async validation if there is not a more specific debounce time passed.
*/
asyncDebounceMs?: number
/**
* If `true`, always run async validation, even if there are errors emitted during synchronous validation.
*/
asyncAlways?: boolean
/**
* A list of validators to pass to the field

@@ -460,7 +329,36 @@ */

>
/**
* An optional object with default metadata for the field.
* A list of listeners which attach to the corresponding events
*/
defaultMeta?: Partial<
FieldMeta<
listeners?: FieldListeners<TParentData, TName, TData>
}
/**
* An object type representing the options for a field in a form.
*/
export interface FieldOptions<
TParentData,
TName extends DeepKeys<TParentData>,
TData extends DeepValue<TParentData, TName>,
TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnChangeAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnBlurAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnSubmitAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnDynamicAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
>
extends
FieldExtraOptions<
TParentData,

@@ -477,27 +375,19 @@ TName,

TOnDynamic,
TOnDynamicAsync,
any,
any,
any,
any,
any,
any,
any,
any,
any
>
>
/**
* A list of listeners which attach to the corresponding events
*/
listeners?: FieldListeners<TParentData, TName, TData>
/**
* Disable the `flat(1)` operation on `field.errors`. This is useful if you want to keep the error structure as is. Not suggested for most use-cases.
*/
disableErrorFlat?: boolean
}
TOnDynamicAsync
>,
FieldLikeOptions<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync
> {}
/**
* An object type representing the required options for the FieldApi class.
*/
export interface FieldApiOptions<

@@ -553,408 +443,45 @@ in out TParentData,

in out TParentSubmitMeta,
> extends FieldOptions<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync
> {
form: FormApi<
TParentData,
TFormOnMount,
TFormOnChange,
TFormOnChangeAsync,
TFormOnBlur,
TFormOnBlurAsync,
TFormOnSubmit,
TFormOnSubmitAsync,
TFormOnDynamic,
TFormOnDynamicAsync,
TFormOnServer,
TParentSubmitMeta
>
}
export type FieldMetaBase<
TParentData,
TName extends DeepKeys<TParentData>,
TData extends DeepValue<TParentData, TName>,
TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnChangeAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnBlurAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnSubmitAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnDynamicAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TFormOnMount extends undefined | FormValidateOrFn<TParentData>,
TFormOnChange extends undefined | FormValidateOrFn<TParentData>,
TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnBlur extends undefined | FormValidateOrFn<TParentData>,
TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>,
TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>,
TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
> = {
/**
* A flag indicating whether the field has been touched.
*/
isTouched: boolean
/**
* A flag indicating whether the field has been blurred.
*/
isBlurred: boolean
/**
* A flag that is `true` if the field's value has been modified by the user. Opposite of `isPristine`.
*/
isDirty: boolean
/**
* A map of errors related to the field value.
*/
errorMap: ValidationErrorMap<
UnwrapFieldValidateOrFn<TName, TOnMount, TFormOnMount>,
UnwrapFieldValidateOrFn<TName, TOnChange, TFormOnChange>,
UnwrapFieldAsyncValidateOrFn<TName, TOnChangeAsync, TFormOnChangeAsync>,
UnwrapFieldValidateOrFn<TName, TOnBlur, TFormOnBlur>,
UnwrapFieldAsyncValidateOrFn<TName, TOnBlurAsync, TFormOnBlurAsync>,
UnwrapFieldValidateOrFn<TName, TOnSubmit, TFormOnSubmit>,
UnwrapFieldAsyncValidateOrFn<TName, TOnSubmitAsync, TFormOnSubmitAsync>,
UnwrapFieldValidateOrFn<TName, TOnDynamic, TFormOnDynamic>,
UnwrapFieldAsyncValidateOrFn<TName, TOnDynamicAsync, TFormOnDynamicAsync>
>
/**
* @private allows tracking the source of the errors in the error map
*/
errorSourceMap: ValidationErrorMapSource
/**
* A flag indicating whether the field is currently being validated.
*/
isValidating: boolean
/**
* @private a counter that is incremented every time a structural array
* operation (push, insert, remove, swap, move, replace, clear) modifies
* the value of an array field. Adapters can subscribe to this to trigger
* re-renders for `mode="array"` fields without having to subscribe to the
* full field value.
*/
_arrayVersion: number
}
export type AnyFieldMetaBase = FieldMetaBase<
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any
>
extends
FieldLikeApiOptions<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync,
TFormOnMount,
TFormOnChange,
TFormOnChangeAsync,
TFormOnBlur,
TFormOnBlurAsync,
TFormOnSubmit,
TFormOnSubmitAsync,
TFormOnDynamic,
TFormOnDynamicAsync,
TFormOnServer,
TParentSubmitMeta
>,
FieldExtraOptions<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync
> {}
export type FieldMetaDerived<
TParentData,
TName extends DeepKeys<TParentData>,
TData extends DeepValue<TParentData, TName>,
TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnChangeAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnBlurAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnSubmitAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnDynamicAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TFormOnMount extends undefined | FormValidateOrFn<TParentData>,
TFormOnChange extends undefined | FormValidateOrFn<TParentData>,
TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnBlur extends undefined | FormValidateOrFn<TParentData>,
TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>,
TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>,
TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
> = {
/**
* An array of errors related to the field value.
*/
errors: Array<
| UnwrapOneLevelOfArray<
UnwrapFieldValidateOrFn<TName, TOnMount, TFormOnMount>
>
| UnwrapOneLevelOfArray<
UnwrapFieldValidateOrFn<TName, TOnChange, TFormOnChange>
>
| UnwrapOneLevelOfArray<
UnwrapFieldAsyncValidateOrFn<TName, TOnChangeAsync, TFormOnChangeAsync>
>
| UnwrapOneLevelOfArray<
UnwrapFieldValidateOrFn<TName, TOnBlur, TFormOnBlur>
>
| UnwrapOneLevelOfArray<
UnwrapFieldAsyncValidateOrFn<TName, TOnBlurAsync, TFormOnBlurAsync>
>
| UnwrapOneLevelOfArray<
UnwrapFieldValidateOrFn<TName, TOnSubmit, TFormOnSubmit>
>
| UnwrapOneLevelOfArray<
UnwrapFieldAsyncValidateOrFn<TName, TOnSubmitAsync, TFormOnSubmitAsync>
>
| UnwrapOneLevelOfArray<
UnwrapFieldValidateOrFn<TName, TOnDynamic, TFormOnDynamic>
>
| UnwrapOneLevelOfArray<
UnwrapFieldAsyncValidateOrFn<
TName,
TOnDynamicAsync,
TFormOnDynamicAsync
>
>
>
/**
* A flag that is `true` if the field's value has not been modified by the user. Opposite of `isDirty`.
*/
isPristine: boolean
/**
* A boolean indicating if the field is valid. Evaluates `true` if there are no field errors.
*/
isValid: boolean
/**
* A flag indicating whether the field's current value is the default value
*/
isDefaultValue: boolean
}
export type AnyFieldMetaDerived = FieldMetaDerived<
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any
>
/**
* An object type representing the metadata of a field in a form.
*/
export type FieldMeta<
TParentData,
TName extends DeepKeys<TParentData>,
TData extends DeepValue<TParentData, TName>,
TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnChangeAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnBlurAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnSubmitAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnDynamicAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TFormOnMount extends undefined | FormValidateOrFn<TParentData>,
TFormOnChange extends undefined | FormValidateOrFn<TParentData>,
TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnBlur extends undefined | FormValidateOrFn<TParentData>,
TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>,
TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>,
TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
> = FieldMetaBase<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync,
TFormOnMount,
TFormOnChange,
TFormOnChangeAsync,
TFormOnBlur,
TFormOnBlurAsync,
TFormOnSubmit,
TFormOnSubmitAsync,
TFormOnDynamic,
TFormOnDynamicAsync
> &
FieldMetaDerived<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync,
TFormOnMount,
TFormOnChange,
TFormOnChangeAsync,
TFormOnBlur,
TFormOnBlurAsync,
TFormOnSubmit,
TFormOnSubmitAsync,
TFormOnDynamic,
TFormOnDynamicAsync
>
export type AnyFieldMeta = FieldMeta<
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any
>
/**
* An object type representing the state of a field.
*/
export type FieldState<
TParentData,
TName extends DeepKeys<TParentData>,
TData extends DeepValue<TParentData, TName>,
TOnMount extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnChange extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnChangeAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TOnBlur extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnBlurAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TOnSubmit extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnSubmitAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TOnDynamic extends undefined | FieldValidateOrFn<TParentData, TName, TData>,
TOnDynamicAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>,
TFormOnMount extends undefined | FormValidateOrFn<TParentData>,
TFormOnChange extends undefined | FormValidateOrFn<TParentData>,
TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnBlur extends undefined | FormValidateOrFn<TParentData>,
TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>,
TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>,
TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
> = {
/**
* The current value of the field.
*/
value: TData
/**
* The current metadata of the field.
*/
meta: FieldMeta<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync,
TFormOnMount,
TFormOnChange,
TFormOnChangeAsync,
TFormOnBlur,
TFormOnBlurAsync,
TFormOnSubmit,
TFormOnSubmitAsync,
TFormOnDynamic,
TFormOnDynamicAsync
>
}
/**
* @public

@@ -1054,2 +581,40 @@ *

in out TParentSubmitMeta,
> implements FieldLikeAPI<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync,
TFormOnMount,
TFormOnChange,
TFormOnChangeAsync,
TFormOnBlur,
TFormOnBlurAsync,
TFormOnSubmit,
TFormOnSubmitAsync,
TFormOnDynamic,
TFormOnDynamicAsync,
TFormOnServer,
TParentSubmitMeta,
FieldExtraOptions<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync
>
> {

@@ -1120,3 +685,3 @@ /**

store!: ReadonlyStore<
FieldState<
FieldLikeState<
TParentData,

@@ -1200,3 +765,3 @@ TName,

prevVal:
| FieldState<
| FieldLikeState<
TParentData,

@@ -1251,3 +816,3 @@ TName,

meta,
} as FieldState<
} as FieldLikeState<
TParentData,

@@ -1521,3 +1086,3 @@ TName,

updater: Updater<
FieldMetaBase<
FieldLikeMetaBase<
TParentData,

@@ -1685,2 +1250,6 @@ TName,

if (!field.instance) continue
// TODO: How to handle FieldGroups? Do we need to? IDK.
if (!(field.instance instanceof FieldApi)) {
continue
}
const { onChangeListenTo, onBlurListenTo } =

@@ -2027,3 +1596,3 @@ field.instance.options.validators || {}

cause: ValidationCause,
opts?: { skipFormValidation?: boolean },
opts?: { skipFormValidation?: boolean; skipGroupValidation?: boolean },
): ValidationError[] | Promise<ValidationError[]> => {

@@ -2033,11 +1602,59 @@ // If the field is pristine, do not validate

// Cascade into any encompassing `FormGroupApi`'s own validators so
// group-scoped strategies (e.g. `revalidateLogic` gated on the group's
// own `submissionAttempts`) get a chance to react to this field change.
// Mirror the field's sync→short-circuit-on-error→async semantics for
// each group: only kick off async validators if the group's sync pass
// was clean (or its `asyncAlways` flag is set).
const encompassingGroups = opts?.skipGroupValidation
? []
: Array.from(this.form.formGroupApis).filter((group) =>
this.name.startsWith(group.name),
)
// Attempt to sync validate first
const { fieldsErrorMap } = opts?.skipFormValidation
const formSyncResult = opts?.skipFormValidation
? { fieldsErrorMap: {} as never }
: this.form.validateSync(cause)
const { hasErrored } = this.validateSync(
cause,
fieldsErrorMap[this.name] ?? {},
)
let fieldsErrorMap = (formSyncResult.fieldsErrorMap[this.name] ??
{}) as ValidationErrorMap
// For each encompassing group whose own submission has been attempted,
// also re-run the parent form's validators with that group as the
// gating context. This ensures form-level errors (e.g. those produced
// by a form-level z.object onDynamic during a group submit) are kept
// fresh on subsequent field changes — even though the form itself
// hasn't been submitted directly.
if (!opts?.skipFormValidation) {
for (const group of encompassingGroups) {
if (group.state.meta.submissionAttempts === 0) continue
const { fieldsErrorMap: groupFormErrors } = this.form.validateSync(
cause,
{
group,
dontUpdateFormErrorMap: true,
filterFieldNames: (fieldName) =>
isFieldInGroup(group.name, fieldName),
},
)
fieldsErrorMap = {
...fieldsErrorMap,
...(groupFormErrors[this.name] ?? {}),
}
}
}
const { hasErrored } = this.validateSync(cause, fieldsErrorMap)
const groupHasErroredWeakMap = new WeakMap<AnyFormGroupApi, boolean>()
for (const group of encompassingGroups) {
const { hasErrored: groupHasErrored } = group.validateSync(
cause,
{},
{ skipRelatedFieldValidation: true },
)
groupHasErroredWeakMap.set(group, groupHasErrored)
}
if (hasErrored && !this.options.asyncAlways) {

@@ -2047,3 +1664,14 @@ this.getInfo().validationMetaMap[

]?.lastAbortController.abort()
return this.state.meta.errors
const groupErrors = [] as ValidationError[][]
for (const group of encompassingGroups) {
group
.getInfo()
.validationMetaMap[getErrorMapKey(cause)]?.lastAbortController.abort()
groupErrors.push(group.state.meta.errors)
}
return [...this.state.meta.errors, ...groupErrors.flat()]
}

@@ -2055,3 +1683,28 @@

: this.form.validateAsync(cause)
return this.validateAsync(cause, formValidationResultPromise)
const fieldAsyncResults = this.validateAsync(
cause,
formValidationResultPromise,
)
const groupAsyncResults: Promise<ValidationError[]>[] = []
for (const group of encompassingGroups) {
if (groupHasErroredWeakMap.get(group) && !group.options.asyncAlways) {
continue
}
groupAsyncResults.push(
group.validateAsync(cause, formValidationResultPromise, {
skipRelatedFieldValidation: true,
}),
)
}
if (groupAsyncResults.length === 0) {
return fieldAsyncResults
}
return Promise.all([fieldAsyncResults, ...groupAsyncResults]).then(
(results) => results.flat(),
)
}

@@ -2131,3 +1784,3 @@

private triggerOnBlurListener() {
private triggerOnBlurListener = () => {
const formDebounceMs = this.form.options.listeners?.onBlurDebounceMs

@@ -2213,3 +1866,19 @@ if (formDebounceMs && formDebounceMs > 0) {

}
for (const group of this.form.formGroupApis) {
if (isFieldInGroup(group.name, this.name)) {
group.triggerOnChangeListener()
}
}
}
/**
* @private
*/
triggerOnSubmitListener = () => {
this.options.listeners?.onSubmit?.({
value: this.state.value,
fieldApi: this,
})
}
}

@@ -2216,0 +1885,0 @@

import { createStore } from '@tanstack/store'
import { concatenatePaths, getBy, makePathArray } from './utils'
import type {
AnyFieldLikeMetaBase,
FormLikeAPI,
UpdateMetaOptions,
ValidationCause,
} from './types'
import type { ReadonlyStore } from '@tanstack/store'

@@ -10,3 +16,3 @@ import type { Updater } from './utils'

} from './FormApi'
import type { AnyFieldMetaBase, FieldOptions } from './FieldApi'
import type { FieldOptions } from './FieldApi'
import type {

@@ -18,7 +24,2 @@ DeepKeys,

} from './util-types'
import type {
FieldManipulator,
UpdateMetaOptions,
ValidationCause,
} from './types'

@@ -132,3 +133,3 @@ export type AnyFieldGroupApi = FieldGroupApi<

in out TSubmitMeta = never,
> implements FieldManipulator<TFieldGroupData, TSubmitMeta> {
> implements FormLikeAPI<TFieldGroupData, TSubmitMeta> {
/**

@@ -374,3 +375,3 @@ * The form that called this field group.

field: TField,
updater: Updater<AnyFieldMetaBase>,
updater: Updater<AnyFieldLikeMetaBase>,
) => {

@@ -377,0 +378,0 @@ return this.form.setFieldMeta(this.getFormFieldName(field), updater)

export * from './FormApi'
export * from './FieldApi'
export * from './FormGroupApi'
export * from './utils'

@@ -4,0 +5,0 @@ export * from './util-types'

@@ -6,8 +6,8 @@ import type {

} from './FormApi'
import type { AnyFieldMeta } from './FieldApi'
import type { DeepKeys } from './util-types'
import type { AnyFieldLikeMeta } from './types'
type ValueFieldMode = 'insert' | 'remove' | 'swap' | 'move'
export const defaultFieldMeta: AnyFieldMeta = {
export const defaultFieldMeta: AnyFieldLikeMeta = {
isValidating: false,

@@ -97,3 +97,3 @@ isTouched: false,

},
new Map<DeepKeys<TFormData>, AnyFieldMeta | undefined>(),
new Map<DeepKeys<TFormData>, AnyFieldLikeMeta | undefined>(),
)

@@ -250,3 +250,3 @@

const getEmptyFieldMeta = (): AnyFieldMeta => defaultFieldMeta
const getEmptyFieldMeta = (): AnyFieldLikeMeta => defaultFieldMeta

@@ -253,0 +253,0 @@ return {

@@ -89,4 +89,5 @@ import type { ValidationSource } from './types'

if (validationSource === 'field')
if (validationSource === 'field') {
return result.issues as TStandardSchemaValidatorIssue<TSource>
}
return transformFormIssues<TSource>(result.issues, value)

@@ -105,4 +106,5 @@ },

if (validationSource === 'field')
if (validationSource === 'field') {
return result.issues as TStandardSchemaValidatorIssue<TSource>
}
return transformFormIssues<TSource>(result.issues, value)

@@ -109,0 +111,0 @@ },

@@ -123,2 +123,3 @@ import { batch } from '@tanstack/store'

fieldMetaBase: null,
formGroupStateBase: null,
isSubmitting: null,

@@ -125,0 +126,0 @@ isSubmitted: null,

@@ -1,4 +0,34 @@

import type { AnyFieldMeta, AnyFieldMetaBase } from './FieldApi'
import type { DeepKeys, DeepKeysOfType, DeepValue } from './util-types'
import type {
FieldAsyncValidateOrFn,
FieldValidateAsyncFn,
FieldValidateFn,
FieldValidateOrFn,
} from './FieldApi'
import type {
DeepKeys,
DeepKeysOfType,
DeepValue,
UnwrapOneLevelOfArray,
} from './util-types'
import type { Updater } from './utils'
import type {
AnyFormApi,
FormApi,
FormAsyncValidateOrFn,
FormValidateAsyncFn,
FormValidateFn,
FormValidateOrFn,
ValidationMeta,
} from './FormApi'
import type { ReadonlyStore } from '@tanstack/store'
import type {
FormGroupAsyncValidateOrFn,
FormGroupValidateAsyncFn,
FormGroupValidateFn,
FormGroupValidateOrFn,
} from './FormGroupApi'
import type {
StandardSchemaV1,
StandardSchemaV1Issue,
} from './standardSchemaValidator'

@@ -149,5 +179,4 @@ export type ValidationError = unknown

* @private
* A list of field manipulation methods that a form-like API must implement.
*/
export interface FieldManipulator<TFormData, TSubmitMeta> {
export interface FormLikeAPI<TFormData, TSubmitMeta> {
/**

@@ -195,3 +224,3 @@ * Validates all fields using the correct handlers for a given validation cause.

field: TField,
) => AnyFieldMeta | undefined
) => AnyFieldLikeMeta | undefined

@@ -203,3 +232,3 @@ /**

field: TField,
updater: Updater<AnyFieldMetaBase>,
updater: Updater<AnyFieldLikeMetaBase>,
) => void

@@ -298,1 +327,948 @@

}
type UnwrapFormAsyncValidateOrFnForInner<
TValidateOrFn extends undefined | FormAsyncValidateOrFn<any>,
> = [TValidateOrFn] extends [FormValidateAsyncFn<any>]
? Awaited<ReturnType<TValidateOrFn>>
: [TValidateOrFn] extends [StandardSchemaV1<infer TOut, any>]
? StandardBrandedSchemaV1<TOut>
: undefined
export type UnwrapFieldAsyncValidateOrFn<
TName extends string,
TValidateOrFn extends
| undefined
| FieldAsyncValidateOrFn<any, any, any>
| FormGroupAsyncValidateOrFn<any, any>,
TFormValidateOrFn extends undefined | FormAsyncValidateOrFn<any>,
> =
| ([TFormValidateOrFn] extends [StandardSchemaV1<any, infer TStandardOut>]
? TName extends keyof TStandardOut
? StandardSchemaV1Issue[]
: undefined
: undefined)
| (UnwrapFormAsyncValidateOrFnForInner<TFormValidateOrFn> extends infer TFormValidateVal
? TFormValidateVal extends { __standardSchemaV1: true }
? [DeepValue<TFormValidateVal, TName>] extends [never]
? undefined
: StandardSchemaV1Issue[]
: TFormValidateVal extends { fields: any }
? TName extends keyof TFormValidateVal['fields']
? TFormValidateVal['fields'][TName]
: undefined
: undefined
: never)
| ([TValidateOrFn] extends [FieldValidateAsyncFn<any, any, any>]
? Awaited<ReturnType<TValidateOrFn>>
: [TValidateOrFn] extends [StandardSchemaV1<any, any>]
? // TODO: Check if `disableErrorFlat` is enabled, if so, return StandardSchemaV1Issue[][]
StandardSchemaV1Issue[]
: undefined)
| ([TValidateOrFn] extends [FormGroupValidateAsyncFn<any, any, any>]
? Awaited<ReturnType<TValidateOrFn>>
: [TValidateOrFn] extends [StandardSchemaV1<any, any>]
? // TODO: Check if `disableErrorFlat` is enabled, if so, return StandardSchemaV1Issue[][]
StandardSchemaV1Issue[]
: undefined)
/**
* @private
*/
// TODO: Add the `Unwrap` type to the errors
export type FieldErrorMapFromValidator<
TParentData,
TName extends DeepKeys<TParentData>,
TData extends DeepValue<TParentData, TName>,
TOnMount extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnChange extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnChangeAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TOnBlur extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnBlurAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TOnSubmit extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnSubmitAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
> = Partial<
Record<
DeepKeys<TParentData>,
ValidationErrorMap<
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync
>
>
>
type StandardBrandedSchemaV1<T> = T & { __standardSchemaV1: true }
type UnwrapFormValidateOrFnForInner<
TValidateOrFn extends undefined | FormValidateOrFn<any>,
> = [TValidateOrFn] extends [FormValidateFn<any>]
? ReturnType<TValidateOrFn>
: [TValidateOrFn] extends [StandardSchemaV1<infer TOut, any>]
? StandardBrandedSchemaV1<TOut>
: undefined
export type UnwrapFieldValidateOrFn<
TName extends string,
TValidateOrFn extends
| undefined
| FieldValidateOrFn<any, any, any>
| FormGroupValidateOrFn<any, any, any>,
TFormValidateOrFn extends undefined | FormValidateOrFn<any>,
> =
| ([TFormValidateOrFn] extends [StandardSchemaV1<any, infer TStandardOut>]
? TName extends keyof TStandardOut
? StandardSchemaV1Issue[]
: undefined
: undefined)
| (UnwrapFormValidateOrFnForInner<TFormValidateOrFn> extends infer TFormValidateVal
? TFormValidateVal extends { __standardSchemaV1: true }
? [DeepValue<TFormValidateVal, TName>] extends [never]
? undefined
: StandardSchemaV1Issue[]
: TFormValidateVal extends { fields: any }
? TName extends keyof TFormValidateVal['fields']
? TFormValidateVal['fields'][TName]
: undefined
: undefined
: never)
| ([TValidateOrFn] extends [FieldValidateFn<any, any, any>]
? ReturnType<TValidateOrFn>
: [TValidateOrFn] extends [StandardSchemaV1<any, any>]
? // TODO: Check if `disableErrorFlat` is enabled, if so, return StandardSchemaV1Issue[][]
StandardSchemaV1Issue[]
: undefined)
| ([TValidateOrFn] extends [FormGroupValidateFn<any, any, any>]
? ReturnType<TValidateOrFn>
: [TValidateOrFn] extends [StandardSchemaV1<any, any>]
? // TODO: Check if `disableErrorFlat` is enabled, if so, return StandardSchemaV1Issue[][]
StandardSchemaV1Issue[]
: undefined)
/**
* @private
*/
export type FieldLikeMetaBase<
TParentData,
TName extends DeepKeys<TParentData>,
TData extends DeepValue<TParentData, TName>,
TOnMount extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnChange extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnChangeAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TOnBlur extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnBlurAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TOnSubmit extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnSubmitAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TOnDynamic extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnDynamicAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TFormOnMount extends undefined | FormValidateOrFn<TParentData>,
TFormOnChange extends undefined | FormValidateOrFn<TParentData>,
TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnBlur extends undefined | FormValidateOrFn<TParentData>,
TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>,
TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>,
TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
> = {
/**
* A flag indicating whether the field has been touched.
*/
isTouched: boolean
/**
* A flag indicating whether the field has been blurred.
*/
isBlurred: boolean
/**
* A flag that is `true` if the field's value has been modified by the user. Opposite of `isPristine`.
*/
isDirty: boolean
/**
* A map of errors related to the field value.
*/
errorMap: ValidationErrorMap<
UnwrapFieldValidateOrFn<TName, TOnMount, TFormOnMount>,
UnwrapFieldValidateOrFn<TName, TOnChange, TFormOnChange>,
UnwrapFieldAsyncValidateOrFn<TName, TOnChangeAsync, TFormOnChangeAsync>,
UnwrapFieldValidateOrFn<TName, TOnBlur, TFormOnBlur>,
UnwrapFieldAsyncValidateOrFn<TName, TOnBlurAsync, TFormOnBlurAsync>,
UnwrapFieldValidateOrFn<TName, TOnSubmit, TFormOnSubmit>,
UnwrapFieldAsyncValidateOrFn<TName, TOnSubmitAsync, TFormOnSubmitAsync>,
UnwrapFieldValidateOrFn<TName, TOnDynamic, TFormOnDynamic>,
UnwrapFieldAsyncValidateOrFn<TName, TOnDynamicAsync, TFormOnDynamicAsync>
>
/**
* @private allows tracking the source of the errors in the error map
*/
errorSourceMap: ValidationErrorMapSource
/**
* A flag indicating whether the field is currently being validated.
*/
isValidating: boolean
/**
* @private a counter that is incremented every time a structural array
* operation (push, insert, remove, swap, move, replace, clear) modifies
* the value of an array field. Adapters can subscribe to this to trigger
* re-renders for `mode="array"` fields without having to subscribe to the
* full field value.
*/
_arrayVersion: number
}
/**
* @private
*/
export type AnyFieldLikeMetaBase = FieldLikeMetaBase<
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any
>
/**
* @private
*/
export type FieldLikeMetaDerived<
TParentData,
TName extends DeepKeys<TParentData>,
TData extends DeepValue<TParentData, TName>,
TOnMount extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnChange extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnChangeAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TOnBlur extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnBlurAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TOnSubmit extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnSubmitAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TOnDynamic extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnDynamicAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TFormOnMount extends undefined | FormValidateOrFn<TParentData>,
TFormOnChange extends undefined | FormValidateOrFn<TParentData>,
TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnBlur extends undefined | FormValidateOrFn<TParentData>,
TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>,
TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>,
TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
> = {
/**
* An array of errors related to the field value.
*/
errors: Array<
| UnwrapOneLevelOfArray<
UnwrapFieldValidateOrFn<TName, TOnMount, TFormOnMount>
>
| UnwrapOneLevelOfArray<
UnwrapFieldValidateOrFn<TName, TOnChange, TFormOnChange>
>
| UnwrapOneLevelOfArray<
UnwrapFieldAsyncValidateOrFn<TName, TOnChangeAsync, TFormOnChangeAsync>
>
| UnwrapOneLevelOfArray<
UnwrapFieldValidateOrFn<TName, TOnBlur, TFormOnBlur>
>
| UnwrapOneLevelOfArray<
UnwrapFieldAsyncValidateOrFn<TName, TOnBlurAsync, TFormOnBlurAsync>
>
| UnwrapOneLevelOfArray<
UnwrapFieldValidateOrFn<TName, TOnSubmit, TFormOnSubmit>
>
| UnwrapOneLevelOfArray<
UnwrapFieldAsyncValidateOrFn<TName, TOnSubmitAsync, TFormOnSubmitAsync>
>
| UnwrapOneLevelOfArray<
UnwrapFieldValidateOrFn<TName, TOnDynamic, TFormOnDynamic>
>
| UnwrapOneLevelOfArray<
UnwrapFieldAsyncValidateOrFn<
TName,
TOnDynamicAsync,
TFormOnDynamicAsync
>
>
>
/**
* A flag that is `true` if the field's value has not been modified by the user. Opposite of `isDirty`.
*/
isPristine: boolean
/**
* A boolean indicating if the field is valid. Evaluates `true` if there are no field errors.
*/
isValid: boolean
/**
* A flag indicating whether the field's current value is the default value
*/
isDefaultValue: boolean
}
/**
* @private
* An object type representing the metadata of a field in a form.
*/
export type FieldLikeMeta<
TParentData,
TName extends DeepKeys<TParentData>,
TData extends DeepValue<TParentData, TName>,
TOnMount extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnChange extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnChangeAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TOnBlur extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnBlurAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TOnSubmit extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnSubmitAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TOnDynamic extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnDynamicAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TFormOnMount extends undefined | FormValidateOrFn<TParentData>,
TFormOnChange extends undefined | FormValidateOrFn<TParentData>,
TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnBlur extends undefined | FormValidateOrFn<TParentData>,
TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>,
TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>,
TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
> = FieldLikeMetaBase<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync,
TFormOnMount,
TFormOnChange,
TFormOnChangeAsync,
TFormOnBlur,
TFormOnBlurAsync,
TFormOnSubmit,
TFormOnSubmitAsync,
TFormOnDynamic,
TFormOnDynamicAsync
> &
FieldLikeMetaDerived<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync,
TFormOnMount,
TFormOnChange,
TFormOnChangeAsync,
TFormOnBlur,
TFormOnBlurAsync,
TFormOnSubmit,
TFormOnSubmitAsync,
TFormOnDynamic,
TFormOnDynamicAsync
>
/**
* @private
*/
export type AnyFieldLikeMeta = FieldLikeMeta<
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any
>
export type AnyFieldMeta = AnyFieldLikeMeta
/**
* @private
* An object type representing the state of a field.
*/
export type FieldLikeState<
TParentData,
TName extends DeepKeys<TParentData>,
TData extends DeepValue<TParentData, TName>,
TOnMount extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnChange extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnChangeAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TOnBlur extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnBlurAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TOnSubmit extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnSubmitAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TOnDynamic extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
TOnDynamicAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
TFormOnMount extends undefined | FormValidateOrFn<TParentData>,
TFormOnChange extends undefined | FormValidateOrFn<TParentData>,
TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnBlur extends undefined | FormValidateOrFn<TParentData>,
TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>,
TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>,
TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
> = {
/**
* The current value of the field.
*/
value: TData
/**
* The current metadata of the field.
*/
meta: FieldLikeMeta<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync,
TFormOnMount,
TFormOnChange,
TFormOnChangeAsync,
TFormOnBlur,
TFormOnBlurAsync,
TFormOnSubmit,
TFormOnSubmitAsync,
TFormOnDynamic,
TFormOnDynamicAsync
>
}
/**
* @private
* An object type representing the options for a field in a form.
*/
export interface FieldLikeOptions<
TParentData,
TName extends DeepKeys<TParentData>,
TData extends DeepValue<TParentData, TName>,
in out TOnMount extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
in out TOnChange extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
in out TOnChangeAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
in out TOnBlur extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
in out TOnBlurAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
in out TOnSubmit extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
in out TOnSubmitAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
in out TOnDynamic extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
in out TOnDynamicAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
> {
/**
* The field name. The type will be `DeepKeys<TParentData>` to ensure your name is a deep key of the parent dataset.
*/
name: TName
/**
* An optional default value for the field.
*/
defaultValue?: NoInfer<TData>
/**
* The default time to debounce async validation if there is not a more specific debounce time passed.
*/
asyncDebounceMs?: number
/**
* If `true`, always run async validation, even if there are errors emitted during synchronous validation.
*/
asyncAlways?: boolean
/**
* An optional object with default metadata for the field.
*/
defaultMeta?: Partial<
FieldLikeMeta<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync,
any,
any,
any,
any,
any,
any,
any,
any,
any
>
>
/**
* Disable the `flat(1)` operation on `field.errors`. This is useful if you want to keep the error structure as is. Not suggested for most use-cases.
*/
disableErrorFlat?: boolean
}
/**
* @private
* An object type representing the required options for the FieldApi class.
*/
export interface FieldLikeApiOptions<
in out TParentData,
in out TName extends DeepKeys<TParentData>,
in out TData extends DeepValue<TParentData, TName>,
in out TOnMount extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
in out TOnChange extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
in out TOnChangeAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
in out TOnBlur extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
in out TOnBlurAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
in out TOnSubmit extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
in out TOnSubmitAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
in out TOnDynamic extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
in out TOnDynamicAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>,
in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>,
in out TFormOnChangeAsync extends
| undefined
| FormAsyncValidateOrFn<TParentData>,
in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>,
in out TFormOnBlurAsync extends
| undefined
| FormAsyncValidateOrFn<TParentData>,
in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>,
in out TFormOnSubmitAsync extends
| undefined
| FormAsyncValidateOrFn<TParentData>,
in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>,
in out TFormOnDynamicAsync extends
| undefined
| FormAsyncValidateOrFn<TParentData>,
in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>,
in out TParentSubmitMeta,
> extends FieldLikeOptions<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync
> {
form: FormApi<
TParentData,
TFormOnMount,
TFormOnChange,
TFormOnChangeAsync,
TFormOnBlur,
TFormOnBlurAsync,
TFormOnSubmit,
TFormOnSubmitAsync,
TFormOnDynamic,
TFormOnDynamicAsync,
TFormOnServer,
TParentSubmitMeta
>
}
/**
* @private
*/
export interface FieldLikeAPI<
in out TParentData,
in out TName extends DeepKeys<TParentData>,
in out TData extends DeepValue<TParentData, TName>,
in out TOnMount extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
in out TOnChange extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
in out TOnChangeAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
in out TOnBlur extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
in out TOnBlurAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
in out TOnSubmit extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
in out TOnSubmitAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
in out TOnDynamic extends
| undefined
| FieldValidateOrFn<TParentData, TName, TData>
| FormGroupValidateOrFn<TParentData, TName, TData>,
in out TOnDynamicAsync extends
| undefined
| FieldAsyncValidateOrFn<TParentData, TName, TData>
| FormGroupAsyncValidateOrFn<TParentData, TName, TData>,
in out TFormOnMount extends undefined | FormValidateOrFn<TParentData>,
in out TFormOnChange extends undefined | FormValidateOrFn<TParentData>,
in out TFormOnChangeAsync extends
| undefined
| FormAsyncValidateOrFn<TParentData>,
in out TFormOnBlur extends undefined | FormValidateOrFn<TParentData>,
in out TFormOnBlurAsync extends
| undefined
| FormAsyncValidateOrFn<TParentData>,
in out TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>,
in out TFormOnSubmitAsync extends
| undefined
| FormAsyncValidateOrFn<TParentData>,
in out TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>,
in out TFormOnDynamicAsync extends
| undefined
| FormAsyncValidateOrFn<TParentData>,
in out TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>,
in out TParentSubmitMeta,
TExtraOptions = {},
> {
form: AnyFormApi
options: FieldLikeApiOptions<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync,
TFormOnMount,
TFormOnChange,
TFormOnChangeAsync,
TFormOnBlur,
TFormOnBlurAsync,
TFormOnSubmit,
TFormOnSubmitAsync,
TFormOnDynamic,
TFormOnDynamicAsync,
TFormOnServer,
TParentSubmitMeta
> &
TExtraOptions
store: ReadonlyStore<
FieldLikeState<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync,
TFormOnMount,
TFormOnChange,
TFormOnChangeAsync,
TFormOnBlur,
TFormOnBlurAsync,
TFormOnSubmit,
TFormOnSubmitAsync,
TFormOnDynamic,
TFormOnDynamicAsync
>
>
/**
* The field name.
*/
name: TName
mount: () => () => void
setValue: (updater: Updater<TData>, options?: UpdateMetaOptions) => void
getMeta: () => AnyFieldLikeMeta
setMeta: (updater: Updater<AnyFieldLikeMetaBase>) => void
getInfo: () => FieldInfo<TParentData>
validate: (
cause: ValidationCause,
opts?: { skipFormValidation?: boolean; skipGroupValidation?: boolean },
) => ValidationError[] | Promise<ValidationError[]>
/**
* @private
*/
triggerOnChangeListener: () => void
/**
* @private
*/
triggerOnSubmitListener: () => void
}
/**
* @private
*/
export interface FieldInfo<TParentData> {
instance: FieldLikeAPI<
TParentData,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any
> | null
validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>
}
import { liteThrottle } from '@tanstack/pacer-lite'
import { formEventClient } from './EventClient'
import { AnyFormGroupApi } from './FormGroupApi'
import type { ValidationLogicProps } from './ValidationLogic'

@@ -306,2 +307,3 @@ import type { FieldValidators } from './FieldApi'

form?: any
group?: any
fieldName?: string

@@ -356,2 +358,3 @@ },

form: options.form,
group: options.group,
validators: options.validators,

@@ -371,2 +374,3 @@ event: { type: cause, fieldName: options.fieldName, async: false },

form?: any
group?: any
fieldName?: string

@@ -469,2 +473,3 @@ },

form: options.form,
group: options.group,
validators: options.validators,

@@ -734,1 +739,12 @@ event: { type: cause, fieldName: options.fieldName, async: true },

}
/**
* @private
*/
export function isFieldInGroup(groupName: string, fieldName: string) {
return (
fieldName === groupName ||
fieldName.startsWith(`${groupName}.`) ||
fieldName.startsWith(`${groupName}[`)
)
}
import type { AnyFormApi, FormValidators } from './FormApi'
import type { AnyFormGroupApi } from './FormGroupApi'

@@ -23,2 +24,8 @@ export interface ValidationLogicValidatorsFn {

form: AnyFormApi
/**
* Set when the validators being processed belong to a `FormGroupApi`.
* Allows validation strategies (e.g. `revalidateLogic`) to gate their
* behavior on the group's own state instead of the parent form's.
*/
group?: AnyFormGroupApi
// TODO: Type this properly

@@ -92,5 +99,12 @@ validators:

const modeToWatch =
props.form.state.submissionAttempts === 0 ? mode : modeAfterSubmission
// When validating a `FormGroupApi`'s own validators, gate on the group's
// submission attempts so a group's `onDynamic` validator only flips into
// `modeAfterSubmission` after that group itself has been submitted.
// Otherwise (form-level validators), gate on the parent form.
const submissionAttempts = props.group
? props.group.state.meta.submissionAttempts
: props.form.state.submissionAttempts
const modeToWatch = submissionAttempts === 0 ? mode : modeAfterSubmission
if ([modeToWatch, 'submit'].includes(props.event.type)) {

@@ -97,0 +111,0 @@ validatorsToAdd.push(dynamicValidator)

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display