commit c2dea48cbe9b662a6ced0743cfbb03ae44cb7187 Author: sinclair Date: Tue Dec 24 23:31:06 2024 +0900 Revision 0.8.0 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..23b08da --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,24 @@ +name: Build +on: [push, pull_request] +jobs: + TypeBox-Remix: + runs-on: ${{ matrix.os }} + strategy: + matrix: + node: [16.x, 18.x, 20.x] + os: [ubuntu-latest, windows-latest, macOS-latest] + steps: + - uses: actions/checkout@v3 + - name: Install Node + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node }} + + - name: Install Packages + run: npm install + + - name: Build Library + run: npm run build + + - name: Test Library + run: npm run test \ No newline at end of file diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 0000000..a59af70 --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,23 @@ +name: Build Nightly +on: + schedule: + - cron: '0 18 * * *' # 6pm Daily +jobs: + TypeBox-Remix-Nightly: + runs-on: ${{ matrix.os }} + strategy: + matrix: + node: [20.x] + os: [ubuntu-latest] + steps: + - uses: actions/checkout@v3 + - name: Install Node + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node }} + + - name: Install Packages + run: npm install + + - name: Build Library + run: npm run build \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ab0e875 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +target \ No newline at end of file diff --git a/benchmark/index.ts b/benchmark/index.ts new file mode 100644 index 0000000..bb5c7be --- /dev/null +++ b/benchmark/index.ts @@ -0,0 +1,85 @@ +import { TypeCompiler } from '@sinclair/typebox/compiler' +import { Value } from '@sinclair/typebox/value' +import { Box } from '@sinclair/typebox-remix' + +import * as v from 'valibot' +import * as z from 'zod' + +// ------------------------------------------------------------------ +// Benchmark +// ------------------------------------------------------------------ +function benchmark(library: string, using: string, callback: Function) { + const [now, iterations] = [Date.now(), 1_000_000] + for (let i = 0; i < iterations; i++) if (!callback()) throw Error('Invalid' + library + using) + const elapsed = `${Date.now() - now} ms`.padEnd(8) + return { library: library.padEnd(12), using: using.padEnd(16), iterations, elapsed } +} +// ------------------------------------------------------------------ +// Zod +// ------------------------------------------------------------------ +function zod() { + const T = z.object({ + x: z.number(), + y: z.number(), + z: z.number(), + }) + return benchmark('zod', 'zod', () => T.safeParse({ x: 1, y: 2, z: 3 }).success) +} +function zod_using_value() { + const T = Box( + z.object({ + x: z.number(), + y: z.number(), + z: z.number(), + }), + ) + return benchmark('zod', 'typebox:value', () => Value.Check(T, { x: 1, y: 2, z: 3 })) +} +function zod_using_compiler() { + const T = TypeCompiler.Compile( + Box( + z.object({ + x: z.number(), + y: z.number(), + z: z.number(), + }), + ), + ) + return benchmark('zod', 'typebox:compile', () => T.Check({ x: 1, y: 2, z: 3 })) +} +// ------------------------------------------------------------------ +// Valibot +// ------------------------------------------------------------------ +function valibot() { + const T = v.object({ + x: v.number(), + y: v.number(), + z: v.number(), + }) + return benchmark('valibot', 'valibot', () => v.safeParse(T, { x: 1, y: 2, z: 3 }).success) +} +function valibot_using_value() { + const T = Box( + v.object({ + x: v.number(), + y: v.number(), + z: v.number(), + }), + ) + return benchmark('valibot', 'typebox:value', () => Value.Check(T, { x: 1, y: 2, z: 3 })) +} +function valibot_using_compiler() { + const T = TypeCompiler.Compile( + Box( + v.object({ + x: v.number(), + y: v.number(), + z: v.number(), + }), + ), + ) + return benchmark('valibot', 'typebox:compile', () => T.Check({ x: 1, y: 2, z: 3 })) +} + +console.table([valibot(), valibot_using_value(), valibot_using_compiler()]) +console.table([zod(), zod_using_value(), zod_using_compiler()]) diff --git a/design/font.ttf b/design/font.ttf new file mode 100644 index 0000000..dc177d0 Binary files /dev/null and b/design/font.ttf differ diff --git a/design/typebox-remix.blend b/design/typebox-remix.blend new file mode 100644 index 0000000..7bfc4d3 Binary files /dev/null and b/design/typebox-remix.blend differ diff --git a/design/typebox-remix.blend1 b/design/typebox-remix.blend1 new file mode 100644 index 0000000..ddabb30 Binary files /dev/null and b/design/typebox-remix.blend1 differ diff --git a/design/valibot.jpg b/design/valibot.jpg new file mode 100644 index 0000000..a904596 Binary files /dev/null and b/design/valibot.jpg differ diff --git a/design/zod.jpg b/design/zod.jpg new file mode 100644 index 0000000..7bf0f8e Binary files /dev/null and b/design/zod.jpg differ diff --git a/example/index.ts b/example/index.ts new file mode 100644 index 0000000..a654555 --- /dev/null +++ b/example/index.ts @@ -0,0 +1,23 @@ +import { Box } from '@sinclair/typebox-remix' +import * as v from 'valibot' +import * as z from 'zod' + +// Valibot to TypeBox (Runtime) + +const V = Box( + v.object({ + x: v.number(), + y: v.number(), + z: v.number(), + }), +) + +// Zod to TypeBox (Static) + +const Z = Box( + z.object({ + a: z.string(), + b: z.string(), + c: z.string(), + }), +) diff --git a/hammer.mjs b/hammer.mjs new file mode 100644 index 0000000..14058dc --- /dev/null +++ b/hammer.mjs @@ -0,0 +1,70 @@ +import * as Fs from 'node:fs' + +// ------------------------------------------------------------------ +// Benchmark +// ------------------------------------------------------------------ +export async function benchmark(target = 'target/benchmark') { + await shell(`hammer run benchmark/index.ts --dist ${target}`) +} +// ------------------------------------------------------------------ +// Clean +// ------------------------------------------------------------------ +export async function clean() { + await folder('target').delete() +} +// ------------------------------------------------------------------ +// Start +// ------------------------------------------------------------------ +export async function start() { + await shell('hammer run example/index.ts --dist target/example') +} + +// ------------------------------------------------------------------------------- +// Format +// ------------------------------------------------------------------------------- +export async function format() { + await shell('prettier --no-semi --single-quote --print-width 240 --trailing-comma all --write test src benchmark example/index.ts') +} + +// ------------------------------------------------------------------ +// Test +// ------------------------------------------------------------------ +export async function test(filter = '') { + await shell(`hammer build ./test/index.ts --dist target/test --platform node`) + await shell(`mocha target/test/index.js -g "${filter}"`) +} +// ------------------------------------------------------------------ +// Build +// ------------------------------------------------------------------ +export async function build_check(target = 'target/build') { + const { version } = JSON.parse(Fs.readFileSync('package.json', 'utf8')) + await shell(`cd ${target} && attw sinclair-typebox-remix-${version}.tgz --ignore-rules unexpected-module-syntax`) +} +export async function build(target = 'target/build') { + await test() + await clean() + await shell(`tsc -p src/tsconfig.json --outDir ${target} --declaration`) + await folder(target).add('package.json') + await folder(target).add('readme.md') + await folder(target).add('license') + await shell(`cd ${target} && npm pack`) + await build_check(target) +} +// ------------------------------------------------------------- +// Publish +// ------------------------------------------------------------- +export async function publish(otp, target = 'target/build') { + const { version } = JSON.parse(Fs.readFileSync('package.json', 'utf8')) + if(version.includes('-dev')) throw Error(`package version should not include -dev specifier`) + await shell(`cd ${target} && npm publish sinclair-typebox-remix-${version}.tgz --access=public --otp ${otp}`) + await shell(`git tag ${version}`) + await shell(`git push origin ${version}`) +} +// ------------------------------------------------------------- +// Publish-Dev +// ------------------------------------------------------------- +export async function publish_dev(otp, target = 'target/build') { + const { version } = JSON.parse(Fs.readFileSync(`${target}/package.json`, 'utf8')) + if(!version.includes('-dev')) throw Error(`development package version should include -dev specifier`) + await shell(`cd ${target} && npm publish sinclair-typebox-remix-${version}.tgz --access=public --otp ${otp} --tag dev`) +} \ No newline at end of file diff --git a/license b/license new file mode 100644 index 0000000..1ce8df6 --- /dev/null +++ b/license @@ -0,0 +1,23 @@ +@sinclair/typebox-remix + +The MIT License (MIT) + +Copyright (c) 2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..60de87a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3293 @@ +{ + "name": "@sinclair/typebox-remix", + "version": "0.8.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "@sinclair/typebox-remix", + "version": "0.8.0", + "license": "MIT", + "devDependencies": { + "@arethetypeswrong/cli": "^0.17.2", + "@sinclair/hammer": "^0.18.0", + "@types/mocha": "^10.0.10", + "@types/node": "^22.10.2", + "mocha": "^11.0.1", + "prettier": "^3.4.2", + "typescript": "^5.7.2" + }, + "optionalDependencies": { + "valibot": ">=1.0.0-beta.9", + "zod": ">=3.24.1" + }, + "peerDependencies": { + "@sinclair/typebox": ">=0.34.13" + } + }, + "node_modules/@andrewbranch/untar.js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@andrewbranch/untar.js/-/untar.js-1.0.3.tgz", + "integrity": "sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==", + "dev": true + }, + "node_modules/@arethetypeswrong/cli": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/cli/-/cli-0.17.2.tgz", + "integrity": "sha512-/u2VcQJ8PKc4hcao/vXnHrYLEI/sQqKarbHi+NEIfvdymaW5o62XOCXy2yvalQa/vR+AAD/QNEgAUzHo5f7hrw==", + "dev": true, + "dependencies": { + "@arethetypeswrong/core": "0.17.2", + "chalk": "^4.1.2", + "cli-table3": "^0.6.3", + "commander": "^10.0.1", + "marked": "^9.1.2", + "marked-terminal": "^7.1.0", + "semver": "^7.5.4" + }, + "bin": { + "attw": "dist/index.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@arethetypeswrong/core": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.17.2.tgz", + "integrity": "sha512-JYeLgS4rQ2l3gHCabaka3atsEyskfpx+WqUbo+6l8LApILJgr0/XDb7KNC9Ovevp4iPVF2Q73oshpgOKJ3uDRQ==", + "dev": true, + "dependencies": { + "@andrewbranch/untar.js": "^1.0.3", + "cjs-module-lexer": "^1.2.3", + "fflate": "^0.8.2", + "lru-cache": "^10.4.3", + "semver": "^7.5.4", + "typescript": "5.6.1-rc", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@arethetypeswrong/core/node_modules/typescript": { + "version": "5.6.1-rc", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.1-rc.tgz", + "integrity": "sha512-E3b2+1zEFu84jB0YQi9BORDjz9+jGbwwy1Zi3G0LUNw7a7cePUrHMRNy8aPh53nXpkFGVHSxIZo5vKTfYaFiBQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.7.tgz", + "integrity": "sha512-IKznSJOsVUuyt7cDzzSZyqBEcZe+7WlBqTVXiF1OXP/4Nm387ToaXZ0fyLwI1iBlI/bzpxVq411QE2/Bt2XWWw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@sinclair/hammer": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@sinclair/hammer/-/hammer-0.18.0.tgz", + "integrity": "sha512-nIrsOWvvCV/SjTSU4qcOsY3mEO8ErN2WBWzbn6mVpqDajy36lG9WbDEfR6Agm3LbN2pdPl1HGjKuiHpbpOTZ2A==", + "dev": true, + "dependencies": { + "esbuild": "0.15.7" + }, + "bin": { + "hammer": "hammer" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.34.13", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.13.tgz", + "integrity": "sha512-ceVKqyCEgC355Kw0s/0tyfY9MzMQINSykJ/pG2w6YnaZyrcjV48svZpr8lVZrYgWjzOmrIPBhQRAtr/7eJpA5g==", + "peer": true + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@types/mocha": { + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "dev": true + }, + "node_modules/@types/node": { + "version": "22.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", + "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", + "dev": true, + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", + "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", + "dev": true + }, + "node_modules/cli-highlight": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "highlight.js": "^10.7.1", + "mz": "^2.4.0", + "parse5": "^5.1.1", + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" + }, + "bin": { + "highlight": "bin/highlight" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.0.0" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "dev": true + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esbuild": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.7.tgz", + "integrity": "sha512-7V8tzllIbAQV1M4QoE52ImKu8hT/NLGlGXkiDsbEU5PS6K8Mn09ZnYoS+dcmHxOS9CRsV4IRAMdT3I67IyUNXw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/linux-loong64": "0.15.7", + "esbuild-android-64": "0.15.7", + "esbuild-android-arm64": "0.15.7", + "esbuild-darwin-64": "0.15.7", + "esbuild-darwin-arm64": "0.15.7", + "esbuild-freebsd-64": "0.15.7", + "esbuild-freebsd-arm64": "0.15.7", + "esbuild-linux-32": "0.15.7", + "esbuild-linux-64": "0.15.7", + "esbuild-linux-arm": "0.15.7", + "esbuild-linux-arm64": "0.15.7", + "esbuild-linux-mips64le": "0.15.7", + "esbuild-linux-ppc64le": "0.15.7", + "esbuild-linux-riscv64": "0.15.7", + "esbuild-linux-s390x": "0.15.7", + "esbuild-netbsd-64": "0.15.7", + "esbuild-openbsd-64": "0.15.7", + "esbuild-sunos-64": "0.15.7", + "esbuild-windows-32": "0.15.7", + "esbuild-windows-64": "0.15.7", + "esbuild-windows-arm64": "0.15.7" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.7.tgz", + "integrity": "sha512-p7rCvdsldhxQr3YHxptf1Jcd86dlhvc3EQmQJaZzzuAxefO9PvcI0GLOa5nCWem1AJ8iMRu9w0r5TG8pHmbi9w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.7.tgz", + "integrity": "sha512-L775l9ynJT7rVqRM5vo+9w5g2ysbOCfsdLV4CWanTZ1k/9Jb3IYlQ06VCI1edhcosTYJRECQFJa3eAvkx72eyQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.7.tgz", + "integrity": "sha512-KGPt3r1c9ww009t2xLB6Vk0YyNOXh7hbjZ3EecHoVDxgtbUlYstMPDaReimKe6eOEfyY4hBEEeTvKwPsiH5WZg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.7.tgz", + "integrity": "sha512-kBIHvtVqbSGajN88lYMnR3aIleH3ABZLLFLxwL2stiuIGAjGlQW741NxVTpUHQXUmPzxi6POqc9npkXa8AcSZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.7.tgz", + "integrity": "sha512-hESZB91qDLV5MEwNxzMxPfbjAhOmtfsr9Wnuci7pY6TtEh4UDuevmGmkUIjX/b+e/k4tcNBMf7SRQ2mdNuK/HQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.7.tgz", + "integrity": "sha512-dLFR0ChH5t+b3J8w0fVKGvtwSLWCv7GYT2Y2jFGulF1L5HftQLzVGN+6pi1SivuiVSmTh28FwUhi9PwQicXI6Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.7.tgz", + "integrity": "sha512-v3gT/LsONGUZcjbt2swrMjwxo32NJzk+7sAgtxhGx1+ZmOFaTRXBAi1PPfgpeo/J//Un2jIKm/I+qqeo4caJvg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.7.tgz", + "integrity": "sha512-LxXEfLAKwOVmm1yecpMmWERBshl+Kv5YJ/1KnyAr6HRHFW8cxOEsEfisD3sVl/RvHyW//lhYUVSuy9jGEfIRAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.7.tgz", + "integrity": "sha512-JKgAHtMR5f75wJTeuNQbyznZZa+pjiUHV7sRZp42UNdyXC6TiUYMW/8z8yIBAr2Fpad8hM1royZKQisqPABPvQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.7.tgz", + "integrity": "sha512-P3cfhudpzWDkglutWgXcT2S7Ft7o2e3YDMrP1n0z2dlbUZghUkKCyaWw0zhp4KxEEzt/E7lmrtRu/pGWnwb9vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.7.tgz", + "integrity": "sha512-T7XKuxl0VpeFLCJXub6U+iybiqh0kM/bWOTb4qcPyDDwNVhLUiPcGdG2/0S7F93czUZOKP57YiLV8YQewgLHKw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.7.tgz", + "integrity": "sha512-6mGuC19WpFN7NYbecMIJjeQgvDb5aMuvyk0PDYBJrqAEMkTwg3Z98kEKuCm6THHRnrgsdr7bp4SruSAxEM4eJw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.7.tgz", + "integrity": "sha512-uUJsezbswAYo/X7OU/P+PuL/EI9WzxsEQXDekfwpQ23uGiooxqoLFAPmXPcRAt941vjlY9jtITEEikWMBr+F/g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.7.tgz", + "integrity": "sha512-+tO+xOyTNMc34rXlSxK7aCwJgvQyffqEM5MMdNDEeMU3ss0S6wKvbBOQfgd5jRPblfwJ6b+bKiz0g5nABpY0QQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.7.tgz", + "integrity": "sha512-yVc4Wz+Pu3cP5hzm5kIygNPrjar/v5WCSoRmIjCPWfBVJkZNb5brEGKUlf+0Y759D48BCWa0WHrWXaNy0DULTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.7.tgz", + "integrity": "sha512-GsimbwC4FSR4lN3wf8XmTQ+r8/0YSQo21rWDL0XFFhLHKlzEA4SsT1Tl8bPYu00IU6UWSJ+b3fG/8SB69rcuEQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.7.tgz", + "integrity": "sha512-8CDI1aL/ts0mDGbWzjEOGKXnU7p3rDzggHSBtVryQzkSOsjCHRVe0iFYUuhczlxU1R3LN/E7HgUO4NXzGGP/Ag==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.7.tgz", + "integrity": "sha512-cOnKXUEPS8EGCzRSFa1x6NQjGhGsFlVgjhqGEbLTPsA7x4RRYiy2RKoArNUU4iR2vHmzqS5Gr84MEumO/wxYKA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.7.tgz", + "integrity": "sha512-7MI08Ec2sTIDv+zH6StNBKO+2hGUYIT42GmFyW6MBBWWtJhTcQLinKS6ldIN1d52MXIbiJ6nXyCJ+LpL4jBm3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.7.tgz", + "integrity": "sha512-R06nmqBlWjKHddhRJYlqDd3Fabx9LFdKcjoOy08YLimwmsswlFBJV4rXzZCxz/b7ZJXvrZgj8DDv1ewE9+StMw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "dev": true + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/marked": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", + "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 16" + } + }, + "node_modules/marked-terminal": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.2.1.tgz", + "integrity": "sha512-rQ1MoMFXZICWNsKMiiHwP/Z+92PLKskTPXj+e7uwXmuMPkNn7iTqC+IvDekVm1MPeC9wYQeLxeFaOvudRR/XbQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^7.0.0", + "ansi-regex": "^6.1.0", + "chalk": "^5.3.0", + "cli-highlight": "^2.1.11", + "cli-table3": "^0.6.5", + "node-emoji": "^2.1.3", + "supports-hyperlinks": "^3.1.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "marked": ">=1 <15" + } + }, + "node_modules/marked-terminal/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mocha": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.0.1.tgz", + "integrity": "sha512-+3GkODfsDG71KSCQhc4IekSW+ItCK/kiez1Z28ksWvYhKXV/syxMlerR/sC7whDp7IyreZ4YxceMLdTs5hQE8A==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^10.4.5", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/node-emoji": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", + "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, + "node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prettier": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", + "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "dev": true, + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.1.0.tgz", + "integrity": "sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "devOptional": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true + }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/valibot": { + "version": "1.0.0-beta.9", + "resolved": "https://registry.npmjs.org/valibot/-/valibot-1.0.0-beta.9.tgz", + "integrity": "sha512-yEX8gMAZ2R1yI2uwOO4NCtVnJQx36zn3vD0omzzj9FhcoblvPukENIiRZXKZwCnqSeV80bMm8wNiGhQ0S8fiww==", + "optional": true, + "peerDependencies": { + "typescript": ">=5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.24.1", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", + "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + }, + "dependencies": { + "@andrewbranch/untar.js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@andrewbranch/untar.js/-/untar.js-1.0.3.tgz", + "integrity": "sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==", + "dev": true + }, + "@arethetypeswrong/cli": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/cli/-/cli-0.17.2.tgz", + "integrity": "sha512-/u2VcQJ8PKc4hcao/vXnHrYLEI/sQqKarbHi+NEIfvdymaW5o62XOCXy2yvalQa/vR+AAD/QNEgAUzHo5f7hrw==", + "dev": true, + "requires": { + "@arethetypeswrong/core": "0.17.2", + "chalk": "^4.1.2", + "cli-table3": "^0.6.3", + "commander": "^10.0.1", + "marked": "^9.1.2", + "marked-terminal": "^7.1.0", + "semver": "^7.5.4" + } + }, + "@arethetypeswrong/core": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.17.2.tgz", + "integrity": "sha512-JYeLgS4rQ2l3gHCabaka3atsEyskfpx+WqUbo+6l8LApILJgr0/XDb7KNC9Ovevp4iPVF2Q73oshpgOKJ3uDRQ==", + "dev": true, + "requires": { + "@andrewbranch/untar.js": "^1.0.3", + "cjs-module-lexer": "^1.2.3", + "fflate": "^0.8.2", + "lru-cache": "^10.4.3", + "semver": "^7.5.4", + "typescript": "5.6.1-rc", + "validate-npm-package-name": "^5.0.0" + }, + "dependencies": { + "typescript": { + "version": "5.6.1-rc", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.1-rc.tgz", + "integrity": "sha512-E3b2+1zEFu84jB0YQi9BORDjz9+jGbwwy1Zi3G0LUNw7a7cePUrHMRNy8aPh53nXpkFGVHSxIZo5vKTfYaFiBQ==", + "dev": true + } + } + }, + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.7.tgz", + "integrity": "sha512-IKznSJOsVUuyt7cDzzSZyqBEcZe+7WlBqTVXiF1OXP/4Nm387ToaXZ0fyLwI1iBlI/bzpxVq411QE2/Bt2XWWw==", + "dev": true, + "optional": true + }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, + "@sinclair/hammer": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@sinclair/hammer/-/hammer-0.18.0.tgz", + "integrity": "sha512-nIrsOWvvCV/SjTSU4qcOsY3mEO8ErN2WBWzbn6mVpqDajy36lG9WbDEfR6Agm3LbN2pdPl1HGjKuiHpbpOTZ2A==", + "dev": true, + "requires": { + "esbuild": "0.15.7" + } + }, + "@sinclair/typebox": { + "version": "0.34.13", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.13.tgz", + "integrity": "sha512-ceVKqyCEgC355Kw0s/0tyfY9MzMQINSykJ/pG2w6YnaZyrcjV48svZpr8lVZrYgWjzOmrIPBhQRAtr/7eJpA5g==", + "peer": true + }, + "@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true + }, + "@types/mocha": { + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "dev": true + }, + "@types/node": { + "version": "22.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", + "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", + "dev": true, + "requires": { + "undici-types": "~6.20.0" + } + }, + "ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true + }, + "ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "requires": { + "environment": "^1.0.0" + } + }, + "ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "requires": { + "fill-range": "^7.1.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, + "chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "cjs-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", + "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", + "dev": true + }, + "cli-highlight": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "highlight.js": "^10.7.1", + "mz": "^2.4.0", + "parse5": "^5.1.1", + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" + } + }, + "cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "requires": { + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true + }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "dev": true + }, + "environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true + }, + "esbuild": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.7.tgz", + "integrity": "sha512-7V8tzllIbAQV1M4QoE52ImKu8hT/NLGlGXkiDsbEU5PS6K8Mn09ZnYoS+dcmHxOS9CRsV4IRAMdT3I67IyUNXw==", + "dev": true, + "requires": { + "@esbuild/linux-loong64": "0.15.7", + "esbuild-android-64": "0.15.7", + "esbuild-android-arm64": "0.15.7", + "esbuild-darwin-64": "0.15.7", + "esbuild-darwin-arm64": "0.15.7", + "esbuild-freebsd-64": "0.15.7", + "esbuild-freebsd-arm64": "0.15.7", + "esbuild-linux-32": "0.15.7", + "esbuild-linux-64": "0.15.7", + "esbuild-linux-arm": "0.15.7", + "esbuild-linux-arm64": "0.15.7", + "esbuild-linux-mips64le": "0.15.7", + "esbuild-linux-ppc64le": "0.15.7", + "esbuild-linux-riscv64": "0.15.7", + "esbuild-linux-s390x": "0.15.7", + "esbuild-netbsd-64": "0.15.7", + "esbuild-openbsd-64": "0.15.7", + "esbuild-sunos-64": "0.15.7", + "esbuild-windows-32": "0.15.7", + "esbuild-windows-64": "0.15.7", + "esbuild-windows-arm64": "0.15.7" + } + }, + "esbuild-android-64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.7.tgz", + "integrity": "sha512-p7rCvdsldhxQr3YHxptf1Jcd86dlhvc3EQmQJaZzzuAxefO9PvcI0GLOa5nCWem1AJ8iMRu9w0r5TG8pHmbi9w==", + "dev": true, + "optional": true + }, + "esbuild-android-arm64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.7.tgz", + "integrity": "sha512-L775l9ynJT7rVqRM5vo+9w5g2ysbOCfsdLV4CWanTZ1k/9Jb3IYlQ06VCI1edhcosTYJRECQFJa3eAvkx72eyQ==", + "dev": true, + "optional": true + }, + "esbuild-darwin-64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.7.tgz", + "integrity": "sha512-KGPt3r1c9ww009t2xLB6Vk0YyNOXh7hbjZ3EecHoVDxgtbUlYstMPDaReimKe6eOEfyY4hBEEeTvKwPsiH5WZg==", + "dev": true, + "optional": true + }, + "esbuild-darwin-arm64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.7.tgz", + "integrity": "sha512-kBIHvtVqbSGajN88lYMnR3aIleH3ABZLLFLxwL2stiuIGAjGlQW741NxVTpUHQXUmPzxi6POqc9npkXa8AcSZQ==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.7.tgz", + "integrity": "sha512-hESZB91qDLV5MEwNxzMxPfbjAhOmtfsr9Wnuci7pY6TtEh4UDuevmGmkUIjX/b+e/k4tcNBMf7SRQ2mdNuK/HQ==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-arm64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.7.tgz", + "integrity": "sha512-dLFR0ChH5t+b3J8w0fVKGvtwSLWCv7GYT2Y2jFGulF1L5HftQLzVGN+6pi1SivuiVSmTh28FwUhi9PwQicXI6Q==", + "dev": true, + "optional": true + }, + "esbuild-linux-32": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.7.tgz", + "integrity": "sha512-v3gT/LsONGUZcjbt2swrMjwxo32NJzk+7sAgtxhGx1+ZmOFaTRXBAi1PPfgpeo/J//Un2jIKm/I+qqeo4caJvg==", + "dev": true, + "optional": true + }, + "esbuild-linux-64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.7.tgz", + "integrity": "sha512-LxXEfLAKwOVmm1yecpMmWERBshl+Kv5YJ/1KnyAr6HRHFW8cxOEsEfisD3sVl/RvHyW//lhYUVSuy9jGEfIRAQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.7.tgz", + "integrity": "sha512-JKgAHtMR5f75wJTeuNQbyznZZa+pjiUHV7sRZp42UNdyXC6TiUYMW/8z8yIBAr2Fpad8hM1royZKQisqPABPvQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.7.tgz", + "integrity": "sha512-P3cfhudpzWDkglutWgXcT2S7Ft7o2e3YDMrP1n0z2dlbUZghUkKCyaWw0zhp4KxEEzt/E7lmrtRu/pGWnwb9vw==", + "dev": true, + "optional": true + }, + "esbuild-linux-mips64le": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.7.tgz", + "integrity": "sha512-T7XKuxl0VpeFLCJXub6U+iybiqh0kM/bWOTb4qcPyDDwNVhLUiPcGdG2/0S7F93czUZOKP57YiLV8YQewgLHKw==", + "dev": true, + "optional": true + }, + "esbuild-linux-ppc64le": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.7.tgz", + "integrity": "sha512-6mGuC19WpFN7NYbecMIJjeQgvDb5aMuvyk0PDYBJrqAEMkTwg3Z98kEKuCm6THHRnrgsdr7bp4SruSAxEM4eJw==", + "dev": true, + "optional": true + }, + "esbuild-linux-riscv64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.7.tgz", + "integrity": "sha512-uUJsezbswAYo/X7OU/P+PuL/EI9WzxsEQXDekfwpQ23uGiooxqoLFAPmXPcRAt941vjlY9jtITEEikWMBr+F/g==", + "dev": true, + "optional": true + }, + "esbuild-linux-s390x": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.7.tgz", + "integrity": "sha512-+tO+xOyTNMc34rXlSxK7aCwJgvQyffqEM5MMdNDEeMU3ss0S6wKvbBOQfgd5jRPblfwJ6b+bKiz0g5nABpY0QQ==", + "dev": true, + "optional": true + }, + "esbuild-netbsd-64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.7.tgz", + "integrity": "sha512-yVc4Wz+Pu3cP5hzm5kIygNPrjar/v5WCSoRmIjCPWfBVJkZNb5brEGKUlf+0Y759D48BCWa0WHrWXaNy0DULTQ==", + "dev": true, + "optional": true + }, + "esbuild-openbsd-64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.7.tgz", + "integrity": "sha512-GsimbwC4FSR4lN3wf8XmTQ+r8/0YSQo21rWDL0XFFhLHKlzEA4SsT1Tl8bPYu00IU6UWSJ+b3fG/8SB69rcuEQ==", + "dev": true, + "optional": true + }, + "esbuild-sunos-64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.7.tgz", + "integrity": "sha512-8CDI1aL/ts0mDGbWzjEOGKXnU7p3rDzggHSBtVryQzkSOsjCHRVe0iFYUuhczlxU1R3LN/E7HgUO4NXzGGP/Ag==", + "dev": true, + "optional": true + }, + "esbuild-windows-32": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.7.tgz", + "integrity": "sha512-cOnKXUEPS8EGCzRSFa1x6NQjGhGsFlVgjhqGEbLTPsA7x4RRYiy2RKoArNUU4iR2vHmzqS5Gr84MEumO/wxYKA==", + "dev": true, + "optional": true + }, + "esbuild-windows-64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.7.tgz", + "integrity": "sha512-7MI08Ec2sTIDv+zH6StNBKO+2hGUYIT42GmFyW6MBBWWtJhTcQLinKS6ldIN1d52MXIbiJ6nXyCJ+LpL4jBm3Q==", + "dev": true, + "optional": true + }, + "esbuild-windows-arm64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.7.tgz", + "integrity": "sha512-R06nmqBlWjKHddhRJYlqDd3Fabx9LFdKcjoOy08YLimwmsswlFBJV4rXzZCxz/b7ZJXvrZgj8DDv1ewE9+StMw==", + "dev": true, + "optional": true + }, + "escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "dev": true + }, + "fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + } + }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "optional": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "dependencies": { + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "marked": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", + "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", + "dev": true + }, + "marked-terminal": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.2.1.tgz", + "integrity": "sha512-rQ1MoMFXZICWNsKMiiHwP/Z+92PLKskTPXj+e7uwXmuMPkNn7iTqC+IvDekVm1MPeC9wYQeLxeFaOvudRR/XbQ==", + "dev": true, + "requires": { + "ansi-escapes": "^7.0.0", + "ansi-regex": "^6.1.0", + "chalk": "^5.3.0", + "cli-highlight": "^2.1.11", + "cli-table3": "^0.6.5", + "node-emoji": "^2.1.3", + "supports-hyperlinks": "^3.1.0" + }, + "dependencies": { + "chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true + } + } + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true + }, + "mocha": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.0.1.tgz", + "integrity": "sha512-+3GkODfsDG71KSCQhc4IekSW+ItCK/kiez1Z28ksWvYhKXV/syxMlerR/sC7whDp7IyreZ4YxceMLdTs5hQE8A==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^10.4.5", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node-emoji": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", + "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", + "dev": true, + "requires": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true + }, + "parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "requires": { + "parse5": "^6.0.1" + }, + "dependencies": { + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + } + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "requires": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + } + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "prettier": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", + "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true + }, + "serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, + "skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "dev": true, + "requires": { + "unicode-emoji-modifier-base": "^1.0.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + } + } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + } + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.1.0.tgz", + "integrity": "sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "requires": { + "any-promise": "^1.0.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "requires": { + "thenify": ">= 3.1.0 < 4" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "devOptional": true + }, + "undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true + }, + "unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "dev": true + }, + "valibot": { + "version": "1.0.0-beta.9", + "resolved": "https://registry.npmjs.org/valibot/-/valibot-1.0.0-beta.9.tgz", + "integrity": "sha512-yEX8gMAZ2R1yI2uwOO4NCtVnJQx36zn3vD0omzzj9FhcoblvPukENIiRZXKZwCnqSeV80bMm8wNiGhQ0S8fiww==", + "optional": true, + "requires": {} + }, + "validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + }, + "zod": { + "version": "3.24.1", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", + "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", + "optional": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..eee3466 --- /dev/null +++ b/package.json @@ -0,0 +1,52 @@ +{ + "name": "@sinclair/typebox-remix", + "version": "0.8.0", + "description": "Integrate Valibot and Zod with TypeBox", + "author": "sinclairzx81", + "license": "MIT", + "scripts": { + "benchmark": "hammer task benchmark", + "clean": "hammer task clean", + "start": "hammer task start", + "format": "hammer task format", + "test": "hammer task test", + "build": "hammer task build", + "publish": "hammer task publish" + }, + "main": "index.js", + "module": "index.js", + "exports": { + ".": { + "import": "./index.js", + "types": "./index.d.ts" + }, + "./typebox": { + "import": "./typebox.js", + "types": "./typebox.d.ts" + }, + "./zod": { + "import": "./zod.js", + "types": "./zod.d.ts" + }, + "./valibot": { + "import": "./valibot.js", + "types": "./valibot.d.ts" + } + }, + "peerDependencies": { + "@sinclair/typebox": ">=0.34.13" + }, + "optionalDependencies": { + "valibot": ">=1.0.0-beta.9", + "zod": ">=3.24.1" + }, + "devDependencies": { + "@arethetypeswrong/cli": "^0.17.2", + "@sinclair/hammer": "^0.18.0", + "@types/mocha": "^10.0.10", + "@types/node": "^22.10.2", + "mocha": "^11.0.1", + "prettier": "^3.4.2", + "typescript": "^5.7.2" + } +} diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..1107752 --- /dev/null +++ b/readme.md @@ -0,0 +1,141 @@ +
+ +

TypeBox Remix

+ +

Integrate Valibot and Zod with TypeBox

+ + + +
+
+ +[![npm version](https://badge.fury.io/js/%40sinclair%2Ftypebox-remix.svg)](https://badge.fury.io/js/%40sinclair%2Ftypebox-remix) +[![Downloads](https://img.shields.io/npm/dm/%40sinclair%2Ftypebox-remix.svg)](https://www.npmjs.com/package/%40sinclair%2Ftypebox-remix) +[![Build](https://github.com/sinclairzx81/typebox-remix/actions/workflows/build.yml/badge.svg)](https://github.com/sinclairzx81/typebox-remix/actions/workflows/build.yml) +[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + +
+ +## Install + +```bash +$ npm install @sinclair/typebox-remix --save +``` + +## Example + +TypeBox Remix converts Valibot and Zod Types into TypeBox compatible schematics + +```typescript +import { Box } from '@sinclair/typebox-remix' + +import * as v from 'valibot' +import * as z from 'zod' + +// Valibot to TypeBox (Runtime) + +const V = Box(v.object({ // const V = { + x: v.number(), // type: 'object', + y: v.number(), // required: ['x', 'y', 'z'], + z: v.number() // properties: { +})) // x: { type: 'number' }, + // y: { type: 'number' }, + // z: { type: 'number' } + // } + // } + +// Zod to TypeBox (Static) + +const Z = Box(z.object({ // const Z: TObject<{ + a: z.string(), // a: TString, + b: z.string(), // b: TString, + c: z.string() // c: TString +})) // }> +``` + +## Overview + +TypeBox Remix is a library that makes Zod and Valibot compatible with TypeBox. It works by structurally remapping the types provided by these libraries into Json Schema schematics, enabling them to integrate with the TypeBox infrastructure and making them compatible with Ajv. + +This library can be used to integrate Valibot and Zod into server infrastructures that standardize on the Json Schema specification. By transforming these libraries to Json Schema, they can benefit from accelerated type checking and achieve better interoperability with non-JavaScript based systems. + +License MIT + +## Contents + +- [Install](#Install) +- [Overview](#Overview) +- [Usage](#Usage) + - [Valibot](#Valibot) + - [Zod](#Zod) +- [Benchmark](#Benchmark) +- [Contribute](#Contribute) + +## Usage + +TypeBox Remix provides a singular Box function to transform Valibot and Zod types into TypeBox schematics. The top-level export is capable of transforming both Valibot and Zod, but you should use the appropriate submodule depending on which library you are using. + +### Valibot + +Use the `/valibot` submodule if you only have Valibot installed. + +```typescript +import { Box } from '@sinclair/typebox-remix/valibot' // Transform Valibot Only + +import * as v from 'valibot' + +const T = Box(v.string()) // const T = { type: 'string' } +``` + +Refer to the Valibot [documentation](https://valibot.dev/) for more information on this type library. + +### Zod + +Use the `/zod` submodule if you only have Zod installed. + +```typescript +import { Box } from '@sinclair/typebox-remix/zod' // Transform Zod Only + +import * as z from 'zod' + +const T = Box(z.string()) // const T = { type: 'string' } +``` + +Refer to the Zod [documentation](https://zod.dev/) for more information on this type library. + + + +## Benchmark + +This project manages a benchmark that runs type check performance using Zod, Valibot and TypeBox validators. The benchmark is setup to run 1 million check operations per library and validator pairing and reports the elapsed time taken to complete. + +### Type + +```typescript +const T = { x: number, y: number, z: number } +``` + +### Results +```typescript +┌─────────┬────────────────┬────────────────────┬────────────┬────────────┐ +│ (index) │ library │ using │ iterations │ elapsed │ +├─────────┼────────────────┼────────────────────┼────────────┼────────────┤ +│ 0 │ 'valibot ' │ 'valibot ' │ 1000000 │ '378 ms ' │ +│ 1 │ 'valibot ' │ 'typebox:value ' │ 1000000 │ '125 ms ' │ +│ 2 │ 'valibot ' │ 'typebox:compile ' │ 1000000 │ '4 ms ' │ +└─────────┴────────────────┴────────────────────┴────────────┴────────────┘ +┌─────────┬────────────────┬────────────────────┬────────────┬────────────┐ +│ (index) │ library │ using │ iterations │ elapsed │ +├─────────┼────────────────┼────────────────────┼────────────┼────────────┤ +│ 0 │ 'zod ' │ 'zod ' │ 1000000 │ '444 ms ' │ +│ 1 │ 'zod ' │ 'typebox:value ' │ 1000000 │ '127 ms ' │ +│ 2 │ 'zod ' │ 'typebox:compile ' │ 1000000 │ '5 ms ' │ +└─────────┴────────────────┴────────────────────┴────────────┴────────────┘ +``` + +For community benchmarks, refer to the [runtime-type-benchmarks](https://github.com/moltar/typescript-runtime-type-benchmarks) project. + +## Contribute + +This project is open to community contribution. Please ensure you submit an open issue before submitting your pull request. TypeBox and associated projects prefer open community discussion before accepting new features. + diff --git a/src/box.ts b/src/box.ts new file mode 100644 index 0000000..3e4bb75 --- /dev/null +++ b/src/box.ts @@ -0,0 +1,58 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox-remix + +The MIT License (MIT) + +Copyright (c) 2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +import { TSchema, KindGuard, Unknown, type TUnknown } from '@sinclair/typebox' +import * as TypeBox from './typebox' +import * as Valibot from './valibot' +import * as Zod from './zod' + +/** Converts a Zod, Valibot or TypeBox Type to a TypeBox Type */ +// prettier-ignore +export type TBox = ( + TypeBox.TBox extends infer Schema extends TSchema ? Schema : + Valibot.TBox extends infer Schema extends TSchema ? Schema : + Zod.TBox extends infer Schema extends TSchema ? Schema : + TUnknown +) +/** Converts a Zod, Valibot or TypeBox Type to a TypeBox Type */ +// prettier-ignore +export function Box(type: Type): TBox { + { + const result = TypeBox.Box(type) + if(KindGuard.IsSchema(result)) return result as never + } + { + const result = Valibot.Box(type) + if(KindGuard.IsSchema(result)) return result as never + } + { + const result = Zod.Box(type) + if(KindGuard.IsSchema(result)) return result as never + } + return Unknown() as never +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..70949b9 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,29 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox-remix + +The MIT License (MIT) + +Copyright (c) 2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +export * from './box' diff --git a/src/tsconfig.json b/src/tsconfig.json new file mode 100644 index 0000000..9f4a7e2 --- /dev/null +++ b/src/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../tsconfig.json", + "files": ["index.ts"] +} diff --git a/src/typebox.ts b/src/typebox.ts new file mode 100644 index 0000000..ad70196 --- /dev/null +++ b/src/typebox.ts @@ -0,0 +1,36 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox-remix + +The MIT License (MIT) + +Copyright (c) 2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +import { TSchema, KindGuard } from '@sinclair/typebox' + +/** Converts a TypeBox Type to a TypeBox Type */ +export type TBox = Type extends TSchema ? Type : undefined +/** Converts a TypeBox Type to a TypeBox Type */ +export function Box = TBox>(type: Type): Result { + return (KindGuard.IsSchema(type) ? type : undefined) as never +} diff --git a/src/valibot.ts b/src/valibot.ts new file mode 100644 index 0000000..85ed9c0 --- /dev/null +++ b/src/valibot.ts @@ -0,0 +1,868 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox-remix + +The MIT License (MIT) + +Copyright (c) 2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +import * as tb from '@sinclair/typebox' +import * as v from 'valibot' + +// ------------------------------------------------------------------ +// Options +// ------------------------------------------------------------------ +function IsSchemaWithPipe(type: BaseSchema): type is v.SchemaWithPipe<[BaseSchema, ...BaseValidation[]]> { + return tb.ValueGuard.IsObject(type) && tb.ValueGuard.HasPropertyKey(type, 'pipe') && tb.ValueGuard.IsArray(type.pipe) +} +// prettier-ignore +function Options(type: BaseSchema) { + if (!IsSchemaWithPipe(type)) return {} + return type.pipe.slice(1).reduce((options, action: { type: string } & { [key: string]: any }) => { + return { + ...options, ...( + action.type === 'args' ? {} : + action.type === 'base64' ? { format: 'valibot:base64' } : + action.type === 'bic' ? { format: 'valibot:bic' } : + action.type === 'brand' ? {} : + action.type === 'bytes' ? {} : + action.type === 'check' ? {} : + action.type === 'check_items' ? {} : + action.type === 'credit_card' ? { format: 'valibot:credit_card' } : + action.type === 'cuid2' ? { format: 'valibot:cuid2' } : + action.type === 'decimal' ? { format: 'valibot:decimal' } : + action.type === 'description' ? { description: action.description } : + action.type === 'digits' ? { format: 'valibot:digits' } : + action.type === 'email' ? { format: 'valibot:email' } : + action.type === 'emoji' ? { format: 'valibot:emoji' } : + action.type === 'empty' ? ( + type.type === 'array' ? { maxItems: 0 } : + type.type === 'string' ? { maxLength: 0 } : + {}) : + action.type === 'ends_with' ? { pattern: `${action.requirement}$` } : + action.type === 'every_item' ? {} : + action.type === 'excludes' ? {} : + action.type === 'filter_items' ? {} : + action.type === 'find_items' ? {} : + action.type === 'finite' ? {} : + action.type === 'graphemes' ? {} : + action.type === 'hash' ? {} : + action.type === 'hexadecimal' ? {} : + action.type === 'hex_color' ? {} : + action.type === 'imei' ? {} : + action.type === 'includes' ? ( + type.type === 'array' ? { contains: tb.Literal(action.requirement) } : + type.type === 'string' ? { pattern: action.requirement } : + {}) : + action.type === 'integer' ? { multipleOf: 1 } : + action.type === 'ip' ? { format: 'valibot:ip' } : + action.type === 'ipv4' ? { format: 'valibot:ipv4' } : + action.type === 'ipv6' ? { format: 'valibot:ipv6' } : + action.type === 'iso_date' ? { format: 'valibot:iso_date' } : + action.type === 'iso_date_time' ? { format: 'valibot:iso_date_time' } : + action.type === 'iso_time' ? { format: 'valibot:iso_time' } : + action.type === 'iso_time_second' ? { format: 'valibot:iso_time_second' } : + action.type === 'iso_timestamp' ? { format: 'valibot:iso_timestamp' } : + action.type === 'iso_week' ? { format: 'valibot:iso_week' } : + action.type === 'length' ? ( + type.type === 'string' ? { minLength: action.requirement, maxLength: action.requirement } : + type.type === 'array' ? { minItems: action.requirement, maxItems: action.requirement } : + {}) : + action.type === 'mac' ? { format: 'valibot:mac' } : + action.type === 'mac48' ? { format: 'valibot:mac48' } : + action.type === 'mac64' ? { format: 'valibot:mac64' } : + action.type === 'map_items' ? {} : + action.type === 'max_bytes' ? {} : + action.type === 'max_graphemes' ? {} : + action.type === 'max_length' ? ( + type.type === 'string' ? { maxLength: action.requirement } : + type.type === 'array' ? { maxItems: action.requirement } : + {}) : + action.type === 'max_size' ? {} : + action.type === 'max_value' ? { maximum: action.requirement } : + action.type === 'max_words' ? {} : + action.type === 'metadata' ? { ...action.metadata } : + action.type === 'mime_type' ? {} : + action.type === 'min_bytes' ? {} : + action.type === 'min_graphemes' ? {} : + action.type === 'min_length' ? ( + type.type === 'string' ? { minLength: action.requirement } : + type.type === 'array' ? { minItems: action.requirement } : + {}) : + action.type === 'min_size' ? {} : + action.type === 'min_value' ? { minimum: action.requirement } : + action.type === 'min_words' ? {} : + action.type === 'multiple_of' ? { multipleOf: action.requirement } : + action.type === 'nanoid' ? { format: 'valibot:nanoid' } : + action.type === 'non_empty' ? {} : + action.type === 'normalize' ? {} : + action.type === 'not_bytes' ? {} : + action.type === 'not_graphemes' ? {} : + action.type === 'not_length' ? {} : // needs TNot + action.type === 'not_size' ? {} : + action.type === 'not_value' ? {} : + action.type === 'not_words' ? {} : + action.type === 'octal' ? { format: 'valibot:octal' } : + action.type === 'partial_check' ? {} : + action.type === 'raw_check' ? {} : + action.type === 'raw_transform' ? {} : + action.type === 'readonly' ? {} : + action.type === 'reduce_items' ? {} : + action.type === 'regex' ? { pattern: action.requirement.source } : + action.type === 'returns' ? {} : + action.type === 'safe_integer' ? { multipleOf: 1 } : + action.type === 'size' ? {} : + action.type === 'some_item' ? {} : + action.type === 'sort_items' ? {} : + action.type === 'starts_with' ? { pattern: `^${action.requirement}` } : + action.type === 'title' ? { title: action.title } : + action.type === 'to_lower_case' ? {} : + action.type === 'to_max_value' ? {} : + action.type === 'to_min_value' ? {} : + action.type === 'to_upper_case' ? {} : + action.type === 'transform' ? {} : + action.type === 'trim' ? {} : + action.type === 'trim_end' ? {} : + action.type === 'trim_start' ? {} : + action.type === 'ulid' ? { format: 'valibot:ulid' } : + action.type === 'url' ? { format: 'valibot:url' } : + action.type === 'uuid' ? { format: 'valibot:uuid' } : + action.type === 'value' ? {} : + action.type === 'words' ? {} : + {}) + } + }, {}) +} +// ------------------------------------------------------------------ +// Formats +// ------------------------------------------------------------------ +tb.FormatRegistry.Set('valibot:base64', (value) => v.safeParse(v.pipe(v.string(), v.base64()), value).success) +tb.FormatRegistry.Set('valibot:bic', (value) => v.safeParse(v.pipe(v.string(), v.bic()), value).success) +tb.FormatRegistry.Set('valibot:credit_card', (value) => v.safeParse(v.pipe(v.string(), v.creditCard()), value).success) +tb.FormatRegistry.Set('valibot:cuid2', (value) => v.safeParse(v.pipe(v.string(), v.cuid2()), value).success) +tb.FormatRegistry.Set('valibot:decimal', (value) => v.safeParse(v.pipe(v.string(), v.decimal()), value).success) +tb.FormatRegistry.Set('valibot:digits', (value) => v.safeParse(v.pipe(v.string(), v.digits()), value).success) +tb.FormatRegistry.Set('valibot:email', (value) => v.safeParse(v.pipe(v.string(), v.email()), value).success) +tb.FormatRegistry.Set('valibot:emoji', (value) => v.safeParse(v.pipe(v.string(), v.emoji()), value).success) +tb.FormatRegistry.Set('valibot:ip', (value) => v.safeParse(v.pipe(v.string(), v.ip()), value).success) +tb.FormatRegistry.Set('valibot:ipv4', (value) => v.safeParse(v.pipe(v.string(), v.ipv4()), value).success) +tb.FormatRegistry.Set('valibot:ipv6', (value) => v.safeParse(v.pipe(v.string(), v.ipv6()), value).success) +tb.FormatRegistry.Set('valibot:iso_date', (value) => v.safeParse(v.pipe(v.string(), v.isoDate()), value).success) +tb.FormatRegistry.Set('valibot:iso_date_time', (value) => v.safeParse(v.pipe(v.string(), v.isoDateTime()), value).success) +tb.FormatRegistry.Set('valibot:iso_time', (value) => v.safeParse(v.pipe(v.string(), v.isoTime()), value).success) +tb.FormatRegistry.Set('valibot:iso_time_second', (value) => v.safeParse(v.pipe(v.string(), v.isoTimeSecond()), value).success) +tb.FormatRegistry.Set('valibot:iso_timestamp', (value) => v.safeParse(v.pipe(v.string(), v.isoTimestamp()), value).success) +tb.FormatRegistry.Set('valibot:iso_week', (value) => v.safeParse(v.pipe(v.string(), v.isoWeek()), value).success) +tb.FormatRegistry.Set('valibot:mac', (value) => v.safeParse(v.pipe(v.string(), v.mac()), value).success) +tb.FormatRegistry.Set('valibot:mac48', (value) => v.safeParse(v.pipe(v.string(), v.mac48()), value).success) +tb.FormatRegistry.Set('valibot:mac64', (value) => v.safeParse(v.pipe(v.string(), v.mac64()), value).success) +tb.FormatRegistry.Set('valibot:nanoid', (value) => v.safeParse(v.pipe(v.string(), v.nanoid()), value).success) +tb.FormatRegistry.Set('valibot:octal', (value) => v.safeParse(v.pipe(v.string(), v.octal()), value).success) +tb.FormatRegistry.Set('valibot:ulid', (value) => v.safeParse(v.pipe(v.string(), v.ulid()), value).success) +tb.FormatRegistry.Set('valibot:url', (value) => v.safeParse(v.pipe(v.string(), v.url()), value).success) +tb.FormatRegistry.Set('valibot:uuid', (value) => v.safeParse(v.pipe(v.string(), v.uuid()), value).success) + +// ------------------------------------------------------------------ +// Schema +// ------------------------------------------------------------------ +type BaseValidation = v.BaseValidation> +type BaseSchema = v.BaseSchema> +type BaseRecordKey = v.BaseSchema> +// ------------------------------------------------------------------ +// Any +// ------------------------------------------------------------------ +type TFromAny<_Type extends v.AnySchema> = tb.Ensure +function FromAny(type: BaseSchema): tb.TSchema { + return tb.Any(Options(type)) +} +// ------------------------------------------------------------------ +// Array +// ------------------------------------------------------------------ +type TFromArray = tb.Ensure>> +function FromArray(type: BaseSchema): tb.TSchema { + return tb.Array(FromType((type as v.ArraySchema).item), Options(type)) +} +// ------------------------------------------------------------------ +// BigInt +// ------------------------------------------------------------------ +type TFromBigInt<_Type extends v.BigintSchema> = tb.Ensure +function FromBigInt(type: BaseSchema): tb.TSchema { + return tb.BigInt(Options(type)) +} +// ------------------------------------------------------------------ +// Blob +// ------------------------------------------------------------------ +tb.TypeRegistry.Set('ValibotBlob', (schema, value) => { + return v.safeParse(schema.schema, value).success +}) +interface TBlob = v.BlobSchema> extends tb.TSchema { + [tb.Kind]: 'ValibotBlob' + static: v.InferOutput + type: Type +} +function _Blob(type: v.BlobSchema, options?: tb.SchemaOptions): TBlob { + return tb.CreateType({ [tb.Kind]: 'ValibotBlob', type }, options) as never +} +type TFromBlob> = tb.Ensure> +function FromBlob(type: BaseSchema): tb.TSchema { + return _Blob(type as v.BlobSchema, Options(type)) +} +// ------------------------------------------------------------------ +// Boolean +// ------------------------------------------------------------------ +type TFromBoolean<_Type extends v.BooleanSchema> = tb.TBoolean +function FromBoolean(type: BaseSchema): tb.TSchema { + return tb.Boolean(Options(type)) +} +// ------------------------------------------------------------------ +// Custom +// ------------------------------------------------------------------ +tb.TypeRegistry.Set('ValibotCustom', (schema, value) => v.safeParse(schema.schema, value).success) +export interface TCustom = v.CustomSchema> extends tb.TSchema { + [tb.Kind]: 'ValibotCustom' + static: v.InferOutput + type: Type +} +function Custom>(type: Type, options?: tb.SchemaOptions): TCustom { + return tb.CreateType({ [tb.Kind]: 'ValibotCustom', type }, options) as never +} +type TFromCustom> = tb.Ensure> +function FromCustom(type: BaseSchema): tb.TSchema { + return Custom(type as v.CustomSchema, Options(type)) +} +// ------------------------------------------------------------------ +// Date +// ------------------------------------------------------------------ +type TFromDate<_Type extends v.DateSchema> = tb.TDate +function FromDate(type: BaseSchema): tb.TSchema { + return tb.Date(Options(type)) +} +// ------------------------------------------------------------------ +// Enum +// ------------------------------------------------------------------ +tb.TypeRegistry.Set('ValibotEnum', (schema, value) => { + return v.safeParse(schema.schema, value).success +}) +export interface TValibotEnum = v.EnumSchema> extends tb.TSchema { + [tb.Kind]: 'ValibotEnum' + static: v.InferOutput + type: Type +} +function ValibotEnum>(type: Type, options?: tb.SchemaOptions): TValibotEnum { + return tb.CreateType({ [tb.Kind]: 'ValibotEnum', type }, options) as never +} +type TFromEnum> = TValibotEnum +function FromEnum(type: Type): tb.TSchema { + return ValibotEnum(type as never as v.EnumSchema, Options(type)) +} +// ------------------------------------------------------------------ +// File +// ------------------------------------------------------------------ +tb.TypeRegistry.Set('ValibotFile', (schema, value) => { + return v.safeParse(schema.schema, value).success +}) +export interface TFile = v.FileSchema> extends tb.TSchema { + [tb.Kind]: 'ValibotFile' + static: v.InferOutput + type: Type +} +function _File(type: v.FileSchema, options?: tb.SchemaOptions): TFile { + return tb.CreateType({ [tb.Kind]: 'ValibotFile', type }, options) as never +} +type TFromFile> = tb.Ensure> +function FromFile(type: BaseSchema): tb.TSchema { + return _File(type as v.FileSchema, Options(type)) +} +// ------------------------------------------------------------------ +// Function +// ------------------------------------------------------------------ +tb.TypeRegistry.Set('ValibotFunction', (schema, value) => { + return v.safeParse(schema.schema, value).success +}) +export interface TFunction = v.FunctionSchema> extends tb.TSchema { + [tb.Kind]: 'ValibotFunction' + static: v.InferOutput + type: Type +} +function _Function>(type: Type, options?: tb.SchemaOptions): TFunction { + return tb.CreateType({ [tb.Kind]: 'ValibotFunction', type }, options) as never +} +type TFromFunction> = tb.Ensure> +function FromFunction(type: BaseSchema): tb.TSchema { + return _Function(type as v.FunctionSchema, Options(type)) +} +// ------------------------------------------------------------------ +// Instance +// ------------------------------------------------------------------ +tb.TypeRegistry.Set('ValibotInstance', (schema, value) => { + return v.safeParse(schema.schema, value).success +}) +export interface TInstance = v.InstanceSchema> extends tb.TSchema { + [tb.Kind]: 'ValibotInstance' + static: v.InferOutput + type: Type +} +function Instance>(type: Type, options?: tb.SchemaOptions): TInstance { + return tb.CreateType({ [tb.Kind]: 'ValibotInstance', type }, options) as never +} +type TFromInstance> = tb.Ensure> +function FromInstance(type: BaseSchema): tb.TSchema { + return Instance(type as v.InstanceSchema, Options(type)) +} +// ------------------------------------------------------------------ +// Intersect +// ------------------------------------------------------------------ +// prettier-ignore +type TFromIntersect = ( + Type extends [infer Left extends BaseSchema, ...infer Right extends BaseSchema[]] + ? TFromIntersect]> + : tb.TIntersect +) +function FromIntersect(type: BaseSchema): tb.TSchema { + const intersect = type as v.IntersectSchema + return tb.Intersect( + intersect.options.map((option) => FromType(option)), + Options(type), + ) +} +// ------------------------------------------------------------------ +// Literal +// ------------------------------------------------------------------ +type TFromLiteral = tb.Ensure> +function FromLiteral(type: BaseSchema): tb.TSchema { + const literal = type as v.LiteralSchema + return tb.Literal(literal.literal, Options(type)) +} +// ------------------------------------------------------------------ +// LooseObject +// ------------------------------------------------------------------ +type TFromLooseObject = tb.Ensure< + tb.TObject<{ + -readonly [Key in keyof Properties]: TFromType + }> +> +function FromLooseObject(type: BaseSchema): tb.TSchema { + const object = type as v.LooseObjectSchema + const keys = globalThis.Object.getOwnPropertyNames(object.entries) + return tb.Object( + keys.reduce((properties, key) => { + return { ...properties, [key]: FromType(object.entries[key]) } + }, {} as tb.TProperties), + Options(type), + ) +} +// ------------------------------------------------------------------ +// LooseTuple +// ------------------------------------------------------------------ +tb.TypeRegistry.Set('ValibotLooseTuple', (schema, value) => { + return v.safeParse(schema.schema, value).success +}) +export interface TLooseTuple = v.LooseTupleSchema> extends tb.TSchema { + [tb.Kind]: 'ValibotLooseTuple' + static: v.InferOutput + type: Type +} +function LooseTuple>(type: Type, schema?: tb.SchemaOptions): TLooseTuple { + return tb.CreateType({ [tb.Kind]: 'ValibotLooseTuple', type }) as never +} +type TFromLooseTuple> = tb.Ensure> +function FromLooseTuple(type: BaseSchema): tb.TSchema { + return LooseTuple(type as v.LooseTupleSchema, Options(type)) +} +// ------------------------------------------------------------------ +// Map +// ------------------------------------------------------------------ +tb.TypeRegistry.Set('ValibotMap', (schema, value) => { + return v.safeParse(schema.schema, value).success +}) +export interface TMap = v.MapSchema> extends tb.TSchema { + [tb.Kind]: 'ValibotMap' + static: v.InferOutput + type: Type +} +function _Map>(type: Type, options?: tb.SchemaOptions): TMap { + return tb.CreateType({ [tb.Kind]: 'ValibotMap', type }) as never +} +type TFromMap> = tb.Ensure> +function FromMap(type: BaseSchema): tb.TSchema { + return _Map(type as v.MapSchema, Options(type)) +} +// ------------------------------------------------------------------ +// NaN +// ------------------------------------------------------------------ +tb.TypeRegistry.Set('ValibotNaN', (schema, value) => { + return v.safeParse(schema.schema, value).success +}) +export interface TNaN = v.NanSchema> extends tb.TSchema { + [tb.Kind]: 'ValibotNaN' + static: v.InferOutput + type: Type +} +function NaN>(type: Type, options?: tb.SchemaOptions): TNaN { + return tb.CreateType({ [tb.Kind]: 'ValibotNaN', type }, options) as never +} +type TFromNaN> = tb.Ensure> +function FromNaN(type: BaseSchema): tb.TSchema { + return NaN(type as v.NanSchema, Options(type)) +} +// ------------------------------------------------------------------ +// Never +// ------------------------------------------------------------------ +type TFromNever<_Type extends v.NeverSchema> = tb.TNever +function FromNever(type: BaseSchema): tb.TSchema { + return tb.Never(Options(type)) +} +// ------------------------------------------------------------------ +// NonNullable +// ------------------------------------------------------------------ +type TFromNonNullable = tb.TExclude, tb.TNull> +function FromNonNullable(type: BaseSchema): tb.TSchema { + const non_nullable = type as v.NonNullableSchema + return tb.Exclude(FromType(non_nullable.wrapped), tb.Null(), Options(type)) +} +// ------------------------------------------------------------------ +// NonNullish +// ------------------------------------------------------------------ +type TFromNonNullish = tb.TExclude, tb.TUnion<[tb.TNull, tb.TUndefined]>> +function FromNonNullish(type: BaseSchema): tb.TSchema { + const non_nullish = type as v.NonNullishSchema + return tb.Exclude(FromType(non_nullish.wrapped), tb.Union([tb.Null(), tb.Undefined()]), Options(type)) +} +// ------------------------------------------------------------------ +// NonOptional +// ------------------------------------------------------------------ +type TFromNonOptional = TFromType> = tb.TOptionalWithFlag +function FromNonOptional(type: BaseSchema): tb.TSchema { + const non_optional = type as v.NonOptionalSchema + return tb.Optional(FromType(non_optional.wrapped), false) +} +// ------------------------------------------------------------------ +// Null +// ------------------------------------------------------------------ +type TFromNull<_Type extends v.NullSchema> = tb.TNull +function FromNull(type: BaseSchema) { + return tb.Null(Options(type)) +} +// ------------------------------------------------------------------ +// Nullable +// ------------------------------------------------------------------ +type TFromNullable = tb.TUnion<[TFromType, tb.TNull]> +function FromNullable(type: BaseSchema) { + const nullable = type as v.NullableSchema + return tb.Union([tb.Null(), FromType(nullable.wrapped)], Options(type)) +} +// ------------------------------------------------------------------ +// Nullish +// ------------------------------------------------------------------ +type TFromNullish = tb.TUnion<[TFromType, tb.TNull, tb.TUndefined]> +function FromNullish(type: BaseSchema) { + const nullish = type as v.NullishSchema + return tb.Union([FromType(nullish.wrapped), tb.Null(), tb.Undefined()], Options(type)) +} +// ------------------------------------------------------------------ +// Number +// ------------------------------------------------------------------ +type TFromNumber<_Type extends v.NumberSchema> = tb.TNumber +function FromNumber(type: BaseSchema): tb.TSchema { + return tb.Number(Options(type)) +} +// ------------------------------------------------------------------ +// Object +// ------------------------------------------------------------------ +type TFromObject = tb.Ensure< + tb.TObject<{ + -readonly [Key in keyof Properties]: TFromType + }> +> +function FromObject(type: BaseSchema): tb.TSchema { + const object = type as v.ObjectSchema + const keys = globalThis.Object.getOwnPropertyNames(object.entries) + return tb.Object( + keys.reduce((properties, key) => { + return { ...properties, [key]: FromType(object.entries[key]) } + }, {} as tb.TProperties), + Options(type), + ) +} +// ------------------------------------------------------------------ +// ObjectWithRest +// ------------------------------------------------------------------ +type TFromObjectWithRest = tb.Ensure< + tb.TObject<{ + -readonly [Key in keyof Properties]: TFromType + }> +> +function FromObjectWithRest(type: BaseSchema): tb.TSchema { + const object = type as v.ObjectWithRestSchema + const keys = globalThis.Object.getOwnPropertyNames(object.entries) + return tb.Object( + keys.reduce((properties, key) => { + return { ...properties, [key]: FromType(object.entries[key]) } + }, {} as tb.TProperties), + { ...Options(type), additionalProperties: FromType(object.rest) }, + ) +} +// ------------------------------------------------------------------ +// Optional +// ------------------------------------------------------------------ +type TFromOptional = TFromType> = tb.TOptionalWithFlag +function FromOptional(type: BaseSchema): tb.TSchema { + const optional = type as v.OptionalSchema + return tb.Optional(FromType(optional.wrapped)) +} +// ------------------------------------------------------------------ +// PickList +// ------------------------------------------------------------------ +type PickListOption = string | number | bigint +// prettier-ignore +type TFromPickList = ( + Options extends [infer Left extends PickListOption, ...infer Right extends PickListOption[]] + ? ( + Left extends tb.TLiteralValue + ? TFromPickList]> + : TFromPickList + ) + : tb.TUnion +) +function FromPickList(type: BaseSchema): tb.TSchema { + const picklist = type as v.PicklistSchema + return tb.Union( + picklist.options.map((option) => tb.Literal(option as tb.TLiteralValue)), + Options(type), + ) +} +// ------------------------------------------------------------------ +// Promise +// ------------------------------------------------------------------ +tb.TypeRegistry.Set('ValibotPromise', (schema, value) => { + return v.safeParse(schema.schema, value).success +}) +export interface TPromise = v.PromiseSchema> extends tb.TSchema { + [tb.Kind]: 'ValibotPromise' + static: v.InferOutput + type: Type +} +function _Promise>(type: Type, options?: tb.SchemaOptions): TPromise { + return tb.CreateType({ [tb.Kind]: 'ValibotPromise', type }, options) as never +} +type TFromPromise> = tb.Ensure> +function FromPromise(type: BaseSchema): tb.TSchema { + return _Promise(type as v.PromiseSchema, Options(type)) +} +// ------------------------------------------------------------------ +// Record +// ------------------------------------------------------------------ +type TFromRecord = tb.Ensure, TFromType>> +function FromRecord(type: BaseSchema) { + const record = type as v.RecordSchema + return tb.Record(FromType(record.key), FromType(record.value), Options(type)) +} +// ------------------------------------------------------------------ +// Set +// ------------------------------------------------------------------ +tb.TypeRegistry.Set('ValibotSet', (schema, value) => { + return v.safeParse(schema.schema, value).success +}) +export interface TSet = v.SetSchema> extends tb.TSchema { + [tb.Kind]: 'ValibotSet' + static: v.InferOutput extends infer Result ? Result : never + type: Type +} +function Set>(type: Type, options?: tb.SchemaOptions): TSet { + return tb.CreateType({ [tb.Kind]: 'ValibotSet', type }, options) as never +} +type TFromSet> = tb.Ensure> +function FromSet(type: BaseSchema): tb.TSchema { + return Set(type as v.SetSchema) +} +// ------------------------------------------------------------------ +// StrictObject +// ------------------------------------------------------------------ +type TFromStrictObject = tb.Ensure< + tb.TObject<{ + -readonly [Key in keyof Properties]: TFromType + }> +> +function FromStrictObject(type: BaseSchema): tb.TSchema { + const object = type as v.StrictObjectSchema + const keys = globalThis.Object.getOwnPropertyNames(object.entries) + return tb.Object( + keys.reduce((properties, key) => { + return { ...properties, [key]: FromType(object.entries[key]) } + }, {} as tb.TProperties), + { ...Options(type), additionalProperties: false }, + ) +} +// ------------------------------------------------------------------ +// StrictTuple +// ------------------------------------------------------------------ +// prettier-ignore +type TFromStrictTuple = ( + Type extends [infer Left extends BaseSchema, ...infer Right extends BaseSchema[]] + ? TFromTuple]> + : tb.TTuple +) +function FromStrictTuple(type: BaseSchema): tb.TSchema { + const tuple = type as v.StrictTupleSchema + const items = globalThis.Array.isArray(tuple.items) ? tuple.items.map((item) => FromType(item)) : [] + return tb.Tuple(items, Options(type)) +} +// ------------------------------------------------------------------ +// String +// ------------------------------------------------------------------ +type TFromString<_Type extends v.StringSchema> = tb.TString +function FromString(type: BaseSchema): tb.TSchema { + return tb.String(Options(type)) +} +// ------------------------------------------------------------------ +// Symbol +// ------------------------------------------------------------------ +type TFromSymbol<_Type extends v.SymbolSchema> = tb.TSymbol +function FromSymbol(type: BaseSchema): tb.TSchema { + return tb.Symbol(Options(type)) +} +// ------------------------------------------------------------------ +// Tuple +// ------------------------------------------------------------------ +// prettier-ignore +type TFromTuple = ( + Type extends [infer Left extends BaseSchema, ...infer Right extends BaseSchema[]] + ? TFromTuple]> + : tb.TTuple +) +function FromTuple(type: BaseSchema): tb.TSchema { + const tuple = type as v.TupleSchema + const items = globalThis.Array.isArray(tuple.items) ? tuple.items.map((item) => FromType(item)) : [] + return tb.Tuple(items, Options(type)) +} +// ------------------------------------------------------------------ +// TupleWithRest +// ------------------------------------------------------------------ +tb.TypeRegistry.Set('ValibotTupleWithRest', (schema, value) => { + return v.safeParse(schema.schema, value).success +}) +interface TTupleWithRest = v.TupleWithRestSchema> extends tb.TSchema { + [tb.Kind]: 'ValibotTupleWithRest' + static: v.InferOutput + type: Type +} +function TupleWithRest>(type: Type, options?: tb.SchemaOptions): TTupleWithRest { + return tb.CreateType({ [tb.Kind]: 'ValibotTupleWithRest', type }, Options(type)) as never +} +type TFromTupleWithRest> = tb.Ensure> +function FromTupleWithRest(type: BaseSchema): tb.TSchema { + return TupleWithRest(type as v.TupleWithRestSchema, Options(type)) +} +// ------------------------------------------------------------------ +// Undefined +// ------------------------------------------------------------------ +type TFromUndefined<_Type extends v.UndefinedSchema> = tb.TUndefined +function FromUndefined(type: BaseSchema): tb.TSchema { + return tb.Undefined(Options(type)) +} +// ------------------------------------------------------------------ +// Undefinable +// ------------------------------------------------------------------ +type TFromUndefinedable = tb.TUnion<[TFromType, tb.TUndefined]> +function FromUndefinedable(type: BaseSchema): tb.TSchema { + const undefinedable = type as v.UndefinedableSchema + return tb.Union([FromType(undefinedable.wrapped), tb.Undefined()], Options(type)) +} +// ------------------------------------------------------------------ +// Union +// ------------------------------------------------------------------ +// prettier-ignore +type TFromUnion = ( + Type extends [infer Left extends BaseSchema, ...infer Right extends BaseSchema[]] + ? TFromUnion]> + : tb.TUnion +) +function FromUnion(type: BaseSchema): tb.TSchema { + const variants = (type as v.UnionSchema).options.map((option) => FromType(option)) + return tb.Union(variants, Options(type)) +} +// ------------------------------------------------------------------ +// Unknown +// ------------------------------------------------------------------ +type TFromUnknown<_Type extends v.UnknownSchema> = tb.TUnknown +function FromUnknown(type: BaseSchema): tb.TSchema { + return tb.Unknown(Options(type)) +} +// ------------------------------------------------------------------ +// Variant +// ------------------------------------------------------------------ +tb.TypeRegistry.Set('ValibotVariant', (schema, value) => { + return v.safeParse(schema.schema, value).success +}) +interface TVariant, any> = v.VariantSchema, any>> extends tb.TSchema { + [tb.Kind]: 'ValibotVariant' + static: v.InferOutput + type: Type +} +function Variant, any>>(type: Type): TVariant { + return tb.CreateType({ [tb.Kind]: 'ValibotVariant', type }, Options(type)) as never +} +type TFromVariant, any>> = tb.Ensure> +function FromVariant(type: BaseSchema): tb.TSchema { + return Variant(type as v.VariantSchema, any>) +} +// ------------------------------------------------------------------ +// Void +// ------------------------------------------------------------------ +type TFromVoid<_Type extends v.VoidSchema> = tb.TVoid +function FromVoid(type: BaseSchema): tb.TSchema { + return tb.Void(Options(type)) +} +// ------------------------------------------------------------------ +// Type +// ------------------------------------------------------------------ +// prettier-ignore +export type TFromType = ( + // Pipes - Extract First Type And Remap + Type extends { pipe: [infer Type extends BaseSchema, ...any[]] } ? TFromType : + // Types + Type extends v.AnySchema ? TFromAny : + Type extends v.ArraySchema ? TFromArray : + Type extends v.BigintSchema ? TFromBigInt : + Type extends v.BlobSchema ? TFromBlob : + Type extends v.BooleanSchema ? TFromBoolean : + Type extends v.CustomSchema ? TFromCustom : + Type extends v.DateSchema ? TFromDate : + Type extends v.EnumSchema ? TFromEnum : + Type extends v.FileSchema ? TFromFile : + Type extends v.FunctionSchema ? TFromFunction : + Type extends v.InstanceSchema ? TFromInstance : + Type extends v.IntersectSchema ? TFromIntersect : + Type extends v.LiteralSchema ? TFromLiteral : + Type extends v.LooseObjectSchema ? TFromLooseObject : + Type extends v.LooseTupleSchema ? TFromLooseTuple : + Type extends v.MapSchema ? TFromMap : + Type extends v.NanSchema ? TFromNaN : + Type extends v.NeverSchema ? TFromNever : + Type extends v.NonNullableSchema ? TFromNonNullable : + Type extends v.NonNullishSchema ? TFromNonNullish : + Type extends v.NonOptionalSchema ? TFromNonOptional : + Type extends v.NullSchema ? TFromNull : + Type extends v.NullableSchema ? TFromNullable : + Type extends v.NullishSchema ? TFromNullish : + Type extends v.NumberSchema ? TFromNumber : + Type extends v.ObjectSchema ? TFromObject : + Type extends v.ObjectWithRestSchema ? TFromObjectWithRest : + Type extends v.OptionalSchema ? TFromOptional : + Type extends v.PicklistSchema ? TFromPickList : + Type extends v.PromiseSchema ? TFromPromise : + Type extends v.RecordSchema ? TFromRecord : + Type extends v.SetSchema ? TFromSet : + Type extends v.StrictObjectSchema ? TFromStrictObject : + Type extends v.StrictTupleSchema ? TFromStrictTuple : + Type extends v.StringSchema ? TFromString : + Type extends v.SymbolSchema ? TFromSymbol : + Type extends v.TupleSchema ? TFromTuple : + Type extends v.TupleWithRestSchema ? TFromTupleWithRest : + Type extends v.UndefinedSchema ? TFromUndefined : + Type extends v.UndefinedableSchema ? TFromUndefinedable : + Type extends v.UnionSchema ? TFromUnion : + Type extends v.UnknownSchema ? TFromUnknown : + Type extends v.VariantSchema, any> ? TFromVariant : + Type extends v.VoidSchema ? TFromVoid : + tb.TNever +) +// prettier-ignore +export function FromType(type: Type): TFromType { + return ( + type.type === 'any' ? FromAny(type) : + type.type === 'array' ? FromArray(type) : + type.type === 'bigint' ? FromBigInt(type) : + type.type === 'blob' ? FromBlob(type) : + type.type === 'boolean' ? FromBoolean(type) : + type.type === 'custom' ? FromCustom(type) : + type.type === 'date' ? FromDate(type) : + type.type === 'enum' ? FromEnum(type) : + type.type === 'file' ? FromFile(type) : + type.type === 'function' ? FromFunction(type) : + type.type === 'intersect' ? FromIntersect(type) : + type.type === 'instance' ? FromInstance(type) : + type.type === 'literal' ? FromLiteral(type) : + type.type === 'loose_object' ? FromLooseObject(type) : + type.type === 'loose_tuple' ? FromLooseTuple(type) : + type.type === 'map' ? FromMap(type) : + type.type === 'nan' ? FromNaN(type) : + type.type === 'never' ? FromNever(type) : + type.type === 'non_nullable' ? FromNonNullable(type) : + type.type === 'non_nullish' ? FromNonNullish(type) : + type.type === 'non_optional' ? FromNonOptional(type) : + type.type === 'null' ? FromNull(type) : + type.type === 'nullable' ? FromNullable(type) : + type.type === 'nullish' ? FromNullish(type) : + type.type === 'number' ? FromNumber(type) : + type.type === 'object' ? FromObject(type) : + type.type === 'object_with_rest' ? FromObjectWithRest(type) : + type.type === 'optional' ? FromOptional(type) : + type.type === 'picklist' ? FromPickList(type) : + type.type === 'promise' ? FromPromise(type) : + type.type === 'record' ? FromRecord(type) : + type.type === 'string' ? FromString(type) : + type.type === 'set' ? FromSet(type) : + type.type === 'strict_object' ? FromStrictObject(type) : + type.type === 'strict_tuple' ? FromStrictTuple(type) : + type.type === 'symbol' ? FromSymbol(type) : + type.type === 'tuple_with_rest' ? FromTupleWithRest(type) : + type.type === 'tuple' ? FromTuple(type) : + type.type === 'undefined' ? FromUndefined(type) : + type.type === 'undefinedable' ? FromUndefinedable(type) : + type.type === 'unknown' ? FromUnknown(type) : + type.type === 'union' ? FromUnion(type) : + type.type === 'variant' ? FromVariant(type) : + type.type === 'void' ? FromVoid(type) : + tb.Never() + ) as never +} +// ------------------------------------------------------------------ +// IsValibot +// ------------------------------------------------------------------ +// prettier-ignore +export function IsValibot(type: unknown): type is BaseSchema { + return ( + tb.ValueGuard.IsObject(type) && + tb.ValueGuard.HasPropertyKey(type, '~standard') && + tb.ValueGuard.IsObject(type['~standard']) && + tb.ValueGuard.HasPropertyKey(type['~standard'], 'vendor') && + type['~standard'].vendor === 'valibot' + ) +} +// ------------------------------------------------------------------ +// Box +// ------------------------------------------------------------------ +/** Converts a Valibot Type to a TypeBox Type */ +// prettier-ignore +export type TBox = ( + Type extends BaseSchema + ? Type extends { '~standard': { vendor: 'valibot' } } + ? TFromType + : undefined + : undefined +) +/** Converts a Valibot Type to a TypeBox Type */ +export function Box = TBox>(type: Type): Result { + return (IsValibot(type) ? FromType(type) : undefined) as never +} diff --git a/src/zod.ts b/src/zod.ts new file mode 100644 index 0000000..641db42 --- /dev/null +++ b/src/zod.ts @@ -0,0 +1,388 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox-remix + +The MIT License (MIT) + +Copyright (c) 2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +import * as tb from '@sinclair/typebox' +import * as z from 'zod' + +// ------------------------------------------------------------------ +// Options +// ------------------------------------------------------------------ +function Options(type: z.ZodTypeAny): tb.SchemaOptions { + const description = tb.ValueGuard.IsUndefined(type.description) ? {} : { description: type.description } + return { ...description } +} +// ------------------------------------------------------------------ +// Formats +// ------------------------------------------------------------------ +const check = (type: z.ZodTypeAny, value: unknown) => type.safeParse(value).success +tb.FormatRegistry.Set('zod:base64', (value) => check(z.string().base64(), value)) +tb.FormatRegistry.Set('zod:base64url', (value) => check(z.string().base64url(), value)) +tb.FormatRegistry.Set('zod:cidrv4', (value) => check(z.string().cidr({ version: 'v4' }), value)) +tb.FormatRegistry.Set('zod:cidrv6', (value) => check(z.string().cidr({ version: 'v6' }), value)) +tb.FormatRegistry.Set('zod:cidr', (value) => check(z.string().cidr(), value)) +tb.FormatRegistry.Set('zod:cuid', (value) => check(z.string().cuid(), value)) +tb.FormatRegistry.Set('zod:cuid2', (value) => check(z.string().cuid2(), value)) +tb.FormatRegistry.Set('zod:ulid', (value) => check(z.string().ulid(), value)) +tb.FormatRegistry.Set('zod:email', (value) => check(z.string().email(), value)) +tb.FormatRegistry.Set('zod:emoji', (value) => check(z.string().emoji(), value)) +tb.FormatRegistry.Set('zod:ipv4', (value) => check(z.string().ip({ version: 'v4' }), value)) +tb.FormatRegistry.Set('zod:ipv6', (value) => check(z.string().ip({ version: 'v6' }), value)) +tb.FormatRegistry.Set('zod:ip', (value) => check(z.string().ip(), value)) +tb.FormatRegistry.Set('zod:ipv6Cidr', (value) => check(z.string().cidr({ version: 'v6' }), value)) +tb.FormatRegistry.Set('zod:nanoid', (value) => check(z.string().nanoid(), value)) +tb.FormatRegistry.Set('zod:jwt', (value) => check(z.string().jwt(), value)) +tb.FormatRegistry.Set('zod:date', (value) => check(z.string().date(), value)) +tb.FormatRegistry.Set('zod:datetime', (value) => check(z.string().datetime(), value)) +tb.FormatRegistry.Set('zod:duration', (value) => check(z.string().duration(), value)) +tb.FormatRegistry.Set('zod:time', (value) => check(z.string().time(), value)) +tb.FormatRegistry.Set('zod:url', (value) => check(z.string().url(), value)) +tb.FormatRegistry.Set('zod:uuid', (value) => check(z.string().uuid(), value)) +// ------------------------------------------------------------------ +// Any +// ------------------------------------------------------------------ +type TFromAny = tb.TAny +function FromAny(_def: Def) { + return tb.Any() +} +// ------------------------------------------------------------------ +// Array +// ------------------------------------------------------------------ +type TFromArray = tb.Ensure>> +function FromArray(def: Def): tb.TSchema { + const minItems = def.minLength === null ? {} : { minItems: def.minLength.value } + const maxItems = def.maxLength === null ? {} : { minItems: def.maxLength.value } + const options = { ...minItems, ...maxItems } + return tb.Array(FromType(def.type), options) +} +// ------------------------------------------------------------------ +// BigInt +// ------------------------------------------------------------------ +type TFromBigInt = tb.TBigInt +function FromBigInt(def: Def) { + return tb.BigInt() +} +// ------------------------------------------------------------------ +// Boolean +// ------------------------------------------------------------------ +type TFromBoolean = tb.TBoolean +function FromBoolean(def: Def) { + return tb.Boolean() +} +// ------------------------------------------------------------------ +// Date +// ------------------------------------------------------------------ +type TFromDate = tb.TDate +function FromDate(def: Def) { + return tb.Date() +} +// ------------------------------------------------------------------ +// Default +// ------------------------------------------------------------------ +type TFromDefault = TFromType +function FromDefault(def: Def): tb.TSchema { + return tb.CloneType(FromType(def.innerType), { default: def.defaultValue() }) +} +// ------------------------------------------------------------------ +// Effects +// ------------------------------------------------------------------ +type TFromEffects = tb.Ensure, Output>> +function FromEffects>(type: Type): tb.TSchema { + return tb + .Transform(FromType(type._def.schema)) + .Decode((value) => type.parse(value)) + .Encode((_) => { + throw Error('Encode not implemented for Zod types') + }) +} +// ------------------------------------------------------------------ +// Literal +// ------------------------------------------------------------------ +type TFromLiteral = tb.Ensure : tb.TNever> +function FromLiteral(def: Def) { + return tb.Literal(def.value as tb.TLiteralValue) +} +// ------------------------------------------------------------------ +// Intersect +// ------------------------------------------------------------------ +// prettier-ignore +type TFromIntersect = ( + Types extends [infer Left extends z.ZodTypeAny, ...infer Right extends z.ZodTypeAny[]] + ? TFromIntersect]> + : tb.Ensure> +) +function FromIntersect(type: Type): tb.TSchema { + return tb.Intersect([FromType(type.left), FromType(type.right)]) +} +// ------------------------------------------------------------------ +// Object +// ------------------------------------------------------------------ +type TFromObject = tb.Ensure< + tb.TObject<{ + [Key in keyof Properties]: TFromType + }> +> +function FromObject, Shape extends z.ZodRawShape>(def: Def, shape: Shape): tb.TSchema { + const additionalProperties = def.unknownKeys === 'strict' ? { additionalProperties: false } : {} + const options = { ...additionalProperties } + return tb.Object( + globalThis.Object.keys(shape).reduce((properties: any, key: any) => { + return { ...properties, [key]: FromType(shape[key]) } + }, {} as tb.TProperties) as never, + options, + ) +} +// ------------------------------------------------------------------ +// Optional +// ------------------------------------------------------------------ +type TFromOptional>> = Result +function FromOptional(def: Def): tb.TSchema { + return tb.Optional(FromType(def.innerType)) +} +// ------------------------------------------------------------------ +// Promise +// ------------------------------------------------------------------ +type TFromPromise = tb.Ensure>> +function FromPromise(def: Def): tb.TSchema { + return tb.Promise(FromType(def.type)) +} +// ------------------------------------------------------------------ +// Nullable +// ------------------------------------------------------------------ +type TFromNullable = tb.Ensure]>> +function FromNullable(def: Def): tb.TSchema { + return tb.Union([tb.Null(), FromType(def.innerType)]) +} +// ------------------------------------------------------------------ +// Number +// ------------------------------------------------------------------ +type TFromNumber = tb.TNumber +// prettier-ignore +function FromNumber(def: Def) { + const options = def.checks.reduce((options, check) => { + return { ...options, ... ( + check.kind === 'int' ? { multipleOf: 1 } : + check.kind === 'max' ? check.inclusive ? { maximum: check.value } : { exclusiveMaximum: check.value } : + check.kind === 'min' ? check.inclusive ? { minimum: check.value } : { exclusiveMinimum: check.value } : + check.kind === 'multipleOf' ? { multipleOf: check.value } : + {} + )} + }, {}) + return tb.Number(options) +} +// ------------------------------------------------------------------ +// Never +// ------------------------------------------------------------------ +type TFromNever = tb.TNever +function FromNever(def: Def) { + return tb.Never() +} +// ------------------------------------------------------------------ +// Null +// ------------------------------------------------------------------ +type TFromNull = tb.TNull +function FromNull(def: Def) { + return tb.Null() +} +// ------------------------------------------------------------------ +// Readonly +// ------------------------------------------------------------------ +type TFromReadonly>> = Result +function FromReadonly(def: Def): tb.TSchema { + return tb.Readonly(FromType(def.innerType)) +} +// ------------------------------------------------------------------ +// Record +// ------------------------------------------------------------------ +export type TFromRecord = tb.Ensure, TFromType>> +function FromRecord(def: Def): tb.TSchema { + return tb.Record(FromType(def.keyType), FromType(def.valueType)) +} +// ------------------------------------------------------------------ +// String +// ------------------------------------------------------------------ +type TFromString = tb.TString +// prettier-ignore +function FromString(def: Def) { + const options = def.checks.reduce((options, check) => { + return { ...options, ...( + check.kind === 'base64' ? { format: 'zod:base64' } : + check.kind === 'base64url' ? { format: 'zod:base64url' } : + check.kind === 'cidr' ? { format: check.version === 'v4' ? 'zod:cidrv4' : check.version === 'v6' ? 'zod:cidrv6' : 'zod:cidr' } : + check.kind === 'cuid' ? { format: 'zod:cuid' } : + check.kind === 'cuid2' ? { format: 'zod:cuid2' } : + check.kind === 'date' ? { format: 'zod:date' } : + check.kind === 'datetime' ? { format: 'zod:datetime' } : + check.kind === 'duration' ? { format: 'zod:duration' } : + check.kind === 'email' ? { format: 'zod:email' } : + check.kind === 'emoji' ? { format: 'zod:emoji' } : + check.kind === 'endsWith' ? { pattern: `${check.value}$` } : + check.kind === 'includes' ? { pattern: check.value } : + check.kind === 'ip' ? { format: check.version === 'v4' ? 'zod:ipv4' : check.version === 'v6' ? 'zod:ipv6' : 'zod:ip' } : + check.kind === 'jwt' ? { format: 'zod:jwt' } : + check.kind === 'length' ? { minLength: check.value, maxLength: check.value } : + check.kind === 'min' ? { minLength: check.value } : + check.kind === 'max' ? { maxLength: check.value } : + check.kind === 'nanoid' ? { format: 'zod:nanoid' } : + check.kind === 'regex' ? { pattern: check.regex.source } : + check.kind === 'startsWith' ? { pattern: `^${check.value}` } : + check.kind === 'time' ? { format: 'zod:time' } : + check.kind === 'ulid' ? { format: 'zod:ulid' } : + check.kind === 'url' ? { format: 'zod:url' } : + check.kind === 'uuid' ? { format: 'zod:uuid' } : + {} + )} + }, {}) + return tb.String(options) +} +// ------------------------------------------------------------------ +// Symbol +// ------------------------------------------------------------------ +type TFromSymbol = tb.TSymbol +function FromSymbol(def: Def) { + return tb.Symbol() +} +// ------------------------------------------------------------------ +// Tuple +// ------------------------------------------------------------------ +// prettier-ignore +type TFromTuple = ( + Types extends [infer Left extends z.ZodTypeAny, ...infer Right extends z.ZodTypeAny[]] + ? TFromTuple]> + : tb.TTuple +) +function FromTuple(def: Def): tb.TSchema { + return tb.Tuple(def.items.map((item) => FromType(item))) +} +// ------------------------------------------------------------------ +// Undefined +// ------------------------------------------------------------------ +type TFromUndefined = tb.TUndefined +function FromUndefined(def: Def) { + return tb.Undefined() +} +// ------------------------------------------------------------------ +// Union +// ------------------------------------------------------------------ +// prettier-ignore +type TFromUnion = ( + Types extends [infer Left extends z.ZodTypeAny, ...infer Right extends z.ZodTypeAny[]] + ? TFromUnion]> + : tb.TUnion +) +function FromUnion(def: Def): tb.TSchema { + return tb.Union(def.options.map((item) => FromType(item))) +} +// ------------------------------------------------------------------ +// Unknown +// ------------------------------------------------------------------ +type TFromUnknown = tb.TUnknown +function FromUnknown(def: Def) { + return tb.Unknown() +} +// ------------------------------------------------------------------ +// Void +// ------------------------------------------------------------------ +type TFromVoid = tb.TVoid +function FromVoid(def: Def) { + return tb.Void() +} +// ------------------------------------------------------------------ +// Type +// ------------------------------------------------------------------ +// prettier-ignore +type TFromType = ( + Type extends z.ZodAny ? TFromAny : + Type extends z.ZodArray ? TFromArray : + Type extends z.ZodBigInt ? TFromBigInt : + Type extends z.ZodBoolean ? TFromBoolean : + Type extends z.ZodDate ? TFromDate : + Type extends z.ZodDefault ? TFromDefault : + Type extends z.ZodEffects ? TFromEffects : + Type extends z.ZodLiteral ? TFromLiteral : + Type extends z.ZodNullable ? TFromNullable : + Type extends z.ZodObject ? TFromObject : + Type extends z.ZodOptional ? TFromOptional : + Type extends z.ZodPromise ? TFromPromise : + Type extends z.ZodRecord ? TFromRecord : + Type extends z.ZodReadonly ? TFromReadonly : + Type extends z.ZodNumber ? TFromNumber : + Type extends z.ZodNever ? TFromNever : + Type extends z.ZodNull ? TFromNull : + Type extends z.ZodString ? TFromString : + Type extends z.ZodSymbol ? TFromSymbol : + Type extends z.ZodTuple ? TFromTuple> : + Type extends z.ZodUndefined ? TFromUndefined : + Type extends z.ZodUnion ? TFromUnion> : + Type extends z.ZodUnknown ? TFromUnknown : + Type extends z.ZodVoid ? TFromVoid : + // Intersection (Ensure Last Due to Zod Differentiation Issue) + Type extends z.ZodIntersection ? TFromIntersect<[Left, Right]> : + tb.TNever +) +// prettier-ignore +function FromType(type: Type): tb.TSchema { + const schema = ( + type instanceof z.ZodAny ? FromAny(type._def) : + type instanceof z.ZodArray ? FromArray(type._def) : + type instanceof z.ZodBigInt ? FromBigInt(type._def) : + type instanceof z.ZodBoolean ? FromBoolean(type._def) : + type instanceof z.ZodDate ? FromDate(type._def) : + type instanceof z.ZodDefault ? FromDefault(type._def) : + type instanceof z.ZodEffects ? FromEffects(type) : + type instanceof z.ZodLiteral ? FromLiteral(type._def) : + type instanceof z.ZodNullable ? FromNullable(type._def) : + type instanceof z.ZodObject ? FromObject(type._def, type.shape) : + type instanceof z.ZodOptional ? FromOptional(type._def) : + type instanceof z.ZodPromise ? FromPromise(type._def) : + type instanceof z.ZodReadonly ? FromReadonly(type._def) : + type instanceof z.ZodRecord ? FromRecord(type._def) : + type instanceof z.ZodNever ? FromNever(type._def) : + type instanceof z.ZodNull ? FromNull(type._def) : + type instanceof z.ZodNumber ? FromNumber(type._def) : + type instanceof z.ZodString ? FromString(type._def) : + type instanceof z.ZodSymbol ? FromSymbol(type._def) : + type instanceof z.ZodTuple ? FromTuple(type._def) : + type instanceof z.ZodUndefined ? FromUndefined(type._def) : + type instanceof z.ZodUnion ? FromUnion(type._def) : + type instanceof z.ZodUnknown ? FromUnknown(type._def) : + type instanceof z.ZodVoid ? FromVoid(type._def) : + // Intersection (Ensure Last Due to Zod Differentiation Issue) + type instanceof z.ZodIntersection ? FromIntersect(type._def) : + tb.Never() + ) as tb.TSchema + return tb.CreateType(schema, Options(type)) as tb.TSchema +} +// ------------------------------------------------------------------ +// Box +// ------------------------------------------------------------------ +/** Converts a Zod Type to a TypeBox Type */ +export type TBox = Type extends z.ZodType ? TFromType : undefined +/** Converts a Zod Type to a TypeBox Type */ +export function Box = TBox>(type: Type): Result { + return (type instanceof z.ZodType ? FromType(type) : undefined) as never +} diff --git a/test/assert.ts b/test/assert.ts new file mode 100644 index 0000000..8e225a8 --- /dev/null +++ b/test/assert.ts @@ -0,0 +1,57 @@ +import * as assert from 'node:assert' + +export namespace Assert { + export function HasProperty(value: unknown, key: K): asserts value is Record { + if (typeof value === 'object' && value !== null && key in value) return + throw new Error(`Expected value to have property '${key as string}'`) + } + export function IsTrue(value: boolean): asserts value is true { + return assert.strictEqual(value, true) + } + export function IsFalse(value: boolean): asserts value is false { + return assert.strictEqual(value, false) + } + export function IsEqual(actual: unknown, expect: unknown) { + if (actual instanceof Uint8Array && expect instanceof Uint8Array) { + assert.equal(actual.length, expect.length) + for (let i = 0; i < actual.length; i++) assert.equal(actual[i], expect[i]) + } + return assert.deepStrictEqual(actual, expect) + } + export function NotEqual(actual: unknown, expect: unknown) { + return assert.notEqual(actual, expect) + } + /** Asserts a numeric value is within range of the expected */ + export function InRange(value: number, expect: number, range: number) { + if (Math.abs(value - expect) <= range) return + throw Error('Expected value to be in range') + } + let nextIdOrdinal = 0 + export function NextId() { + return `$id-${nextIdOrdinal++}` + } + export function Throws(callback: Function) { + try { + callback() + } catch { + return + } + throw Error('Expected throw') + } + export async function ThrowsAsync(callback: Function) { + try { + await callback() + } catch { + return + } + throw Error('Expected throw') + } + export function IsInstanceOf any>(value: any, constructor: T): asserts value is InstanceType { + if (value instanceof constructor) return + throw Error(`Value is not instance of ${constructor}`) + } + export function IsTypeOf(value: any, type: T) { + if (typeof value === type) return + throw Error(`Value is not typeof ${type}`) + } +} diff --git a/test/index.ts b/test/index.ts new file mode 100644 index 0000000..8bc91a9 --- /dev/null +++ b/test/index.ts @@ -0,0 +1,2 @@ +import './zod' +import './valibot' diff --git a/test/tsconfig.json b/test/tsconfig.json new file mode 100644 index 0000000..9f4a7e2 --- /dev/null +++ b/test/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../tsconfig.json", + "files": ["index.ts"] +} diff --git a/test/valibot.ts b/test/valibot.ts new file mode 100644 index 0000000..6b7bc2e --- /dev/null +++ b/test/valibot.ts @@ -0,0 +1,417 @@ +import { Box } from '@sinclair/typebox-remix' +import * as Types from '@sinclair/typebox' +import { TypeGuard } from '@sinclair/typebox' +import { Assert } from './assert' +import * as v from 'valibot' + +describe('Valibot', () => { + // ---------------------------------------------------------------- + // Metadata + // ---------------------------------------------------------------- + it('Should map Description', () => { + const T = Box(v.pipe(v.number(), v.description('a number'))) + Assert.IsEqual(T.description, 'a number') + }) + it('Should map Title', () => { + const T = Box(v.pipe(v.number(), v.title('a number'))) + Assert.IsEqual(T.title, 'a number') + }) + it('Should map Metadata', () => { + const T = Box(v.pipe(v.number(), v.metadata({ x: 1, y: 2 }))) + Assert.IsEqual(T.x, 1) + Assert.IsEqual(T.y, 2) + }) + // ---------------------------------------------------------------- + // Any + // ---------------------------------------------------------------- + it('Should map Any', () => { + const T = Box(v.any()) + Assert.IsTrue(TypeGuard.IsAny(T)) + }) + // ---------------------------------------------------------------- + // Array + // ---------------------------------------------------------------- + it('Should map Array', () => { + const T = Box(v.array(v.number())) + Assert.IsTrue(TypeGuard.IsArray(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.items)) + }) + // ---------------------------------------------------------------- + // BigInt + // ---------------------------------------------------------------- + it('Should map BigInt', () => { + const T = Box(v.bigint()) + Assert.IsTrue(TypeGuard.IsBigInt(T)) + }) + // ---------------------------------------------------------------- + // Date + // ---------------------------------------------------------------- + it('Should map Date', () => { + const T = Box(v.date()) + Assert.IsTrue(TypeGuard.IsDate(T)) + }) + // ---------------------------------------------------------------- + // Effects + // ---------------------------------------------------------------- + // it('Should map Effects (Transform)', () => { + // const T = Box(v.number().transform(x => x)) + // Assert.IsTrue(TypeGuard.IsNumber(T)) + // Assert.IsTrue(TypeGuard.IsTransform(T)) + // }) + // it('Should map Effects (Refine)', () => { + // const T = Box(v.number().refine(x => true)) + // Assert.IsTrue(TypeGuard.IsNumber(T)) + // Assert.IsTrue(TypeGuard.IsTransform(T)) + // }) + // ---------------------------------------------------------------- + // Literal + // ---------------------------------------------------------------- + it('Should map Literal (Number)', () => { + const T = Box(v.literal(42)) + Assert.IsTrue(TypeGuard.IsLiteral(T)) + Assert.IsEqual(T.const, 42) + }) + it('Should map Literal (String)', () => { + const T = Box(v.literal('hello')) + Assert.IsTrue(TypeGuard.IsLiteral(T)) + Assert.IsEqual(T.const, 'hello') + }) + it('Should map Literal (Boolean)', () => { + const T = Box(v.literal(true)) + Assert.IsTrue(TypeGuard.IsLiteral(T)) + Assert.IsEqual(T.const, true) + }) + // ---------------------------------------------------------------- + // Nullable + // ---------------------------------------------------------------- + it('Should map Nullable', () => { + const T = Box(v.nullable(v.number())) + Assert.IsTrue(TypeGuard.IsUnion(T)) + Assert.IsTrue(TypeGuard.IsNull(T.anyOf[0])) + Assert.IsTrue(TypeGuard.IsNumber(T.anyOf[1])) + }) + // ---------------------------------------------------------------- + // Object + // ---------------------------------------------------------------- + it('Should map Object', () => { + const T = Box( + v.object({ + x: v.number(), + y: v.string(), + }), + ) + Assert.IsTrue(TypeGuard.IsObject(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) + Assert.IsTrue(TypeGuard.IsString(T.properties.y)) + }) + it('Should map Object (Strict)', () => { + const T = Box( + v.strictObject({ + x: v.number(), + y: v.string(), + }), + ) + Assert.IsTrue(TypeGuard.IsObject(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) + Assert.IsTrue(TypeGuard.IsString(T.properties.y)) + Assert.IsEqual(T.additionalProperties, false) + }) + // ---------------------------------------------------------------- + // Optional + // ---------------------------------------------------------------- + it('Should map Optional', () => { + const T = Box( + v.object({ + x: v.optional(v.number()), + y: v.optional(v.number()), + }), + ) + Assert.IsTrue(TypeGuard.IsObject(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) + Assert.IsTrue(TypeGuard.IsOptional(T.properties.x)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) + Assert.IsTrue(TypeGuard.IsOptional(T.properties.y)) + }) + it('Should map Optional (Partial)', () => { + const T = Box( + v.partial( + v.object({ + x: v.number(), + y: v.number(), + }), + ), + ) + Assert.IsTrue(TypeGuard.IsObject(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) + Assert.IsTrue(TypeGuard.IsOptional(T.properties.x)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) + Assert.IsTrue(TypeGuard.IsOptional(T.properties.y)) + }) + // ---------------------------------------------------------------- + // Promise + // ---------------------------------------------------------------- + it('Should map Promise', () => { + const T = Box(v.promise()) + Assert.IsEqual(T[Types.Kind], 'ValibotPromise') + }) + // ---------------------------------------------------------------- + // Record + // ---------------------------------------------------------------- + it('Should map Record (String Key)', () => { + const T = Box(v.record(v.string(), v.number())) + Assert.IsTrue(TypeGuard.IsRecord(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties[Types.PatternStringExact])) + }) + it('Should map Record (Finite Union)', () => { + const T = Box(v.record(v.union([v.literal('x'), v.literal('y')]), v.number())) + Assert.IsTrue(TypeGuard.IsObject(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) + }) + // ---------------------------------------------------------------- + // Never + // ---------------------------------------------------------------- + it('Should map Never', () => { + const T = Box(v.never()) + Assert.IsTrue(TypeGuard.IsNever(T)) + }) + // ---------------------------------------------------------------- + // Null + // ---------------------------------------------------------------- + it('Should map Null', () => { + const T = Box(v.null()) + Assert.IsTrue(TypeGuard.IsNull(T)) + }) + // ---------------------------------------------------------------- + // Number + // ---------------------------------------------------------------- + it('Should map Number', () => { + const T = Box(v.number()) + Assert.IsTrue(TypeGuard.IsNumber(T)) + }) + it('Should map Number (Integer)', () => { + const T = Box(v.pipe(v.number(), v.integer())) + Assert.IsTrue(TypeGuard.IsNumber(T)) + Assert.IsEqual(T.multipleOf, 1) + }) + it('Should map Number (Minimum)', () => { + const T = Box(v.pipe(v.number(), v.minValue(100))) + Assert.IsTrue(TypeGuard.IsNumber(T)) + Assert.IsEqual(T.minimum, 100) + }) + it('Should map Number (Maximum)', () => { + const T = Box(v.pipe(v.number(), v.maxValue(100))) + Assert.IsTrue(TypeGuard.IsNumber(T)) + Assert.IsEqual(T.maximum, 100) + }) + // ---------------------------------------------------------------- + // String + // ---------------------------------------------------------------- + it('Should map String', () => { + const T = Box(v.string()) + Assert.IsTrue(TypeGuard.IsString(T)) + }) + it('Should map String (Base64)', () => { + const T = Box(v.pipe(v.string(), v.base64())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:base64') + }) + it('Should map String (Bic)', () => { + const T = Box(v.pipe(v.string(), v.bic())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:bic') + }) + it('Should map String (CreditCard)', () => { + const T = Box(v.pipe(v.string(), v.creditCard())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:credit_card') + }) + it('Should map String (Cuid2)', () => { + const T = Box(v.pipe(v.string(), v.cuid2())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:cuid2') + }) + it('Should map String (Decimal)', () => { + const T = Box(v.pipe(v.string(), v.decimal())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:decimal') + }) + it('Should map String (Digits)', () => { + const T = Box(v.pipe(v.string(), v.digits())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:digits') + }) + it('Should map String (Email)', () => { + const T = Box(v.pipe(v.string(), v.email())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:email') + }) + it('Should map String (Emoji)', () => { + const T = Box(v.pipe(v.string(), v.emoji())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:emoji') + }) + it('Should map String (Empty)', () => { + const T = Box(v.pipe(v.string(), v.empty())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.maxLength, 0) + }) + it('Should map String (EndsWith)', () => { + const T = Box(v.pipe(v.string(), v.endsWith('hello'))) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.pattern, 'hello$') + }) + it('Should map String (Includes)', () => { + const T = Box(v.pipe(v.string(), v.includes('hello'))) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.pattern, 'hello') + }) + it('Should map String (Ipv4)', () => { + const T = Box(v.pipe(v.string(), v.ipv4())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:ipv4') + }) + it('Should map String (IpV6)', () => { + const T = Box(v.pipe(v.string(), v.ipv6())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:ipv6') + }) + it('Should map String (Ip)', () => { + const T = Box(v.pipe(v.string(), v.ip())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:ip') + }) + it('Should map String (IsoDate)', () => { + const T = Box(v.pipe(v.string(), v.isoDate())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:iso_date') + }) + it('Should map String (IsoDateTime)', () => { + const T = Box(v.pipe(v.string(), v.isoDateTime())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:iso_date_time') + }) + it('Should map String (IsoTime)', () => { + const T = Box(v.pipe(v.string(), v.isoTime())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:iso_time') + }) + it('Should map String (IsoTimeSecond)', () => { + const T = Box(v.pipe(v.string(), v.isoTimeSecond())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:iso_time_second') + }) + it('Should map String (IsoTimestamp)', () => { + const T = Box(v.pipe(v.string(), v.isoTimestamp())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:iso_timestamp') + }) + it('Should map String (IsoWeek)', () => { + const T = Box(v.pipe(v.string(), v.isoWeek())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:iso_week') + }) + it('Should map String (Length)', () => { + const T = Box(v.pipe(v.string(), v.length(100))) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.maxLength, 100) + Assert.IsEqual(T.minLength, 100) + }) + it('Should map String (Mac48)', () => { + const T = Box(v.pipe(v.string(), v.mac48())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:mac48') + }) + it('Should map String (Mac64)', () => { + const T = Box(v.pipe(v.string(), v.mac64())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:mac64') + }) + it('Should map String (Mac)', () => { + const T = Box(v.pipe(v.string(), v.mac())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:mac') + }) + it('Should map String (MaxLength)', () => { + const T = Box(v.pipe(v.string(), v.maxLength(100))) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.maxLength, 100) + }) + it('Should map String (MinLength)', () => { + const T = Box(v.pipe(v.string(), v.minLength(100))) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.minLength, 100) + }) + it('Should map String (Nanoid)', () => { + const T = Box(v.pipe(v.string(), v.nanoid())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:nanoid') + }) + it('Should map String (Octal)', () => { + const T = Box(v.pipe(v.string(), v.octal())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:octal') + }) + it('Should map String (RegExp)', () => { + const T = Box(v.pipe(v.string(), v.regex(/abc/))) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.pattern, 'abc') + }) + it('Should map String (StartsWith)', () => { + const T = Box(v.pipe(v.string(), v.startsWith('hello'))) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.pattern, '^hello') + }) + it('Should map String (Ulid)', () => { + const T = Box(v.pipe(v.string(), v.ulid())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:ulid') + }) + it('Should map String (Url)', () => { + const T = Box(v.pipe(v.string(), v.url())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:url') + }) + it('Should map String (Uuid)', () => { + const T = Box(v.pipe(v.string(), v.uuid())) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'valibot:uuid') + }) + // ---------------------------------------------------------------- + // Symbol + // ---------------------------------------------------------------- + it('Should map Symbol', () => { + const T = Box(v.symbol()) + Assert.IsTrue(TypeGuard.IsSymbol(T)) + }) + // ---------------------------------------------------------------- + // Undefined + // ---------------------------------------------------------------- + it('Should map Undefined', () => { + const T = Box(v.undefined()) + Assert.IsTrue(TypeGuard.IsUndefined(T)) + }) + // ---------------------------------------------------------------- + // Union + // ---------------------------------------------------------------- + it('Should map Union', () => { + const T = Box(v.union([v.string(), v.boolean()])) + Assert.IsTrue(TypeGuard.IsUnion(T)) + Assert.IsTrue(TypeGuard.IsString(T.anyOf[0])) + Assert.IsTrue(TypeGuard.IsBoolean(T.anyOf[1])) + }) + // ---------------------------------------------------------------- + // Unknown + // ---------------------------------------------------------------- + it('Should map Unknown', () => { + const T = Box(v.unknown()) + Assert.IsTrue(TypeGuard.IsUnknown(T)) + }) + // ---------------------------------------------------------------- + // Void + // ---------------------------------------------------------------- + it('Should map Void', () => { + const T = Box(v.void()) + Assert.IsTrue(TypeGuard.IsVoid(T)) + }) +}) diff --git a/test/zod.ts b/test/zod.ts new file mode 100644 index 0000000..7d5e03f --- /dev/null +++ b/test/zod.ts @@ -0,0 +1,446 @@ +import { Box } from '@sinclair/typebox-remix' +import * as Types from '@sinclair/typebox' +import { TypeGuard } from '@sinclair/typebox' +import { Assert } from './assert' +import * as z from 'zod' + +describe('Zod', () => { + // ---------------------------------------------------------------- + // Metadata + // ---------------------------------------------------------------- + it('Should map Description', () => { + const T = Box(z.number().describe('a number')) + Assert.IsEqual(T.description, 'a number') + }) + it('Should map Default', () => { + const T = Box(z.number().default(12345)) + Assert.IsEqual(T.default, 12345) + }) + // ---------------------------------------------------------------- + // Any + // ---------------------------------------------------------------- + it('Should map Any', () => { + const T = Box(z.any()) + Assert.IsTrue(TypeGuard.IsAny(T)) + }) + // ---------------------------------------------------------------- + // Array + // ---------------------------------------------------------------- + it('Should map Array', () => { + const T = Box(z.array(z.number())) + Assert.IsTrue(TypeGuard.IsArray(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.items)) + }) + // ---------------------------------------------------------------- + // BigInt + // ---------------------------------------------------------------- + it('Should map BigInt', () => { + const T = Box(z.bigint()) + Assert.IsTrue(TypeGuard.IsBigInt(T)) + }) + // ---------------------------------------------------------------- + // Date + // ---------------------------------------------------------------- + it('Should map Date', () => { + const T = Box(z.date()) + Assert.IsTrue(TypeGuard.IsDate(T)) + }) + // ---------------------------------------------------------------- + // Effects + // ---------------------------------------------------------------- + it('Should map Effects (Transform)', () => { + const T = Box(z.number().transform((x) => x)) + Assert.IsTrue(TypeGuard.IsNumber(T)) + Assert.IsTrue(TypeGuard.IsTransform(T)) + }) + it('Should map Effects (Refine)', () => { + const T = Box(z.number().refine((x) => true)) + Assert.IsTrue(TypeGuard.IsNumber(T)) + Assert.IsTrue(TypeGuard.IsTransform(T)) + }) + // ---------------------------------------------------------------- + // Literal + // ---------------------------------------------------------------- + it('Should map Literal (Number)', () => { + const T = Box(z.literal(42)) + Assert.IsTrue(TypeGuard.IsLiteral(T)) + Assert.IsEqual(T.const, 42) + }) + it('Should map Literal (String)', () => { + const T = Box(z.literal('hello')) + Assert.IsTrue(TypeGuard.IsLiteral(T)) + Assert.IsEqual(T.const, 'hello') + }) + it('Should map Literal (Boolean)', () => { + const T = Box(z.literal(true)) + Assert.IsTrue(TypeGuard.IsLiteral(T)) + Assert.IsEqual(T.const, true) + }) + // ---------------------------------------------------------------- + // Nullable + // ---------------------------------------------------------------- + it('Should map Nullable', () => { + const T = Box(z.number().nullable()) + Assert.IsTrue(TypeGuard.IsUnion(T)) + Assert.IsTrue(TypeGuard.IsNull(T.anyOf[0])) + Assert.IsTrue(TypeGuard.IsNumber(T.anyOf[1])) + }) + // ---------------------------------------------------------------- + // Object + // ---------------------------------------------------------------- + it('Should map Object', () => { + const T = Box( + z.object({ + x: z.number(), + y: z.string(), + }), + ) + Assert.IsTrue(TypeGuard.IsObject(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) + Assert.IsTrue(TypeGuard.IsString(T.properties.y)) + }) + it('Should map Object (Strict)', () => { + const T = Box( + z + .object({ + x: z.number(), + y: z.string(), + }) + .strict(), + ) + Assert.IsTrue(TypeGuard.IsObject(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) + Assert.IsTrue(TypeGuard.IsString(T.properties.y)) + Assert.IsEqual(T.additionalProperties, false) + }) + // ---------------------------------------------------------------- + // Optional + // ---------------------------------------------------------------- + it('Should map Optional', () => { + const T = Box( + z.object({ + x: z.number().optional(), + y: z.number().optional(), + }), + ) + Assert.IsTrue(TypeGuard.IsObject(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) + Assert.IsTrue(TypeGuard.IsOptional(T.properties.x)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) + Assert.IsTrue(TypeGuard.IsOptional(T.properties.y)) + }) + it('Should map Optional (Readonly)', () => { + const T = Box( + z.object({ + x: z.number().optional().readonly(), + y: z.number().optional().readonly(), + }), + ) + Assert.IsTrue(TypeGuard.IsObject(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) + Assert.IsTrue(TypeGuard.IsOptional(T.properties.x)) + Assert.IsTrue(TypeGuard.IsReadonly(T.properties.x)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) + Assert.IsTrue(TypeGuard.IsOptional(T.properties.y)) + Assert.IsTrue(TypeGuard.IsReadonly(T.properties.y)) + }) + it('Should map Optional (Partial)', () => { + const T = Box( + z + .object({ + x: z.number(), + y: z.number(), + }) + .partial(), + ) + Assert.IsTrue(TypeGuard.IsObject(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) + Assert.IsTrue(TypeGuard.IsOptional(T.properties.x)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) + Assert.IsTrue(TypeGuard.IsOptional(T.properties.y)) + }) + // ---------------------------------------------------------------- + // Promise + // ---------------------------------------------------------------- + it('Should map Promise', () => { + const T = Box(z.promise(z.number())) + Assert.IsTrue(TypeGuard.IsPromise(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.item)) + }) + // ---------------------------------------------------------------- + // Readonly + // ---------------------------------------------------------------- + it('Should map Readonly', () => { + const T = Box( + z.object({ + x: z.number().readonly(), + y: z.number().readonly(), + }), + ) + Assert.IsTrue(TypeGuard.IsObject(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) + Assert.IsTrue(TypeGuard.IsReadonly(T.properties.x)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) + Assert.IsTrue(TypeGuard.IsReadonly(T.properties.y)) + }) + it('Should map Readonly (Optional)', () => { + const T = Box( + z.object({ + x: z.number().readonly().optional(), + y: z.number().readonly().optional(), + }), + ) + Assert.IsTrue(TypeGuard.IsObject(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) + Assert.IsTrue(TypeGuard.IsReadonly(T.properties.x)) + Assert.IsTrue(TypeGuard.IsOptional(T.properties.x)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) + Assert.IsTrue(TypeGuard.IsReadonly(T.properties.y)) + Assert.IsTrue(TypeGuard.IsOptional(T.properties.y)) + }) + // ---------------------------------------------------------------- + // Record + // ---------------------------------------------------------------- + it('Should map Record (Key Implicit)', () => { + const T = Box(z.record(z.number())) + Assert.IsTrue(TypeGuard.IsRecord(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties[Types.PatternStringExact])) + }) + it('Should map Record (Number Key)', () => { + const T = Box(z.record(z.number(), z.number())) + Assert.IsTrue(TypeGuard.IsRecord(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties[Types.PatternNumberExact])) + }) + it('Should map Record (String Key)', () => { + const T = Box(z.record(z.string(), z.number())) + Assert.IsTrue(TypeGuard.IsRecord(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties[Types.PatternStringExact])) + }) + it('Should map Record (Finite Union)', () => { + const T = Box(z.record(z.union([z.literal('x'), z.literal('y')]), z.number())) + Assert.IsTrue(TypeGuard.IsObject(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) + Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) + }) + // ---------------------------------------------------------------- + // Never + // ---------------------------------------------------------------- + it('Should map Never', () => { + const T = Box(z.never()) + Assert.IsTrue(TypeGuard.IsNever(T)) + }) + // ---------------------------------------------------------------- + // Null + // ---------------------------------------------------------------- + it('Should map Null', () => { + const T = Box(z.null()) + Assert.IsTrue(TypeGuard.IsNull(T)) + }) + // ---------------------------------------------------------------- + // Number + // ---------------------------------------------------------------- + it('Should map Number', () => { + const T = Box(z.number()) + Assert.IsTrue(TypeGuard.IsNumber(T)) + }) + it('Should map Number (Integer)', () => { + const T = Box(z.number().int()) + Assert.IsTrue(TypeGuard.IsNumber(T)) + Assert.IsEqual(T.multipleOf, 1) + }) + it('Should map Number (Minimum)', () => { + const T = Box(z.number().min(100)) + Assert.IsTrue(TypeGuard.IsNumber(T)) + Assert.IsEqual(T.minimum, 100) + }) + it('Should map Number (Maximum)', () => { + const T = Box(z.number().max(100)) + Assert.IsTrue(TypeGuard.IsNumber(T)) + Assert.IsEqual(T.maximum, 100) + }) + // ---------------------------------------------------------------- + // String + // ---------------------------------------------------------------- + it('Should map String', () => { + const T = Box(z.string()) + Assert.IsTrue(TypeGuard.IsString(T)) + }) + it('Should map String (Base64)', () => { + const T = Box(z.string().base64()) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:base64') + }) + it('Should map String (Base64Url)', () => { + const T = Box(z.string().base64url()) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:base64url') + }) + it('Should map String (Cidr V4)', () => { + const T = Box(z.string().cidr({ version: 'v4' })) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:cidrv4') + }) + it('Should map String (Cidr v6)', () => { + const T = Box(z.string().cidr({ version: 'v6' })) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:cidrv6') + }) + it('Should map String (Cidr)', () => { + const T = Box(z.string().cidr()) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:cidr') + }) + it('Should map String (Cuid)', () => { + const T = Box(z.string().cuid()) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:cuid') + }) + it('Should map String (Cuid2)', () => { + const T = Box(z.string().cuid2()) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:cuid2') + }) + it('Should map String (Ulid)', () => { + const T = Box(z.string().ulid()) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:ulid') + }) + it('Should map String (Email)', () => { + const T = Box(z.string().email()) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:email') + }) + it('Should map String (Emoji)', () => { + const T = Box(z.string().emoji()) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:emoji') + }) + it('Should map String (EndsWith)', () => { + const T = Box(z.string().endsWith('hello')) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.pattern, 'hello$') + }) + it('Should map String (Includes)', () => { + const T = Box(z.string().includes('hello')) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.pattern, 'hello') + }) + it('Should map String (IpV4)', () => { + const T = Box(z.string().ip({ version: 'v4' })) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:ipv4') + }) + it('Should map String (IpV6)', () => { + const T = Box(z.string().ip({ version: 'v6' })) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:ipv6') + }) + it('Should map String (Ip)', () => { + const T = Box(z.string().ip()) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:ip') + }) + it('Should map String (Jwt)', () => { + const T = Box(z.string().jwt()) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:jwt') + }) + it('Should map String (Length)', () => { + const T = Box(z.string().length(100)) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.minLength, 100) + Assert.IsEqual(T.maxLength, 100) + }) + + it('Should map String (Min)', () => { + const T = Box(z.string().min(100)) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.minLength, 100) + }) + it('Should map String (Max)', () => { + const T = Box(z.string().max(100)) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.maxLength, 100) + }) + it('Should map String (Nanoid)', () => { + const T = Box(z.string().nanoid()) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:nanoid') + }) + it('Should map String (RegExp)', () => { + const T = Box(z.string().regex(/abc/)) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.pattern, 'abc') + }) + it('Should map String (StartsWith)', () => { + const T = Box(z.string().startsWith('hello')) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.pattern, '^hello') + }) + it('Should map String (Time)', () => { + const T = Box(z.string().time()) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:time') + }) + it('Should map String (Ulid)', () => { + const T = Box(z.string().ulid()) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:ulid') + }) + it('Should map String (Url)', () => { + const T = Box(z.string().url()) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:url') + }) + it('Should map String (Uuid)', () => { + const T = Box(z.string().uuid()) + Assert.IsTrue(TypeGuard.IsString(T)) + Assert.IsEqual(T.format, 'zod:uuid') + }) + // ---------------------------------------------------------------- + // Symbol + // ---------------------------------------------------------------- + it('Should map Symbol', () => { + const T = Box(z.symbol()) + Assert.IsTrue(TypeGuard.IsSymbol(T)) + }) + // ---------------------------------------------------------------- + // Tuple + // ---------------------------------------------------------------- + it('Should map Tuple', () => { + const T = Box(z.tuple([z.number(), z.string()])) + Assert.IsTrue(TypeGuard.IsTuple(T)) + Assert.IsTrue(TypeGuard.IsNumber(T.items![0])) + Assert.IsTrue(TypeGuard.IsString(T.items![1])) + }) + // ---------------------------------------------------------------- + // Undefined + // ---------------------------------------------------------------- + it('Should map Undefined', () => { + const T = Box(z.undefined()) + Assert.IsTrue(TypeGuard.IsUndefined(T)) + }) + // ---------------------------------------------------------------- + // Union + // ---------------------------------------------------------------- + it('Should map Union', () => { + const T = Box(z.union([z.string(), z.boolean()])) + Assert.IsTrue(TypeGuard.IsUnion(T)) + Assert.IsTrue(TypeGuard.IsString(T.anyOf[0])) + Assert.IsTrue(TypeGuard.IsBoolean(T.anyOf[1])) + }) + // ---------------------------------------------------------------- + // Unknown + // ---------------------------------------------------------------- + it('Should map Unknown', () => { + const T = Box(z.unknown()) + Assert.IsTrue(TypeGuard.IsUnknown(T)) + }) + // ---------------------------------------------------------------- + // Void + // ---------------------------------------------------------------- + it('Should map Void', () => { + const T = Box(z.void()) + Assert.IsTrue(TypeGuard.IsVoid(T)) + }) +}) diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..05179a8 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "strict": true, + "target": "ES2020", + "moduleResolution": "Node", + "baseUrl": ".", + "paths": { + "@sinclair/typebox-remix/typebox": ["src/typebox.ts"], + "@sinclair/typebox-remix/valibot": ["src/valibot.ts"], + "@sinclair/typebox-remix/zod": ["src/zod.ts"], + "@sinclair/typebox-remix": ["src/index.ts"] + } + } +} \ No newline at end of file diff --git a/typebox-remix.png b/typebox-remix.png new file mode 100644 index 0000000..9ffc060 Binary files /dev/null and b/typebox-remix.png differ