@tanstack/form-core
Advanced tools
Comparing version 0.10.0 to 0.10.1
// src/FormApi.ts | ||
import { Store } from "@tanstack/store"; | ||
import { functionalUpdate, getBy, isNonEmptyArray, setBy } from "./utils.js"; | ||
import { | ||
deleteBy, | ||
functionalUpdate, | ||
getBy, | ||
isNonEmptyArray, | ||
setBy | ||
} from "./utils.js"; | ||
function getDefaultFormState(defaultState) { | ||
@@ -305,3 +311,3 @@ return { | ||
const newState = { ...prev }; | ||
delete newState.values[field]; | ||
newState.values = deleteBy(newState.values, field); | ||
delete newState.fieldMeta[field]; | ||
@@ -308,0 +314,0 @@ return newState; |
import { Store } from '@tanstack/store'; | ||
import { DeepKeys, DeepValue, Updater } from './utils.js'; | ||
export { Narrow, Pretty, RequiredByKey, UpdaterFn, functionalUpdate, getBy, isNonEmptyArray, setBy } from './utils.js'; | ||
export { Narrow, Pretty, RequiredByKey, UpdaterFn, deleteBy, functionalUpdate, getBy, isNonEmptyArray, setBy } from './utils.js'; | ||
import { ValidationError, Validator } from './types.js'; | ||
@@ -5,0 +5,0 @@ |
@@ -12,2 +12,6 @@ type UpdaterFn<TInput, TOutput = TInput> = (input: TInput) => TOutput; | ||
declare function setBy(obj: any, _path: any, updater: Updater<any>): any; | ||
/** | ||
* Delete a field on an object using a path, including dot notation. | ||
*/ | ||
declare function deleteBy(obj: any, _path: any): any; | ||
declare function isNonEmptyArray(obj: any): boolean; | ||
@@ -34,2 +38,2 @@ type RequiredByKey<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>; | ||
export { DeepKeys, DeepValue, Narrow, Pretty, RequiredByKey, Updater, UpdaterFn, functionalUpdate, getBy, isNonEmptyArray, setBy }; | ||
export { DeepKeys, DeepValue, Narrow, Pretty, RequiredByKey, Updater, UpdaterFn, deleteBy, functionalUpdate, getBy, isNonEmptyArray, setBy }; |
@@ -6,4 +6,3 @@ // src/utils.ts | ||
function getBy(obj, path) { | ||
const pathArray = makePathArray(path); | ||
const pathObj = pathArray; | ||
const pathObj = makePathArray(path); | ||
return pathObj.reduce((current, pathPart) => { | ||
@@ -34,2 +33,31 @@ if (typeof current !== "undefined") { | ||
} | ||
if (Array.isArray(parent) && key !== void 0) { | ||
const prefix = parent.slice(0, key); | ||
return [ | ||
...prefix.length ? prefix : new Array(key), | ||
doSet(parent[key]), | ||
...parent.slice(key + 1) | ||
]; | ||
} | ||
return [...new Array(key), doSet()]; | ||
} | ||
return doSet(obj); | ||
} | ||
function deleteBy(obj, _path) { | ||
const path = makePathArray(_path); | ||
function doDelete(parent) { | ||
if (path.length === 1) { | ||
const finalPath = path[0]; | ||
const { [finalPath]: remove, ...rest } = parent; | ||
return rest; | ||
} | ||
const key = path.shift(); | ||
if (typeof key === "string") { | ||
if (typeof parent === "object") { | ||
return { | ||
...parent, | ||
[key]: doDelete(parent[key]) | ||
}; | ||
} | ||
} | ||
if (typeof key === "number") { | ||
@@ -40,11 +68,10 @@ if (Array.isArray(parent)) { | ||
...prefix.length ? prefix : new Array(key), | ||
doSet(parent[key]), | ||
doDelete(parent[key]), | ||
...parent.slice(key + 1) | ||
]; | ||
} | ||
return [...new Array(key), doSet()]; | ||
} | ||
throw new Error("Uh oh!"); | ||
throw new Error("It seems we have created an infinite loop in deleteBy. "); | ||
} | ||
return doSet(obj); | ||
return doDelete(obj); | ||
} | ||
@@ -73,2 +100,3 @@ var reFindNumbers0 = /^(\d*)$/gm; | ||
export { | ||
deleteBy, | ||
functionalUpdate, | ||
@@ -75,0 +103,0 @@ getBy, |
// src/FormApi.ts | ||
import { Store } from "@tanstack/store"; | ||
import { functionalUpdate, getBy, isNonEmptyArray, setBy } from "./utils.js"; | ||
import { | ||
deleteBy, | ||
functionalUpdate, | ||
getBy, | ||
isNonEmptyArray, | ||
setBy | ||
} from "./utils.js"; | ||
function getDefaultFormState(defaultState) { | ||
@@ -299,3 +305,3 @@ return { | ||
const newState = { ...prev }; | ||
delete newState.values[field]; | ||
newState.values = deleteBy(newState.values, field); | ||
delete newState.fieldMeta[field]; | ||
@@ -302,0 +308,0 @@ return newState; |
import { Store } from '@tanstack/store'; | ||
import { DeepKeys, DeepValue, Updater } from './utils.js'; | ||
export { Narrow, Pretty, RequiredByKey, UpdaterFn, functionalUpdate, getBy, isNonEmptyArray, setBy } from './utils.js'; | ||
export { Narrow, Pretty, RequiredByKey, UpdaterFn, deleteBy, functionalUpdate, getBy, isNonEmptyArray, setBy } from './utils.js'; | ||
import { ValidationError, Validator } from './types.js'; | ||
@@ -5,0 +5,0 @@ |
@@ -12,2 +12,6 @@ type UpdaterFn<TInput, TOutput = TInput> = (input: TInput) => TOutput; | ||
declare function setBy(obj: any, _path: any, updater: Updater<any>): any; | ||
/** | ||
* Delete a field on an object using a path, including dot notation. | ||
*/ | ||
declare function deleteBy(obj: any, _path: any): any; | ||
declare function isNonEmptyArray(obj: any): boolean; | ||
@@ -34,2 +38,2 @@ type RequiredByKey<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>; | ||
export { DeepKeys, DeepValue, Narrow, Pretty, RequiredByKey, Updater, UpdaterFn, functionalUpdate, getBy, isNonEmptyArray, setBy }; | ||
export { DeepKeys, DeepValue, Narrow, Pretty, RequiredByKey, Updater, UpdaterFn, deleteBy, functionalUpdate, getBy, isNonEmptyArray, setBy }; |
@@ -6,4 +6,3 @@ // src/utils.ts | ||
function getBy(obj, path) { | ||
const pathArray = makePathArray(path); | ||
const pathObj = pathArray; | ||
const pathObj = makePathArray(path); | ||
return pathObj.reduce((current, pathPart) => { | ||
@@ -34,2 +33,31 @@ if (typeof current !== "undefined") { | ||
} | ||
if (Array.isArray(parent) && key !== void 0) { | ||
const prefix = parent.slice(0, key); | ||
return [ | ||
...prefix.length ? prefix : new Array(key), | ||
doSet(parent[key]), | ||
...parent.slice(key + 1) | ||
]; | ||
} | ||
return [...new Array(key), doSet()]; | ||
} | ||
return doSet(obj); | ||
} | ||
function deleteBy(obj, _path) { | ||
const path = makePathArray(_path); | ||
function doDelete(parent) { | ||
if (path.length === 1) { | ||
const finalPath = path[0]; | ||
const { [finalPath]: remove, ...rest } = parent; | ||
return rest; | ||
} | ||
const key = path.shift(); | ||
if (typeof key === "string") { | ||
if (typeof parent === "object") { | ||
return { | ||
...parent, | ||
[key]: doDelete(parent[key]) | ||
}; | ||
} | ||
} | ||
if (typeof key === "number") { | ||
@@ -40,11 +68,10 @@ if (Array.isArray(parent)) { | ||
...prefix.length ? prefix : new Array(key), | ||
doSet(parent[key]), | ||
doDelete(parent[key]), | ||
...parent.slice(key + 1) | ||
]; | ||
} | ||
return [...new Array(key), doSet()]; | ||
} | ||
throw new Error("Uh oh!"); | ||
throw new Error("It seems we have created an infinite loop in deleteBy. "); | ||
} | ||
return doSet(obj); | ||
return doDelete(obj); | ||
} | ||
@@ -73,2 +100,3 @@ var reFindNumbers0 = /^(\d*)$/gm; | ||
export { | ||
deleteBy, | ||
functionalUpdate, | ||
@@ -75,0 +103,0 @@ getBy, |
{ | ||
"name": "@tanstack/form-core", | ||
"version": "0.10.0", | ||
"version": "0.10.1", | ||
"description": "Powerful, type-safe, framework agnostic forms.", | ||
@@ -5,0 +5,0 @@ "author": "tannerlinsley", |
import { Store } from '@tanstack/store' | ||
import type { DeepKeys, DeepValue, Updater } from './utils' | ||
import { functionalUpdate, getBy, isNonEmptyArray, setBy } from './utils' | ||
import { | ||
deleteBy, | ||
functionalUpdate, | ||
getBy, | ||
isNonEmptyArray, | ||
setBy, | ||
} from './utils' | ||
import type { FieldApi, FieldMeta, ValidationCause } from './FieldApi' | ||
@@ -556,4 +562,5 @@ import type { ValidationError, Validator } from './types' | ||
const newState = { ...prev } | ||
delete newState.values[field as keyof TFormData] | ||
newState.values = deleteBy(newState.values, field) | ||
delete newState.fieldMeta[field] | ||
return newState | ||
@@ -560,0 +567,0 @@ }) |
@@ -229,2 +229,59 @@ import { expect } from 'vitest' | ||
it('should handle fields inside an array', async () => { | ||
interface Employee { | ||
firstName: string | ||
} | ||
interface Form { | ||
employees: Partial<Employee>[] | ||
} | ||
const form = new FormApi<Form, unknown>() | ||
const field = new FieldApi({ | ||
form, | ||
name: 'employees', | ||
defaultValue: [], | ||
}) | ||
field.mount() | ||
const fieldInArray = new FieldApi({ | ||
form, | ||
name: `employees.${0}.firstName`, | ||
defaultValue: 'Darcy', | ||
}) | ||
fieldInArray.mount() | ||
expect(field.state.value.length).toBe(1) | ||
expect(fieldInArray.getValue()).toBe('Darcy') | ||
}) | ||
it('should handle deleting fields in an array', async () => { | ||
interface Employee { | ||
firstName: string | ||
} | ||
interface Form { | ||
employees: Partial<Employee>[] | ||
} | ||
const form = new FormApi<Form, unknown>() | ||
const field = new FieldApi({ | ||
form, | ||
name: 'employees', | ||
defaultValue: [], | ||
}) | ||
field.mount() | ||
const fieldInArray = new FieldApi({ | ||
form, | ||
name: `employees.${0}.firstName`, | ||
defaultValue: 'Darcy', | ||
}) | ||
fieldInArray.mount() | ||
form.deleteField(`employees.${0}.firstName`) | ||
expect(field.state.value.length).toBe(1) | ||
expect(Object.keys(field.state.value[0]!).length).toBe(0) | ||
}) | ||
it('should not wipe values when updating', () => { | ||
@@ -504,3 +561,2 @@ const form = new FormApi({ | ||
field.mount() | ||
expect(form.state.errors.length).toBe(0) | ||
@@ -507,0 +563,0 @@ field.setValue('other', { touch: true }) |
@@ -20,4 +20,3 @@ export type UpdaterFn<TInput, TOutput = TInput> = (input: TInput) => TOutput | ||
export function getBy(obj: any, path: any) { | ||
const pathArray = makePathArray(path) | ||
const pathObj = pathArray | ||
const pathObj = makePathArray(path) | ||
return pathObj.reduce((current: any, pathPart: any) => { | ||
@@ -56,2 +55,40 @@ if (typeof current !== 'undefined') { | ||
if (Array.isArray(parent) && key !== undefined) { | ||
const prefix = parent.slice(0, key) | ||
return [ | ||
...(prefix.length ? prefix : new Array(key)), | ||
doSet(parent[key]), | ||
...parent.slice(key + 1), | ||
] | ||
} | ||
return [...new Array(key), doSet()] | ||
} | ||
return doSet(obj) | ||
} | ||
/** | ||
* Delete a field on an object using a path, including dot notation. | ||
*/ | ||
export function deleteBy(obj: any, _path: any) { | ||
const path = makePathArray(_path) | ||
function doDelete(parent: any): any { | ||
if (path.length === 1) { | ||
const finalPath = path[0]! | ||
const { [finalPath]: remove, ...rest } = parent | ||
return rest | ||
} | ||
const key = path.shift() | ||
if (typeof key === 'string') { | ||
if (typeof parent === 'object') { | ||
return { | ||
...parent, | ||
[key]: doDelete(parent[key]), | ||
} | ||
} | ||
} | ||
if (typeof key === 'number') { | ||
@@ -62,13 +99,12 @@ if (Array.isArray(parent)) { | ||
...(prefix.length ? prefix : new Array(key)), | ||
doSet(parent[key]), | ||
doDelete(parent[key]), | ||
...parent.slice(key + 1), | ||
] | ||
} | ||
return [...new Array(key), doSet()] | ||
} | ||
throw new Error('Uh oh!') | ||
throw new Error('It seems we have created an infinite loop in deleteBy. ') | ||
} | ||
return doSet(obj) | ||
return doDelete(obj) | ||
} | ||
@@ -75,0 +111,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
502036
72
6664