diff --git a/.changeset/pretty-eels-prove.md b/.changeset/pretty-eels-prove.md new file mode 100644 index 000000000..e47600f9f --- /dev/null +++ b/.changeset/pretty-eels-prove.md @@ -0,0 +1,5 @@ +--- +'@hono/conform-validator': major +--- + +Create Conform validator middleware diff --git a/.github/workflows/ci-conform-validator.yml b/.github/workflows/ci-conform-validator.yml new file mode 100644 index 000000000..1ed7a98c0 --- /dev/null +++ b/.github/workflows/ci-conform-validator.yml @@ -0,0 +1,25 @@ +name: ci-conform-validator +on: + push: + branches: [main] + paths: + - 'packages/conform-validator/**' + pull_request: + branches: ['*'] + paths: + - 'packages/conform-validator/**' + +jobs: + ci: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./packages/conform-validator + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20.x + - run: yarn install --frozen-lockfile + - run: yarn build + - run: yarn test diff --git a/package.json b/package.json index 8360c25eb..d9ad8e0b5 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "build:node-ws": "yarn workspace @hono/node-ws build", "build:react-compat": "yarn workspace @hono/react-compat build", "build:effect-validator": "yarn workspace @hono/effect-validator build", + "build:conform-validator": "yarn workspace @hono/conform-validator build", "build": "run-p 'build:*'", "lint": "eslint 'packages/**/*.{ts,tsx}'", "lint:fix": "eslint --fix 'packages/**/*.{ts,tsx}'", diff --git a/packages/conform-validator/README.md b/packages/conform-validator/README.md new file mode 100644 index 000000000..a3fbc8b8a --- /dev/null +++ b/packages/conform-validator/README.md @@ -0,0 +1,112 @@ +# Conform validator middleware for Hono + +The validator middleware using [conform](https://conform.guide) for [Hono](https://honojs.dev) applications. This middleware allows you to validate submitted FormValue and making better use of [Hono RPC](https://hono.dev/docs/guides/rpc). + +## Usage + +Zod: + +```ts +import { z } from 'zod' +import { parseWithZod } from '@conform-to/zod' +import { conformValidator } from '@hono/conform-validator' +import { HTTPException } from 'hono/http-exception' + +const schema = z.object({ + name: z.string(), + age: z.string(), +}) + +app.post( + '/author', + conformValidator((formData) => parseWithZod(formData, { schema })), + (c) => { + const submission = c.req.valid('form') + const data = submission.value + + return c.json({ success: true, message: `${data.name} is ${data.age}` }) + } +) +``` + +Yup: + +```ts +import { object, string } from 'yup' +import { parseWithYup } from '@conform-to/yup' +import { conformValidator } from '@hono/conform-validator' +import { HTTPException } from 'hono/http-exception' + +const schema = object({ + name: string(), + age: string(), +}) + +app.post( + '/author', + conformValidator((formData) => parseWithYup(formData, { schema })), + (c) => { + const submission = c.req.valid('form') + const data = submission.value + return c.json({ success: true, message: `${data.name} is ${data.age}` }) + } +) +``` + +Valibot: + +```ts +import { object, string } from 'valibot' +import { parseWithValibot } from 'conform-to-valibot' +import { conformValidator } from '@hono/conform-validator' +import { HTTPException } from 'hono/http-exception' + +const schema = object({ + name: string(), + age: string(), +}) + +app.post( + '/author', + conformValidator((formData) => parseWithYup(formData, { schema })), + (c) => { + const submission = c.req.valid('form') + const data = submission.value + return c.json({ success: true, message: `${data.name} is ${data.age}` }) + } +) +``` + +## Custom Hook Option + +By default, `conformValidator()` returns a [`SubmissionResult`](https://github.com/edmundhung/conform/blob/6b98c077d757edd4846321678dfb6de283c177b1/packages/conform-dom/submission.ts#L40-L47) when a validation error occurs. If you wish to change this behavior, or if you wish to perform common processing, you can modify the response by passing a function as the second argument. + +```ts +app.post( + '/author', + conformValidator( + (formData) => parseWithYup(formData, { schema }) + (submission, c) => { + if(submission.status !== 'success') { + return c.json({ success: false, message: 'Bad Request' }, 400) + } + } + ), + (c) => { + const submission = c.req.valid('form') + const data = submission.value + return c.json({ success: true, message: `${data.name} is ${data.age}` }) + } +) +``` + +> [!NOTE] +> if a response is returned by the Hook function, subsequent middleware or handler functions will not be executed. [see more](https://hono.dev/docs/concepts/middleware). + +## Author + +uttk + +## License + +MIT diff --git a/packages/conform-validator/package.json b/packages/conform-validator/package.json new file mode 100644 index 000000000..afa31f27e --- /dev/null +++ b/packages/conform-validator/package.json @@ -0,0 +1,56 @@ +{ + "name": "@hono/conform-validator", + "version": "0.0.0", + "description": "Validator middleware using Conform", + "type": "module", + "main": "dist/index.cjs", + "module": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist" + ], + "scripts": { + "test": "vitest --run", + "build": "tsup ./src/index.ts --format esm,cjs --dts", + "prerelease": "yarn build && yarn test", + "release": "yarn publish" + }, + "exports": { + ".": { + "import": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "require": { + "types": "./dist/index.d.cts", + "default": "./dist/index.cjs" + } + } + }, + "license": "MIT", + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/honojs/middleware.git" + }, + "homepage": "https://github.com/honojs/middleware", + "peerDependencies": { + "@conform-to/dom": ">=1.1.5", + "hono": ">=4.5.1" + }, + "devDependencies": { + "@conform-to/dom": "^1.1.5", + "@conform-to/yup": "^1.1.5", + "@conform-to/zod": "^1.1.5", + "conform-to-valibot": "^1.10.0", + "hono": "^4.5.1", + "tsup": "^8.2.3", + "valibot": "^0.36.0", + "vitest": "^2.0.4", + "yup": "^1.4.0", + "zod": "^3.23.8" + } +} diff --git a/packages/conform-validator/src/index.ts b/packages/conform-validator/src/index.ts new file mode 100644 index 000000000..57d1ccbf3 --- /dev/null +++ b/packages/conform-validator/src/index.ts @@ -0,0 +1,59 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import type { Context, Env, Input as HonoInput, MiddlewareHandler, ValidationTargets } from 'hono' +import type { Submission } from '@conform-to/dom' +import { getFormDataFromContext } from './utils' + +type FormTargetValue = ValidationTargets['form']['string'] + +type GetInput = T extends (_: any) => infer S + ? Awaited extends Submission + ? V + : never + : never + +type GetSuccessSubmission = S extends { status: 'success' } ? S : never + +type ParseFn = (formData: FormData) => Submission | Promise> + +type Hook = ( + submission: Awaited>, + c: Context +) => Response | Promise | void | Promise + +export const conformValidator = < + F extends ParseFn, + E extends Env, + P extends string, + In = GetInput, + Out = Awaited>, + I extends HonoInput = { + in: { + form: { [K in keyof In]: FormTargetValue } + } + out: { form: GetSuccessSubmission } + } +>( + parse: F, + hook?: Hook +): MiddlewareHandler => { + return async (c, next) => { + const formData = await getFormDataFromContext(c) + const submission = await parse(formData) + + if (hook) { + const hookResult = hook(submission as any, c) + if (hookResult instanceof Response || hookResult instanceof Promise) { + return hookResult + } + } + + if (submission.status !== 'success') { + return c.json(submission.reply(), 400) + } + + c.req.addValidatedData('form', submission) + + await next() + } +} diff --git a/packages/conform-validator/src/utils.ts b/packages/conform-validator/src/utils.ts new file mode 100644 index 000000000..9c628402b --- /dev/null +++ b/packages/conform-validator/src/utils.ts @@ -0,0 +1,25 @@ +import type { Context } from 'hono' +import { bufferToFormData } from 'hono/utils/buffer' + +// ref: https://github.com/honojs/hono/blob/a63bcfd6fba66297d8234c21aed8a42ac00711fe/src/validator/validator.ts#L27-L28 +const multipartRegex = /^multipart\/form-data(; boundary=[A-Za-z0-9'()+_,\-./:=?]+)?$/ +const urlencodedRegex = /^application\/x-www-form-urlencoded$/ + +export const getFormDataFromContext = async (ctx: Context): Promise => { + const contentType = ctx.req.header('Content-Type') + if (!contentType || !(multipartRegex.test(contentType) || urlencodedRegex.test(contentType))) { + return new FormData() + } + + const cache = ctx.req.bodyCache.formData + if (cache) { + return cache + } + + const arrayBuffer = await ctx.req.arrayBuffer() + const formData = await bufferToFormData(arrayBuffer, contentType) + + ctx.req.bodyCache.formData = formData + + return formData +} diff --git a/packages/conform-validator/test/common.test.ts b/packages/conform-validator/test/common.test.ts new file mode 100644 index 000000000..14faca9f3 --- /dev/null +++ b/packages/conform-validator/test/common.test.ts @@ -0,0 +1,35 @@ +import { Hono } from 'hono' +import { z } from 'zod' +import { parseWithZod } from '@conform-to/zod' +import { conformValidator } from '../src' + +describe('Validate common processing', () => { + const app = new Hono() + const schema = z.object({ name: z.string() }) + const route = app.post( + '/author', + conformValidator((formData) => parseWithZod(formData, { schema })), + (c) => { + const submission = c.req.valid('form') + const value = submission.value + return c.json({ success: true, message: `my name is ${value.name}` }) + } + ) + + describe('When the request body is empty', () => { + it('Should return 400 response', async () => { + const res = await route.request('/author', { method: 'POST' }) + expect(res.status).toBe(400) + }) + }) + + describe('When the request body is not FormData', () => { + it('Should return 400 response', async () => { + const res = await route.request('/author', { + method: 'POST', + body: JSON.stringify({ name: 'Space Cat!' }), + }) + expect(res.status).toBe(400) + }) + }) +}) diff --git a/packages/conform-validator/test/hook.test.ts b/packages/conform-validator/test/hook.test.ts new file mode 100644 index 000000000..a4b07dee4 --- /dev/null +++ b/packages/conform-validator/test/hook.test.ts @@ -0,0 +1,62 @@ +import * as z from 'zod' +import { Hono } from 'hono' +import { hc } from 'hono/client' +import { parseWithZod } from '@conform-to/zod' +import { conformValidator } from '../src' +import { vi } from 'vitest' + +describe('Validate the hook option processing', () => { + const app = new Hono() + const schema = z.object({ name: z.string() }) + const hookMockFn = vi.fn((submission, c) => { + if (submission.status !== 'success') { + return c.json({ success: false, message: 'Bad Request' }, 400) + } + }) + const handlerMockFn = vi.fn((c) => { + const submission = c.req.valid('form') + const value = submission.value + return c.json({ success: true, message: `name is ${value.name}` }) + }) + const route = app.post( + '/author', + conformValidator((formData) => parseWithZod(formData, { schema }), hookMockFn), + handlerMockFn + ) + const client = hc('http://localhost', { + fetch: (req, init) => { + return app.request(req, init) + }, + }) + + afterEach(() => { + hookMockFn.mockClear() + handlerMockFn.mockClear() + }) + + it('Should called hook function', async () => { + await client.author.$post({ form: { name: 'Space Cat' } }) + expect(hookMockFn).toHaveBeenCalledTimes(1) + }) + + describe('When the hook return Response', () => { + it('Should return response that the hook returned', async () => { + const req = new Request('http://localhost/author', { body: new FormData(), method: 'POST' }) + const res = (await app.request(req)).clone() + const hookRes = hookMockFn.mock.results[0].value.clone() + expect(hookMockFn).toHaveReturnedWith(expect.any(Response)) + expect(res.status).toBe(hookRes.status) + expect(await res.json()).toStrictEqual(await hookRes.json()) + }) + }) + + describe('When the hook not return Response', () => { + it('Should return response that the handler function returned', async () => { + const res = (await client.author.$post({ form: { name: 'Space Cat' } })).clone() + const handlerRes = handlerMockFn.mock.results[0].value.clone() + expect(hookMockFn).not.toHaveReturnedWith(expect.any(Response)) + expect(res.status).toBe(handlerRes.status) + expect(await res.json()).toStrictEqual(await handlerRes.json()) + }) + }) +}) diff --git a/packages/conform-validator/test/valibot.test.ts b/packages/conform-validator/test/valibot.test.ts new file mode 100644 index 000000000..363c2d407 --- /dev/null +++ b/packages/conform-validator/test/valibot.test.ts @@ -0,0 +1,111 @@ +import type { ExtractSchema, ParsedFormValue } from 'hono/types' +import type { Equal, Expect } from 'hono/utils/types' +import type { StatusCode } from 'hono/utils/http-status' +import * as v from 'valibot' +import { Hono } from 'hono' +import { hc } from 'hono/client' +import { parseWithValibot } from 'conform-to-valibot' +import { conformValidator } from '../src' + +describe('Validate requests using a Valibot schema', () => { + const app = new Hono() + + const schema = v.object({ + name: v.string(), + age: v.pipe( + v.string(), + v.transform((v) => Number(v)), + v.integer() + ), + nickname: v.optional(v.string()), + }) + + const route = app.post( + '/author', + conformValidator((formData) => parseWithValibot(formData, { schema })), + (c) => { + const submission = c.req.valid('form') + const value = submission.value + + return c.json({ + success: true, + message: `${value.name} is ${value.age}, nickname is ${ + value?.nickname || 'nothing yet :3' + }`, + }) + } + ) + + it('check the route object types', () => { + type Actual = ExtractSchema + type Expected = { + '/author': { + $post: { + input: { + form: { + name: ParsedFormValue | ParsedFormValue[] + age: ParsedFormValue | ParsedFormValue[] + nickname?: ParsedFormValue | ParsedFormValue[] | undefined + } + } + output: { + success: boolean + message: string + } + outputFormat: 'json' + status: StatusCode + } + } + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + type verify = Expect> + }) + + it('Should return 200 response', async () => { + const client = hc('http://localhost', { + fetch: (req, init) => { + return app.request(req, init) + }, + }) + + const res = await client.author.$post({ + form: { + name: 'Space Cat', + age: '20', + nickname: 'meow', + }, + }) + + expect(res).not.toBeNull() + expect(res.status).toBe(200) + + const json = await res.json() + expect(json).toEqual({ + success: true, + message: 'Space Cat is 20, nickname is meow', + }) + }) + + it('Should return 400 response', async () => { + const formData = new FormData() + + const req = new Request('http://localhost/author', { + body: formData, + method: 'POST', + }) + + const res = await app.request(req) + expect(res).not.toBeNull() + expect(res.status).toBe(400) + + const json = await res.json() + expect(json).toMatchObject({ + status: 'error', + error: { + name: ['Invalid type: Expected string but received undefined'], + age: ['Invalid type: Expected string but received undefined'], + }, + }) + }) +}) diff --git a/packages/conform-validator/test/yup.test.ts b/packages/conform-validator/test/yup.test.ts new file mode 100644 index 000000000..f8c81d0f2 --- /dev/null +++ b/packages/conform-validator/test/yup.test.ts @@ -0,0 +1,107 @@ +import type { ExtractSchema, ParsedFormValue } from 'hono/types' +import type { Equal, Expect } from 'hono/utils/types' +import type { StatusCode } from 'hono/utils/http-status' +import * as y from 'yup' +import { Hono } from 'hono' +import { hc } from 'hono/client' +import { parseWithYup } from '@conform-to/yup' +import { conformValidator } from '../src' + +describe('Validate requests using a Yup schema', () => { + const app = new Hono() + + const schema = y.object({ + name: y.string().required(), + age: y.number().required(), + nickname: y.string().optional(), + }) + + const route = app.post( + '/author', + conformValidator((formData) => parseWithYup(formData, { schema })), + (c) => { + const submission = c.req.valid('form') + const value = submission.value + + return c.json({ + success: true, + message: `${value.name} is ${value.age}, nickname is ${ + value?.nickname || 'nothing yet :3' + }`, + }) + } + ) + + it('check the route object types', () => { + type Actual = ExtractSchema + type Expected = { + '/author': { + $post: { + input: { + form: { + name: ParsedFormValue | ParsedFormValue[] + age: ParsedFormValue | ParsedFormValue[] + nickname?: ParsedFormValue | ParsedFormValue[] | undefined + } + } + output: { + success: boolean + message: string + } + outputFormat: 'json' + status: StatusCode + } + } + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + type verify = Expect> + }) + + it('Should return 200 response', async () => { + const client = hc('http://localhost', { + fetch: (req, init) => { + return app.request(req, init) + }, + }) + + const res = await client.author.$post({ + form: { + name: 'Space Cat', + age: '20', + nickname: 'meow', + }, + }) + + expect(res).not.toBeNull() + expect(res.status).toBe(200) + + const json = await res.json() + expect(json).toEqual({ + success: true, + message: 'Space Cat is 20, nickname is meow', + }) + }) + + it('Should return 400 response', async () => { + const formData = new FormData() + + const req = new Request('http://localhost/author', { + body: formData, + method: 'POST', + }) + + const res = await app.request(req) + expect(res).not.toBeNull() + expect(res.status).toBe(400) + + const json = await res.json() + expect(json).toMatchObject({ + status: 'error', + error: { + name: ['name is a required field'], + age: ['age is a required field'], + }, + }) + }) +}) diff --git a/packages/conform-validator/test/zod.test.ts b/packages/conform-validator/test/zod.test.ts new file mode 100644 index 000000000..7cb091319 --- /dev/null +++ b/packages/conform-validator/test/zod.test.ts @@ -0,0 +1,107 @@ +import type { ExtractSchema, ParsedFormValue } from 'hono/types' +import type { Equal, Expect } from 'hono/utils/types' +import type { StatusCode } from 'hono/utils/http-status' +import * as z from 'zod' +import { Hono } from 'hono' +import { hc } from 'hono/client' +import { parseWithZod } from '@conform-to/zod' +import { conformValidator } from '../src' + +describe('Validate requests using a Zod schema', () => { + const app = new Hono() + + const schema = z.object({ + name: z.string(), + age: z.string().transform((str) => Number(str)), + nickname: z.string().optional(), + }) + + const route = app.post( + '/author', + conformValidator((formData) => parseWithZod(formData, { schema })), + (c) => { + const submission = c.req.valid('form') + const value = submission.value + + return c.json({ + success: true, + message: `${value.name} is ${value.age}, nickname is ${ + value?.nickname || 'nothing yet :3' + }`, + }) + } + ) + + it('check the route object types', () => { + type Actual = ExtractSchema + type Expected = { + '/author': { + $post: { + input: { + form: { + name: ParsedFormValue | ParsedFormValue[] + age: ParsedFormValue | ParsedFormValue[] + nickname?: ParsedFormValue | ParsedFormValue[] | undefined + } + } + output: { + success: boolean + message: string + } + outputFormat: 'json' + status: StatusCode + } + } + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + type verify = Expect> + }) + + it('Should return 200 response', async () => { + const client = hc('http://localhost', { + fetch: (req, init) => { + return app.request(req, init) + }, + }) + + const res = await client.author.$post({ + form: { + name: 'Space Cat', + age: '20', + nickname: 'meow', + }, + }) + + expect(res).not.toBeNull() + expect(res.status).toBe(200) + + const json = await res.json() + expect(json).toEqual({ + success: true, + message: 'Space Cat is 20, nickname is meow', + }) + }) + + it('Should return 400 response', async () => { + const formData = new FormData() + + const req = new Request('http://localhost/author', { + body: formData, + method: 'POST', + }) + + const res = await app.request(req) + expect(res).not.toBeNull() + expect(res.status).toBe(400) + + const json = await res.json() + expect(json).toMatchObject({ + status: 'error', + error: { + name: ['Required'], + age: ['Required'], + }, + }) + }) +}) diff --git a/packages/conform-validator/tsconfig.cjs.json b/packages/conform-validator/tsconfig.cjs.json new file mode 100644 index 000000000..b8bf50ee9 --- /dev/null +++ b/packages/conform-validator/tsconfig.cjs.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "CommonJS", + "declaration": false, + "outDir": "./dist/cjs" + } +} \ No newline at end of file diff --git a/packages/conform-validator/tsconfig.esm.json b/packages/conform-validator/tsconfig.esm.json new file mode 100644 index 000000000..8130f1a53 --- /dev/null +++ b/packages/conform-validator/tsconfig.esm.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "ESNext", + "declaration": true, + "outDir": "./dist/esm" + } +} \ No newline at end of file diff --git a/packages/conform-validator/tsconfig.json b/packages/conform-validator/tsconfig.json new file mode 100644 index 000000000..6c1a39902 --- /dev/null +++ b/packages/conform-validator/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": "./src", + }, + "include": [ + "src/**/*.ts" + ], +} \ No newline at end of file diff --git a/packages/conform-validator/vitest.config.ts b/packages/conform-validator/vitest.config.ts new file mode 100644 index 000000000..17b54e485 --- /dev/null +++ b/packages/conform-validator/vitest.config.ts @@ -0,0 +1,8 @@ +/// +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + globals: true, + }, +}) diff --git a/yarn.lock b/yarn.lock index 0931cbbb7..1457372a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -992,6 +992,35 @@ __metadata: languageName: node linkType: hard +"@conform-to/dom@npm:1.1.5, @conform-to/dom@npm:^1.1.5": + version: 1.1.5 + resolution: "@conform-to/dom@npm:1.1.5" + checksum: 8297852ec422630a01a401842a994a0e19f8585df820ab26df3bbb4687fd97812acbb6ebce7ddc38c6b9197ee1d45ddf136f42a3f33703613c52710de4cf026a + languageName: node + linkType: hard + +"@conform-to/yup@npm:^1.1.5": + version: 1.1.5 + resolution: "@conform-to/yup@npm:1.1.5" + dependencies: + "@conform-to/dom": "npm:1.1.5" + peerDependencies: + yup: ">=0.32.0" + checksum: 31849faaf1b9c4e0368547b0174aadd9fd0c2c4e9d38c63b7455806c721ccf8f56e3826f2b979bb795f55b793492de7ff3f445ac45302acd1f82c74100a24dbf + languageName: node + linkType: hard + +"@conform-to/zod@npm:^1.1.5": + version: 1.1.5 + resolution: "@conform-to/zod@npm:1.1.5" + dependencies: + "@conform-to/dom": "npm:1.1.5" + peerDependencies: + zod: ^3.21.0 + checksum: 047ddb45be8d156f0b0cddf4b6db7a3612e04f7c4b194502f29230a6c720d2e841058afe13838e2daac0804db1bb236ed8ba673fc4737c46589b90ec73935e4d + languageName: node + linkType: hard + "@cspotcode/source-map-support@npm:0.8.1": version: 0.8.1 resolution: "@cspotcode/source-map-support@npm:0.8.1" @@ -1067,6 +1096,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/aix-ppc64@npm:0.23.0" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/android-arm64@npm:0.17.19" @@ -1102,6 +1138,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/android-arm64@npm:0.23.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/android-arm@npm:0.17.19" @@ -1137,6 +1180,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/android-arm@npm:0.23.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/android-x64@npm:0.17.19" @@ -1172,6 +1222,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/android-x64@npm:0.23.0" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/darwin-arm64@npm:0.17.19" @@ -1207,6 +1264,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/darwin-arm64@npm:0.23.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/darwin-x64@npm:0.17.19" @@ -1242,6 +1306,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/darwin-x64@npm:0.23.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/freebsd-arm64@npm:0.17.19" @@ -1277,6 +1348,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/freebsd-arm64@npm:0.23.0" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/freebsd-x64@npm:0.17.19" @@ -1312,6 +1390,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/freebsd-x64@npm:0.23.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-arm64@npm:0.17.19" @@ -1347,6 +1432,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-arm64@npm:0.23.0" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-arm@npm:0.17.19" @@ -1382,6 +1474,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-arm@npm:0.23.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-ia32@npm:0.17.19" @@ -1417,6 +1516,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-ia32@npm:0.23.0" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-loong64@npm:0.17.19" @@ -1452,6 +1558,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-loong64@npm:0.23.0" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-mips64el@npm:0.17.19" @@ -1487,6 +1600,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-mips64el@npm:0.23.0" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-ppc64@npm:0.17.19" @@ -1522,6 +1642,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-ppc64@npm:0.23.0" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-riscv64@npm:0.17.19" @@ -1557,6 +1684,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-riscv64@npm:0.23.0" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-s390x@npm:0.17.19" @@ -1592,6 +1726,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-s390x@npm:0.23.0" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-x64@npm:0.17.19" @@ -1627,6 +1768,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-x64@npm:0.23.0" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/netbsd-x64@npm:0.17.19" @@ -1662,6 +1810,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/netbsd-x64@npm:0.23.0" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/openbsd-arm64@npm:0.23.0" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/openbsd-x64@npm:0.17.19" @@ -1697,6 +1859,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/openbsd-x64@npm:0.23.0" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/sunos-x64@npm:0.17.19" @@ -1732,6 +1901,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/sunos-x64@npm:0.23.0" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/win32-arm64@npm:0.17.19" @@ -1767,6 +1943,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/win32-arm64@npm:0.23.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/win32-ia32@npm:0.17.19" @@ -1802,6 +1985,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/win32-ia32@npm:0.23.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/win32-x64@npm:0.17.19" @@ -1837,6 +2027,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/win32-x64@npm:0.23.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": version: 4.4.0 resolution: "@eslint-community/eslint-utils@npm:4.4.0" @@ -2028,6 +2225,26 @@ __metadata: languageName: unknown linkType: soft +"@hono/conform-validator@workspace:packages/conform-validator": + version: 0.0.0-use.local + resolution: "@hono/conform-validator@workspace:packages/conform-validator" + dependencies: + "@conform-to/dom": "npm:^1.1.5" + "@conform-to/yup": "npm:^1.1.5" + "@conform-to/zod": "npm:^1.1.5" + conform-to-valibot: "npm:^1.10.0" + hono: "npm:^4.5.1" + tsup: "npm:^8.2.3" + valibot: "npm:^0.36.0" + vitest: "npm:^2.0.4" + yup: "npm:^1.4.0" + zod: "npm:^3.23.8" + peerDependencies: + "@conform-to/dom": ">=1.1.5" + hono: ">=4.5.1" + languageName: unknown + linkType: soft + "@hono/effect-validator@workspace:packages/effect-validator": version: 0.0.0-use.local resolution: "@hono/effect-validator@workspace:packages/effect-validator" @@ -3708,6 +3925,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm-eabi@npm:4.19.1": + version: 4.19.1 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.19.1" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@rollup/rollup-android-arm-eabi@npm:4.9.0": version: 4.9.0 resolution: "@rollup/rollup-android-arm-eabi@npm:4.9.0" @@ -3715,6 +3939,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm64@npm:4.19.1": + version: 4.19.1 + resolution: "@rollup/rollup-android-arm64@npm:4.19.1" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-android-arm64@npm:4.9.0": version: 4.9.0 resolution: "@rollup/rollup-android-arm64@npm:4.9.0" @@ -3722,6 +3953,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-arm64@npm:4.19.1": + version: 4.19.1 + resolution: "@rollup/rollup-darwin-arm64@npm:4.19.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-arm64@npm:4.9.0": version: 4.9.0 resolution: "@rollup/rollup-darwin-arm64@npm:4.9.0" @@ -3729,6 +3967,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-x64@npm:4.19.1": + version: 4.19.1 + resolution: "@rollup/rollup-darwin-x64@npm:4.19.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-x64@npm:4.9.0": version: 4.9.0 resolution: "@rollup/rollup-darwin-x64@npm:4.9.0" @@ -3736,6 +3981,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm-gnueabihf@npm:4.19.1": + version: 4.19.1 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.19.1" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-arm-gnueabihf@npm:4.9.0": version: 4.9.0 resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.9.0" @@ -3743,6 +3995,20 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm-musleabihf@npm:4.19.1": + version: 4.19.1 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.19.1" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-gnu@npm:4.19.1": + version: 4.19.1 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.19.1" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-gnu@npm:4.9.0": version: 4.9.0 resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.9.0" @@ -3750,6 +4016,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-musl@npm:4.19.1": + version: 4.19.1 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.19.1" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-musl@npm:4.9.0": version: 4.9.0 resolution: "@rollup/rollup-linux-arm64-musl@npm:4.9.0" @@ -3757,6 +4030,20 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.19.1": + version: 4.19.1 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.19.1" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-gnu@npm:4.19.1": + version: 4.19.1 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.19.1" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-riscv64-gnu@npm:4.9.0": version: 4.9.0 resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.9.0" @@ -3764,6 +4051,20 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-s390x-gnu@npm:4.19.1": + version: 4.19.1 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.19.1" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-gnu@npm:4.19.1": + version: 4.19.1 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.19.1" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-x64-gnu@npm:4.9.0": version: 4.9.0 resolution: "@rollup/rollup-linux-x64-gnu@npm:4.9.0" @@ -3771,6 +4072,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-musl@npm:4.19.1": + version: 4.19.1 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.19.1" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-x64-musl@npm:4.9.0": version: 4.9.0 resolution: "@rollup/rollup-linux-x64-musl@npm:4.9.0" @@ -3778,6 +4086,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-arm64-msvc@npm:4.19.1": + version: 4.19.1 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.19.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-win32-arm64-msvc@npm:4.9.0": version: 4.9.0 resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.9.0" @@ -3785,6 +4100,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-ia32-msvc@npm:4.19.1": + version: 4.19.1 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.19.1" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@rollup/rollup-win32-ia32-msvc@npm:4.9.0": version: 4.9.0 resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.9.0" @@ -3792,6 +4114,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-x64-msvc@npm:4.19.1": + version: 4.19.1 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.19.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@rollup/rollup-win32-x64-msvc@npm:4.9.0": version: 4.9.0 resolution: "@rollup/rollup-win32-x64-msvc@npm:4.9.0" @@ -4103,7 +4432,7 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:*, @types/estree@npm:^1.0.0": +"@types/estree@npm:*, @types/estree@npm:1.0.5, @types/estree@npm:^1.0.0": version: 1.0.5 resolution: "@types/estree@npm:1.0.5" checksum: b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d @@ -4797,6 +5126,27 @@ __metadata: languageName: node linkType: hard +"@vitest/expect@npm:2.0.4": + version: 2.0.4 + resolution: "@vitest/expect@npm:2.0.4" + dependencies: + "@vitest/spy": "npm:2.0.4" + "@vitest/utils": "npm:2.0.4" + chai: "npm:^5.1.1" + tinyrainbow: "npm:^1.2.0" + checksum: 18acdd6b1f5001830722fab7d41b0bd754e37572dded74d1549c5e8f40e58d9e4bbbb6a8ce6be1200b04653237329ba1aeeb3330c2a41f1024450016464d491e + languageName: node + linkType: hard + +"@vitest/pretty-format@npm:2.0.4, @vitest/pretty-format@npm:^2.0.4": + version: 2.0.4 + resolution: "@vitest/pretty-format@npm:2.0.4" + dependencies: + tinyrainbow: "npm:^1.2.0" + checksum: c2ac3ca302b93ad53ea2977209ee4eb31a313c18690034a09f8ec5528d7e82715c233c4927ecf8b364203c5e5475231d9b737b3fb7680eea71882e1eae11e473 + languageName: node + linkType: hard + "@vitest/runner@npm:0.34.6": version: 0.34.6 resolution: "@vitest/runner@npm:0.34.6" @@ -4873,6 +5223,16 @@ __metadata: languageName: node linkType: hard +"@vitest/runner@npm:2.0.4": + version: 2.0.4 + resolution: "@vitest/runner@npm:2.0.4" + dependencies: + "@vitest/utils": "npm:2.0.4" + pathe: "npm:^1.1.2" + checksum: b550372ce5e2c6a3f08dbd584ea669723fc0d789ebaa4224b703f12e908813fb76b963ea9ac2265aa751cab0309f637dc1fa7ce3fb3e67e08e52e241d33237ee + languageName: node + linkType: hard + "@vitest/snapshot@npm:0.34.6": version: 0.34.6 resolution: "@vitest/snapshot@npm:0.34.6" @@ -4950,6 +5310,17 @@ __metadata: languageName: node linkType: hard +"@vitest/snapshot@npm:2.0.4": + version: 2.0.4 + resolution: "@vitest/snapshot@npm:2.0.4" + dependencies: + "@vitest/pretty-format": "npm:2.0.4" + magic-string: "npm:^0.30.10" + pathe: "npm:^1.1.2" + checksum: 67608c5b1e2f8b02ebc95286cd644c31ea29344c81d67151375b6eebf088a0eea242756eefb509aac626b8f7f091044fdcbc80d137d811ead1117a4a524e2d74 + languageName: node + linkType: hard + "@vitest/spy@npm:0.34.6": version: 0.34.6 resolution: "@vitest/spy@npm:0.34.6" @@ -5013,6 +5384,15 @@ __metadata: languageName: node linkType: hard +"@vitest/spy@npm:2.0.4": + version: 2.0.4 + resolution: "@vitest/spy@npm:2.0.4" + dependencies: + tinyspy: "npm:^3.0.0" + checksum: ef0d0c5e36bb6dfa3ef7561368b39c92cd89bb52d112ec13345dfc99981796a9af98bafd35ce6952322a6a7534eaad144485fe7764628d94d77edeba5fa773b6 + languageName: node + linkType: hard + "@vitest/utils@npm:0.34.6": version: 0.34.6 resolution: "@vitest/utils@npm:0.34.6" @@ -5095,6 +5475,18 @@ __metadata: languageName: node linkType: hard +"@vitest/utils@npm:2.0.4": + version: 2.0.4 + resolution: "@vitest/utils@npm:2.0.4" + dependencies: + "@vitest/pretty-format": "npm:2.0.4" + estree-walker: "npm:^3.0.3" + loupe: "npm:^3.1.1" + tinyrainbow: "npm:^1.2.0" + checksum: 48e0bad3aa463d147b125e355b6bc6c5b4a5eab600132ebafac8379800273b2f47df17dbf76fe179b1500cc6b5866ead2d375a39a9114a03f705eb8850b93afa + languageName: node + linkType: hard + "@yarnpkg/lockfile@npm:^1.1.0": version: 1.1.0 resolution: "@yarnpkg/lockfile@npm:1.1.0" @@ -6097,6 +6489,17 @@ __metadata: languageName: node linkType: hard +"bundle-require@npm:^5.0.0": + version: 5.0.0 + resolution: "bundle-require@npm:5.0.0" + dependencies: + load-tsconfig: "npm:^0.2.3" + peerDependencies: + esbuild: ">=0.18" + checksum: 92c46df02586e0ebd66ee4831c9b5775adb3c32a43fe2b2aaf7bc675135c141f751de6a9a26b146d64c607c5b40f9eef5f10dce3c364f602d4bed268444c32c6 + languageName: node + linkType: hard + "busboy@npm:^1.6.0": version: 1.6.0 resolution: "busboy@npm:1.6.0" @@ -6428,7 +6831,7 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^3.5.3": +"chokidar@npm:^3.5.3, chokidar@npm:^3.6.0": version: 3.6.0 resolution: "chokidar@npm:3.6.0" dependencies: @@ -6831,6 +7234,16 @@ __metadata: languageName: node linkType: hard +"conform-to-valibot@npm:^1.10.0": + version: 1.10.0 + resolution: "conform-to-valibot@npm:1.10.0" + peerDependencies: + "@conform-to/dom": ^1.0.0 + valibot: ">= 0.32.0" + checksum: e11f07c00d7b443e80a6d0bcca79c1842bdc8f6f4d966c79ab8ee12fadfb0bd31c04a593f2c880f162c8ffb431b0845696f17ecddaf6ae9b4e3843c8ad168ad0 + languageName: node + linkType: hard + "connect@npm:^3.7.0": version: 3.7.0 resolution: "connect@npm:3.7.0" @@ -6843,6 +7256,13 @@ __metadata: languageName: node linkType: hard +"consola@npm:^3.2.3": + version: 3.2.3 + resolution: "consola@npm:3.2.3" + checksum: c606220524ec88a05bb1baf557e9e0e04a0c08a9c35d7a08652d99de195c4ddcb6572040a7df57a18ff38bbc13ce9880ad032d56630cef27bef72768ef0ac078 + languageName: node + linkType: hard + "content-disposition@npm:0.5.4": version: 0.5.4 resolution: "content-disposition@npm:0.5.4" @@ -8220,6 +8640,89 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:^0.23.0": + version: 0.23.0 + resolution: "esbuild@npm:0.23.0" + dependencies: + "@esbuild/aix-ppc64": "npm:0.23.0" + "@esbuild/android-arm": "npm:0.23.0" + "@esbuild/android-arm64": "npm:0.23.0" + "@esbuild/android-x64": "npm:0.23.0" + "@esbuild/darwin-arm64": "npm:0.23.0" + "@esbuild/darwin-x64": "npm:0.23.0" + "@esbuild/freebsd-arm64": "npm:0.23.0" + "@esbuild/freebsd-x64": "npm:0.23.0" + "@esbuild/linux-arm": "npm:0.23.0" + "@esbuild/linux-arm64": "npm:0.23.0" + "@esbuild/linux-ia32": "npm:0.23.0" + "@esbuild/linux-loong64": "npm:0.23.0" + "@esbuild/linux-mips64el": "npm:0.23.0" + "@esbuild/linux-ppc64": "npm:0.23.0" + "@esbuild/linux-riscv64": "npm:0.23.0" + "@esbuild/linux-s390x": "npm:0.23.0" + "@esbuild/linux-x64": "npm:0.23.0" + "@esbuild/netbsd-x64": "npm:0.23.0" + "@esbuild/openbsd-arm64": "npm:0.23.0" + "@esbuild/openbsd-x64": "npm:0.23.0" + "@esbuild/sunos-x64": "npm:0.23.0" + "@esbuild/win32-arm64": "npm:0.23.0" + "@esbuild/win32-ia32": "npm:0.23.0" + "@esbuild/win32-x64": "npm:0.23.0" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 08c148c067795165798c0467ce02d2d1ecedc096989bded5f0d795c61a1fcbec6c14d0a3c9f4ad6185cc29ec52087acaa335ed6d98be6ad57f7fa4264626bde0 + languageName: node + linkType: hard + "escalade@npm:^3.1.1": version: 3.1.1 resolution: "escalade@npm:3.1.1" @@ -8723,7 +9226,7 @@ __metadata: languageName: node linkType: hard -"execa@npm:^5.0.0": +"execa@npm:^5.0.0, execa@npm:^5.1.1": version: 5.1.1 resolution: "execa@npm:5.1.1" dependencies: @@ -10166,6 +10669,13 @@ __metadata: languageName: node linkType: hard +"hono@npm:^4.5.1": + version: 4.5.1 + resolution: "hono@npm:4.5.1" + checksum: 71228cefd3808b4bb42c10de23d67f135678eb0ab7fdfd1728d934ec2ee1241be9b1260f279b81acd2a6a57346d06d047a2650ff9bddd48fda6581751a690d80 + languageName: node + linkType: hard + "hosted-git-info@npm:^2.1.4": version: 2.8.9 resolution: "hosted-git-info@npm:2.8.9" @@ -12113,7 +12623,7 @@ __metadata: languageName: node linkType: hard -"joycon@npm:^3.0.1": +"joycon@npm:^3.0.1, joycon@npm:^3.1.1": version: 3.1.1 resolution: "joycon@npm:3.1.1" checksum: 131fb1e98c9065d067fd49b6e685487ac4ad4d254191d7aa2c9e3b90f4e9ca70430c43cad001602bdbdabcf58717d3b5c5b7461c1bd8e39478c8de706b3fe6ae @@ -12551,6 +13061,13 @@ __metadata: languageName: node linkType: hard +"lilconfig@npm:^3.1.1": + version: 3.1.2 + resolution: "lilconfig@npm:3.1.2" + checksum: f059630b1a9bddaeba83059db00c672b64dc14074e9f232adce32b38ca1b5686ab737eb665c5ba3c32f147f0002b4bee7311ad0386a9b98547b5623e87071fbe + languageName: node + linkType: hard + "lines-and-columns@npm:^1.1.6": version: 1.2.4 resolution: "lines-and-columns@npm:1.2.4" @@ -15384,6 +15901,29 @@ __metadata: languageName: node linkType: hard +"postcss-load-config@npm:^6.0.1": + version: 6.0.1 + resolution: "postcss-load-config@npm:6.0.1" + dependencies: + lilconfig: "npm:^3.1.1" + peerDependencies: + jiti: ">=1.21.0" + postcss: ">=8.0.9" + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + checksum: 74173a58816dac84e44853f7afbd283f4ef13ca0b6baeba27701214beec33f9e309b128f8102e2b173e8d45ecba45d279a9be94b46bf48d219626aa9b5730848 + languageName: node + linkType: hard + "postcss@npm:^8.4.27, postcss@npm:^8.4.32": version: 8.4.32 resolution: "postcss@npm:8.4.32" @@ -15559,6 +16099,13 @@ __metadata: languageName: node linkType: hard +"property-expr@npm:^2.0.5": + version: 2.0.6 + resolution: "property-expr@npm:2.0.6" + checksum: 69b7da15038a1146d6447c69c445306f66a33c425271235bb20507f1846dbf9577a8f9dfafe8acbfcb66f924b270157f155248308f026a68758f35fc72265b3c + languageName: node + linkType: hard + "property-information@npm:^6.0.0": version: 6.4.0 resolution: "property-information@npm:6.4.0" @@ -16390,6 +16937,69 @@ __metadata: languageName: node linkType: hard +"rollup@npm:^4.19.0": + version: 4.19.1 + resolution: "rollup@npm:4.19.1" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.19.1" + "@rollup/rollup-android-arm64": "npm:4.19.1" + "@rollup/rollup-darwin-arm64": "npm:4.19.1" + "@rollup/rollup-darwin-x64": "npm:4.19.1" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.19.1" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.19.1" + "@rollup/rollup-linux-arm64-gnu": "npm:4.19.1" + "@rollup/rollup-linux-arm64-musl": "npm:4.19.1" + "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.19.1" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.19.1" + "@rollup/rollup-linux-s390x-gnu": "npm:4.19.1" + "@rollup/rollup-linux-x64-gnu": "npm:4.19.1" + "@rollup/rollup-linux-x64-musl": "npm:4.19.1" + "@rollup/rollup-win32-arm64-msvc": "npm:4.19.1" + "@rollup/rollup-win32-ia32-msvc": "npm:4.19.1" + "@rollup/rollup-win32-x64-msvc": "npm:4.19.1" + "@types/estree": "npm:1.0.5" + fsevents: "npm:~2.3.2" + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-powerpc64le-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 2e526c38b4bcb22a058cf95e40c8c105a86f27d582c677c47df9315a17b18e75c772edc0773ca4d12d58ceca254bb5d63d4172041f6fd9f01e1a613d8bba6d09 + languageName: node + linkType: hard + "router@npm:^1.3.1": version: 1.3.8 resolution: "router@npm:1.3.8" @@ -17403,6 +18013,24 @@ __metadata: languageName: node linkType: hard +"sucrase@npm:^3.35.0": + version: 3.35.0 + resolution: "sucrase@npm:3.35.0" + dependencies: + "@jridgewell/gen-mapping": "npm:^0.3.2" + commander: "npm:^4.0.0" + glob: "npm:^10.3.10" + lines-and-columns: "npm:^1.1.6" + mz: "npm:^2.7.0" + pirates: "npm:^4.0.1" + ts-interface-checker: "npm:^0.1.9" + bin: + sucrase: bin/sucrase + sucrase-node: bin/sucrase-node + checksum: ac85f3359d2c2ecbf5febca6a24ae9bf96c931f05fde533c22a94f59c6a74895e5d5f0e871878dfd59c2697a75ebb04e4b2224ef0bfc24ca1210735c2ec191ef + languageName: node + linkType: hard + "superstatic@npm:^9.0.3": version: 9.0.3 resolution: "superstatic@npm:9.0.3" @@ -17648,6 +18276,13 @@ __metadata: languageName: node linkType: hard +"tiny-case@npm:^1.0.3": + version: 1.0.3 + resolution: "tiny-case@npm:1.0.3" + checksum: c0cbed35884a322265e2cd61ff435168d1ea523f88bf3864ce14a238ae9169e732649776964283a66e4eb882e655992081d4daf8c865042e2233425866111b35 + languageName: node + linkType: hard + "tinybench@npm:^2.5.0, tinybench@npm:^2.5.1": version: 2.5.1 resolution: "tinybench@npm:2.5.1" @@ -17697,6 +18332,13 @@ __metadata: languageName: node linkType: hard +"tinyrainbow@npm:^1.2.0": + version: 1.2.0 + resolution: "tinyrainbow@npm:1.2.0" + checksum: 7f78a4b997e5ba0f5ecb75e7ed786f30bab9063716e7dff24dd84013fb338802e43d176cb21ed12480561f5649a82184cf31efb296601a29d38145b1cdb4c192 + languageName: node + linkType: hard + "tinyspy@npm:^2.1.1, tinyspy@npm:^2.2.0": version: 2.2.0 resolution: "tinyspy@npm:2.2.0" @@ -17773,6 +18415,13 @@ __metadata: languageName: node linkType: hard +"toposort@npm:^2.0.2": + version: 2.0.2 + resolution: "toposort@npm:2.0.2" + checksum: ab9ca91fce4b972ccae9e2f539d755bf799a0c7eb60da07fd985fce0f14c159ed1e92305ff55697693b5bc13e300f5417db90e2593b127d421c9f6c440950222 + languageName: node + linkType: hard + "toucan-js@npm:^4.0.0": version: 4.0.0 resolution: "toucan-js@npm:4.0.0" @@ -18114,6 +18763,47 @@ __metadata: languageName: node linkType: hard +"tsup@npm:^8.2.3": + version: 8.2.3 + resolution: "tsup@npm:8.2.3" + dependencies: + bundle-require: "npm:^5.0.0" + cac: "npm:^6.7.14" + chokidar: "npm:^3.6.0" + consola: "npm:^3.2.3" + debug: "npm:^4.3.5" + esbuild: "npm:^0.23.0" + execa: "npm:^5.1.1" + globby: "npm:^11.1.0" + joycon: "npm:^3.1.1" + picocolors: "npm:^1.0.1" + postcss-load-config: "npm:^6.0.1" + resolve-from: "npm:^5.0.0" + rollup: "npm:^4.19.0" + source-map: "npm:0.8.0-beta.0" + sucrase: "npm:^3.35.0" + tree-kill: "npm:^1.2.2" + peerDependencies: + "@microsoft/api-extractor": ^7.36.0 + "@swc/core": ^1 + postcss: ^8.4.12 + typescript: ">=4.5.0" + peerDependenciesMeta: + "@microsoft/api-extractor": + optional: true + "@swc/core": + optional: true + postcss: + optional: true + typescript: + optional: true + bin: + tsup: dist/cli-default.js + tsup-node: dist/cli-node.js + checksum: 4a6fba80b441b400e44633db7e52d383cfd502119e6bdf7680ac07d5110eab2473d8b980a664c1564d0418d89c0e680b24a9f43d2d7da1193ce72259a863725a + languageName: node + linkType: hard + "tsutils@npm:^3.21.0": version: 3.21.0 resolution: "tsutils@npm:3.21.0" @@ -18794,6 +19484,13 @@ __metadata: languageName: node linkType: hard +"valibot@npm:^0.36.0": + version: 0.36.0 + resolution: "valibot@npm:0.36.0" + checksum: deff84cdcdc324d5010c2087e553cd26b07752ac18912c9152eccd241b507a49a9ad77fed57501d45bcbef9bec6a7a6707b17d9bef8d35e681d45f098a70e466 + languageName: node + linkType: hard + "valid-url@npm:^1": version: 1.0.9 resolution: "valid-url@npm:1.0.9" @@ -18995,6 +19692,21 @@ __metadata: languageName: node linkType: hard +"vite-node@npm:2.0.4": + version: 2.0.4 + resolution: "vite-node@npm:2.0.4" + dependencies: + cac: "npm:^6.7.14" + debug: "npm:^4.3.5" + pathe: "npm:^1.1.2" + tinyrainbow: "npm:^1.2.0" + vite: "npm:^5.0.0" + bin: + vite-node: vite-node.mjs + checksum: 2689b05b391b59cf3d15e1e80884e9b054f2ca90b2150cc7a08b0f234e79e6750a28cc8d107a57f005185e759c3bc020030f687065317fc37fe169ce17f4cdb7 + languageName: node + linkType: hard + "vite@npm:^3.0.0 || ^4.0.0 || ^5.0.0-0, vite@npm:^3.1.0 || ^4.0.0 || ^5.0.0-0, vite@npm:^5.0.0": version: 5.0.10 resolution: "vite@npm:5.0.10" @@ -19434,6 +20146,55 @@ __metadata: languageName: node linkType: hard +"vitest@npm:^2.0.4": + version: 2.0.4 + resolution: "vitest@npm:2.0.4" + dependencies: + "@ampproject/remapping": "npm:^2.3.0" + "@vitest/expect": "npm:2.0.4" + "@vitest/pretty-format": "npm:^2.0.4" + "@vitest/runner": "npm:2.0.4" + "@vitest/snapshot": "npm:2.0.4" + "@vitest/spy": "npm:2.0.4" + "@vitest/utils": "npm:2.0.4" + chai: "npm:^5.1.1" + debug: "npm:^4.3.5" + execa: "npm:^8.0.1" + magic-string: "npm:^0.30.10" + pathe: "npm:^1.1.2" + std-env: "npm:^3.7.0" + tinybench: "npm:^2.8.0" + tinypool: "npm:^1.0.0" + tinyrainbow: "npm:^1.2.0" + vite: "npm:^5.0.0" + vite-node: "npm:2.0.4" + why-is-node-running: "npm:^2.3.0" + peerDependencies: + "@edge-runtime/vm": "*" + "@types/node": ^18.0.0 || >=20.0.0 + "@vitest/browser": 2.0.4 + "@vitest/ui": 2.0.4 + happy-dom: "*" + jsdom: "*" + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@types/node": + optional: true + "@vitest/browser": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + bin: + vitest: vitest.mjs + checksum: 139200d0bda3270fd00641e4bd5524f78a2b1fe9a3d4a0d5ba2b6ed08bbcf6f1e711cc4bfd8b0d823628a2fcab00f822bb210bd5bf3c6a9260fd6115ea085a3d + languageName: node + linkType: hard + "walker@npm:^1.0.8": version: 1.0.8 resolution: "walker@npm:1.0.8" @@ -19582,6 +20343,18 @@ __metadata: languageName: node linkType: hard +"why-is-node-running@npm:^2.3.0": + version: 2.3.0 + resolution: "why-is-node-running@npm:2.3.0" + dependencies: + siginfo: "npm:^2.0.0" + stackback: "npm:0.0.2" + bin: + why-is-node-running: cli.js + checksum: 1cde0b01b827d2cf4cb11db962f3958b9175d5d9e7ac7361d1a7b0e2dc6069a263e69118bd974c4f6d0a890ef4eedfe34cf3d5167ec14203dbc9a18620537054 + languageName: node + linkType: hard + "widest-line@npm:^3.1.0": version: 3.1.0 resolution: "widest-line@npm:3.1.0" @@ -19993,6 +20766,18 @@ __metadata: languageName: node linkType: hard +"yup@npm:^1.4.0": + version: 1.4.0 + resolution: "yup@npm:1.4.0" + dependencies: + property-expr: "npm:^2.0.5" + tiny-case: "npm:^1.0.3" + toposort: "npm:^2.0.2" + type-fest: "npm:^2.19.0" + checksum: fe142141365eed0f78fb2e18bdd2f10bf101385dae12a5f9de14884448067bdca16a54b547fc0bffec04a098dd70b4519ff366422f3da006fd11a0717a7863ac + languageName: node + linkType: hard + "zip-stream@npm:^4.1.0": version: 4.1.1 resolution: "zip-stream@npm:4.1.1" @@ -20011,6 +20796,13 @@ __metadata: languageName: node linkType: hard +"zod@npm:^3.23.8": + version: 3.23.8 + resolution: "zod@npm:3.23.8" + checksum: 8f14c87d6b1b53c944c25ce7a28616896319d95bc46a9660fe441adc0ed0a81253b02b5abdaeffedbeb23bdd25a0bf1c29d2c12dd919aef6447652dd295e3e69 + languageName: node + linkType: hard + "zwitch@npm:^2.0.0": version: 2.0.4 resolution: "zwitch@npm:2.0.4"