Merge pull request #3 from cupcakearmy/1

update deps
This commit is contained in:
Nicco 2023-03-03 23:47:16 +01:00 committed by GitHub
commit b3865cc243
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 589 additions and 364 deletions

19
.github/actions/build/action.yaml vendored Normal file
View File

@ -0,0 +1,19 @@
name: "Build"
description: "Build the project."
runs:
using: "composite" # This is the magic
steps:
- uses: pnpm/action-setup@v2
with:
version: 7
- uses: actions/setup-node@v3
with:
node-version: 18
cache: "pnpm"
registry-url: https://registry.npmjs.org/
- run: pnpm install --frozen-lockfile
shell: bash
- run: pnpm run build
shell: bash

View File

@ -23,16 +23,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: pnpm/action-setup@v2 - uses: ./.github/actions/build
with:
version: 7
- uses: actions/setup-node@v3
with:
node-version: 18
cache: "pnpm"
- run: pnpm install
- run: pnpm run build
- uses: actions/configure-pages@v3 - uses: actions/configure-pages@v3
- uses: actions/upload-pages-artifact@v1 - uses: actions/upload-pages-artifact@v1

18
.github/workflows/release.yaml vendored Normal file
View File

@ -0,0 +1,18 @@
name: Release
on:
push:
tags:
- "v*.*.*"
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/build
- run: pnpm test
- run: pnpm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@ -14,14 +14,5 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: pnpm/action-setup@v2 - uses: ./.github/actions/build
with:
version: 7
- uses: actions/setup-node@v3
with:
node-version: 18
cache: "pnpm"
- run: pnpm install --frozen-lockfile
- run: pnpm run compile
- run: pnpm run test - run: pnpm run test

View File

@ -1,9 +1,9 @@
![Logo](https://raw.githubusercontent.com/cupcakearmy/formhero/master/.github/Logo.jpg) ![Logo](https://raw.githubusercontent.com/cupcakearmy/formhero/master/.github/Logo.jpg)
![dependencies](https://badgen.net/david/dep/cupcakearmy/formhero)
![downloads badge](https://badgen.net/npm/dt/formhero)
![types badge](https://badgen.net/npm/types/formhero)
![version badge](https://badgen.net/npm/v/formhero) ![version badge](https://badgen.net/npm/v/formhero)
![types badge](https://badgen.net/npm/types/formhero)
![downloads badge](https://badgen.net/npm/dt/formhero)
![dependencies](https://badgen.net//bundlephobia/dependency-count/formhero)
![minzip size badge](https://badgen.net/bundlephobia/minzip/formhero) ![minzip size badge](https://badgen.net/bundlephobia/minzip/formhero)
**Fully customisable react form utility.** **Fully customisable react form utility.**
@ -22,7 +22,7 @@
npm i formhero npm i formhero
``` ```
*Note:* Requires at least typescript version `3.5`, otherwise the error object will not have the right inherited types. _Note:_ Requires at least typescript version `3.5`, otherwise the error object will not have the right inherited types.
### 👁 Demos ### 👁 Demos
@ -99,7 +99,7 @@ const Form = () => {
password: '', password: '',
}, },
{ {
username: value => value.length > 3, username: (value) => value.length > 3,
email: { email: {
validator: /@/, validator: /@/,
message: 'Must contain an @', message: 'Must contain an @',
@ -146,7 +146,7 @@ const Form = () => {
return ( return (
<form <form
onSubmit={e => { onSubmit={(e) => {
e.preventDefault() e.preventDefault()
console.log(form) console.log(form)
}} }}
@ -159,7 +159,7 @@ const Form = () => {
{...field('awesome', { {...field('awesome', {
setter: 'checked', setter: 'checked',
getter: 'onChange', getter: 'onChange',
extractor: e => e.target.checked, extractor: (e) => e.target.checked,
})} })}
/> />
Is it awesome? Is it awesome?
@ -176,28 +176,28 @@ const Form = () => {
Sometimes you don't know all the fields upfront. You can simply define a generic type and assign it to the initial object. Of course type assistance is limited in this case as formhero cannot be sure what keys are valid. Sometimes you don't know all the fields upfront. You can simply define a generic type and assign it to the initial object. Of course type assistance is limited in this case as formhero cannot be sure what keys are valid.
```typescript ```typescript
import React from "react"; import React from 'react'
import ReactDOM from "react-dom"; import ReactDOM from 'react-dom'
import { useForm } from "formhero"; import { useForm } from 'formhero'
type MyForm = { [field: string]: string | number }; type MyForm = { [field: string]: string | number }
const init: MyForm = { const init: MyForm = {
username: "unicorn", username: 'unicorn',
password: "" password: '',
}; }
const Form: React.FC = () => { const Form: React.FC = () => {
const { field, form, errors } = useForm(init); const { field, form, errors } = useForm(init)
return ( return (
<form> <form>
<input {...field("username")} placeholder="Username" /> <input {...field('username')} placeholder="Username" />
<input {...field("someother")} placeholder="Something else" /> <input {...field('someother')} placeholder="Something else" />
<input {...field("password")} placeholder="Password" type="password" /> <input {...field('password')} placeholder="Password" type="password" />
</form> </form>
); )
}; }
``` ```
## 📖 Documentation ## 📖 Documentation
@ -267,9 +267,9 @@ const validators = {
message: 'My custom error message', message: 'My custom error message',
}, },
/[\d]/, /[\d]/,
async value => value.length > 0, async (value) => value.length > 0,
{ {
validator: value => true, validator: (value) => true,
message: 'Some other error', message: 'Some other error',
}, },
], ],
@ -283,7 +283,7 @@ const validators = {
username: async (s: string) => { username: async (s: string) => {
const taken = await API.isUsernameTaken(s) const taken = await API.isUsernameTaken(s)
return taken ? 'Username is taken' : true return taken ? 'Username is taken' : true
} },
} }
``` ```
@ -307,7 +307,7 @@ const validators = {}
const options = { const options = {
setter: 'value', // This is not stricly necessarry as 'value' would already be the default. setter: 'value', // This is not stricly necessarry as 'value' would already be the default.
getter: 'onChangeText', getter: 'onChangeText',
extractor: text => text.toLowerCase(), extractor: (text) => text.toLowerCase(),
} }
export default () => { export default () => {
@ -339,7 +339,7 @@ export default () => {
{...field('username', { {...field('username', {
setter: 'value', // This is not stricly necessarry as 'value' would already be the default. setter: 'value', // This is not stricly necessarry as 'value' would already be the default.
getter: 'onChangeText', getter: 'onChangeText',
extractor: text => text.toLowerCase(), extractor: (text) => text.toLowerCase(),
})} })}
/> />
<Text>{form.username}</Text> <Text>{form.username}</Text>

View File

@ -1,60 +1,62 @@
import * as React from 'react' import * as React from 'react'
import { useEffect, useState } from 'react' import { useMemo, useState } from 'react'
export type FieldOptions<G extends string = 'onChange', S extends string = 'value'> = { // Possible future ideas
extractor?: useFormExtractor // TODO: Scroll to error field
getter: G // TODO: Focus on error field
setter: S
export type FieldOptions<G extends string = 'onChange', S extends string = 'value', T = any> = {
extractor?: useFormExtractor<T> | null
getter?: G
setter?: S
} }
type RuleFunctionReturn = boolean | string type RuleFunctionReturn = boolean | string
type RuleFunction<I> = (value: I) => RuleFunctionReturn | Promise<RuleFunctionReturn> type RuleFunction<I, F> = (value: I, data: F) => RuleFunctionReturn | Promise<RuleFunctionReturn>
type Rule<I> = RuleFunction<I> | RegExp type Rule<I, F> = RuleFunction<I, F> | RegExp
type RuleObject<I> = Rule<I> | { rule: Rule<I>; message: string } type RuleObject<I, F> = Rule<I, F> | { rule: Rule<I, F>; message: string }
type RuleSet<I> = RuleObject<I> | RuleObject<I>[] type RuleSet<I, F> = RuleObject<I, F> | RuleObject<I, F>[]
function isSimpleRule<I>(obj: RuleObject<I>): obj is Rule<I> { function isSimpleRule<I, F>(obj: RuleObject<I, F>): obj is Rule<I, F> {
return obj instanceof RegExp || typeof obj === 'function' return obj instanceof RegExp || typeof obj === 'function'
} }
export type useFormExtractor = (from: any) => any export type useFormExtractor<T = any> = (from: any) => T
export const NoExtractor: useFormExtractor = (v: unknown) => v
export const HTMLInputExtractor: useFormExtractor = (e: React.FormEvent<HTMLInputElement>) => e.currentTarget.value export const HTMLInputExtractor: useFormExtractor = (e: React.FormEvent<HTMLInputElement>) => e.currentTarget.value
export const HTMLCheckboxExtractor: useFormExtractor = (e: React.FormEvent<HTMLInputElement>) => e.currentTarget.checked export const HTMLCheckboxExtractor: useFormExtractor = (e: React.FormEvent<HTMLInputElement>) => e.currentTarget.checked
export type FormOptions<R> = { export type FormOptions<R> = {
rules: R rules: R
// fields: FieldOptions
} }
// Form = Type of form // F = Type of form
// R = Rules, derived from F // R = Rules, derived from F
// E = Errors, derived from F // E = Errors, derived from F
export const useForm = <Form extends object, R extends { [K in keyof Form]?: RuleSet<Form[K]> }, E extends { [key in keyof R]?: RuleFunctionReturn }>(init: Form, options?: FormOptions<R>) => { export const useForm = <F extends object, R extends { [K in keyof F]?: RuleSet<F[K], F> }, E extends { [key in keyof R]?: RuleFunctionReturn }>(init: F, options?: FormOptions<R>) => {
const validators: R = options?.rules ?? ({} as R) const validators: R = options?.rules ?? ({} as R)
const [form, setForm] = useState<Form>(init) const [form, setForm] = useState<F>(init)
const [errors, setErrors] = useState<E>({} as E) const [errors, setErrors] = useState<E>({} as E)
const [isValid, setIsValid] = useState<boolean>(true) const isValid = useMemo(() => {
return !Object.values(errors).reduce((acc, cur) => acc || cur !== undefined, false)
useEffect(() => {
setIsValid(!Object.values(errors).reduce((acc, cur) => acc || cur !== undefined, false))
}, [errors]) }, [errors])
const setField = <A extends keyof Form>(key: A, value: Form[A]) => { const setField = <A extends keyof F>(key: A, value: F[A]) => {
setForm({ setForm({
...form, ...form,
[key]: value, [key]: value,
}) })
} }
async function applyRule<I>(value: any, rule: Rule<I>): Promise<RuleFunctionReturn> { async function applyRule<I>(value: any, rule: Rule<I, F>): Promise<RuleFunctionReturn> {
if (typeof rule === 'function') return await rule(value) if (typeof rule === 'function') return await rule(value, form)
if (rule instanceof RegExp) return rule.test(value) if (rule instanceof RegExp) return rule.test(value)
throw new Error(`Unsupported validator: ${rule}`) throw new Error(`Unsupported validator: ${rule}`)
} }
async function validate<K extends keyof Form>(key: K, value: Form[K]) { async function validate<K extends keyof F>(key: K, value: F[K]) {
const set: RuleSet<Form[K]> | undefined = validators[key] as any const set: RuleSet<F[K], F> | undefined = validators[key] as any
if (!set) return if (!set) return
const rules = Array.isArray(set) ? set : [set] const rules = Array.isArray(set) ? set : [set]
@ -74,18 +76,19 @@ export const useForm = <Form extends object, R extends { [K in keyof Form]?: Rul
}) })
} }
function update<A extends keyof Form, RAW = any>(key: A, extractor?: (e: RAW) => Form[A]) { // Internal use
return (value: RAW) => { function update<A extends keyof F>(key: A, extractor?: useFormExtractor<F[A]> | null) {
const extracted = extractor ? extractor(value) : HTMLInputExtractor(value) return (value: any) => {
const extracted = extractor ? extractor(value) : extractor === undefined ? HTMLInputExtractor(value) : value
setField(key, extracted) setField(key, extracted)
validate(key, extracted) validate(key, extracted)
} }
} }
type FieldReturn<K extends keyof Form, G extends string, S extends string> = { [getter in G]: ReturnType<typeof update<K>> } & { [setter in S]: Form[K] } type FieldReturn<K extends keyof F, G extends string, S extends string> = { [getter in G]: ReturnType<typeof update<K>> } & { [setter in S]: F[K] }
function field<K extends keyof Form>(key: K): FieldReturn<K, 'onChange', 'value'> function field<K extends keyof F>(key: K): FieldReturn<K, 'onChange', 'value'>
function field<K extends keyof Form, G extends string, S extends string>(key: K, opts: FieldOptions<G, S>): FieldReturn<K, G, S> function field<K extends keyof F, G extends string, S extends string>(key: K, opts: FieldOptions<G, S, F[K]>): FieldReturn<K, G, S>
function field<K extends keyof Form, G extends string, S extends string>(key: K, opts?: FieldOptions<G, S>): FieldReturn<K, G, S> { function field<K extends keyof F, G extends string, S extends string>(key: K, opts?: FieldOptions<G, S, F[K]>): FieldReturn<K, G, S> {
return { return {
[opts?.getter || 'onChange']: update<K>(key, opts?.extractor), [opts?.getter || 'onChange']: update<K>(key, opts?.extractor),
[opts?.setter || 'value']: form[key], [opts?.setter || 'value']: form[key],

View File

@ -1,9 +1,12 @@
{ {
"name": "formhero", "name": "formhero",
"version": "0.1.0", "version": "1.0.0-rc.0",
"type": "module", "type": "module",
"module": "./dist/index.js", "module": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
"files": [
"dist"
],
"scripts": { "scripts": {
"clean": "rm -rf ./dist", "clean": "rm -rf ./dist",
"prepublishOnly": "run-s clean build test", "prepublishOnly": "run-s clean build test",
@ -21,16 +24,16 @@
}, },
"devDependencies": { "devDependencies": {
"@testing-library/react": "^13.4.0", "@testing-library/react": "^13.4.0",
"@types/react": "^18.0.27", "@types/react": "^18.0.28",
"@types/react-dom": "^18.0.10", "@types/react-dom": "^18.0.11",
"@vitejs/plugin-react": "^3.1.0", "@vitejs/plugin-react": "^3.1.0",
"@vitest/coverage-c8": "^0.28.4", "@vitest/coverage-c8": "^0.29.2",
"happy-dom": "^8.2.6", "happy-dom": "^8.9.0",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"typescript": "^4.9.5", "typescript": "^4.9.5",
"vite": "^4.1.1", "vite": "^4.1.4",
"vitest": "^0.28.4" "vitest": "^0.29.2"
} }
} }

365
pnpm-lock.yaml generated
View File

@ -2,31 +2,31 @@ lockfileVersion: 5.4
specifiers: specifiers:
'@testing-library/react': ^13.4.0 '@testing-library/react': ^13.4.0
'@types/react': ^18.0.27 '@types/react': ^18.0.28
'@types/react-dom': ^18.0.10 '@types/react-dom': ^18.0.11
'@vitejs/plugin-react': ^3.1.0 '@vitejs/plugin-react': ^3.1.0
'@vitest/coverage-c8': ^0.28.4 '@vitest/coverage-c8': ^0.29.2
happy-dom: ^8.2.6 happy-dom: ^8.9.0
npm-run-all: ^4.1.5 npm-run-all: ^4.1.5
react: ^18.2.0 react: ^18.2.0
react-dom: ^18.2.0 react-dom: ^18.2.0
typescript: ^4.9.5 typescript: ^4.9.5
vite: ^4.1.1 vite: ^4.1.4
vitest: ^0.28.4 vitest: ^0.29.2
devDependencies: devDependencies:
'@testing-library/react': 13.4.0_biqbaboplfbrettd7655fr4n2y '@testing-library/react': 13.4.0_biqbaboplfbrettd7655fr4n2y
'@types/react': 18.0.27 '@types/react': 18.0.28
'@types/react-dom': 18.0.10 '@types/react-dom': 18.0.11
'@vitejs/plugin-react': 3.1.0_vite@4.1.1 '@vitejs/plugin-react': 3.1.0_vite@4.1.4
'@vitest/coverage-c8': 0.28.4_happy-dom@8.2.6 '@vitest/coverage-c8': 0.29.2_vitest@0.29.2
happy-dom: 8.2.6 happy-dom: 8.9.0
npm-run-all: 4.1.5 npm-run-all: 4.1.5
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0
typescript: 4.9.5 typescript: 4.9.5
vite: 4.1.1 vite: 4.1.4
vitest: 0.28.4_happy-dom@8.2.6 vitest: 0.29.2_happy-dom@8.9.0
packages: packages:
@ -45,25 +45,25 @@ packages:
'@babel/highlight': 7.18.6 '@babel/highlight': 7.18.6
dev: true dev: true
/@babel/compat-data/7.20.14: /@babel/compat-data/7.21.0:
resolution: {integrity: sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==} resolution: {integrity: sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dev: true dev: true
/@babel/core/7.20.12: /@babel/core/7.21.0:
resolution: {integrity: sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==} resolution: {integrity: sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@ampproject/remapping': 2.2.0 '@ampproject/remapping': 2.2.0
'@babel/code-frame': 7.18.6 '@babel/code-frame': 7.18.6
'@babel/generator': 7.20.14 '@babel/generator': 7.21.1
'@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.12 '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.0
'@babel/helper-module-transforms': 7.20.11 '@babel/helper-module-transforms': 7.21.2
'@babel/helpers': 7.20.13 '@babel/helpers': 7.21.0
'@babel/parser': 7.20.15 '@babel/parser': 7.21.2
'@babel/template': 7.20.7 '@babel/template': 7.20.7
'@babel/traverse': 7.20.13 '@babel/traverse': 7.21.2
'@babel/types': 7.20.7 '@babel/types': 7.21.2
convert-source-map: 1.9.0 convert-source-map: 1.9.0
debug: 4.3.4 debug: 4.3.4
gensync: 1.0.0-beta.2 gensync: 1.0.0-beta.2
@ -73,24 +73,25 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@babel/generator/7.20.14: /@babel/generator/7.21.1:
resolution: {integrity: sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==} resolution: {integrity: sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.20.7 '@babel/types': 7.21.2
'@jridgewell/gen-mapping': 0.3.2 '@jridgewell/gen-mapping': 0.3.2
'@jridgewell/trace-mapping': 0.3.17
jsesc: 2.5.2 jsesc: 2.5.2
dev: true dev: true
/@babel/helper-compilation-targets/7.20.7_@babel+core@7.20.12: /@babel/helper-compilation-targets/7.20.7_@babel+core@7.21.0:
resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==} resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0 '@babel/core': ^7.0.0
dependencies: dependencies:
'@babel/compat-data': 7.20.14 '@babel/compat-data': 7.21.0
'@babel/core': 7.20.12 '@babel/core': 7.21.0
'@babel/helper-validator-option': 7.18.6 '@babel/helper-validator-option': 7.21.0
browserslist: 4.21.5 browserslist: 4.21.5
lru-cache: 5.1.1 lru-cache: 5.1.1
semver: 6.3.0 semver: 6.3.0
@ -101,30 +102,30 @@ packages:
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dev: true dev: true
/@babel/helper-function-name/7.19.0: /@babel/helper-function-name/7.21.0:
resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/template': 7.20.7 '@babel/template': 7.20.7
'@babel/types': 7.20.7 '@babel/types': 7.21.2
dev: true dev: true
/@babel/helper-hoist-variables/7.18.6: /@babel/helper-hoist-variables/7.18.6:
resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.20.7 '@babel/types': 7.21.2
dev: true dev: true
/@babel/helper-module-imports/7.18.6: /@babel/helper-module-imports/7.18.6:
resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.20.7 '@babel/types': 7.21.2
dev: true dev: true
/@babel/helper-module-transforms/7.20.11: /@babel/helper-module-transforms/7.21.2:
resolution: {integrity: sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==} resolution: {integrity: sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/helper-environment-visitor': 7.18.9 '@babel/helper-environment-visitor': 7.18.9
@ -133,8 +134,8 @@ packages:
'@babel/helper-split-export-declaration': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6
'@babel/helper-validator-identifier': 7.19.1 '@babel/helper-validator-identifier': 7.19.1
'@babel/template': 7.20.7 '@babel/template': 7.20.7
'@babel/traverse': 7.20.13 '@babel/traverse': 7.21.2
'@babel/types': 7.20.7 '@babel/types': 7.21.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
@ -148,14 +149,14 @@ packages:
resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.20.7 '@babel/types': 7.21.2
dev: true dev: true
/@babel/helper-split-export-declaration/7.18.6: /@babel/helper-split-export-declaration/7.18.6:
resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.20.7 '@babel/types': 7.21.2
dev: true dev: true
/@babel/helper-string-parser/7.19.4: /@babel/helper-string-parser/7.19.4:
@ -168,18 +169,18 @@ packages:
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dev: true dev: true
/@babel/helper-validator-option/7.18.6: /@babel/helper-validator-option/7.21.0:
resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dev: true dev: true
/@babel/helpers/7.20.13: /@babel/helpers/7.21.0:
resolution: {integrity: sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==} resolution: {integrity: sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/template': 7.20.7 '@babel/template': 7.20.7
'@babel/traverse': 7.20.13 '@babel/traverse': 7.21.2
'@babel/types': 7.20.7 '@babel/types': 7.21.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
@ -193,36 +194,36 @@ packages:
js-tokens: 4.0.0 js-tokens: 4.0.0
dev: true dev: true
/@babel/parser/7.20.15: /@babel/parser/7.21.2:
resolution: {integrity: sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==} resolution: {integrity: sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==}
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
hasBin: true hasBin: true
dependencies: dependencies:
'@babel/types': 7.20.7 '@babel/types': 7.21.2
dev: true dev: true
/@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.20.12: /@babel/plugin-transform-react-jsx-self/7.21.0_@babel+core@7.21.0:
resolution: {integrity: sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==} resolution: {integrity: sha512-f/Eq+79JEu+KUANFks9UZCcvydOOGMgF7jBrcwjHa5jTZD8JivnhCJYvmlhR/WTXBWonDExPoW0eO/CR4QJirA==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0-0 '@babel/core': ^7.0.0-0
dependencies: dependencies:
'@babel/core': 7.20.12 '@babel/core': 7.21.0
'@babel/helper-plugin-utils': 7.20.2 '@babel/helper-plugin-utils': 7.20.2
dev: true dev: true
/@babel/plugin-transform-react-jsx-source/7.19.6_@babel+core@7.20.12: /@babel/plugin-transform-react-jsx-source/7.19.6_@babel+core@7.21.0:
resolution: {integrity: sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==} resolution: {integrity: sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0-0 '@babel/core': ^7.0.0-0
dependencies: dependencies:
'@babel/core': 7.20.12 '@babel/core': 7.21.0
'@babel/helper-plugin-utils': 7.20.2 '@babel/helper-plugin-utils': 7.20.2
dev: true dev: true
/@babel/runtime/7.20.13: /@babel/runtime/7.21.0:
resolution: {integrity: sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==} resolution: {integrity: sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
regenerator-runtime: 0.13.11 regenerator-runtime: 0.13.11
@ -233,30 +234,30 @@ packages:
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/code-frame': 7.18.6 '@babel/code-frame': 7.18.6
'@babel/parser': 7.20.15 '@babel/parser': 7.21.2
'@babel/types': 7.20.7 '@babel/types': 7.21.2
dev: true dev: true
/@babel/traverse/7.20.13: /@babel/traverse/7.21.2:
resolution: {integrity: sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==} resolution: {integrity: sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/code-frame': 7.18.6 '@babel/code-frame': 7.18.6
'@babel/generator': 7.20.14 '@babel/generator': 7.21.1
'@babel/helper-environment-visitor': 7.18.9 '@babel/helper-environment-visitor': 7.18.9
'@babel/helper-function-name': 7.19.0 '@babel/helper-function-name': 7.21.0
'@babel/helper-hoist-variables': 7.18.6 '@babel/helper-hoist-variables': 7.18.6
'@babel/helper-split-export-declaration': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6
'@babel/parser': 7.20.15 '@babel/parser': 7.21.2
'@babel/types': 7.20.7 '@babel/types': 7.21.2
debug: 4.3.4 debug: 4.3.4
globals: 11.12.0 globals: 11.12.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
/@babel/types/7.20.7: /@babel/types/7.21.2:
resolution: {integrity: sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==} resolution: {integrity: sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/helper-string-parser': 7.19.4 '@babel/helper-string-parser': 7.19.4
@ -514,7 +515,7 @@ packages:
engines: {node: '>=12'} engines: {node: '>=12'}
dependencies: dependencies:
'@babel/code-frame': 7.18.6 '@babel/code-frame': 7.18.6
'@babel/runtime': 7.20.13 '@babel/runtime': 7.21.0
'@types/aria-query': 5.0.1 '@types/aria-query': 5.0.1
aria-query: 5.1.3 aria-query: 5.1.3
chalk: 4.1.2 chalk: 4.1.2
@ -530,9 +531,9 @@ packages:
react: ^18.0.0 react: ^18.0.0
react-dom: ^18.0.0 react-dom: ^18.0.0
dependencies: dependencies:
'@babel/runtime': 7.20.13 '@babel/runtime': 7.21.0
'@testing-library/dom': 8.20.0 '@testing-library/dom': 8.20.0
'@types/react-dom': 18.0.10 '@types/react-dom': 18.0.11
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0
dev: true dev: true
@ -555,22 +556,22 @@ packages:
resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==}
dev: true dev: true
/@types/node/18.11.19: /@types/node/18.14.5:
resolution: {integrity: sha512-YUgMWAQBWLObABqrvx8qKO1enAvBUdjZOAWQ5grBAkp5LQv45jBvYKZ3oFS9iKRCQyFjqw6iuEa1vmFqtxYLZw==} resolution: {integrity: sha512-CRT4tMK/DHYhw1fcCEBwME9CSaZNclxfzVMe7GsO6ULSwsttbj70wSiX6rZdIjGblu93sTJxLdhNIT85KKI7Qw==}
dev: true dev: true
/@types/prop-types/15.7.5: /@types/prop-types/15.7.5:
resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
dev: true dev: true
/@types/react-dom/18.0.10: /@types/react-dom/18.0.11:
resolution: {integrity: sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==} resolution: {integrity: sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==}
dependencies: dependencies:
'@types/react': 18.0.27 '@types/react': 18.0.28
dev: true dev: true
/@types/react/18.0.27: /@types/react/18.0.28:
resolution: {integrity: sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==} resolution: {integrity: sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==}
dependencies: dependencies:
'@types/prop-types': 15.7.5 '@types/prop-types': 15.7.5
'@types/scheduler': 0.16.2 '@types/scheduler': 0.16.2
@ -581,67 +582,57 @@ packages:
resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==}
dev: true dev: true
/@vitejs/plugin-react/3.1.0_vite@4.1.1: /@vitejs/plugin-react/3.1.0_vite@4.1.4:
resolution: {integrity: sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==} resolution: {integrity: sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies: peerDependencies:
vite: ^4.1.0-beta.0 vite: ^4.1.0-beta.0
dependencies: dependencies:
'@babel/core': 7.20.12 '@babel/core': 7.21.0
'@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.20.12 '@babel/plugin-transform-react-jsx-self': 7.21.0_@babel+core@7.21.0
'@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.20.12 '@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.21.0
magic-string: 0.27.0 magic-string: 0.27.0
react-refresh: 0.14.0 react-refresh: 0.14.0
vite: 4.1.1 vite: 4.1.4
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
/@vitest/coverage-c8/0.28.4_happy-dom@8.2.6: /@vitest/coverage-c8/0.29.2_vitest@0.29.2:
resolution: {integrity: sha512-btelLBxaWhHnywXRQxDlrvPhGdnuIaD3XulsxcZRIcnpLPbFu39dNTT0IYu2QWP2ZZrV0AmNtdLIfD4c77zMAg==} resolution: {integrity: sha512-NmD3WirQCeQjjKfHu4iEq18DVOBFbLn9TKVdMpyi5YW2EtnS+K22/WE+9/wRrepOhyeTxuEFgxUVkCAE1GhbnQ==}
peerDependencies:
vitest: '>=0.29.0 <1'
dependencies: dependencies:
c8: 7.12.0 c8: 7.13.0
picocolors: 1.0.0 picocolors: 1.0.0
std-env: 3.3.2 std-env: 3.3.2
vitest: 0.28.4_happy-dom@8.2.6 vitest: 0.29.2_happy-dom@8.9.0
transitivePeerDependencies:
- '@edge-runtime/vm'
- '@vitest/browser'
- '@vitest/ui'
- happy-dom
- jsdom
- less
- sass
- stylus
- sugarss
- supports-color
- terser
dev: true dev: true
/@vitest/expect/0.28.4: /@vitest/expect/0.29.2:
resolution: {integrity: sha512-JqK0NZ4brjvOSL8hXAnIsfi+jxDF7rH/ZWCGCt0FAqRnVFc1hXsfwXksQvEnKqD84avRt3gmeXoK4tNbmkoVsQ==} resolution: {integrity: sha512-wjrdHB2ANTch3XKRhjWZN0UueFocH0cQbi2tR5Jtq60Nb3YOSmakjdAvUa2JFBu/o8Vjhj5cYbcMXkZxn1NzmA==}
dependencies: dependencies:
'@vitest/spy': 0.28.4 '@vitest/spy': 0.29.2
'@vitest/utils': 0.28.4 '@vitest/utils': 0.29.2
chai: 4.3.7 chai: 4.3.7
dev: true dev: true
/@vitest/runner/0.28.4: /@vitest/runner/0.29.2:
resolution: {integrity: sha512-Q8UV6GjDvBSTfUoq0QXVCNpNOUrWu4P2qvRq7ssJWzn0+S0ojbVOxEjMt+8a32X6SdkhF8ak+2nkppsqV0JyNQ==} resolution: {integrity: sha512-A1P65f5+6ru36AyHWORhuQBJrOOcmDuhzl5RsaMNFe2jEkoj0faEszQS4CtPU/LxUYVIazlUtZTY0OEZmyZBnA==}
dependencies: dependencies:
'@vitest/utils': 0.28.4 '@vitest/utils': 0.29.2
p-limit: 4.0.0 p-limit: 4.0.0
pathe: 1.1.0 pathe: 1.1.0
dev: true dev: true
/@vitest/spy/0.28.4: /@vitest/spy/0.29.2:
resolution: {integrity: sha512-8WuhfXLlvCXpNXEGJW6Gc+IKWI32435fQJLh43u70HnZ1otJOa2Cmg2Wy2Aym47ZnNCP4NolF+8cUPwd0MigKQ==} resolution: {integrity: sha512-Hc44ft5kaAytlGL2PyFwdAsufjbdOvHklwjNy/gy/saRbg9Kfkxfh+PklLm1H2Ib/p586RkQeNFKYuJInUssyw==}
dependencies: dependencies:
tinyspy: 1.0.2 tinyspy: 1.1.1
dev: true dev: true
/@vitest/utils/0.28.4: /@vitest/utils/0.29.2:
resolution: {integrity: sha512-l2QztOLdc2LkR+w/lP52RGh8hW+Ul4KESmCAgVE8q737I7e7bQoAfkARKpkPJ4JQtGpwW4deqlj1732VZD7TFw==} resolution: {integrity: sha512-F14/Uc+vCdclStS2KEoXJlOLAEyqRhnw0gM27iXw9bMTcyKRPJrQ+rlC6XZ125GIPvvKYMPpVxNhiou6PsEeYQ==}
dependencies: dependencies:
cli-truncate: 3.1.0 cli-truncate: 3.1.0
diff: 5.1.0 diff: 5.1.0
@ -726,18 +717,14 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true hasBin: true
dependencies: dependencies:
caniuse-lite: 1.0.30001450 caniuse-lite: 1.0.30001460
electron-to-chromium: 1.4.286 electron-to-chromium: 1.4.319
node-releases: 2.0.9 node-releases: 2.0.10
update-browserslist-db: 1.0.10_browserslist@4.21.5 update-browserslist-db: 1.0.10_browserslist@4.21.5
dev: true dev: true
/buffer-from/1.1.2: /c8/7.13.0:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} resolution: {integrity: sha512-/NL4hQTv1gBL6J6ei80zu3IiTrmePDKXKXOTLpHvcIWZTVYQlDhVWjjWvkhICylE8EwwnMVzDZugCvdx0/DIIA==}
dev: true
/c8/7.12.0:
resolution: {integrity: sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A==}
engines: {node: '>=10.12.0'} engines: {node: '>=10.12.0'}
hasBin: true hasBin: true
dependencies: dependencies:
@ -750,7 +737,7 @@ packages:
istanbul-reports: 3.1.5 istanbul-reports: 3.1.5
rimraf: 3.0.2 rimraf: 3.0.2
test-exclude: 6.0.0 test-exclude: 6.0.0
v8-to-istanbul: 9.0.1 v8-to-istanbul: 9.1.0
yargs: 16.2.0 yargs: 16.2.0
yargs-parser: 20.2.9 yargs-parser: 20.2.9
dev: true dev: true
@ -767,8 +754,8 @@ packages:
get-intrinsic: 1.2.0 get-intrinsic: 1.2.0
dev: true dev: true
/caniuse-lite/1.0.30001450: /caniuse-lite/1.0.30001460:
resolution: {integrity: sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==} resolution: {integrity: sha512-Bud7abqjvEjipUkpLs4D7gR0l8hBYBHoa+tGtKJHvT2AYzLp1z7EmVkUT4ERpVUfca8S2HGIVs883D8pUH1ZzQ==}
dev: true dev: true
/chai/4.3.7: /chai/4.3.7:
@ -904,7 +891,7 @@ packages:
es-get-iterator: 1.1.3 es-get-iterator: 1.1.3
get-intrinsic: 1.2.0 get-intrinsic: 1.2.0
is-arguments: 1.1.1 is-arguments: 1.1.1
is-array-buffer: 3.0.1 is-array-buffer: 3.0.2
is-date-object: 1.0.5 is-date-object: 1.0.5
is-regex: 1.1.4 is-regex: 1.1.4
is-shared-array-buffer: 1.0.2 is-shared-array-buffer: 1.0.2
@ -919,8 +906,8 @@ packages:
which-typed-array: 1.1.9 which-typed-array: 1.1.9
dev: true dev: true
/define-properties/1.1.4: /define-properties/1.2.0:
resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
dependencies: dependencies:
has-property-descriptors: 1.0.0 has-property-descriptors: 1.0.0
@ -940,8 +927,8 @@ packages:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
dev: true dev: true
/electron-to-chromium/1.4.286: /electron-to-chromium/1.4.319:
resolution: {integrity: sha512-Vp3CVhmYpgf4iXNKAucoQUDcCrBQX3XLBtwgFqP9BUXuucgvAV9zWp1kYU7LL9j4++s9O+12cb3wMtN4SJy6UQ==} resolution: {integrity: sha512-WeoI6NwZUgteKB+Wmn692S35QycwwNxwgTomNnoCJ79znBAjtBi6C/cIW62JkXmpJRX5rKNYSLDBdAM8l5fH0w==}
dev: true dev: true
/emoji-regex/8.0.0: /emoji-regex/8.0.0:
@ -976,8 +963,8 @@ packages:
has-property-descriptors: 1.0.0 has-property-descriptors: 1.0.0
has-proto: 1.0.1 has-proto: 1.0.1
has-symbols: 1.0.3 has-symbols: 1.0.3
internal-slot: 1.0.4 internal-slot: 1.0.5
is-array-buffer: 3.0.1 is-array-buffer: 3.0.2
is-callable: 1.2.7 is-callable: 1.2.7
is-negative-zero: 2.0.2 is-negative-zero: 2.0.2
is-regex: 1.1.4 is-regex: 1.1.4
@ -1112,7 +1099,7 @@ packages:
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
dependencies: dependencies:
call-bind: 1.0.2 call-bind: 1.0.2
define-properties: 1.1.4 define-properties: 1.2.0
es-abstract: 1.21.1 es-abstract: 1.21.1
functions-have-names: 1.2.3 functions-have-names: 1.2.3
dev: true dev: true
@ -1171,7 +1158,7 @@ packages:
resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
dependencies: dependencies:
define-properties: 1.1.4 define-properties: 1.2.0
dev: true dev: true
/gopd/1.0.1: /gopd/1.0.1:
@ -1184,11 +1171,12 @@ packages:
resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
dev: true dev: true
/happy-dom/8.2.6: /happy-dom/8.9.0:
resolution: {integrity: sha512-s53VwyMFpQPEZdN00M82i3tFTzz0T4kBVD4tu8b+im99s1NkLK6tfKGCCl2Jmf3ZWfFCRwS+DV2qkR7S1wmIhQ==} resolution: {integrity: sha512-JZwJuGdR7ko8L61136YzmrLv7LgTh5b8XaEM3P709mLjyQuXJ3zHTDXvUtBBahRjGlcYW0zGjIiEWizoTUGKfA==}
dependencies: dependencies:
css.escape: 1.5.1 css.escape: 1.5.1
he: 1.2.0 he: 1.2.0
iconv-lite: 0.6.3
node-fetch: 2.6.9 node-fetch: 2.6.9
webidl-conversions: 7.0.0 webidl-conversions: 7.0.0
whatwg-encoding: 2.0.0 whatwg-encoding: 2.0.0
@ -1272,8 +1260,8 @@ packages:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
dev: true dev: true
/internal-slot/1.0.4: /internal-slot/1.0.5:
resolution: {integrity: sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==} resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
dependencies: dependencies:
get-intrinsic: 1.2.0 get-intrinsic: 1.2.0
@ -1289,8 +1277,8 @@ packages:
has-tostringtag: 1.0.0 has-tostringtag: 1.0.0
dev: true dev: true
/is-array-buffer/3.0.1: /is-array-buffer/3.0.2:
resolution: {integrity: sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==} resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==}
dependencies: dependencies:
call-bind: 1.0.2 call-bind: 1.0.2
get-intrinsic: 1.2.0 get-intrinsic: 1.2.0
@ -1544,13 +1532,13 @@ packages:
brace-expansion: 1.1.11 brace-expansion: 1.1.11
dev: true dev: true
/mlly/1.1.0: /mlly/1.1.1:
resolution: {integrity: sha512-cwzBrBfwGC1gYJyfcy8TcZU1f+dbH/T+TuOhtYP2wLv/Fb51/uV7HJQfBPtEupZ2ORLRU1EKFS/QfS3eo9+kBQ==} resolution: {integrity: sha512-Jnlh4W/aI4GySPo6+DyTN17Q75KKbLTyFK8BrGhjNP4rxuUjbRWhE6gHg3bs33URWAF44FRm7gdQA348i3XxRw==}
dependencies: dependencies:
acorn: 8.8.2 acorn: 8.8.2
pathe: 1.1.0 pathe: 1.1.0
pkg-types: 1.0.1 pkg-types: 1.0.2
ufo: 1.0.1 ufo: 1.1.1
dev: true dev: true
/ms/2.1.2: /ms/2.1.2:
@ -1579,8 +1567,8 @@ packages:
whatwg-url: 5.0.0 whatwg-url: 5.0.0
dev: true dev: true
/node-releases/2.0.9: /node-releases/2.0.10:
resolution: {integrity: sha512-2xfmOrRkGogbTK9R6Leda0DGiXeY3p2NJpy4+gNCffdUvV6mdEJnaDEic1i3Ec2djAo8jWYoJMR5PB0MSMpxUA==} resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==}
dev: true dev: true
/normalize-package-data/2.5.0: /normalize-package-data/2.5.0:
@ -1617,7 +1605,7 @@ packages:
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
dependencies: dependencies:
call-bind: 1.0.2 call-bind: 1.0.2
define-properties: 1.1.4 define-properties: 1.2.0
dev: true dev: true
/object-keys/1.1.1: /object-keys/1.1.1:
@ -1630,7 +1618,7 @@ packages:
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
dependencies: dependencies:
call-bind: 1.0.2 call-bind: 1.0.2
define-properties: 1.1.4 define-properties: 1.2.0
has-symbols: 1.0.3 has-symbols: 1.0.3
object-keys: 1.1.1 object-keys: 1.1.1
dev: true dev: true
@ -1724,11 +1712,11 @@ packages:
engines: {node: '>=4'} engines: {node: '>=4'}
dev: true dev: true
/pkg-types/1.0.1: /pkg-types/1.0.2:
resolution: {integrity: sha512-jHv9HB+Ho7dj6ItwppRDDl0iZRYBD0jsakHXtFgoLr+cHSF6xC+QL54sJmWxyGxOLYSHm0afhXhXcQDQqH9z8g==} resolution: {integrity: sha512-hM58GKXOcj8WTqUXnsQyJYXdeAPbythQgEF3nTcEo+nkD49chjQ9IKm/QJy9xf6JakXptz86h7ecP2024rrLaQ==}
dependencies: dependencies:
jsonc-parser: 3.2.0 jsonc-parser: 3.2.0
mlly: 1.1.0 mlly: 1.1.1
pathe: 1.1.0 pathe: 1.1.0
dev: true dev: true
@ -1794,7 +1782,7 @@ packages:
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
dependencies: dependencies:
call-bind: 1.0.2 call-bind: 1.0.2
define-properties: 1.1.4 define-properties: 1.2.0
functions-have-names: 1.2.3 functions-have-names: 1.2.3
dev: true dev: true
@ -1819,8 +1807,8 @@ packages:
glob: 7.2.3 glob: 7.2.3
dev: true dev: true
/rollup/3.14.0: /rollup/3.18.0:
resolution: {integrity: sha512-o23sdgCLcLSe3zIplT9nQ1+r97okuaiR+vmAPZPTDYB7/f3tgWIYNyiQveMsZwshBT0is4eGax/HH83Q7CG+/Q==} resolution: {integrity: sha512-J8C6VfEBjkvYPESMQYxKHxNOh4A5a3FlP+0BETGo34HEcE4eTlgCrO2+eWzlu2a/sHs2QUkZco+wscH7jhhgWg==}
engines: {node: '>=14.18.0', npm: '>=8.0.0'} engines: {node: '>=14.18.0', npm: '>=8.0.0'}
hasBin: true hasBin: true
optionalDependencies: optionalDependencies:
@ -1912,13 +1900,6 @@ packages:
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/source-map-support/0.5.21:
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
dependencies:
buffer-from: 1.1.2
source-map: 0.6.1
dev: true
/source-map/0.6.1: /source-map/0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -1958,7 +1939,7 @@ packages:
resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
dependencies: dependencies:
internal-slot: 1.0.4 internal-slot: 1.0.5
dev: true dev: true
/string-width/4.2.3: /string-width/4.2.3:
@ -1984,7 +1965,7 @@ packages:
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
dependencies: dependencies:
call-bind: 1.0.2 call-bind: 1.0.2
define-properties: 1.1.4 define-properties: 1.2.0
es-abstract: 1.21.1 es-abstract: 1.21.1
dev: true dev: true
@ -1992,7 +1973,7 @@ packages:
resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==}
dependencies: dependencies:
call-bind: 1.0.2 call-bind: 1.0.2
define-properties: 1.1.4 define-properties: 1.2.0
es-abstract: 1.21.1 es-abstract: 1.21.1
dev: true dev: true
@ -2000,7 +1981,7 @@ packages:
resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==}
dependencies: dependencies:
call-bind: 1.0.2 call-bind: 1.0.2
define-properties: 1.1.4 define-properties: 1.2.0
es-abstract: 1.21.1 es-abstract: 1.21.1
dev: true dev: true
@ -2066,8 +2047,8 @@ packages:
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
dev: true dev: true
/tinyspy/1.0.2: /tinyspy/1.1.1:
resolution: {integrity: sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==} resolution: {integrity: sha512-UVq5AXt/gQlti7oxoIg5oi/9r0WpF7DGEVwXgqWSMmyN16+e3tl5lIvTaOpJ3TAtu5xFzWccFRM4R5NaWHF+4g==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
dev: true dev: true
@ -2099,8 +2080,8 @@ packages:
hasBin: true hasBin: true
dev: true dev: true
/ufo/1.0.1: /ufo/1.1.1:
resolution: {integrity: sha512-boAm74ubXHY7KJQZLlXrtMz52qFvpsbOxDcZOnw/Wf+LS4Mmyu7JxmzD4tDLtUQtmZECypJ0FrCz4QIe6dvKRA==} resolution: {integrity: sha512-MvlCc4GHrmZdAllBc0iUDowff36Q9Ndw/UzqmEKyrfSzokTd9ZCy1i+IIk5hrYKkjoYVQyNbrw7/F8XJ2rEwTg==}
dev: true dev: true
/unbox-primitive/1.0.2: /unbox-primitive/1.0.2:
@ -2123,8 +2104,8 @@ packages:
picocolors: 1.0.0 picocolors: 1.0.0
dev: true dev: true
/v8-to-istanbul/9.0.1: /v8-to-istanbul/9.1.0:
resolution: {integrity: sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==} resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==}
engines: {node: '>=10.12.0'} engines: {node: '>=10.12.0'}
dependencies: dependencies:
'@jridgewell/trace-mapping': 0.3.17 '@jridgewell/trace-mapping': 0.3.17
@ -2139,19 +2120,17 @@ packages:
spdx-expression-parse: 3.0.1 spdx-expression-parse: 3.0.1
dev: true dev: true
/vite-node/0.28.4_@types+node@18.11.19: /vite-node/0.29.2_@types+node@18.14.5:
resolution: {integrity: sha512-KM0Q0uSG/xHHKOJvVHc5xDBabgt0l70y7/lWTR7Q0pR5/MrYxadT+y32cJOE65FfjGmJgxpVEEY+69btJgcXOQ==} resolution: {integrity: sha512-5oe1z6wzI3gkvc4yOBbDBbgpiWiApvuN4P55E8OI131JGrSuo4X3SOZrNmZYo4R8Zkze/dhi572blX0zc+6SdA==}
engines: {node: '>=v14.16.0'} engines: {node: '>=v14.16.0'}
hasBin: true hasBin: true
dependencies: dependencies:
cac: 6.7.14 cac: 6.7.14
debug: 4.3.4 debug: 4.3.4
mlly: 1.1.0 mlly: 1.1.1
pathe: 1.1.0 pathe: 1.1.0
picocolors: 1.0.0 picocolors: 1.0.0
source-map: 0.6.1 vite: 4.1.4_@types+node@18.14.5
source-map-support: 0.5.21
vite: 4.1.1_@types+node@18.11.19
transitivePeerDependencies: transitivePeerDependencies:
- '@types/node' - '@types/node'
- less - less
@ -2162,8 +2141,8 @@ packages:
- terser - terser
dev: true dev: true
/vite/4.1.1: /vite/4.1.4:
resolution: {integrity: sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==} resolution: {integrity: sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@ -2190,13 +2169,13 @@ packages:
esbuild: 0.16.17 esbuild: 0.16.17
postcss: 8.4.21 postcss: 8.4.21
resolve: 1.22.1 resolve: 1.22.1
rollup: 3.14.0 rollup: 3.18.0
optionalDependencies: optionalDependencies:
fsevents: 2.3.2 fsevents: 2.3.2
dev: true dev: true
/vite/4.1.1_@types+node@18.11.19: /vite/4.1.4_@types+node@18.14.5:
resolution: {integrity: sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==} resolution: {integrity: sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@ -2220,17 +2199,17 @@ packages:
terser: terser:
optional: true optional: true
dependencies: dependencies:
'@types/node': 18.11.19 '@types/node': 18.14.5
esbuild: 0.16.17 esbuild: 0.16.17
postcss: 8.4.21 postcss: 8.4.21
resolve: 1.22.1 resolve: 1.22.1
rollup: 3.14.0 rollup: 3.18.0
optionalDependencies: optionalDependencies:
fsevents: 2.3.2 fsevents: 2.3.2
dev: true dev: true
/vitest/0.28.4_happy-dom@8.2.6: /vitest/0.29.2_happy-dom@8.9.0:
resolution: {integrity: sha512-sfWIy0AdlbyGRhunm+TLQEJrFH9XuRPdApfubsyLcDbCRrUX717BRQKInTgzEfyl2Ipi1HWoHB84Nqtcwxogcg==} resolution: {integrity: sha512-ydK9IGbAvoY8wkg29DQ4ivcVviCaUi3ivuPKfZEVddMTenFHUfB8EEDXQV8+RasEk1ACFLgMUqAaDuQ/Nk+mQA==}
engines: {node: '>=v14.16.0'} engines: {node: '>=v14.16.0'}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@ -2253,17 +2232,17 @@ packages:
dependencies: dependencies:
'@types/chai': 4.3.4 '@types/chai': 4.3.4
'@types/chai-subset': 1.3.3 '@types/chai-subset': 1.3.3
'@types/node': 18.11.19 '@types/node': 18.14.5
'@vitest/expect': 0.28.4 '@vitest/expect': 0.29.2
'@vitest/runner': 0.28.4 '@vitest/runner': 0.29.2
'@vitest/spy': 0.28.4 '@vitest/spy': 0.29.2
'@vitest/utils': 0.28.4 '@vitest/utils': 0.29.2
acorn: 8.8.2 acorn: 8.8.2
acorn-walk: 8.2.0 acorn-walk: 8.2.0
cac: 6.7.14 cac: 6.7.14
chai: 4.3.7 chai: 4.3.7
debug: 4.3.4 debug: 4.3.4
happy-dom: 8.2.6 happy-dom: 8.9.0
local-pkg: 0.4.3 local-pkg: 0.4.3
pathe: 1.1.0 pathe: 1.1.0
picocolors: 1.0.0 picocolors: 1.0.0
@ -2272,9 +2251,9 @@ packages:
strip-literal: 1.0.1 strip-literal: 1.0.1
tinybench: 2.3.1 tinybench: 2.3.1
tinypool: 0.3.1 tinypool: 0.3.1
tinyspy: 1.0.2 tinyspy: 1.1.1
vite: 4.1.1_@types+node@18.11.19 vite: 4.1.4_@types+node@18.14.5
vite-node: 0.28.4_@types+node@18.11.19 vite-node: 0.29.2_@types+node@18.14.5
why-is-node-running: 2.2.2 why-is-node-running: 2.2.2
transitivePeerDependencies: transitivePeerDependencies:
- less - less

View File

@ -1,34 +1,15 @@
import { act, cleanup, fireEvent, render, screen } from '@testing-library/react' import { act, cleanup, fireEvent, render } from '@testing-library/react'
import React, { useEffect } from 'react' import React from 'react'
import { beforeEach, describe, expect, test } from 'vitest' import { beforeEach, describe, expect, test } from 'vitest'
import { useForm } from '../lib' import { useForm } from '../lib'
import { Insight, Util } from './shared'
beforeEach(cleanup) beforeEach(cleanup)
const Insight = {
Portal({ data }: { data: any }) {
return <div data-testid="result">{JSON.stringify(data)}</div>
},
async verify(obj: any) {
const result = await screen.findByTestId('result')
const data = JSON.parse(result.innerText)
expect(data).toMatchObject(obj)
},
}
const Util = {
find<E extends HTMLElement = HTMLInputElement>(id: string) {
return screen.findByTestId<E>(id)
},
writeToField(node: HTMLInputElement, value: string) {
fireEvent.change(node, { target: { value } })
},
}
describe('Field', () => { describe('Field', () => {
test('Basic Form', async () => { test('Basic Form', async () => {
const BasicForm = () => { function Component() {
const form = useForm({ username: '', password: '' }) const form = useForm({ username: '', password: '' })
const { field } = form const { field } = form
return ( return (
@ -47,7 +28,7 @@ describe('Field', () => {
) )
} }
render(<BasicForm />) render(<Component />)
async function inputIntoForm(id: string, value: string) { async function inputIntoForm(id: string, value: string) {
const node = await Util.find(id) const node = await Util.find(id)
await act(() => { await act(() => {
@ -60,27 +41,65 @@ describe('Field', () => {
await inputIntoForm('password', 'bar') await inputIntoForm('password', 'bar')
}) })
test('setField', async () => { test.skip('Checkbox', async () => {
const value = 'foo' function Component() {
const Component = () => { const { field, form } = useForm({ cool: false })
const { field, setField, form } = useForm({ username: '', password: '' })
useEffect(() => setField('username', value), [])
return ( return (
<div> <form>
<input data-testid="field" {...field('username')}></input> <input
data-testid="field"
type="checkbox"
{...field('cool', {
setter: 'checked',
getter: 'onChange',
extractor: (e) => e.target.checked,
})}
/>
<Insight.Portal data={form} /> <Insight.Portal data={form} />
</div> </form>
) )
} }
render(<Component />) render(<Component />)
const node = await screen.findByTestId<HTMLInputElement>('field') const field = await Util.find('field')
expect(node.value).toBe(value) expect(field.checked).toBe(false)
Insight.verify({ username: value, password: '' }) await Insight.verify({ cool: false })
await act(() => {
// Bugged for now
fireEvent.click(field)
})
expect(field.checked).toBe(true)
await Insight.verify({ cool: true })
})
test('Select', async () => {
function Component() {
const { form, field } = useForm({ letter: '' })
return (
<>
<select data-testid="field" {...field('letter')}>
<option value="a">A</option>
<option value="b">B</option>
<option value="c">C</option>
</select>
<Insight.Portal data={form} />
</>
)
}
render(<Component />)
const field = await Util.find('field')
const value = 'b'
await act(() => {
fireEvent.change(field, { target: { value } })
})
expect(field.value).toBe(value)
await Insight.verify({ letter: value })
}) })
test('Field sync', async () => { test('Field sync', async () => {
const value = 'foo' const value = 'foo'
const Component = () => { function Component() {
const { field, form } = useForm({ name: '' }) const { field, form } = useForm({ name: '' })
return ( return (
<form> <form>
@ -101,54 +120,3 @@ describe('Field', () => {
expect(a.value).toBe(b.value) expect(a.value).toBe(b.value)
}) })
}) })
describe('Validation', () => {
test('Basic', async () => {
const Component = () => {
const { errors, field } = useForm({ password: '' }, { rules: { password: [(p) => p.length > 8] } })
return (
<div>
<input {...field('password')} data-testid="field" />
<Insight.Portal data={errors} />
</div>
)
}
render(<Component />)
const node = await Util.find('field')
await act(() => {
Util.writeToField(node, '123')
})
Insight.verify({ password: true })
})
test('Array of rules', async () => {
const Component = () => {
const { errors, field } = useForm({ password: '' }, { rules: { password: [(p) => p.length > 8, /#/] } })
return (
<div>
<input {...field('password')} data-testid="field" />
<Insight.Portal data={errors} />
</div>
)
}
render(<Component />)
const node = await Util.find('field')
await act(() => {
Util.writeToField(node, '12345678')
})
Insight.verify({ password: true })
await act(() => {
Util.writeToField(node, '1234#5678')
})
Insight.verify({})
})
})
// Is valid
// Reset / setForm
// Set error
// Checkbox
// Extractor
// Custom extractor

11
test/blocks.tsx Normal file
View File

@ -0,0 +1,11 @@
import React from 'react'
// Custom field with non standard setter and getter. Emulate custom component from a library
export function NumberField(props: { number: number; update: (value: number) => void }) {
return <input data-testid="field" value={props.number} onChange={(e) => props.update(parseInt(e.target.value))} />
}
// Component that needs a different extractor, as it's returning the actual value and not the event.
export function DirectReturnInput(props: { value: string; onChange: (v: string) => void }) {
return <input data-testid="field" value={props.value} onChange={(e) => props.onChange(e.target.value)} />
}

57
test/options.test.tsx Normal file
View File

@ -0,0 +1,57 @@
import { act, cleanup, render } from '@testing-library/react'
import React from 'react'
import { beforeEach, describe, test } from 'vitest'
import { useForm } from '../lib'
import { DirectReturnInput, NumberField } from './blocks'
import { Insight, Util } from './shared'
beforeEach(cleanup)
describe('Options', () => {
test('Custom component props', async () => {
function Component() {
const { form, field } = useForm({ foo: 5 })
return (
<div>
<NumberField
{...field('foo', {
setter: 'number',
getter: 'update',
extractor: null,
})}
/>
<Insight.Portal data={form} />
</div>
)
}
render(<Component />)
const node = await Util.find('field')
await act(() => {
Util.writeToField(node, '123')
})
Insight.verify({ foo: 123 })
})
test('Disable default extractor', async () => {
function Component() {
const { form, field } = useForm({ username: '' })
return (
<div>
<DirectReturnInput {...field('username', { extractor: null })} />
<Insight.Portal data={form} />
</div>
)
}
render(<Component />)
const node = await Util.find('field')
await act(() => {
Util.writeToField(node, '123')
})
Insight.verify({ username: '123' })
})
})

23
test/shared.tsx Normal file
View File

@ -0,0 +1,23 @@
import { fireEvent, screen } from '@testing-library/react'
import React from 'react'
import { expect } from 'vitest'
export const Insight = {
Portal({ data }: { data: any }) {
return <div data-testid="result">{JSON.stringify(data)}</div>
},
async verify(obj: any) {
const result = await screen.findByTestId('result')
const data = JSON.parse(result.innerText)
expect(data).toMatchObject(obj)
},
}
export const Util = {
find<E extends HTMLElement = HTMLInputElement>(id: string) {
return screen.findByTestId<E>(id)
},
writeToField(node: HTMLInputElement, value: string) {
fireEvent.change(node, { target: { value } })
},
}

53
test/utility.test.tsx Normal file
View File

@ -0,0 +1,53 @@
import { cleanup, render } from '@testing-library/react'
import React, { useEffect } from 'react'
import { beforeEach, describe, expect, test } from 'vitest'
import { useForm } from '../lib'
import { Insight, Util } from './shared'
beforeEach(cleanup)
describe('Utility', () => {
test('Manually set a single field', async () => {
const value = 'foo'
function Component() {
const { field, setField, form } = useForm({ username: '', password: '' })
useEffect(() => setField('username', value), [])
return (
<div>
<input data-testid="field" {...field('username')}></input>
<Insight.Portal data={form} />
</div>
)
}
render(<Component />)
const node = await Util.find('field')
expect(node.value).toBe(value)
Insight.verify({ username: value, password: '' })
})
test('Manually set the form state later on', async () => {
const value = 'foo'
function Component() {
const { form, field, setForm } = useForm({ username: '' })
useEffect(() => {
setForm({
username: value,
})
}, [])
return (
<form>
<input data-testid="username" {...field('username')} />
<Insight.Portal data={form} />
</form>
)
}
render(<Component />)
const node = await Util.find('username')
expect(node.value).toBe(value)
await Insight.verify({ username: value })
})
})

109
test/validation.test.tsx Normal file
View File

@ -0,0 +1,109 @@
import { act, cleanup, fireEvent, render } from '@testing-library/react'
import React from 'react'
import { beforeEach, describe, test } from 'vitest'
import { useForm } from '../lib'
import { Insight, Util } from './shared'
beforeEach(cleanup)
describe('Validation', () => {
test('Basic', async () => {
function Component() {
const { errors, field } = useForm({ password: '' }, { rules: { password: [(p) => p.length > 8] } })
return (
<div>
<input {...field('password')} data-testid="field" />
<Insight.Portal data={errors} />
</div>
)
}
render(<Component />)
const node = await Util.find('field')
await act(() => {
Util.writeToField(node, '123')
})
Insight.verify({ password: true })
})
test('Array of rules', async () => {
function Component() {
const { errors, field } = useForm({ password: '' }, { rules: { password: [(p) => p.length > 8, /#/] } })
return (
<div>
<input {...field('password')} data-testid="field" />
<Insight.Portal data={errors} />
</div>
)
}
render(<Component />)
const node = await Util.find('field')
await act(() => {
Util.writeToField(node, '12345678')
})
Insight.verify({ password: true })
await act(() => {
Util.writeToField(node, '1234#5678')
})
Insight.verify({})
})
// https://github.com/testing-library/react-testing-library/issues/828
test.skip('Invalid rule', async () => {
function Component() {
const { field } = useForm(
{ username: '' },
{
rules: {
username: [
// @ts-ignore Give an invalid rules and expect to fail
5,
],
},
}
)
return (
<form>
<input data-testid="field" {...field('username')} />
</form>
)
}
render(<Component />)
const field = await Util.find('field')
await act(() => {
Util.writeToField(field, 'abc')
})
})
test('Invalid dependency on other component', async () => {
function Component() {
const { errors, field } = useForm(
{ min: 10, max: 20 },
{
rules: {
max: (value, form) => value > form.min,
},
}
)
return (
<form>
<input type="number" {...field('min')} />
<input type="number" {...field('max')} data-testid="max" />
<Insight.Portal data={errors} />
</form>
)
}
render(<Component />)
const field = await Util.find('max')
const value = 5
await act(() => {
fireEvent.change(field, { target: { value } })
})
await Insight.verify({ max: true })
})
})