@tanstack/form-core 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/{cjs/FieldApi.js → lib/FieldApi.cjs} +80 -113
- package/build/lib/FieldApi.cjs.map +1 -0
- package/build/lib/FieldApi.d.ts +112 -0
- package/build/lib/FieldApi.d.ts.map +1 -0
- package/build/lib/FieldApi.js +305 -0
- package/build/lib/FieldApi.js.map +1 -0
- package/build/lib/FieldApi.legacy.cjs +307 -0
- package/build/lib/FieldApi.legacy.cjs.map +1 -0
- package/build/lib/FieldApi.legacy.js +305 -0
- package/build/lib/FieldApi.legacy.js.map +1 -0
- package/build/{cjs/FormApi.js → lib/FormApi.cjs} +66 -78
- package/build/lib/FormApi.cjs.map +1 -0
- package/build/{types → lib}/FormApi.d.ts +3 -2
- package/build/lib/FormApi.d.ts.map +1 -0
- package/build/lib/FormApi.js +246 -0
- package/build/lib/FormApi.js.map +1 -0
- package/build/lib/FormApi.legacy.cjs +248 -0
- package/build/lib/FormApi.legacy.cjs.map +1 -0
- package/build/lib/FormApi.legacy.js +246 -0
- package/build/lib/FormApi.legacy.js.map +1 -0
- package/build/{cjs/_virtual/_rollupPluginBabelHelpers.js → lib/_virtual/_rollupPluginBabelHelpers.cjs} +18 -45
- package/build/lib/_virtual/_rollupPluginBabelHelpers.cjs.map +1 -0
- package/build/lib/_virtual/_rollupPluginBabelHelpers.js +56 -0
- package/build/{cjs → lib}/_virtual/_rollupPluginBabelHelpers.js.map +1 -1
- package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.cjs +65 -0
- package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.cjs.map +1 -0
- package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.js +56 -0
- package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.js.map +1 -0
- package/build/lib/index.cjs +14 -0
- package/build/lib/index.cjs.map +1 -0
- package/build/{types → lib}/index.d.ts +1 -0
- package/build/lib/index.d.ts.map +1 -0
- package/build/lib/index.js +4 -0
- package/build/{cjs → lib}/index.js.map +1 -1
- package/build/lib/index.legacy.cjs +14 -0
- package/build/lib/index.legacy.cjs.map +1 -0
- package/build/lib/index.legacy.js +4 -0
- package/build/lib/index.legacy.js.map +1 -0
- package/build/lib/tests/FieldApi.spec.d.ts +2 -0
- package/build/lib/tests/FieldApi.spec.d.ts.map +1 -0
- package/build/lib/tests/FieldApi.test-d.d.ts +2 -0
- package/build/lib/tests/FieldApi.test-d.d.ts.map +1 -0
- package/build/lib/tests/FormApi.spec.d.ts +2 -0
- package/build/lib/tests/FormApi.spec.d.ts.map +1 -0
- package/build/{cjs/utils.js → lib/utils.cjs} +18 -27
- package/build/lib/utils.cjs.map +1 -0
- package/build/{types → lib}/utils.d.ts +10 -0
- package/build/lib/utils.d.ts.map +1 -0
- package/build/lib/utils.js +77 -0
- package/build/lib/utils.js.map +1 -0
- package/build/lib/utils.legacy.cjs +81 -0
- package/build/lib/utils.legacy.cjs.map +1 -0
- package/build/lib/utils.legacy.js +77 -0
- package/build/lib/utils.legacy.js.map +1 -0
- package/package.json +22 -9
- package/src/FieldApi.ts +101 -46
- package/src/FormApi.ts +34 -14
- package/src/tests/FieldApi.spec.ts +169 -0
- package/src/tests/FieldApi.test-d.ts +41 -0
- package/src/tests/FormApi.spec.ts +216 -0
- package/src/utils.ts +10 -1
- package/build/cjs/FieldApi.js.map +0 -1
- package/build/cjs/FormApi.js.map +0 -1
- package/build/cjs/index.js +0 -26
- package/build/cjs/utils.js.map +0 -1
- package/build/esm/index.js +0 -716
- package/build/esm/index.js.map +0 -1
- package/build/stats-html.html +0 -2689
- package/build/stats-react.json +0 -196
- package/build/types/FieldApi.d.ts +0 -85
- package/build/types/tests/test.test.d.ts +0 -0
- package/build/umd/index.development.js +0 -779
- package/build/umd/index.development.js.map +0 -1
- package/build/umd/index.production.js +0 -22
- package/build/umd/index.production.js.map +0 -1
- package/src/tests/test.test.tsx +0 -5
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function functionalUpdate(updater, input) {
|
|
4
|
+
return typeof updater === 'function' ? updater(input) : updater;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Get a value from an object using a path, including dot notation.
|
|
9
|
+
*/
|
|
10
|
+
function getBy(obj, path) {
|
|
11
|
+
const pathArray = makePathArray(path);
|
|
12
|
+
const pathObj = pathArray;
|
|
13
|
+
return pathObj.reduce((current, pathPart) => {
|
|
14
|
+
if (typeof current !== 'undefined') {
|
|
15
|
+
return current[pathPart];
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
}, obj);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Set a value on an object using a path, including dot notation.
|
|
23
|
+
*/
|
|
24
|
+
function setBy(obj, _path, updater) {
|
|
25
|
+
const path = makePathArray(_path);
|
|
26
|
+
function doSet(parent) {
|
|
27
|
+
if (!path.length) {
|
|
28
|
+
return functionalUpdate(updater, parent);
|
|
29
|
+
}
|
|
30
|
+
const key = path.shift();
|
|
31
|
+
if (typeof key === 'string') {
|
|
32
|
+
if (typeof parent === 'object') {
|
|
33
|
+
return {
|
|
34
|
+
...parent,
|
|
35
|
+
[key]: doSet(parent[key])
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
[key]: doSet()
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
if (typeof key === 'number') {
|
|
43
|
+
if (Array.isArray(parent)) {
|
|
44
|
+
const prefix = parent.slice(0, key);
|
|
45
|
+
return [...(prefix.length ? prefix : new Array(key)), doSet(parent[key]), ...parent.slice(key + 1)];
|
|
46
|
+
}
|
|
47
|
+
return [...new Array(key), doSet()];
|
|
48
|
+
}
|
|
49
|
+
throw new Error('Uh oh!');
|
|
50
|
+
}
|
|
51
|
+
return doSet(obj);
|
|
52
|
+
}
|
|
53
|
+
const reFindNumbers0 = /^(\d*)$/gm;
|
|
54
|
+
const reFindNumbers1 = /\.(\d*)\./gm;
|
|
55
|
+
const reFindNumbers2 = /^(\d*)\./gm;
|
|
56
|
+
const reFindNumbers3 = /\.(\d*$)/gm;
|
|
57
|
+
const reFindMultiplePeriods = /\.{2,}/gm;
|
|
58
|
+
const intPrefix = '__int__';
|
|
59
|
+
const intReplace = intPrefix + "$1";
|
|
60
|
+
function makePathArray(str) {
|
|
61
|
+
if (typeof str !== 'string') {
|
|
62
|
+
throw new Error('Path must be a string.');
|
|
63
|
+
}
|
|
64
|
+
return str.replace('[', '.').replace(']', '').replace(reFindNumbers0, intReplace).replace(reFindNumbers1, "." + intReplace + ".").replace(reFindNumbers2, intReplace + ".").replace(reFindNumbers3, "." + intReplace).replace(reFindMultiplePeriods, '.').split('.').map(d => {
|
|
65
|
+
if (d.indexOf(intPrefix) === 0) {
|
|
66
|
+
return parseInt(d.substring(intPrefix.length), 10);
|
|
67
|
+
}
|
|
68
|
+
return d;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Is this type a tuple?
|
|
73
|
+
|
|
74
|
+
// If this type is a tuple, what indices are allowed?
|
|
75
|
+
|
|
76
|
+
// Hack to get TypeScript to show simplified types in error messages
|
|
77
|
+
|
|
78
|
+
exports.functionalUpdate = functionalUpdate;
|
|
79
|
+
exports.getBy = getBy;
|
|
80
|
+
exports.setBy = setBy;
|
|
81
|
+
//# sourceMappingURL=utils.legacy.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.legacy.cjs","sources":["../../src/utils.ts"],"sourcesContent":["export type UpdaterFn<TInput, TOutput = TInput> = (input: TInput) => TOutput\n\nexport type Updater<TInput, TOutput = TInput> =\n | TOutput\n | UpdaterFn<TInput, TOutput>\n\nexport function functionalUpdate<TInput, TOutput = TInput>(\n updater: Updater<TInput, TOutput>,\n input: TInput,\n): TOutput {\n return typeof updater === 'function'\n ? (updater as UpdaterFn<TInput, TOutput>)(input)\n : updater\n}\n\n/**\n * Get a value from an object using a path, including dot notation.\n */\nexport function getBy(obj: any, path: any) {\n const pathArray = makePathArray(path)\n const pathObj = pathArray\n return pathObj.reduce((current: any, pathPart: any) => {\n if (typeof current !== 'undefined') {\n return current[pathPart]\n }\n return undefined\n }, obj)\n}\n\n/**\n * Set a value on an object using a path, including dot notation.\n */\nexport function setBy(obj: any, _path: any, updater: Updater<any>) {\n const path = makePathArray(_path)\n\n function doSet(parent?: any): any {\n if (!path.length) {\n return functionalUpdate(updater, parent)\n }\n\n const key = path.shift()\n\n if (typeof key === 'string') {\n if (typeof parent === 'object') {\n return {\n ...parent,\n [key]: doSet(parent[key]),\n }\n }\n return {\n [key]: doSet(),\n }\n }\n\n if (typeof key === 'number') {\n if (Array.isArray(parent)) {\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 throw new Error('Uh oh!')\n }\n\n return doSet(obj)\n}\n\nconst reFindNumbers0 = /^(\\d*)$/gm\nconst reFindNumbers1 = /\\.(\\d*)\\./gm\nconst reFindNumbers2 = /^(\\d*)\\./gm\nconst reFindNumbers3 = /\\.(\\d*$)/gm\nconst reFindMultiplePeriods = /\\.{2,}/gm\n\nconst intPrefix = '__int__'\nconst intReplace = `${intPrefix}$1`\n\nfunction makePathArray(str: string) {\n if (typeof str !== 'string') {\n throw new Error('Path must be a string.')\n }\n\n return str\n .replace('[', '.')\n .replace(']', '')\n .replace(reFindNumbers0, intReplace)\n .replace(reFindNumbers1, `.${intReplace}.`)\n .replace(reFindNumbers2, `${intReplace}.`)\n .replace(reFindNumbers3, `.${intReplace}`)\n .replace(reFindMultiplePeriods, '.')\n .split('.')\n .map((d) => {\n if (d.indexOf(intPrefix) === 0) {\n return parseInt(d.substring(intPrefix.length), 10)\n }\n return d\n })\n}\n\nexport type RequiredByKey<T, K extends keyof T> = Omit<T, K> &\n Required<Pick<T, K>>\n\ntype ComputeRange<\n N extends number,\n Result extends Array<unknown> = [],\n> = Result['length'] extends N\n ? Result\n : ComputeRange<N, [...Result, Result['length']]>\ntype Index40 = ComputeRange<40>[number]\n\n// Is this type a tuple?\ntype IsTuple<T> = T extends readonly any[] & { length: infer Length }\n ? Length extends Index40\n ? T\n : never\n : never\n\n// If this type is a tuple, what indices are allowed?\ntype AllowedIndexes<\n Tuple extends ReadonlyArray<any>,\n Keys extends number = never,\n> = Tuple extends readonly []\n ? Keys\n : Tuple extends readonly [infer _, ...infer Tail]\n ? AllowedIndexes<Tail, Keys | Tail['length']>\n : Keys\n\nexport type DeepKeys<T> = unknown extends T\n ? keyof T\n : object extends T\n ? string\n : T extends readonly any[] & IsTuple<T>\n ? AllowedIndexes<T> | DeepKeysPrefix<T, AllowedIndexes<T>>\n : T extends any[]\n ? DeepKeys<T[number]>\n : T extends Date\n ? never\n : T extends object\n ? (keyof T & string) | DeepKeysPrefix<T, keyof T>\n : never\n\ntype DeepKeysPrefix<T, TPrefix> = TPrefix extends keyof T & (number | string)\n ? `${TPrefix}.${DeepKeys<T[TPrefix]> & string}`\n : never\n\nexport type DeepValue<T, TProp> = T extends Record<string | number, any>\n ? TProp extends `${infer TBranch}.${infer TDeepProp}`\n ? DeepValue<T[TBranch], TDeepProp>\n : T[TProp & string]\n : never\n\ntype Narrowable = string | number | bigint | boolean\n\ntype NarrowRaw<A> =\n | (A extends [] ? [] : never)\n | (A extends Narrowable ? A : never)\n | {\n [K in keyof A]: A[K] extends Function ? A[K] : NarrowRaw<A[K]>\n }\n\nexport type Narrow<A> = Try<A, [], NarrowRaw<A>>\n\ntype Try<A1, A2, Catch = never> = A1 extends A2 ? A1 : Catch\n\n// Hack to get TypeScript to show simplified types in error messages\nexport type Pretty<T> = { [K in keyof T]: T[K] } & {}\n"],"names":["functionalUpdate","updater","input","getBy","obj","path","pathArray","makePathArray","pathObj","reduce","current","pathPart","undefined","setBy","_path","doSet","parent","length","key","shift","Array","isArray","prefix","slice","Error","reFindNumbers0","reFindNumbers1","reFindNumbers2","reFindNumbers3","reFindMultiplePeriods","intPrefix","intReplace","str","replace","split","map","d","indexOf","parseInt","substring"],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
function functionalUpdate(updater, input) {
|
|
2
|
+
return typeof updater === 'function' ? updater(input) : updater;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Get a value from an object using a path, including dot notation.
|
|
7
|
+
*/
|
|
8
|
+
function getBy(obj, path) {
|
|
9
|
+
const pathArray = makePathArray(path);
|
|
10
|
+
const pathObj = pathArray;
|
|
11
|
+
return pathObj.reduce((current, pathPart) => {
|
|
12
|
+
if (typeof current !== 'undefined') {
|
|
13
|
+
return current[pathPart];
|
|
14
|
+
}
|
|
15
|
+
return undefined;
|
|
16
|
+
}, obj);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Set a value on an object using a path, including dot notation.
|
|
21
|
+
*/
|
|
22
|
+
function setBy(obj, _path, updater) {
|
|
23
|
+
const path = makePathArray(_path);
|
|
24
|
+
function doSet(parent) {
|
|
25
|
+
if (!path.length) {
|
|
26
|
+
return functionalUpdate(updater, parent);
|
|
27
|
+
}
|
|
28
|
+
const key = path.shift();
|
|
29
|
+
if (typeof key === 'string') {
|
|
30
|
+
if (typeof parent === 'object') {
|
|
31
|
+
return {
|
|
32
|
+
...parent,
|
|
33
|
+
[key]: doSet(parent[key])
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
[key]: doSet()
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
if (typeof key === 'number') {
|
|
41
|
+
if (Array.isArray(parent)) {
|
|
42
|
+
const prefix = parent.slice(0, key);
|
|
43
|
+
return [...(prefix.length ? prefix : new Array(key)), doSet(parent[key]), ...parent.slice(key + 1)];
|
|
44
|
+
}
|
|
45
|
+
return [...new Array(key), doSet()];
|
|
46
|
+
}
|
|
47
|
+
throw new Error('Uh oh!');
|
|
48
|
+
}
|
|
49
|
+
return doSet(obj);
|
|
50
|
+
}
|
|
51
|
+
const reFindNumbers0 = /^(\d*)$/gm;
|
|
52
|
+
const reFindNumbers1 = /\.(\d*)\./gm;
|
|
53
|
+
const reFindNumbers2 = /^(\d*)\./gm;
|
|
54
|
+
const reFindNumbers3 = /\.(\d*$)/gm;
|
|
55
|
+
const reFindMultiplePeriods = /\.{2,}/gm;
|
|
56
|
+
const intPrefix = '__int__';
|
|
57
|
+
const intReplace = intPrefix + "$1";
|
|
58
|
+
function makePathArray(str) {
|
|
59
|
+
if (typeof str !== 'string') {
|
|
60
|
+
throw new Error('Path must be a string.');
|
|
61
|
+
}
|
|
62
|
+
return str.replace('[', '.').replace(']', '').replace(reFindNumbers0, intReplace).replace(reFindNumbers1, "." + intReplace + ".").replace(reFindNumbers2, intReplace + ".").replace(reFindNumbers3, "." + intReplace).replace(reFindMultiplePeriods, '.').split('.').map(d => {
|
|
63
|
+
if (d.indexOf(intPrefix) === 0) {
|
|
64
|
+
return parseInt(d.substring(intPrefix.length), 10);
|
|
65
|
+
}
|
|
66
|
+
return d;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Is this type a tuple?
|
|
71
|
+
|
|
72
|
+
// If this type is a tuple, what indices are allowed?
|
|
73
|
+
|
|
74
|
+
// Hack to get TypeScript to show simplified types in error messages
|
|
75
|
+
|
|
76
|
+
export { functionalUpdate, getBy, setBy };
|
|
77
|
+
//# sourceMappingURL=utils.legacy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.legacy.js","sources":["../../src/utils.ts"],"sourcesContent":["export type UpdaterFn<TInput, TOutput = TInput> = (input: TInput) => TOutput\n\nexport type Updater<TInput, TOutput = TInput> =\n | TOutput\n | UpdaterFn<TInput, TOutput>\n\nexport function functionalUpdate<TInput, TOutput = TInput>(\n updater: Updater<TInput, TOutput>,\n input: TInput,\n): TOutput {\n return typeof updater === 'function'\n ? (updater as UpdaterFn<TInput, TOutput>)(input)\n : updater\n}\n\n/**\n * Get a value from an object using a path, including dot notation.\n */\nexport function getBy(obj: any, path: any) {\n const pathArray = makePathArray(path)\n const pathObj = pathArray\n return pathObj.reduce((current: any, pathPart: any) => {\n if (typeof current !== 'undefined') {\n return current[pathPart]\n }\n return undefined\n }, obj)\n}\n\n/**\n * Set a value on an object using a path, including dot notation.\n */\nexport function setBy(obj: any, _path: any, updater: Updater<any>) {\n const path = makePathArray(_path)\n\n function doSet(parent?: any): any {\n if (!path.length) {\n return functionalUpdate(updater, parent)\n }\n\n const key = path.shift()\n\n if (typeof key === 'string') {\n if (typeof parent === 'object') {\n return {\n ...parent,\n [key]: doSet(parent[key]),\n }\n }\n return {\n [key]: doSet(),\n }\n }\n\n if (typeof key === 'number') {\n if (Array.isArray(parent)) {\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 throw new Error('Uh oh!')\n }\n\n return doSet(obj)\n}\n\nconst reFindNumbers0 = /^(\\d*)$/gm\nconst reFindNumbers1 = /\\.(\\d*)\\./gm\nconst reFindNumbers2 = /^(\\d*)\\./gm\nconst reFindNumbers3 = /\\.(\\d*$)/gm\nconst reFindMultiplePeriods = /\\.{2,}/gm\n\nconst intPrefix = '__int__'\nconst intReplace = `${intPrefix}$1`\n\nfunction makePathArray(str: string) {\n if (typeof str !== 'string') {\n throw new Error('Path must be a string.')\n }\n\n return str\n .replace('[', '.')\n .replace(']', '')\n .replace(reFindNumbers0, intReplace)\n .replace(reFindNumbers1, `.${intReplace}.`)\n .replace(reFindNumbers2, `${intReplace}.`)\n .replace(reFindNumbers3, `.${intReplace}`)\n .replace(reFindMultiplePeriods, '.')\n .split('.')\n .map((d) => {\n if (d.indexOf(intPrefix) === 0) {\n return parseInt(d.substring(intPrefix.length), 10)\n }\n return d\n })\n}\n\nexport type RequiredByKey<T, K extends keyof T> = Omit<T, K> &\n Required<Pick<T, K>>\n\ntype ComputeRange<\n N extends number,\n Result extends Array<unknown> = [],\n> = Result['length'] extends N\n ? Result\n : ComputeRange<N, [...Result, Result['length']]>\ntype Index40 = ComputeRange<40>[number]\n\n// Is this type a tuple?\ntype IsTuple<T> = T extends readonly any[] & { length: infer Length }\n ? Length extends Index40\n ? T\n : never\n : never\n\n// If this type is a tuple, what indices are allowed?\ntype AllowedIndexes<\n Tuple extends ReadonlyArray<any>,\n Keys extends number = never,\n> = Tuple extends readonly []\n ? Keys\n : Tuple extends readonly [infer _, ...infer Tail]\n ? AllowedIndexes<Tail, Keys | Tail['length']>\n : Keys\n\nexport type DeepKeys<T> = unknown extends T\n ? keyof T\n : object extends T\n ? string\n : T extends readonly any[] & IsTuple<T>\n ? AllowedIndexes<T> | DeepKeysPrefix<T, AllowedIndexes<T>>\n : T extends any[]\n ? DeepKeys<T[number]>\n : T extends Date\n ? never\n : T extends object\n ? (keyof T & string) | DeepKeysPrefix<T, keyof T>\n : never\n\ntype DeepKeysPrefix<T, TPrefix> = TPrefix extends keyof T & (number | string)\n ? `${TPrefix}.${DeepKeys<T[TPrefix]> & string}`\n : never\n\nexport type DeepValue<T, TProp> = T extends Record<string | number, any>\n ? TProp extends `${infer TBranch}.${infer TDeepProp}`\n ? DeepValue<T[TBranch], TDeepProp>\n : T[TProp & string]\n : never\n\ntype Narrowable = string | number | bigint | boolean\n\ntype NarrowRaw<A> =\n | (A extends [] ? [] : never)\n | (A extends Narrowable ? A : never)\n | {\n [K in keyof A]: A[K] extends Function ? A[K] : NarrowRaw<A[K]>\n }\n\nexport type Narrow<A> = Try<A, [], NarrowRaw<A>>\n\ntype Try<A1, A2, Catch = never> = A1 extends A2 ? A1 : Catch\n\n// Hack to get TypeScript to show simplified types in error messages\nexport type Pretty<T> = { [K in keyof T]: T[K] } & {}\n"],"names":["functionalUpdate","updater","input","getBy","obj","path","pathArray","makePathArray","pathObj","reduce","current","pathPart","undefined","setBy","_path","doSet","parent","length","key","shift","Array","isArray","prefix","slice","Error","reFindNumbers0","reFindNumbers1","reFindNumbers2","reFindNumbers3","reFindMultiplePeriods","intPrefix","intReplace","str","replace","split","map","d","indexOf","parseInt","substring"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/form-core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"description": "Powerful, type-safe, framework agnostic forms.",
|
|
5
5
|
"author": "tannerlinsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -10,23 +10,36 @@
|
|
|
10
10
|
"type": "github",
|
|
11
11
|
"url": "https://github.com/sponsors/tannerlinsley"
|
|
12
12
|
},
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
13
|
+
"type": "module",
|
|
14
|
+
"types": "build/lib/index.d.ts",
|
|
15
|
+
"main": "build/lib/index.legacy.cjs",
|
|
16
|
+
"module": "build/lib/index.legacy.js",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./build/lib/index.d.ts",
|
|
20
|
+
"import": "./build/lib/index.js",
|
|
21
|
+
"require": "./build/lib/index.cjs",
|
|
22
|
+
"default": "./build/lib/index.cjs"
|
|
23
|
+
},
|
|
24
|
+
"./package.json": "./package.json"
|
|
25
|
+
},
|
|
16
26
|
"sideEffects": false,
|
|
17
27
|
"files": [
|
|
18
|
-
"build
|
|
28
|
+
"build/lib/*",
|
|
19
29
|
"src"
|
|
20
30
|
],
|
|
21
31
|
"dependencies": {
|
|
22
32
|
"@tanstack/store": "0.0.1-beta.89"
|
|
23
33
|
},
|
|
24
34
|
"scripts": {
|
|
25
|
-
"clean": "rimraf ./build",
|
|
35
|
+
"clean": "rimraf ./build && rimraf ./coverage",
|
|
26
36
|
"test:eslint": "eslint --ext .ts,.tsx ./src",
|
|
27
|
-
"test:types": "tsc",
|
|
28
|
-
"test:lib": "
|
|
37
|
+
"test:types": "tsc --noEmit && vitest typecheck",
|
|
38
|
+
"test:lib": "vitest run --coverage",
|
|
29
39
|
"test:lib:dev": "pnpm run test:lib --watch",
|
|
30
|
-
"build
|
|
40
|
+
"test:build": "publint --strict",
|
|
41
|
+
"build": "pnpm build:rollup && pnpm build:types",
|
|
42
|
+
"build:rollup": "rollup --config rollup.config.js",
|
|
43
|
+
"build:types": "tsc --emitDeclarationOnly"
|
|
31
44
|
}
|
|
32
45
|
}
|
package/src/FieldApi.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import type { DeepKeys, DeepValue, RequiredByKey, Updater } from './utils'
|
|
1
|
+
import type { DeepKeys, DeepValue, Updater } from './utils'
|
|
3
2
|
import type { FormApi, ValidationError } from './FormApi'
|
|
4
3
|
import { Store } from '@tanstack/store'
|
|
5
4
|
|
|
@@ -15,8 +14,20 @@ type ValidateAsyncFn<TData, TFormData> = (
|
|
|
15
14
|
fieldApi: FieldApi<TData, TFormData>,
|
|
16
15
|
) => ValidationError | Promise<ValidationError>
|
|
17
16
|
|
|
18
|
-
export interface FieldOptions<
|
|
19
|
-
|
|
17
|
+
export interface FieldOptions<
|
|
18
|
+
_TData,
|
|
19
|
+
TFormData,
|
|
20
|
+
/**
|
|
21
|
+
* This allows us to restrict the name to only be a valid field name while
|
|
22
|
+
* also assigning it to a generic
|
|
23
|
+
*/
|
|
24
|
+
TName = unknown extends TFormData ? string : DeepKeys<TFormData>,
|
|
25
|
+
/**
|
|
26
|
+
* If TData is unknown, we can use the TName generic to determine the type
|
|
27
|
+
*/
|
|
28
|
+
TData = unknown extends _TData ? DeepValue<TFormData, TName> : _TData,
|
|
29
|
+
> {
|
|
30
|
+
name: TName
|
|
20
31
|
index?: TData extends any[] ? number : never
|
|
21
32
|
defaultValue?: TData
|
|
22
33
|
asyncDebounceMs?: number
|
|
@@ -62,8 +73,8 @@ export type ChangeProps<TData> = {
|
|
|
62
73
|
onBlur: (event: any) => void
|
|
63
74
|
}
|
|
64
75
|
|
|
65
|
-
export type InputProps = {
|
|
66
|
-
value:
|
|
76
|
+
export type InputProps<T> = {
|
|
77
|
+
value: T
|
|
67
78
|
onChange: (event: any) => void
|
|
68
79
|
onBlur: (event: any) => void
|
|
69
80
|
}
|
|
@@ -75,14 +86,33 @@ export type FieldState<TData> = {
|
|
|
75
86
|
meta: FieldMeta
|
|
76
87
|
}
|
|
77
88
|
|
|
89
|
+
/**
|
|
90
|
+
* TData may not be known at the time of FieldApi construction, so we need to
|
|
91
|
+
* use a conditional type to determine if TData is known or not.
|
|
92
|
+
*
|
|
93
|
+
* If TData is not known, we use the TFormData type to determine the type of
|
|
94
|
+
* the field value based on the field name.
|
|
95
|
+
*/
|
|
96
|
+
type GetTData<Name, TData, TFormData> = unknown extends TData
|
|
97
|
+
? DeepValue<TFormData, Name>
|
|
98
|
+
: TData
|
|
99
|
+
|
|
78
100
|
export class FieldApi<TData, TFormData> {
|
|
79
101
|
uid: number
|
|
80
102
|
form: FormApi<TFormData>
|
|
81
103
|
name!: DeepKeys<TFormData>
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
104
|
+
/**
|
|
105
|
+
* This is a hack that allows us to use `GetTData` without calling it everywhere
|
|
106
|
+
*
|
|
107
|
+
* Unfortunately this hack appears to be needed alongside the `TName` hack
|
|
108
|
+
* further up in this file. This properly types all of the internal methods,
|
|
109
|
+
* while the `TName` hack types the options properly
|
|
110
|
+
*/
|
|
111
|
+
_tdata!: GetTData<typeof this.name, TData, TFormData>
|
|
112
|
+
store!: Store<FieldState<typeof this._tdata>>
|
|
113
|
+
state!: FieldState<typeof this._tdata>
|
|
114
|
+
prevState!: FieldState<typeof this._tdata>
|
|
115
|
+
options: FieldOptions<typeof this._tdata, TFormData> = {} as any
|
|
86
116
|
|
|
87
117
|
constructor(opts: FieldApiOptions<TData, TFormData>) {
|
|
88
118
|
this.form = opts.form
|
|
@@ -95,7 +125,7 @@ export class FieldApi<TData, TFormData> {
|
|
|
95
125
|
|
|
96
126
|
this.name = opts.name as any
|
|
97
127
|
|
|
98
|
-
this.store = new Store<FieldState<
|
|
128
|
+
this.store = new Store<FieldState<typeof this._tdata>>(
|
|
99
129
|
{
|
|
100
130
|
value: this.getValue(),
|
|
101
131
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
@@ -113,19 +143,15 @@ export class FieldApi<TData, TFormData> {
|
|
|
113
143
|
? state.meta.error
|
|
114
144
|
: undefined
|
|
115
145
|
|
|
116
|
-
|
|
117
|
-
this.validate('change', state.value)
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
this.#prevState = state
|
|
146
|
+
this.prevState = state
|
|
121
147
|
this.state = state
|
|
122
148
|
},
|
|
123
149
|
},
|
|
124
150
|
)
|
|
125
151
|
|
|
126
152
|
this.state = this.store.state
|
|
127
|
-
this
|
|
128
|
-
this.update(opts)
|
|
153
|
+
this.prevState = this.state
|
|
154
|
+
this.update(opts as never)
|
|
129
155
|
}
|
|
130
156
|
|
|
131
157
|
mount = () => {
|
|
@@ -147,7 +173,7 @@ export class FieldApi<TData, TFormData> {
|
|
|
147
173
|
})
|
|
148
174
|
})
|
|
149
175
|
|
|
150
|
-
this.options.onMount?.(this)
|
|
176
|
+
this.options.onMount?.(this as never)
|
|
151
177
|
|
|
152
178
|
return () => {
|
|
153
179
|
unsubscribe()
|
|
@@ -158,20 +184,30 @@ export class FieldApi<TData, TFormData> {
|
|
|
158
184
|
}
|
|
159
185
|
}
|
|
160
186
|
|
|
161
|
-
update = (opts: FieldApiOptions<
|
|
187
|
+
update = (opts: FieldApiOptions<typeof this._tdata, TFormData>) => {
|
|
162
188
|
this.options = {
|
|
163
189
|
asyncDebounceMs: this.form.options.asyncDebounceMs ?? 0,
|
|
164
190
|
onChangeAsyncDebounceMs: this.form.options.onChangeAsyncDebounceMs ?? 0,
|
|
165
191
|
onBlurAsyncDebounceMs: this.form.options.onBlurAsyncDebounceMs ?? 0,
|
|
166
192
|
...opts,
|
|
167
|
-
}
|
|
193
|
+
} as never
|
|
168
194
|
|
|
169
195
|
// Default Value
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
this.options.defaultValue !== undefined
|
|
173
|
-
|
|
174
|
-
|
|
196
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
197
|
+
if (this.state.value === undefined) {
|
|
198
|
+
if (this.options.defaultValue !== undefined) {
|
|
199
|
+
this.setValue(this.options.defaultValue as never)
|
|
200
|
+
} else if (
|
|
201
|
+
opts.form.options.defaultValues?.[
|
|
202
|
+
this.options.name as keyof TFormData
|
|
203
|
+
] !== undefined
|
|
204
|
+
) {
|
|
205
|
+
this.setValue(
|
|
206
|
+
opts.form.options.defaultValues[
|
|
207
|
+
this.options.name as keyof TFormData
|
|
208
|
+
] as never,
|
|
209
|
+
)
|
|
210
|
+
}
|
|
175
211
|
}
|
|
176
212
|
|
|
177
213
|
// Default Meta
|
|
@@ -181,35 +217,50 @@ export class FieldApi<TData, TFormData> {
|
|
|
181
217
|
}
|
|
182
218
|
}
|
|
183
219
|
|
|
184
|
-
getValue = ():
|
|
220
|
+
getValue = (): typeof this._tdata => {
|
|
185
221
|
return this.form.getFieldValue(this.name)
|
|
186
222
|
}
|
|
223
|
+
|
|
187
224
|
setValue = (
|
|
188
|
-
updater: Updater<
|
|
225
|
+
updater: Updater<typeof this._tdata>,
|
|
189
226
|
options?: { touch?: boolean; notify?: boolean },
|
|
190
|
-
) =>
|
|
227
|
+
) => {
|
|
228
|
+
this.form.setFieldValue(this.name, updater as never, options)
|
|
229
|
+
this.validate('change', this.state.value)
|
|
230
|
+
}
|
|
191
231
|
|
|
192
232
|
getMeta = (): FieldMeta => this.form.getFieldMeta(this.name)
|
|
233
|
+
|
|
193
234
|
setMeta = (updater: Updater<FieldMeta>) =>
|
|
194
235
|
this.form.setFieldMeta(this.name, updater)
|
|
195
236
|
|
|
196
237
|
getInfo = () => this.form.getFieldInfo(this.name)
|
|
197
238
|
|
|
198
|
-
pushValue = (
|
|
199
|
-
this.
|
|
200
|
-
|
|
201
|
-
|
|
239
|
+
pushValue = (
|
|
240
|
+
value: typeof this._tdata extends any[]
|
|
241
|
+
? (typeof this._tdata)[number]
|
|
242
|
+
: never,
|
|
243
|
+
) => this.form.pushFieldValue(this.name, value as any)
|
|
244
|
+
|
|
245
|
+
insertValue = (
|
|
246
|
+
index: number,
|
|
247
|
+
value: typeof this._tdata extends any[]
|
|
248
|
+
? (typeof this._tdata)[number]
|
|
249
|
+
: never,
|
|
250
|
+
) => this.form.insertFieldValue(this.name, index, value as any)
|
|
251
|
+
|
|
202
252
|
removeValue = (index: number) => this.form.removeFieldValue(this.name, index)
|
|
253
|
+
|
|
203
254
|
swapValues = (aIndex: number, bIndex: number) =>
|
|
204
255
|
this.form.swapFieldValues(this.name, aIndex, bIndex)
|
|
205
256
|
|
|
206
|
-
getSubField = <TName extends DeepKeys<
|
|
207
|
-
new FieldApi<DeepValue<
|
|
208
|
-
name: `${this.name}.${name}` as
|
|
257
|
+
getSubField = <TName extends DeepKeys<typeof this._tdata>>(name: TName) =>
|
|
258
|
+
new FieldApi<DeepValue<typeof this._tdata, TName>, TFormData>({
|
|
259
|
+
name: `${this.name}.${name}` as never,
|
|
209
260
|
form: this.form,
|
|
210
261
|
})
|
|
211
262
|
|
|
212
|
-
validateSync =
|
|
263
|
+
validateSync = (value = this.state.value, cause: ValidationCause) => {
|
|
213
264
|
const { onChange, onBlur } = this.options
|
|
214
265
|
const validate =
|
|
215
266
|
cause === 'submit' ? undefined : cause === 'change' ? onChange : onBlur
|
|
@@ -220,7 +271,7 @@ export class FieldApi<TData, TFormData> {
|
|
|
220
271
|
// track freshness of the validation
|
|
221
272
|
const validationCount = (this.getInfo().validationCount || 0) + 1
|
|
222
273
|
this.getInfo().validationCount = validationCount
|
|
223
|
-
const error = normalizeError(validate(value, this))
|
|
274
|
+
const error = normalizeError(validate(value as never, this as never))
|
|
224
275
|
|
|
225
276
|
if (this.state.meta.error !== error) {
|
|
226
277
|
this.setMeta((prev) => ({
|
|
@@ -303,7 +354,7 @@ export class FieldApi<TData, TFormData> {
|
|
|
303
354
|
// Only kick off validation if this validation is the latest attempt
|
|
304
355
|
if (checkLatest()) {
|
|
305
356
|
try {
|
|
306
|
-
const rawError = await validate(value, this)
|
|
357
|
+
const rawError = await validate(value as never, this as never)
|
|
307
358
|
|
|
308
359
|
if (checkLatest()) {
|
|
309
360
|
const error = normalizeError(rawError)
|
|
@@ -333,7 +384,7 @@ export class FieldApi<TData, TFormData> {
|
|
|
333
384
|
|
|
334
385
|
validate = (
|
|
335
386
|
cause: ValidationCause,
|
|
336
|
-
value?:
|
|
387
|
+
value?: typeof this._tdata,
|
|
337
388
|
): ValidationError | Promise<ValidationError> => {
|
|
338
389
|
// If the field is pristine and validatePristine is false, do not validate
|
|
339
390
|
if (!this.state.meta.isTouched) return
|
|
@@ -354,12 +405,13 @@ export class FieldApi<TData, TFormData> {
|
|
|
354
405
|
|
|
355
406
|
getChangeProps = <T extends UserChangeProps<any>>(
|
|
356
407
|
props: T = {} as T,
|
|
357
|
-
): ChangeProps<
|
|
408
|
+
): ChangeProps<typeof this._tdata> &
|
|
409
|
+
Omit<T, keyof ChangeProps<typeof this._tdata>> => {
|
|
358
410
|
return {
|
|
359
411
|
...props,
|
|
360
412
|
value: this.state.value,
|
|
361
413
|
onChange: (value) => {
|
|
362
|
-
this.setValue(value)
|
|
414
|
+
this.setValue(value as never)
|
|
363
415
|
props.onChange?.(value)
|
|
364
416
|
},
|
|
365
417
|
onBlur: (e) => {
|
|
@@ -370,21 +422,24 @@ export class FieldApi<TData, TFormData> {
|
|
|
370
422
|
}
|
|
371
423
|
this.validate('blur')
|
|
372
424
|
},
|
|
373
|
-
} as ChangeProps<
|
|
425
|
+
} as ChangeProps<typeof this._tdata> &
|
|
426
|
+
Omit<T, keyof ChangeProps<typeof this._tdata>>
|
|
374
427
|
}
|
|
375
428
|
|
|
376
429
|
getInputProps = <T extends UserInputProps>(
|
|
377
430
|
props: T = {} as T,
|
|
378
|
-
): InputProps
|
|
431
|
+
): InputProps<typeof this._tdata> &
|
|
432
|
+
Omit<T, keyof InputProps<typeof this._tdata>> => {
|
|
379
433
|
return {
|
|
380
434
|
...props,
|
|
381
|
-
value:
|
|
435
|
+
value: this.state.value,
|
|
382
436
|
onChange: (e) => {
|
|
383
437
|
this.setValue(e.target.value)
|
|
384
438
|
props.onChange?.(e.target.value)
|
|
385
439
|
},
|
|
386
440
|
onBlur: this.getChangeProps(props).onBlur,
|
|
387
|
-
}
|
|
441
|
+
} as InputProps<typeof this._tdata> &
|
|
442
|
+
Omit<T, keyof InputProps<typeof this._tdata>>
|
|
388
443
|
}
|
|
389
444
|
}
|
|
390
445
|
|
package/src/FormApi.ts
CHANGED
|
@@ -164,26 +164,45 @@ export class FormApi<TFormData> {
|
|
|
164
164
|
if (!options) return
|
|
165
165
|
|
|
166
166
|
this.store.batch(() => {
|
|
167
|
-
|
|
168
|
-
options.
|
|
167
|
+
const shouldUpdateValues =
|
|
168
|
+
options.defaultValues &&
|
|
169
|
+
options.defaultValues !== this.options.defaultValues
|
|
170
|
+
|
|
171
|
+
const shouldUpdateState =
|
|
169
172
|
options.defaultState !== this.options.defaultState
|
|
170
|
-
) {
|
|
171
|
-
this.store.setState((prev) => ({
|
|
172
|
-
...prev,
|
|
173
|
-
...options.defaultState,
|
|
174
|
-
}))
|
|
175
|
-
}
|
|
176
173
|
|
|
177
|
-
|
|
178
|
-
|
|
174
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
175
|
+
if (!shouldUpdateValues || !shouldUpdateValues) {
|
|
176
|
+
return
|
|
179
177
|
}
|
|
178
|
+
|
|
179
|
+
this.store.setState(() =>
|
|
180
|
+
getDefaultFormState(
|
|
181
|
+
Object.assign(
|
|
182
|
+
{},
|
|
183
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
184
|
+
shouldUpdateState ? options.defaultState : {},
|
|
185
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
186
|
+
shouldUpdateValues
|
|
187
|
+
? {
|
|
188
|
+
values: options.defaultValues,
|
|
189
|
+
}
|
|
190
|
+
: {},
|
|
191
|
+
),
|
|
192
|
+
),
|
|
193
|
+
)
|
|
180
194
|
})
|
|
181
195
|
|
|
182
196
|
this.options = options
|
|
183
197
|
}
|
|
184
198
|
|
|
185
199
|
reset = () =>
|
|
186
|
-
this.store.setState(() =>
|
|
200
|
+
this.store.setState(() =>
|
|
201
|
+
getDefaultFormState({
|
|
202
|
+
...this.options.defaultState,
|
|
203
|
+
values: this.options.defaultValues ?? this.options.defaultState?.values,
|
|
204
|
+
}),
|
|
205
|
+
)
|
|
187
206
|
|
|
188
207
|
validateAllFields = async (cause: ValidationCause) => {
|
|
189
208
|
const fieldValidationPromises: Promise<ValidationError>[] = [] as any
|
|
@@ -281,6 +300,7 @@ export class FormApi<TFormData> {
|
|
|
281
300
|
}
|
|
282
301
|
|
|
283
302
|
getFieldInfo = <TField extends DeepKeys<TFormData>>(field: TField) => {
|
|
303
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
284
304
|
return (this.fieldInfo[field] ||= {
|
|
285
305
|
instances: {},
|
|
286
306
|
})
|
|
@@ -327,7 +347,7 @@ export class FormApi<TFormData> {
|
|
|
327
347
|
|
|
328
348
|
pushFieldValue = <TField extends DeepKeys<TFormData>>(
|
|
329
349
|
field: TField,
|
|
330
|
-
value: DeepValue<TFormData, TField
|
|
350
|
+
value: DeepValue<TFormData, TField>[number],
|
|
331
351
|
opts?: { touch?: boolean },
|
|
332
352
|
) => {
|
|
333
353
|
return this.setFieldValue(
|
|
@@ -340,7 +360,7 @@ export class FormApi<TFormData> {
|
|
|
340
360
|
insertFieldValue = <TField extends DeepKeys<TFormData>>(
|
|
341
361
|
field: TField,
|
|
342
362
|
index: number,
|
|
343
|
-
value: DeepValue<TFormData, TField
|
|
363
|
+
value: DeepValue<TFormData, TField>[number],
|
|
344
364
|
opts?: { touch?: boolean },
|
|
345
365
|
) => {
|
|
346
366
|
this.setFieldValue(
|
|
@@ -378,7 +398,7 @@ export class FormApi<TFormData> {
|
|
|
378
398
|
this.setFieldValue(field, (prev: any) => {
|
|
379
399
|
const prev1 = prev[index1]!
|
|
380
400
|
const prev2 = prev[index2]!
|
|
381
|
-
return setBy(setBy(prev,
|
|
401
|
+
return setBy(setBy(prev, `${index1}`, prev2), `${index2}`, prev1)
|
|
382
402
|
})
|
|
383
403
|
}
|
|
384
404
|
}
|