mirror of
https://github.com/LukeHagar/form.git
synced 2025-12-06 12:27:45 +00:00
fix: Field components should now infer state.value properly
* chore: refactor TS typings for React * fix: field should now infer state.value properly in React adapter * chore: fix Vue package typings * chore: fix linting * chore: fix React adapter * chore: improve performance of TData type in FieldApi * chore: add back index and parent type * chore: add Vue TSC dep on Vue example * chore: fix lint and type test * chore: update Vite stuff * chore: add implicit dep for Vue and React examples * chore: add type test pre-req * chore: install deps from examples in PR CI * chore: remove filter from more installation
This commit is contained in:
10
.github/workflows/pr.yml
vendored
10
.github/workflows/pr.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
node-version: 18.15.0
|
||||
cache: 'pnpm'
|
||||
- name: Install dependencies
|
||||
run: pnpm --filter "./packages/**" --filter form --prefer-offline install --no-frozen-lockfile
|
||||
run: pnpm --prefer-offline install --no-frozen-lockfile
|
||||
- name: Run Tests
|
||||
uses: nick-fields/retry@v2.8.3
|
||||
with:
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
node-version: 16.14.2
|
||||
cache: 'pnpm'
|
||||
- name: Install dependencies
|
||||
run: pnpm --filter "./packages/**" --filter form --prefer-offline install --no-frozen-lockfile
|
||||
run: pnpm --prefer-offline install --no-frozen-lockfile
|
||||
- run: pnpm run test:eslint --base=${{ github.event.pull_request.base.sha }}
|
||||
typecheck:
|
||||
name: 'Typecheck'
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
node-version: 16.14.2
|
||||
cache: 'pnpm'
|
||||
- name: Install dependencies
|
||||
run: pnpm --filter "./packages/**" --filter form --prefer-offline install --no-frozen-lockfile
|
||||
run: pnpm --prefer-offline install --no-frozen-lockfile
|
||||
- run: pnpm run test:types --base=${{ github.event.pull_request.base.sha }}
|
||||
format:
|
||||
name: 'Format'
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
node-version: 16.14.2
|
||||
cache: 'pnpm'
|
||||
- name: Install dependencies
|
||||
run: pnpm --filter "./packages/**" --filter form --prefer-offline install --no-frozen-lockfile
|
||||
run: pnpm --prefer-offline install --no-frozen-lockfile
|
||||
- run: pnpm run test:format --base=${{ github.event.pull_request.base.sha }}
|
||||
test-build:
|
||||
name: 'Test Build'
|
||||
@@ -105,7 +105,7 @@ jobs:
|
||||
node-version: 16.14.2
|
||||
cache: 'pnpm'
|
||||
- name: Install dependencies
|
||||
run: pnpm --filter "./packages/**" --filter form --prefer-offline install --no-frozen-lockfile
|
||||
run: pnpm --prefer-offline install --no-frozen-lockfile
|
||||
- name: Get appropriate base and head commits for `nx affected` commands
|
||||
uses: nrwl/nx-set-shas@v3
|
||||
with:
|
||||
|
||||
@@ -13,12 +13,11 @@
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"zod": "^3.21.4",
|
||||
"@tanstack/form-core": "0.3.2",
|
||||
"@tanstack/vue-form": "0.3.2"
|
||||
"@tanstack/form-core": "0.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-react": "^2.0.0",
|
||||
"vite": "^3.0.0"
|
||||
"@vitejs/plugin-react": "^4.0.4",
|
||||
"vite": "^4.4.9"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
@@ -31,5 +30,18 @@
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"nx": {
|
||||
"implicitDependencies": [
|
||||
"@tanstack/form-core",
|
||||
"@tanstack/react-form"
|
||||
],
|
||||
"targets": {
|
||||
"test:types": {
|
||||
"dependsOn": [
|
||||
"build"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,17 +5,31 @@
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"build:dev": "vite build -m development",
|
||||
"test:types": "vue-tsc --noEmit",
|
||||
"serve": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tanstack/vue-form": "0.3.2",
|
||||
"vue": "^3.3.4",
|
||||
"@tanstack/form-core": "0.3.2",
|
||||
"@tanstack/react-form": "0.3.2"
|
||||
"@tanstack/vue-form": "0.3.2",
|
||||
"vue": "^3.3.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^4.2.3",
|
||||
"@vitejs/plugin-vue": "^4.3.4",
|
||||
"typescript": "^5.0.4",
|
||||
"vite": "^4.4.4"
|
||||
"vite": "^4.4.9",
|
||||
"vue-tsc": "^1.8.10"
|
||||
},
|
||||
"nx": {
|
||||
"implicitDependencies": [
|
||||
"@tanstack/form-core",
|
||||
"@tanstack/vue-form"
|
||||
],
|
||||
"targets": {
|
||||
"test:types": {
|
||||
"dependsOn": [
|
||||
"build"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ const form = useForm({
|
||||
|
||||
form.provideFormContext()
|
||||
|
||||
async function onChangeFirstName(value) {
|
||||
async function onChangeFirstName(value: string) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
return value.includes(`error`) && `No 'error' allowed in first name`
|
||||
}
|
||||
|
||||
@@ -56,8 +56,6 @@
|
||||
"@types/testing-library__jest-dom": "^5.14.5",
|
||||
"@typescript-eslint/eslint-plugin": "^6.4.1",
|
||||
"@typescript-eslint/parser": "^6.4.1",
|
||||
"@vitejs/plugin-vue": "^4.3.4",
|
||||
"@vitejs/plugin-vue-jsx": "^3.0.2",
|
||||
"@vitest/coverage-istanbul": "^0.34.3",
|
||||
"axios": "^0.26.1",
|
||||
"babel-eslint": "^10.1.0",
|
||||
|
||||
@@ -43,10 +43,19 @@ export interface FieldOptions<
|
||||
defaultMeta?: Partial<FieldMeta>
|
||||
}
|
||||
|
||||
export type FieldApiOptions<TData, TFormData> = FieldOptions<
|
||||
TData,
|
||||
TFormData
|
||||
> & {
|
||||
export interface FieldApiOptions<
|
||||
_TData,
|
||||
TFormData,
|
||||
/**
|
||||
* This allows us to restrict the name to only be a valid field name while
|
||||
* also assigning it to a generic
|
||||
*/
|
||||
TName = unknown extends TFormData ? string : DeepKeys<TFormData>,
|
||||
/**
|
||||
* If TData is unknown, we can use the TName generic to determine the type
|
||||
*/
|
||||
TData = unknown extends _TData ? DeepValue<TFormData, TName> : _TData,
|
||||
> extends FieldOptions<_TData, TFormData, TName, TData> {
|
||||
form: FormApi<TFormData>
|
||||
}
|
||||
|
||||
@@ -65,35 +74,45 @@ export type FieldState<TData> = {
|
||||
meta: FieldMeta
|
||||
}
|
||||
|
||||
/**
|
||||
* TData may not be known at the time of FieldApi construction, so we need to
|
||||
* use a conditional type to determine if TData is known or not.
|
||||
*
|
||||
* If TData is not known, we use the TFormData type to determine the type of
|
||||
* the field value based on the field name.
|
||||
*/
|
||||
type GetTData<Name, TData, TFormData> = unknown extends TData
|
||||
? DeepValue<TFormData, Name>
|
||||
: TData
|
||||
type GetTData<
|
||||
TData,
|
||||
TFormData,
|
||||
Opts extends FieldApiOptions<TData, TFormData>,
|
||||
> = Opts extends FieldApiOptions<
|
||||
infer _TData,
|
||||
infer _TFormData,
|
||||
infer _TName,
|
||||
infer RealTData
|
||||
>
|
||||
? RealTData
|
||||
: never
|
||||
|
||||
export class FieldApi<TData, TFormData> {
|
||||
export class FieldApi<
|
||||
_TData,
|
||||
TFormData,
|
||||
Opts extends FieldApiOptions<_TData, TFormData> = FieldApiOptions<
|
||||
_TData,
|
||||
TFormData
|
||||
>,
|
||||
TData extends GetTData<_TData, TFormData, Opts> = GetTData<
|
||||
_TData,
|
||||
TFormData,
|
||||
Opts
|
||||
>,
|
||||
> {
|
||||
uid: number
|
||||
form: FormApi<TFormData>
|
||||
form: Opts['form']
|
||||
name!: DeepKeys<TFormData>
|
||||
/**
|
||||
* This is a hack that allows us to use `GetTData` without calling it everywhere
|
||||
*
|
||||
* Unfortunately this hack appears to be needed alongside the `TName` hack
|
||||
* further up in this file. This properly types all of the internal methods,
|
||||
* while the `TName` hack types the options properly
|
||||
*/
|
||||
_tdata!: GetTData<typeof this.name, TData, TFormData>
|
||||
store!: Store<FieldState<typeof this._tdata>>
|
||||
state!: FieldState<typeof this._tdata>
|
||||
prevState!: FieldState<typeof this._tdata>
|
||||
options: FieldOptions<typeof this._tdata, TFormData> = {} as any
|
||||
options: Opts = {} as any
|
||||
store!: Store<FieldState<TData>>
|
||||
state!: FieldState<TData>
|
||||
prevState!: FieldState<TData>
|
||||
|
||||
constructor(opts: FieldApiOptions<TData, TFormData>) {
|
||||
constructor(
|
||||
opts: Opts & {
|
||||
form: FormApi<TFormData>
|
||||
},
|
||||
) {
|
||||
this.form = opts.form
|
||||
this.uid = uid++
|
||||
// Support field prefixing from FieldScope
|
||||
@@ -104,7 +123,7 @@ export class FieldApi<TData, TFormData> {
|
||||
|
||||
this.name = opts.name as any
|
||||
|
||||
this.store = new Store<FieldState<typeof this._tdata>>(
|
||||
this.store = new Store<FieldState<TData>>(
|
||||
{
|
||||
value: this.getValue(),
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
@@ -138,7 +157,7 @@ export class FieldApi<TData, TFormData> {
|
||||
|
||||
mount = () => {
|
||||
const info = this.getInfo()
|
||||
info.instances[this.uid] = this
|
||||
info.instances[this.uid] = this as never
|
||||
|
||||
const unsubscribe = this.form.store.subscribe(() => {
|
||||
this.store.batch(() => {
|
||||
@@ -167,7 +186,7 @@ export class FieldApi<TData, TFormData> {
|
||||
}
|
||||
}
|
||||
|
||||
update = (opts: FieldApiOptions<typeof this._tdata, TFormData>) => {
|
||||
update = (opts: FieldApiOptions<TData, TFormData>) => {
|
||||
// Default Value
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
if (this.state.value === undefined) {
|
||||
@@ -189,12 +208,12 @@ export class FieldApi<TData, TFormData> {
|
||||
this.options = opts as never
|
||||
}
|
||||
|
||||
getValue = (): typeof this._tdata => {
|
||||
getValue = (): TData => {
|
||||
return this.form.getFieldValue(this.name)
|
||||
}
|
||||
|
||||
setValue = (
|
||||
updater: Updater<typeof this._tdata>,
|
||||
updater: Updater<TData>,
|
||||
options?: { touch?: boolean; notify?: boolean },
|
||||
) => {
|
||||
this.form.setFieldValue(this.name, updater as never, options)
|
||||
@@ -218,17 +237,12 @@ export class FieldApi<TData, TFormData> {
|
||||
|
||||
getInfo = () => this.form.getFieldInfo(this.name)
|
||||
|
||||
pushValue = (
|
||||
value: typeof this._tdata extends any[]
|
||||
? (typeof this._tdata)[number]
|
||||
: never,
|
||||
) => this.form.pushFieldValue(this.name, value as any)
|
||||
pushValue = (value: TData extends any[] ? TData[number] : never) =>
|
||||
this.form.pushFieldValue(this.name, value as any)
|
||||
|
||||
insertValue = (
|
||||
index: number,
|
||||
value: typeof this._tdata extends any[]
|
||||
? (typeof this._tdata)[number]
|
||||
: never,
|
||||
value: TData extends any[] ? TData[number] : never,
|
||||
) => this.form.insertFieldValue(this.name, index, value as any)
|
||||
|
||||
removeValue = (index: number) => this.form.removeFieldValue(this.name, index)
|
||||
@@ -236,8 +250,8 @@ export class FieldApi<TData, TFormData> {
|
||||
swapValues = (aIndex: number, bIndex: number) =>
|
||||
this.form.swapFieldValues(this.name, aIndex, bIndex)
|
||||
|
||||
getSubField = <TName extends DeepKeys<typeof this._tdata>>(name: TName) =>
|
||||
new FieldApi<DeepValue<typeof this._tdata, TName>, TFormData>({
|
||||
getSubField = <TName extends DeepKeys<TData>>(name: TName) =>
|
||||
new FieldApi<DeepValue<TData, TName>, TFormData>({
|
||||
name: `${this.name}.${name}` as never,
|
||||
form: this.form,
|
||||
})
|
||||
@@ -371,7 +385,7 @@ export class FieldApi<TData, TFormData> {
|
||||
|
||||
validate = (
|
||||
cause: ValidationCause,
|
||||
value?: typeof this._tdata,
|
||||
value?: TData,
|
||||
): ValidationError[] | Promise<ValidationError[]> => {
|
||||
// If the field is pristine and validatePristine is false, do not validate
|
||||
if (!this.state.meta.isTouched) return []
|
||||
@@ -389,7 +403,7 @@ export class FieldApi<TData, TFormData> {
|
||||
return this.validateAsync(value, cause)
|
||||
}
|
||||
|
||||
handleChange = (updater: Updater<typeof this._tdata>) => {
|
||||
handleChange = (updater: Updater<TData>) => {
|
||||
this.setValue(updater, { touch: true })
|
||||
}
|
||||
|
||||
|
||||
63
packages/react-form/src/tests/useField.test-d.tsx
Normal file
63
packages/react-form/src/tests/useField.test-d.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
import { assertType } from 'vitest'
|
||||
import * as React from 'react'
|
||||
import { useForm } from '../useForm'
|
||||
|
||||
it('should type state.value properly', () => {
|
||||
function Comp() {
|
||||
const form = useForm({
|
||||
defaultValues: {
|
||||
firstName: 'test',
|
||||
age: 84,
|
||||
},
|
||||
} as const)
|
||||
|
||||
return (
|
||||
<form.Provider>
|
||||
<form.Field
|
||||
name="firstName"
|
||||
children={(field) => {
|
||||
assertType<'test'>(field.state.value)
|
||||
}}
|
||||
/>
|
||||
<form.Field
|
||||
name="age"
|
||||
children={(field) => {
|
||||
assertType<84>(field.state.value)
|
||||
}}
|
||||
/>
|
||||
</form.Provider>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it('should type onChange properly', () => {
|
||||
function Comp() {
|
||||
const form = useForm({
|
||||
defaultValues: {
|
||||
firstName: 'test',
|
||||
age: 84,
|
||||
},
|
||||
} as const)
|
||||
|
||||
return (
|
||||
<form.Provider>
|
||||
<form.Field
|
||||
name="firstName"
|
||||
onChange={(val) => {
|
||||
assertType<'test'>(val)
|
||||
return null
|
||||
}}
|
||||
children={(field) => null}
|
||||
/>
|
||||
<form.Field
|
||||
name="age"
|
||||
onChange={(val) => {
|
||||
assertType<84>(val)
|
||||
return null
|
||||
}}
|
||||
children={(field) => null}
|
||||
/>
|
||||
</form.Provider>
|
||||
)
|
||||
}
|
||||
})
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { FieldOptions } from '@tanstack/form-core'
|
||||
import type { FieldOptions, DeepKeys } from '@tanstack/form-core'
|
||||
|
||||
export type UseFieldOptions<TData, TFormData> = FieldOptions<
|
||||
export type UseFieldOptions<
|
||||
TData,
|
||||
TFormData
|
||||
> & {
|
||||
TFormData,
|
||||
TName = unknown extends TFormData ? string : DeepKeys<TFormData>,
|
||||
> = FieldOptions<TData, TFormData, TName> & {
|
||||
mode?: 'value' | 'array'
|
||||
}
|
||||
|
||||
@@ -3,17 +3,17 @@ import { useStore } from '@tanstack/react-store'
|
||||
import type {
|
||||
DeepKeys,
|
||||
DeepValue,
|
||||
FieldOptions,
|
||||
FieldApiOptions,
|
||||
Narrow,
|
||||
} from '@tanstack/form-core'
|
||||
import { FieldApi, functionalUpdate } from '@tanstack/form-core'
|
||||
import { FieldApi, type FormApi, functionalUpdate } from '@tanstack/form-core'
|
||||
import { useFormContext, formContext } from './formContext'
|
||||
import useIsomorphicLayoutEffect from 'use-isomorphic-layout-effect'
|
||||
import type { UseFieldOptions } from './types'
|
||||
|
||||
declare module '@tanstack/form-core' {
|
||||
// eslint-disable-next-line no-shadow
|
||||
interface FieldApi<TData, TFormData> {
|
||||
interface FieldApi<_TData, TFormData, Opts, TData> {
|
||||
Field: FieldComponent<TData, TFormData>
|
||||
}
|
||||
}
|
||||
@@ -25,13 +25,27 @@ export type UseField<TFormData> = <TField extends DeepKeys<TFormData>>(
|
||||
>,
|
||||
) => FieldApi<DeepValue<TFormData, TField>, TFormData>
|
||||
|
||||
export function useField<TData, TFormData>(
|
||||
opts: UseFieldOptions<TData, TFormData>,
|
||||
): FieldApi<TData, TFormData> {
|
||||
export function useField<
|
||||
TData,
|
||||
TFormData,
|
||||
TName extends unknown extends TFormData
|
||||
? string
|
||||
: DeepKeys<TFormData> = unknown extends TFormData
|
||||
? string
|
||||
: DeepKeys<TFormData>,
|
||||
>(
|
||||
opts: UseFieldOptions<TData, TFormData, TName>,
|
||||
): FieldApi<
|
||||
TData,
|
||||
TFormData,
|
||||
Omit<typeof opts, 'onMount'> & {
|
||||
form: FormApi<TFormData>
|
||||
}
|
||||
> {
|
||||
// Get the form API either manually or from context
|
||||
const { formApi, parentFieldName } = useFormContext()
|
||||
|
||||
const [fieldApi] = useState<FieldApi<TData, TFormData>>(() => {
|
||||
const [fieldApi] = useState(() => {
|
||||
const name = (
|
||||
typeof opts.index === 'number'
|
||||
? [parentFieldName, opts.index, opts.name]
|
||||
@@ -40,9 +54,13 @@ export function useField<TData, TFormData>(
|
||||
.filter((d) => d !== undefined)
|
||||
.join('.')
|
||||
|
||||
const api = new FieldApi({ ...opts, form: formApi, name: name as any })
|
||||
const api = new FieldApi({
|
||||
...opts,
|
||||
form: formApi,
|
||||
name: name,
|
||||
} as never)
|
||||
|
||||
api.Field = Field as any
|
||||
api.Field = Field as never
|
||||
|
||||
return api
|
||||
})
|
||||
@@ -56,70 +74,52 @@ export function useField<TData, TFormData>(
|
||||
})
|
||||
|
||||
useStore(
|
||||
fieldApi.store as any,
|
||||
fieldApi.store,
|
||||
opts.mode === 'array'
|
||||
? (state: any) => {
|
||||
return [state.meta, Object.keys(state.value || []).length]
|
||||
}
|
||||
: undefined,
|
||||
)
|
||||
|
||||
// Instantiates field meta and removes it when unrendered
|
||||
useIsomorphicLayoutEffect(() => fieldApi.mount(), [fieldApi])
|
||||
|
||||
return fieldApi
|
||||
return fieldApi as never
|
||||
}
|
||||
|
||||
// export type FieldValue<TFormData, TField> = TFormData extends any[]
|
||||
// ? TField extends `[${infer TIndex extends number | 'i'}].${infer TRest}`
|
||||
// ? DeepValue<TFormData[TIndex extends 'i' ? number : TIndex], TRest>
|
||||
// : TField extends `[${infer TIndex extends number | 'i'}]`
|
||||
// ? TFormData[TIndex extends 'i' ? number : TIndex]
|
||||
// : never
|
||||
// : TField extends `${infer TPrefix}[${infer TIndex extends
|
||||
// | number
|
||||
// | 'i'}].${infer TRest}`
|
||||
// ? DeepValue<
|
||||
// DeepValue<TFormData, TPrefix>[TIndex extends 'i' ? number : TIndex],
|
||||
// TRest
|
||||
// >
|
||||
// : TField extends `${infer TPrefix}[${infer TIndex extends number | 'i'}]`
|
||||
// ? DeepValue<TFormData, TPrefix>[TIndex extends 'i' ? number : TIndex]
|
||||
// : DeepValue<TFormData, TField>
|
||||
type FieldComponentProps<
|
||||
TParentData,
|
||||
TFormData,
|
||||
TField,
|
||||
TName extends unknown extends TFormData ? string : DeepKeys<TFormData>,
|
||||
> = {
|
||||
children: (
|
||||
fieldApi: FieldApi<
|
||||
TField,
|
||||
TFormData,
|
||||
FieldApiOptions<TField, TFormData, TName>
|
||||
>,
|
||||
) => any
|
||||
} & (TParentData extends any[]
|
||||
? {
|
||||
name?: TName
|
||||
index: number
|
||||
}
|
||||
: {
|
||||
name: TName
|
||||
index?: never
|
||||
}) &
|
||||
Omit<UseFieldOptions<TField, TFormData, TName>, 'name' | 'index'>
|
||||
|
||||
export type FieldValue<TFormData, TField> = TFormData extends any[]
|
||||
? unknown extends TField
|
||||
? TFormData[number]
|
||||
: DeepValue<TFormData[number], TField>
|
||||
: DeepValue<TFormData, TField>
|
||||
|
||||
// type Test1 = FieldValue<{ foo: { bar: string }[] }, 'foo'>
|
||||
// // ^?
|
||||
// type Test2 = FieldValue<{ foo: { bar: string }[] }, 'foo[i]'>
|
||||
// // ^?
|
||||
// type Test3 = FieldValue<{ foo: { bar: string }[] }, 'foo[2].bar'>
|
||||
// // ^?
|
||||
|
||||
export type FieldComponent<TParentData, TFormData> = <TField>({
|
||||
export type FieldComponent<TParentData, TFormData> = <
|
||||
// Type of the field
|
||||
TField,
|
||||
// Name of the field
|
||||
TName extends unknown extends TFormData ? string : DeepKeys<TFormData>,
|
||||
>({
|
||||
children,
|
||||
...fieldOptions
|
||||
}: {
|
||||
children: (
|
||||
fieldApi: FieldApi<FieldValue<TParentData, TField>, TFormData>,
|
||||
) => any
|
||||
} & Omit<
|
||||
UseFieldOptions<FieldValue<TParentData, TField>, TFormData>,
|
||||
'name' | 'index'
|
||||
> &
|
||||
(TParentData extends any[]
|
||||
? {
|
||||
name?: TField extends undefined ? TField : DeepKeys<TParentData>
|
||||
index: number
|
||||
}
|
||||
: {
|
||||
name: TField extends undefined ? TField : DeepKeys<TParentData>
|
||||
index?: never
|
||||
})) => any
|
||||
}: FieldComponentProps<TParentData, TFormData, TField, TName>) => any
|
||||
|
||||
export function Field<TData, TFormData>({
|
||||
children,
|
||||
|
||||
@@ -28,10 +28,9 @@ export function useForm<TData>(opts?: FormOptions<TData>): FormApi<TData> {
|
||||
// @ts-ignore
|
||||
const api = new FormApi<TData>(opts)
|
||||
|
||||
// eslint-disable-next-line react/display-name
|
||||
api.Provider = (props) => (
|
||||
<formContext.Provider {...props} value={{ formApi: api }} />
|
||||
)
|
||||
api.Provider = function Provider(props) {
|
||||
return <formContext.Provider {...props} value={{ formApi: api }} />
|
||||
}
|
||||
api.Field = Field as any
|
||||
api.useField = useField as any
|
||||
api.useStore = (
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
export type NoInfer<T> = [T][T extends any ? 0 : never]
|
||||
import type { FieldOptions, DeepKeys } from '@tanstack/form-core'
|
||||
|
||||
export type ReleaseVersion = 2
|
||||
export type UseFieldOptions<
|
||||
TData,
|
||||
TFormData,
|
||||
TName = unknown extends TFormData ? string : DeepKeys<TFormData>,
|
||||
> = FieldOptions<TData, TFormData, TName> & {
|
||||
mode?: 'value' | 'array'
|
||||
}
|
||||
|
||||
@@ -1,28 +1,22 @@
|
||||
import { FieldApi } from '@tanstack/form-core'
|
||||
import type {
|
||||
FieldState,
|
||||
DeepKeys,
|
||||
DeepValue,
|
||||
FieldOptions,
|
||||
Narrow,
|
||||
import {
|
||||
FieldApi,
|
||||
type FieldApiOptions,
|
||||
type FormApi,
|
||||
} from '@tanstack/form-core'
|
||||
import type { DeepKeys, DeepValue, Narrow } from '@tanstack/form-core'
|
||||
import { useStore } from '@tanstack/vue-store'
|
||||
import { defineComponent, onMounted, onUnmounted, watch } from 'vue-demi'
|
||||
import type { SlotsType, SetupContext, Ref } from 'vue-demi'
|
||||
import { provideFormContext, useFormContext } from './formContext'
|
||||
import type { UseFieldOptions } from './types'
|
||||
|
||||
declare module '@tanstack/form-core' {
|
||||
// eslint-disable-next-line no-shadow
|
||||
interface FieldApi<TData, TFormData> {
|
||||
Field: FieldComponent<TData, TFormData>
|
||||
interface FieldApi<_TData, TFormData, Opts, TData> {
|
||||
Field: FieldComponent<TFormData, TData>
|
||||
}
|
||||
}
|
||||
|
||||
export interface UseFieldOptions<TData, TFormData>
|
||||
extends FieldOptions<TData, TFormData> {
|
||||
mode?: 'value' | 'array'
|
||||
}
|
||||
|
||||
export type UseField<TFormData> = <TField extends DeepKeys<TFormData>>(
|
||||
opts?: { name: Narrow<TField> } & UseFieldOptions<
|
||||
DeepValue<TFormData, TField>,
|
||||
@@ -30,25 +24,45 @@ export type UseField<TFormData> = <TField extends DeepKeys<TFormData>>(
|
||||
>,
|
||||
) => FieldApi<DeepValue<TFormData, TField>, TFormData>
|
||||
|
||||
export function useField<TData, TFormData>(
|
||||
opts: UseFieldOptions<TData, TFormData>,
|
||||
export function useField<
|
||||
TData,
|
||||
TFormData,
|
||||
TName extends unknown extends TFormData
|
||||
? string
|
||||
: DeepKeys<TFormData> = unknown extends TFormData
|
||||
? string
|
||||
: DeepKeys<TFormData>,
|
||||
>(
|
||||
opts: UseFieldOptions<TData, TFormData, TName>,
|
||||
): {
|
||||
api: FieldApi<TData, TFormData>
|
||||
state: Readonly<Ref<FieldApi<TData, TFormData>['state']>>
|
||||
api: FieldApi<
|
||||
TData,
|
||||
TFormData,
|
||||
Omit<typeof opts, 'onMount'> & {
|
||||
form: FormApi<TFormData>
|
||||
}
|
||||
>
|
||||
state: Readonly<
|
||||
Ref<
|
||||
FieldApi<
|
||||
TData,
|
||||
TFormData,
|
||||
Omit<typeof opts, 'onMount'> & {
|
||||
form: FormApi<TFormData>
|
||||
}
|
||||
>['state']
|
||||
>
|
||||
>
|
||||
} {
|
||||
// Get the form API either manually or from context
|
||||
const { formApi, parentFieldName } = useFormContext()
|
||||
|
||||
const fieldApi = (() => {
|
||||
const name = (
|
||||
typeof opts.index === 'number'
|
||||
? [parentFieldName, opts.index, opts.name]
|
||||
: [parentFieldName, opts.name]
|
||||
)
|
||||
.filter((d) => d !== undefined)
|
||||
.join('.')
|
||||
|
||||
const api = new FieldApi({ ...opts, form: formApi, name: name as never })
|
||||
const api = new FieldApi({
|
||||
...opts,
|
||||
form: formApi,
|
||||
name: opts.name,
|
||||
} as never)
|
||||
|
||||
api.Field = Field as never
|
||||
|
||||
@@ -77,56 +91,49 @@ export function useField<TData, TFormData>(
|
||||
return { api: fieldApi, state: fieldState } as never
|
||||
}
|
||||
|
||||
// export type FieldValue<TFormData, TField> = TFormData extends any[]
|
||||
// ? TField extends `[${infer TIndex extends number | 'i'}].${infer TRest}`
|
||||
// ? DeepValue<TFormData[TIndex extends 'i' ? number : TIndex], TRest>
|
||||
// : TField extends `[${infer TIndex extends number | 'i'}]`
|
||||
// ? TFormData[TIndex extends 'i' ? number : TIndex]
|
||||
// : never
|
||||
// : TField extends `${infer TPrefix}[${infer TIndex extends
|
||||
// | number
|
||||
// | 'i'}].${infer TRest}`
|
||||
// ? DeepValue<
|
||||
// DeepValue<TFormData, TPrefix>[TIndex extends 'i' ? number : TIndex],
|
||||
// TRest
|
||||
// >
|
||||
// : TField extends `${infer TPrefix}[${infer TIndex extends number | 'i'}]`
|
||||
// ? DeepValue<TFormData, TPrefix>[TIndex extends 'i' ? number : TIndex]
|
||||
// : DeepValue<TFormData, TField>
|
||||
|
||||
export type FieldValue<TFormData, TField> = TFormData extends any[]
|
||||
? unknown extends TField
|
||||
? TFormData[number]
|
||||
: DeepValue<TFormData[number], TField>
|
||||
: DeepValue<TFormData, TField>
|
||||
|
||||
// type Test1 = FieldValue<{ foo: { bar: string }[] }, 'foo'>
|
||||
// // ^?
|
||||
// type Test2 = FieldValue<{ foo: { bar: string }[] }, 'foo[i]'>
|
||||
// // ^?
|
||||
// type Test3 = FieldValue<{ foo: { bar: string }[] }, 'foo[2].bar'>
|
||||
// // ^?
|
||||
type FieldComponentProps<
|
||||
TParentData,
|
||||
TFormData,
|
||||
TField,
|
||||
TName extends unknown extends TFormData ? string : DeepKeys<TFormData>,
|
||||
> = (TParentData extends any[]
|
||||
? {
|
||||
name?: TName
|
||||
index: number
|
||||
}
|
||||
: {
|
||||
name: TName
|
||||
index?: never
|
||||
}) &
|
||||
Omit<UseFieldOptions<TField, TFormData, TName>, 'name' | 'index'>
|
||||
|
||||
export type FieldComponent<TParentData, TFormData> = <TField>(
|
||||
fieldOptions: Omit<
|
||||
UseFieldOptions<FieldValue<TParentData, TField>, TFormData>,
|
||||
'name' | 'index'
|
||||
> &
|
||||
(TParentData extends any[]
|
||||
? {
|
||||
name?: TField extends undefined ? TField : DeepKeys<TParentData>
|
||||
index: number
|
||||
}
|
||||
: {
|
||||
name: TField extends undefined ? TField : DeepKeys<TParentData>
|
||||
index?: never
|
||||
}),
|
||||
export type FieldComponent<TParentData, TFormData> = <
|
||||
// Type of the field
|
||||
TField,
|
||||
// Name of the field
|
||||
TName extends unknown extends TFormData ? string : DeepKeys<TFormData>,
|
||||
>(
|
||||
fieldOptions: FieldComponentProps<TParentData, TFormData, TField, TName>,
|
||||
context: SetupContext<
|
||||
{},
|
||||
SlotsType<{
|
||||
default: {
|
||||
field: FieldApi<FieldValue<TParentData, TField>, TFormData>
|
||||
state: FieldState<any>
|
||||
field: FieldApi<
|
||||
TField,
|
||||
TFormData,
|
||||
FieldApiOptions<TField, TFormData, TName>
|
||||
>
|
||||
state: FieldApi<
|
||||
TField,
|
||||
TFormData,
|
||||
FieldApiOptions<TField, TFormData, TName>
|
||||
>['state']
|
||||
}
|
||||
}>
|
||||
>,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { FormApi, type FormState, type FormOptions } from '@tanstack/form-core'
|
||||
import { useStore } from '@tanstack/vue-store'
|
||||
import { type NoInfer, useStore } from '@tanstack/vue-store'
|
||||
import { type UseField, type FieldComponent, Field, useField } from './useField'
|
||||
import { provideFormContext } from './formContext'
|
||||
import {
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
type SetupContext,
|
||||
defineComponent,
|
||||
} from 'vue-demi'
|
||||
import type { NoInfer } from './types'
|
||||
|
||||
declare module '@tanstack/form-core' {
|
||||
// eslint-disable-next-line no-shadow
|
||||
|
||||
420
pnpm-lock.yaml
generated
420
pnpm-lock.yaml
generated
@@ -237,9 +237,6 @@ importers:
|
||||
'@tanstack/react-form':
|
||||
specifier: workspace:*
|
||||
version: link:../../../packages/react-form
|
||||
'@tanstack/vue-form':
|
||||
specifier: workspace:*
|
||||
version: link:../../../packages/vue-form
|
||||
axios:
|
||||
specifier: ^0.26.1
|
||||
version: 0.26.1
|
||||
@@ -254,20 +251,17 @@ importers:
|
||||
version: 3.21.4
|
||||
devDependencies:
|
||||
'@vitejs/plugin-react':
|
||||
specifier: ^2.0.0
|
||||
version: 2.1.0(vite@3.1.3)
|
||||
specifier: ^4.0.4
|
||||
version: 4.0.4(vite@4.4.9)
|
||||
vite:
|
||||
specifier: ^3.0.0
|
||||
version: 3.1.3
|
||||
specifier: ^4.4.9
|
||||
version: 4.4.9(@types/node@17.0.45)
|
||||
|
||||
examples/vue/simple:
|
||||
dependencies:
|
||||
'@tanstack/form-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../../packages/form-core
|
||||
'@tanstack/react-form':
|
||||
specifier: workspace:*
|
||||
version: link:../../../packages/react-form
|
||||
'@tanstack/vue-form':
|
||||
specifier: workspace:*
|
||||
version: link:../../../packages/vue-form
|
||||
@@ -276,14 +270,17 @@ importers:
|
||||
version: 3.3.4
|
||||
devDependencies:
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^4.2.3
|
||||
specifier: ^4.3.4
|
||||
version: 4.3.4(vite@4.4.9)(vue@3.3.4)
|
||||
typescript:
|
||||
specifier: ^5.0.4
|
||||
version: 5.2.2
|
||||
vite:
|
||||
specifier: ^4.4.4
|
||||
specifier: ^4.4.9
|
||||
version: 4.4.9(@types/node@17.0.45)
|
||||
vue-tsc:
|
||||
specifier: ^1.8.10
|
||||
version: 1.8.10(typescript@5.2.2)
|
||||
|
||||
packages/form-core:
|
||||
dependencies:
|
||||
@@ -676,7 +673,7 @@ packages:
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@babel/types': 7.22.11
|
||||
'@babel/types': 7.22.15
|
||||
|
||||
/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.18.6(@babel/core@7.22.10):
|
||||
resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==}
|
||||
@@ -1328,6 +1325,17 @@ packages:
|
||||
dependencies:
|
||||
'@babel/core': 7.22.10
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
dev: false
|
||||
|
||||
/@babel/plugin-transform-react-jsx-self@7.22.5(@babel/core@7.22.10):
|
||||
resolution: {integrity: sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
'@babel/core': 7.22.10
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
dev: true
|
||||
|
||||
/@babel/plugin-transform-react-jsx-source@7.18.6(@babel/core@7.22.10):
|
||||
resolution: {integrity: sha512-utZmlASneDfdaMh0m/WausbjUjEdGrQJz0vFK93d7wD3xf5wBtX219+q6IlCNZeguIcxS2f/CvLZrlLSvSHQXw==}
|
||||
@@ -1337,19 +1345,16 @@ packages:
|
||||
dependencies:
|
||||
'@babel/core': 7.22.10
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
dev: false
|
||||
|
||||
/@babel/plugin-transform-react-jsx@7.19.0(@babel/core@7.22.10):
|
||||
resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==}
|
||||
/@babel/plugin-transform-react-jsx-source@7.22.5(@babel/core@7.22.10):
|
||||
resolution: {integrity: sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
'@babel/core': 7.22.10
|
||||
'@babel/helper-annotate-as-pure': 7.22.5
|
||||
'@babel/helper-module-imports': 7.22.5
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
'@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.10)
|
||||
'@babel/types': 7.22.15
|
||||
dev: true
|
||||
|
||||
/@babel/plugin-transform-react-jsx@7.22.5(@babel/core@7.22.10):
|
||||
@@ -1772,15 +1777,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/android-arm@0.15.18:
|
||||
resolution: {integrity: sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/android-arm@0.18.20:
|
||||
resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1862,15 +1858,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-loong64@0.15.18:
|
||||
resolution: {integrity: sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-loong64@0.18.20:
|
||||
resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -3151,20 +3138,17 @@ packages:
|
||||
eslint-visitor-keys: 3.4.3
|
||||
dev: true
|
||||
|
||||
/@vitejs/plugin-react@2.1.0(vite@3.1.3):
|
||||
resolution: {integrity: sha512-am6rPyyU3LzUYne3Gd9oj9c4Rzbq5hQnuGXSMT6Gujq45Il/+bunwq3lrB7wghLkiF45ygMwft37vgJ/NE8IAA==}
|
||||
/@vitejs/plugin-react@4.0.4(vite@4.4.9):
|
||||
resolution: {integrity: sha512-7wU921ABnNYkETiMaZy7XqpueMnpu5VxvVps13MjmCo+utBdD79sZzrApHawHtVX66cCJQQTXFcjH0y9dSUK8g==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
vite: ^3.0.0
|
||||
vite: ^4.2.0
|
||||
dependencies:
|
||||
'@babel/core': 7.22.10
|
||||
'@babel/plugin-transform-react-jsx': 7.19.0(@babel/core@7.22.10)
|
||||
'@babel/plugin-transform-react-jsx-development': 7.18.6(@babel/core@7.22.10)
|
||||
'@babel/plugin-transform-react-jsx-self': 7.18.6(@babel/core@7.22.10)
|
||||
'@babel/plugin-transform-react-jsx-source': 7.18.6(@babel/core@7.22.10)
|
||||
magic-string: 0.26.4
|
||||
'@babel/plugin-transform-react-jsx-self': 7.22.5(@babel/core@7.22.10)
|
||||
'@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.22.10)
|
||||
react-refresh: 0.14.0
|
||||
vite: 3.1.3
|
||||
vite: 4.4.9(@types/node@17.0.45)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@@ -3250,6 +3234,24 @@ packages:
|
||||
pretty-format: 29.6.3
|
||||
dev: true
|
||||
|
||||
/@volar/language-core@1.10.1:
|
||||
resolution: {integrity: sha512-JnsM1mIPdfGPxmoOcK1c7HYAsL6YOv0TCJ4aW3AXPZN/Jb4R77epDyMZIVudSGjWMbvv/JfUa+rQ+dGKTmgwBA==}
|
||||
dependencies:
|
||||
'@volar/source-map': 1.10.1
|
||||
dev: true
|
||||
|
||||
/@volar/source-map@1.10.1:
|
||||
resolution: {integrity: sha512-3/S6KQbqa7pGC8CxPrg69qHLpOvkiPHGJtWPkI/1AXCsktkJ6gIk/5z4hyuMp8Anvs6eS/Kvp/GZa3ut3votKA==}
|
||||
dependencies:
|
||||
muggle-string: 0.3.1
|
||||
dev: true
|
||||
|
||||
/@volar/typescript@1.10.1:
|
||||
resolution: {integrity: sha512-+iiO9yUSRHIYjlteT+QcdRq8b44qH19/eiUZtjNtuh6D9ailYM7DVR0zO2sEgJlvCaunw/CF9Ov2KooQBpR4VQ==}
|
||||
dependencies:
|
||||
'@volar/language-core': 1.10.1
|
||||
dev: true
|
||||
|
||||
/@vue/babel-helper-vue-transform-on@1.1.5:
|
||||
resolution: {integrity: sha512-SgUymFpMoAyWeYWLAY+MkCK3QEROsiUnfaw5zxOVD/M64KQs8D/4oK6Q5omVA2hnvEOE0SCkH2TZxs/jnnUj7w==}
|
||||
dev: true
|
||||
@@ -3322,6 +3324,25 @@ packages:
|
||||
dependencies:
|
||||
vue: 3.3.4
|
||||
|
||||
/@vue/language-core@1.8.10(typescript@5.2.2):
|
||||
resolution: {integrity: sha512-db8PtM4ZZr7SYNH30XpKxUYnUBYaTvcuJ4c2whKK04fuAjbtjAIZ2al5GzGEfUlesmvkpgdbiSviRXUxgD9Omw==}
|
||||
peerDependencies:
|
||||
typescript: '*'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@volar/language-core': 1.10.1
|
||||
'@volar/source-map': 1.10.1
|
||||
'@vue/compiler-dom': 3.3.4
|
||||
'@vue/reactivity': 3.3.4
|
||||
'@vue/shared': 3.3.4
|
||||
minimatch: 9.0.3
|
||||
muggle-string: 0.3.1
|
||||
typescript: 5.2.2
|
||||
vue-template-compiler: 2.7.14
|
||||
dev: true
|
||||
|
||||
/@vue/reactivity-transform@3.3.4:
|
||||
resolution: {integrity: sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==}
|
||||
dependencies:
|
||||
@@ -3375,6 +3396,15 @@ packages:
|
||||
vue-component-type-helpers: 1.8.4
|
||||
dev: true
|
||||
|
||||
/@vue/typescript@1.8.10(typescript@5.2.2):
|
||||
resolution: {integrity: sha512-vPSpTXMk4chYwvyTGjM891cKgnx2r6vtbdANOp2mRU31f4HYGyLrZBlGgiua7SaO2cLjUg8y91OipJe0t8OFhA==}
|
||||
dependencies:
|
||||
'@volar/typescript': 1.10.1
|
||||
'@vue/language-core': 1.8.10(typescript@5.2.2)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
dev: true
|
||||
|
||||
/@yarnpkg/lockfile@1.1.0:
|
||||
resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==}
|
||||
dev: true
|
||||
@@ -4558,6 +4588,10 @@ packages:
|
||||
resolution: {integrity: sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==}
|
||||
dev: false
|
||||
|
||||
/de-indent@1.0.2:
|
||||
resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
|
||||
dev: true
|
||||
|
||||
/debug@2.6.9:
|
||||
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
|
||||
peerDependencies:
|
||||
@@ -4972,221 +5006,11 @@ packages:
|
||||
is-symbol: 1.0.4
|
||||
dev: true
|
||||
|
||||
/esbuild-android-64@0.15.18:
|
||||
resolution: {integrity: sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-android-arm64@0.15.18:
|
||||
resolution: {integrity: sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-darwin-64@0.15.18:
|
||||
resolution: {integrity: sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-darwin-arm64@0.15.18:
|
||||
resolution: {integrity: sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-freebsd-64@0.15.18:
|
||||
resolution: {integrity: sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-freebsd-arm64@0.15.18:
|
||||
resolution: {integrity: sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-32@0.15.18:
|
||||
resolution: {integrity: sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ia32]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-64@0.15.18:
|
||||
resolution: {integrity: sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-arm64@0.15.18:
|
||||
resolution: {integrity: sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-arm@0.15.18:
|
||||
resolution: {integrity: sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-mips64le@0.15.18:
|
||||
resolution: {integrity: sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [mips64el]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-ppc64le@0.15.18:
|
||||
resolution: {integrity: sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-riscv64@0.15.18:
|
||||
resolution: {integrity: sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-s390x@0.15.18:
|
||||
resolution: {integrity: sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-netbsd-64@0.15.18:
|
||||
resolution: {integrity: sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [netbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-openbsd-64@0.15.18:
|
||||
resolution: {integrity: sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-plugin-file-path-extensions@1.0.0:
|
||||
resolution: {integrity: sha512-v5LpSkml+CbsC0+xAaETEGDECdvKp1wKkD4aXMdI4zLjXP0EYfK4GjGhphumt4N+kjR3A8Q+DIkpgxX1XTqO4Q==}
|
||||
engines: {node: '>=v14.0.0', npm: '>=7.0.0'}
|
||||
dev: true
|
||||
|
||||
/esbuild-sunos-64@0.15.18:
|
||||
resolution: {integrity: sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [sunos]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-32@0.15.18:
|
||||
resolution: {integrity: sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-64@0.15.18:
|
||||
resolution: {integrity: sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-arm64@0.15.18:
|
||||
resolution: {integrity: sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild@0.15.18:
|
||||
resolution: {integrity: sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==}
|
||||
engines: {node: '>=12'}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
optionalDependencies:
|
||||
'@esbuild/android-arm': 0.15.18
|
||||
'@esbuild/linux-loong64': 0.15.18
|
||||
esbuild-android-64: 0.15.18
|
||||
esbuild-android-arm64: 0.15.18
|
||||
esbuild-darwin-64: 0.15.18
|
||||
esbuild-darwin-arm64: 0.15.18
|
||||
esbuild-freebsd-64: 0.15.18
|
||||
esbuild-freebsd-arm64: 0.15.18
|
||||
esbuild-linux-32: 0.15.18
|
||||
esbuild-linux-64: 0.15.18
|
||||
esbuild-linux-arm: 0.15.18
|
||||
esbuild-linux-arm64: 0.15.18
|
||||
esbuild-linux-mips64le: 0.15.18
|
||||
esbuild-linux-ppc64le: 0.15.18
|
||||
esbuild-linux-riscv64: 0.15.18
|
||||
esbuild-linux-s390x: 0.15.18
|
||||
esbuild-netbsd-64: 0.15.18
|
||||
esbuild-openbsd-64: 0.15.18
|
||||
esbuild-sunos-64: 0.15.18
|
||||
esbuild-windows-32: 0.15.18
|
||||
esbuild-windows-64: 0.15.18
|
||||
esbuild-windows-arm64: 0.15.18
|
||||
dev: true
|
||||
|
||||
/esbuild@0.18.20:
|
||||
resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -6039,6 +5863,11 @@ packages:
|
||||
dependencies:
|
||||
function-bind: 1.1.1
|
||||
|
||||
/he@1.2.0:
|
||||
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/hermes-estree@0.12.0:
|
||||
resolution: {integrity: sha512-+e8xR6SCen0wyAKrMT3UD0ZCCLymKhRgjEB5sS28rKiFir/fXgLoeRilRUssFCILmGHb+OvHDUlhxs0+IEyvQw==}
|
||||
dev: false
|
||||
@@ -7094,13 +6923,6 @@ packages:
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/magic-string@0.26.4:
|
||||
resolution: {integrity: sha512-e5uXtVJ22aEpK9u1+eQf0fSxHeqwyV19K+uGnlROCxUhzwRip9tBsaMViK/0vC3viyPd5Gtucp3UmEp/Q2cPTQ==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
sourcemap-codec: 1.4.8
|
||||
dev: true
|
||||
|
||||
/magic-string@0.27.0:
|
||||
resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -7680,6 +7502,10 @@ packages:
|
||||
/ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
||||
/muggle-string@0.3.1:
|
||||
resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==}
|
||||
dev: true
|
||||
|
||||
/mz@2.7.0:
|
||||
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
|
||||
dependencies:
|
||||
@@ -8305,15 +8131,6 @@ packages:
|
||||
yaml: 2.3.1
|
||||
dev: true
|
||||
|
||||
/postcss@8.4.16:
|
||||
resolution: {integrity: sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
dependencies:
|
||||
nanoid: 3.3.6
|
||||
picocolors: 1.0.0
|
||||
source-map-js: 1.0.2
|
||||
dev: true
|
||||
|
||||
/postcss@8.4.28:
|
||||
resolution: {integrity: sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
@@ -8836,14 +8653,6 @@ packages:
|
||||
glob: 10.3.3
|
||||
dev: true
|
||||
|
||||
/rollup@2.78.1:
|
||||
resolution: {integrity: sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
hasBin: true
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
dev: true
|
||||
|
||||
/rollup@3.28.1:
|
||||
resolution: {integrity: sha512-R9OMQmIHJm9znrU3m3cpE8uhN0fGdXiawME7aZIpQqvpS/85+Vt1Hq1/yVIcYfOmaQiHjvXkQAoJukvLpau6Yw==}
|
||||
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
||||
@@ -9117,11 +8926,6 @@ packages:
|
||||
whatwg-url: 7.1.0
|
||||
dev: true
|
||||
|
||||
/sourcemap-codec@1.4.8:
|
||||
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
|
||||
deprecated: Please use @jridgewell/sourcemap-codec instead
|
||||
dev: true
|
||||
|
||||
/spawn-command@0.0.2:
|
||||
resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==}
|
||||
dev: true
|
||||
@@ -9944,33 +9748,6 @@ packages:
|
||||
- terser
|
||||
dev: true
|
||||
|
||||
/vite@3.1.3:
|
||||
resolution: {integrity: sha512-/3XWiktaopByM5bd8dqvHxRt5EEgRikevnnrpND0gRfNkrMrPaGGexhtLCzv15RcCMtV2CLw+BPas8YFeSG0KA==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
less: '*'
|
||||
sass: '*'
|
||||
stylus: '*'
|
||||
terser: ^5.4.0
|
||||
peerDependenciesMeta:
|
||||
less:
|
||||
optional: true
|
||||
sass:
|
||||
optional: true
|
||||
stylus:
|
||||
optional: true
|
||||
terser:
|
||||
optional: true
|
||||
dependencies:
|
||||
esbuild: 0.15.18
|
||||
postcss: 8.4.16
|
||||
resolve: 1.22.1
|
||||
rollup: 2.78.1
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
dev: true
|
||||
|
||||
/vite@4.4.9(@types/node@17.0.45):
|
||||
resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
@@ -10097,6 +9874,25 @@ packages:
|
||||
vue: 3.3.4
|
||||
dev: false
|
||||
|
||||
/vue-template-compiler@2.7.14:
|
||||
resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==}
|
||||
dependencies:
|
||||
de-indent: 1.0.2
|
||||
he: 1.2.0
|
||||
dev: true
|
||||
|
||||
/vue-tsc@1.8.10(typescript@5.2.2):
|
||||
resolution: {integrity: sha512-ptpTFFDoHQgkWJF7i5iERxooiQzOGtG1uKTfmAUuS3qPuSQGq+Ky/S8BFHhnFGwoOxq/PjmGN2QSZEfg1rtzQA==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
typescript: '*'
|
||||
dependencies:
|
||||
'@vue/language-core': 1.8.10(typescript@5.2.2)
|
||||
'@vue/typescript': 1.8.10(typescript@5.2.2)
|
||||
semver: 7.5.4
|
||||
typescript: 5.2.2
|
||||
dev: true
|
||||
|
||||
/vue@2.6.14:
|
||||
resolution: {integrity: sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==}
|
||||
dev: true
|
||||
|
||||
Reference in New Issue
Block a user